将 SNMP ASN.1 映射到 C++ 数据类型

Mapping SNMP ASN.1 to C++ Datatypes

我正在将 SNMP EtherLike MIB 变量添加到我们现有的 SNMP C++ 代码库中,这是我第一次这样做。

我面临的困难是理解 MIB 变量的数据类型并将其映射到 C++ 数据类型 - 例如 dot3StatsIndex MIB 变量语法是 InterfaceIndex 那么它在 C++ 中的等效数据类型是什么。

由于我是第一次实施或者说处于学习阶段 - 请让我知道有哪些不同的 ASN.1 数据类型以及这些类型是否都在上面列出以及它们如何映射到 C++ 数据类型?

还有如何从 RFC 中导出 MIB 变量的数据类型?

我认为如果你只是遵循类型继承链,你最终会得到一个基本的 SNMP 类型,它应该映射到你拥有的类型。

对于 InterfaceIndex,查看它是从哪个 MIB 导入的(它是 IF-MIB):

IMPORTS
    MODULE-IDENTITY, OBJECT-TYPE, OBJECT-IDENTITY,
    Integer32, Counter32, Counter64, mib-2, transmission
        FROM SNMPv2-SMI
    MODULE-COMPLIANCE, OBJECT-GROUP
        FROM SNMPv2-CONF
    TruthValue
        FROM SNMPv2-TC
    ifIndex, InterfaceIndex
        FROM IF-MIB;

然后找到它的定义,它应该引用一个基本类型(它是 Integer32,可能映射到 ASN1_INT)。

InterfaceIndex ::= TEXTUAL-CONVENTION
    DISPLAY-HINT "d"
    STATUS       current
    DESCRIPTION
        "A unique value, greater than zero, for each interface or ...
        network management system to the next re-initialization."
    SYNTAX       Integer32 (1..2147483647)

在我的 C++ SNMP 代理中,我写了类似下面的内容(不幸的是,实际的源代码不再对我可用,我相信还有更多的选择,但你明白了):

using varbind_val_t = std::variant<
   
   // ASN.1 INTEGER, SMIv2 Integer32
   int32_t,
   
   // ASN.1 OCTET STRING
   std::string,
   
   // ASN.1 OBJECT IDENTIFIER
   oid_t,
   
   // RFC4001 InetAddressType (TextualConvention)
   IpAddress::Type, // enum saying IPv4 or IPv6
   
   // RFC4001 InetAddress (TextualConvention)
   IpAddress,       // can be an IPv4 or IPv6 address
   
   // SMIv2 IpAddress
   ipv4_t,
   
   // ASN.1 MacAddress (TextualConvention)
   mac_address_t,
   
   // SMIv2 Counter32/Gauge32/TimeTicks/Unsigned32
   uint32_t,
   
   // SMIv2 Counter64
   uint64_t
>;

在构建或接收 PDU 时,此变体的相关访问者将根据上面给出的 C++ 类型的值对给定值的有线表示进行编码或解码。有时这是一个非常薄的包装器(整数就是整数!),有时它需要更多的工作(oid_t 需要展开)。这是非常快速和灵活的。关键是映射完全取决于您——尝试选择具有相同可能值范围的类型,否则您可能会在途中某处丢失信息。但是没有 C++ 类型到 ASN.1 或 SMIv2 类型的“the”映射。

InterfaceIndex这样的任何文本约定都不是真正的类型,而是SNMP管理器关于如何表示特定字段的线索。对于那些没有包含在上面列表中的特殊情况,我只是使用了实际的底层类型,在这种情况下,如 Ilya 所示,Integer32。您可以阅读 MIB 来了解这些事情的真正含义(或者使用像 iReasoning 这样的管理器,它可以很好地告诉您)。

您应该参考相关规范来确定您需要支持的类型: