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// +build all trap
6
7package gosnmp
8
9import (
10	"log"
11	"net"
12	"os" //"io/ioutil"
13	"reflect"
14	"testing"
15	"time"
16)
17
18const (
19	trapTestAddress = "127.0.0.1"
20
21	// TODO this is bad. Listen and Connect expect different address formats
22	// so we need an int version and a string version - they should be the same.
23	trapTestPort       = 9162
24	trapTestPortString = "9162"
25
26	trapTestOid     = ".1.2.1234.4.5"
27	trapTestPayload = "TRAPTEST1234"
28
29	trapTestEnterpriseOid = ".1.2.1234"
30	trapTestAgentAddress  = "127.0.0.1"
31	trapTestGenericTrap   = 6
32	trapTestSpecificTrap  = 55
33	trapTestTimestamp     = 300
34)
35
36var testsUnmarshalTrap = []struct {
37	in  func() []byte
38	out *SnmpPacket
39}{
40	{genericV3Trap,
41		&SnmpPacket{
42			Version:   Version3,
43			PDUType:   SNMPv2Trap,
44			RequestID: 190378322,
45			MsgFlags:  AuthNoPriv,
46			SecurityParameters: &UsmSecurityParameters{
47				UserName:                 "myuser",
48				AuthenticationProtocol:   MD5,
49				AuthenticationPassphrase: "mypassword",
50				Logger:                   log.New(os.Stdout, "", 0),
51			},
52		},
53	},
54}
55
56/*func TestUnmarshalTrap(t *testing.T) {
57	Default.Logger = log.New(os.Stdout, "", 0)
58
59SANITY:
60	for i, test := range testsUnmarshalTrap {
61
62		Default.SecurityParameters = test.out.SecurityParameters.Copy()
63
64		var buf = test.in()
65		var res = Default.unmarshalTrap(buf)
66		if res == nil {
67			t.Errorf("#%d, UnmarshalTrap returned nil", i)
68			continue SANITY
69		}
70
71		// test enough fields fields to ensure unmarshalling was successful.
72		// full unmarshal testing is performed in TestUnmarshal
73		if res.Version != test.out.Version {
74			t.Errorf("#%d Version result: %v, test: %v", i, res.Version, test.out.Version)
75		}
76		if res.RequestID != test.out.RequestID {
77			t.Errorf("#%d RequestID result: %v, test: %v", i, res.RequestID, test.out.RequestID)
78		}
79	}
80}
81*/
82func genericV3Trap() []byte {
83	return []byte{
84		0x30, 0x81, 0xd7, 0x02, 0x01, 0x03, 0x30, 0x11, 0x02, 0x04, 0x62, 0xaf,
85		0x5a, 0x8e, 0x02, 0x03, 0x00, 0xff, 0xe3, 0x04, 0x01, 0x01, 0x02, 0x01,
86		0x03, 0x04, 0x33, 0x30, 0x31, 0x04, 0x11, 0x80, 0x00, 0x1f, 0x88, 0x80,
87		0x77, 0xdf, 0xe4, 0x4f, 0xaa, 0x70, 0x02, 0x58, 0x00, 0x00, 0x00, 0x00,
88		0x02, 0x01, 0x0f, 0x02, 0x01, 0x00, 0x04, 0x06, 0x6d, 0x79, 0x75, 0x73,
89		0x65, 0x72, 0x04, 0x0c, 0xd8, 0xb6, 0x9c, 0xb8, 0x22, 0x91, 0xfc, 0x65,
90		0xb6, 0x84, 0xcb, 0xfe, 0x04, 0x00, 0x30, 0x81, 0x89, 0x04, 0x11, 0x80,
91		0x00, 0x1f, 0x88, 0x80, 0x77, 0xdf, 0xe4, 0x4f, 0xaa, 0x70, 0x02, 0x58,
92		0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xa7, 0x72, 0x02, 0x04, 0x39, 0x19,
93		0x9c, 0x61, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x64, 0x30, 0x0f,
94		0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x43, 0x03,
95		0x15, 0x2f, 0xec, 0x30, 0x14, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x06, 0x03,
96		0x01, 0x01, 0x04, 0x01, 0x00, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x02, 0x01,
97		0x01, 0x30, 0x16, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01,
98		0x00, 0x04, 0x0a, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x61, 0x70, 0x74, 0x6f,
99		0x70, 0x30, 0x0d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x07,
100		0x00, 0x02, 0x01, 0x05, 0x30, 0x14, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02,
101		0x01, 0x01, 0x02, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x02, 0x03,
102		0x04, 0x05}
103}
104
105func makeTestTrapHandler(t *testing.T, done chan int, version SnmpVersion) func(*SnmpPacket, *net.UDPAddr) {
106	return func(packet *SnmpPacket, addr *net.UDPAddr) {
107		//log.Printf("got trapdata from %s\n", addr.IP)
108		defer close(done)
109
110		if version == Version1 {
111			if packet.Enterprise != trapTestEnterpriseOid {
112				t.Fatalf("incorrect trap Enterprise OID received, expected %s got %s", trapTestEnterpriseOid, packet.Enterprise)
113			}
114			if packet.AgentAddress != trapTestAgentAddress {
115				t.Fatalf("incorrect trap Agent Address received, expected %s got %s", trapTestAgentAddress, packet.AgentAddress)
116			}
117			if packet.GenericTrap != trapTestGenericTrap {
118				t.Fatalf("incorrect trap Generic Trap identifier received, expected %v got %v", trapTestGenericTrap, packet.GenericTrap)
119			}
120			if packet.SpecificTrap != trapTestSpecificTrap {
121				t.Fatalf("incorrect trap Specific Trap identifier received, expected %v got %v", trapTestSpecificTrap, packet.SpecificTrap)
122			}
123			if packet.Timestamp != trapTestTimestamp {
124				t.Fatalf("incorrect trap Timestamp received, expected %v got %v", trapTestTimestamp, packet.Timestamp)
125			}
126		}
127
128		for _, v := range packet.Variables {
129			switch v.Type {
130			case OctetString:
131				b := v.Value.([]byte)
132				// log.Printf("OID: %s, string: %x\n", v.Name, b)
133
134				// Only one OctetString in the payload, so it must be the expected one
135				if v.Name != trapTestOid {
136					t.Fatalf("incorrect trap OID received, expected %s got %s", trapTestOid, v.Name)
137				}
138				if string(b) != trapTestPayload {
139					t.Fatalf("incorrect trap payload received, expected %s got %x", trapTestPayload, b)
140				}
141			default:
142				// log.Printf("trap: %+v\n", v)
143			}
144		}
145	}
146}
147
148// TODO: This restores global state set by other tests so that these tests can
149// run. Tests should be avoiding use of global state where possible (and, if
150// possible, use of global state other than possibly loggers should be
151// eliminated entirely).
152func TestRestoreGlobals(t *testing.T) {
153	Default.Version = Version2c
154	Default.SecurityModel = 0
155	Default.SecurityParameters = nil
156}
157
158// test sending a basic SNMP trap, using our own listener to receive
159func TestSendTrapBasic(t *testing.T) {
160	done := make(chan int)
161
162	tl := NewTrapListener()
163	defer tl.Close()
164
165	tl.OnNewTrap = makeTestTrapHandler(t, done, Version2c)
166	tl.Params = Default
167
168	// listener goroutine
169	errch := make(chan error)
170	go func() {
171		// defer close(errch)
172		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
173		if err != nil {
174			errch <- err
175		}
176	}()
177
178	// Wait until the listener is ready.
179	select {
180	case <-tl.Listening():
181	case err := <-errch:
182		t.Fatalf("error in listen: %v", err)
183	}
184
185	ts := &GoSNMP{
186		Target:    trapTestAddress,
187		Port:      trapTestPort,
188		Community: "public",
189		Version:   Version2c,
190		Timeout:   time.Duration(2) * time.Second,
191		Retries:   3,
192		MaxOids:   MaxOids,
193	}
194
195	err := ts.Connect()
196	if err != nil {
197		t.Fatalf("Connect() err: %v", err)
198	}
199	defer ts.Conn.Close()
200
201	pdu := SnmpPDU{
202		Name:  trapTestOid,
203		Type:  OctetString,
204		Value: trapTestPayload,
205	}
206
207	trap := SnmpTrap{
208		Variables: []SnmpPDU{pdu},
209	}
210
211	_, err = ts.SendTrap(trap)
212	if err != nil {
213		t.Fatalf("SendTrap() err: %v", err)
214	}
215
216	// wait for response from handler
217	select {
218	case <-done:
219	case <-time.After(2 * time.Second):
220		t.Fatal("timed out waiting for trap to be received")
221	}
222}
223
224// test sending a basic SNMP inform and receiving the response
225func TestSendInformBasic(t *testing.T) {
226	done := make(chan int)
227
228	tl := NewTrapListener()
229	defer tl.Close()
230
231	tl.OnNewTrap = makeTestTrapHandler(t, done, Version2c)
232	tl.Params = Default
233
234	// listener goroutine
235	errch := make(chan error)
236	go func() {
237		// defer close(errch)
238		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
239		if err != nil {
240			errch <- err
241		}
242	}()
243
244	// Wait until the listener is ready.
245	select {
246	case <-tl.Listening():
247	case err := <-errch:
248		t.Fatalf("error in listen: %v", err)
249	}
250
251	ts := &GoSNMP{
252		Target:    trapTestAddress,
253		Port:      trapTestPort,
254		Community: "public",
255		Version:   Version2c,
256		Timeout:   time.Duration(2) * time.Second,
257		Retries:   3,
258		MaxOids:   MaxOids,
259	}
260
261	err := ts.Connect()
262	if err != nil {
263		t.Fatalf("Connect() err: %v", err)
264	}
265	defer ts.Conn.Close()
266
267	pdu := SnmpPDU{
268		Name:  trapTestOid,
269		Type:  OctetString,
270		Value: trapTestPayload,
271	}
272
273	// Make it an inform.
274	trap := SnmpTrap{
275		Variables: []SnmpPDU{pdu},
276		IsInform:  true,
277	}
278
279	var resp *SnmpPacket
280	resp, err = ts.SendTrap(trap)
281	if err != nil {
282		t.Fatalf("SendTrap() err: %v", err)
283	}
284
285	// wait for response from handler
286	select {
287	case <-done:
288	case <-time.After(2 * time.Second):
289		t.Fatal("timed out waiting for trap to be received")
290	}
291
292	if resp.PDUType != GetResponse {
293		t.Fatal("Inform response is not a response PDU")
294	}
295
296	for i, tv := range trap.Variables {
297		rv := resp.Variables[i+1]
298		if reflect.DeepEqual(tv, rv) {
299			t.Fatalf("Expected variable %d = %#v, got %#v", i, tv, rv)
300		}
301	}
302}
303
304// test the listener is not blocked if Listening is not used
305func TestSendTrapWithoutWaitingOnListen(t *testing.T) {
306	done := make(chan int)
307
308	tl := NewTrapListener()
309	defer tl.Close()
310
311	tl.OnNewTrap = makeTestTrapHandler(t, done, Version2c)
312	tl.Params = Default
313
314	errch := make(chan error)
315	listening := make(chan bool)
316	go func() {
317		// Reduce the chance of necessity for a restart.
318		listening <- true
319
320		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
321		if err != nil {
322			errch <- err
323		}
324	}()
325
326	select {
327	case <-listening:
328	case err := <-errch:
329		t.Fatalf("error in listen: %v", err)
330	}
331
332	ts := &GoSNMP{
333		Target:    trapTestAddress,
334		Port:      trapTestPort,
335		Community: "public",
336		Version:   Version2c,
337		Timeout:   time.Duration(2) * time.Second,
338		Retries:   3,
339		MaxOids:   MaxOids,
340	}
341
342	err := ts.Connect()
343	if err != nil {
344		t.Fatalf("Connect() err: %v", err)
345	}
346	defer ts.Conn.Close()
347
348	pdu := SnmpPDU{
349		Name:  trapTestOid,
350		Type:  OctetString,
351		Value: trapTestPayload,
352	}
353
354	trap := SnmpTrap{
355		Variables: []SnmpPDU{pdu},
356	}
357
358	_, err = ts.SendTrap(trap)
359	if err != nil {
360		t.Fatalf("SendTrap() err: %v", err)
361	}
362
363	// Wait for a response from the handler and restart the SendTrap
364	// if the listener wasn't ready.
365	select {
366	case <-done:
367	case <-time.After(2 * time.Second):
368		_, err = ts.SendTrap(trap)
369		if err != nil {
370			t.Fatalf("restarted SendTrap() err: %v", err)
371		}
372
373		t.Log("restarted")
374
375		select {
376		case <-done:
377		case <-time.After(2 * time.Second):
378			t.Fatal("timed out waiting for trap to be received")
379		}
380	}
381}
382
383// test sending a basic SNMP trap, using our own listener to receive
384func TestSendV1Trap(t *testing.T) {
385	done := make(chan int)
386
387	tl := NewTrapListener()
388	defer tl.Close()
389
390	tl.OnNewTrap = makeTestTrapHandler(t, done, Version1)
391	tl.Params = Default
392
393	// listener goroutine
394	errch := make(chan error)
395	go func() {
396		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
397		if err != nil {
398			errch <- err
399		}
400	}()
401
402	// Wait until the listener is ready.
403	select {
404	case <-tl.Listening():
405	case err := <-errch:
406		t.Fatalf("error in listen: %v", err)
407	}
408
409	ts := &GoSNMP{
410		Target: trapTestAddress,
411		Port:   trapTestPort,
412		//Community: "public",
413		Version: Version1,
414		Timeout: time.Duration(2) * time.Second,
415		Retries: 3,
416		MaxOids: MaxOids,
417	}
418
419	err := ts.Connect()
420	if err != nil {
421		t.Fatalf("Connect() err: %v", err)
422	}
423	defer ts.Conn.Close()
424
425	pdu := SnmpPDU{
426		Name:  trapTestOid,
427		Type:  OctetString,
428		Value: trapTestPayload,
429	}
430
431	trap := SnmpTrap{
432		Variables:    []SnmpPDU{pdu},
433		Enterprise:   trapTestEnterpriseOid,
434		AgentAddress: trapTestAgentAddress,
435		GenericTrap:  trapTestGenericTrap,
436		SpecificTrap: trapTestSpecificTrap,
437		Timestamp:    trapTestTimestamp,
438	}
439
440	_, err = ts.SendTrap(trap)
441	if err != nil {
442		t.Fatalf("SendTrap() err: %v", err)
443	}
444
445	// wait for response from handler
446	select {
447	case <-done:
448	case <-time.After(2 * time.Second):
449		t.Fatal("timed out waiting for trap to be received")
450	}
451}
452
453func TestSendV3TrapNoAuthNoPriv(t *testing.T) {
454	done := make(chan int)
455
456	tl := NewTrapListener()
457	defer tl.Close()
458
459	sp := &UsmSecurityParameters{
460		UserName:                 "test",
461		AuthoritativeEngineBoots: 1,
462		AuthoritativeEngineTime:  1,
463		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
464	}
465
466	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
467	tl.Params = Default
468	tl.Params.Version = Version3
469	tl.Params.SecurityParameters = sp
470	tl.Params.SecurityModel = UserSecurityModel
471	tl.Params.MsgFlags = NoAuthNoPriv
472
473	// listener goroutine
474	errch := make(chan error)
475	go func() {
476		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
477		if err != nil {
478			errch <- err
479		}
480	}()
481
482	// Wait until the listener is ready.
483	select {
484	case <-tl.Listening():
485	case err := <-errch:
486		t.Fatalf("error in listen: %v", err)
487	}
488
489	ts := &GoSNMP{
490		Target: trapTestAddress,
491		Port:   trapTestPort,
492		//Community: "public",
493		Version:            Version3,
494		Timeout:            time.Duration(2) * time.Second,
495		Retries:            3,
496		MaxOids:            MaxOids,
497		SecurityModel:      UserSecurityModel,
498		SecurityParameters: sp,
499		MsgFlags:           NoAuthNoPriv,
500	}
501
502	err := ts.Connect()
503	if err != nil {
504		t.Fatalf("Connect() err: %v", err)
505	}
506	defer ts.Conn.Close()
507
508	pdu := SnmpPDU{
509		Name:  trapTestOid,
510		Type:  OctetString,
511		Value: trapTestPayload,
512	}
513
514	trap := SnmpTrap{
515		Variables:    []SnmpPDU{pdu},
516		Enterprise:   trapTestEnterpriseOid,
517		AgentAddress: trapTestAgentAddress,
518		GenericTrap:  trapTestGenericTrap,
519		SpecificTrap: trapTestSpecificTrap,
520		Timestamp:    trapTestTimestamp,
521	}
522
523	_, err = ts.SendTrap(trap)
524	if err != nil {
525		t.Fatalf("SendTrap() err: %v", err)
526	}
527
528	// wait for response from handler
529	select {
530	case <-done:
531	case <-time.After(2 * time.Second):
532		t.Fatal("timed out waiting for trap to be received")
533	}
534
535}
536
537func TestSendV3TrapMD5AuthNoPriv(t *testing.T) {
538	done := make(chan int)
539
540	tl := NewTrapListener()
541	defer tl.Close()
542
543	sp := &UsmSecurityParameters{
544		UserName:                 "test",
545		AuthenticationProtocol:   MD5,
546		AuthenticationPassphrase: "password",
547		AuthoritativeEngineBoots: 1,
548		AuthoritativeEngineTime:  1,
549		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
550	}
551
552	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
553	tl.Params = Default
554	tl.Params.Version = Version3
555	tl.Params.SecurityParameters = sp
556	tl.Params.SecurityModel = UserSecurityModel
557	tl.Params.MsgFlags = AuthNoPriv
558
559	// listener goroutine
560	errch := make(chan error)
561	go func() {
562		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
563		if err != nil {
564			errch <- err
565		}
566	}()
567
568	// Wait until the listener is ready.
569	select {
570	case <-tl.Listening():
571	case err := <-errch:
572		t.Fatalf("error in listen: %v", err)
573	}
574
575	ts := &GoSNMP{
576		Target: trapTestAddress,
577		Port:   trapTestPort,
578		//Community: "public",
579		Version:            Version3,
580		Timeout:            time.Duration(2) * time.Second,
581		Retries:            3,
582		MaxOids:            MaxOids,
583		SecurityModel:      UserSecurityModel,
584		SecurityParameters: sp,
585		MsgFlags:           AuthNoPriv,
586	}
587
588	err := ts.Connect()
589	if err != nil {
590		t.Fatalf("Connect() err: %v", err)
591	}
592	defer ts.Conn.Close()
593
594	pdu := SnmpPDU{
595		Name:  trapTestOid,
596		Type:  OctetString,
597		Value: trapTestPayload,
598	}
599
600	trap := SnmpTrap{
601		Variables:    []SnmpPDU{pdu},
602		Enterprise:   trapTestEnterpriseOid,
603		AgentAddress: trapTestAgentAddress,
604		GenericTrap:  trapTestGenericTrap,
605		SpecificTrap: trapTestSpecificTrap,
606		Timestamp:    trapTestTimestamp,
607	}
608
609	_, err = ts.SendTrap(trap)
610	if err != nil {
611		t.Fatalf("SendTrap() err: %v", err)
612	}
613
614	// wait for response from handler
615	select {
616	case <-done:
617	case <-time.After(2 * time.Second):
618		t.Fatal("timed out waiting for trap to be received")
619	}
620
621}
622
623func TestSendV3TrapSHAAuthNoPriv(t *testing.T) {
624	done := make(chan int)
625
626	tl := NewTrapListener()
627	defer tl.Close()
628
629	sp := &UsmSecurityParameters{
630		UserName:                 "test",
631		AuthenticationProtocol:   SHA,
632		AuthenticationPassphrase: "password",
633		AuthoritativeEngineBoots: 1,
634		AuthoritativeEngineTime:  1,
635		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
636	}
637
638	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
639	tl.Params = Default
640	tl.Params.Version = Version3
641	tl.Params.SecurityParameters = sp
642	tl.Params.SecurityModel = UserSecurityModel
643	tl.Params.MsgFlags = AuthNoPriv
644
645	// listener goroutine
646	errch := make(chan error)
647	go func() {
648		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
649		if err != nil {
650			errch <- err
651		}
652	}()
653
654	// Wait until the listener is ready.
655	select {
656	case <-tl.Listening():
657	case err := <-errch:
658		t.Fatalf("error in listen: %v", err)
659	}
660
661	ts := &GoSNMP{
662		Target: trapTestAddress,
663		Port:   trapTestPort,
664		//Community: "public",
665		Version:            Version3,
666		Timeout:            time.Duration(2) * time.Second,
667		Retries:            3,
668		MaxOids:            MaxOids,
669		SecurityModel:      UserSecurityModel,
670		SecurityParameters: sp,
671		MsgFlags:           AuthNoPriv,
672	}
673
674	err := ts.Connect()
675	if err != nil {
676		t.Fatalf("Connect() err: %v", err)
677	}
678	defer ts.Conn.Close()
679
680	pdu := SnmpPDU{
681		Name:  trapTestOid,
682		Type:  OctetString,
683		Value: trapTestPayload,
684	}
685
686	trap := SnmpTrap{
687		Variables:    []SnmpPDU{pdu},
688		Enterprise:   trapTestEnterpriseOid,
689		AgentAddress: trapTestAgentAddress,
690		GenericTrap:  trapTestGenericTrap,
691		SpecificTrap: trapTestSpecificTrap,
692		Timestamp:    trapTestTimestamp,
693	}
694
695	_, err = ts.SendTrap(trap)
696	if err != nil {
697		t.Fatalf("SendTrap() err: %v", err)
698	}
699
700	// wait for response from handler
701	select {
702	case <-done:
703	case <-time.After(2 * time.Second):
704		t.Fatal("timed out waiting for trap to be received")
705	}
706
707}
708func TestSendV3TrapSHAAuthDESPriv(t *testing.T) {
709	done := make(chan int)
710
711	tl := NewTrapListener()
712	defer tl.Close()
713
714	sp := &UsmSecurityParameters{
715		UserName:                 "test",
716		AuthenticationProtocol:   SHA,
717		AuthenticationPassphrase: "password",
718		PrivacyProtocol:          DES,
719		PrivacyPassphrase:        "password",
720		AuthoritativeEngineBoots: 1,
721		AuthoritativeEngineTime:  1,
722		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
723	}
724
725	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
726	tl.Params = Default
727	tl.Params.Version = Version3
728	tl.Params.SecurityParameters = sp
729	tl.Params.SecurityModel = UserSecurityModel
730	tl.Params.MsgFlags = AuthPriv
731
732	// listener goroutine
733	errch := make(chan error)
734	go func() {
735		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
736		if err != nil {
737			errch <- err
738		}
739	}()
740
741	// Wait until the listener is ready.
742	select {
743	case <-tl.Listening():
744	case err := <-errch:
745		t.Fatalf("error in listen: %v", err)
746	}
747
748	ts := &GoSNMP{
749		Target: trapTestAddress,
750		Port:   trapTestPort,
751		//Community: "public",
752		Version:            Version3,
753		Timeout:            time.Duration(2) * time.Second,
754		Retries:            3,
755		MaxOids:            MaxOids,
756		SecurityModel:      UserSecurityModel,
757		SecurityParameters: sp,
758		MsgFlags:           AuthPriv,
759	}
760
761	err := ts.Connect()
762	if err != nil {
763		t.Fatalf("Connect() err: %v", err)
764	}
765	defer ts.Conn.Close()
766
767	pdu := SnmpPDU{
768		Name:  trapTestOid,
769		Type:  OctetString,
770		Value: trapTestPayload,
771	}
772
773	trap := SnmpTrap{
774		Variables:    []SnmpPDU{pdu},
775		Enterprise:   trapTestEnterpriseOid,
776		AgentAddress: trapTestAgentAddress,
777		GenericTrap:  trapTestGenericTrap,
778		SpecificTrap: trapTestSpecificTrap,
779		Timestamp:    trapTestTimestamp,
780	}
781
782	_, err = ts.SendTrap(trap)
783	if err != nil {
784		t.Fatalf("SendTrap() err: %v", err)
785	}
786
787	// wait for response from handler
788	select {
789	case <-done:
790	case <-time.After(2 * time.Second):
791		t.Fatal("timed out waiting for trap to be received")
792	}
793
794}
795
796func TestSendV3TrapSHAAuthAESPriv(t *testing.T) {
797	done := make(chan int)
798
799	tl := NewTrapListener()
800	defer tl.Close()
801
802	sp := &UsmSecurityParameters{
803		UserName:                 "test",
804		AuthenticationProtocol:   SHA,
805		AuthenticationPassphrase: "password",
806		PrivacyProtocol:          AES,
807		PrivacyPassphrase:        "password",
808		AuthoritativeEngineBoots: 1,
809		AuthoritativeEngineTime:  1,
810		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
811	}
812
813	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
814	tl.Params = Default
815	tl.Params.Version = Version3
816	tl.Params.SecurityParameters = sp
817	tl.Params.SecurityModel = UserSecurityModel
818	tl.Params.MsgFlags = AuthPriv
819
820	// listener goroutine
821	errch := make(chan error)
822	go func() {
823		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
824		if err != nil {
825			errch <- err
826		}
827	}()
828
829	// Wait until the listener is ready.
830	select {
831	case <-tl.Listening():
832	case err := <-errch:
833		t.Fatalf("error in listen: %v", err)
834	}
835
836	ts := &GoSNMP{
837		Target: trapTestAddress,
838		Port:   trapTestPort,
839		//Community: "public",
840		Version:            Version3,
841		Timeout:            time.Duration(2) * time.Second,
842		Retries:            3,
843		MaxOids:            MaxOids,
844		SecurityModel:      UserSecurityModel,
845		SecurityParameters: sp,
846		MsgFlags:           AuthPriv,
847	}
848
849	err := ts.Connect()
850	if err != nil {
851		t.Fatalf("Connect() err: %v", err)
852	}
853	defer ts.Conn.Close()
854
855	pdu := SnmpPDU{
856		Name:  trapTestOid,
857		Type:  OctetString,
858		Value: trapTestPayload,
859	}
860
861	trap := SnmpTrap{
862		Variables:    []SnmpPDU{pdu},
863		Enterprise:   trapTestEnterpriseOid,
864		AgentAddress: trapTestAgentAddress,
865		GenericTrap:  trapTestGenericTrap,
866		SpecificTrap: trapTestSpecificTrap,
867		Timestamp:    trapTestTimestamp,
868	}
869
870	_, err = ts.SendTrap(trap)
871	if err != nil {
872		t.Fatalf("SendTrap() err: %v", err)
873	}
874
875	// wait for response from handler
876	select {
877	case <-done:
878	case <-time.After(2 * time.Second):
879		t.Fatal("timed out waiting for trap to be received")
880	}
881
882}
883
884func TestSendV3TrapSHAAuthAES192Priv(t *testing.T) {
885	done := make(chan int)
886
887	tl := NewTrapListener()
888	defer tl.Close()
889
890	sp := &UsmSecurityParameters{
891		UserName:                 "test",
892		AuthenticationProtocol:   SHA,
893		AuthenticationPassphrase: "password",
894		PrivacyProtocol:          AES192,
895		PrivacyPassphrase:        "password",
896		AuthoritativeEngineBoots: 1,
897		AuthoritativeEngineTime:  1,
898		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
899	}
900
901	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
902	tl.Params = Default
903	tl.Params.Version = Version3
904	tl.Params.SecurityParameters = sp
905	tl.Params.SecurityModel = UserSecurityModel
906	tl.Params.MsgFlags = AuthPriv
907
908	// listener goroutine
909	errch := make(chan error)
910	go func() {
911		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
912		if err != nil {
913			errch <- err
914		}
915	}()
916
917	// Wait until the listener is ready.
918	select {
919	case <-tl.Listening():
920	case err := <-errch:
921		t.Fatalf("error in listen: %v", err)
922	}
923
924	ts := &GoSNMP{
925		Target: trapTestAddress,
926		Port:   trapTestPort,
927		//Community: "public",
928		Version:            Version3,
929		Timeout:            time.Duration(2) * time.Second,
930		Retries:            3,
931		MaxOids:            MaxOids,
932		SecurityModel:      UserSecurityModel,
933		SecurityParameters: sp,
934		MsgFlags:           AuthPriv,
935	}
936
937	err := ts.Connect()
938	if err != nil {
939		t.Fatalf("Connect() err: %v", err)
940	}
941	defer ts.Conn.Close()
942
943	pdu := SnmpPDU{
944		Name:  trapTestOid,
945		Type:  OctetString,
946		Value: trapTestPayload,
947	}
948
949	trap := SnmpTrap{
950		Variables:    []SnmpPDU{pdu},
951		Enterprise:   trapTestEnterpriseOid,
952		AgentAddress: trapTestAgentAddress,
953		GenericTrap:  trapTestGenericTrap,
954		SpecificTrap: trapTestSpecificTrap,
955		Timestamp:    trapTestTimestamp,
956	}
957
958	_, err = ts.SendTrap(trap)
959	if err != nil {
960		t.Fatalf("SendTrap() err: %v", err)
961	}
962
963	// wait for response from handler
964	select {
965	case <-done:
966	case <-time.After(2 * time.Second):
967		t.Fatal("timed out waiting for trap to be received")
968	}
969
970}
971func TestSendV3TrapSHAAuthAES192CPriv(t *testing.T) {
972	done := make(chan int)
973
974	tl := NewTrapListener()
975	defer tl.Close()
976
977	sp := &UsmSecurityParameters{
978		UserName:                 "test",
979		AuthenticationProtocol:   SHA,
980		AuthenticationPassphrase: "password",
981		PrivacyProtocol:          AES192C,
982		PrivacyPassphrase:        "password",
983		AuthoritativeEngineBoots: 1,
984		AuthoritativeEngineTime:  1,
985		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
986	}
987
988	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
989	tl.Params = Default
990	tl.Params.Version = Version3
991	tl.Params.SecurityParameters = sp
992	tl.Params.SecurityModel = UserSecurityModel
993	tl.Params.MsgFlags = AuthPriv
994
995	// listener goroutine
996	errch := make(chan error)
997	go func() {
998		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
999		if err != nil {
1000			errch <- err
1001		}
1002	}()
1003
1004	// Wait until the listener is ready.
1005	select {
1006	case <-tl.Listening():
1007	case err := <-errch:
1008		t.Fatalf("error in listen: %v", err)
1009	}
1010
1011	ts := &GoSNMP{
1012		Target: trapTestAddress,
1013		Port:   trapTestPort,
1014		//Community: "public",
1015		Version:            Version3,
1016		Timeout:            time.Duration(2) * time.Second,
1017		Retries:            3,
1018		MaxOids:            MaxOids,
1019		SecurityModel:      UserSecurityModel,
1020		SecurityParameters: sp,
1021		MsgFlags:           AuthPriv,
1022	}
1023
1024	err := ts.Connect()
1025	if err != nil {
1026		t.Fatalf("Connect() err: %v", err)
1027	}
1028	defer ts.Conn.Close()
1029
1030	pdu := SnmpPDU{
1031		Name:  trapTestOid,
1032		Type:  OctetString,
1033		Value: trapTestPayload,
1034	}
1035
1036	trap := SnmpTrap{
1037		Variables:    []SnmpPDU{pdu},
1038		Enterprise:   trapTestEnterpriseOid,
1039		AgentAddress: trapTestAgentAddress,
1040		GenericTrap:  trapTestGenericTrap,
1041		SpecificTrap: trapTestSpecificTrap,
1042		Timestamp:    trapTestTimestamp,
1043	}
1044
1045	_, err = ts.SendTrap(trap)
1046	if err != nil {
1047		t.Fatalf("SendTrap() err: %v", err)
1048	}
1049
1050	// wait for response from handler
1051	select {
1052	case <-done:
1053	case <-time.After(2 * time.Second):
1054		t.Fatal("timed out waiting for trap to be received")
1055	}
1056}
1057func TestSendV3TrapSHAAuthAES256Priv(t *testing.T) {
1058	done := make(chan int)
1059
1060	tl := NewTrapListener()
1061	defer tl.Close()
1062
1063	sp := &UsmSecurityParameters{
1064		UserName:                 "test",
1065		AuthenticationProtocol:   SHA,
1066		AuthenticationPassphrase: "password",
1067		PrivacyProtocol:          AES256,
1068		PrivacyPassphrase:        "password",
1069		AuthoritativeEngineBoots: 1,
1070		AuthoritativeEngineTime:  1,
1071		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
1072	}
1073
1074	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
1075	tl.Params = Default
1076	tl.Params.Version = Version3
1077	tl.Params.SecurityParameters = sp
1078	tl.Params.SecurityModel = UserSecurityModel
1079	tl.Params.MsgFlags = AuthPriv
1080
1081	// listener goroutine
1082	errch := make(chan error)
1083	go func() {
1084		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
1085		if err != nil {
1086			errch <- err
1087		}
1088	}()
1089
1090	// Wait until the listener is ready.
1091	select {
1092	case <-tl.Listening():
1093	case err := <-errch:
1094		t.Fatalf("error in listen: %v", err)
1095	}
1096
1097	ts := &GoSNMP{
1098		Target: trapTestAddress,
1099		Port:   trapTestPort,
1100		//Community: "public",
1101		Version:            Version3,
1102		Timeout:            time.Duration(2) * time.Second,
1103		Retries:            3,
1104		MaxOids:            MaxOids,
1105		SecurityModel:      UserSecurityModel,
1106		SecurityParameters: sp,
1107		MsgFlags:           AuthPriv,
1108	}
1109
1110	err := ts.Connect()
1111	if err != nil {
1112		t.Fatalf("Connect() err: %v", err)
1113	}
1114	defer ts.Conn.Close()
1115
1116	pdu := SnmpPDU{
1117		Name:  trapTestOid,
1118		Type:  OctetString,
1119		Value: trapTestPayload,
1120	}
1121
1122	trap := SnmpTrap{
1123		Variables:    []SnmpPDU{pdu},
1124		Enterprise:   trapTestEnterpriseOid,
1125		AgentAddress: trapTestAgentAddress,
1126		GenericTrap:  trapTestGenericTrap,
1127		SpecificTrap: trapTestSpecificTrap,
1128		Timestamp:    trapTestTimestamp,
1129	}
1130
1131	_, err = ts.SendTrap(trap)
1132	if err != nil {
1133		t.Fatalf("SendTrap() err: %v", err)
1134	}
1135
1136	// wait for response from handler
1137	select {
1138	case <-done:
1139	case <-time.After(2 * time.Second):
1140		t.Fatal("timed out waiting for trap to be received")
1141	}
1142
1143}
1144func TestSendV3TrapSHAAuthAES256CPriv(t *testing.T) {
1145	done := make(chan int)
1146
1147	tl := NewTrapListener()
1148	defer tl.Close()
1149
1150	sp := &UsmSecurityParameters{
1151		UserName:                 "test",
1152		AuthenticationProtocol:   SHA,
1153		AuthenticationPassphrase: "password",
1154		PrivacyProtocol:          AES256C,
1155		PrivacyPassphrase:        "password",
1156		AuthoritativeEngineBoots: 1,
1157		AuthoritativeEngineTime:  1,
1158		AuthoritativeEngineID:    string([]byte{0x80, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04}),
1159	}
1160
1161	tl.OnNewTrap = makeTestTrapHandler(t, done, Version3)
1162	tl.Params = Default
1163	tl.Params.Version = Version3
1164	tl.Params.SecurityParameters = sp
1165	tl.Params.SecurityModel = UserSecurityModel
1166	tl.Params.MsgFlags = AuthPriv
1167
1168	// listener goroutine
1169	errch := make(chan error)
1170	go func() {
1171		err := tl.Listen(net.JoinHostPort(trapTestAddress, trapTestPortString))
1172		if err != nil {
1173			errch <- err
1174		}
1175	}()
1176
1177	// Wait until the listener is ready.
1178	select {
1179	case <-tl.Listening():
1180	case err := <-errch:
1181		t.Fatalf("error in listen: %v", err)
1182	}
1183
1184	ts := &GoSNMP{
1185		Target: trapTestAddress,
1186		Port:   trapTestPort,
1187		//Community: "public",
1188		Version:            Version3,
1189		Timeout:            time.Duration(2) * time.Second,
1190		Retries:            3,
1191		MaxOids:            MaxOids,
1192		SecurityModel:      UserSecurityModel,
1193		SecurityParameters: sp,
1194		MsgFlags:           AuthPriv,
1195	}
1196
1197	err := ts.Connect()
1198	if err != nil {
1199		t.Fatalf("Connect() err: %v", err)
1200	}
1201	defer ts.Conn.Close()
1202
1203	pdu := SnmpPDU{
1204		Name:  trapTestOid,
1205		Type:  OctetString,
1206		Value: trapTestPayload,
1207	}
1208
1209	trap := SnmpTrap{
1210		Variables:    []SnmpPDU{pdu},
1211		Enterprise:   trapTestEnterpriseOid,
1212		AgentAddress: trapTestAgentAddress,
1213		GenericTrap:  trapTestGenericTrap,
1214		SpecificTrap: trapTestSpecificTrap,
1215		Timestamp:    trapTestTimestamp,
1216	}
1217
1218	_, err = ts.SendTrap(trap)
1219	if err != nil {
1220		t.Fatalf("SendTrap() err: %v", err)
1221	}
1222
1223	// wait for response from handler
1224	select {
1225	case <-done:
1226	case <-time.After(2 * time.Second):
1227		t.Fatal("timed out waiting for trap to be received")
1228	}
1229
1230}
1231