SNMP超详解
背景介绍
SNMP(Simple Network Management Protocol),简单网络管理协议。简单易用,是事实上的网络管理工业标准,有SNMPv1, SNMPv2c, SNMPv3三种正式版本。
SNMP的网络管理模型
有4个组成部分:
管理节点(Management Node)
运行SNMP代理程序(SNMP agent),维护一个本地数据库,描述节点的状态和历史,并影响节点的运行。
管理站(Management Station)
运行专门的网络管理软件(manager),使用管理协议与被管理节点上的SNMP代理通信,维护管理信息库。
管理信息库(Management Information Base)
每个站点使用一个或多个变量描述自己的状态,这些变量称为“对象(objects)”,所有的对象组成管理信息库MIB(Management Information Base)
管理协议(Management Protocol)
管理协议用于管理工作站查询和修改被管理节点的状态,被管理节点可以使用管理协议向管理站点产生“陷阱(trap)”报告。
SNMP的发展
SNMPv1 (1990) 定义了许多公用MIB
SNMPv2 (1996) 弥补SNMPv1 的不足,支持批量传送(bulk)、提高了效率和性能,支持分布式网络管理,扩展了数据类型(增加了Unsigned32和Counter64类型、丰富了故障处理能力、加强了数据定义语言
SNMPv3 (1998) 安全性有了提升,具备前两个版本的功能,包含验证服务和加密服务在内的全新的安全机制,同时还规定了一套专门的网络安全和访问控制规则。 SNMPv3是在SNMPv2基础之上增加了安全和管理机制。
抓包分析与实战应用
一般来说,想要抓SNMP报文还是比较难的,至少需要安装Mib Browser或者其他一些模拟工具。正好我目前的工作是开发网管,C/S架构的网管软件涉及很多SNMP操作,抓包就很容易了。
SNMP get-next-reques报文
网元状态轮询不到时,网元不通,所以只有get-next-request没有get-response。
先插入SNMP报文的介绍图片:
对照之前抓取的报文可以看到:
SNMP协议基于传输层UDP协议,报文目标端口号为161(网元端口),说明这是管理站向代理发出的报文。协议版本为v2c,团体名为Public123,对应snmp原子操作为get-next,错误状态(error-stauts)为noError。
请求中variable-bindings包含的两个量为
1.3.6.1.4.1.3902.1082.40.50.2.13.3.1.1和1.3.6.1.4.1.3902.1082.40.50.2.13.3.1.2,分别是获取业务相关的两个值Direction 和 Mode。
常见的标准MIB变量都从1.3.6.1.2.1(iso.org.dod.internet.memt.mib)标识开始。
而我抓取的报文的MIB量以1.3.6.1.4.1开始,可见是为了描述厂商设备的信息自定义的私有Mib量。此外,这两个量是表量,
为了表达的方便,我将oid的公共前缀定义为Prefix
Prefix = 1.3.6.1.4.1.3902.1082.40.50.2.13.3.1
Index | Direction (Prefix.1) | Mode(Prefix.2) |
---|---|---|
1 | 1(Prefix.1.1) | 1(Prefix.2.1) |
2 | 1(Prefix.1.2) | 1(Prefix.2.2) |
网元状态正常时,抓取的SNMP报文
get操作
第一个get-next-request
与上面分析的一样,variable-bindings包含的两个量为
1.3.6.1.4.1.3902.1082.40.50.2.13.3.1.1和1.3.6.1.4.1.3902.1082.40.50.2.13.3.1.2。
对应表头的Direction 和 Mode
第一个get-response报文:
1.3.6.1.4.1.3902.1082.40.50.2.13.3.1.1.1
1.3.6.1.4.1.3902.1082.40.50.2.13.3.1.2.1
最后.1是索引,value的值为1,对应枚举值为1,对于Direction表示Ingress,Mode表示Network Side。
接着不断再次发送get-next-request。
如图,这时请求的snmp量都加上了索引值,表示请求获取网元当前位置的下一个量的值。
最后一个Get-response
1.3.6.1.4.1.3902.1082.40.50.2.13.3.1.50 : RowStatus
响应的是索引为1的结点的信息,第一个可用的结点的索引就是1。这个信息是Mode和RowStatus,不是按照请求的Direction和Mode返回的,并且RowStatus的值为1,表示状态行可用。可能是指第一个可用的行,然后get-next访问结束了。所以,没有下一个结点时,返回第一个可用行的“无效”的信息。
对于RowStatus的几种状态的解释:
-active(1):表明状态行是可用的
-notInService(2):表明行存在但不可用
-notReady (3):表明存在,但因为缺少必要的信息而不能用
-createAndGo (4):由管理者设置,表明希望创建一个行并设置该行的状态列对象为active
-createAndWait(5):由管理者设置,表明希望创建一个行,但不可用,被设置为了notInService
-destroy(6):删除行
引申一下——SNMP实战
SNMP API 4的下载链接:
https://www.researchgate.net/publication/252065477_AdventNet_SNMP_API_4
基于adventNet SNMP API编写的代码
getAll操作代码:
target.setObjectIDList(null);
target.addObjectID(mibOps.getSnmpOID("CosToOuterDirection").toString());
target.addObjectID(mibOps.getSnmpOID("CosToOuterMode").toString());
SnmpVarBind[][] varbind = target.snmpGetAllVariableBindings();
代码中SNMP API:
com.adventnet.snmp.snmp2.SnmpOID
OID操作
addObjectID(String snmpOidStr )
setObjectIDList(java.lang.String[] s)
com.adventnet.snmp.mibs.MibOperations
getSnmpOID (String snmpVarName ) // 根据MIB量名称字符串获得对应的OID
com.adventnet.snmp.beans.SnmpTarget
SNMP原子操作命令
SnmpVarBind[][] snmpGetAllVariableBindings()
com.adventnet.snmp.snmp2.SnmpVarBind
API总结:
核心API:
MibOperations 用于mib文件的解析处理
SnmpTarget 用于SNMP命令的操作
重要API :
SnmpAPI – 定义SNMP的错误和变量类型
SnmpVarBind – SNMP变量绑定(名值对)
SnmpVar – SNMP变量
辅助API :
SNMP各种类型量的类:SnmpBits、SnmpBitstring、SnmpCounter、SnmpCounter64、SnmpGauge、SnmpGroup、SnmpInt、SnmpIpAddress、SnmpMessage、SnmpNsap、SnmpNull、SnmpOpaque、SnmpString、SnmpTimeticks、SnmpUnsignedInt
SnmpOID – SNMP OID类
SnmpPDU – SNMP PDU类
SnmpAPI – SNMP 常量及常用工具
set操作
Set-request
分别给三个量Direction、Mode、RowStatus赋值。.2表示加上了索引,对应表格中某一位置
Get-response:
从响应包看Rtnvar 变量数组不为空,三个snmp变量都有值,且错误码状态为noError,设置成功。
基于adventNet SNMP API开发的代码
set操作代码:
target.setObjectIDList(null);
target.addObjectID(mibOps.getSnmpOID("CosToOuterDirection").toString() + index);
target.addObjectID(mibOps.getSnmpOID("CosToOuterMode").toString() + index);
target.addObjectID(mibOps.getSnmpOID("CosToOuterRowStatus").toString() + index);
SnmpVar[] setVars = new SnmpVar[target.getObjectIDList().length];
int j = 0;
setVars[j++] = SnmpVar.createVariable(String.valueOf(XXX),SnmpAPI.INTEGER);
setVars[j++] = SnmpVar.createVariable(String.valueOf(XXX),SnmpAPI.INTEGER);
setVars[j++] = SnmpVar.createVariable(4, SnmpAPI.INTEGER);
rtnVars = target.snmpSetVariables(setVars);
今天的文章[SNMP超详解]:简介、抓包分析与编程实战分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/31264.html