SNMP协议 PDU报文格式分析(BER编码)

 

关于SNMP的GetNextRequest PDU实现分析:



SNMPv1的标准文档RFC1157中对GetNextRequest PDU的应用列举了一个表格遍历的例子。因为第一次搞这个东西,初看那个例子时弄得我晕圈了。搞不明白GetNextRequest PDU该如何实现。

现在初步对那个例子有了点认识,记录下来,以免日后遗忘。不当之处请指正。


下面是SNMP协议文档RFC1157中4.1.3.1中的例子。

GetNextRequest PDU的最重要的功能是表的遍历,这种操作受到了前面所说的管理变量的表示方法的支持,从而可以访问一组相关的变量,就好象他们在一个表内。

       下面通过一个例子解释表遍历的过程:

被管设备维护如下路由表:

         Destination                     NextHop         Metric

         10.0.0.99                       89.1.1.42       5

         9.1.2.3                           99.0.0.3        3

         10.0.0.51                       89.1.1.42       5

       假设网管站欲取得这张路由表的信息,该表的索引是目的网络地址。

       网管站向被管设备发送一个GetNextRequest PDU,其中的受管对象的标识如下

       GetNextRequest ( ipRouteDest, ipRouteNextHop, ipRouteMetric1 )

       SNMP agent响应如下GetResponse PDU:

GetResponse (( ipRouteDest.9.1.2.3 =  "9.1.2.3" ),

                         ( ipRouteNextHop.9.1.2.3 = "99.0.0.3" ),

                         ( ipRouteMetric1.9.1.2.3 = 3 ))

说明:这里的响应初看就懵了。开始就是没明白( ipRouteDest.9.1.2.3 =  "9.1.2.3" )是什么意思。其实他的意思是,代理向管理站回复时,回复了一个对象ID是ipRouteDest.9.1.2.3,value是"9.1.2.3"的对象。这样以来,管理站下一个GetNextRequest 报文中必然会包含ID是ipRouteDest.9.1.2.3的对象。

对于ipRouteDest.9.1.2.3这个ID是可以根据情况自己设计,不一定要使用这种方式。而代理要做的就是要对ipRouteDest对象做特殊处理,要根据ipRouteDest.9.1.2.3中“9.1.2.3”去查下一条记录。

       网管站继续:

       GetNextRequest ( ipRouteDest.9.1.2.3,

                         ipRouteNextHop.9.1.2.3,

ipRouteMetric1.9.1.2.3 )

    agent响应:

       GetResponse (( ipRouteDest.10.0.0.51 = "10.0.0.51" ),

                         ( ipRouteNextHop.10.0.0.51 = "89.1.1.42" ),

                         ( ipRouteMetric1.10.0.0.51 = 5 ))

  值得注意的是agent必须能够确定下一个管理变量名,以保证所有变量能被取到且只被取到一次。

       网管站继续:

                        GetNextRequest ( ipRouteDest.10.0.0.51,

                         ipRouteNextHop.10.0.0.51,

                         ipRouteMetric1.10.0.0.51 )

 agent 响应:

       GetResponse (( ipRouteDest.10.0.0.99 = "10.0.0.99" ),

                         ( ipRouteNextHop.10.0.0.99 = "89.1.1.42" ),

                         ( ipRouteMetric1.10.0.0.99 = 5 ))

网管站继续

    GetNextRequest ( ipRouteDest.10.0.0.99,

                         ipRouteNextHop.10.0.0.99,

                         ipRouteMetric1.10.0.0.99 )

这时因为路由表中所有的行都被取遍,agent因返回路由表对象的下一字典后继即该管理对象在MIB树中的后序遍历的直接后继。这里应是nettoMediaIndex,管理对象的OBJECT IDENTIFIER。这个响应通知网管站对表的遍历已经完成。


再说一下“索引”的问题吧!

开始给出的路由表是

Destination                     NextHop         Metric

         10.0.0.99                       89.1.1.42       5

         9.1.2.3                           99.0.0.3        3

         10.0.0.51                       89.1.1.42       5


但是后来遍历时,第一个怎么是从9.1.2.3开始呢?其实上面的表或许只是随便这么一写。从代理应答的过程来看,这个表在程序真正的存储顺序应该是:

9.1.2.3--》10.0.0.51---》10.0.0.99.

哎呀,真不好意思。希望你不是像我这么笨。




简单网络管理协议(SNMP)是目前在计算机网络中用得最广泛的网络管理协议,它使用ASN.1(Abstract Syntax Notation One)来定义SNMP报文格式和MIB(Management Information Base)变量的名称。


