/// <summary>
        /// Gets the OID lookup table for the specified device name and version.
        /// </summary>
        /// <param name="deviceName">The device name to look up.</param>
        /// <param name="version">The current version of the device.</param>
        /// <param name="deviceVersion">Returns the device version container matching this device.</param>
        /// <param name="deviceAddress">The IP address of the device (only used to include it with possible exceptions).</param>
        /// <returns>The OID lookup table for the specified device name and version.</returns>
        protected IDeviceSpecificOidLookup ObtainOidTable(string deviceName, SemanticVersion version, out DeviceVersion deviceVersion, IpAddress deviceAddress)
        {
            using (var database = DeviceDatabaseProvider.Instance.DeviceDatabase)
            {
                int foundDeviceId = -1;
                if (!database.TryFindDeviceId(deviceName, out foundDeviceId))
                {
                    var exception = new HamnetSnmpException($"Device name '{deviceName}' cannot be found in device database", deviceAddress?.ToString());
                    log.Error(exception.Message);
                    this.CollectException("No OID lookup for device name", exception);
                    throw exception;
                }

                deviceVersion = null;
                if (!database.TryFindDeviceVersionId(foundDeviceId, version, out deviceVersion))
                {
                    var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}' (ID {foundDeviceId}) cannot be matched to any version range of device database", deviceAddress?.ToString());
                    log.Error(exception.Message);
                    this.CollectException("No OID lookup for device version", exception);
                    throw exception;
                }

                string foundOidMappingIds = string.Empty;
                if (!database.TryFindOidLookupId(deviceVersion.Id, out foundOidMappingIds))
                {
                    var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}' (ID {foundDeviceId}, version ID {deviceVersion.Id}) cannot be matched to any OID mapping ID of device database", deviceAddress?.ToString());
                    log.Error(exception.Message);
                    this.CollectException("No OID mapping for device version", exception);
                    throw exception;
                }

                // need to convert the string containing a comma-separated list of OID lookup tables IDs into single, integer table IDs
                // Example: There are two lookups given in order "3,1" in the foundOidMappingIds string.
                //          If a RetrievableValuesEnum has a value in lookup of ID 3 that value shall be used. Otherwise the value of lookup #1.
                string[] splitOidMappingIds = foundOidMappingIds.Split(new char[] { ',', ';', ':', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                List <IDeviceSpecificOidLookup> orderedOidLookupsList = new List <IDeviceSpecificOidLookup>(splitOidMappingIds.Length);
                foreach (var sid in splitOidMappingIds)
                {
                    int intId;
                    if (!int.TryParse(sid, out intId))
                    {
                        log.Warn($"OID mapping table ID '{sid}' as found for device '{deviceName}' v '{version}' (version ID {deviceVersion.Id}, mapping IDs '{foundOidMappingIds}') is not an integer value and will be ignored");
                        continue;
                    }

                    IDeviceSpecificOidLookup foundLookup = null;
                    if (!database.TryFindDeviceSpecificOidLookup(intId, deviceVersion.MaximumSupportedSnmpVersion.ToSnmpVersion(), out foundLookup))
                    {
                        var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}': Cannot find OID mapping ID table of ID {intId} in device database", deviceAddress?.ToString());
                        log.Error(exception.Message);
                        this.CollectException("No OID mapping for mapping ID", exception);
                        throw exception;
                    }

                    orderedOidLookupsList.Add(foundLookup);
                }

                return(new DeviceSpecificMultiLayerOidLookupProxy(orderedOidLookupsList));
            }
        }
