snmp ++ tp id 发送请求失败id占多少字节

转摘:SNMP配置
SNMP是Simple Network Manger Protocol(简单网络管理协议)的缩写,在1988年8月就成为一个网络管理标准RFC1157。到目前,因众多厂家对该协议的支持,SNMP已成为事实上的网管标准,适合于在多厂家系统的互连环境中使用。利用SNMP协议,网络管理员可以对网络上的节点进行信息查询、网络配置、故障定位、容量规划,网络监控和管理是SNMP的基本功能。
SNMP是一个应用层协议,为客户机/服务器模式,包括三个部分:
SNMP网络管理器
MIB管理信息库
SNMP网络管理器,是采用SNMP来对网络进行控制和监控的系统,也称为NMS (Network Management System)。常用的运行在NMS上的网管平台有HP OpenView 、CiscoView、CiscoWorks 2000,锐捷网络针对自己的网络设备,开发了一套网管软件--Star View。这些常用的网管软件可以方便的对网络设备进行监控和管理。
SNMP代理(SNMP Agent)是运行在被管理设备上的软件,负责接受、处理并且响应来自NMS的监控和控制报文,也可以主动发送一些消息报文给NMS。
NMS和Agent的关系可以用如下的图来表示:
网络管理站(NMS)与网管代理(Agent)的关系图
MIB(Management Information Base)是一个虚拟的网络管理信息库。被管理的网络设备中包含了大量的信息,为了能够在SNMP报文中唯一的标识某个特定的管理单元,MIB采用树形层次结构来描述网络设备中的管理单元。树的节点表示某个特定的管理单元。如下图MIB对象命名树,为了唯一标识网络设备中的某个管理单元System,可以采用一串的数字来表示,如{1.3.6.1.2.1.1}这一串数字即为管理单元的Object Identifier(单元标识符),MIB则是网络设备的单元标识符的集合。
MIB树形层次结构
目前SNMP支持以下版本:
SNMPv1 :简单网络管理协议的第一个正式版本,在RFC1157中定义。
SNMPv2C:基于共同体(Community-Based)的SNMPv2管理架构, 在RFC1901中定义的一个实验性协议。
SNMPv3 :通过对数据进行鉴别和加密,提供了以下的安全特性:
确保数据在传输过程中不被篡改;
确保数据从合法的数据源发出;
加密报文,确保数据的机密性;
SNMPv1和SNMPv2C都采用基于共同体(Community-based)的安全架构。通过定义主机地址以及认证名(Commumity String)来限定能够对代理的MIB进行操作的管理者。
SNMPv2C增加了Get-bulk操作机制并且能够对管理工作站返回更加详细的错误信息类型。Get-bulk操作能够一次性地获取表格中的所有信息或者获取大批量的
数据,从而减少请求-响应的次数。SNMPv2C错误处理能力的提高包括扩充错误代码以区分不同类型的错误,而在SNMPv1中这些错误仅有一种错误代码。现在通过错误代码可以区分错误类型。由于网络上可能同时存在支持SNMPv1和SNMPv2C的管理工作站,因此SNMP代理必须能够识别SNMPv1和SNMPv2C报文,并且能返回相应版本的报文。
协议中的NMS和Agent之间的交互信息,定义了6种操作类型:
Get-request操作:NMS从Agent提取一个或多个参数值。
Get-next-request操作:NMS从Agent提取一个或多个参数的下一个参数值。
Get-bulk操作:NMS从Agent提取批量的参数值;
Set-request操作:NMS设置Agent的一个或多个参数值。
Get-response操作:Agent返回的一个或多个参数值,是Agent对NMS前面3个操作的响应操作。
Trap操作:Agent主动发出的报文,通知NMS有某些事情发生。
前面的4个报文是由NMS向Agent发出的,后面两个是Agent发给NMS的(注意:SNMPv1版本不支持Get-bulk操作)。下图描述了这几种种操作。
SNMP的报文类型
NMS向Agent发出的前面3种操作和Agent的应答操作采用UDP的161端口。Agent发出的Trap操作采用UDP的162端口。
通过SNMP对R2700交换卡(NM2-24ESW/NM2-16ESW)进行管理时,NM2-16ESW会获取到不存在的17~26口的错误信息;NM2-24ESW会获取到不存在的25~26口的错误信息。
SNMPv1和SNMPv2版本使用认证名用来鉴别是否有权使用MIB对象。为了能够管理设备,网络管理系统 (NMS)的认证名必须同设备中定义的某个认证名一致。
一个认证名可以有以下属性:
只读(Read-only):为被授权的管理工作站提供对所有MIB变量的读权限。
读写(Read-write):为被授权的管理工作站提供对所有MIB变量的读写权限。
在SNMPv2的基础上,
SNMPv3通过安全模型以及安全级别来确定对数据采用哪种安全机制进行处理;目前可用的安全模型有三种类别:SNMPv1、SNMPv2C、SNMPv3。
下表为目前可用的安全模型以及安全级别
引擎标识用于唯一标识一个SNMP引擎。由于每个SNMP实体仅包含一个SNMP引擎,它将在一个管理域中唯一标识一个SNMP实体。因此,作为一个实体的SNMPv3代理器必须拥有一个唯一的引擎标识,即SnmpEngineID。
引擎标识为一个OCTET STRING,长度为5~32字节长。在RFC3411中定义了引擎标识的格式:
前4个字节标识厂商的私有企业号(由IANA分配),用HEX表示。
第5个字节表示剩下的字节如何标识:
1:后面4个字节是一个Ipv4地址。
2:后面16个字节是一个Ipv6地址。
3:后面6个字节是一个MAC地址。
4:文本,最长27个字节,由厂商自行定义。
5:16进制值,最长27个字节,由厂商自行定义。
6-127:保留。
128-255:由厂商特定的格式。
SNMP的配置工作在网络设备的全局配置模式下完成,在进行SNMP配置前,请先进入全局配置模式。
SNMPv1/SNMPv2C采用基于共同体(Community-based)的安全方案,SNMP代理只接受来自相同认证名(Community-String)的管理操作,与网络设备的认证名不符的SNMP报文将不被响应,直接丢弃。认证名相当于NMS和Agent之间的密码。
可以设置访问列表关联,只有指定的IP地址的NMS可以管理;
可以设定该共同体的操作权限,是ReadOnly(只读)还是ReadWrite(读写);
指定视图的名称,用于基于视图的管理。默认没有指定视图,即允许访问& 所有MIB对象;
可以指明能够使用该认证名的管理者的IP。 若不指明,则表示不限制使用该认证名的管理者的IP地址。缺省为不限制使用该认证名的管理者的IP地址;
要配置SNMP认证名,在全局配置模式下执行如下命令:
可以配置一条或者多条指定,来指定多个不同的共同体名称,使得网络设备可以供不同的权限的NMS的管理,要删除共同体名称和权限,在全局配置模式下,执行no snmp-server
community命令。
可以使用基于视图的访问控制模型来判定一个操作关联的管理对象是否在视图允许之内或被排除在外,只有在视图允许之内的管理对象才被允许访问。在进行控制时,一般是将某些用户和一个组关联,再将某个组与某个视图关联。一个组内的用户具有相同的访问权限。
可以设置包含视图和排除视图;
可以为一组用户设置只读的视图和可写的视图;
如果是SNMPv3的用户,可以为其指定使用的安全级别,是否需要进行认证、是否需要进行加密;
要配置MIB视图和组,在全局配置模式下执行如下命令:
使用no snmp-server view
view-name命令来删除一个视图,或者使用no snmp-server view
oid-tree命令在一个视图中删除一棵子树。也可以使用no snmp-server
group groupname命令来删除一个组。
可以使用基于用户的安全模型来进行安全管理,基于用户的管理必须事先配置用户的信息,NMS只有使用合法的用户才能同代理进行通信。
对于SNMPv3用户,可以指定安全级别、认证算法(MD5或SHA)、认证口令、加密算法(目前只有DES)和加密口令;
要配置SNMP用户,在全局配置模式下执行如下命令:
通过no snmp-server user
groupname删除指定用户。
Agent在特定的情况下,也会主动的向NMS发送消息,要配置Agent主动发送消息的NMS主机地址,在全局配置模式下,执行如下指令:
可以对SNMP的Agent的基本参数进行配置,设置设备的联系方式、设备位置、序列号的信息,NMS通过访问设备的这些参数,便可以得知设备的联系人,设备所在的物理位置等信息。
要配置SNMP代理参数,在全局配置模式下,执行如下指令:
代理最大数据报文长度
为了减少对网络带宽的影响,可以定义SNMP代理的数据包的最大长度。在全局配置模式下,执行如下指令:
SNMP代理服务是我司产品提供的一个服务,默认是启动的,在不需要代理服务的时候,可以通过如下方式屏蔽snmp代理功能以及相关配置信息;屏蔽snmp代理功能,在全局配置模式下,执行如下指令:
不同于屏蔽命令,我司产品提供了关闭snmp代理的命令,该命令会直接snmp所有服务,但是不会屏蔽代理的配置信息;要关闭SNMP代理服务,在全局配置模式下,执行如下指令:
主动向NMS发送Trap消息
Trap是Agent不经请求主动向NMS发送的消息,用于报告一些紧急而重要的事件的发生。缺省是不允许Agent主动发送Trap消息,如果要允许,在全局配置模式下,执行如下指令:
在设备中可以基于接口配置是否发送该接口的LinkTrap,当功能打开时,如果接口发生Link状态变化,SNMP将发出LinkTrap,反之则不发。缺省情况下,该功能打开。
下面配置将配置接口为不发送Link
Ruijie(config)#
interfacegigabitEthernet
Ruijie(config-if)# no
link-status
可以指定Agent发送Trap消息的一些参数,执行如下指令来设置:
若每次重新初始化(重启)后的接口索引值维持不变,将有利于网络管理。当要求重启后设备的接口索引值不发生变化,执行如下命令:
Ruijie(config)# snmp-server if-index
打开接口索引维持功能
若要关闭该功能,执行no snmp-server if-index
persist命令。缺省情况下,该功能是关闭的。
下面配置打开接口索引维持功能:
Ruijie(config)# snmp-server if-index
的监控与维护
为了监控SNMP状态和排除SNMP配置中的一些故障,我司产品提供了SNMP的监控指令,可以方便的查看当前网络设备的SNMP的状态,在特权用户模式下,执行show snmp来查看当前的SNMP状态。
Ruijie# show
Contact: wugb@.cn
Location: fuzhou
2381 SNMP packets input
5 Bad SNMP version errors
6 Unknown community name
0 Illegal operation for community
name supplied
0 Encoding errors
9325 Number of requested
0 Number of altered
31 Get-request PDUs
2339 Get-next PDUs
0 Set-request PDUs
2406 SNMP packets output
0 Too big errors (Maximum packet size
4 No such name errors
0 Bad values errors
0 General errors
2370 Get-response PDUs
36 SNMP trap PDUs
SNMP global trap: disabled
SNMP logging: enabled
SNMP agent: enabled
对于上述的统计报文信息的解释见下表:
代理支持的MIB对象
在特权用户模式下,执行show snmp mib来查看当前的代理支持的MIB对象。
Ruijie# show snmp
sysObjectID
sysContact
sysLocation
sysServices
sysORLastChange
snmpInPkts
snmpOutPkts
snmpInBadVersions
snmpInBadCommunityNames
snmpInBadCommunityUses
snmpInASNParseErrs
snmpInTooBigs
snmpInNoSuchNames
snmpInBadValues
snmpInReadOnlys
snmpInGenErrs
snmpInTotalReqVars
snmpInTotalSetVars
snmpInGetRequests
snmpInGetNexts
snmpInSetRequests
snmpInGetResponses
snmpInTraps
snmpOutTooBigs
snmpOutNoSuchNames
snmpOutBadValues
snmpOutGenErrs
snmpOutGetRequests
snmpOutGetNexts
snmpOutSetRequests
snmpOutGetResponses
snmpOutTraps
snmpEnableAuthenTraps
snmpSilentDrops
snmpProxyDrops
entPhysicalEntry
entPhysicalEntry.entPhysicalIndex
entPhysicalEntry.entPhysicalDescr
entPhysicalEntry.entPhysicalVendorType
entPhysicalEntry.entPhysicalContainedIn
entPhysicalEntry.entPhysicalClass
entPhysicalEntry.entPhysicalParentRelPos
entPhysicalEntry.entPhysicalName
entPhysicalEntry.entPhysicalHardwareRev
entPhysicalEntry.entPhysicalFirmwareRev
entPhysicalEntry.entPhysicalSoftwareRev
entPhysicalEntry.entPhysicalSerialNum
entPhysicalEntry.entPhysicalMfgName
entPhysicalEntry.entPhysicalModelName
entPhysicalEntry.entPhysicalAlias
entPhysicalEntry.entPhysicalAssetID
entPhysicalEntry.entPhysicalIsFRU
entPhysicalContainsEntry
entPhysicalContainsEntry.entPhysicalChildIndex
entLastChangeTime
在特权用户模式下,执行show snmp user来查看当前代理上配置的SNMP用户。
Ruijie# show snmp
User name: test
Engine ID:
storage-type: permanent&&&&
Security level: auth priv
Auth protocol: SHA
Priv protocol: DES
Group-name: g1
在特权用户模式下,执行show snmp group来查看当前代理上配置的组。
Ruijie# show snmp
groupname: g1
securityModel: v3
securityLevel:authPriv
readview: default
writeview: default
notifyview:
groupname: public
securityModel: v1
securityLevel:noAuthNoPriv
readview: default
writeview: default
notifyview:
groupname: public
securityModel: v2c
securityLevel:noAuthNoPriv
readview: default
writeview: default
notifyview:
在特权用户模式下,执行show snmp view来查看当前代理上配置的视图。
Ruijie# show snmp
default(include) 1.3.6.1
test-view(include)
1.3.6.1.2.1
如图,网络设备和网管工作站NMS通过以太网连接,NMS的IP地址为192.168.12.181,网络设备的IP地址为192.168.12.1,在网管工作站上运行了网管软件(以HP OpenView为例)。
SNMP典型配置组网图
网络设备具体配置
启动SNMP代理服务:
Ruijie(config)# snmp-server community public RO
只需要在全局配置模式下,配置以上指令,网络设备便启动了SNMP代理服务功能,这时NMS便可以对网络设备进行SNMP的监控了,不过只配置了只读权限,不能修改网络设备的配置,只能是监控网络设备。其他的配置都是可选的。
如果需要有读写的功能,可以采用如下的配置:
Ruijie(config)# snmp-server community private RW
以下是配置网络设备SNMP的一些代理基本参数,NMS可以通过这些参数得知网络设备的一些基本系统信息,该配置为可选配置:
Ruijie(config)# snmp-server location fuzhou
Ruijie(config)# snmp-server contact wugb@.cn
Ruijie(config)# snmp-server chassis-id
以下的配置,是允许网络设备主动向NMS发送一些Trap消息,该配置为可选配置:
Ruijie(config)# snmp-server enable traps
Ruijie(config)# snmp-server host 192.168.12.181 public
通过如上配置,网络设备的SNMP代理已经配置完毕,NMS便可以对网络设备进行监控和管理了,以HP OpenView为例,可以产生网络拓扑结构图,如下图:
网络拓扑结构图
您可以对网络设备中的管理单元进行查询和设置,点击HP OpenView的TOOL-&SNMP MIB Brower菜单,出现如下的对话框,在Name中输入IP地址192.168.12.1,在Community Name中输入Public,选择要查询的MIB的具体管理单元,比如下图的System。点击Start Query,便开始对网络设备进行MIB的查询了,具体的查询结果见对话框的MIB Values窗口:
MIB查询界面
HP OpenView有很强大的网络管理的功能,比如,还可以用图表示出网络接口的流量统计图,其他的具体的各项SNMP的功能,见网管软件的文档,这里不在详述:
接口流量统计图
访问列表关联控制实例
我司产品可以设置访问列表关联的方式,只要访问列表中允许的NMS才可以利用SNMP对Agent进行监控和管理,限制NMS对网络设备的访问,提高SNMP的
在全局配置模式下:
Ruijie(config)# access-list 1 permit
192.168.12.181
Ruijie(config)# snmp-server community public RO 1
通过如上配置,只有IP地址为192.168.12.181的主机才能利用SNMP对网络设备进行监控和管理了。&
相关配置实例
以下的配置允许SNMPv3的管理者采用认证+加密模式通过用户名v3user对MIB-2(1.3.6.1.2.1)节点下的管理变量进行设置和查看。采用的认证模式为MD5,使用的认证密码为MD5-Auth,采用DES加密,加密密钥为DES-Priv。同时允许向192.168.65.199以SNMPv3格式发送Trap。发送Trap使用的用户名为v3user,采用认证+加密模式发送,采用的认证模式为MD5,使用的认证密码为MD5-Auth,采用DES加密,加密密钥为DES-Priv。
Ruijie(config)# snmp-server view v3userview 1.3.6.1.2.1
Ruijie (config)# snmp-server group v3usergroup v3 priv read v3userview write
v3userview
Ruijie (config)# snmp-server user v3user v3usergroup v3 auth md5 md5-auth priv des56 des-priv
Ruijie (config)# snmp-server host 192.168.65.199 traps version 3 priv
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。SNMP的协议分析_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
SNMP的协议分析
上传于||文档简介
&&S​N​M​P​的​协​议​分​析
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩15页未读,继续阅读
你可能喜欢SNMP协议发展及安全机制介绍_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
SNMP协议发展及安全机制介绍
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩8页未读,继续阅读
你可能喜欢5534人阅读
SNMPv3 Message Format
一个SNMPv3的Message包括以下部分:
1) msgVersion
3) msgMaxSize
发送方支持的最大消息长度/the maximum message size supported by a sender of an SNMP message.
4) msgFlags
8位字段,包含3个flag,最后三位从高到低依次为 reportableFlag, privFlag, authFlag.
reportableFlag如果设置为1,那么如果满足产生report的条件,就会返回一个report给发送方。
所有的request(GET,SET)或者inform,reportableFlag设置为1;Response,Trap,Report中需要设置为0。
privFlag为1表示PDU是加密的。authFlag为1表示PDU是认证的。
5) msgSecurityModel
&&&&&&&&&&&&&&&&&&&& 0& reserved for 'any'
&&&&&&&&&&&&&&&&&&&& 1& reserved for SNMPv1
&&&&&&&&&&&&&&&&&&&& 2& reserved for SNMPv2c
&&&&&&&&&&&&&&&&&&&& 3& User-Based Security Model (USM)
6) msgAuthoritativeEngineID
7) msgAuthoritativeEngineBoots
8) msgAuthoritativeEngineTime
9) msgUserName
10) msgAuthenticationParameters
12个字节的HMAC消息摘要(HMAC-MD5-96 或者 HMAC-SHA-96)
11) msgPrivacyParameters
用来产生DES加密算法的初始向量(IV)。
12) contextEngineID
13) contextName
包含了实际请求或者应答数据。
12+13+14一起称为scopedPDU
SNMPv3发送和接受消息的处理过程
RFC 3414中详细的描述了这个过程。
下载SNMP4J()的源代码,亦可以比较清楚地看到发送和接受消息的处理过程。
发送消息主要的处理在org.snmp4j.security.USM.generateRequestMessage()中(此函数又调用了generateResponseMessage(),实际上的处理在这个函数中)。
接受消息主要的处理在org.snmp4j.security.USM.processIncomingMsg()中。
发送消息首先根据请求数据生成平文的PDU,在PDU头上加上contextEngineID和contextName,得到scopedPDU。
然后对上面所说的SNMPv3 Message Format的1~14各部分设定相应的值,得到整个消息体,
其中msgAuthenticationParameters的12个字节数据置为全零。
然后对scopedPDU部分进行加密。
最后使用HMAC算法作用在加密后的整个消息体上,生成12个字节信息摘要,替换msgAuthenticationParameters。
接受消息和发送相反,首先把收到的消息体中msgAuthenticationParameters的12个字节数据替换为全零。
然后使用HMAC算法作用在替换了msgAuthenticationParameters后的消息体上,生成12个字节信息摘要,
把这个信息摘要和原始的msgAuthenticationParameters比较,如果不等,返回错误。
之后解密scopedPDU。
1) Key Localization
用户的认证(authKey)和加密密码(privKey)不会直接使用。
对于同一个用户的密码,通过Key Localization,用于不同的authoritative SNMP engine的密钥实际上是不一样的。
对于认证密码,Key Localization的过程如下:
org.snmp4j.security.AuthGeneric.passwordToKey(OctetString passwordString, byte[] engineID)
a) 使用用户密码重复填充1个64字节块,使用此64字节块重复填充得到1M字节的数据,
b) 使用认证算法(MD5/SHA1)作用于上面得到的1M字节的数据,得到的摘要为Ku
c)& 在snmp engine id的前后加上Ku, 然后再次使用认证算法(MD5/SHA1),得到的摘要即为localized key: Kul
加密密码的处理过程如下:
org.snmp4j.security.SecurityProtocols.passwordToKey(OID privProtocolID, OID authProtocolID, OctetString passwordString, byte[] engineID)
authProtocolID和privProtocolID分别是当前用户的Authentication Protocol和Privacy Protocol.
a) 根据authProtocolID得到当前的AuthenticationProtocol
b) 调用org.snmp4j.security.AuthGeneric.passwordToKey(passwordString, engineID),实际上就是上面认证密码的Key Localization过程。
c) 根据privProtocolID得到加密算法,比较加密算法要求的密钥最小/最大长度和上面得到的localized privKey的长度,
&&& 如果过长截断,如果过短,调用privProtocol.extendShortKey()方法延长。
org.snmp4j.security.AuthGeneric.authenticate(byte[] authenticationKey, byte[] message, int messageOffset , int messageLength, ByteArrayWindow digest)
认证实际上就是根据HMAC计算消息摘要(digest)的过程。
传入的authenticationKey就是localized authKey.
计算摘要的过程见HMAC算法-&
注意只使用计算得到摘要的前12个字节(96位)
3) 加密解密
CBC-DES加密的处理在函数
org.snmp4j.security.PrivDES.encrypt(byte[] unencryptedData, int offset, int length, byte[] encryptionKey, long engineBoots, long engineTime, DecryptParams decryptParams)
参数encryptionKey就是16字节的localized privKey, 它的前8个字节用来作为DES key, 因为DES只使用56 bits,每个字节的最低位实际上被丢弃。
The first 8 octets of the 16-octet secret (private privacy key) are& used as a DES key.& Since DES uses only 56 bits, the Least Significant Bit in each octet is disregarded.
CBC模式需要一个64 bit的IV(Initialization Vector)。
encryptionKey的后8个字节用作pre-IV。
为了让每个packet能有不同的IV, 需要对pre-IV进行salt。
使用32-bit的snmpEngineBoots和一个32-bit的随机数一起产生一个64-bit(8字节)的salt。
salt的前4个字节是32-bit的snmpEngineBoots,后4个字节是32-bit的随机数。
然后salt和pre-IV进行异或运算得到IV, IV=salt XOR pre-IV。
最后salt放入msgPrivacyParameters字段发送给接受方用来产生正确的IV进行解密。
解密的处理在函数org.snmp4j.security.PrivDES.decrypt(byte[], int, int, byte[], long, long, DecryptParams)里面。&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:670381次
积分:7388
积分:7388
排名:第1758名
原创:116篇
转载:95篇
评论:111条
(9)(9)(1)(19)(3)(13)(9)(4)(9)(6)(1)(1)(5)(9)(2)(1)(1)(1)(3)(4)(2)(6)(1)(2)(6)(3)(40)(6)(8)(4)(1)(4)(1)(7)(2)(3)(3)(2)dxwangtcg 的BLOG
用户名:dxwangtcg
文章数:367
评论数:187
访问量:978799
注册日期:
阅读量:24883
阅读量:276183
阅读量:1006510
阅读量:153629
51CTO推荐博文
前两天项目要求一个附加功能,远程监视服务器的运行状况,要定期监视指定端口,指定业务,还包括服务器的磁盘空间,内存,CPU使用率等等。这头俩事还好说,ping和telnet也就搞定了,实在不行就开个socket连一下,关键后边的事有点抓瞎,要是在本地,可以通过API得到系统信息,分析磁盘空间,内存啥的,可是远程得到别的机子的信息,那不成木马了么。到网上一查,原来有SNMP可以帮着做这件事情。于是就了解了一下,发现这个东西挺有意思。简单地做个笔记。
SNMP简单网络管理协议,是一个用来进行网络管理的协议,之所以称其简单,是因为它是另一个网管协议的简化版。并不是说简化版就不顶用。相反,那个不简化的网管协议号称因为太复杂,几乎不可能实现并推广。不过说实在的,SNMP我都没觉得它多简单,它至今经过十多年的演进,广泛用于各种网络设备及工业控制中,我个人感觉,随着网络进一步发展,电器都会有IP地址的时候,SNMP或它的替代品的作用,应该是会更加重要的。
SNMP简单说,包括了被管的设备,代理和网管系统三个部分。被管的设备指的就是我们要获取信息的设备,这个任务里我需要获取它的磁盘空间。但是被管理设备只是产生这些数据,真正将数据报告回来的工作是由代理完成的。代理说白了就是一个运行在被管设备上的程序。网络编程的角度讲它就是一个小的socket服务程序,监听着好像是161端口。通过在被管设备上,需要启动snmp服务。比如在linux上,就需要执行service snmpd start来启动snmp服务,也就是把代理跑起来。实际过程中,代理包含在各种网络设备上,包括交换机,路由器甚至打印机,手机,调制解调器上。网管系统就是我们要从被管设备获取数据并进行分析处理的这个程序。可以想像它运行在本地。只要我将一个合格的请求发往正在运行的代理处,代理从请求中,理解请求的内容,并从被管设备上用它自己的方式搜集到所需的信息,并发送回来,这样一个网管的简单过程就完成了。
这样的管理方式,还是很灵活的,只要请求包符合协议标准,用哪种语言开发网管系统无所谓;从代理角度讲,只要能正常监听并处理请求,代理可以任意实现。我不太清楚国际上有没有一个统一的标准,比如让我写代理,有请求要查询网络端口的数量,我非把显示器尺寸返回去,不知道警察抓不抓我,至少客户会要求退货吧。也正是因为这种灵活,SNMP也可以支持大规模的集中管理,我同样一个查询存储空间的请求,可以发给我的PC,也可以发给我的诺基亚手机,可能得到的会是存储卡的容量吧,就看代理怎么实现了。
至于如何表达我的请求,这里有一个统一的标准,就是MIB,管理信息库的缩写,就好像一个注册表一样,但是这个注册表不实际存值,不像Windows的注册表。它只是给每一种设备信息编了一个号,称为OID。这个号是以树的形式组织的,中间用点隔开,便于管理。约定好了查的时候直接报告这个号就知道查什么值了。这个号是大家统一的,好比如每个人都有眼睛,眼睛的好坏我们可以用视力来衡量,我们就可以这样定:“人(1).身体(2).五官(3).眼睛(4).视力(5)”。那如果我向一个人发请求,问他的视力,那可以冲他说:那谁谁谁,我是那谁家的谁谁谁,告诉我.1.2.3.4.5.0 这里的"1.2.3.4.5"是对象标识符,后面再加上.0就是实例标识符。
snmp为了简单,规定的操作类型较少,基本常用的有获取(Get),设置(Set),获取下一个(GetNext),还有一个由代理主动发出的(Trap)用于报告事件。另外snmp已经发展到V3了,这个过程中又新增了什么GetBulk等等。我还没有用到,不敢乱说。回头试试再作笔记。
在linux下,配置SNMP服务要修改/etc/snmp/snmpd.conf,也可以通过snmpconf命令配,挺方便的。
在windows下,直接在控制面板,添加删除程序里,添加Windows组件,然后选网络管理,就装上snmp服务了。在服务列表里找到它,可以通过属性进行配置。
基本上概念也就这些了。实际在开发的时候,有几种选择:
1.直接发UDP包,这样最原始,最灵活,基本上完全自主。不过太麻烦。没有非要重新造轮子玩。
2.在Windows上用winsnmp这个API。拼包的工作它就管了。
3.选择一些开源的SNMP开发包。比如像NET-SNMP,SNMP++,还有其它的很多。.net下还有一个现成的组件OLEPRNLib,我不知道它应该算那种。
我这次主要用了winsnmp和SNMP++。
首先SnmpStartup一下。成了,就会通过5个参数传回5个值。关于本地SNMPAPI的基本信息,版本号和SNMP版本。头两个版本用团体名作认证。方便,但安全性较差。V3就比较安全了。
if (SNMPAPI_SUCCESS == SnmpStartup((smiLPUINT32)&m_nMajorVersion, (smiLPUINT32)&m_nMinorVersion, (smiLPUINT32)&m_nLevel, (smiLPUINT32)&m_nTranslateMode, (smiLPUINT32)&m_nRetransmitMode))在我的机子上返回的分别是:2,0,2,1,1
头两个数说明我的WinSnmp版本是2.0.
第3个2,说明WinSnmp支持标准的SNMPv2
第四个1,说明我的SNMP采用SNMPAPI_UNTRANSLATED_V1这种转换模式。
最后一个1说明支持重传。
任务比较紧,这几个参数的具体意思,我回头研究研究再作笔记。
m_hSession = SnmpCreateSession(NULL, 0, CSNMPManager::snmp_callbacknext, this);
建立一个会话。用这个会话,就可以发送请求了。
第一个参数是窗口句柄,用来接收消息。是这样,具我了解,SNMP首先可以异步传输。也就是说发送出请求后,并不阻塞。那么如果有回应消息了,就会给这个窗口句柄一个消息,如果在MFC下,可以做消息映射。第二个参数就是将来收到响应时,窗口会收到的对应的消息值。然后具体的响应是什么,到消息的参数里去看。
这里我传的是空,因为我测试的程序没有窗口。
第三个参数是一个函数指针。不发消息给窗口,就可以申请回调。我现在用的就是回调。第四个参数是调回调的时候,传给我的自定义参数,可以传空。我现在传this是因为我注册的snmp_callbacknext是个静态函数。我把实例指针传进去,是为了把实例信息带进去。
接下来,就可以通过SnmpStrToEntity,得到SNMP实体了。这里把客户端和服务端统称为实体。m_hsrcAgent&& =&& SnmpStrToEntity(m_hSession,&& m_pSrcAddr))得到实体句柄
再接下来,m_hContext = SnmpStrToContext(m_hSession, &community);得到上下文句柄。这里的团体名,有人也叫共同体。总之是个帐户一样的东西。在配置SNMP的时候,要设置这个,并给它设置只读还是读写。一般安全起见,设成只读。已经够用了。
现在可以建立变量绑定表了,HSNMP_VBL hVbl = SnmpCreateVbl(m_hSession, NULL, NULL);后两个参数是OID和值。可以一次性建好变量绑定表。我这里是先建了一个空的,一会儿再往里填值。
这里就用到OID了,但我们习惯的“1.3.6.1...”这种字符串形式,需要通过SnmpStrToOid转成smiOID类型。这是为了API拼SNMP包方便,定义的一个新类型。因为最终的SNMP请求的UDP包,是字节形式的。是要符合BER编码规范的。所谓BER编码,就是将一个数据封装成:标志,长度,内容这样一个数据段。比如规定整形标志是1,再假设1234的十六进制是0x12,0x34。那么我要发一个1234出去就要这样编码:01 02 12 34。
将变量加入到变量绑定表:SnmpSetVb(hVbl, 0, &oid, NULL),第二个参数是索引,第三个参数是变量,第四个参数是值。
hSendPDU = SnmpCreatePdu(m_hSession, SNMP_PDU_GETNEXT, 0, 0, 0, hVbl);构造实际的UDP包。PDU:协议数据单元。第二个参数说明请求的类型:可以传一开始提到的那几种类型,snmp.h里面有定义:
#define SNMP_PDU_GET&&&&&&&&&&&&&&& (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x0)#define SNMP_PDU_GETNEXT&&&&&&&&&&& (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x1)#define SNMP_PDU_RESPONSE&&&&&&&&&& (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x2)#define SNMP_PDU_SET&&&&&&&&&&&&&&& (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x3)#define SNMP_PDU_V1TRAP&&&&&&&&&&&& (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x4)#define SNMP_PDU_GETBULK&&&&&&&&&&& (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x5)#define SNMP_PDU_INFORM&&&&&&&&&&&& (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x6)#define SNMP_PDU_TRAP&&&&&&&&&&&&&& (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x7)
一切就绪,最后就要发包了:
SnmpSendMsg(m_hSession, m_hsrcAgent, m_hdstAgent, m_hContext, hSendPDU)
这里面几个参数都是前面准备好的,这个方法就没啥可说的了。正确调用后,就可以等着回应了。
在回调函数SNMPAPI_STATUS CALLBACK CSNMPManager::snmp_callback(HSNMP_SESSION hSession,& HWND hWnd,& UINT wMsg,& WPARAM wParam,& LPARAM lParam,& LPVOID lpClientData)
里,我们可以得到一个hSession.这个是代理那边扔过来的。和我们的hSession没啥关系。
之后我们通过这个hSession,调用SnmpRecvMsg(hSession, &hsrcAgent, &hdstAgent, &hContext, &hRecvPDU)),得回实体,上下文,以及响应的PDU。
得到响应的PDU,比较激动的时刻就到了,因为我们要开始拆响应包了,如果从里面拆出了我们想查的值,那就说明OK了,于是调用:
&SnmpGetPduData(hRecvPDU, NULL, NULL, (smiLPINT)&nErrStatus, (smiLPINT)&nErrIndex, &hRecvVbl)
晕,得到了变量绑定表,那就是说还有一层,不过保佑啊,可千万别一层层剥下来,最后得到4个字节值,转换编码一瞅,俩字“挠挠”,呵呵。
int nVblCnt = SnmpCountVbl(hRecvVbl);
得一下变量绑定表的长度。
smiOID&smiVALUE&for (int i=1; i&=nVblC i++)&{&&&&SnmpGetVb(hRecvVbl, i, &oid, &val); &&parseVb(val);&&&&&}
循环,得一下每一个变量。得到OID的值,可以用SnmpOidToStr得回成字符串的形式看一下,是哪个OID的值。
然后值的类型是smiOID,很像COM里的variant_t。一个类型值拖着一个大的联合体。
#define SNMP_SYNTAX_INT&&&&&&&& (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x02)#define SNMP_SYNTAX_BITS&&&&&&& (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x03)#define SNMP_SYNTAX_OCTETS&&&&& (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x04)#define SNMP_SYNTAX_NULL&&&&&&& (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x05)#define SNMP_SYNTAX_OID&&&&&&&& (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x06)#define SNMP_SYNTAX_INT32&&&&&& SNMP_SYNTAX_INT#define SNMP_SYNTAX_IPADDR&&&&& (ASN_APPLICATION | ASN_PRIMITIVE | 0x00)#define SNMP_SYNTAX_CNTR32&&&&& (ASN_APPLICATION | ASN_PRIMITIVE | 0x01)#define SNMP_SYNTAX_GAUGE32&&&& (ASN_APPLICATION | ASN_PRIMITIVE | 0x02)#define SNMP_SYNTAX_TIMETICKS&& (ASN_APPLICATION | ASN_PRIMITIVE | 0x03)#define SNMP_SYNTAX_OPAQUE&&&&& (ASN_APPLICATION | ASN_PRIMITIVE | 0x04)#define SNMP_SYNTAX_NSAPADDR&&& (ASN_APPLICATION | ASN_PRIMITIVE | 0x05)#define SNMP_SYNTAX_CNTR64&&&&& (ASN_APPLICATION | ASN_PRIMITIVE | 0x06)#define SNMP_SYNTAX_UINT32&&&&& (ASN_APPLICATION | ASN_PRIMITIVE | 0x07)
这几种值类型。常用的有SNMP_SYNTAX_UINT32、SNMP_SYNTAX_OCTETS、SNMP_SYNTAX_OID这几种吧,用法都差不多。没啥问题。
代码到这里,架子就基本上搭好了,我们可以传一个OID过去,看看返回值了,我只知道想查什么,可我怎么知道它的OID是什么呀?别急,有一个网站很好,这上面有很全的MIB资料。分平台,设备,很齐全。可以上它上面去查。我查了一下,在linux下,如果想查磁盘空间,应该去查
HOST-RESOURCES-MIB (v2)Tree
子树,下面有
1.3.6.1.2.1.25.2iso(1). org(3). dod(6). internet(1). mgmt(2). mib-2(1). host(25). hrStorage(2)
hrMemorySize
1.3.6.1.2.1.25.2.2.0
hrStorageTable
not-accessible
SEQUENCE OF
1.3.6.1.2.1.25.2.3
hrStorageEntry
not-accessible
HrStorageEntry
1.3.6.1.2.1.25.2.3.1
hrStorageIndex
Integer32 ( 1.. )
1.3.6.1.2.1.25.2.3.1.1
hrStorageType
AutonomousType
1.3.6.1.2.1.25.2.3.1.2
hrStorageDescr
DisplayString
1.3.6.1.2.1.25.2.3.1.3
hrStorageAllocationUnits
Integer32 ( 1.. )
1.3.6.1.2.1.25.2.3.1.4
hrStorageSize
read-write
Integer32 ( 0.. )
1.3.6.1.2.1.25.2.3.1.5
hrStorageUsed
Integer32 ( 0.. )
1.3.6.1.2.1.25.2.3.1.6
hrStorageAllocationFailures
1.3.6.1.2.1.25.2.3.1.7
hrDeviceTypes
1.3.6.1.2.1.25.3.1
这里面有一个表,表下面有行,一个分区是一行,每行有索引,有分区描述(一般是卷标),有分区尺寸,有已用空间。
至此,眼前的任务,算是应付下来了。这个过程中,还会牵扯到传输设置,表的操作,GetNext操作的实现等内容,今天实在来不及全记下来了,我稍后再补充完整。
了这篇文章
类别:┆阅读(0)┆评论(0)}

我要回帖

更多关于 tplinkid发送请求失败 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信