通过 snmp 获取数据的几个方式

@2013-08-29 新版功能: 创建

通过 snmp 获取数据时的常用的方法有:

  • snmpget

    snmpget [COMMON OPTIONS] [-Cf] AGENT OID [OID]...

    要请求的一个或多个 OID 不能是不完全的。在知道所有的 OID 的情况下, snmpget 是最有效的方式。

    $ snmpget -v 2c -c public 10.0.0.2 sysDescr.0
    SNMPv2-MIB::sysDescr.0 = STRING: Linux gw-beijing 3.8.13-gentoo-ks #3 SMP Mon May 27 10:30:52 CST 2013 x86_64
    
    # tcpdump -nn -p -i eth0 port snmp
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
    13:30:15.533031 IP 10.2.11.2.44058 > 10.0.0.2.161:  C=public GetRequest(28)  .1.3.6.1.2.1.1.1.0
    13:30:15.533269 IP 10.0.0.2.161 > 10.2.11.2.44058:  C=public GetResponse(104)  .1.3.6.1.2.1.1.1.0="Linux gw-beijing 3.8.13-gentoo-ks #3 SMP Mon May 27 10:30:52 CST 2013 x86_64"
    
  • snmpwalk

    snmpwalk [APPLICATION OPTIONS] [COMMON OPTIONS] AGENT [OID]

    需要获取的 OID 可以是不完整的,甚至可以为空。但从 tcpdump 的结果可以看到, snmpwalk 时数据的请求和回应每次都只针对唯一一个OID,因此,在请求的 OID 比较 多时,其效率会很低。其优势时可以对不能预先确定的 OID 进行遍历获取。

    $ snmpwalk  -v 2c -c public 10.0.0.2 ifName
    IF-MIB::ifName.1 = STRING: lo
    IF-MIB::ifName.2 = STRING: eno1
    IF-MIB::ifName.3 = STRING: eno2
    
    # tcpdump -nn -p -i eth0 port snmp
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
    13:42:17.690844 IP 10.2.11.2.36949 > 10.0.0.2.161:  C=public GetNextRequest(30)  .1.3.6.1.2.1.31.1.1.1.1
    13:42:17.691076 IP 10.0.0.2.161 > 10.2.11.2.36949:  C=public GetResponse(33)  .1.3.6.1.2.1.31.1.1.1.1.1="lo"
    13:42:17.691316 IP 10.2.11.2.36949 > 10.0.0.2.161:  C=public GetNextRequest(31)  .1.3.6.1.2.1.31.1.1.1.1.1
    13:42:17.691442 IP 10.0.0.2.161 > 10.2.11.2.36949:  C=public GetResponse(35)  .1.3.6.1.2.1.31.1.1.1.1.2="eno1"
    13:42:17.691570 IP 10.2.11.2.36949 > 10.0.0.2.161:  C=public GetNextRequest(31)  .1.3.6.1.2.1.31.1.1.1.1.2
    13:42:17.691691 IP 10.0.0.2.161 > 10.2.11.2.36949:  C=public GetResponse(35)  .1.3.6.1.2.1.31.1.1.1.1.3="eno2"
    13:42:17.691809 IP 10.2.11.2.36949 > 10.0.0.2.161:  C=public GetNextRequest(31)  .1.3.6.1.2.1.31.1.1.1.1.3
    13:42:17.692628 IP 10.0.0.2.161 > 10.2.11.2.36949:  C=public GetResponse(32)  .1.3.6.1.2.1.31.1.1.1.2.1=0
    
  • snmpbulkget

    snmpbulkget [COMMON OPTIONS] [-Cn <num>] [-Cr <NUM>] AGENT OID [OID]...

    对那些不能预先确定的 OID 相关的数据获取可以用到 snmpbulkget。"-Cn <num>" 参数指定在 GETBULK 请求的 OID 中的前 n 个不会被做迭代查询(默认值为0)。 "-Cr <NUM>" 参数指定 GETBULK 请求的 OID(不包含已经由 -Cn 指定的前 n 个 OID) 被迭代查询的次数(默认值10)。如果一次 BULK 请求拿不到完整的数据,则需要根据 结果调整请求 OID 后再次执行。退出的判断依据是如果结果中没有出现和请求的 OID 同类别的结果,则可认为该 OID 的所有值都已经获取到。详细的说明可以参考 RFC 3416。从 tcpdump 的结果可以看到,snmpbulkget 比 snmpwalk 在网络数据传输层面的效率更高。

    $ snmpbulkget  -v 2c -c public -Cn1 -Cr4 10.0.0.2 sysUpTime ifName
    DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (452288128) 52 days, 8:21:21.28
    IF-MIB::ifName.1 = STRING: lo
    IF-MIB::ifName.2 = STRING: eno1
    IF-MIB::ifName.3 = STRING: eno2
    IF-MIB::ifInMulticastPkts.1 = Counter32: 0
    
    # tcpdump -nn -p -i eth0 port snmp
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
    13:57:52.683078 IP 10.2.11.2.57705 > 10.0.0.2.161:  C=public GetBulk(43)  N=1 M=4 .1.3.6.1.2.1.1.3 .1.3.6.1.2.1.31.1.1.1.1
    13:57:52.683413 IP 10.0.0.2.161 > 10.2.11.2.57705:  C=public GetResponse(176)  .1.3.6.1.2.1.1.3.0=452319608 .1.3.6.1.2.1.31.1.1.1.1.1="lo" .1.3.6.1.2.1.31.1.1.1.1.2="eno1" .1.3.6.1.2.1.31.1.1.1.1.3="eno2" .1.3.6.1.2.1.31.1.1.1.2.1=0