Пример #2
0
        /// <summary>
        /// Constructs for the given lower layer.
        /// </summary>
        /// <param name="lowerLayer">The lower layer for talking to this device.</param>
        /// <param name="oidLookup">The OID lookup table for the device.</param>
        /// <param name="osVersion">The SW version of the device.</param>
        /// <param name="model">The device's model name. Shall be the same name as used for the device name during OID database lookups.</param>
        /// <param name="options">The options to use.</param>
        public DeviceHandlerBase(ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidLookup, SemVersion.SemanticVersion osVersion, string model, IQuerierOptions options)
        {
            if (lowerLayer == null)
            {
                throw new ArgumentNullException(nameof(lowerLayer), "lower layer is null when constructing a device handler");
            }

            if (oidLookup == null)
            {
                throw new ArgumentNullException(nameof(oidLookup), "OID lookup table is null when constructing a device handler");
            }

            if (osVersion == null)
            {
                throw new ArgumentNullException(nameof(osVersion), "OS version info is null when constructing a device handler");
            }

            if (string.IsNullOrWhiteSpace(model))
            {
                throw new ArgumentNullException(nameof(model), "Model name is null, empty or white-space-only when constructing a device handler");
            }

            this.LowerLayer = lowerLayer;
            this.OidLookup  = oidLookup;
            this.OsVersion  = osVersion;
            this.Model      = model;
            this.Options    = options ?? throw new ArgumentNullException(nameof(options), "The options are null when constructing a device handler");
        }
        /// <inheritdoc />
        public override IDeviceHandler CreateHandler(ISnmpLowerLayer lowerLayer, IQuerierOptions options)
        {
            string osVersionString = null;

            // try #1: In IEEE SNMP tree
            try
            {
                osVersionString = lowerLayer.QueryAsString(OsVersionOid, "MikroTik RouterOS Version String #1");
            }
            catch (SnmpException ex)
            {
                this.CollectException("MtikSnmp: Getting version string", ex);
                osVersionString = null;
            }
            catch (HamnetSnmpException ex)
            {
                this.CollectException("MtikSnmp: Getting version string", ex);
                osVersionString = null;
            }

            // try #2: Withing MikroTik enterprise tree
            if (string.IsNullOrWhiteSpace(osVersionString))
            {
                osVersionString = lowerLayer.QueryAsString(OsVersionOid2, "MikroTik RouterOS Version String #2");
            }

            // Example: "RouterOS 6.45.3 (stable) on RB711-5Hn-MMCX"
            Match match = OsVersionExtractionRegex.Match(osVersionString);

            SemanticVersion osVersion = match.Success ? match.Groups[1].Value.ToSemanticVersion() : null;

            var model = lowerLayer.SystemData.Description.Replace(RouterOsDetectionString, string.Empty).Trim();

            log.Info($"Detected device '{lowerLayer.Address}' as MikroTik '{model}' v '{osVersion}'");

            DeviceVersion            deviceVersion;
            IDeviceSpecificOidLookup oidTable = this.ObtainOidTable(model.Trim(), osVersion, out deviceVersion, lowerLayer.Address);

            if (string.IsNullOrWhiteSpace(deviceVersion.HandlerClassName))
            {
                try
                {
                    return(new MikrotikSnmpDeviceHandler(lowerLayer, oidTable, osVersion, model, options));
                }
                catch (Exception ex)
                {
                    this.CollectException("MtikSnmp: OID table lookup", ex);

                    // we want to catch and nest the exception here as the APIs involved are not able to append the infomration for which
                    // device (i.e. IP address) the exception is for
                    throw new HamnetSnmpException($"Failed to create MikroTik handler for device '{lowerLayer.Address}': {ex.Message}", ex, lowerLayer.Address?.ToString());
                }
            }
            else
            {
                return(this.GetHandlerViaReflection(deviceVersion.HandlerClassName, lowerLayer, oidTable, osVersion, model, options));
            }
        }
Пример #4
0
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="macAddress">The MAC address of the peer (serves as index in OIDs for MikroTik devices).</param>
 /// <param name="interfaceId">The ID of the interface (i.e. the value to append to interface-specific OIDs).</param>
 /// <param name="isAccessPoint">Value indicating whether the device proving the peer info is an access point or a client.</param>
 /// <param name="numberOfClients">The number of clients that are connected to this AP when in AP mode. null if not an AP or not available.</param>
 public LazyLoadingAlixWirelessPeerInfo(
     ISnmpLowerLayer lowerSnmpLayer,
     IDeviceSpecificOidLookup oidLookup,
     string macAddress,
     int?interfaceId,
     bool?isAccessPoint,
     int?numberOfClients)
     : base(lowerSnmpLayer, oidLookup, macAddress, interfaceId, isAccessPoint, numberOfClients)
 {
 }
Пример #5
0
        public void TryFindOids()
        {
            int goodOidLookupId = 1;
            int badOidLookupId  = int.MaxValue;

            using (var context = new DeviceDatabaseContext(this.database))
            {
                IDeviceSpecificOidLookup foundLookup = null;

                Assert.IsTrue(context.TryFindDeviceSpecificOidLookup(goodOidLookupId, SnmpSharpNet.SnmpVersion.Ver1, out foundLookup), $"Cannot find OID lookup ID for 'good' lookup ID '{goodOidLookupId}'");
                Assert.GreaterOrEqual(foundLookup.Count, 1, $"Empty lookup for for 'good' lookup ID '{goodOidLookupId}'");

                Assert.IsFalse(context.TryFindDeviceSpecificOidLookup(badOidLookupId, SnmpSharpNet.SnmpVersion.Ver1, out foundLookup), $"Found lookup for 'bad' lookup ID '{badOidLookupId}'");
            }
        }
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="peerIndex">The peer's index (to use in SNMP get).</param>
 /// <param name="numberOfClients">The number of clients that are connected to this AP when in AP mode. null if not an AP or not available.</param>
 public LazyLoadingUbiquitiAirFiberWirelessPeerInfo(
     ISnmpLowerLayer lowerSnmpLayer,
     IDeviceSpecificOidLookup oidLookup,
     int peerIndex,
     int?numberOfClients)
     : base(
         lowerSnmpLayer,
         oidLookup,
         null,
         null, // For UBNT there's no way to find which wireless interface this peer belongs to.
         null,
         numberOfClients)
 {
     this.peerIndex = peerIndex;
 }
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="macAddress">The MAC address of the peer (serves as index in OIDs for MikroTik devices).</param>
 /// <param name="interfaceId">The ID of the interface (i.e. the value to append to interface-specific OIDs).</param>
 /// <param name="isAccessPoint">Value indicating whether the device proving the peer info is an access point or a client.</param>
 /// <param name="numberOfClients">The number of clients that are connected to this AP when in AP mode. null if not an AP or not available.</param>
 protected LazyLoadingGenericWirelessPeerInfo(
     ISnmpLowerLayer lowerSnmpLayer,
     IDeviceSpecificOidLookup oidLookup,
     string macAddress,
     int?interfaceId,
     bool?isAccessPoint,
     int?numberOfClients)
     : base(lowerSnmpLayer)
 {
     this.OidLookup       = oidLookup;
     this.PeerMac         = macAddress;
     this.InterfaceId     = interfaceId;
     this.IsAccessPoint   = isAccessPoint;
     this.NumberOfClients = numberOfClients;
 }
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="interfaceId">The interface ID (to use in SNMP get).</param>
 /// <param name="peerWalkCollection">The collection generated by the walk operation that triggered creation of this peer info.</param>
 /// <param name="numberOfClients">The number of clients that are connected to this AP when in AP mode. null if not an AP or not available.</param>
 public LazyLoadingUbiquitiAirOs4WirelessPeerInfo(
     ISnmpLowerLayer lowerSnmpLayer,
     IDeviceSpecificOidLookup oidLookup,
     int interfaceId,
     VbCollection peerWalkCollection,
     int?numberOfClients)
     : base(
         lowerSnmpLayer,
         oidLookup,
         null,
         interfaceId,
         null,
         numberOfClients)
 {
     this.walkCollection = peerWalkCollection;
 }
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="macAddress">The MAC address of the peer (serves as index in OIDs for MikroTik devices).</param>
 /// <param name="peerIndex">The peer's index (to use in SNMP get).</param>
 /// <param name="isAccessPoint">Value indicating whether the device proving the peer info is an access point or a client.</param>
 /// <param name="numberOfClients">The number of clients that are connected to this AP when in AP mode. null if not an AP or not available.</param>
 public LazyLoadingUbiquitiAirOs6plusWirelessPeerInfo(
     ISnmpLowerLayer lowerSnmpLayer,
     IDeviceSpecificOidLookup oidLookup,
     string macAddress,
     int peerIndex,
     bool?isAccessPoint,
     int?numberOfClients)
     : base(
         lowerSnmpLayer,
         oidLookup,
         macAddress,
         null, // For UBNT there's no way to find which wireless interface this peer belongs to.
         isAccessPoint,
         numberOfClients)
 {
     this.peerIndex = peerIndex;
 }
