SNMP定义了在客户和服务器之间交换的SNMP报文的语法和语义。它使用ASN.1(抽象语言 Abstract Syntax Notation One)来定义SNMP报文格式和MIB变量的名称。因此与绝大多数UDP协议不同,SNMP报文不含固定字段,也不能用固定的结构来定义。
抽象语法记法ASN.1
在ISO/OSI参考模型中,应用层要求标识各种简单、复合的数据形式以及取自各种字符集的字符串等比较复杂的用户数据。这就需要定义一个抽象语法记法,该记法规定类型的实例在传送中的标识规则(通过8bit位组序列)。
通过定义若干个简单类型和由简单类型复合而成的结构类型,在表示层用一致的形式来标识应用层的复杂多样的数据,便于异构系统间的通信,这种记法就叫作抽象语法记法(ASN.1)。ASN.1是一种描述数据和数据特征的正式语言,它和数据的存储及编码无关。
根据ASN.1标准定义,数据类型分为:
①简单数据类型:boolean、null、integer、real、octer、string、object identifier、ip address、time ticks等
②构造数据类型:sequence、sequence of set、set of choice等。
③构造数据类型提供一种或多种简单数据类型进行复合的方法。
基本编码规则BER
在具体系统中,需要用具体的编码规则将ASN.1语法标识的抽象数据转换成具体的比特流。SNMP使用的编码方法是BER(Basic Encoding Rule)。
BER的数据都由三个域构成:标识域(tag)+长度域(length)+值域(value)
1.标识域
标识域指明数据的类型,占用一个字节,常见类型:
类型 | 字节表示 |
---|---|
BOOL | 0x01 |
OCTSTR | 0x04 |
OBJID | 0x06 |
SEQ | 0X30 |
IPADDR | 0x40 |
GAUGE | 0x42 |
OPAQUE | 0x44 |
INT | 0x02 |
NULL | 0x05 |
ENUM | 0x0A |
SETOF | 0x31 |
COUNTER | 0x41 |
TIMETICKS | 0x43 |
2.长度域
长度域指明值域的长度,不定长,一般为1-3个字节。其格式分为短格式和长格式:
3.值域
值域保存的是数据的实际编码。虽然ASN.1定义了很多数据类型,但大多数类型可由整型、对象标识、空、串等基本数据类型和sequence构造类型标识。例如:有符号整数和无符号整数、Time Ticks、Gauge、Counter统一用整数表示。
(1)整型 Integer
integer::=0x02 length {byte} * (表示重复)
整型数据值域用补码表示,去掉多余的0(正数)或1(负数)。值域最高位为符号位。
(2)对象标识Object ID
SNMP服务器维护的所有管理信息库(MIB)对象采用Object ID
如:1.3.6.1.2.1.1.1表示MIB库中的设备描述SysDesc变量,其编码规则如下:
(1)objectID : : = 0x06 length {subidentifier} *
(2)subidentifier : : = {leadingbyte} * lastbyte
(3)leadingbyte : : = 1 7 bitvalue
(4)lastbyte : : = 0 7 bitvalue
(5)首两个ID被合并为一个字节X40 + Y
虽然规则很多,但由于大多数子对象标识在0~127,只需按规则(1)(5)即可;
当子对象标识大于127,则按规则(2)(3)(4)将其分解为多个字节,最后一个字节的最高位为0,其余字节的高位为1。
如: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。
(3)sequence组合类型
sequence::=0x30 length {asndata} *
如 :30 05 02 01 10 05 00 表示一个sequence结构,内含两个成员,其中一个为整型,另一个为空类型(NULL)。
(4)其他类型
null::=0x05 0x00
string::=0x04 length {byte} *
SNMP报文
SNMP共有5种报文,分别为:Get_Request(0xA0)、Get_Next_Request(0xA1)、Get_Response (0xA2)、Set_Request (0xA3)和Trap(0xA4),结构如下:
SNMP_Message::=SEQUENCE{version Integer,community Octer-String ,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}