summaryrefslogtreecommitdiffhomepage
path: root/dhcpv6
diff options
context:
space:
mode:
Diffstat (limited to 'dhcpv6')
-rw-r--r--dhcpv6/dhcpv6_test.go34
-rw-r--r--dhcpv6/dhcpv6message.go68
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 {