Пример #10
0
        /// <summary>
        /// Constructs for the given lower layer.
        /// </summary>
        /// <param name="lowerLayer">The lower layer for talking to this device.</param>
        /// <param name="oidLookup">The OID lookup table for the device.</param>
        /// <param name="osVersion">The SW version of the device.</param>
        /// <param name="model">The device's model name. Shall be the same name as used for the device name during OID database lookups.</param>
        /// <param name="options">The options to use.</param>
        public AlixDeviceHandler(ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidLookup, SemanticVersion osVersion, string model, IQuerierOptions options)
            : base(lowerLayer, oidLookup, osVersion, model, options)
        {
            if ((options.AllowedApis & this.SupportedApi) == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(options), $"This device handler doesn't support any of the APIs allowed by the IQuerierOptions (allowed: {options.AllowedApis}, supported {this.SupportedApi}).");
            }

            LazyLoadingDeviceSystemData llsd = lowerLayer.SystemData as LazyLoadingDeviceSystemData;

            if (llsd != null)
            {
                if (oidLookup.TryGetValue(RetrievableValuesEnum.RxSignalStrengthCh0AppendMacAndInterfaceId, out DeviceSpecificOid oid0) && !oid0.Oid.IsNull)
                {
                    // for ALIX/H4L devices we currently only support RSSI querying
                    llsd.SupportedFeatures = DeviceSupportedFeatures.Rssi;
                }
            }
        }
Пример #11
0
        /// <inheritdoc />
        public override IDeviceHandler CreateHandler(ISnmpLowerLayer lowerLayer, IQuerierOptions options)
        {
            string osVersionString = "0.0.0";

            // Example: "..."
            Match match = OsVersionExtractionRegex.Match(osVersionString);

            SemanticVersion osVersion = osVersionString.ToSemanticVersion(); // match.Success ? match.Groups[1].Value.ToSemanticVersion() : null;

            var model = lowerLayer.SystemData.Description;                   //lowerLayer.SystemData.Description.Replace(RouterOsDetectionString, string.Empty).Trim();

            log.Info($"Detected device '{lowerLayer.Address}' as ALIX '{model}' v '{osVersion}'");

            DeviceVersion            deviceVersion;
            IDeviceSpecificOidLookup oidTable = this.ObtainOidTable(model.Trim(), osVersion, out deviceVersion, lowerLayer.Address);

            if (string.IsNullOrWhiteSpace(deviceVersion.HandlerClassName))
            {
                try
                {
                    return(new AlixDeviceHandler(lowerLayer, oidTable, osVersion, model, options));
                }
                catch (Exception ex)
                {
                    this.CollectException("AlixSnmp: OID table lookup", ex);

                    // we want to catch and nest the exception here as the APIs involved are not able to append the infomration for which
                    // device (i.e. IP address) the exception is for
                    throw new HamnetSnmpException($"Failed to create ALIX handler for device '{lowerLayer.Address}': {ex.Message}", ex, lowerLayer?.Address?.ToString());
                }
            }
            else
            {
                return(this.GetHandlerViaReflection(deviceVersion.HandlerClassName, lowerLayer, oidTable, osVersion, model, options));
            }
        }
Пример #12
0
 /// <inheritdoc />
 protected override IWirelessPeerInfos RetrieveWirelessPeerInfos(ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidLookup)
 {
     return(new LazyLoadingAlixWirelessPeerInfos(this.LowerLayer, this.OidLookup));
 }
