Пример #1
0
        public async Task <ISnmpMessage?> SetV3TsmAsync <T>(IPAddress ip, string oid, int retries, int port, TimeSpan timeout,
                                                            X509Certificate2 certificate, TimeSpan connectionTimeout, T setValue)
        {
            if (ip == null)
            {
                throw new ArgumentNullException(nameof(ip));
            }

            if (string.IsNullOrWhiteSpace(oid))
            {
                throw new ArgumentNullException(nameof(oid));
            }

            if (!Regex.IsMatch(oid, @"^(([0-9]+)\.)+[0-9]+$"))
            {
                throw new ArgumentException(oid, nameof(oid));
            }

            if (port <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(port), port.ToString());
            }

            if (retries <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(retries), retries.ToString());
            }

            if (timeout <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(timeout), timeout.ToString());
            }

            if (connectionTimeout <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(connectionTimeout));
            }

            if (certificate is null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            var startDate   = DateTime.Now;
            var snmpType    = "SET";
            var snmpVersion = $"3 {SecurityModel.Tsm}";

            var          attempt  = 0;
            ISnmpMessage?response = null;

            while (attempt < retries)
            {
                var setValueByType = setValue switch
                {
                    int x => new Variable(new ObjectIdentifier(oid), new Integer32(x)),
                    string x => new Variable(new ObjectIdentifier(oid), new OctetString(x)),
                    IPAddress x => new Variable(new ObjectIdentifier(oid), new IP(x.ToString())),
                    uint x => new Variable(new ObjectIdentifier(oid), new Gauge32(x)),
                    byte[] x => new Variable(new ObjectIdentifier(oid), new OctetString(x)),
                    _ => throw new ArgumentOutOfRangeException(nameof(setValue)),
                };

                try
                {
                    var receiver       = new IPEndPoint(ip, port);
                    var clientEndPoint = ip.AddressFamily == AddressFamily.InterNetwork
                        ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0);
                    var vList = new List <Variable>()
                    {
                        setValueByType
                    };

                    var chain = new X509Chain();
                    chain.Build(certificate);

                    using var client = new Client(clientEndPoint);
                    client.LoadX509Certificate(chain);
                    client.SupportedCipherSuites.Add(TCipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA);

                    var auth = TsmAuthenticationProvider.Instance;
                    IPrivacyProvider priv = new TsmPrivacyProvider(auth);

                    var request = new SetRequestMessage(VersionCode.V3, Messenger.NextMessageId, Messenger.NextRequestId, OctetString.Empty, vList, priv, Messenger.MaxMessageSize);
                    response = await request.GetSecureResponseAsync(connectionTimeout, timeout, receiver, client).ConfigureAwait(false);

                    if (response is ReportMessage)
                    {
                        if (response.Pdu().Variables.Count == 0)
                        {
                            throw new Exception("wrong report message received");
                        }

                        var id = response.Pdu().Variables[0].Id;
                        if (id != Messenger.NotInTimeWindow)
                        {
                            var error = id.GetErrorMessage();
                            throw new Exception($"ERROR: {error}");
                        }

                        var request2 = new GetRequestMessage(VersionCode.V3, Messenger.NextMessageId, Messenger.NextRequestId, OctetString.Empty, OctetString.Empty, vList, priv, Messenger.MaxMessageSize, response);
                        response = await request2.GetSecureResponseAsync(connectionTimeout, timeout, receiver, client).ConfigureAwait(false);
                    }

                    break;
                }
                catch (Exception ex) when(ex is SnmpException || ex is SocketException || ex is OperationCanceledException || ex is System.TimeoutException)
                {
                    if (ex is System.TimeoutException && ex.Message == "Could Not Connect To Server")
                    {
                        _Logger.LogInformation($"{ip} - DTLS failed {attempt + 1} time(s)");
                    }

                    await _SnmpLog.LogTransactionAsync(startDate, ip.ToString(), oid, null, snmpType, snmpVersion, ex.GetType().ToString(), ex.Message).ConfigureAwait(false);

                    ++attempt;
                    if (attempt >= retries)
                    {
                        throw;
                    }
                }
            }

            if (response is null)
            {
                await _SnmpLog.LogTransactionAsync(startDate, ip.ToString(), oid, null, snmpType, snmpVersion, SnmpType.Null.ToString(), null).ConfigureAwait(false);

                return(response);
            }

            var type = response.Pdu().TypeCode;
            var data = response.Pdu().ErrorStatus;

            await _SnmpLog.LogTransactionAsync(startDate, ip.ToString(), oid, null, snmpType, snmpVersion, type.ToString(), data.ToString()).ConfigureAwait(false);

            return(response);
        }
