diff options
-rw-r--r-- | dhcpv4/dhcpv4.go | 5 | ||||
-rw-r--r-- | dhcpv6/dhcpv6.go | 29 | ||||
-rw-r--r-- | dhcpv6/dhcpv6_test.go | 104 | ||||
-rw-r--r-- | dhcpv6/dhcpv6message.go | 27 | ||||
-rw-r--r-- | dhcpv6/dhcpv6message_test.go | 104 |
5 files changed, 133 insertions, 136 deletions
diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go index 3847425..927e9b8 100644 --- a/dhcpv4/dhcpv4.go +++ b/dhcpv4/dhcpv4.go @@ -682,9 +682,8 @@ func (d *DHCPv4) ValidateOptions() { } } -// IsOptionRequested function takes a DHCPv4 message and an OptionCode, and -// returns true if that option is within the requested options of the DHCPv4 -// message. +// 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 { diff --git a/dhcpv6/dhcpv6.go b/dhcpv6/dhcpv6.go index adc52c5..d82ed4a 100644 --- a/dhcpv6/dhcpv6.go +++ b/dhcpv6/dhcpv6.go @@ -202,35 +202,6 @@ func EncapsulateRelay(d DHCPv6, mType MessageType, linkAddr, peerAddr net.IP) (D return &outer, nil } -// IsNetboot function takes a DHCPv6 message and returns true if the machine -// is trying to netboot. It checks if "boot file" is one of the requested -// options, which is useful for SOLICIT/REQUEST packet types, it also checks -// if the "boot file" option is included in the packet, which is useful for -// ADVERTISE/REPLY packet. -func IsNetboot(msg DHCPv6) bool { - if IsOptionRequested(msg, OptionBootfileURL) { - return true - } - if optbf := msg.GetOneOption(OptionBootfileURL); optbf != nil { - return true - } - return false -} - -// IsOptionRequested function takes a DHCPv6 message and an OptionCode, and -// returns true if that option is within the requested options of the DHCPv6 -// message. -func IsOptionRequested(msg DHCPv6, requested OptionCode) bool { - for _, optoro := range msg.GetOption(OptionORO) { - for _, o := range optoro.(*OptRequestedOption).RequestedOptions() { - if o == requested { - return true - } - } - } - return false -} - // IsUsingUEFI function takes a DHCPv6 message and returns true if // the machine trying to netboot is using UEFI of false if it is not. func IsUsingUEFI(msg DHCPv6) bool { diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go index c48df24..812d284 100644 --- a/dhcpv6/dhcpv6_test.go +++ b/dhcpv6/dhcpv6_test.go @@ -4,6 +4,7 @@ import ( "net" "testing" + "github.com/insomniacslk/dhcp/iana" "github.com/stretchr/testify/require" ) @@ -125,33 +126,96 @@ func TestFromAndToBytes(t *testing.T) { require.Equal(t, expected, toBytes) } -func TestIsNetboot(t *testing.T) { - msg1 := DHCPv6Message{} - require.False(t, IsNetboot(&msg1)) +func TestNewAdvertiseFromSolicit(t *testing.T) { + s := DHCPv6Message{} + s.SetMessage(MessageTypeSolicit) + s.SetTransactionID(0xabcdef) + cid := OptClientId{} + s.AddOption(&cid) + duid := Duid{} - msg2 := DHCPv6Message{} - optro := OptRequestedOption{} - optro.AddRequestedOption(OptionBootfileURL) - msg2.AddOption(&optro) - require.True(t, IsNetboot(&msg2)) + a, err := NewAdvertiseFromSolicit(&s, WithServerID(duid)) + require.NoError(t, err) + require.Equal(t, a.(*DHCPv6Message).TransactionID(), s.TransactionID()) + require.Equal(t, a.Type(), MessageTypeAdvertise) +} + +func TestNewReplyFromDHCPv6Message(t *testing.T) { + msg := DHCPv6Message{} + msg.SetTransactionID(0xabcdef) + cid := OptClientId{} + msg.AddOption(&cid) + sid := OptServerId{} + duid := Duid{} + sid.Sid = duid + msg.AddOption(&sid) + + msg.SetMessage(MessageTypeConfirm) + rep, err := NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) + require.NoError(t, err) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.Type(), MessageTypeReply) + + msg.SetMessage(MessageTypeRenew) + rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) + require.NoError(t, err) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.Type(), MessageTypeReply) + + msg.SetMessage(MessageTypeRebind) + rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) + require.NoError(t, err) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.Type(), MessageTypeReply) + + msg.SetMessage(MessageTypeRelease) + rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) + require.NoError(t, err) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.Type(), MessageTypeReply) - msg3 := DHCPv6Message{} - optbf := OptBootFileURL{} - msg3.AddOption(&optbf) - require.True(t, IsNetboot(&msg3)) + msg.SetMessage(MessageTypeSolicit) + rep, err = NewReplyFromDHCPv6Message(&msg) + require.Error(t, err) + + relay := DHCPv6Relay{} + rep, err = NewReplyFromDHCPv6Message(&relay) + require.Error(t, err) } -func TestIsOptionRequested(t *testing.T) { - msg1 := DHCPv6Message{} - require.False(t, IsOptionRequested(&msg1, OptionDNSRecursiveNameServer)) +func TestNewMessageTypeSolicitWithCID(t *testing.T) { + hwAddr, err := net.ParseMAC("24:0A:9E:9F:EB:2B") + require.NoError(t, err) + + duid := Duid{ + Type: DUID_LL, + HwType: iana.HwTypeEthernet, + LinkLayerAddr: hwAddr, + } - msg2 := DHCPv6Message{} - optro := OptRequestedOption{} - optro.AddRequestedOption(OptionDNSRecursiveNameServer) - msg2.AddOption(&optro) - require.True(t, IsOptionRequested(&msg2, OptionDNSRecursiveNameServer)) + s, err := NewSolicitWithCID(duid) + require.NoError(t, err) + + require.Equal(t, s.Type(), MessageTypeSolicit) + // Check CID + cidOption := s.GetOneOption(OptionClientID) + require.NotNil(t, cidOption) + cid, ok := cidOption.(*OptClientId) + require.True(t, ok) + require.Equal(t, cid.Cid, duid) + + // Check ORO + oroOption := s.GetOneOption(OptionORO) + require.NotNil(t, oroOption) + oro, ok := oroOption.(*OptRequestedOption) + require.True(t, ok) + opts := oro.RequestedOptions() + require.Contains(t, opts, OptionDNSRecursiveNameServer) + require.Contains(t, opts, OptionDomainSearchList) + require.Equal(t, len(opts), 2) } + func TestIsUsingUEFIArchTypeTrue(t *testing.T) { msg := DHCPv6Message{} opt := OptClientArchType{ArchType: EFI_BC} diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index e601932..7ee00ad 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -286,6 +286,33 @@ func (d *DHCPv6Message) UpdateOption(option Option) { d.AddOption(option) } +// IsNetboot returns true if the machine is trying to netboot. It checks if +// "boot file" is one of the requested options, which is useful for +// SOLICIT/REQUEST packet types, it also checks if the "boot file" option is +// included in the packet, which is useful for ADVERTISE/REPLY packet. +func (d *DHCPv6Message) IsNetboot() bool { + if d.IsOptionRequested(OptionBootfileURL) { + return true + } + if optbf := d.GetOneOption(OptionBootfileURL); optbf != nil { + return true + } + return false +} + +// IsOptionRequested takes an OptionCode and returns true if that option is +// within the requested options of the DHCPv6 message. +func (d *DHCPv6Message) IsOptionRequested(requested OptionCode) bool { + for _, optoro := range d.GetOption(OptionORO) { + for _, o := range optoro.(*OptRequestedOption).RequestedOptions() { + if o == requested { + return true + } + } + } + return false +} + func (d *DHCPv6Message) String() string { return fmt.Sprintf("DHCPv6Message(messageType=%v transactionID=0x%06x, %d options)", d.MessageTypeToString(), d.TransactionID(), len(d.options), diff --git a/dhcpv6/dhcpv6message_test.go b/dhcpv6/dhcpv6message_test.go index ad90be6..5c92a7b 100644 --- a/dhcpv6/dhcpv6message_test.go +++ b/dhcpv6/dhcpv6message_test.go @@ -1,98 +1,34 @@ package dhcpv6 import ( - "net" "testing" - "github.com/insomniacslk/dhcp/iana" "github.com/stretchr/testify/require" ) -func TestNewAdvertiseFromSolicit(t *testing.T) { - s := DHCPv6Message{} - s.SetMessage(MessageTypeSolicit) - s.SetTransactionID(0xabcdef) - cid := OptClientId{} - s.AddOption(&cid) - duid := Duid{} +func TestIsNetboot(t *testing.T) { + msg1 := DHCPv6Message{} + require.False(t, msg1.IsNetboot()) - a, err := NewAdvertiseFromSolicit(&s, WithServerID(duid)) - require.NoError(t, err) - require.Equal(t, a.(*DHCPv6Message).TransactionID(), s.TransactionID()) - require.Equal(t, a.Type(), MessageTypeAdvertise) -} - -func TestNewReplyFromDHCPv6Message(t *testing.T) { - msg := DHCPv6Message{} - msg.SetTransactionID(0xabcdef) - cid := OptClientId{} - msg.AddOption(&cid) - sid := OptServerId{} - duid := Duid{} - sid.Sid = duid - msg.AddOption(&sid) - - msg.SetMessage(MessageTypeConfirm) - rep, err := NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) - require.NoError(t, err) - require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) - require.Equal(t, rep.Type(), MessageTypeReply) - - msg.SetMessage(MessageTypeRenew) - rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) - require.NoError(t, err) - require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) - require.Equal(t, rep.Type(), MessageTypeReply) - - msg.SetMessage(MessageTypeRebind) - rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) - require.NoError(t, err) - require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) - require.Equal(t, rep.Type(), MessageTypeReply) + msg2 := DHCPv6Message{} + optro := OptRequestedOption{} + optro.AddRequestedOption(OptionBootfileURL) + msg2.AddOption(&optro) + require.True(t, msg2.IsNetboot()) - msg.SetMessage(MessageTypeRelease) - rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) - require.NoError(t, err) - require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) - require.Equal(t, rep.Type(), MessageTypeReply) - - msg.SetMessage(MessageTypeSolicit) - rep, err = NewReplyFromDHCPv6Message(&msg) - require.Error(t, err) - - relay := DHCPv6Relay{} - rep, err = NewReplyFromDHCPv6Message(&relay) - require.Error(t, err) + msg3 := DHCPv6Message{} + optbf := OptBootFileURL{} + msg3.AddOption(&optbf) + require.True(t, msg3.IsNetboot()) } -func TestNewMessageTypeSolicitWithCID(t *testing.T) { - hwAddr, err := net.ParseMAC("24:0A:9E:9F:EB:2B") - require.NoError(t, err) - - duid := Duid{ - Type: DUID_LL, - HwType: iana.HwTypeEthernet, - LinkLayerAddr: hwAddr, - } - - s, err := NewSolicitWithCID(duid) - require.NoError(t, err) - - require.Equal(t, s.Type(), MessageTypeSolicit) - // Check CID - cidOption := s.GetOneOption(OptionClientID) - require.NotNil(t, cidOption) - cid, ok := cidOption.(*OptClientId) - require.True(t, ok) - require.Equal(t, cid.Cid, duid) +func TestIsOptionRequested(t *testing.T) { + msg1 := DHCPv6Message{} + require.False(t, msg1.IsOptionRequested(OptionDNSRecursiveNameServer)) - // Check ORO - oroOption := s.GetOneOption(OptionORO) - require.NotNil(t, oroOption) - oro, ok := oroOption.(*OptRequestedOption) - require.True(t, ok) - opts := oro.RequestedOptions() - require.Contains(t, opts, OptionDNSRecursiveNameServer) - require.Contains(t, opts, OptionDomainSearchList) - require.Equal(t, len(opts), 2) + msg2 := DHCPv6Message{} + optro := OptRequestedOption{} + optro.AddRequestedOption(OptionDNSRecursiveNameServer) + msg2.AddOption(&optro) + require.True(t, msg2.IsOptionRequested(OptionDNSRecursiveNameServer)) } |