snmp协议

SNMP学习笔记之SNMP 原理与实战详解 - 云+社区 - 腾讯云

NET-SNMP基本命令 - tigerloveapple - 博客园

简单易懂的snmpd.conf配置文件说明 - zhming - 博客园

记录一下

1、安装snmp代理

安装 yum install -y net-snmp net-snmp-utils

修改配置 vi /etc/snmp/snmpd.conf     去掉first,secend,third的注释,基本功能就可以用了。

启动服务  systemctl restart snmpd

测试  snmpget -v 2c -c public 127.0.0.1 sysName.0

2、命令测试

2.1 snmpget  

oid可以写数字形式,也可以写节点名称,或简写为最后一段

最后一个8,是sysORTable的索引

[root@cgsl-LIN-1E8F1930CBB c]# snmpget -v2c -c public 127.0.0.1 SNMPv2-MIB::sysORDescr.8
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations

[root@cgsl-LIN-1E8F1930CBB c]# snmpget -v2c -c public 127.0.0.1 sysORDescr.8
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations

[root@cgsl-LIN-1E8F1930CBB c]# snmpget -v2c -c public localhost .1.3.6.1.2.1.1.9.1.3.8
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations

也可以查询 标量,例如  snmpget -v 2c -c public 127.0.0.1 sysName.0

最后一个0是固定的,表示索引。

附录1

[root@cgsl-LIN-1E8F1930CBB c]# snmptranslate -Tt 
  org(3) type=0
    dod(6) type=0
      internet(1) type=0
        directory(1) type=0
        mgmt(2) type=0
          mib-2(1) type=0
            system(1) type=0
              sysDescr(1) type=2 tc=4 hint=255a
              sysObjectID(2) type=1
              sysUpTime(3) type=8
                sysUpTimeInstance(0) type=0
              sysContact(4) type=2 tc=4 hint=255a
              sysName(5) type=2 tc=4 hint=255a
              sysLocation(6) type=2 tc=4 hint=255a
              sysServices(7) type=3
              sysORLastChange(8) type=8 tc=14
              sysORTable(9) type=0
                sysOREntry(1) type=0
                  sysORIndex(1) type=3
                  sysORID(2) type=1
                  sysORDescr(3) type=2 tc=4 hint=255a
                  sysORUpTime(4) type=8 tc=14

2.2 snmpwalk 是一个linux命令,而不是snmp原始操作,它调用snmpgetnext操作,遍历一个节点下面的所有数据

[root@cgsl-LIN-1E8F1930CBB c]# snmpwalk -v2c -c public localhost .1.3.6.1.2.1.1.9
SNMPv2-MIB::sysORID.1 = OID: SNMP-MPD-MIB::snmpMPDCompliance
SNMPv2-MIB::sysORID.2 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORID.3 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.5 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
SNMPv2-MIB::sysORID.6 = OID: TCP-MIB::tcpMIB
SNMPv2-MIB::sysORID.7 = OID: IP-MIB::ip
SNMPv2-MIB::sysORID.8 = OID: UDP-MIB::udpMIB
SNMPv2-MIB::sysORID.9 = OID: SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance
SNMPv2-MIB::sysORID.10 = OID: NOTIFICATION-LOG-MIB::notificationLogMIB
SNMPv2-MIB::sysORDescr.1 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.2 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORDescr.3 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
SNMPv2-MIB::sysORUpTime.1 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.2 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.3 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.4 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.5 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.8 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.9 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.10 = Timeticks: (0) 0:00:00.00

2.3 snmpgetnext

返回一个节点的下一个元素,观察第二条命令,输入是.8节点,返回的是.9 节点

[root@cgsl-LIN-1E8F1930CBB c]# snmpget -v2c -c public localhost .1.3.6.1.2.1.1.9.1.3.8
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations

[root@cgsl-LIN-1E8F1930CBB c]# snmpgetnext -v2c -c public localhost .1.3.6.1.2.1.1.9.1.3.8
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.

[root@cgsl-LIN-1E8F1930CBB c]# snmpgetnext -v2c -c public 127.0.0.1 SNMPv2-MIB::sysORDescr.10
SNMPv2-MIB::sysORUpTime.1 = Timeticks: (0) 0:00:00.00

再看下面这个测试,说明getnext会自动找到第一个有数据的节点

