diff options
-rw-r--r-- | dhcpv6/async/client_test.go | 9 | ||||
-rw-r--r-- | dhcpv6/dhcpv6_test.go | 12 | ||||
-rw-r--r-- | dhcpv6/dhcpv6message.go | 36 | ||||
-rw-r--r-- | dhcpv6/modifiers.go | 15 | ||||
-rw-r--r-- | netboot/netconf_test.go | 13 |
5 files changed, 45 insertions, 40 deletions
diff --git a/dhcpv6/async/client_test.go b/dhcpv6/async/client_test.go index 9b58112..8603248 100644 --- a/dhcpv6/async/client_test.go +++ b/dhcpv6/async/client_test.go @@ -8,7 +8,6 @@ import ( "github.com/insomniacslk/dhcp/dhcpv6" "github.com/insomniacslk/dhcp/dhcpv6/client6" - "github.com/insomniacslk/dhcp/iana" "github.com/stretchr/testify/require" ) @@ -20,13 +19,7 @@ func solicit(input string) (*dhcpv6.Message, error) { if err != nil { return nil, err } - duid := dhcpv6.Duid{ - Type: dhcpv6.DUID_LLT, - HwType: iana.HWTypeEthernet, - Time: dhcpv6.GetTime(), - LinkLayerAddr: mac, - } - return dhcpv6.NewSolicitWithCID(duid) + return dhcpv6.NewSolicit(mac) } // server creates a server which responds with a predefined response diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go index d509572..10a7296 100644 --- a/dhcpv6/dhcpv6_test.go +++ b/dhcpv6/dhcpv6_test.go @@ -197,7 +197,7 @@ func TestNewReplyFromMessage(t *testing.T) { require.Error(t, err) } -func TestNewMessageTypeSolicitWithCID(t *testing.T) { +func TestNewMessageTypeSolicit(t *testing.T) { hwAddr, err := net.ParseMAC("24:0A:9E:9F:EB:2B") require.NoError(t, err) @@ -207,7 +207,7 @@ func TestNewMessageTypeSolicitWithCID(t *testing.T) { LinkLayerAddr: hwAddr, } - s, err := NewSolicitWithCID(duid) + s, err := NewSolicit(hwAddr, WithClientID(duid)) require.NoError(t, err) require.Equal(t, s.Type(), MessageTypeSolicit) @@ -227,6 +227,14 @@ func TestNewMessageTypeSolicitWithCID(t *testing.T) { require.Contains(t, opts, OptionDNSRecursiveNameServer) require.Contains(t, opts, OptionDomainSearchList) require.Equal(t, len(opts), 2) + + // Check IA_NA + iaid := [4]byte{hwAddr[2], hwAddr[3], hwAddr[4], hwAddr[5]} + iaNaOption := s.GetOneOption(OptionIANA) + require.NotNil(t, iaNaOption) + iaNa, ok := iaNaOption.(*OptIANA) + require.True(t, ok) + require.Equal(t, iaid, iaNa.IaId) } func TestIsUsingUEFIArchTypeTrue(t *testing.T) { diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index 9237c1b..707a65d 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -42,8 +42,15 @@ func GetTime() uint32 { return uint32((now.Nanoseconds() / 1000000000) % 0xffffffff) } -// NewSolicitWithCID creates a new SOLICIT message with CID. -func NewSolicitWithCID(duid Duid, modifiers ...Modifier) (*Message, error) { +// NewSolicit creates a new SOLICIT message, using the given hardware address to +// derive the IAID in the IA_NA option. +func NewSolicit(hwaddr net.HardwareAddr, modifiers ...Modifier) (*Message, error) { + duid := Duid{ + Type: DUID_LLT, + HwType: iana.HWTypeEthernet, + Time: GetTime(), + LinkLayerAddr: hwaddr, + } m, err := NewMessage() if err != nil { return nil, err @@ -57,12 +64,13 @@ func NewSolicitWithCID(duid Duid, modifiers ...Modifier) (*Message, error) { }) m.AddOption(oro) m.AddOption(&OptElapsedTime{}) - // FIXME use real values for IA_NA - iaNa := &OptIANA{} - iaNa.IaId = [4]byte{0xfa, 0xce, 0xb0, 0x0c} - iaNa.T1 = 0xe10 - iaNa.T2 = 0x1518 - m.AddOption(iaNa) + if len(hwaddr) < 4 { + return nil, errors.New("short hardware addrss: less than 4 bytes") + } + l := len(hwaddr) + var iaid [4]byte + copy(iaid[:], hwaddr[l-4:l]) + modifiers = append([]Modifier{WithIAID(iaid)}, modifiers...) // Apply modifiers for _, mod := range modifiers { mod(m) @@ -70,18 +78,6 @@ func NewSolicitWithCID(duid Duid, modifiers ...Modifier) (*Message, error) { return m, nil } -// NewSolicit creates a new SOLICIT message with DUID-LLT, using the -// given network interface's hardware address and current time -func NewSolicit(ifaceHWAddr net.HardwareAddr, modifiers ...Modifier) (*Message, error) { - duid := Duid{ - Type: DUID_LLT, - HwType: iana.HWTypeEthernet, - Time: GetTime(), - LinkLayerAddr: ifaceHWAddr, - } - return NewSolicitWithCID(duid, modifiers...) -} - // NewAdvertiseFromSolicit creates a new ADVERTISE packet based on an SOLICIT packet. func NewAdvertiseFromSolicit(sol *Message, modifiers ...Modifier) (*Message, error) { if sol == nil { diff --git a/dhcpv6/modifiers.go b/dhcpv6/modifiers.go index eaa370d..200a602 100644 --- a/dhcpv6/modifiers.go +++ b/dhcpv6/modifiers.go @@ -77,6 +77,21 @@ func WithIANA(addrs ...OptIAAddress) Modifier { } } +// WithIAID updates an OptIANA option with the provided IAID +func WithIAID(iaid [4]byte) Modifier { + return func(d DHCPv6) { + opt := d.GetOneOption(OptionIANA) + if opt == nil { + opt = &OptIANA{ + Options: Options{}, + } + } + iaNa := opt.(*OptIANA) + copy(iaNa.IaId[:], iaid[:]) + d.UpdateOption(iaNa) + } +} + // WithDNS adds or updates an OptDNSRecursiveNameServer func WithDNS(dnses ...net.IP) Modifier { return func(d DHCPv6) { diff --git a/netboot/netconf_test.go b/netboot/netconf_test.go index 69d58ad..1341af4 100644 --- a/netboot/netconf_test.go +++ b/netboot/netconf_test.go @@ -7,27 +7,20 @@ import ( "github.com/insomniacslk/dhcp/dhcpv4" "github.com/insomniacslk/dhcp/dhcpv6" - "github.com/insomniacslk/dhcp/iana" "github.com/stretchr/testify/require" ) -func getAdv(modifiers ...dhcpv6.Modifier) *dhcpv6.Message { +func getAdv(advModifiers ...dhcpv6.Modifier) *dhcpv6.Message { hwaddr, err := net.ParseMAC("aa:bb:cc:dd:ee:ff") if err != nil { log.Panic(err) } - duid := dhcpv6.Duid{ - Type: dhcpv6.DUID_LLT, - HwType: iana.HWTypeEthernet, - Time: dhcpv6.GetTime(), - LinkLayerAddr: hwaddr, - } - sol, err := dhcpv6.NewSolicitWithCID(duid, modifiers...) + sol, err := dhcpv6.NewSolicit(hwaddr) if err != nil { log.Panic(err) } - d, err := dhcpv6.NewAdvertiseFromSolicit(sol, modifiers...) + d, err := dhcpv6.NewAdvertiseFromSolicit(sol, advModifiers...) if err != nil { log.Panic(err) } |