1.SNMP治理模型1.1.什么是SNMPSNMP(SimpleNetworkManagementPRotocol)是被广泛接受并投入使用的工业标准,它的目标是保证治理信息在任意两点中传送,便于网络治理员在网络上的任何节点检索信息,进行修改,寻找故障;完成故障诊断,容量规划和报告生成。它采用轮询机制,提供最基本的功能集。最适合小型、快速、低价格的环境使用。它只要求无证实的传输层协议UDP,受到许多产品的广泛支持。SNMP在TCP/ip协议族中的地位如下图:1.2.SNMP的基本操作:SNMP以GET-SET方式替代了复杂的命令集,利用基本操作演绎出全部操作。用户可以采用治理信息库标准或按标准的方式来定义自己的治理信息库(MIB)。这样做的好处是:通过降低占网管系统中大多数的代理部件的成本来降低整个网管系统的成本。1.3.网管站和代理网管站(NMS)对网络设备发送各种查询报文,并接收来自被管设备的响应及陷阱(trap)报文,将结果显示出来。代理(agent)是驻留在被管设备上的一个进程,负责接受、处理来自网管站的请求报文,然后从设备上其他协议模块中取得治理变量的数值,形成响应报文,反送给NMS。在一些紧急情况下,如接口状态发生改变,呼叫成功等时候,主动通知NMS(发送陷阱TRAP报文)。他们的关系如下图:SNMP就是用来规定NMS和Agent之间是如何传递治理信息的应用层协议。1.4.ASN.1和SMISNMP是应用层协议,它要求两端的协议实体交换各种报文,而低层要求用户数据都是BYTE序列,这就产生了一个问题:SNMP协议实体如何从接受到的一个BYTE序列中识别出报文又如何把一个用内部数据结构表示的报文转换成一个可供发送的BYTE序列,也就是编解码问题。解决这个问题,就需要一个定义从实际的软件数据结构中抽象出来的数据类型的表示方法,称为抽象句法。ASN.1就是用来描述抽象记法的语言,事实上可应用与任何协议层,在它的基础上,通过规定编码规则,就可以确定数据在传送中的八比特组的值。SMI(StrUCtofManagementImformation),通过定义一个宏OBJECT-TYPE,规定了治理对象的表示方法,从这个意义上说,它是ASN.1的一个子集。另外它还定义了几个SNMP常用的基本类型和值。MIB(ManagementImformationBase),是所监控网络设备的标准变量定义的集合。SNMP用层次结构命名方案来识别治理对象,就象一棵树,树的节点表示治理对象,它可以用从根开始的一条路径来无二义的识别。见下图:治理对象B可以用一串数字唯一确定{1.2.1.1}这串数字是治理对象的objectidentifier(客体标识符)。通过objectidentifier可确定从根到B的一条路径。治理对象A的objectidentifier是{1.2.1.1.5},或{B5},后一种表示方法表明A是B的第5棵孩子。在agent中这棵树是用较复杂的数据结构来实现的,幸运的是,建树这个工作可由MIB编译器完成。在树的叶节点中,存放有访问函数的指针,Agent就是通过调用这些函数来从相关模块取得治理变量的值的。1.5.SNMP报文SNMP报文结构如下:(编码之前)SNMP消息报文包含两个部分:SNMP报头和协议数据单元PDU。版本识别符(versionidentifier):确保SNMP代理使用相同的协议,每个SNMP代理都直接抛弃与自己协议版本不同的数据报。团体名(CommunityName):用于SNMP从代理对SNMP管理站进行认证;如果网络配置成要求验证时,SNMP从代理将对团体名和管理站的IP地址进行认证,如果失败,SNMP从代理将向管理站发送一个认证失败的Trap消息(见后);协议数据单元(PDU):其中PDU指明了SNMP的消息类型及其相关参数。下图是封装成UDP数据报的5种操作的SNMP报文格式。可见一个SNMP报文共有三个部分组成,即公共SNMP首部、get/set首部trap首部、变量绑定。(1)公共SNMP首部共三个字段:版本:写入版本字段的是版本号减1,对于SNMP(即SNMPV1)则应写入0。共同体(community)共同体就是一个字符串,作为管理进程和代理进程之间的明文口令,常用的是6个字符“public”。PDU类型:根据PDU的类型,填入0~4中的一个数字,其对应关系如表2所示意图。表2PDU类型PDU类型名称0get-request1get-next-request2get-response3set-request4Trap(2)get/set首部请求标识符(requestID)这是由管理进程设置的一个整数值。代理进程在发送get-response报文时也要返回此请求标识符。管理进程可同时向许多代理发出get报文,这些报文都使用UDP传送,先发送的有可能后到达。设置了请求标识符可使管理进程能够识别返回的响应报文对于哪一个请求报文差错状态(errorstatus)由代理进程回答时填入0~5中的一个数字,差错索引(errorlindex)当出现noSuchName、badValue或readOnly的差错时,由代理进程在回答时设置的一个整数,它指明有差错的变量在变量列表中的偏移。(3)trap首部企业(enterprise)填入trap报文的网络设备的对象标识符。此对象标识符肯定是在图3的对象命名树上的enterprise结点{1.3.6.1.4.1}下面的一棵子树上。trap类型此字段正式的名称是generic-trap,共分为表4中的7种。当使用上述类型2、3、5时,在报文后面变量部分的第一个变量应标识响应的接口。特定代码(specific-code)指明代理自定义的时间(若trap类型为6),否则为0。时间戳(timestamp)指明自代理进程初始化到trap报告的事件发生所经历的时间,单位为10ms。例如时间戳为1908表明在代理初始化后1908ms发生了该时间。(4)变量绑定(variable-bindings)指明一个或多个变量的名和对应的值。在get或get-next报文中,变量的值应忽略。SNMP共有5中报文,所以其PDU也有5中,仅以GetRequest-PDU为例2.治理变量的表示治理变量表示治理对象类型在某一时刻的值(或称该类型的实例),SNMP以治理变量作为操作对象。治理变量的表示方法是这样规定的:形如x.y,其中x是治理对象的objectidentifer。y是能唯一确定对象类型值的一组数字,在非表型变量中为0,在表型变量中是这个表的索引,比如接口表中的接口号,或路由表中的目的网络地址等等。如:在MIB文件里定义了ipAdEntNetMask这一治理对象,其objectidentifier为1.3.6.1.1.5.6.1.3它是个路由表中的一项,它的一个实例就是路由表中某一行的子网掩码,假如这行的索引、目的网络地址为129.102.1.0。则这个变量名是:1.3.6.1.1.5.6.1.3.129.102.1.0。在以后的说明中,为了方便,把唯一确定治理变量的一组数字,也就是x.y中的y称作实例。3.SNMP的运行过程驻留在被管设备上的AGENT从UDP端口161接受来自网管站的串行化报文,经解码、团体名验证、分析得到治理变量在MIB树中对应的节点,从相应的模块中得到治理变量的值,再形成响应报文,编码发送回网管站。网管站得到响应报文后,再经同样的处理,最终显示结果。下面根据RFC1157具体介绍Agent接受到报文后采取的动作:首先解码生成用内部数据结构表示的报文,解码依据ASN.1的基本编码规则,假如在此过程中出现错误导致解码失败则丢弃该报文,不做进一步处理。第二步:将报文中的版本号取出,假如与本Agent支持的SNMP版本不一致,则丢弃该报文,不做进一步处理。当前北研的数据通信产品只支持SNMP版本1。第三步:将报文中的团体名取出,此团体名由发出请求的网管站填写。如与本设备认可的团体名不符,则丢弃该报文,不做进一步处理,同时产生一个陷阱报文。SNMPv1只提供了较弱的安全措施,在版本3中这一功能将大大加强。第四步:从通过验证的ASN.1对象中提出协议数据单元PDU,假如失败,丢弃报文,不做进一不处理。否则处理PDU,结果将产生一个报文,该报文的发送目的地址应同收到报文的源地址一致。根据不同的PDU,SNMP协议实体将做不同的处理:1.6.GetRequestPDU:第一种情况:假如PDU中的变量名在本地维护的MIB树中不存在,则接受到这个PDU的协议实体将向发出者发送一个GetResponse报文,其中的PDU与源PDU只有一点不同:将ERROR-STATUS置为noSuchName,并在ERROR-INDEX中指出产生该变量在变量LIST中的位置。第二种情况:假如本地协议实体将产生的响应报文的长度大于本地长度限制,将向该PDU的发出者发送一个GetResponse报文,该PDU除了ERROR-STATUS置为tooBig,ERROR-INDEX置为0以外,与源PDU相同。第三种情况:假如本地协议实体因为其他原因不能产生正确的响应报文,将向该PDU的发出者发送一个GetResponse报文,该PDU除了ERROR-STATUS置为genErr,ERROR-INDEX置为出错变量在变量LIST中的位置,其余与源PDU相同。第四中情况:假如上面的情况都没有发生,则本地协议实体向该PDU的发出者发送一个GetResponse报文,该PDU中将包含变量名和相应值的对偶表,ERROR-STATUS为noError,ERROR-INDEX为0,request-id域的值应与收到PDU的request-id相同。1.7.GetNextRequestPDUGetNextRequestPDU的最重要的功能是表的遍历,这种操作受到了前面所说的治理变量的表示方法的支持,从而可以访问一组相关的变量,就好象他们在一个表内。下面通过一个例子解释表遍历的过程:被管设备维护如下路由表:DestinationNextHopMetric10.0.0.9989.1.1.4259.1.2.399.0.0.3310.0.0.5189.1.1.425假设网管站欲取得这张路由表的信息,该表的索引是目的网络地址。网管站向被管设备发送一个GetNextRequestPDU,其中的受管对象的标识如下GetNextRequest(ipRouteDest,ipRouteNextHop,ipRouteMetric1)SNMPagent响应如下GetResponsePDU: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))网管站继续: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))网管站继续:GetNextRe