github.com/gopacket/gopacket@v1.1.0/layers/dhcp_test.go (about)

     1  // Copyright 2016, Google, Inc. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file in the root of the source
     5  // tree.
     6  
     7  package layers
     8  
     9  import (
    10  	"bytes"
    11  	"net"
    12  	"testing"
    13  
    14  	"github.com/gopacket/gopacket"
    15  )
    16  
    17  func TestDHCPv4EncodeRequest(t *testing.T) {
    18  	dhcp := &DHCPv4{Operation: DHCPOpRequest, HardwareType: LinkTypeEthernet, Xid: 0x12345678,
    19  		ClientIP: net.IP{0, 0, 0, 0}, YourClientIP: net.IP{0, 0, 0, 0}, NextServerIP: net.IP{0, 0, 0, 0}, RelayAgentIP: net.IP{0, 0, 0, 0},
    20  		ClientHWAddr: net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc},
    21  		ServerName:   make([]byte, 64), File: make([]byte, 128)}
    22  
    23  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptMessageType, []byte{byte(DHCPMsgTypeDiscover)}))
    24  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptHostname, []byte{'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}))
    25  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptPad, nil))
    26  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptParamsRequest,
    27  		[]byte{byte(DHCPOptSubnetMask), byte(DHCPOptBroadcastAddr), byte(DHCPOptTimeOffset),
    28  			byte(DHCPOptRouter), byte(DHCPOptDomainName), byte(DHCPOptDNS), byte(DHCPOptDomainSearch),
    29  			byte(DHCPOptHostname), byte(DHCPOptNetBIOSTCPNS), byte(DHCPOptInterfaceMTU), byte(DHCPOptClasslessStaticRoute),
    30  			byte(DHCPOptNTPServers)}))
    31  
    32  	buf := gopacket.NewSerializeBuffer()
    33  	opts := gopacket.SerializeOptions{FixLengths: true}
    34  	err := gopacket.SerializeLayers(buf, opts, dhcp)
    35  	if err != nil {
    36  		t.Fatal(err)
    37  	}
    38  
    39  	p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDHCPv4, testDecodeOptions)
    40  	dhcp2 := p2.Layer(LayerTypeDHCPv4).(*DHCPv4)
    41  	testDHCPEqual(t, dhcp, dhcp2)
    42  }
    43  
    44  func TestDHCPv4EncodeResponse(t *testing.T) {
    45  	dhcp := &DHCPv4{Operation: DHCPOpReply, HardwareType: LinkTypeEthernet, Xid: 0x12345678,
    46  		ClientIP: net.IP{0, 0, 0, 0}, YourClientIP: net.IP{192, 168, 0, 123}, NextServerIP: net.IP{192, 168, 0, 1}, RelayAgentIP: net.IP{0, 0, 0, 0},
    47  		ClientHWAddr: net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc},
    48  		ServerName:   make([]byte, 64), File: make([]byte, 128)}
    49  
    50  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptMessageType, []byte{byte(DHCPMsgTypeOffer)}))
    51  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptSubnetMask, []byte{255, 255, 255, 0}))
    52  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptPad, nil))
    53  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptT1, []byte{0x00, 0x00, 0x0e, 0x10}))
    54  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptT2, []byte{0x00, 0x00, 0x0e, 0x10}))
    55  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptLeaseTime, []byte{0x00, 0x00, 0x0e, 0x10}))
    56  	dhcp.Options = append(dhcp.Options, NewDHCPOption(DHCPOptServerID, []byte{192, 168, 0, 1}))
    57  
    58  	buf := gopacket.NewSerializeBuffer()
    59  	opts := gopacket.SerializeOptions{FixLengths: true}
    60  	err := gopacket.SerializeLayers(buf, opts, dhcp)
    61  	if err != nil {
    62  		t.Fatal(err)
    63  	}
    64  
    65  	p2 := gopacket.NewPacket(buf.Bytes(), LayerTypeDHCPv4, testDecodeOptions)
    66  	dhcp2 := p2.Layer(LayerTypeDHCPv4).(*DHCPv4)
    67  	testDHCPEqual(t, dhcp, dhcp2)
    68  }
    69  
    70  func TestDHCPv4DecodeOption(t *testing.T) {
    71  	var tests = []struct {
    72  		msg string
    73  		buf []byte
    74  		err error
    75  	}{
    76  		{
    77  			msg: "DHCPOptPad",
    78  			buf: []byte{0},
    79  			err: nil,
    80  		},
    81  		{
    82  			msg: "Option with zero length",
    83  			buf: []byte{119, 0},
    84  			err: nil,
    85  		},
    86  		{
    87  			msg: "Option with maximum length",
    88  			buf: bytes.Join([][]byte{
    89  				{119, 255},
    90  				bytes.Repeat([]byte{0}, 255),
    91  			}, nil),
    92  			err: nil,
    93  		},
    94  		{
    95  			msg: "Too short option",
    96  			buf: []byte{},
    97  			err: DecOptionNotEnoughData,
    98  		},
    99  		{
   100  			msg: "Too short option when option is not 0 or 255",
   101  			buf: []byte{119},
   102  			err: DecOptionNotEnoughData,
   103  		},
   104  		{
   105  			msg: "Malformed option",
   106  			buf: []byte{119, 1},
   107  			err: DecOptionMalformed,
   108  		},
   109  	}
   110  
   111  	for i := range tests {
   112  		var (
   113  			opt = new(DHCPOption)
   114  			err = opt.decode(tests[i].buf)
   115  		)
   116  		if want, got := tests[i].err, err; want != got {
   117  			t.Errorf("[#%v %v] Unexpected error want: %v, got: %v\n", i, tests[i].msg, want, err)
   118  		}
   119  	}
   120  }
   121  
   122  func testDHCPEqual(t *testing.T, d1, d2 *DHCPv4) {
   123  	if d1.Operation != d2.Operation {
   124  		t.Errorf("expected Operation=%s, got %s", d1.Operation, d2.Operation)
   125  	}
   126  	if d1.HardwareType != d2.HardwareType {
   127  		t.Errorf("expected HardwareType=%s, got %s", d1.HardwareType, d2.HardwareType)
   128  	}
   129  	if d1.HardwareLen != d2.HardwareLen {
   130  		t.Errorf("expected HardwareLen=%v, got %v", d1.HardwareLen, d2.HardwareLen)
   131  	}
   132  	if d1.HardwareOpts != d2.HardwareOpts {
   133  		t.Errorf("expected HardwareOpts=%v, got %v", d1.HardwareOpts, d2.HardwareOpts)
   134  	}
   135  	if d1.Xid != d2.Xid {
   136  		t.Errorf("expected Xid=%v, got %v", d1.Xid, d2.Xid)
   137  	}
   138  	if d1.Secs != d2.Secs {
   139  		t.Errorf("expected Secs=%v, got %v", d1.Secs, d2.Secs)
   140  	}
   141  	if d1.Flags != d2.Flags {
   142  		t.Errorf("expected Flags=%v, got %v", d1.Flags, d2.Flags)
   143  	}
   144  	if !d1.ClientIP.Equal(d2.ClientIP) {
   145  		t.Errorf("expected ClientIP=%v, got %v", d1.ClientIP, d2.ClientIP)
   146  	}
   147  	if !d1.YourClientIP.Equal(d2.YourClientIP) {
   148  		t.Errorf("expected YourClientIP=%v, got %v", d1.YourClientIP, d2.YourClientIP)
   149  	}
   150  	if !d1.NextServerIP.Equal(d2.NextServerIP) {
   151  		t.Errorf("expected NextServerIP=%v, got %v", d1.NextServerIP, d2.NextServerIP)
   152  	}
   153  	if !d1.RelayAgentIP.Equal(d2.RelayAgentIP) {
   154  		t.Errorf("expected RelayAgentIP=%v, got %v", d1.RelayAgentIP, d2.RelayAgentIP)
   155  	}
   156  	if !bytes.Equal(d1.ClientHWAddr, d2.ClientHWAddr) {
   157  		t.Errorf("expected ClientHWAddr=%v, got %v", d1.ClientHWAddr, d2.ClientHWAddr)
   158  	}
   159  	if !bytes.Equal(d1.ServerName, d2.ServerName) {
   160  		t.Errorf("expected ServerName=%v, got %v", d1.ServerName, d2.ServerName)
   161  	}
   162  	if !bytes.Equal(d1.File, d2.File) {
   163  		t.Errorf("expected File=%v, got %v", d1.File, d2.File)
   164  	}
   165  	if len(d1.Options) != len(d2.Options) {
   166  		t.Errorf("expected %d options, got %d", len(d1.Options), len(d2.Options))
   167  	}
   168  
   169  	for i, o := range d1.Options {
   170  		testDHCPOptionEqual(t, i, o, d2.Options[i])
   171  	}
   172  }
   173  
   174  func testDHCPOptionEqual(t *testing.T, idx int, d1, d2 DHCPOption) {
   175  	if d1.Type != d2.Type {
   176  		t.Errorf("expection Options[%d].Type = %s, got %s", idx, d1.Type, d2.Type)
   177  	}
   178  	if !bytes.Equal(d1.Data, d2.Data) {
   179  		t.Errorf("expection Options[%d].Data to be = %v, got %v", idx, d1.Data, d2.Data)
   180  	}
   181  }