1、引言
基于TCP/IP的网络管理包含3个组成部分:
1) 一个管理信息库MIB(Management Information Base)。管理信息库包含所有代理进程的所有可被查询和修改的参数。RFC 1213[McCloghrie and Rose 1991]定义了第二版的MIB,叫做MIB-II。
2) 关于MIB的一套公用的结构和表示符号。叫做管理信息结构SMI(Structure of Management Information)。这个在RFC 1155 [Rose and McCloghrie 1990] 中定义。例如:SMI定义计数器是一个非负整数,它的计数范围是 0~4294967295,当达到最大值时,又从0开始计数。
3) 管理进程和代理进程之间的通信协议,叫做简单网络管理协议SNMP(Simple Network Management Protocol)。在RFC 1157 [Case et al. 1990]中定义。SNMP包括数据报交换的格式等。尽管可以在传输层采用各种各样的协议,但是在SNMP中,用得最多的协议还是UDP。
2、SNMP协议概述
简单网络管理协议(SNMP:Simple Network Management Protocol)是由互联网工程任务组(IETF:Internet Engineering Task Force )定义的一套网络管理协议。该协议基于简单网关监视协议(SGMP:Simple Gateway Monitor Protocol)。利用SNMP,一个管理工作站可以远程管理所有支持这种协议的网络设备,包括监视网络状态、修改网络设备配置、接收网络事件警告等。 虽然SNMP开始是面向基于IP的网络管理,但作为一个工业标准也被成功用于电话网络管理。
http://www.fjzzled.com/hzjdyyyyjs/95.html
http://www.fjzzled.com/hzjdyyyyjs/94.html
http://www.sjys365.com/smzl/2999.html
http://www.sjys365.com/smzl/2998.html
3、SNMP的发展史
SNMP经过了一个相对较长的发展过程,到目前为止一共经历了三个版本。当下使用最广泛是SNMPv2。
l 1989年发布了第一个版本的SNMP,称为SNMPv1。
l 1991年发布SNMP的一个补充---RMON(Remote Network Monitoring,远程网络监视)。RMON扩充了SNMP的功能,包括对LAN的管理以及对依附于这些网络设备的管理。注:RMON没有修改和增加SNMP协议本身以及SMI,只是增加了SNMP监视子网的能力,把整个子网当成一个个体来监视,提供了新的MIB库及相关的MIB行为。
l 1993年SNMPv1的升级版被提出,SNMPv2。
l 1995年SNMPv2正式发布,v2增加了SNMPv1的功能,并规定了如何在基于OSI的网络中使用SNMP。同时RMON于本年度扩展为RMONv2
l 1998年SNMPv3发布,一系列文档定义了SNMP的安全性,并定义了将来改进的总体结构。SNMPv3可以和v2、v1一起使用。
4、SNMP的工作原理
SNMP采用特殊的客户机/服务器模式,即代理/管理站模型。对网络的管理与维护是通过管理工作站与SNMP代理间的交互工作完成的。每个SNMP从代理负责回答SNMP管理工作站(主代理)关于MIB定义信息的各种查询。
SNMP的应用场景如图1所示:
管理站和代理端使用MIB进行接口统一,MIB定义了设备中的被管理对象。管理站和代理都实现相应的MIB对象,使得双方可以识别对方的数据,实现通信。管理站向代理请求MIB中定义的数据,代理端识别后,将管理设备提供的相关状态或参数等数据转换成MIB定义的格式,最后将该信息返回给管理站,完成一次管理操作。
5、SNMP的报文类型
SNMP中定义了五种消息类型:Get-Request、Get-Response、Get-Next-Request、Set-Request和Trap 。
(1)Get-Request 、Get-Next-Request与Get-Response
SNMP 管理站用Get-Request消息从拥有SNMP代理的网络设备中检索信息,而SNMP代理则用Get-Response消息响应。Get-Next- Request用于和Get-Request组合起来查询特定的表对象中的列元素。
(2)Set-Request
SNMP管理站用Set-Request 可以对网络设备进行远程配置(包括设备名、设备属性、删除设备或使某一个设备属性有效/无效等)。
(3)Trap
SNMP代理使用Trap向SNMP管理站发送非请求消息,一般用于描述某一事件的发生,如接口UP/DOWN,IP地址更改等。
上面五种消息中Get-Request、Get-Next-Request和Set-Request是由管理站发送到代理侧的161端口的;后面两种Get-Response和Trap 是由代理进程发给管理进程的,其中Trap消息被发送到管理进程的162端口,所有数据都是走UDP封装。SNMP工作流程如图2:
6、SNMP的报文格式
SNMP代理和管理站通过SNMP协议中的标准消息进行通信,每个消息都是一个单独的数据报。SNMP使用UDP(用户数据报协议)作为第四层协议(传输协议),进行无连接操作。SNMP消息报文包含两个部分:SNMP报头和协议数据单元PDU。
在实际网络传输环境下,SNMP报文的长度取决于其所采用的编码方式。SNMP统一采用BER(Basic Encoding Rule)的编码规则,同时在正式SNMP规范中使用的是ASN.1语法,Abastract Syntax Notation v1,即抽象语法描述语言。这两个概念在后面实践环节再做进一步介绍,这里只要稍微了解一下即可,不妨碍我们对协议本身的分析。这里我们简单解释一下BER编码规则:
BER作为ANS.1的基本编码规则,描述具体的ANS.1对象如何编码为比特流在网络上进行传输。BER编码规则由三部分组成:
SNMP中定义了几种基本的数据类型,其中v1和v2版有些改动,具体参见相应的RFC文档。这里我们只介绍几种最常见的类型:
l INTEGER:一个整数
l OCTER STRING: 0或多个8bit字节,每个字节在0~255之间取值
l DisplayString:0或多个8bit字节,每个字节必须是ASCII码。在MIB-II中,所有该类型变量不能超过255个字符(0个字符可以)
l NULL:代表相关的变量没有值
l IpAddress:4字节长的OCTER STRING,以网络字节序表示IP地址
l PhyAddress:6字节长的OCTER STRING,代表物理地址
l Counter:非负整数,可以从0递增到232-1()。达到最大值后归0
l TimeTicks:时间计数器,以0.01秒为单位递增,不同的变量可以有不同的递增幅度。所以在定义这种类型的变量时需要制定递增幅度
l SEQUENCE:与C语言中的结构体类似
l SEQUENCE OF:一个向量,参见后面ANS.1语法详细介绍章节
SNMP报文在传输层是封装在UDP报文中的,而UDP又是基于IP网络的,因此,我们可以得到完整的报文描述结构,如下图所示:
PDU类型其实包含两个字节,第一个字节表示真实的PDU的类型;第二个字节表示后面报文所占的字节总数。针对SNMPv1,这个字段取值如下:
表1 PDU类型
PDU类型 | 名 称 |
0 | get-request |
1 | get-next-request |
2 | get-response |
3 | set-request |
4 | trap |
也就是说,trap的类型是4。但是在数据报文中,该字段一般表示为ax,其中x取[0,4],即a0~a3表示相应的get、set等操作,a4表示trap报文。这里除了类型字段意外,其他字段均采用BER编码方式:
实战演练之报文格式分析
Trap报文格式和上述图5所展示的结构有些差别,这里我们只分析SNMPv1和SNMPv2的Trap报文格式。trap报文前面的部分都一样,区别在PDU协议数据单元部分。
SNMPv1 Trap报文
SNMPv1的Trap报文格式如下所示:
注意:除了PDU类型和PDU长度字段外,后面的每个字段都是BER编码方式。
trap类型”可以取以下值,其中0~6是已定义的特定trap,7及其以后的类型由供应商自定义。
表2 trap类型、名称及描述信息
trap类型 | 名称 | 描述信息 |
0 | coldStart | 代理进程对自己初始化 |
1 | warmStart | 代理进程对自己重新初始化 |
2 | linkDown | 一个接口已从工作状态变为故障状态(报文中的第一个变量标识此接口) |
3 | linkUp | 一个接口已从故障状态变为工作状态(报文中的第一个变量标识此接口) |
4 | authenticationFailure | 从SNMP管理进程收到无效共同体的报文 |
5 | egpNeighborLoss | 一个EGP邻站已变为故障状态(报文中的第一个变量包含邻站IP地址) |
6 | enterpriseSpecific | 在这个特定的代码段中查找trap信息 |
通过wireshark抓包工具,捕获一条如下的SNMP报文,接下来对其进行仔细分析。
SNMPv1原始报文内容:
00 23 5a 9e 58 b9 00 4c 41 49 50 55 08 00 45 00 00 48 00 00 40 00 40 11 a5 4e c0 a8 0a 01 c0 a8 0a 05 0c 00 00 a2 00 34 ff e0 30 2a02 01 00 04 06 70 75 62 6c 69 63 a4 1d 06 0a 2b 06 01 04 01 bf 08 03 02 0a 40 04 c0 a8 0a 01 02 01 00 02 01 00 43 01 0e 30 00
目的MAC:00 23 5a 9e 58 b9
源MAC:00 4c 41 49 50 55
协议类型:08 00 ,为IP数据报
IP头:45 00 00 48 00 00 40 00 40 11 a5 4e c0 a8 0a 01 c0 a8 0a 05 0c
UDP头:0c 00 00 a2 00 34 ff e0
其余部分都为SNMP报文,接下来我们对照前面的报文结构体来逐个分析一下。
n 30 表示SNMP消息是ASN.1的SEQUENCE类型;
n 2a 表示该SNMP报文的总长度是42(0x2a)个字节,该字段所表示的报文长度起始于它后面的第一个字节直到报文结束;
n 02 01 00 表示版本号,可见其确实为BER编码方式。02表示该字段是INTEGER类型;01表示该字段占1个字节;00表示版本号,该值为“版本号-1”;
n 04 06 70 75 62 6c 69 63 表示团体名,04表示该字段为OCTET STRING类型;06表示该字段占6个字节;70 75 62 6c 69 63 表示团体名的ANSII码的十六进制形式,这里是“public”;
n a4 1d 其中a4中的“4”表示这是一个trap报文,a4又叫报文的标签标记;1d表示后面还有29(0x1d)个字节的数据;
n 06 0a 2b 06 01 04 01 bf 08 03 02 0a 企业OID标识。06表示该字段是个对象标识符,OBJECT IDENTIFIER;0a表示该字段占10(0x0a)个字节;关于SNMP的OID的编码方式有些奇特:例如1.3.6.1.2…. 取前两个数字分别记为x和y。编码时40*x+y,这里x=1,y=3,因此结果为40*1+3=43,即表示十六进制的2b。因此,这里的企业OID编码即为1.3.6.1.4.1.8072.3.2.10;
n 40 04 c0 a8 0a 01 同样40表示该字段为OCTET STRING 类型;04表示IP地址占4个字节;IP地址为192.168.10.1;
n 02 01 00 其中00表示trap类型为coldStart;
n 02 01 00 其中00表示我们指定的trap即specific-trap也为coldStart类型;
n 43 01 0e 43表示为TimeTicks类型;01表示该字段占1个字节;0e即十进制的14表示时间标签为0.14秒,这里时间计数器以0.01秒递增;
n 30 00 30表示“键-值”值对的编码类型为SEQUENCE;00表示该字段占0个字节,即没有该字段。
SNMPv2 Trap报文
同样的,这里除了trap类型和报文长度是标准网络字节序之外,其余协议字段也均为BER编码方式。可以看到v2版的trap报文正在向统一的报文格式发展,已经非常类似普通的SNMP请求、响应报文了。
SNMPv2原始报文内容:
00 23 5a 9e 58 b9 00 4c 41 49 50 55 08 00 45 00 00 7b 00 00 40 00 40 11 a5 1b c0 a8 0a 01 c0 a8 0a 05 0c 01 00 a2 00 67 04 bb 30 5d02 01 01 04 06 70 75 62 6c 69 63 a7 50 02 04 17 73 2c fb 02 01 00 02 01 00 30 42 30 0d 06 08 2b 06 01 02 01 01 03 00 43 01 0e 30 1706 0a 2b 06 01 06 03 01 01 04 01 00 06 09 2b 06 01 06 03 01 01 05 01 30 18 06 0a 2b 06 01 06 03 01 01 04 03 00 06 0a 2b 06 01 04 01 bf 08 03 02 0a
目的MAC:00 23 5a 9e 58 b9
源MAC:00 4c 41 49 50 55
协议类型:08 00,IP报文
IP头:45 00 00 7b 00 00 40 00 40 11 a5 1b c0 a8 0a 01 c0 a8 0a 05
UDP头:0c 01 00 a2 00 67 04 bb
余下部分全为SNMP报文内容,这里我们做一下简单的约定:
xx 标注类型;xx 标注长度;xx 标注真正的数据。
这样一来上面这串原始数据就好分析多了J
n 30 5d 整个SNMP报文的编码方式为30,即SEQUENCE类型,报文长度93(0x5d)字节;
n 02 01 01 版本号01即v2版本;
n 04 06 70 75 62 6c 69 63 团体名70 75 62 6c 69 63 即英文的“public”;
n a7 50 a7表示trap类型为7,即厂商自定义trap;50表示PDU区段占80(0x50)字节;
n 02 04 17 73 2c fb 请求ID为17 73 2c fb 十进制的393424123;
n 02 01 00 错误状态0;
n 02 01 00 错误索引0;
n 30 42 “变量名-值”对编码类型30 即SEQUENCE类型;“变量名-值”所占总字节0x42,即66字节;
n 30 0d 06 08 2b 06 01 02 01 01 03 00 43 01 0e 第一个“名-值”对区段编码方式30 即SEQUENCE类型;第一个“名-值”对总长度0x0d,13字节;第一个变量名的编码类型0x06,时间标签;第一个变量名占0x08个字节;第一个变量名2b 06 01 02 01 01 03 00,为1.3.6.1.2.1.1.3.0;第一个变量值为0x0e,即14;
n 30 17 06 0a 2b 06 01 06 03 01 01 04 01 00 06 09 2b 06 01 06 03 01 01 05 01 第二个“名-值”对;变量名1.3.6.1.6.3.1.1.4.1.0;变量值1.3.6.1.6.3.1.1.5.1;
n 30 18 06 0a 2b 06 01 06 03 01 01 04 03 00 06 0a 2b 06 01 04 01 bf 08 03 02 0a 第三个“名-值”对;变量名1.3.6.1.6.3.1.1.4.3.0;变量值1.3.6.1.4.1.8072.3.2.10;
今天我们简单对SNMP协议做个入门普及,包括它的原理,应用场景报文格式等。下面的章节,我们将以开源net-snmp为例来向大家阐述多种代理开发流程和原理,以及要注意的问题,其中每种扩展mib的方式都对应不同的开发需求。
第二篇
管理信息库:MIB
我们要扩展mib首先必须清楚mib是如何定义的,用的什么语言,有哪些约定,遵循哪些规则等等。这些基本东西掌握过后,我们就可以很轻松的来写自己的mib文件了。
所谓管理信息库,或者MIB,就是所有代理进程包含的、并且能够被管理进程进行查询和设置的信息的集合,或者叫管理对象的集合,在RFC 1213 [McColghrie 和Rose 1991]中定义了MIB-II,即第二版的MIB库。MIB是采用SMI(RFC 1155)来定义的。SMI全称为Structure Management Information,管理信息结构。SMI规范定义了一个基本框架,使用框架内的规范可以定义MIB,而SMI同时又是ASN.1的一个子集,它主要约定了使用到的语法、类型、宏、数据格式等。
本节知识相对来说有些枯燥,但是没办法,如果你要看懂mib的定义文件,并且能很灵活自如的对其进行扩展,那么这些基础是必须夯实的。俗话说“磨刀不误砍柴工”。
ASN.1语法
ASN.1(Abstract Syntax Notification 1),抽象语法描述语言,是一种独立于机器的描述语言,用于描述在网络上传递的消息。在SNMP中ANS.1主要用于MIB的定义,另一方面也用于协议的定义。所以理解ASN.1是理解协议、读懂SNMP国际规范RFC、进行SNMP开发的前提。在SNMP开发中,不但要用ASN.1编写MIB文件,还要使用ASN.1中的BER进行编解码。
ASN.1 可分为两个部分:
l 语法规则:从数据类型、内容顺序或结构等方面来描述消息的内容
l 编码规则:如何编码、解码实际消息中的数据
语法部分用于对数据结构、类型、顺序进行描述。编码则将语法部分描述的数据进行编码,变为二进制比特流,以便在网络上传输,或反方向地将接收到的数据流进行解码。这使得编码流可以跨平台、跨设备进行传输。
ASN.1的记法规则,ASN.1的结构、类型和取值的表示方法和编程语言的表示法相似:
Ø 多个空格和空行都看作是一个空格。
Ø 注释用成对的连字符(--)在注释的每行开始处表示,或者将一对连字符用在注释的开始处和注释行结束的结尾处。
Ø 标识符(取值和字段的名称)、类型引用(类型的名称)和模块名称由大写字母、小写字母、数字和连字符组成。
Ø 标识符、类型引用或模块名以由大写字母开始。
Ø 内建类型都由大写字母组成。内建类型一般用作标准表示法提供的类型。
Octet(字节)表示一个8bit的无符号整数。bit8表示最高位,bit1标识最低位。下列元语用于定义ASN.1符号:
l BIT 类型和值用等宽字体表示。它通畅表示一个十六进制的字节值。
l n1 粗斜体表示变量
l [] 粗的方括号标示该值为可选项
l {} 粗的大括号表示一组相关项。
l | 粗体竖杠表示一组之中的内容可任选其一。
l … 粗体省略号表示重复出现
l = 粗体等号,用一个子项表示该项
1 ASN.1术语
1.抽象语法(Abstract Syntax)
l 描述通用数据结构
l 允许定义数据类型和值
2.数据类型(Data Type)
l 值的集合,可以是简单类型或结构类型可以对数据类型命名
3.编码(Encoding)
l 用于表示数据值的字节序列
4.编码规则(Encoding Rules)
l 给出从一种语法到另一种的映射方法
5.传输语法(Transfer Syntax)
l 位模式(Bits pattern):描述数据是在传输时是如何表示的
2 ASN.1模块定义
模块(module)是ASN.1规范中的基本构造块,定义一个名为modulereference的模块,其格式如下:
<modulereference> DEFINITIONS ::=
BEGIN
EXPORTS
IMPORTS
AssignmentList
END
其中:EXPORTS 这个模块中的定义可能被其他模块引入,用的比较少;IMPORTS 定义将要由其他模块引入的对象或子模块;AssignmentList 这个模块中将定义类型分配、值分配及宏定义。
3 ASN.1数据类型
1. 基本类型:
ASN.1语法中有六种基本类型,分别如下,基本已经做到见名知意了:
BOOLEAN,INTEGER,ENUMERATED,REAL,BIT STRING,OCTET STRING
2. 字符串类型(ISO10646-1的子集):
Ø NumericString (0-9,<space>)
Ø PrintableString (0-9,A-Z,a-z,<space>,<s[ecial>])
Ø VisibleString
Ø GraphicString
Ø UTF8String
Ø IA5String (ASCII)
3. 对象类型:
OBJECT IDENTIFIER
ObjectDescriptor:一个任意长的非负整数序列,用于标记对象(如算法等)
4. 其它类型:
NULL 空值
UTCTime: yymmdd hhmm[ss] <local offset from UTC>
GeneralizedTime:yyyymmdd hhmm[ss] <local offset from UTC>,强制始于2050年
4 ASN.1类型定义
ASN.1灵活之处在于,除了它内置的一些数据类型外,用户还可以自定义自己想要的任何类型,一般都是通过现有类型来组合来实现。
新类型定义的语法:<type name> ::= <type>
示例:
Counter ::= INTEGER
IpAddress ::= OCTET STRING
Months ::= ENUMERATED {
january (1), february (2), march (3), april (4), may (5), june (6),
july (7), august (8), september (9),october (10), november (11), december(12)
}
上面的定义过程中,INTEGER太常见了,就用Counter来作为它的一种别名,注意是一种,以后就可以用Counter来定义新变量了。同理,IpAddress就是OCTE STRING类型一种别名。
5 ASN.1子类型定义
子类型是在类型的定义基础上增加更明确限制条件,如设定新类型的取值范围,缺省值等等。
语法: <subtype name> ::= <type> (<constraint>)
示例:
Counter ::= INTEGER (0..65536)
IpAddress ::= OCTET STRING ( SIZE(4) )
Spring ::= Months (march | april | may)
Summer ::= Months (june | july | august )
SmallPrime ::= INTEGER ( 2 | 3 | 5 | 7 | 11 )
ExportKey ::= BIT STRING ( SIZE(40) )
这样定义过后,以后用Counter定义的任何变量都被限定大于0小于65536。IpAddress定义变量长度都是4字节,等等。
6 ASN.1赋值
赋值在MIB库文件中的定义是最常见的一部分。
语法:<value name> <type> ::= <value>
value name :由用户自定义,但一般最好不要重名;
type:就是前面ASN.1的内置数据类型,或用户自定义类型;
value:当然就是该变量的值,一般要和变量类型所限定的范围一致。
示例:
ipInReceives Counter ::= 2450
ipRouteMask IpAddress ::= ‘FFFFFF00’H
currentMonth Months ::= july
currentTime UTCTime ::= “030708094018+0800”
name VisibleString ::= “John”
married BOOLEAN ::= TRUE
faxMessage BIT STRING ::= ‘01100001101’B
internet OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) 1 }
private OBJECT IDENTIFIER ::= { internet 4 }
最后两种赋值格式,我们后面再讲。
7 ASN.1的结构体类型
l SEQUENCE 一个或多个类型的有序集合,类似于C语言中的struct 类型定义:
UserAccount ::= SEQUENCE {
username PrintableString,
password PrintableString,
accountNr INTEGER
}
赋值
myAccount UserAccount ::= {
username “tly”,
password “guesswhat”,
accountNr 2345
}
l SEQUENCE OF 0个或多个某个给定类型多次出现的有序集合,对应于C语言中的数组:
定义
MemberCountries ::= SEQUENCE OF PrintableString
AccountRegistry ::= SEQUENCE OF UserAccount
赋值
eastAsia MemberCountries ::= {
“China”, “Japan”, “Korean”, “DPR”
}
l SET 一个或多个类型的无序集合,类似于SEQUENCE,但其中的组件不考虑分量顺序:
定义
UserAccount ::= SET {
username [0] PrintableString,
password [1] PrintableString,
accountNr [2] INTEGER
}
赋值
myAccount UserAccount ::= {
accountNr 2345,
username “tly”,
password “guesswhat”
}
l SET OF 0个或多个某个给定类型多次出现的无序集合,每一分量(组件)类型必须相同,但不考虑顺序要求。
类型定义
Keywords ::= SET OF PrintableString
赋值
someASN1Keywords Keywords ::= {
“INTEGER”, “BOOLEAN”, “REAL”
}
l CHOICE 多个类型其中的一个,类似于C语言中的枚举型:
例如:
SimpleSyntax ::=
CHOICE{
number
INTEGER,
string
OCTER STRING,
object
OBJECT IDENTIFIER,
empty
NULL
}
SimpleSyntax可以是INTEGER、OCTER STRING、OBJECT IDENTIFIER、NULL中的一个类型的变量。上述结构类型允许有可选组件。可选组件可能有默认值。SNMP中使用到的结构类型包括SEQUENCE、SEQUENCE OF和CHOICE。
8 ANS.1标签类型
标签用于区分不同的类型,并且在结构类型SEQUENCE和SET中,组件类型可能引起混淆,可以为它们的组件(分量)指定Context-specific标签,清晰指示组件的类型。除了CHOICE和ANY外,每种ASN.1类型都有一个标签,由一个类和一个非负的标签数组成。标签值可以唯一区分ASN.1类型。也就是说,ASN.1类型的名字并不影响它的抽象含义,只有标签才有这个作用。
标签用在编码中,可以唯一地标示类型,便于编码。ASN.1提供了4中标签:
l Universal:标识ISO和ITU定义的类型,ASN.1定义的类型均有Universal值,该值在所有的程序里都一致。
l Application:应用程序自定义类型。本标识可以唯一地标识自定义类型。类型名在ASN.1中可以相同,所以Application就成为唯一标识自定义类型的方法。类型的含义由制定者自己定义。例如:
name ::=[APPLICATION 0] VisibleString
Name ::=[APPLICATION 1] SEQUENCE
{
givenname VisibleString,
initial VisibleString,
familiyName VisibleString
}
l Private:该类型的含义根据具体的企业而不同。Private标识不会被用在国际规范中。企业提供的程序一般经常使用application和context-specific标识。在特殊场合下,一个企业的技术规范想要扩展成为一个国际规范时,使用private标识在企业规范成为国际规范的过程中可以较好地保护该企业的规范。例如:
CompanyNumber ::=[PRIVATE 2] INTEGER
companyNumber CompanyNumber ::=5651
l Context-specific:专用于结构类型中。该类型的含义根据给定的结构类型而不同。对于SET和SEQUENCE,为了避免里面的组件混淆,一般情况下给予不同的Context-specific标签。如:
CustomerRecord ::=SET{
name [0] VisibleString
mailingAddress [1] VisibleString
accountNumber [2] INTEGER,
balanceDue [3] INTEGER -- in cents--
}
SET和CHOICE中的分量顺序可能不同,例如name和mailingAddress都拥有同样的类型VisibleString,且它们的顺序可能颠倒,如果不指定一个context-specific标签就不知道一个VisibleString类型的值究竟是赋给name还是mailingAddress的。使用标签值就可以区分开,标签0是name,标签1是mailingAddress。
9 宏定义
ASN.1提供一种用户可以将符号扩展为自己使用的或别人使用的符号的机制,这就允许设计者去扩展语言定义一个“对象”,比如定义一个调制解调器或定义一个交换机。这些对象有普通的ASN.1属性和条件属性,比如父母和物理位置等。例如一个一部的调制解调器可以以普通调制解调器作为父类,从父类处继承属性。使用ASN.1可以定义为:
mode ::=SEQUENCE{
speed INTEGER,
modulation IA5String,
manufacturer IA5String
}
一个宏定义可以被导入和导出。ASN.1中的宏模板为:
<macro name>MACRO ::=
BEGIN
TYPE NOTATION ::=<user-defined type notation>
VALUE NOTATION ::=<user-defined value notation>
<supporting syntxt>
END
下面是一个使用宏模板定义类型的例子:
ERROR MACRO ::=
BEGIN
TYPE NOTATION ::= Parameter
VALUE NOTATION ::=value(VALUE CHOICE
{
localValue INTEGER,
globalValue OBJECT INDENTIFIER
})
Parameter ::=“PARAMETER”NamedType | empty
NamedType ::=identifier type | type
END
PS:宏在1994年从ASN.1中移除,取而代之的是Information Object Class。2002年X.680和X.690系列标准中已经使用Information Object Class代替。SNMPv1在1990年发布,所以SNMPv1中使用ASN.1宏。而SNMPv2 SMI的RFC中明确指出,SNMPv2中使用1998版ASN.1,所以SNMPv2还是使用ASN.1中的宏定义管理对象和通告。
实战演练之MIB文件分析
请自己分析rfc-1303.mib、rfc1065-SMI.mib、rfc1155-SMI.mib、rfc1213-MIB.mib,以及SNMPv2-SMI.mib(rfc2578)、SNMPv2-TC.mib(rfc2579)和SNMPv2-TM.mib(rfc3417)。
本章内容理论性较强,但是如果很好掌握了ASN.1语法50%的基础知识就可以读懂现有80%的MIB文件,同时可以编写初中级的简单MIB文件了。
未完,待续…