Пример #2
0
        public async Task <Variable?> GetV3TsmAsync(IPAddress ip, string oid, int retries, int port, TimeSpan timeout,
                                                    X509Certificate2 certificate, TimeSpan connectionTimeout)
        {
            if (ip == null)
            {
                throw new ArgumentNullException(nameof(ip));
            }

            if (string.IsNullOrWhiteSpace(oid))
            {
                throw new ArgumentNullException(nameof(oid));
            }

            if (!Regex.IsMatch(oid, @"^(([0-9]+)\.)+[0-9]+$"))
            {
                throw new ArgumentException(oid, nameof(oid));
            }

            if (port <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(port), port.ToString());
            }

            if (retries <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(retries), retries.ToString());
            }

            if (timeout <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(timeout), timeout.ToString());
            }

            if (connectionTimeout <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(connectionTimeout));
            }

            if (certificate is null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            var startDate   = DateTime.Now;
            var snmpType    = "GET";
            var snmpVersion = $"3 {SecurityModel.Tsm}";

            var attempt = 0;
            IEnumerable <Variable> reply = new List <Variable>();

            while (attempt < retries)
            {
                try
                {
                    var receiver       = new IPEndPoint(ip, port);
                    var clientEndPoint = ip.AddressFamily == AddressFamily.InterNetwork
                        ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0);
                    var vList = new List <Variable>()
                    {
                        new Variable(new ObjectIdentifier(oid))
                    };

                    var chain = new X509Chain();
                    chain.Build(certificate);

                    using var client = new Client(clientEndPoint);
                    client.LoadX509Certificate(chain);
                    client.SupportedCipherSuites.Add(TCipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA);

                    var auth = TsmAuthenticationProvider.Instance;
                    IPrivacyProvider priv = new TsmPrivacyProvider(auth);

                    var          request  = new GetRequestMessage(VersionCode.V3, Messenger.NextMessageId, Messenger.NextRequestId, OctetString.Empty, vList, priv, Messenger.MaxMessageSize);
                    ISnmpMessage response = await request.GetSecureResponseAsync(connectionTimeout, timeout, receiver, client).ConfigureAwait(false);

                    if (response is ReportMessage)
                    {
                        if (response.Pdu().Variables.Count == 0)
                        {
                            throw new Exception("wrong report message received");
                        }

                        var id = response.Pdu().Variables[0].Id;
                        if (id != Messenger.NotInTimeWindow)
                        {
                            var error = id.GetErrorMessage();
                            throw new Exception($"ERROR: {error}");
                        }

                        // according to RFC 3414, send a second request to sync time.
                        var request2 = new GetRequestMessage(VersionCode.V3, Messenger.NextMessageId, Messenger.NextRequestId, OctetString.Empty, OctetString.Empty, vList, priv, Messenger.MaxMessageSize, response);
                        response = await request2.GetSecureResponseAsync(connectionTimeout, timeout, receiver, client).ConfigureAwait(false);
                    }
                    else if (response.Pdu().ErrorStatus.ToInt32() != 0) // != ErrorCode.NoError
                    {
                        throw ErrorException.Create(
                                  "error in response",
                                  receiver.Address,
                                  response);
                    }

                    reply = response.Pdu().Variables;
                    break;
                }
                catch (Exception ex) when(ex is SnmpException || ex is SocketException || ex is OperationCanceledException || ex is System.TimeoutException)
                {
                    if (ex is System.TimeoutException && ex.Message == "Could Not Connect To Server")
                    {
                        _Logger.LogInformation($"{ip} - DTLS failed {attempt + 1} time(s)");
                    }

                    await _SnmpLog.LogTransactionAsync(startDate, ip.ToString(), oid, null, snmpType, snmpVersion, ex.GetType().ToString(), ex.Message).ConfigureAwait(false);

                    ++attempt;
                    if (attempt >= retries)
                    {
                        throw;
                    }
                }
            }

            var type = string.Empty;
            var data = string.Empty;

            foreach (var res in reply)
            {
                type += res.Data.TypeCode;
                data += res.Data.ToString();
            }

            await _SnmpLog.LogTransactionAsync(startDate, ip.ToString(), oid, null, snmpType, snmpVersion, type, data).ConfigureAwait(false);

            return(reply.FirstOrDefault());
        }