[root@cgsl-LIN-1E8F1930CBB c]# snmpgetnext -v2c -c public 127.0.0.1 1.3.6.1
SNMPv2-MIB::sysDescr.0 = STRING: Linux cgsl-LIN-1E8F1930CBB 4.19.5-300.fc29.x86_64 #1 SMP Tue Nov 27 19:29:23 UTC 2018 x86_64
[root@cgsl-LIN-1E8F1930CBB c]# snmpgetnext -v2c -c public 127.0.0.1 1.3.6.1.1
SNMPv2-MIB::sysDescr.0 = STRING: Linux cgsl-LIN-1E8F1930CBB 4.19.5-300.fc29.x86_64 #1 SMP Tue Nov 27 19:29:23 UTC 2018 x86_64
[root@cgsl-LIN-1E8F1930CBB c]# snmpgetnext -v2c -c public 127.0.0.1 1.3.6
SNMPv2-MIB::sysDescr.0 = STRING: Linux cgsl-LIN-1E8F1930CBB 4.19.5-300.fc29.x86_64 #1 SMP Tue Nov 27 19:29:23 UTC 2018 x86_64
[root@cgsl-LIN-1E8F1930CBB c]# snmpgetnext -v2c -c public 127.0.0.1 1.3
SNMPv2-MIB::sysDescr.0 = STRING: Linux cgsl-LIN-1E8F1930CBB 4.19.5-300.fc29.x86_64 #1 SMP Tue Nov 27 19:29:23 UTC 2018 x86_64


[root@cgsl-LIN-1E8F1930CBB c]# snmpget -v2c -c public 127.0.0.1 .1.3.6.1.2.1.1.1.0
SNMPv2-MIB::sysDescr.0 = STRING: Linux cgsl-LIN-1E8F1930CBB 4.19.5-300.fc29.x86_64 #1 SMP Tue Nov 27 19:29:23 UTC 2018 x86_64

2.4 snmpbulkget  批量getnext,指定最多返回条数

[root@cgsl-LIN-1E8F1930CBB c]# snmpbulkget -v2c -c public -C r5 localhost .1.3.6.1.2.1.1.9.1.3.5
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.

[root@cgsl-LIN-1E8F1930CBB c]# snmpbulkget -v2c -c public -C r5 localhost .1.3.6.1.2.1.1.9.1.3.5  sysORUpTime.1
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORUpTime.2 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORUpTime.3 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORUpTime.4 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORUpTime.5 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (0) 0:00:00.00
注意:oid中的小数点,只是一个分隔符,在实际的报文中,是没有的。实际报文中就是数字序列。最前面的小数点,也是可有可无的。

最后,看一下 nonRepeaters 和 maxRepetitions 这两个参数(就是下面的n2r5,代表有两个标量,不需要重复获取;对表量,最大获取下5个)

[gaofeng@cgsl]$ snmpbulkget -v2c -c public -C n2r5  localhost 1.3.6.1.2.1.1.3.0 1.3.6.1.2.1.1.4.0 .1.3.6.1.2.1.1.9.1.3.2 .1.3.6.1.2.1.1.9.1.4.2
SNMPv2-MIB::sysContact.0 = STRING: Root <root@localhost> (configure /etc/snmp/snmp.local.conf)
SNMPv2-MIB::sysName.0 = STRING: cgsl-LIN-1E8F1930CBB
SNMPv2-MIB::sysORDescr.3 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORUpTime.3 = Timeticks: (92) 0:00:00.92
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORUpTime.4 = Timeticks: (92) 0:00:00.92
SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORUpTime.5 = Timeticks: (92) 0:00:00.92
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (92) 0:00:00.92
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (92) 0:00:00.92
 

2.5 snmptable 这也是一个linux命令

[root@cgsl-LIN-1E8F1930CBB c]# snmptable -v2c -c public localhost .1.3.6.1.2.1.1.9
SNMP table: SNMPv2-MIB::sysORTable

                                         sysORID                                                                     sysORDescr  sysORUpTime
                 SNMP-MPD-MIB::snmpMPDCompliance                                The MIB for Message Processing and Dispatching. 0:0:00:00.00
        SNMP-USER-BASED-SM-MIB::usmMIBCompliance The management information definitions for the SNMP User-based Security Model. 0:0:00:00.00
  SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance                                          The SNMP Management Architecture MIB. 0:0:00:00.00
                             SNMPv2-MIB::snmpMIB                                             The MIB module for SNMPv2 entities 0:0:00:00.00
         SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup                                      View-based Access Control Model for SNMP. 0:0:00:00.00
                                 TCP-MIB::tcpMIB                                The MIB module for managing TCP implementations 0:0:00:00.00
                                      IP-MIB::ip                        The MIB module for managing IP and ICMP implementations 0:0:00:00.00
                                 UDP-MIB::udpMIB                                The MIB module for managing UDP implementations 0:0:00:00.00
 SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance                The MIB modules for managing SNMP Notification, plus filtering. 0:0:00:00.00
        NOTIFICATION-LOG-MIB::notificationLogMIB                                 The MIB module for logging SNMP Notifications. 0:0:00:00.00

