mirror of
https://github.com/danderson/netboot.git
synced 2025-08-21 06:31:17 +02:00
Add a basic regression test for DHCP parsing.
This commit is contained in:
parent
178a83f3e0
commit
fa657ad649
35
dhcp/dhcp.go
35
dhcp/dhcp.go
@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"sort"
|
||||
)
|
||||
|
||||
var magic = []byte{99, 130, 83, 99}
|
||||
@ -68,6 +69,40 @@ type Packet struct {
|
||||
Options Options
|
||||
}
|
||||
|
||||
func (p *Packet) testString() string {
|
||||
var b bytes.Buffer
|
||||
bcast := "Unicast"
|
||||
if p.Broadcast {
|
||||
bcast = "Broadcast"
|
||||
}
|
||||
fmt.Fprintf(&b, `=====
|
||||
%s
|
||||
%#v
|
||||
%s
|
||||
MAC: %s
|
||||
ClientIP: %s
|
||||
YourIP: %s
|
||||
RelayIP: %s
|
||||
|
||||
BootServerIP: %s
|
||||
BootServerName: %s
|
||||
BootFilename: %s
|
||||
|
||||
Options:
|
||||
`, p.Type, p.TransactionID, bcast, p.HardwareAddr, p.ClientAddr, p.YourAddr, p.RelayAddr, p.BootServerAddr, p.BootServerName, p.BootFilename)
|
||||
|
||||
var opts []int
|
||||
for n := range p.Options {
|
||||
opts = append(opts, n)
|
||||
}
|
||||
sort.Ints(opts)
|
||||
for _, n := range opts {
|
||||
fmt.Fprintf(&b, " %d: %#v\n", n, p.Options[n])
|
||||
}
|
||||
b.WriteString("=====\n")
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Marshal returns the wire encoding of p.
|
||||
func (p *Packet) Marshal() ([]byte, error) {
|
||||
if len(p.TransactionID) != 4 {
|
||||
|
73
dhcp/dhcp_test.go
Normal file
73
dhcp/dhcp_test.go
Normal file
@ -0,0 +1,73 @@
|
||||
package dhcp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"go.universe.tf/netboot/pcap"
|
||||
)
|
||||
|
||||
func udpFromPcap(fname string) ([][]byte, error) {
|
||||
f, err := os.Open(fname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err := pcap.NewReader(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r.LinkType != pcap.LinkEthernet {
|
||||
return nil, errors.New("Pcap packets are not ethernet")
|
||||
}
|
||||
|
||||
ret := [][]byte{}
|
||||
for r.Next() {
|
||||
// Assume here that the packets are UDPv4, and just chop off
|
||||
// the headers in front of the UDP payload
|
||||
pkt := r.Packet()
|
||||
hdrLen := 14 // Ethernet header
|
||||
hdrLen += int(pkt.Bytes[hdrLen]&0xF) * 4 // IP header
|
||||
hdrLen += 8 // UDP header
|
||||
ret = append(ret, pkt.Bytes[hdrLen:])
|
||||
}
|
||||
if r.Err() != nil {
|
||||
return nil, r.Err()
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
rawPkts, err := udpFromPcap("testdata/dhcp.pcap")
|
||||
if err != nil {
|
||||
t.Fatalf("Getting test packets from pcap: %s", err)
|
||||
}
|
||||
|
||||
var pkts bytes.Buffer
|
||||
for i, rawPkt := range rawPkts {
|
||||
pkt, err := Unmarshal(rawPkt)
|
||||
if err != nil {
|
||||
t.Fatalf("Parsing DHCP packet #%d: %s", i+1, err)
|
||||
}
|
||||
pkts.WriteString(pkt.testString())
|
||||
}
|
||||
|
||||
expectedFile := "testdata/dhcp.parsed"
|
||||
expected, err := ioutil.ReadFile(expectedFile)
|
||||
if err != nil {
|
||||
t.Fatalf("Reading expected file: %s", err)
|
||||
}
|
||||
|
||||
if pkts.String() != string(expected) {
|
||||
if os.Getenv("UPDATE_TESTDATA") != "" {
|
||||
ioutil.WriteFile(expectedFile, pkts.Bytes(), 0644)
|
||||
t.Errorf("dhcp.pcap didn't decode to dhcp.parsed (updated dhcp.parsed)")
|
||||
} else {
|
||||
t.Fatalf("dhcp.pcap didn't decode to dhcp.parsed (rerun with UPDATE_TESTDATA=1 to get diff)")
|
||||
}
|
||||
}
|
||||
}
|
68
dhcp/testdata/dhcp.parsed
vendored
Normal file
68
dhcp/testdata/dhcp.parsed
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
=====
|
||||
DHCPDISCOVER
|
||||
"\x9bN\x05W"
|
||||
Broadcast
|
||||
MAC: d0:50:99:4e:05:57
|
||||
ClientIP: 0.0.0.0
|
||||
YourIP: 0.0.0.0
|
||||
RelayIP: 0.0.0.0
|
||||
|
||||
BootServerIP: 0.0.0.0
|
||||
BootServerName:
|
||||
BootFilename:
|
||||
|
||||
Options:
|
||||
53: []byte{0x1}
|
||||
55: []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xb, 0xc, 0xd, 0xf, 0x10, 0x11, 0x12, 0x16, 0x17, 0x1c, 0x28, 0x29, 0x2a, 0x2b, 0x32, 0x33, 0x36, 0x3a, 0x3b, 0x3c, 0x42, 0x43, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87}
|
||||
57: []byte{0x4, 0xec}
|
||||
60: []byte{0x50, 0x58, 0x45, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3a, 0x41, 0x72, 0x63, 0x68, 0x3a, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3a, 0x55, 0x4e, 0x44, 0x49, 0x3a, 0x30, 0x30, 0x32, 0x30, 0x30, 0x31}
|
||||
93: []byte{0x0, 0x0}
|
||||
94: []byte{0x1, 0x2, 0x1}
|
||||
97: []byte{0x0, 0x0, 0x2, 0x0, 0x3, 0x0, 0x4, 0x0, 0x5, 0x0, 0x6, 0x0, 0x7, 0x0, 0x8, 0x0, 0x9}
|
||||
=====
|
||||
=====
|
||||
DHCPOFFER
|
||||
"\x9bN\x05W"
|
||||
Broadcast
|
||||
MAC: d0:50:99:4e:05:57
|
||||
ClientIP: 0.0.0.0
|
||||
YourIP: 0.0.0.0
|
||||
RelayIP: 0.0.0.0
|
||||
|
||||
BootServerIP: 0.0.0.0
|
||||
BootServerName:
|
||||
BootFilename:
|
||||
|
||||
Options:
|
||||
43: []byte{0x6, 0x1, 0x3, 0x8, 0x7, 0x80, 0x0, 0x1, 0xc0, 0xa8, 0x10, 0xa, 0x9, 0xc, 0x80, 0x0, 0x9, 0x50, 0x69, 0x78, 0x69, 0x65, 0x63, 0x6f, 0x72, 0x65, 0xa, 0xa, 0x0, 0x50, 0x69, 0x78, 0x69, 0x65, 0x63, 0x6f, 0x72, 0x65, 0xff}
|
||||
53: []byte{0x2}
|
||||
54: []byte{0xc0, 0xa8, 0x10, 0xa}
|
||||
60: []byte{0x50, 0x58, 0x45, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74}
|
||||
97: []byte{0x0, 0x0, 0x2, 0x0, 0x3, 0x0, 0x4, 0x0, 0x5, 0x0, 0x6, 0x0, 0x7, 0x0, 0x8, 0x0, 0x9}
|
||||
=====
|
||||
=====
|
||||
DHCPOFFER
|
||||
"\x9bN\x05W"
|
||||
Broadcast
|
||||
MAC: d0:50:99:4e:05:57
|
||||
ClientIP: 0.0.0.0
|
||||
YourIP: 192.168.16.12
|
||||
RelayIP: 0.0.0.0
|
||||
|
||||
BootServerIP: 192.168.16.1
|
||||
BootServerName:
|
||||
BootFilename:
|
||||
|
||||
Options:
|
||||
1: []byte{0xff, 0xff, 0xff, 0x0}
|
||||
3: []byte{0xc0, 0xa8, 0x10, 0x1}
|
||||
6: []byte{0xc0, 0xa8, 0x10, 0x1}
|
||||
12: []byte{0x63, 0x6f, 0x72, 0x65, 0x30, 0x31}
|
||||
15: []byte{0x68, 0x6f, 0x6d, 0x65, 0x2e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x65, 0x2e, 0x74, 0x66}
|
||||
28: []byte{0xc0, 0xa8, 0x10, 0xff}
|
||||
51: []byte{0x0, 0x0, 0xe, 0x10}
|
||||
53: []byte{0x2}
|
||||
54: []byte{0xc0, 0xa8, 0x10, 0x1}
|
||||
58: []byte{0x0, 0x0, 0x7, 0x8}
|
||||
59: []byte{0x0, 0x0, 0xc, 0x4e}
|
||||
=====
|
BIN
dhcp/testdata/dhcp.pcap
vendored
Normal file
BIN
dhcp/testdata/dhcp.pcap
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user