Пример #13
0
 /// <summary>
 /// Allows deriving class to retrieve and return their implementation of <see cref="IInterfaceDetails" />.
 /// </summary>
 /// <param name="lowerLayer">The lower layer for talking to this device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <returns>The retrieved interface details.</returns>
 protected abstract IInterfaceDetails RetrieveDeviceInterfaceDetails(ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidLookup);
Пример #14
0
 /// <inheritdoc />
 protected override IWirelessPeerInfos RetrieveWirelessPeerInfos(ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidLookup)
 {
     return(new LazyLoadingUbiquitiAirOsUpTo56WirelessPeerInfos(this.LowerLayer, this.OidLookup) as IWirelessPeerInfos);
 }
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 public LazyLoadingMikroTikWirelessPeerInfos(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup)
     : base(lowerSnmpLayer, oidLookup)
 {
 }
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 protected LazyLoadingGenericWirelessPeerInfos(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup)
     : base(lowerSnmpLayer)
 {
     this.OidLookup = oidLookup;
 }
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="interfaceId">The ID of the interface (i.e. the value to append to interface-specific OIDs).</param>
 /// <param name="wirelessInterfaceNames">A list of string that are used to detect whether the interface is actually related to the wireless link.</param>
 public LazyLoadingUbiquitiInterfaceDetail(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup, int interfaceId, IEnumerable <string> wirelessInterfaceNames)
     : base(lowerSnmpLayer, oidLookup, interfaceId)
 {
     this.wirelessInterfaceNames = wirelessInterfaceNames;
 }
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="interfaceId">The ID of the interface (i.e. the value to append to interface-specific OIDs).</param>
 public LazyLoadingGenericInterfaceDetail(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup, int interfaceId)
     : base(lowerSnmpLayer)
 {
     this.OidLookup   = oidLookup;
     this.InterfaceId = interfaceId;
 }
Пример #19
0
        /// <summary>
        /// Gets the device handler of the given handler class name via reflection.
        /// </summary>
        /// <param name="handlerClassName">The class name of the device handler to get.</param>
        /// <param name="lowerLayer">The lower layer for talking to this device.</param>
        /// <param name="oidTable">The OID lookup table for the device.</param>
        /// <param name="osVersion">The SW version of the device.</param>
        /// <param name="model">The device's model name. Shall be the same name as used for the device name during OID database lookups.</param>
        /// <param name="options">The options to use.</param>
        /// <returns>The generated device handler.</returns>
        protected IDeviceHandler GetHandlerViaReflection(string handlerClassName, ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidTable, SemanticVersion osVersion, string model, IQuerierOptions options)
        {
            var type = Type.GetType($"SnmpAbstraction.{handlerClassName}");

            if (type == null)
            {
                var ex = new HamnetSnmpException($"{lowerLayer.Address} ({model} v {osVersion}): Cannot find a DeviceHandler implementation of name '{handlerClassName}'", lowerLayer.Address?.ToString());
                this.CollectException("Missing handler class name", ex);
                throw ex;
            }

            object myObject = null;

            try
            {
                myObject = Activator.CreateInstance(type, lowerLayer, oidTable, osVersion, model, options);
            }
            catch (Exception ex)
            {
                this.CollectException($"Instantiate handler class '{type.FullName}'", ex);

                throw new HamnetSnmpException($"{lowerLayer.Address} ({model} v {osVersion}): Exception while instantiating DeviceHandler of name '{handlerClassName}': {ex.Message}", ex, lowerLayer.Address?.ToString());
            }

            IDeviceHandler castedHandler = myObject as IDeviceHandler;

            if (castedHandler == null)
            {
                var ex = new HamnetSnmpException($"{lowerLayer.Address} ({model} v {osVersion}): Instantiating DeviceHandler of name '{handlerClassName}' is NOT an IDeviceHandler", lowerLayer.Address?.ToString());
                this.CollectException($"Cast handler class '{type.FullName}' to IDeviceHandler", ex);
                throw ex;
            }

            return(castedHandler);
        }
