轻松学习SNMP协议之入门篇

文章出处:Linux 宝库 作者:未知 发布时间:2006-09-21
  1. SNMP管理模型
  1.1.   什么是SNMP
  SNMP(Simple Network Management Protocol)是被广泛接受并投入使用的工业标准,它的目标是保证管理信息在任意两点中传送,便于网络管理员在网络上的任何节点检索信息,进行修改,寻找故障;完成故障诊断,容量规划和报告生成。它采用轮询机制,提供最基本的功能集。最适合小型、快速、低价格的环境使用。它只要求无证实的传输层协议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和SMI
  SNMP是应用层协议,它要求两端的协议实体交换各种报文,而低层要求用户数据都是BYTE序列,这就产生了一个问题: SNMP协议实体如何从接受到的一个BYTE序列中识别出报文又如何把一个用内部数据结构表示的报文转换成一个可供发送的BYTE序列, 也就是编解码问题。
  
  解决这个问题,就需要一个定义从实际的软件数据结构中抽象出来的数据类型的表示方法,称为抽象句法。
  
  ASN.1就是用来描述抽象记法的语言,事实上可应用与任何协议层,在它的基础上,通过规定编码规则,就可以确定数据在传送中的八比特组的值。
  
  SMI(Struct of Management Imformation),通过定义一个宏OBJECT-TYPE,规定了管理对象的表示方法,从这个意义上说,它是ASN.1的一个子集。另外它还定义了几个SNMP常用的基本类型和值。
  
  MIB (Management Imformation Base), 是所监控网络设备的标准变量定义的集合。SNMP用层次结构命名方案来识别管理对象,就象一棵树,树的节点表示管理对象,它可以用从根开始的一条路径来无二义的识别。见下图:
  
 

  管理对象B可以用一串数字唯一确定{1.2.1.1} 这串数字是管理对象的object identifier(客体标识符)。通过object identifier可确定从根到 B的一条路径。
  
  管理对象 A 的object identifier 是{1.2.1.1.5},或{B 5},后一种表示方法表明A是B的第5棵孩子。
  
  在agent中这棵树是用较复杂的数据结构来实现的,幸运的是,建树这个工作可由MIB编译器完成。在树的叶节点中,存放有访问函数的指针,Agent就是通过调用这些函数来从相关模块取得管理变量的值的。
  
  1.5.   SNMP报文
  SNMP报文结构如下:(编码之前)
  
 

  SNMP共有5中报文,所以其PDU也有5中,仅以GetRequest-PDU为例
  
 

  2.管理变量的表示
  管理变量表示管理对象类型在某一时刻的值(或称该类型的实例),SNMP以管理变量作为操作对象。
  
  管理变量的表示方法是这样规定的:形如x.y,其中x是管理对象的object identifer。y是能唯一确定对象类型值的一组数字,在非表型变量中为0,在表型变量中是这个表的索引,比如接口表中的接口号,或路由表中的目的网络地址等等 。如:在MIB文件里定义了ipAdEntNetMask这一管理对象,其object identifier为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.   GetRequest PDU:
  第一种情况:如果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.   GetNextRequest PDU
  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 ))
  
  网管站继续:
  
  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。这个响应通知网管站对表的遍历已经完成。
  
  1.8.   GetResponse PDU
  GetResponse PDU只有当受到getRequest GetNextReque