Пример #1
0
		private static ISnmpMessage ParseMessage(int first, Stream stream, UserRegistry registry)
		{
			ISnmpData array = DataFactory.CreateSnmpData(first, stream);
			if (array == null)
			{
				return null;
			}

			if (array.TypeCode != SnmpType.Sequence)
			{
				throw new SnmpException("not an SNMP message");
			}

			Sequence body = (Sequence)array;
			if (body.Count != 3 && body.Count != 4)
			{
				throw new SnmpException("not an SNMP message");
			}

			VersionCode version = (VersionCode)((Integer32)body[0]).ToInt32();
			Header header;
			SecurityParameters parameters;
			IPrivacyProvider privacy;
			Scope scope;
			if (body.Count == 3)
			{
				header = Header.Empty;
				parameters = new SecurityParameters(null, null, null, (OctetString)body[1], null, null);
				privacy = DefaultPrivacyProvider.DefaultPair;                
				scope = new Scope((ISnmpPdu)body[2]);
			}
			else
			{
				header = new Header(body[1]);
				parameters = new SecurityParameters((OctetString)body[2]);
				privacy = registry.Find(parameters.UserName);
				if (privacy == null)
				{
					// handle decryption exception.
					return new MalformedMessage(header.MessageId, parameters.UserName);
				}

				var code = body[3].TypeCode;
				if (code == SnmpType.Sequence)
				{
					// v3 not encrypted
					scope = new Scope((Sequence)body[3]);
				}
				else if (code == SnmpType.OctetString)
				{
					// v3 encrypted
					try
					{
						scope = new Scope((Sequence)privacy.Decrypt(body[3], parameters));
					}
					catch (DecryptionException)
					{
						// handle decryption exception.
						return new MalformedMessage(header.MessageId, parameters.UserName);
					}
				}
				else
				{
					throw new SnmpException(string.Format(CultureInfo.InvariantCulture, "invalid v3 packets scoped data: {0}", code));
				}

				if (!privacy.AuthenticationProvider.VerifyHash(version, header, parameters, body[3], privacy))
				{
					throw new SnmpException("invalid v3 packet data");
				}
			}

			var scopeCode = scope.Pdu.TypeCode;
			switch (scopeCode)
			{
				case SnmpType.TrapV1Pdu:
					return new TrapV1Message(body);
				case SnmpType.TrapV2Pdu:
					return new TrapV2Message(version, header, parameters, scope, privacy);
				case SnmpType.GetRequestPdu:
					return new GetRequestMessage(version, header, parameters, scope, privacy);
				case SnmpType.ResponsePdu:
					return new ResponseMessage(version, header, parameters, scope, privacy, false);
				case SnmpType.SetRequestPdu:
					return new SetRequestMessage(version, header, parameters, scope, privacy);
				case SnmpType.GetNextRequestPdu:
					return new GetNextRequestMessage(version, header, parameters, scope, privacy);
				case SnmpType.GetBulkRequestPdu:
					return new GetBulkRequestMessage(version, header, parameters, scope, privacy);
				case SnmpType.ReportPdu:
					return new ReportMessage(version, header, parameters, scope, privacy);
				case SnmpType.InformRequestPdu:
					return new InformRequestMessage(version, header, parameters, scope, privacy);
				default:
					throw new SnmpException(string.Format(CultureInfo.InvariantCulture, "unsupported pdu: {0}", scopeCode));
			}
		}