Пример #20
0
        /// <inheritdoc />
        public override IDeviceHandler CreateHandler(ISnmpLowerLayer lowerLayer, IQuerierOptions options)
        {
            if (!this.detectionId.HasValue)
            {
                var ex = new InvalidOperationException("Cannot perform CreateHandler() without previous and successful call to IsApplicable");
                this.CollectException("UbntSnmp: CreateHandler(ISnmpLowerLayer, IQuerierOptions)", ex);
                throw ex;
            }

            try
            {
                List <Oid> queryList = new List <Oid>();

                Oid osVersionOid = null;
                if (string.IsNullOrWhiteSpace(this.osDetectedVersion))
                {
                    osVersionOid = OsVersionRootOid + new Oid(new uint[] { this.detectionId.Value });
                    queryList.Add(osVersionOid);
                }

                Oid modelOid = null;
                if (string.IsNullOrWhiteSpace(this.detectedModel))
                {
                    modelOid = ModelRootOid + new Oid(new uint[] { this.detectionId.Value });
                    queryList.Add(modelOid);
                }

                VbCollection osVersionCollection = null;
                if (queryList.Count > 0)
                {
                    osVersionCollection = lowerLayer.Query(queryList);
                }

                string osVersionString = (osVersionOid != null)
                    ? osVersionCollection[osVersionOid].Value.ToString()
                    : this.osDetectedVersion;

                Match           match     = OsVersionExtractionRegex.Match(osVersionString);
                SemanticVersion osVersion = match.Success ? match.Groups[1].Value.ToSemanticVersion() : null;

                string model = (modelOid != null)
                    ? osVersionCollection[modelOid].Value.ToString()
                    : this.detectedModel;

                if (string.IsNullOrWhiteSpace(model))
                {
                    var info = $"Model (retrieved using OID '{modelOid}') is null, empty or white-space-only";
                    log.Warn(info);
                    var ex = new HamnetSnmpException(info, lowerLayer?.Address?.ToString());
                    this.CollectException("UbntSnmp: No model", ex);
                    throw ex;
                }

                log.Info($"Detected device '{lowerLayer.Address}' as Ubiquiti '{model}' v '{osVersion}'");

                DeviceVersion            deviceVersion;
                IDeviceSpecificOidLookup oidTable = this.ObtainOidTable(model.Trim(), osVersion, out deviceVersion, lowerLayer?.Address);
                if (string.IsNullOrWhiteSpace(deviceVersion.HandlerClassName))
                {
                    return((model == AirFiberFakeModelString)
                        ? new UbiquitiAirFiberDeviceHandler(lowerLayer, oidTable, osVersion, model, options) as IDeviceHandler
                        : new UbiquitiAirOsAbove56DeviceHandler(lowerLayer, oidTable, osVersion, model, options) as IDeviceHandler);
                }
                else
                {
                    return(this.GetHandlerViaReflection(deviceVersion.HandlerClassName, lowerLayer, oidTable, osVersion, model, options));
                }
            }
            catch (Exception ex)
            {
                this.CollectException("UbntSnmp: Model detection and OID lookup", ex);

                // we want to catch and nest the exception here as the APIs involved are not able to append the infomration for which
                // device (i.e. IP address) the exception is for
                throw new HamnetSnmpException($"Failed to create handler for Ubiquiti device '{lowerLayer.Address}': {ex.Message}", ex, lowerLayer?.Address?.ToString());
            }
        }
Пример #21
0
 /// <summary>
 /// Allow overriding of instanatiation of the actual interface detail implementation.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="interfaceId">The interface ID.</param>
 /// <returns>The instantiated interface details container.</returns>
 /// <remarks>Alternatively inheriting classes can choose to right away override the complete interface list retrieval
 /// by implementing <see cref="RetrieveInterfaceDetails" /></remarks>.
 protected virtual IInterfaceDetail InstantiateInterfaceDetail(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup, int interfaceId)
 {
     return(new LazyLoadingGenericInterfaceDetail(this.LowerSnmpLayer, this.OidLookup, interfaceId));
 }