ASN.1是一种描述数据和数据特征的正式语言,它和数据的存储及编码无关。根据ASN.1标准定义,数据类型分为:简单数据类型: booleannullintegerrealocterstringobject identifieripaddresstime ticks等。构造数据类型:sequencesequence of setset ofchoice等。构造数据类型提供一种或多种简单数据类型进行复合的方法。

基本编码规则BER

在具体系统中,我们需要用具体的编码规则将ASN.1语法表示的抽象数据转换成具体的比特流。

SNMP使用的编码方法是BER(Basic Encoding Rule)BER的数据都由三个域构成:标识域(tag)+

度域(length)+值域(value)

标识域

标识域指明数据的类型,占用1个字节,常见的

类型有:

BOOL(0x01);

INT(0x02);

OCTSTR(0x04);

NULL(0x05);

OBJID(0x06);

ENUM(0x0A);

SEQ(0x30);

SETOF(0x31);

IPADDR (0x40);

COUNTER (0x41);

GAUGE(0x42);

TIMETICKS(0x43);

OPAQUE(0x44);

GET(0xA0);

GETNEXT(0xA1);

GETResp(0xA2);

SET(0xA3);

TRAP(0xA4);

长度域

长度域指明值域的长度,不定长,一般为一到三个字节。其格式可分为短格式和长格式.长度域采用短/长指示器(Short/Long Form)来标明长度指示符是否是单个字节,指示器在bit8上。如果短/长指示器是0,则为短限定格式,7位包含的就是数据的长度值,长度值在0127之间;如果短/长指示器是1,则为长限定格式,其低7位的值表示后面紧跟的长度指示值的字节数,而后续字节拼接起来的值就是数据字段的长度,即数据长度。

:

length30 => 1E 

length169 => 81 A9 

length1500 => 82 05 DC

值域

值域保存的是数据的实际编码。虽然ASN.1定义了很多数据类型,但大多数类型可由整形、对象标

识、空、串等基本数据类型和sequence构造类型表示。例如有符号整数和无符号整数、TimeTicksGaugeCounter统一用整数表示。

整型Integer

integer::=0x02 length {byte}* (*表示重复)

整型数据值域用补码表示,去掉多余的零(正数)或一(负数)。值域最高位为符号位。例:

1500 => 02 02 05 DC

-1500 => 02 02 FA 24

对象标识ObjectID

SNMP服务器维护的所有管理信息库(MIB)对象采用ObjectID表示,,1.3.6.1.2.1.1.1表示MIB

中的设备描述SysDesc变量,其编码规则如下:

objectID::=0x06 length {subidentifier}*  (1)

subidentifier::={leadingbyte}* lastbyte (2)

leadingbyte::=1 7bitvalue (3)

lastbyte::=0 7bitvalue (4)

首两个ID被合并为一个字节X*40+Y (5)

虽然规则很多,但由于大多数子对象标识在0~127,只需按规则(1)(5)即可;当子对象标识大于127,则按规则(2)(3)(4)将其分解为多个字节,最后一个字节的高位为零,其余字节的高位为一。

:1.3.6.1.810.1,根据规则(5),首两个子对象

标识1.3被合并为2B(1*40+3=43);子对象标识810超过127 ,根据规则(2)(3)(4)将其拆分为两个

字节86 2A(810=11 0010 1010 ==> 1000 0110 00101010);整个MIB被编码为:0x06 0x06 0x2b 0x06 0x010x86 0x2a 0x01

sequence组合类型

sequence::=0x30 length {asndata}*

:30 05 02 01 10 05 00表示一个sequence结构,内含两个成员,其中一个为整型,另一个为空类型(NULL)

其它类型

null::=0x05 0x00

string::=0x04 length {byte}*

SNMP报文

SNMP报文格式

SNMP共有五种报文,分别为Get_Request(0xA0)Get_Next_Request(0xA1)Get_Response(0xA2)Set_Request(0xA3)Trap(0xA4),其结构如下:


SNMP_Message::=SEQUENCE{version Integer,community OcterString, pdu SNMP_PDUs}

SNMP_PDUs::=CHOICE{get_request PDU,get_next_request PDU,get_response PDU,set_request PDU,trap TrapPDU}

PDU::=SEQUENCE{request-id Integer,error-status Integer,error index Integer,variable-bindings VarBindList}

TrapPDU∷=SEQUENCE{enterprise ObjectID,agent_addr IPAddr, trap_type Integer, specific_type Integer,time TimeTicks, variable-bindings VarBindList}

你可能感兴趣的:(SNMP协议 PDU报文格式分析(BER编码))