diff options
Diffstat (limited to 'dhcpv6')
-rw-r--r-- | dhcpv6/dhcpv6_test.go | 34 | ||||
-rw-r--r-- | dhcpv6/dhcpv6message.go | 68 |
2 files changed, 102 insertions, 0 deletions
diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go index ff89280..9f37def 100644 --- a/dhcpv6/dhcpv6_test.go +++ b/dhcpv6/dhcpv6_test.go @@ -116,5 +116,39 @@ func TestNewReplyFromRequest(t *testing.T) { require.Equal(t, rep.Type(), REPLY) } +func TestNewReplyFromRenew(t *testing.T) { + ren := DHCPv6Message{} + ren.SetMessage(RENEW) + ren.SetTransactionID(0xabcdef) + cid := OptClientId{} + ren.AddOption(&cid) + + rep, err := NewReplyFromRenew(&ren) + require.Error(t, err) + + sid := OptServerId{} + ren.AddOption(&sid) + rep, err = NewReplyFromRenew(&ren) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), ren.TransactionID()) + require.Equal(t, rep.Type(), REPLY) +} + +func TestNewReplyFromRebind(t *testing.T) { + reb := DHCPv6Message{} + reb.SetMessage(REPLY) + rep, err := NewReplyFromRebind(&reb) + require.Error(t, err) + + reb.SetMessage(REBIND) + reb.SetTransactionID(0xabcdef) + cid := OptClientId{} + reb.AddOption(&cid) + + rep, err = NewReplyFromRebind(&reb) + require.NoError(t, err) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), reb.TransactionID()) + require.Equal(t, rep.Type(), REPLY) +} + // TODO test NewSolicit // test String and Summary diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index ab014b3..7c22642 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -198,6 +198,74 @@ func NewRequestFromAdvertise(advertise DHCPv6, modifiers ...Modifier) (DHCPv6, e return d, nil } +// NewReplyFromRebind creates a new REPLY packet based on a REBIND packet. +func NewReplyFromRebind(rebind DHCPv6, modifiers ...Modifier) (DHCPv6, error) { + if rebind == nil { + return nil, errors.New("REBIND cannot be nil") + } + if rebind.Type() != REBIND { + return nil, errors.New("The passed REBIND must have REBIND type set") + } + reb, ok := rebind.(*DHCPv6Message) + if !ok { + return nil, errors.New("The passed REBIND must be of DHCPv6Message type") + } + // build REPLY from REBIND + rep := DHCPv6Message{} + rep.SetMessage(REPLY) + rep.SetTransactionID(reb.TransactionID()) + // add Client ID + cid := reb.GetOneOption(OPTION_CLIENTID) + if cid == nil { + return nil, errors.New("Client ID cannot be nil in REBIND when building REPLY") + } + rep.AddOption(cid) + + // apply modifiers + d := DHCPv6(&rep) + for _, mod := range modifiers { + d = mod(d) + } + return d, nil +} + +// NewReplyFromRenew creates a new REPLY packet based on a RENEW packet. +func NewReplyFromRenew(renew DHCPv6, modifiers ...Modifier) (DHCPv6, error) { + if renew == nil { + return nil, errors.New("RENEW cannot be nil") + } + if renew.Type() != RENEW { + return nil, errors.New("The passed RENEW must have RENEW type set") + } + ren, ok := renew.(*DHCPv6Message) + if !ok { + return nil, errors.New("The passed RENEW must be of DHCPv6Message type") + } + // build REPLY from RENEW + rep := DHCPv6Message{} + rep.SetMessage(REPLY) + rep.SetTransactionID(ren.TransactionID()) + // add Client ID + cid := ren.GetOneOption(OPTION_CLIENTID) + if cid == nil { + return nil, errors.New("Client ID cannot be nil in RENEW when building REPLY") + } + rep.AddOption(cid) + // add Server ID + sid := ren.GetOneOption(OPTION_SERVERID) + if sid == nil { + return nil, errors.New("Server ID cannot be nil in RENEW when building REPLY") + } + rep.AddOption(sid) + + // apply modifiers + d := DHCPv6(&rep) + for _, mod := range modifiers { + d = mod(d) + } + return d, nil +} + // NewReplyFromRequest creates a new REPLY packet based on a REQUEST packet. func NewReplyFromRequest(request DHCPv6, modifiers ...Modifier) (DHCPv6, error) { if request == nil { |