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
18
"github.com/google/go-cmp/cmp"
19
"github.com/google/gopacket"
20
"github.com/google/gopacket/layers"
21
"github.com/google/gopacket/pcapgo"
22
"github.com/gosnmp/gosnmp"
26
rec = flag.Bool("rec", false, "record and use net-snmp expected outputs, else use recorded values [if true requires libsnmp/cgo]. ")
27
pcap = flag.String("pcap", "", "dir to put exp and got data as pcap files, no pcaps made if blank.")
30
func TestPDU(t *testing.T) {
34
t.Log("playback mode enabled")
37
recdir := filepath.Join("testdata", t.Name())
38
if *rec && !isPlayback() {
39
if err := os.MkdirAll(recdir, 0755); err != nil {
40
t.Fatalf("error creating record dir: %s", err)
43
t.Fatal("record mode requires `-tags netsnmp` and libsnmpd installed")
48
pcapdir = filepath.Join(*pcap, t.Name())
49
if err := os.MkdirAll(pcapdir, 0755); err != nil {
50
t.Fatalf("error creating pcap dir: %s", err)
54
tstpdus := []gosnmp.SnmpPDU{
56
Name: ".1.3.6.1.2.1.1.7.0",
61
Name: ".1.3.6.1.2.1.2.2.1.10.1",
62
Type: gosnmp.Counter32,
63
Value: uint32(271070065),
66
Name: ".1.3.6.1.2.1.2.2.1.5.1",
68
Value: uint32(math.MaxUint32),
71
Name: ".1.3.6.1.2.1.1.4.0",
72
Type: gosnmp.OctetString,
73
Value: []byte("Administrator"),
76
Name: ".1.3.6.1.2.1.4.21.1.1.127.0.0.1",
77
Type: gosnmp.IPAddress,
81
Name: ".1.3.6.1.4.1.6574.4.2.12.1.0",
82
Type: gosnmp.OpaqueFloat,
86
Name: ".1.3.6.1.4.1.6574.4.2.12.1.1",
87
Type: gosnmp.OpaqueFloat,
91
Name: ".1.3.6.1.4.1.6574.4.2.12.2.0",
92
Type: gosnmp.OpaqueDouble,
96
Name: ".1.3.6.1.4.1.6574.4.2.12.2.1",
97
Type: gosnmp.OpaqueDouble,
101
Name: ".1.3.6.1.2.1.2.2.1.10.1",
102
Type: gosnmp.Counter32,
103
Value: uint32(271070065),
106
Name: ".1.3.6.1.2.1.1.3.0",
107
Type: gosnmp.TimeTicks,
108
Value: uint32(318870100),
111
Name: ".1.3.6.1.2.1.1.3.1",
112
Type: gosnmp.Uinteger32,
113
Value: uint32(math.MaxInt32),
116
Name: ".1.3.6.1.2.1.1.3.2",
117
Type: gosnmp.Counter64,
118
Value: uint64(math.MaxInt64),
121
sess := gosnmp.Default
122
sess.Version = gosnmp.Version2c
124
for i, tstpdu := range tstpdus {
125
tname := fmt.Sprintf("test%d_PDU%s", i, tstpdu.Type.String())
126
t.Run(tname, func(t *testing.T) {
127
fname := filepath.Join(recdir, tname+"_pkt.b64")
129
pdus := []gosnmp.SnmpPDU{tstpdu}
130
pkt := sess.MkSnmpPacket(gosnmp.SetRequest, pdus, 0, 0)
133
exp, err := netSnmpPduPkt(fname, pdus[0], sess, pkt.RequestID, testing.Verbose())
139
pktrec := base64.StdEncoding.EncodeToString(exp)
140
if err = os.WriteFile(fname, []byte(pktrec), 0600); err != nil {
141
t.Logf("error writing record file: %s", err)
145
got, err := pkt.MarshalMsg()
151
savePcap(t, filepath.Join(pcapdir, tname), exp, got)
154
if diff := cmp.Diff(exp, got); diff != "" {
155
t.Fatalf("\ngot(%d): %q\nexp(%d): %q\ndiff:\n%s", len(got), got, len(exp), exp, diff)
161
func writePcap(fn string, payload []byte) error {
164
f, err := os.OpenFile(fn, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
171
SrcIP: net.ParseIP("192.168.2.1"),
172
DstIP: net.ParseIP("192.168.2.2"),
173
Protocol: layers.IPProtocolUDP,
180
err = l4.SetNetworkLayerForChecksum(l3)
185
buf := gopacket.NewSerializeBuffer()
186
err = gopacket.SerializeLayers(
188
gopacket.SerializeOptions{
189
ComputeChecksums: true,
194
gopacket.Payload(payload),
200
pkt := gopacket.NewPacket(buf.Bytes(),
204
w := pcapgo.NewWriter(f)
205
err = w.WriteFileHeader(1600, layers.LinkTypeIPv4)
210
err = w.WritePacket(gopacket.CaptureInfo{
211
Timestamp: time.Now(),
212
CaptureLength: len(pkt.Data()),
213
Length: len(pkt.Data()),
222
func savePcap(t *testing.T, fp string, exp, got []byte) {
223
err := writePcap(fp+"_exp", exp)
225
t.Logf("error saving exp pcap: %s", err.Error())
227
err = writePcap(fp+"_got", got)
229
t.Logf("error saving got pcap: %s", err.Error())