Пример #22
0
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 public LazyLoadingGenericInterfaceDetails(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup)
     : base(lowerSnmpLayer)
 {
     this.OidLookup = oidLookup;
 }
Пример #23
0
 /// <summary>
 /// Constructs for the given lower layer.
 /// </summary>
 /// <param name="lowerLayer">The lower layer for talking to this device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <param name="osVersion">The SW version of the device.</param>
 /// <param name="model">The device's model name. Shall be the same name as used for the device name during OID database lookups.</param>
 /// <param name="options">The options to use.</param>
 public GenericDeviceHandler(ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidLookup, SemanticVersion osVersion, string model, IQuerierOptions options)
     : base(lowerLayer, oidLookup, osVersion, model, options)
 {
 }
Пример #24
0
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 public LazyLoadingAlixInterfaceDetails(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup)
     : base(lowerSnmpLayer, oidLookup)
 {
 }
Пример #25
0
 /// <summary>
 /// Allows deriving class to retrieve and return their implementation of <see cref="IWirelessPeerInfos" />.
 /// </summary>
 /// <param name="lowerLayer">The lower layer for talking to this device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 /// <returns>The retrieved interface details.</returns>
 protected abstract IWirelessPeerInfos RetrieveWirelessPeerInfos(ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidLookup);
Пример #26
0
 /// <inheritdoc />
 protected override IInterfaceDetail InstantiateInterfaceDetail(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup, int interfaceId)
 {
     return(new LazyLoadingAlixInterfaceDetail(this.LowerSnmpLayer, this.OidLookup, interfaceId, new string[] { "WLAN" }));
 }
Пример #27
0
 /// <inheritdoc />
 protected override IInterfaceDetails RetrieveDeviceInterfaceDetails(ISnmpLowerLayer lowerLayer, IDeviceSpecificOidLookup oidLookup)
 {
     return(new LazyLoadingAlixInterfaceDetails(this.LowerLayer, this.OidLookup));
 }
Пример #28
0
 /// <summary>
 /// Construct taking the lower layer to use for lazy-querying the data.
 /// </summary>
 /// <param name="lowerSnmpLayer">The communication layer to use for talking to the device.</param>
 /// <param name="oidLookup">The OID lookup table for the device.</param>
 public LazyLoadingUbiquitiAirFiberWirelessPeerInfos(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup)
     : base(lowerSnmpLayer, oidLookup)
 {
 }
Пример #29
0
        /// <summary>
        /// Tries to obtain the oid lookup table given lookup ID.
        /// </summary>
        /// <param name="context">The device database context to extend.</param>
        /// <param name="oidLookupId">The OID mapping lookup ID to get.</param>
        /// <param name="maximumSupportedSnmpVersion">The maximum supported SNMP version (to put into returned lookup)</param>
        /// <param name="oidLookup">Returns the OID lookup, if found.</param>
        /// <returns><c>true</c> if a lookup of the given lookup ID has been found and the ID returned. Otherwise <c>false</c>.</returns>
        public static bool TryFindDeviceSpecificOidLookup(this DeviceDatabaseContext context, int oidLookupId, SnmpVersion maximumSupportedSnmpVersion, out IDeviceSpecificOidLookup oidLookup)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context), "The context to search OID lookup is null");
            }

            oidLookup = null;

            var result = context.DeviceSpecificOids.Where(d => d.OidMappingId == oidLookupId);

            if (!result.Any())
            {
                return(false);
            }

            oidLookup = new DeviceSpecificOidLookup(result, maximumSupportedSnmpVersion);

            return(true);
        }
 /// <inheritdoc />
 protected override IInterfaceDetail InstantiateInterfaceDetail(ISnmpLowerLayer lowerSnmpLayer, IDeviceSpecificOidLookup oidLookup, int interfaceId)
 {
     return(new LazyLoadingUbiquitiInterfaceDetail(this.LowerSnmpLayer, this.OidLookup, interfaceId, new string[] { "WIFI", "ATH", "AIR", "ETH" }));
 }