gosnmp
/
trap_test.go
1408 строк · 34.9 Кб
1// Copyright 2012 The GoSNMP Authors. All rights reserved. Use of this
2// source code is governed by a BSD-style license that can be found in the
3// LICENSE file.
4
5//go:build all || trap
6// +build all trap
7
8package gosnmp9
10import (11"io"12"log"13"net"14"reflect"15"testing"16"time"17
18"github.com/stretchr/testify/require"19)
20
21const (22trapTestAddress = "127.0.0.1"23
24// TODO this is bad. Listen and Connect expect different address formats25// so we need an int version and a string version - they should be the same.26trapTestPort = 916227trapTestPortString = "9162"28
29trapTestOid = ".1.2.1234.4.5"30trapTestPayload = "TRAPTEST1234"31
32trapTestEnterpriseOid = ".1.2.1234"33trapTestAgentAddress = "127.0.0.1"34trapTestGenericTrap = 635trapTestSpecificTrap = 5536trapTestTimestamp = 30037)
38
39var secParamsList = []*UsmSecurityParameters{40&UsmSecurityParameters{41UserName: "myuser",42AuthenticationProtocol: MD5,43AuthenticationPassphrase: "mypassword",44Logger: NewLogger(log.New(io.Discard, "", 0)),45},46&UsmSecurityParameters{47UserName: "myuser1",48AuthenticationProtocol: MD5,49AuthenticationPassphrase: "mypassword1",50PrivacyProtocol: AES,51PrivacyPassphrase: "myprivacy1",52Logger: NewLogger(log.New(io.Discard, "", 0)),53},54&UsmSecurityParameters{55UserName: "myuser2",56AuthenticationProtocol: SHA,57AuthenticationPassphrase: "mypassword2",58PrivacyProtocol: DES,59PrivacyPassphrase: "myprivacy2",60Logger: NewLogger(log.New(io.Discard, "", 0)),61},62&UsmSecurityParameters{63UserName: "myuser2",64AuthenticationProtocol: MD5,65AuthenticationPassphrase: "mypassword2",66PrivacyProtocol: AES,67PrivacyPassphrase: "myprivacy2",68Logger: NewLogger(log.New(io.Discard, "", 0)),69},70}
71
72var testsUnmarshalTrap = []struct {73in func() []byte74out *SnmpPacket75}{76{genericV3Trap,77&SnmpPacket{78Version: Version3,79PDUType: SNMPv2Trap,80RequestID: 957979745,81MsgFlags: AuthNoPriv,82SecurityParameters: &UsmSecurityParameters{83UserName: "myuser",84AuthenticationProtocol: MD5,85AuthenticationPassphrase: "mypassword",86Logger: NewLogger(log.New(io.Discard, "", 0)),87},88},89},90{91snmpV3AuthPrivTrap,92&SnmpPacket{93Version: 3,94PDUType: SNMPv2Trap,95RequestID: 1318065890,96MsgFlags: AuthPriv,97SecurityParameters: &UsmSecurityParameters{98UserName: "myuser2",99AuthenticationProtocol: MD5,100AuthenticationPassphrase: "mypassword2",101PrivacyProtocol: AES,102PrivacyPassphrase: "myprivacy2",103Logger: NewLogger(log.New(io.Discard, "", 0)),104},105},106},107}
108
109func TestUnmarshalTrap(t *testing.T) {110Default.Logger = NewLogger(log.New(io.Discard, "", 0))111
112SANITY:113for i, test := range testsUnmarshalTrap {114
115Default.SecurityParameters = test.out.SecurityParameters.Copy()116Default.Version = Version3117var buf = test.in()118res, err := Default.UnmarshalTrap(buf, true)119require.NoError(t, err, "unmarshalTrap failed")120if res == nil {121t.Errorf("#%d, UnmarshalTrap returned nil", i)122continue SANITY123}124
125// test enough fields to ensure unmarshalling was successful.126// full unmarshal testing is performed in TestUnmarshal127if res.Version != test.out.Version {128t.Errorf("#%d Version result: %v, test: %v", i, res.Version, test.out.Version)129}130if res.RequestID != test.out.RequestID {131t.Errorf("#%d RequestID result: %v, test: %v", i, res.RequestID, test.out.RequestID)132}133}134}
135
136func TestUnmarshalTrapWithMultipleUsers(t *testing.T) {137Default.Logger = NewLogger(log.New(io.Discard, "", 0))138usmMap := NewSnmpV3SecurityParametersTable(NewLogger(log.New(io.Discard, "", 0)))139for _, sp := range secParamsList {140usmMap.Add(sp.UserName, sp)141}142SANITY:143for i, test := range testsUnmarshalTrap {144Default.TrapSecurityParametersTable = usmMap145Default.Version = Version3146var buf = test.in()147res, err := Default.UnmarshalTrap(buf, true)148require.NoError(t, err, "unmarshalTrap failed")149if res == nil {150t.Errorf("#%d, UnmarshalTrap returned nil", i)151continue SANITY152}153
154// test enough fields to ensure unmarshalling was successful.155// full unmarshal testing is performed in TestUnmarshal156require.Equal(t, test.out.Version, res.Version)157require.Equal(t, test.out.RequestID, res.RequestID)158
159Default.TrapSecurityParametersTable = nil160}161}
162
163func genericV3Trap() []byte {164return []byte{1650x30, 0x81, 0xd7, 0x02, 0x01, 0x03, 0x30, 0x11, 0x02, 0x04, 0x62, 0xaf,1660x5a, 0x8e, 0x02, 0x03, 0x00, 0xff, 0xe3, 0x04, 0x01, 0x01, 0x02, 0x01,1670x03, 0x04, 0x33, 0x30, 0x31, 0x04, 0x11, 0x80, 0x00, 0x1f, 0x88, 0x80,1680x77, 0xdf, 0xe4, 0x4f, 0xaa, 0x70, 0x02, 0x58, 0x00, 0x00, 0x00, 0x00,1690x02, 0x01, 0x0f, 0x02, 0x01, 0x00, 0x04, 0x06, 0x6d, 0x79, 0x75, 0x73,1700x65, 0x72, 0x04, 0x0c, 0xd8, 0xb6, 0x9c, 0xb8, 0x22, 0x91, 0xfc, 0x65,1710xb6, 0x84, 0xcb, 0xfe, 0x04, 0x00, 0x30, 0x81, 0x89, 0x04, 0x11, 0x80,1720x00, 0x1f, 0x88, 0x80, 0x77, 0xdf, 0xe4, 0x4f, 0xaa, 0x70, 0x02, 0x58,1730x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xa7, 0x72, 0x02, 0x04, 0x39, 0x19,1740x9c, 0x61, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x64, 0x30, 0x0f,1750x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x43, 0x03,1760x15, 0x2f, 0xec, 0x30, 0x14, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x06, 0x03,1770x01, 0x01, 0x04, 0x01, 0x00, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x02, 0x01,1780x01, 0x30, 0x16, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01,1790x00, 0x04, 0x0a, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x61, 0x70, 0x74, 0x6f,1800x70, 0x30, 0x0d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x07,1810x00, 0x02, 0x01, 0x05, 0x30, 0x14, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02,1820x01, 0x01, 0x02, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x03,1830x04, 0x05}184}
185
186/*
187snmptrap -v3 -l authPriv -u myuser2 -a MD5 -A mypassword2 -x AES -X myprivacy2 127.0.0.1:9162 ” 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 60
188*/
189func snmpV3AuthPrivTrap() []byte {190return []byte{1910x30, 0x81, 0xbb, 0x02, 0x01, 0x03, 0x30, 0x11, 0x02, 0x04, 0x3a, 0x1c,1920xf4, 0xf7, 0x02, 0x03, 0x00, 0xff, 0xe3, 0x04, 0x01, 0x03, 0x02, 0x01,1930x03, 0x04, 0x3c, 0x30, 0x3a, 0x04, 0x11, 0x80, 0x00, 0x1f, 0x88, 0x80,1940x6b, 0x8f, 0xad, 0x3b, 0x07, 0xc2, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00,1950x02, 0x01, 0x01, 0x02, 0x01, 0x00, 0x04, 0x07, 0x6d, 0x79, 0x75, 0x73,1960x65, 0x72, 0x32, 0x04, 0x0c, 0xa8, 0xe2, 0xf4, 0xab, 0x3c, 0xd5, 0x9c,1970x22, 0x5e, 0x0a, 0x12, 0xdd, 0x04, 0x08, 0x95, 0x7b, 0xdc, 0x33, 0x6a,1980xf4, 0x3c, 0x8f, 0x04, 0x65, 0x70, 0x64, 0xbd, 0xcf, 0x4b, 0xa8, 0x19,1990xda, 0xf4, 0x0d, 0x09, 0x8f, 0x7a, 0x28, 0xa6, 0x82, 0x00, 0xe0, 0xbd,2000x96, 0x76, 0xf8, 0xc2, 0xa3, 0xe3, 0xb0, 0x92, 0x00, 0x82, 0x2d, 0xba,2010xce, 0x34, 0x2f, 0x53, 0x19, 0x18, 0xba, 0xfc, 0xe5, 0xf5, 0x0e, 0x9a,2020xba, 0x52, 0xaf, 0x6b, 0x67, 0xaa, 0x20, 0x23, 0xb5, 0x17, 0x04, 0x7e,2030x17, 0x08, 0xb8, 0xc6, 0x67, 0x14, 0xb5, 0x91, 0x4d, 0x6b, 0xd8, 0xbf,2040x94, 0x24, 0x22, 0x0f, 0x21, 0x4f, 0xde, 0x6f, 0x41, 0x51, 0xa6, 0x10,2050x86, 0xf2, 0x01, 0xd1, 0xd6, 0xa9, 0x3c, 0x88, 0xea, 0x41, 0x25, 0x25,2060xbc, 0x12, 0x12, 0xa6, 0xd6, 0x8f, 0x55, 0x6a, 0x55, 0xcb}207}
208
209func makeTestTrapHandler(t *testing.T, done chan int, version SnmpVersion) func(*SnmpPacket, *net.UDPAddr) {210Default.Logger = NewLogger(log.New(io.Discard, "", 0))211return func(packet *SnmpPacket, addr *net.UDPAddr) {212//log.Printf("got trapdata from %s\n", addr.IP)213defer close(done)214
215if version == Version1 {216if packet.Enterprise != trapTestEnterpriseOid {217t.Fatalf("incorrect trap Enterprise OID received, expected %s got %s", trapTestEnterpriseOid, packet.Enterprise)218}219if packet.AgentAddress != trapTestAgentAddress {220t.Fatalf("incorrect trap Agent Address received, expected %s got %s", trapTestAgentAddress, packet.AgentAddress)221}222if packet.GenericTrap != trapTestGenericTrap {223t.Fatalf("incorrect trap Generic Trap identifier received, expected %v got %v", trapTestGenericTrap, packet.GenericTrap)224}225if packet.SpecificTrap != trapTestSpecificTrap {226t.Fatalf("incorrect trap Specific Trap identifier received, expected %v got %v", trapTestSpecificTrap, packet.SpecificTrap)227}228if packet.Timestamp != trapTestTimestamp {229t.Fatalf("incorrect trap Timestamp received, expected %v got %v", trapTestTimestamp, packet.Timestamp)230}231}232
233for _, v := range packet.Variables {234switch v.Type {235case OctetString:236b := v.Value.([]byte)237// log.Printf("OID: %s, string: %x\n", v.Name, b)238
239// Only one OctetString in the payload, so it must be the expected one240if v.Name != trapTestOid {241t.Fatalf("incorrect trap OID received, expected %s got %s", trapTestOid, v.Name)242}243if string(b) != trapTestPayload {244t.Fatalf("incorrect trap payload received, expected %s got %x", trapTestPayload, b)245}246default:247// log.Printf("trap: %+v\n", v)248}249}250}251}
252
253// TODO: This restores global state set by other tests so that these tests can
254// run. Tests should be avoiding use of global state where possible (and, if
255// possible, use of global state other than possibly loggers should be
256// eliminated entirely).
257func TestRestoreGlobals(t *testing.T) {258Default.Version = Version2c259Default.SecurityModel = 0260Default.SecurityParameters = nil261}
262
263// test sending a basic SNMP trap, using our own listener to receive
264func TestSendTrapBasic(t *testing.T) {265done := make(chan int)266
267tl := NewTrapListener()268defer tl.Close()269
270tl.OnNewTrap = makeTestTrapHandler(t, done, Version2c)271tl.Params = Default272
273// listener goroutine274errch := make(chan error)275go func() {276// defer close(errch)277err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))278if err != nil {279errch <- err280}281}()282
283// Wait until the listener is ready.284select {285case <-tl.Listening():286case err := <-errch:287t.Fatalf("error in listen: %v", err)288}289ts := &GoSNMP{290Target: trapTestAddress,291Port: trapTestPort,292Community: "public",293Version: Version2c,294Timeout: time.Duration(2) * time.Second,295Retries: 3,296MaxOids: MaxOids,297Logger: NewLogger(log.New(io.Discard, "", 0)),298}299
300err := ts.Connect()301if err != nil {302t.Fatalf("Connect() err: %v", err)303}304defer ts.Conn.Close()305
306pdu := SnmpPDU{307Name: trapTestOid,308Type: OctetString,309Value: trapTestPayload,310}311
312trap := SnmpTrap{313Variables: []SnmpPDU{pdu},314}315
316_, err = ts.SendTrap(trap)317if err != nil {318t.Fatalf("SendTrap() err: %v", err)319}320
321// wait for response from handler322select {323case <-done:324case <-time.After(2 * time.Second):325t.Fatal("timed out waiting for trap to be received")326}327}
328
329// test sending a basic SNMP inform and receiving the response
330func TestSendInformBasic(t *testing.T) {331done := make(chan int)332
333tl := NewTrapListener()334defer tl.Close()335
336tl.OnNewTrap = makeTestTrapHandler(t, done, Version2c)337tl.Params = Default338
339// listener goroutine340errch := make(chan error)341go func() {342// defer close(errch)343err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))344if err != nil {345errch <- err346}347}()348
349// Wait until the listener is ready.350select {351case <-tl.Listening():352case err := <-errch:353t.Fatalf("error in listen: %v", err)354}355
356ts := &GoSNMP{357Target: trapTestAddress,358Port: trapTestPort,359Community: "public",360Version: Version2c,361Timeout: time.Duration(2) * time.Second,362Retries: 3,363MaxOids: MaxOids,364}365
366err := ts.Connect()367if err != nil {368t.Fatalf("Connect() err: %v", err)369}370defer ts.Conn.Close()371
372pdu := SnmpPDU{373Name: trapTestOid,374Type: OctetString,375Value: trapTestPayload,376}377
378// Make it an inform.379trap := SnmpTrap{380Variables: []SnmpPDU{pdu},381IsInform: true,382}383
384var resp *SnmpPacket385resp, err = ts.SendTrap(trap)386if err != nil {387t.Fatalf("SendTrap() err: %v", err)388}389
390// wait for response from handler391select {392case <-done:393case <-time.After(2 * time.Second):394t.Fatal("timed out waiting for trap to be received")395}396
397if resp.PDUType != GetResponse {398t.Fatal("Inform response is not a response PDU")399}400
401for i, tv := range trap.Variables {402rv := resp.Variables[i+1]403if reflect.DeepEqual(tv, rv) {404t.Fatalf("Expected variable %d = %#v, got %#v", i, tv, rv)405}406}407}
408
409// test the listener is not blocked if Listening is not used
410func TestSendTrapWithoutWaitingOnListen(t *testing.T) {411done := make(chan int)412
413tl := NewTrapListener()414defer tl.Close()415
416tl.OnNewTrap = makeTestTrapHandler(t, done, Version2c)417tl.Params = Default418
419errch := make(chan error)420listening := make(chan bool)421go func() {422// Reduce the chance of necessity for a restart.423listening <- true424
425err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))426if err != nil {427errch <- err428}429}()430
431select {432case <-listening:433case err := <-errch:434t.Fatalf("error in listen: %v", err)435}436
437ts := &GoSNMP{438Target: trapTestAddress,439Port: trapTestPort,440Community: "public",441Version: Version2c,442Timeout: time.Duration(2) * time.Second,443Retries: 3,444MaxOids: MaxOids,445}446
447err := ts.Connect()448if err != nil {449t.Fatalf("Connect() err: %v", err)450}451defer ts.Conn.Close()452
453pdu := SnmpPDU{454Name: trapTestOid,455Type: OctetString,456Value: trapTestPayload,457}458
459trap := SnmpTrap{460Variables: []SnmpPDU{pdu},461}462
463_, err = ts.SendTrap(trap)464if err != nil {465t.Fatalf("SendTrap() err: %v", err)466}467
468// Wait for a response from the handler and restart the SendTrap469// if the listener wasn't ready.470select {471case <-done:472case <-time.After(2 * time.Second):473_, err = ts.SendTrap(trap)474if err != nil {475t.Fatalf("restarted SendTrap() err: %v", err)476}477
478t.Log("restarted")479
480select {481case <-done:482case <-time.After(2 * time.Second):483t.Fatal("timed out waiting for trap to be received")484}485}486}
487
488// test sending a basic SNMP trap, using our own listener to receive
489func TestSendV1Trap(t *testing.T) {490done := make(chan int)491
492tl := NewTrapListener()493defer tl.Close()494
495tl.OnNewTrap = makeTestTrapHandler(t, done, Version1)496tl.Params = Default497
498// listener goroutine499errch := make(chan error)500go func() {501err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))502if err != nil {503errch <- err504}505}()506
507// Wait until the listener is ready.508select {509case <-tl.Listening():510case err := <-errch:511t.Fatalf("error in listen: %v", err)512}513
514ts := &GoSNMP{515Target: trapTestAddress,516Port: trapTestPort,517//Community: "public",518Version: Version1,519Timeout: time.Duration(2) * time.Second,520Retries: 3,521MaxOids: MaxOids,522}523
524err := ts.Connect()525if err != nil {526t.Fatalf("Connect() err: %v", err)527}528defer ts.Conn.Close()529
530pdu := SnmpPDU{531Name: trapTestOid,532Type: OctetString,533Value: trapTestPayload,534}535
536trap := SnmpTrap{537Variables: []SnmpPDU{pdu},538Enterprise: trapTestEnterpriseOid,539AgentAddress: trapTestAgentAddress,540GenericTrap: trapTestGenericTrap,541SpecificTrap: trapTestSpecificTrap,542Timestamp: trapTestTimestamp,543}544
545_, err = ts.SendTrap(trap)546if err != nil {547t.Fatalf("SendTrap() err: %v", err)548}549
550// wait for response from handler551select {552case <-done:553case <-time.After(2 * time.Second):554t.Fatal("timed out waiting for trap to be received")555}556}
557
558func TestSendV3TrapNoAuthNoPriv(t *testing.T) {559done := make(chan int)560
561tl := NewTrapListener()562defer tl.Close()563
564sp := &UsmSecurityParameters{565UserName: "test",566AuthoritativeEngineBoots: 1,567AuthoritativeEngineTime: 1,568AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),569}570
571tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)572tl.Params = Default573tl.Params.Version = Version3574tl.Params.SecurityParameters = sp575tl.Params.SecurityModel = UserSecurityModel576tl.Params.MsgFlags = NoAuthNoPriv577
578// listener goroutine579errch := make(chan error)580go func() {581err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))582if err != nil {583errch <- err584}585}()586
587// Wait until the listener is ready.588select {589case <-tl.Listening():590case err := <-errch:591t.Fatalf("error in listen: %v", err)592}593
594ts := &GoSNMP{595Target: trapTestAddress,596Port: trapTestPort,597//Community: "public",598Version: Version3,599Timeout: time.Duration(2) * time.Second,600Retries: 3,601MaxOids: MaxOids,602SecurityModel: UserSecurityModel,603SecurityParameters: sp,604MsgFlags: NoAuthNoPriv,605}606
607err := ts.Connect()608if err != nil {609t.Fatalf("Connect() err: %v", err)610}611defer ts.Conn.Close()612
613pdu := SnmpPDU{614Name: trapTestOid,615Type: OctetString,616Value: trapTestPayload,617}618
619trap := SnmpTrap{620Variables: []SnmpPDU{pdu},621Enterprise: trapTestEnterpriseOid,622AgentAddress: trapTestAgentAddress,623GenericTrap: trapTestGenericTrap,624SpecificTrap: trapTestSpecificTrap,625Timestamp: trapTestTimestamp,626}627
628_, err = ts.SendTrap(trap)629if err != nil {630t.Fatalf("SendTrap() err: %v", err)631}632
633// wait for response from handler634select {635case <-done:636case <-time.After(2 * time.Second):637t.Fatal("timed out waiting for trap to be received")638}639
640}
641
642func TestSendV3TrapMD5AuthNoPriv(t *testing.T) {643done := make(chan int)644
645tl := NewTrapListener()646defer tl.Close()647
648sp := &UsmSecurityParameters{649UserName: "test",650AuthenticationProtocol: MD5,651AuthenticationPassphrase: "password",652AuthoritativeEngineBoots: 1,653AuthoritativeEngineTime: 1,654AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),655}656
657tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)658tl.Params = Default659tl.Params.Version = Version3660tl.Params.SecurityParameters = sp661tl.Params.SecurityModel = UserSecurityModel662tl.Params.MsgFlags = AuthNoPriv663
664// listener goroutine665errch := make(chan error)666go func() {667err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))668if err != nil {669errch <- err670}671}()672
673// Wait until the listener is ready.674select {675case <-tl.Listening():676case err := <-errch:677t.Fatalf("error in listen: %v", err)678}679
680ts := &GoSNMP{681Target: trapTestAddress,682Port: trapTestPort,683//Community: "public",684Version: Version3,685Timeout: time.Duration(2) * time.Second,686Retries: 3,687MaxOids: MaxOids,688SecurityModel: UserSecurityModel,689SecurityParameters: sp,690MsgFlags: AuthNoPriv,691}692
693err := ts.Connect()694if err != nil {695t.Fatalf("Connect() err: %v", err)696}697defer ts.Conn.Close()698
699pdu := SnmpPDU{700Name: trapTestOid,701Type: OctetString,702Value: trapTestPayload,703}704
705trap := SnmpTrap{706Variables: []SnmpPDU{pdu},707Enterprise: trapTestEnterpriseOid,708AgentAddress: trapTestAgentAddress,709GenericTrap: trapTestGenericTrap,710SpecificTrap: trapTestSpecificTrap,711Timestamp: trapTestTimestamp,712}713
714_, err = ts.SendTrap(trap)715if err != nil {716t.Fatalf("SendTrap() err: %v", err)717}718
719// wait for response from handler720select {721case <-done:722case <-time.After(2 * time.Second):723t.Fatal("timed out waiting for trap to be received")724}725
726}
727
728func TestSendV3TrapSHAAuthNoPriv(t *testing.T) {729done := make(chan int)730
731tl := NewTrapListener()732defer tl.Close()733
734sp := &UsmSecurityParameters{735UserName: "test",736AuthenticationProtocol: SHA,737AuthenticationPassphrase: "password",738AuthoritativeEngineBoots: 1,739AuthoritativeEngineTime: 1,740AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),741}742
743tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)744tl.Params = Default745tl.Params.Version = Version3746tl.Params.SecurityParameters = sp747tl.Params.SecurityModel = UserSecurityModel748tl.Params.MsgFlags = AuthNoPriv749
750// listener goroutine751errch := make(chan error)752go func() {753err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))754if err != nil {755errch <- err756}757}()758
759// Wait until the listener is ready.760select {761case <-tl.Listening():762case err := <-errch:763t.Fatalf("error in listen: %v", err)764}765
766ts := &GoSNMP{767Target: trapTestAddress,768Port: trapTestPort,769//Community: "public",770Version: Version3,771Timeout: time.Duration(2) * time.Second,772Retries: 3,773MaxOids: MaxOids,774SecurityModel: UserSecurityModel,775SecurityParameters: sp,776MsgFlags: AuthNoPriv,777}778
779err := ts.Connect()780if err != nil {781t.Fatalf("Connect() err: %v", err)782}783defer ts.Conn.Close()784
785pdu := SnmpPDU{786Name: trapTestOid,787Type: OctetString,788Value: trapTestPayload,789}790
791trap := SnmpTrap{792Variables: []SnmpPDU{pdu},793Enterprise: trapTestEnterpriseOid,794AgentAddress: trapTestAgentAddress,795GenericTrap: trapTestGenericTrap,796SpecificTrap: trapTestSpecificTrap,797Timestamp: trapTestTimestamp,798}799
800_, err = ts.SendTrap(trap)801if err != nil {802t.Fatalf("SendTrap() err: %v", err)803}804
805// wait for response from handler806select {807case <-done:808case <-time.After(2 * time.Second):809t.Fatal("timed out waiting for trap to be received")810}811
812}
813func TestSendV3TrapSHAAuthDESPriv(t *testing.T) {814done := make(chan int)815
816tl := NewTrapListener()817defer tl.Close()818
819sp := &UsmSecurityParameters{820UserName: "test",821AuthenticationProtocol: SHA,822AuthenticationPassphrase: "password",823PrivacyProtocol: DES,824PrivacyPassphrase: "password",825AuthoritativeEngineBoots: 1,826AuthoritativeEngineTime: 1,827AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),828}829
830tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)831tl.Params = Default832tl.Params.Version = Version3833tl.Params.SecurityParameters = sp834tl.Params.SecurityModel = UserSecurityModel835tl.Params.MsgFlags = AuthPriv836
837// listener goroutine838errch := make(chan error)839go func() {840err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))841if err != nil {842errch <- err843}844}()845
846// Wait until the listener is ready.847select {848case <-tl.Listening():849case err := <-errch:850t.Fatalf("error in listen: %v", err)851}852
853ts := &GoSNMP{854Target: trapTestAddress,855Port: trapTestPort,856//Community: "public",857Version: Version3,858Timeout: time.Duration(2) * time.Second,859Retries: 3,860MaxOids: MaxOids,861SecurityModel: UserSecurityModel,862SecurityParameters: sp,863MsgFlags: AuthPriv,864}865
866err := ts.Connect()867if err != nil {868t.Fatalf("Connect() err: %v", err)869}870defer ts.Conn.Close()871
872pdu := SnmpPDU{873Name: trapTestOid,874Type: OctetString,875Value: trapTestPayload,876}877
878trap := SnmpTrap{879Variables: []SnmpPDU{pdu},880Enterprise: trapTestEnterpriseOid,881AgentAddress: trapTestAgentAddress,882GenericTrap: trapTestGenericTrap,883SpecificTrap: trapTestSpecificTrap,884Timestamp: trapTestTimestamp,885}886
887_, err = ts.SendTrap(trap)888if err != nil {889t.Fatalf("SendTrap() err: %v", err)890}891
892// wait for response from handler893select {894case <-done:895case <-time.After(2 * time.Second):896t.Fatal("timed out waiting for trap to be received")897}898
899}
900
901func TestSendV3TrapSHAAuthAESPriv(t *testing.T) {902done := make(chan int)903
904tl := NewTrapListener()905defer tl.Close()906
907sp := &UsmSecurityParameters{908UserName: "test",909AuthenticationProtocol: SHA,910AuthenticationPassphrase: "password",911PrivacyProtocol: AES,912PrivacyPassphrase: "password",913AuthoritativeEngineBoots: 1,914AuthoritativeEngineTime: 1,915AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),916}917
918tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)919tl.Params = Default920tl.Params.Version = Version3921tl.Params.SecurityParameters = sp922tl.Params.SecurityModel = UserSecurityModel923tl.Params.MsgFlags = AuthPriv924
925// listener goroutine926errch := make(chan error)927go func() {928err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))929if err != nil {930errch <- err931}932}()933
934// Wait until the listener is ready.935select {936case <-tl.Listening():937case err := <-errch:938t.Fatalf("error in listen: %v", err)939}940
941ts := &GoSNMP{942Target: trapTestAddress,943Port: trapTestPort,944//Community: "public",945Version: Version3,946Timeout: time.Duration(2) * time.Second,947Retries: 3,948MaxOids: MaxOids,949SecurityModel: UserSecurityModel,950SecurityParameters: sp,951MsgFlags: AuthPriv,952}953
954err := ts.Connect()955if err != nil {956t.Fatalf("Connect() err: %v", err)957}958defer ts.Conn.Close()959
960pdu := SnmpPDU{961Name: trapTestOid,962Type: OctetString,963Value: trapTestPayload,964}965
966trap := SnmpTrap{967Variables: []SnmpPDU{pdu},968Enterprise: trapTestEnterpriseOid,969AgentAddress: trapTestAgentAddress,970GenericTrap: trapTestGenericTrap,971SpecificTrap: trapTestSpecificTrap,972Timestamp: trapTestTimestamp,973}974
975_, err = ts.SendTrap(trap)976if err != nil {977t.Fatalf("SendTrap() err: %v", err)978}979
980// wait for response from handler981select {982case <-done:983case <-time.After(2 * time.Second):984t.Fatal("timed out waiting for trap to be received")985}986
987}
988
989func TestSendV3TrapSHAAuthAES192Priv(t *testing.T) {990done := make(chan int)991
992tl := NewTrapListener()993defer tl.Close()994
995sp := &UsmSecurityParameters{996UserName: "test",997AuthenticationProtocol: SHA,998AuthenticationPassphrase: "password",999PrivacyProtocol: AES192,1000PrivacyPassphrase: "password",1001AuthoritativeEngineBoots: 1,1002AuthoritativeEngineTime: 1,1003AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),1004}1005
1006tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)1007tl.Params = Default1008tl.Params.Version = Version31009tl.Params.SecurityParameters = sp1010tl.Params.SecurityModel = UserSecurityModel1011tl.Params.MsgFlags = AuthPriv1012
1013// listener goroutine1014errch := make(chan error)1015go func() {1016err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))1017if err != nil {1018errch <- err1019}1020}()1021
1022// Wait until the listener is ready.1023select {1024case <-tl.Listening():1025case err := <-errch:1026t.Fatalf("error in listen: %v", err)1027}1028
1029ts := &GoSNMP{1030Target: trapTestAddress,1031Port: trapTestPort,1032//Community: "public",1033Version: Version3,1034Timeout: time.Duration(2) * time.Second,1035Retries: 3,1036MaxOids: MaxOids,1037SecurityModel: UserSecurityModel,1038SecurityParameters: sp,1039MsgFlags: AuthPriv,1040}1041
1042err := ts.Connect()1043if err != nil {1044t.Fatalf("Connect() err: %v", err)1045}1046defer ts.Conn.Close()1047
1048pdu := SnmpPDU{1049Name: trapTestOid,1050Type: OctetString,1051Value: trapTestPayload,1052}1053
1054trap := SnmpTrap{1055Variables: []SnmpPDU{pdu},1056Enterprise: trapTestEnterpriseOid,1057AgentAddress: trapTestAgentAddress,1058GenericTrap: trapTestGenericTrap,1059SpecificTrap: trapTestSpecificTrap,1060Timestamp: trapTestTimestamp,1061}1062
1063_, err = ts.SendTrap(trap)1064if err != nil {1065t.Fatalf("SendTrap() err: %v", err)1066}1067
1068// wait for response from handler1069select {1070case <-done:1071case <-time.After(2 * time.Second):1072t.Fatal("timed out waiting for trap to be received")1073}1074
1075}
1076func TestSendV3TrapSHAAuthAES192CPriv(t *testing.T) {1077done := make(chan int)1078
1079tl := NewTrapListener()1080defer tl.Close()1081
1082sp := &UsmSecurityParameters{1083UserName: "test",1084AuthenticationProtocol: SHA,1085AuthenticationPassphrase: "password",1086PrivacyProtocol: AES192C,1087PrivacyPassphrase: "password",1088AuthoritativeEngineBoots: 1,1089AuthoritativeEngineTime: 1,1090AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),1091}1092
1093tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)1094tl.Params = Default1095tl.Params.Version = Version31096tl.Params.SecurityParameters = sp1097tl.Params.SecurityModel = UserSecurityModel1098tl.Params.MsgFlags = AuthPriv1099
1100// listener goroutine1101errch := make(chan error)1102go func() {1103err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))1104if err != nil {1105errch <- err1106}1107}()1108
1109// Wait until the listener is ready.1110select {1111case <-tl.Listening():1112case err := <-errch:1113t.Fatalf("error in listen: %v", err)1114}1115
1116ts := &GoSNMP{1117Target: trapTestAddress,1118Port: trapTestPort,1119//Community: "public",1120Version: Version3,1121Timeout: time.Duration(2) * time.Second,1122Retries: 3,1123MaxOids: MaxOids,1124SecurityModel: UserSecurityModel,1125SecurityParameters: sp,1126MsgFlags: AuthPriv,1127}1128
1129err := ts.Connect()1130if err != nil {1131t.Fatalf("Connect() err: %v", err)1132}1133defer ts.Conn.Close()1134
1135pdu := SnmpPDU{1136Name: trapTestOid,1137Type: OctetString,1138Value: trapTestPayload,1139}1140
1141trap := SnmpTrap{1142Variables: []SnmpPDU{pdu},1143Enterprise: trapTestEnterpriseOid,1144AgentAddress: trapTestAgentAddress,1145GenericTrap: trapTestGenericTrap,1146SpecificTrap: trapTestSpecificTrap,1147Timestamp: trapTestTimestamp,1148}1149
1150_, err = ts.SendTrap(trap)1151if err != nil {1152t.Fatalf("SendTrap() err: %v", err)1153}1154
1155// wait for response from handler1156select {1157case <-done:1158case <-time.After(2 * time.Second):1159t.Fatal("timed out waiting for trap to be received")1160}1161}
1162func TestSendV3TrapSHAAuthAES256Priv(t *testing.T) {1163done := make(chan int)1164
1165tl := NewTrapListener()1166defer tl.Close()1167
1168sp := &UsmSecurityParameters{1169UserName: "test",1170AuthenticationProtocol: SHA,1171AuthenticationPassphrase: "password",1172PrivacyProtocol: AES256,1173PrivacyPassphrase: "password",1174AuthoritativeEngineBoots: 1,1175AuthoritativeEngineTime: 1,1176AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),1177}1178
1179tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)1180tl.Params = Default1181tl.Params.Version = Version31182tl.Params.SecurityParameters = sp1183tl.Params.SecurityModel = UserSecurityModel1184tl.Params.MsgFlags = AuthPriv1185
1186// listener goroutine1187errch := make(chan error)1188go func() {1189err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))1190if err != nil {1191errch <- err1192}1193}()1194
1195// Wait until the listener is ready.1196select {1197case <-tl.Listening():1198case err := <-errch:1199t.Fatalf("error in listen: %v", err)1200}1201
1202ts := &GoSNMP{1203Target: trapTestAddress,1204Port: trapTestPort,1205//Community: "public",1206Version: Version3,1207Timeout: time.Duration(2) * time.Second,1208Retries: 3,1209MaxOids: MaxOids,1210SecurityModel: UserSecurityModel,1211SecurityParameters: sp,1212MsgFlags: AuthPriv,1213}1214
1215err := ts.Connect()1216if err != nil {1217t.Fatalf("Connect() err: %v", err)1218}1219defer ts.Conn.Close()1220
1221pdu := SnmpPDU{1222Name: trapTestOid,1223Type: OctetString,1224Value: trapTestPayload,1225}1226
1227trap := SnmpTrap{1228Variables: []SnmpPDU{pdu},1229Enterprise: trapTestEnterpriseOid,1230AgentAddress: trapTestAgentAddress,1231GenericTrap: trapTestGenericTrap,1232SpecificTrap: trapTestSpecificTrap,1233Timestamp: trapTestTimestamp,1234}1235
1236_, err = ts.SendTrap(trap)1237if err != nil {1238t.Fatalf("SendTrap() err: %v", err)1239}1240
1241// wait for response from handler1242select {1243case <-done:1244case <-time.After(2 * time.Second):1245t.Fatal("timed out waiting for trap to be received")1246}1247
1248}
1249func TestSendV3TrapSHAAuthAES256CPriv(t *testing.T) {1250done := make(chan int)1251
1252tl := NewTrapListener()1253defer tl.Close()1254
1255sp := &UsmSecurityParameters{1256UserName: "test",1257AuthenticationProtocol: SHA,1258AuthenticationPassphrase: "password",1259PrivacyProtocol: AES256C,1260PrivacyPassphrase: "password",1261AuthoritativeEngineBoots: 1,1262AuthoritativeEngineTime: 1,1263AuthoritativeEngineID: string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),1264}1265
1266tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)1267tl.Params = Default1268tl.Params.Version = Version31269tl.Params.SecurityParameters = sp1270tl.Params.SecurityModel = UserSecurityModel1271tl.Params.MsgFlags = AuthPriv1272
1273// listener goroutine1274errch := make(chan error)1275go func() {1276err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))1277if err != nil {1278errch <- err1279}1280}()1281
1282// Wait until the listener is ready.1283select {1284case <-tl.Listening():1285case err := <-errch:1286t.Fatalf("error in listen: %v", err)1287}1288
1289ts := &GoSNMP{1290Target: trapTestAddress,1291Port: trapTestPort,1292//Community: "public",1293Version: Version3,1294Timeout: time.Duration(2) * time.Second,1295Retries: 3,1296MaxOids: MaxOids,1297SecurityModel: UserSecurityModel,1298SecurityParameters: sp,1299MsgFlags: AuthPriv,1300}1301
1302err := ts.Connect()1303if err != nil {1304t.Fatalf("Connect() err: %v", err)1305}1306defer ts.Conn.Close()1307
1308pdu := SnmpPDU{1309Name: trapTestOid,1310Type: OctetString,1311Value: trapTestPayload,1312}1313
1314trap := SnmpTrap{1315Variables: []SnmpPDU{pdu},1316Enterprise: trapTestEnterpriseOid,1317AgentAddress: trapTestAgentAddress,1318GenericTrap: trapTestGenericTrap,1319SpecificTrap: trapTestSpecificTrap,1320Timestamp: trapTestTimestamp,1321}1322
1323_, err = ts.SendTrap(trap)1324if err != nil {1325t.Fatalf("SendTrap() err: %v", err)1326}1327
1328// wait for response from handler1329select {1330case <-done:1331case <-time.After(2 * time.Second):1332t.Fatal("timed out waiting for trap to be received")1333}1334
1335}
1336
1337func TestSendV3EngineIdDiscovery(t *testing.T) {1338tl := NewTrapListener()1339defer tl.Close()1340authorativeEngineID := string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04})1341unknownEngineID := string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x05})1342sp := &UsmSecurityParameters{1343UserName: "test",1344AuthenticationProtocol: SHA,1345AuthenticationPassphrase: "password",1346PrivacyProtocol: AES256,1347PrivacyPassphrase: "password",1348AuthoritativeEngineBoots: 1,1349AuthoritativeEngineTime: 1,1350AuthoritativeEngineID: authorativeEngineID,1351}1352tl.Params = Default1353tl.Params.Version = Version31354tl.Params.SecurityParameters = sp1355tl.Params.SecurityModel = UserSecurityModel1356tl.Params.MsgFlags = AuthPriv1357
1358// listener goroutine1359errch := make(chan error)1360go func() {1361err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))1362if err != nil {1363errch <- err1364}1365}()1366
1367// Wait until the listener is ready.1368select {1369case <-tl.Listening():1370case err := <-errch:1371t.Fatalf("error in listen: %v", err)1372}1373
1374ts := &GoSNMP{1375Target: trapTestAddress,1376Port: trapTestPort,1377//Community: "public",1378Version: Version3,1379Timeout: time.Duration(2) * time.Second,1380Retries: 3,1381MaxOids: MaxOids,1382SecurityModel: UserSecurityModel,1383SecurityParameters: sp,1384MsgFlags: AuthPriv,1385}1386
1387err := ts.Connect()1388if err != nil {1389t.Fatalf("Connect() err: %v", err)1390}1391defer ts.Conn.Close()1392
1393getEngineIDRequest := SnmpPacket{1394Version: Version3,1395MsgFlags: Reportable,1396SecurityModel: UserSecurityModel,1397SecurityParameters: &UsmSecurityParameters{},1398ContextEngineID: unknownEngineID,1399PDUType: GetRequest,1400MsgID: 1824792385,1401RequestID: 1411852680,1402MsgMaxSize: 65507,1403}1404result, err := ts.sendOneRequest(&getEngineIDRequest, true)1405require.NoError(t, err, "sendOneRequest failed")1406require.Equal(t, result.SecurityParameters.(*UsmSecurityParameters).AuthoritativeEngineID, authorativeEngineID, "invalid authoritativeEngineID")1407require.Equal(t, result.PDUType, Report, "invalid received PDUType")1408}
1409