2.6 snmptranslate命令

[root@cgsl-LIN-1E8F1930CBB c]# snmptranslate -On SNMPv2-MIB::sysORDescr.10
.1.3.6.1.2.1.1.9.1.3.10

2.7 snmptrap, 有一个发送程序,一个接收程序

注意,要用root用户,包括后面的收发trap,否则没有权限

第一步,配置snmptrapd的trap处理规则
[root@cgsl-LIN-1E8F1930CBB snmp]# cat snmptrapd.conf 
# Example configuration file for snmptrapd
#
# No traps are handled by default, you must edit this file!
#
 authCommunity   log,execute,net public
# traphandle SNMPv2-MIB::coldStart    /usr/bin/bin/my_great_script cold

第二步,增加一个trap的mib文件
root@cgsl-LIN-1E8F1930CBB mibs]# pwd
/usr/share/snmp/mibs
[root@cgsl-LIN-1E8F1930CBB mibs]# cat NOTIFICATION-TEST-MIB.txt
NOTIFICATION-TEST-MIB DEFINITIONS ::= BEGIN       IMPORTS ucdavis FROM UCD-SNMP-MIB; demonotifs OBJECT IDENTIFIER ::= { ucdavis 991 } demo-notif NOTIFICATION-TYPE         STATUS current         OBJECTS { sysLocation }         DESCRIPTION "Just a test notification"         ::= { demonotifs 17 } END


第三步、打开trap监听,结果写入到log文件中
[root@cgsl-LIN-1E8F1930CBB mibs]# snmptrapd -C -c /etc/snmp/snmptrapd.conf -Lf /tmp/trapd.log
[root@cgsl-LIN-1E8F1930CBB mibs]# tail /tmp/trapd.log
NET-SNMP version 5.7.3
[root@cgsl-LIN-1E8F1930CBB mibs]# tail -f /tmp/trapd.log
NET-SNMP version 5.7.3
2021-09-19 10:44:39 cgsl [UDP: [127.0.0.1]:36838->[127.0.0.1]:162]:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (8377651) 23:16:16.51	SNMPv2-MIB::snmpTrapOID.0 = OID: UCD-SNMP-MIB::ucdavis.991.17	SNMPv2-MIB::sysLocation.0 = STRING: just here
2021-09-19 10:44:40 cgsl [UDP: [127.0.0.1]:36798->[127.0.0.1]:162]:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (8377716) 23:16:17.16	SNMPv2-MIB::snmpTrapOID.0 = OID: UCD-SNMP-MIB::ucdavis.991.17	SNMPv2-MIB::sysLocation.0 = STRING: just here
2021-09-19 10:44:40 cgsl [UDP: [127.0.0.1]:50218->[127.0.0.1]:162]:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (8377781) 23:16:17.81	SNMPv2-MIB::snmpTrapOID.0 = OID: UCD-SNMP-MIB::ucdavis.991.17	SNMPv2-MIB::sysLocation.0 = STRING: just here

第四步、发送trap,可有看到前面的snmptrapd可有监听到trap消息
[root@cgsl-LIN-1E8F1930CBB c]# snmptrap -v 2c -c public 127.0.0.1:162 "" NOTIFICATION-TEST-MIB::demo-notif          SNMPv2-MIB::sysLocation.0 s "just here"
[root@cgsl-LIN-1E8F1930CBB c]# snmptrap -v 2c -c public 127.0.0.1:162 "" NOTIFICATION-TEST-MIB::demo-notif          SNMPv2-MIB::sysLocation.0 s "just here"
[root@cgsl-LIN-1E8F1930CBB c]# snmptrap -v 2c -c public 127.0.0.1:162 "" NOTIFICATION-TEST-MIB::demo-notif          SNMPv2-MIB::sysLocation.0 s "just here"

测试时,这个trap oid和数据oid,是可以直接写的,不需要自己在mib文件中定义
snmptrap -v 2c -c public 127.0.0.1:162 "" .1.2.5.5  .1.8.8.0 s "just here9999"

2021-10-03 19:11:38 cgsl [UDP: [127.0.0.1]:51291->[127.0.0.1]:162]:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (920486) 2:33:24.86	SNMPv2-MIB::snmpTrapOID.0 = OID: iso.2.5.5	iso.8.8.0 = STRING: "just here9999"

2.8 snmp go

----mod.go----

module gui2

go 1.16
require github.com/gosnmp/gosnmp v1.32.0


----snmp.go----
package main

