将 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 这样的管理器,它可以很好地告诉您)。
您应该参考相关规范来确定您需要支持的类型:
我正在将 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 这样的管理器,它可以很好地告诉您)。
您应该参考相关规范来确定您需要支持的类型: