# snmp_interaction **Repository Path**: dengkunnanmayun/snmp_interaction ## Basic Information - **Project Name**: snmp_interaction - **Description**: No description available - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 0 - **Created**: 2019-12-17 - **Last Updated**: 2024-12-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SNMP 交互框架 -- ## SNMP交互框架项目简介 基于SNMP4J 实现易用性框架,网络上关于SNMP交互的资料不多,没有找到集成好的SNMP处理组件,为了解决 SNMP集成困难,基于SNMP4J及Snmp协议栈开发一个易用性组件,组件可以打成一个普通工具jar。 提供可视化XML配置,注入相关Filter,VarBindOrder,Adapter自定义处理类,login和OID映射处理,不需要直接 面对繁琐的OID,Filter实现可以对下发数据进行节点过滤,VarBindOrder对于下发节点进行特殊排序需求,Adapter 配置每个节点的设配需求,如ip,mac,time特殊解析。 获取数据带Instance(全部索引拼接)获取单条数据。不带则获取全表数据,数据自动处理全部数据,可配置 最大处理条数,不配置也不会溢出。 支持SNMPV3,SNMPV2,SNMPV1,下发数据会根据返回错误码进行封装 (不同厂家的设备可能不相同,错误码需要重新设配)。 直接调用入口类,处理流程不需要关心,支持并发调用,消息均为同步消息,但是互不影响。 ## SNMP 交互框架参数说明 ``` snmpVersion SNMP版本 1/2/3 NEType 网源类型名称 (不需要必填,如果需要集成扩展会用) NetNodeID 网元类型ID (不需要必填,如果需要集成扩展会用) WRITECOM 写共同体 (必填 ,设配配置,一般厂家都固定的) READCOM 读共同体(必填 ,设配配置,一般厂家都固定的) TIMEOUT 超时时间 (必填 单位秒,默认3秒) PORT 端口 (必填 默认161) IPADDRESS 目的IP (必填 请求目的设备IP) SnmpUserName 用户名称 (必填 Device login name,可以登录设备配置的名称,一帮设备都有snmp用户配置) V3 V3配置 (必填,如果是snmpv3,需要配置UN=none;SL=noAuth,noPriv) SSH_PORT ssh端口 (必填 默认22) RETRY 重试次数 (不必填,默认3次) ``` ## SNMP 协议栈 ``` 封装的协议类型: STRING MacAddress PhysAddress Counter64 IpAddress INTEGER NULLOBJ BITSTRING UNSIGNED32 UINTEGER32 OctetString ``` ## 使用配置入口参考 cn.snmp.mutual.test.TestConfig 配置SNMP默认信息,需要交互的MIB表XML(Mib配置Demo) SendSnmp4jOperator 调用setInfo/getInfo ``` //默认网元信息容器,构造参数 DefaultNeObject ne = new DefaultNeObject(); ne.setProperty("snmpVersion", "2"); ne.setProperty("NEType", "XX-C"); ne.setProperty("NetNodeID", "22"); ne.setProperty("WRITECOM", "private"); ne.setProperty("READCOM", "public"); ne.setProperty("TIMEOUT", "3"); ne.setProperty("PORT", "161"); ne.setProperty("IPADDRESS", "172.16.67.197"); ne.setProperty("SnmpUserName", "none"); ne.setProperty("V3", "UN=none;SL=noAuth,noPriv"); ne.setProperty("SSH_PORT", "22"); ne.setProperty("RETRY", "1"); //或得相关参数(通过ne信息,mib xml 或得需要解析的表配置的相关信息) ObjService osParam = DefaultSnmpHelper.getSnmpParams(ne, "SlaConfigTable", mibFilePath); log.info("***Remove Task***Begin to query XX-C device task:" + osParam.toString()); //下发数据,一行数据封装成一个ObjService ,命名为RowSet,行状态RowStatus = 4 ObjService rowSet = new ObjService("RowSet"); rowSet.setValue("SlaConfigRowStatus", "4"); rowSet.setValue("SlaConfigOperId", "4"); osParam.addContainedObject(rowSet); rowSet.setValue("Instance", "1"); //osParam.setValue("Instance", 4); ObjService result1 = SendSnmp4jOperator.setInfo(osParam); //result1 下发返回的结果,包括错误码 //获取数据的时候指定Instance单条数据获取,不指定就是全表获取 ObjService result = SendSnmp4jOperator.getInfo(osParam); //ObjService params = DefaultSnmpHelper.getSnmpParams(ne, "rcSlaGlobalParam", "mibpath"); //SendSnmp4jOperator.getInfo(params); ``` ## XMl配置结构说明 ``` 通过XML配置Mib 表结构 指定XML类型 ResourceBundle 国际化配置路径 MibTable 支持配置多个表,List类型和Table 表类型 MibTable Name 表名称, Type : Table/List Filter 指定过滤器 VarBindOrder 下发顺序实现类配置配 MibNodeAdapter 针对节点配置的节点解析类 ``` ## XMl配置Demo ``` ``` ## 实现描述 GET操作 ``` //获取数据的时候指定Instance单条数据获取,不指定就是全表获取 ObjService result = SendSnmp4jOperator.getInfo(osParam); 第一次获取get-request操作,当获需要取全表的时候get-next-request操作,将结果处理后缓存,最后汇总 ``` SET操作 ``` ObjService result1 = SendSnmp4jOperator.setInfo(osParam); set-request操作,Table表数据下发,一次操作下发一个rowSet数据,携带多个rowSet会循环下发。 List表数据下发,多次set-request操作,一次下发异常终止数据下发。 ``` ## SNMP协议单元 SNMP规定了5种协议数据单元PDU(也就是SNMP报文),用来在管理进程和代理之间的交换。 get-request操作:从代理进程处提取一个或多个参数值。 get-next-request操作:从代理进程处提取紧跟当前参数值的下一个参数值。 set-request操作:设置代理进程的一个或多个参数值。 get-response操作:返回的一个或多个参数值。这个操作是由代理进程发出的,它是前面三种操作的响应操作。trap操作:代理进程主动发出的报文,通知管理进程有某些事情发生。 # SNMP协议相关知识简介 (来源网络,可以理解SNMP交互流程) ## SNMP 协议简介 简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议。 SNMP广泛用于管理和监控网络设备,大多数专业的网络设备都有SNMP agent代理,这些代理被激活和配置后用于和SNMP管理 NMS(network management system)网络管理系统通信。 (1)管理信息库MIB:任何一个被管理的资源都表示成一个对象,称为被管理的对象。MIB是被管理对象的集合。它定义了被管理对象的一系列属性:对象的名称、对象的访问权限和对象的数据类型等。每个SNMP设备(Agent)都有自己的MIB。MIB也可以看作是NMS(网管系统)和Agent之间的沟通桥梁。 (2)管理信息结构(SMI) SMI定义了SNMP框架所用信息的组织、组成和标识,它还为描述MIB对象和描述协议怎样交换信息奠定了基础。 ### 简单类型(simple) Integer:整型是-2,147,483,648~2,147,483,647的有符号整数 octet string: 字符串是0~65535个字节的有序序列 OBJECT IDENTIFIER: 来自按照ASN.1规则分配的对象标识符集 ### 简单结构类型(simple-constructed) SEQUENCE 用于列表。这一数据类型与大多数程序设计语言中的“structure”类似。一个SEQUENCE包括0个或更多元素,每一个元素又是另一个ASN.1数据类型 SEQUENCE OF type 用于表格。这一数据类型与大多数程序设计语言中的“array”类似。一个表格包括0个或更多元素,每一个元素又是另一个ASN.1数据类型。 ### 应用类型(application-wide) IpAddress: 以网络序表示的IP地址。因为它是一个32位的值,所以定义为4个字节; counter:计数器是一个非负的整数,它递增至最大值,而后回零。在SNMPv1中定义的计数器是32位的,即最大值为4,294,967,295; Gauge :也是一个非负整数,它可以递增或递减,但达到最大值时保持在最大值,最大值为232-1; time ticks:是一个时间单位,表示以0.01秒为单位计算的时间; SNMP报文结构如下:(编码之前) 版本号 团体名 协议数据单元PDU ## SNMP协议单元 SNMP规定了5种协议数据单元PDU(也就是SNMP报文),用来在管理进程和代理之间的交换。 get-request操作:从代理进程处提取一个或多个参数值。 get-next-request操作:从代理进程处提取紧跟当前参数值的下一个参数值。 set-request操作:设置代理进程的一个或多个参数值。 get-response操作:返回的一个或多个参数值。这个操作是由代理进程发出的,它是前面三种操作的响应操作。trap操作:代理进程主动发出的报文,通知管理进程有某些事情发生。 ## SNMP的运行过程 驻留在被管设备上的AGENT从UDP端口161接受来自网管站的串行化报文,经解码、团体名验证、分析得到管理变量在MIB树中对应的节点,从相应的模块中得到管理变量的值,再形成响应报文,编码发送回网管站。网管站得到响应报文后,再经同样的处理,最终显示结果。 ##SNMP的运行过程 驻留在被管设备上的AGENT从UDP端口161接受来自网管站的串行化报文,经解码、团体名验证、分析得到管理变量在MIB树中对应的节点,从相应的模块中得到管理变量的值,再形成响应报文,编码发送回网管站。网管站得到响应报文后,再经同样的处理,最终显示结果。 ###下面根据RFC1157详细介绍Agent接受到报文后采取的动作: ####首先解码生成用内部数据结构表示的报文,解码依据ASN.1的基本编码规则,如果在此过程中出现错误导致解码失败则丢弃该报文,不做进一步处理。 ####第二步:将报文中的版本号取出,如果与本Agent支持的SNMP版本不一致,则丢弃该报文,不做进一步处理。当前北研的数据通信产品只支持SNMP版本1。 ####第三步:将报文中的团体名取出,此团体名由发出请求的网管站填写。如与本设备认可的团体名不符,则丢弃该报文,不做进一步处理,同时产生一个陷阱报文。SNMPv1只提供了较弱的安全措施,在版本3中这一功能将大大加强。 ####第四步:从通过验证的ASN.1对象中提出协议数据单元PDU,如果失败,丢弃报文,不做进一不处理。否则处理PDU,结果将产生一个报文,该报文的发送目的地址应同收到报文的源地址一致。 ###根据不同的PDU,SNMP协议实体将做不同的处理: #### 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相同。 #### 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。这个响应通知网管站对表的遍历已经完成。 #### GetResponse PDU GetResponse PDU只有当受到getRequest GetNextRequest SetRequest才由协议实体产生,网管站收到这个PDU后,应显示其结果。 ####SetRequest PDU SetRequest PDU除了PDU类型标识以外,和GetRequest相同,当需要对被管变量进行写操作时,网管站侧的协议实体将生成该PDU。 对SetRequest的响应将根据下面情况分别处理: 如果是关于一个只读变量的设置请求,则收到该PDU的协议实体产生一个GetReponse报文,并置error status为noSuchName, error index的值是错误变量在变量list中的位置。 如果被管设备上的协议实体收到的PDU中的变量对偶中的值,类型、长度不符和要求,则收到该PDU的协议实体产生一个GetReponse报文,并置error status为badValue, error index的值是错误变量在变量list中的位置。 如果需要产生的GetReponse报文长度超过了本地限制,则收到该PDU的协议实体产生一个GetReponse报文,并置error status为tooBig, error index的值是0。 如果是其他原因导致SET失败,则收到该PDU的协议实体产生一个GetReponse报文,并置error status为genErr, error index的值是错误变量在变量list中的位置。 如果不符合上面任何情况,则agent将把管理变量设置收到的PDU中的相应值,这往往可以改变被管设备的运行状态。同时产生一个GetResponse PDU,其中error status置为noError,error index的值为0。 #### Trap PDU Trap PDU的有如下的形式 产生trap的系统的OBJECT IDENTIFIER  系统的IP地址 普通类型 特定类型 时戳 变量对偶表 Trap是被管设备遇到紧急情况时主动向网管站发送的消息。网管站收到trap PDU后要将起变量对偶表中的内容显示出来。一些常用的trap类型有冷、热启动,链路状态发生变化等。