import (
	"fmt"
	g "github.com/gosnmp/gosnmp"
	"log"
	"time"
)
func main() {
	g.Default.Target = "192.168.127.152"
	g.Default.Community = "public"
	g.Default.Version = g.Version2c
	g.Default.Timeout = time.Duration(1) * time.Second
	g.Default.Retries = 4
	g.Default.ExponentialTimeout = false
	err := g.Default.Connect()
	log.Println("hello")
	if err != nil {
		log.Fatalf("Connect() err: %v", err)
	}

	defer g.Default.Conn.Close()

	oids := []string{"1.3.6.1.2.1.1.5.0","1.3.6.1.2.1.1.7.0"}
	result, err := g.Default.Get(oids) // Get() accepts up to g.MAX_OIDS
	if err != nil {
		log.Fatalf("Get() err: %v", err)
	}
	printVariables(result)


	oids = []string{"1.3.6.1.2.1.1.4.0","1.3.6.1.2.1.1.5.0"}
	result, err = g.Default.GetNext(oids) // Get() accepts up to g.MAX_OIDS
	if err != nil {
		log.Fatalf("Get() err: %v", err)
	}
	printVariables(result)

	oids = []string{"1.3.6.1.2.1.1.3.0","1.3.6.1.2.1.1.4.0",".1.3.6.1.2.1.1.9.1.3.2",".1.3.6.1.2.1.1.9.1.4.2"}
	result, err = g.Default.GetBulk(oids,2,4) // Get() accepts up to g.MAX_OIDS
	if err != nil {
		log.Fatalf("Get() err: %v", err)
	}
	printVariables(result)
}

func printVariables(result *g.SnmpPacket) {
	fmt.Println("---------")
	for i, v := range result.Variables {
		fmt.Printf("%d. oid: %s  %s", i, v.Name, v.Type)

		// the Value of each variable returned by Get() implements
		// interface{}. You could do a type switch...
		switch v.Type {
		case g.OctetString:
			fmt.Printf("  string: %s\n", string(v.Value.([]byte)))
		default:
			// ... or often you're just interested in numeric values.
			// ToBigInt() will return the Value as a BigInt, for plugging
			// into your calculations.
			fmt.Printf("  number: %d\n", g.ToBigInt(v.Value))
		}
	}
}

2021/09/19 16:15:09 hello
---------
0. oid: .1.3.6.1.2.1.1.5.0  OctetString  string: cgsl-LIN-1E8F1930CBB
1. oid: .1.3.6.1.2.1.1.7.0  NoSuchInstance  number: 0
---------
0. oid: .1.3.6.1.2.1.1.5.0  OctetString  string: cgsl-LIN-1E8F1930CBB
1. oid: .1.3.6.1.2.1.1.6.0  OctetString  string: Unknown (edit /etc/snmp/snmpd.conf)
---------
0. oid: .1.3.6.1.2.1.1.4.0  OctetString  string: Root <root@localhost> (configure /etc/snmp/snmp.local.conf)
1. oid: .1.3.6.1.2.1.1.5.0  OctetString  string: cgsl-LIN-1E8F1930CBB
2. oid: .1.3.6.1.2.1.1.9.1.3.3  OctetString  string: The SNMP Management Architecture MIB.
3. oid: .1.3.6.1.2.1.1.9.1.4.3  TimeTicks  number: 92
4. oid: .1.3.6.1.2.1.1.9.1.3.4  OctetString  string: The MIB module for SNMPv2 entities
5. oid: .1.3.6.1.2.1.1.9.1.4.4  TimeTicks  number: 92
6. oid: .1.3.6.1.2.1.1.9.1.3.5  OctetString  string: View-based Access Control Model for SNMP.
7. oid: .1.3.6.1.2.1.1.9.1.4.5  TimeTicks  number: 92
8. oid: .1.3.6.1.2.1.1.9.1.3.6  OctetString  string: The MIB module for managing TCP implementations
9. oid: .1.3.6.1.2.1.1.9.1.4.6  TimeTicks  number: 92

改为自己创建snmp实例,不使用default实例

package main

import (
	"fmt"
	g "github.com/gosnmp/gosnmp"
	"log"
	"time"
)
func main() {
	//g.Default.Target = "192.168.127.152"
	//g.Default.Community = "public"
	//g.Default.Version = g.Version2c
	//g.Default.Timeout = time.Duration(1) * time.Second
	//g.Default.Retries = 4
	//g.Default.ExponentialTimeout = false
	//err := g.Default.Connect()

	var target = &g.GoSNMP{
		Target: "192.168.127.152",
		Port:               161,
		Transport:          "udp",
		Community:          "public",
		Version:            g.Version2c,
		Timeout:            time.Duration(2) * time.Second,
		Retries:            3,
		ExponentialTimeout: false,
		MaxOids:            g.MaxOids,
	}
	err := target.Connect()
	log.Println("hello")
	if err != nil {
		log.Fatalf("Connect() err: %v", err)
	}

	defer target.Conn.Close()

	oids := []string{"1.3.6.1.2.1.1.5.0","1.3.6.1.2.1.1.7.0"}
	result, err := target.Get(oids) // Get() accepts up to g.MAX_OIDS
	if err != nil {
		log.Fatalf("Get() err: %v", err)
	}
	printVariables(result)


	oids = []string{"1.3.6.1.2.1.1.4.0","1.3.6.1.2.1.1.5.0"}
	result, err = target.GetNext(oids) // Get() accepts up to g.MAX_OIDS
	if err != nil {
		log.Fatalf("Get() err: %v", err)
	}
	printVariables(result)

	oids = []string{"1.3.6.1.2.1.1.3.0","1.3.6.1.2.1.1.4.0",".1.3.6.1.2.1.1.9.1.3.2",".1.3.6.1.2.1.1.9.1.4.2"}
	result, err = target.GetBulk(oids,2,4) // Get() accepts up to g.MAX_OIDS
	if err != nil {
		log.Fatalf("Get() err: %v", err)
	}
	printVariables(result)
}

func printVariables(result *g.SnmpPacket) {
	fmt.Println("---------")
	for i, v := range result.Variables {
		fmt.Printf("%d. oid: %s  %s", i, v.Name, v.Type)

		// the Value of each variable returned by Get() implements
		// interface{}. You could do a type switch...
		switch v.Type {
		case g.OctetString:
			fmt.Printf("  string: %s\n", string(v.Value.([]byte)))
		default:
			// ... or often you're just interested in numeric values.
			// ToBigInt() will return the Value as a BigInt, for plugging
			// into your calculations.
			fmt.Printf("  number: %d\n", g.ToBigInt(v.Value))
		}
	}
}

3、snmp4j-agent

网上manager的代码比较多,agent的代码很少。

记录一下agent的代码实现。

这段代码,同时支持v1,v2和v3。 演示的是agent收到消息(set、get、getnext等)后,先发送一个trap,然后发响应消息。  通过抓包可以看到,v1和v2传输是明文的,v3(包括v3 trap)都是密文的。v2和v3很多时候,类是不一样的,比如target和pdu类。另外,发trap消息,和发其他消息差不多,都是要用snmp.send到target。 trap消息前两个oid是固定的,一个是时间戳,一个是trap的oid。如果写错了,mib浏览器就无法显示trap详情。

	<dependency>
	  <groupId>org.snmp4j</groupId>
	  <artifactId>snmp4j-agent</artifactId>
	  <version>2.7.4</version>
	</dependency>

import java.io.IOException;
import java.util.Date;
import java.util.Objects;
import java.util.Vector;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.CommunityTarget;
import org.snmp4j.MessageDispatcher;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.MessageException;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.UserTarget;
import org.snmp4j.event.AuthenticationFailureEvent;
import org.snmp4j.event.AuthenticationFailureListener;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.mp.StatusInformation;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TimeTicks;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class SnmpAgent implements CommandResponder{
    private Snmp snmp;
    private CommunityTarget targetv2;
    private UserTarget targetv3;
    
    public void start() throws Exception{
        initTarget() ;
        
        MessageDispatcherImpl dispatcher = new MessageDispatcherImpl();
        
        dispatcher.addAuthenticationFailureListener(new AuthenticationFailureListener() {
            @Override
            public void authenticationFailure(AuthenticationFailureEvent event) {
                System.out.println("AuthenticationFailureEvent : " + event.getError());
                /**
                 * v3 协议中, manager第一次不知道agent的引擎ID,所以发送空的引擎ID,用户名为Initial
                 * agent 回复错误,这里有1410错误打印。(错误信息中包含引擎ID和boot次数)
                 * manager 再发送消息
                 * agent 回复错误,这里有1411错误打印。(错误信息包含agent的运行时间,用户时间同步)
                 * manager 再发消息,才能成功。
                 * 即snmp v3有两次握手过程,然后才能正式通讯。
                 */
                
                if(event.getError() == SnmpConstants.SNMPv3_USM_AUTHENTICATION_FAILURE) {
                    System.out.println(SnmpConstants.SNMPv3_USM_AUTHENTICATION_FAILURE);
                }
                
            }
        });
        
        
        DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping(new UdpAddress("10.137.157.81/30161"));
        dispatcher.addTransportMapping(transport);
        dispatcher.addMessageProcessingModel(new MPv1());
        dispatcher.addMessageProcessingModel(new MPv2c());
        
        byte[] engineId = "0123456789".getBytes();//UUID.randomUUID().toString().replaceAll("-", "").getBytes("utf-8");
        USM usm = new USM(SecurityProtocols.getInstance().addDefaultProtocols(), new OctetString(engineId), 1);
       
        String userName="ommbZT",password1="public123",password2="public123";
        UsmUser user = new UsmUser(new OctetString(userName), 
                AuthMD5.ID, new OctetString(password1),
                PrivDES.ID, new OctetString(password2));
        usm.addUser(user.getSecurityName(), user);
        
        dispatcher.addMessageProcessingModel(new MPv3(usm));
        
        snmp = new Snmp(dispatcher, transport);
        snmp.addCommandResponder(this);
        snmp.listen();
    }
    
    public void stop() throws Exception{
        if(snmp!=null) {
            snmp.close();
        }
    }
    @Override
    public void processPdu(CommandResponderEvent event) {
        System.out.println(new Date() + " CommandResponderEvent : " + event);
       
        PDU command = event.getPDU(); 
        
        Vector<VariableBinding> variableBindings = (Vector<VariableBinding>) command.getVariableBindings();
        for (VariableBinding variableBinding : variableBindings) {
            variableBinding.setVariable(new OctetString("hello"));
        }  
        
        PDU pdu = new PDU(event.getPDU());
        if(event.getSecurityLevel() == SnmpConstants.version3) {
            pdu = new ScopedPDU((ScopedPDU)event.getPDU());
        }
        pdu.setType(PDU.RESPONSE);

        
        try {

            if(event.getSecurityLevel() == SnmpConstants.version3) {
                targetv3.setAddress(new UdpAddress("10.4.201.243/30162"));
                targetv3.setSecurityName(new OctetString(event.getSecurityName()));
                
                ScopedPDU pduV3Trap = new ScopedPDU();
                pduV3Trap.setType(PDU.TRAP);
                pduV3Trap.add(new VariableBinding(new OID(".1.3.6.1.2.1.1.3.0"), new TimeTicks(0)));
                pduV3Trap.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.0"), new OID(".1.3.6.1.6.3.1.1.4.1.0")));
                pduV3Trap.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.1"), new OctetString("hello")));
                pduV3Trap.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.2"), new Integer32(1)));
                pduV3Trap.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.3"), new Integer32(2)));
                pduV3Trap.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.4"), new Integer32(3)));
              sendV3Trap(pduV3Trap);
            }
            if(event.getSecurityLevel() == SnmpConstants.version2c) {
                targetv2.setAddress(new UdpAddress("10.4.201.243/30162"));
                
                PDU trapPDU = new PDU();
                
                trapPDU.setType(PDU.TRAP);
                trapPDU.add(new VariableBinding(new OID(".1.3.6.1.2.1.1.3.0"), new TimeTicks(System.currentTimeMillis()/1000)));
                trapPDU.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.0"), new OID(".1.3.6.1.6.3.1.1.4.1.0")));
                trapPDU.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.1"), new OctetString("hello")));
                trapPDU.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.2"), new Integer32(1)));
                trapPDU.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.3"), new Integer32(2)));
                trapPDU.add(new VariableBinding(new OID(".1.3.6.1.6.3.1.1.4.1.4"), new Integer32(3)));
                sendV2Trap(trapPDU);
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        
        MessageDispatcher messageDispatcher = event.getMessageDispatcher();
       
        try {
            messageDispatcher.returnResponsePdu(event.getMessageProcessingModel(), event.getSecurityModel(),
                        event.getSecurityName(), event.getSecurityLevel(), pdu, event.getMaxSizeResponsePDU(),
                        event.getStateReference(), new StatusInformation());
        } catch (MessageException e) {
           
            e.printStackTrace();
        }
        
        event.setProcessed(true);
    }
    private void initTarget() {
        targetv2 = new CommunityTarget(); 
        targetv2.setRetries(1);
        targetv2.setTimeout(1500);
        targetv2.setCommunity(new OctetString("public"));
        targetv2.setVersion(SnmpConstants.version2c);
        
        targetv3 = new UserTarget();
        targetv3.setRetries(1);
        targetv3.setTimeout(1500);
        targetv3.setVersion(SnmpConstants.version3);
        targetv3.setSecurityLevel(SecurityLevel.AUTH_PRIV);
    }
    public void sendV2Trap(PDU pdu) throws IOException {
        ResponseEvent respEvent = null;
        try {
            respEvent = snmp.send(pdu, targetv2);
        } catch (IOException ex) {
            System.out.println( ex);
            throw ex;
        }

        if (!pdu.isConfirmedPdu() && respEvent == null) {
            System.out.println("send trap to target : "+targetv2.getAddress()+" successfully, no need to confirm");
            return;
        }

        if (respEvent == null) {
            System.out.println("no response received from target :"+targetv2.getAddress());
            throw new IOException(String.format("no response received from target : %s", targetv2.getAddress().toString()));
        }
        handleResponseEvent(respEvent);
    }
    public void sendV3Trap(ScopedPDU pdu) throws IOException {

        pdu.setContextEngineID(new OctetString(MPv3.createLocalEngineID()));
        ResponseEvent respEvent = null;
        try {
            respEvent = snmp.send(pdu, targetv3);
        } catch (IOException ex) {
            System.out.println( ex);
            throw ex;
        }

        if (!pdu.isConfirmedPdu() && respEvent == null) {
            System.out.println("send trap to target : "+targetv3.getAddress()+" successfully, no need to confirm");
            return;
        }

        if (respEvent == null) {
            System.out.println("no response received from target :"+targetv3.getAddress());
            throw new IOException(String.format("no response received from target : %s", targetv3.getAddress().toString()));
        }
        handleResponseEvent(respEvent);
    }

    private void handleResponseEvent(ResponseEvent respEvent) {
        PDU response = respEvent.getResponse();
        PDU request = respEvent.getRequest();
        if (Objects.isNull(response)) {
            System.out.println("response is empty for request :"+ request);
            return;
        }

        System.out.println("received response : "+response+" on request : "+request+" from : "+respEvent.getPeerAddress());
        Vector<VariableBinding> recVBs = (Vector<VariableBinding>) response.getVariableBindings();
        recVBs.stream().forEach(variableBinding -> System.out.println("oid : "+variableBinding.getOid()+" variable : "+variableBinding.getVariable()));
    }

}


public class App {
    public static void main(String[] args) throws Exception{
        System.out.println("Hello World!");
        new SnmpAgent().start();
        Thread.sleep(365*24*3600*1000);
    }
}

测试命令:snmpget -r 1 -v2c -c public 10.137.157.81:30161 .1.3.6.1.2.1.1.9.1.3.8.0
snmpget -r 1 -v3 -u ommbZT  -l authPriv -a MD5 -A public123 -x DES -X public123 10.137.157.81:30161 .1.3.6.1.2.1.1.9.1.3.8.0

控制台打印:
Hello World!
Sun Oct 03 00:56:29 CST 2021 CommandResponderEvent : CommandResponderEvent[securityModel=2, securityLevel=1, maxSizeResponsePDU=65535, pduHandle=PduHandle[1242598624], stateReference=StateReference[msgID=0,pduHandle=PduHandle[1242598624],securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=GET[requestID=1242598624, errorStatus=Success(0), errorIndex=0, VBS[1.3.6.1.2.1.1.9.1.3.8.0 = Null]], messageProcessingModel=1, securityName=public, processed=false, peerAddress=10.4.201.243/54744, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@c3f89a, tmStateReference=null]
send trap to target : 10.4.201.243/30162 successfully, no need to confirm
AuthenticationFailureEvent : 1410
AuthenticationFailureEvent : 1411
Sun Oct 03 00:57:08 CST 2021 CommandResponderEvent : CommandResponderEvent[securityModel=3, securityLevel=3, maxSizeResponsePDU=65325, pduHandle=PduHandle[315369337], stateReference=StateReference[msgID=2003855890,pduHandle=null,securityEngineID=0123456789,securityModel=org.snmp4j.security.USM@1e4bf0b,securityName=ommbZT,securityLevel=3,contextEngineID=0123456789,contextName=,retryMsgIDs=null], pdu=GET[{contextEngineID=0123456789, contextName=}, requestID=315369337, errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.9.1.3.8.0 = Null]], messageProcessingModel=3, securityName=ommbZT, processed=false, peerAddress=10.4.201.243/54614, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@c3f89a, tmStateReference=null]
send trap to target : 10.4.201.243/30162 successfully, no need to confirm

4、trap发送和接收

参考:利用SNMP4J实现 Snmp Trap 完整例子_gaohaicheng123的博客-CSDN博客

snmptrap -v 2c -c public 192.168.1.4:162 "" .1.2.5.5  .1.8.8.0 s "just here8888"

这个v2c的trap,java和snmptrapd都能收到并解析。 

snmptrap -v3 -l authPriv -u ommbZT -a MD5 -A public123 -x DES -X public123  192.168.1.4:162 "" .1.2.5.5  .1.8.8.0 s "just here8888"

这个trap,java程序能够收到并解码。用户名错误,或者加密算法不对,java都会报错。但看tcpdump抓包来看,trap消息只有一次发送,没有两次握手过程。

snmptrapd也能收到(java或snmptrap命令)发送的trap,但无法解码,应该是哪里还需要配置用户、密码等信息。

package gaofeng.snmp;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.PDUv1;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TimeTicks;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class Trap {

    public static void main(String[] args) throws Exception {
        sendV3();
    }
    public static ResponseEvent sendV1Trap() throws Exception {
        Snmp snmp = new Snmp(new DefaultUdpTransportMapping(new UdpAddress("0.0.0.0/161")));

        PDUv1 pdu = new PDUv1();
        VariableBinding v = new VariableBinding();
        v.setOid(SnmpConstants.sysName);
        v.setVariable(new OctetString("Snmp Trap V1 Test"));
        pdu.add(v);
        pdu.setType(PDU.V1TRAP);

        // set target
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));
        target.setAddress(new UdpAddress("192.168.127.152/162"));

        target.setRetries(2);
        target.setTimeout(1500);
        target.setVersion(SnmpConstants.version1);

        return snmp.send(pdu, target);
    }

    public static ResponseEvent sendV2cTrap() throws Exception {
        Snmp snmp = new Snmp(new DefaultUdpTransportMapping(new UdpAddress("0.0.0.0/161")));
        PDU pdu = new PDU();
        pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.3.0"),new TimeTicks(5000)));
        pdu.add(new VariableBinding(new OID("1.3.6.1.6.3.1.1.4.1.0"),new OID("1.2.5.5")));
        pdu.add(new VariableBinding(new OID("1.8.8.0"),new OctetString("just here8888")));
        
        pdu.setType(PDU.TRAP);

        // set target
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));
        target.setAddress(new UdpAddress("192.168.127.152/162"));

        target.setRetries(2);
        target.setTimeout(1500);
        target.setVersion(SnmpConstants.version2c);
        // send pdu, return response
        return snmp.send(pdu, target);

    }
    
    public static ResponseEvent sendV3() throws Exception{
        Snmp snmp = new Snmp(new DefaultUdpTransportMapping(new UdpAddress("0.0.0.0/161")));
        PDU pdu = new ScopedPDU();
        pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.3.0"),new TimeTicks(5000)));
        pdu.add(new VariableBinding(new OID("1.3.6.1.6.3.1.1.4.1.0"),new OID("1.2.5.5")));
        pdu.add(new VariableBinding(new OID("1.8.8.0"),new OctetString("just here8888")));
        
        pdu.setType(PDU.TRAP);

        USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 500);   
        SecurityModels.getInstance().addSecurityModel(usm);   

        UserTarget target = new UserTarget();

        byte[] enginId = "TEO_ID".getBytes();

            UsmUser user = new UsmUser(new OctetString("ommbZT"),AuthMD5.ID,new OctetString("public123"),PrivDES.ID,new OctetString("public123"));
            snmp.getUSM().addUser(user.getSecurityName(),user);

            target.setAddress(new UdpAddress("127.0.0.1/162")); 
//            target.setAddress(new UdpAddress("192.168.127.152/162")); 
            target.setRetries(2);   
            target.setTimeout(3000);   
            target.setVersion(SnmpConstants.version3);   
//            target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV);   
            target.setSecurityLevel(SecurityLevel.AUTH_PRIV);   
            target.setSecurityName(user.getSecurityName()); 
            
            snmp.setLocalEngine(enginId, 500, 1);
            ResponseEvent responseEvent = snmp.send(pdu, target);
            //System.out.println(responseEvent.getError());

            return responseEvent;
        }
}
traplistener.java

package gaofeng.snmp;


import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.AuthenticationFailureEvent;
import org.snmp4j.event.AuthenticationFailureListener;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.Priv3DES;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.DefaultUdpTransportMapping;

/**
 * Hello world!
 *
 */
public class App {
    public static void main( String[] args ) throws Exception{
        System.out.println( "Hello World!" );
        TransportMapping transport = new DefaultUdpTransportMapping(new UdpAddress("0.0.0.0/162"));
        MessageDispatcherImpl dispatcher = new MessageDispatcherImpl();
        dispatcher.addAuthenticationFailureListener(new AuthenticationFailureListener() {
            @Override
            public void authenticationFailure(AuthenticationFailureEvent event) {
                System.out.println("AuthenticationFailureEvent : " + event.getError());  
            }
        });
        
        Snmp snmp = new Snmp(dispatcher, transport);
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());  
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());  
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());  
        UsmUser usmUser = new UsmUser(new OctetString("ommbZT"), AuthMD5.ID,
                new OctetString("public123"), PrivDES.ID,
                new OctetString("public123"));

        USM usm = new USM(SecurityProtocols.getInstance().addDefaultProtocols(), new OctetString(MPv3  
                .createLocalEngineID()), 0); 
        usm.addUser(usmUser);
        SecurityModels.getInstance().addSecurityModel(usm);  
        snmp.listen();
        
        snmp.addCommandResponder(new CommandResponder() {

            @Override
            public void processPdu(CommandResponderEvent event) {
                System.out.println(event);
            }
            
        }); 
        Thread.sleep(365*24*3600*1000);

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值