diff options
Diffstat (limited to 'dhcpv4')
-rw-r--r-- | dhcpv4/bsdp/client.go | 12 | ||||
-rw-r--r-- | dhcpv4/dhcpv4.go | 13 | ||||
-rw-r--r-- | dhcpv4/dhcpv4_test.go | 10 | ||||
-rw-r--r-- | dhcpv4/option_archtype.go | 42 | ||||
-rw-r--r-- | dhcpv4/option_archtype_test.go | 9 | ||||
-rw-r--r-- | dhcpv4/options.go | 3 | ||||
-rw-r--r-- | dhcpv4/options_test.go | 5 |
7 files changed, 43 insertions, 51 deletions
diff --git a/dhcpv4/bsdp/client.go b/dhcpv4/bsdp/client.go index 2683e2a..38de094 100644 --- a/dhcpv4/bsdp/client.go +++ b/dhcpv4/bsdp/client.go @@ -38,8 +38,8 @@ func castVendorOpt(ack *dhcpv4.DHCPv4) { // Exchange runs a full BSDP exchange (Inform[list], Ack, Inform[select], // Ack). Returns a list of DHCPv4 structures representing the exchange. -func (c *Client) Exchange(ifname string, informList *dhcpv4.DHCPv4) ([]dhcpv4.DHCPv4, error) { - conversation := make([]dhcpv4.DHCPv4, 1) +func (c *Client) Exchange(ifname string, informList *dhcpv4.DHCPv4) ([]*dhcpv4.DHCPv4, error) { + conversation := make([]*dhcpv4.DHCPv4, 1) var err error // Get our file descriptor for the broadcast socket. @@ -73,7 +73,7 @@ func (c *Client) Exchange(ifname string, informList *dhcpv4.DHCPv4) ([]dhcpv4.DH return conversation, err } } - conversation[0] = *informList + conversation[0] = informList // ACK[LIST] ackForList, err := dhcpv4.BroadcastSendReceive(sendFd, recvFd, informList, c.ReadTimeout, c.WriteTimeout, dhcpv4.MessageTypeAck) @@ -83,7 +83,7 @@ func (c *Client) Exchange(ifname string, informList *dhcpv4.DHCPv4) ([]dhcpv4.DH // Rewrite vendor-specific option for pretty printing. castVendorOpt(ackForList) - conversation = append(conversation, *ackForList) + conversation = append(conversation, ackForList) // Parse boot images sent back by server bootImages, err := ParseBootImageListFromAck(*ackForList) @@ -99,7 +99,7 @@ func (c *Client) Exchange(ifname string, informList *dhcpv4.DHCPv4) ([]dhcpv4.DH if err != nil { return conversation, err } - conversation = append(conversation, *informSelect) + conversation = append(conversation, informSelect) // ACK[SELECT] ackForSelect, err := dhcpv4.BroadcastSendReceive(sendFd, recvFd, informSelect, c.ReadTimeout, c.WriteTimeout, dhcpv4.MessageTypeAck) @@ -107,5 +107,5 @@ func (c *Client) Exchange(ifname string, informList *dhcpv4.DHCPv4) ([]dhcpv4.DH if err != nil { return conversation, err } - return append(conversation, *ackForSelect), nil + return append(conversation, ackForSelect), nil } diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go index d452f6e..972d103 100644 --- a/dhcpv4/dhcpv4.go +++ b/dhcpv4/dhcpv4.go @@ -656,6 +656,19 @@ func (d *DHCPv4) ValidateOptions() { } } +// IsOptionRequested returns true if that option is within the requested +// options of the DHCPv4 message. +func (d *DHCPv4) IsOptionRequested(requested OptionCode) bool { + for _, optprl := range d.GetOption(OptionParameterRequestList) { + for _, o := range optprl.(*OptParameterRequestList).RequestedOpts { + if o == requested { + return true + } + } + } + return false +} + // ToBytes encodes a DHCPv4 structure into a sequence of bytes in its wire // format. func (d *DHCPv4) ToBytes() []byte { diff --git a/dhcpv4/dhcpv4_test.go b/dhcpv4/dhcpv4_test.go index fe9fe0d..28f38d4 100644 --- a/dhcpv4/dhcpv4_test.go +++ b/dhcpv4/dhcpv4_test.go @@ -493,5 +493,15 @@ func TestNewInform(t *testing.T) { require.True(t, m.ClientIPAddr().Equal(localIP)) } +func TestIsOptionRequested(t *testing.T) { + pkt, err := New() + require.NoError(t, err) + require.False(t, pkt.IsOptionRequested(OptionDomainNameServer)) + + optprl := OptParameterRequestList{RequestedOpts: []OptionCode{OptionDomainNameServer}} + pkt.AddOption(&optprl) + require.True(t, pkt.IsOptionRequested(OptionDomainNameServer)) +} + // TODO // test Summary() and String() diff --git a/dhcpv4/option_archtype.go b/dhcpv4/option_archtype.go index 16ca98d..8eafc55 100644 --- a/dhcpv4/option_archtype.go +++ b/dhcpv4/option_archtype.go @@ -6,43 +6,14 @@ package dhcpv4 import ( "encoding/binary" "fmt" -) - -//ArchType encodes an architecture type in an uint16 -type ArchType uint16 -// see rfc4578 -const ( - INTEL_X86PC ArchType = 0 - NEC_PC98 ArchType = 1 - EFI_ITANIUM ArchType = 2 - DEC_ALPHA ArchType = 3 - ARC_X86 ArchType = 4 - INTEL_LEAN_CLIENT ArchType = 5 - EFI_IA32 ArchType = 6 - EFI_BC ArchType = 7 - EFI_XSCALE ArchType = 8 - EFI_X86_64 ArchType = 9 + "github.com/insomniacslk/dhcp/iana" ) -// ArchTypeToStringMap maps an ArchType to a mnemonic name -var ArchTypeToStringMap = map[ArchType]string{ - INTEL_X86PC: "Intel x86PC", - NEC_PC98: "NEC/PC98", - EFI_ITANIUM: "EFI Itanium", - DEC_ALPHA: "DEC Alpha", - ARC_X86: "Arc x86", - INTEL_LEAN_CLIENT: "Intel Lean Client", - EFI_IA32: "EFI IA32", - EFI_BC: "EFI BC", - EFI_XSCALE: "EFI Xscale", - EFI_X86_64: "EFI x86-64", -} - // OptClientArchType represents an option encapsulating the Client System // Architecture Type option Definition. type OptClientArchType struct { - ArchTypes []ArchType + ArchTypes []iana.ArchType } // Code returns the option code. @@ -71,10 +42,7 @@ func (o *OptClientArchType) Length() int { func (o *OptClientArchType) String() string { var archTypes string for idx, at := range o.ArchTypes { - name, ok := ArchTypeToStringMap[at] - if !ok { - name = "Unknown" - } + name := iana.ArchTypeToString(at) archTypes += name if idx < len(o.ArchTypes)-1 { archTypes += ", " @@ -100,10 +68,10 @@ func ParseOptClientArchType(data []byte) (*OptClientArchType, error) { if len(data) < 2+length { return nil, ErrShortByteStream } - archTypes := make([]ArchType, 0, length%2) + archTypes := make([]iana.ArchType, 0, length%2) for idx := 0; idx < length; idx += 2 { b := data[2+idx : 2+idx+2] - archTypes = append(archTypes, ArchType(binary.BigEndian.Uint16(b))) + archTypes = append(archTypes, iana.ArchType(binary.BigEndian.Uint16(b))) } return &OptClientArchType{ArchTypes: archTypes}, nil } diff --git a/dhcpv4/option_archtype_test.go b/dhcpv4/option_archtype_test.go index cb9bc3f..d803328 100644 --- a/dhcpv4/option_archtype_test.go +++ b/dhcpv4/option_archtype_test.go @@ -3,6 +3,7 @@ package dhcpv4 import ( "testing" + "github.com/insomniacslk/dhcp/iana" "github.com/stretchr/testify/require" ) @@ -14,7 +15,7 @@ func TestParseOptClientArchType(t *testing.T) { } opt, err := ParseOptClientArchType(data) require.NoError(t, err) - require.Equal(t, opt.ArchTypes[0], EFI_IA32) + require.Equal(t, opt.ArchTypes[0], iana.EFI_IA32) } func TestParseOptClientArchTypeMultiple(t *testing.T) { @@ -26,8 +27,8 @@ func TestParseOptClientArchTypeMultiple(t *testing.T) { } opt, err := ParseOptClientArchType(data) require.NoError(t, err) - require.Equal(t, opt.ArchTypes[0], EFI_IA32) - require.Equal(t, opt.ArchTypes[1], EFI_ITANIUM) + require.Equal(t, opt.ArchTypes[0], iana.EFI_IA32) + require.Equal(t, opt.ArchTypes[1], iana.EFI_ITANIUM) } func TestParseOptClientArchTypeInvalid(t *testing.T) { @@ -61,7 +62,7 @@ func TestOptClientArchTypeParseAndToBytesMultiple(t *testing.T) { func TestOptClientArchType(t *testing.T) { opt := OptClientArchType{ - ArchTypes: []ArchType{EFI_ITANIUM}, + ArchTypes: []iana.ArchType{iana.EFI_ITANIUM}, } require.Equal(t, opt.Length(), 2) require.Equal(t, opt.Code(), OptionClientSystemArchitectureType) diff --git a/dhcpv4/options.go b/dhcpv4/options.go index d869b7d..02fa6e4 100644 --- a/dhcpv4/options.go +++ b/dhcpv4/options.go @@ -126,6 +126,9 @@ func OptionsFromBytesWithoutMagicCookie(data []byte) ([]Option, error) { return nil, err } options = append(options, opt) + if opt.Code() == OptionEnd { + break + } // Options with zero length have no length byte, so here we handle the // ones with nonzero length diff --git a/dhcpv4/options_test.go b/dhcpv4/options_test.go index 0268483..899fb2c 100644 --- a/dhcpv4/options_test.go +++ b/dhcpv4/options_test.go @@ -167,12 +167,9 @@ func TestOptionsFromBytes(t *testing.T) { } opts, err := OptionsFromBytes(options) require.NoError(t, err) - require.Equal(t, 5, len(opts)) + require.Equal(t, 2, len(opts)) require.Equal(t, opts[0].(*OptionGeneric), &OptionGeneric{OptionCode: OptionNameServer, Data: []byte{192, 168, 1, 1}}) require.Equal(t, opts[1].(*OptionGeneric), &OptionGeneric{OptionCode: OptionEnd}) - require.Equal(t, opts[2].(*OptionGeneric), &OptionGeneric{OptionCode: OptionPad}) - require.Equal(t, opts[3].(*OptionGeneric), &OptionGeneric{OptionCode: OptionPad}) - require.Equal(t, opts[4].(*OptionGeneric), &OptionGeneric{OptionCode: OptionPad}) } func TestOptionsFromBytesZeroLength(t *testing.T) { |