2

我正在为我们的一个 C# 应用程序编写一个代理,该应用程序使用 SharpSnmpLib 通过 SNMP GET 公开各种应用程序属性,过去我已经成功地发送了陷阱并检索了 GET。我能够公开单个属性,但我无法弄清楚如何在我的应用程序中定义一个表。

该表应该为我的应用程序中的流概念的每个实例公开一组 GET 参数(流的数量在启动时是固定的),每个流应该表示为表中的一行。

在 MIB 中定义它很容易,而且我过去已经使用 C++ 库成功定义和实现了这样的表,所以我知道这是可能的。

以下是我在 MIB 中定义应用程序版本的简单 GET 的方式:

dtStream      OBJECT IDENTIFIER ::= {dtApps 3}

dtVersion OBJECT-TYPE
    SYNTAX      DisplayString
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "The version number of the application"
    ::= {dtStream 1}

在代码中:

public class StringVar : ScalarObject
{
    private ISnmpData _data;
    private string _value;
    public StringVar(ObjectIdentifier oid, string value) : base(oid)
    {
        Value = value;
    }
    public override ISnmpData Data
    {
        get { return _data; }
        set { throw new AccessFailureException(); }
    }
    public string Value
    {
        set { _data = new OctetString(_value = value); }
        get { return _value; }
    }
}
...
ObjectStore os = new ObjectStore();
os.Add(Version = new StringVar(OID_STREAM_VERSION, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()));

这是我正在尝试创建的表的示例 MIB 定义:

dtStreamTable OBJECT-TYPE
    SYNTAX      SEQUENCE OF DtStreamEntry
    MAX-ACCESS  not-accessible
    STATUS      current
    DESCRIPTION
        "Statistics on the status and performance of the streams"
    ::= {dtStream 5}

DtStreamEntry OBJECT-TYPE
    SYNTAX      DtStreamEntry
    MAX-ACCESS  not-accessible
    STATUS      current
    DESCRIPTION
        "Status of a particular stream."
    INDEX       {dtStreamID}
    ::= {dtStreamTable 1}

DtStreamEntry ::= SEQUENCE {
    dtmStreamID           Integer32,
    dtStreamName          DisplayString
    dtStreamHost          DisplayString
    dtStreamType          Integer32
}

dtStreamID OBJECT-TYPE
    SYNTAX      Integer32 (0..255)
    MAX-ACCESS  not-accessible
    STATUS      current
    DESCRIPTION
        "Index of the stream entry in the table."
    ::= {DtStreamEntry 1}

dtStreamName OBJECT-TYPE
    SYNTAX      DisplayString
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "Name of the stream."
    ::= {DtStreamEntry 2}

dtStreamHost OBJECT-TYPE
    SYNTAX      DisplayString
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "Hostname that the stream is connected to."
    ::= {DtStreamEntry 3}

dtStreamType OBJECT-TYPE
    SYNTAX      Integer32(1..2)
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "Type of stream"
    ::= {DtStreamEntry 4}

在 iReasoning MIB 浏览器中看起来像这样:

截屏

我已经将我认为是“行”的内容定义为派生自的类TableObject

    class StreamEntry : TableObject
    {
        private readonly IList<ScalarObject> _elements = new List<ScalarObject>();

        public StreamEntry(int id, string name, string host, int type) 
            : base()
        {
            _elements.Add(StreamId = new IntVar(OID_STREAM_ID, id));
            _elements.Add(Name = new StringVar(OID_STREAM_NAME, name));
            _elements.Add(Host = new StringVar(OID_STREAM_HOST, host));
            _elements.Add(Type = new IntVar(OID_STREAM_TYPE, type));
        }

        public IntVar StreamId { get; private set; }
        public StringVar Name { get; private set; }
        public StringVar Host { get; private set; }
        public IntVar Type { get; private set; }

        protected override IEnumerable<ScalarObject> Objects
        {
            get { return _elements; }
        }
    }

毕竟,我想我的问题是,如何将这些关联到一个表中,该表与表或条目的 OID 一起返回?

我尝试将多个StreamEntry对象添加到 ObjectStore:

foreach(Stream s in Streams)
{
    os.Add(new StreamEntry(s.ID, s.Name, s.HostName, s.Type));
}

有了这个,我只能检索第一个的数据(使用单独的 GET,或在 MIB 浏览器中的 dtStreamEntry 上 WALK)。

4

1 回答 1

1

好的,我想通了。所有都ScalarObjects需要添加到ObjectStoreOID 顺序中 - 否则一切都会中断。

因此,我需要在派生自的封闭对象中创建多个StreamEntry对象(不再TableObject作为基类),并且我需要从每个对象中提取并按 OID 对它们进行排序,然后再将它们作为 Objects 集合覆盖返回。StreamTableTableObjectScalarObjectsStreamEntry

我现在有一个有效的 SNMP 表。:)

于 2014-10-15T12:25:28.747 回答