diff options
author | Pablo Mazzini <pmazzini@gmail.com> | 2018-07-08 23:53:07 +0100 |
---|---|---|
committer | insomniac <insomniacslk@users.noreply.github.com> | 2018-07-08 23:53:07 +0100 |
commit | ab01f8d86f0edc6873008db8983ffa34363db3a5 (patch) | |
tree | 4f0b793e71c2b10c0412250acc2610f5947030fa | |
parent | f15362a37221d3c20f1844dfdf6151a265123608 (diff) |
add NewReplyFromDHCPv6Message (#78)
Add a more generic NewReplyFromMessage to avoid code duplication.
This is one step closer towards fixing issue #73.
Leave NewReplyFromRequest, NewReplyFromRenew and NewReplyFromRebind
for backwards compatibility.
-rw-r--r-- | dhcpv6/dhcpv6_test.go | 73 | ||||
-rw-r--r-- | dhcpv6/dhcpv6message.go | 106 |
2 files changed, 49 insertions, 130 deletions
diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go index 9f37def..f8ec76d 100644 --- a/dhcpv6/dhcpv6_test.go +++ b/dhcpv6/dhcpv6_test.go @@ -82,72 +82,61 @@ func TestFromAndToBytes(t *testing.T) { require.Equal(t, expected, toBytes) } -func withServerID(d DHCPv6) DHCPv6 { - sid := OptServerId{} - d.AddOption(&sid) - return d -} - func TestNewAdvertiseFromSolicit(t *testing.T) { s := DHCPv6Message{} s.SetMessage(SOLICIT) s.SetTransactionID(0xabcdef) cid := OptClientId{} s.AddOption(&cid) + duid := Duid{} - a, err := NewAdvertiseFromSolicit(&s, withServerID) + a, err := NewAdvertiseFromSolicit(&s, WithServerID(duid)) require.NoError(t, err) require.Equal(t, a.(*DHCPv6Message).TransactionID(), s.TransactionID()) require.Equal(t, a.Type(), ADVERTISE) } -func TestNewReplyFromRequest(t *testing.T) { - req := DHCPv6Message{} - req.SetMessage(REQUEST) - req.SetTransactionID(0xabcdef) +func TestNewReplyFromDHCPv6Message(t *testing.T) { + msg := DHCPv6Message{} + msg.SetTransactionID(0xabcdef) cid := OptClientId{} - req.AddOption(&cid) + msg.AddOption(&cid) sid := OptServerId{} - req.AddOption(&sid) + duid := Duid{} + sid.Sid = duid + msg.AddOption(&sid) - rep, err := NewReplyFromRequest(&req) + msg.SetMessage(CONFIRM) + rep, err := NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) require.NoError(t, err) - require.Equal(t, rep.(*DHCPv6Message).TransactionID(), req.TransactionID()) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) require.Equal(t, rep.Type(), REPLY) -} -func TestNewReplyFromRenew(t *testing.T) { - ren := DHCPv6Message{} - ren.SetMessage(RENEW) - ren.SetTransactionID(0xabcdef) - cid := OptClientId{} - ren.AddOption(&cid) + msg.SetMessage(RENEW) + rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) + require.NoError(t, err) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.Type(), REPLY) - rep, err := NewReplyFromRenew(&ren) - require.Error(t, err) + msg.SetMessage(REBIND) + rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) + require.NoError(t, err) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.Type(), REPLY) - sid := OptServerId{} - ren.AddOption(&sid) - rep, err = NewReplyFromRenew(&ren) - require.Equal(t, rep.(*DHCPv6Message).TransactionID(), ren.TransactionID()) + msg.SetMessage(RELEASE) + rep, err = NewReplyFromDHCPv6Message(&msg, WithServerID(duid)) + require.NoError(t, err) + require.Equal(t, rep.(*DHCPv6Message).TransactionID(), msg.TransactionID()) require.Equal(t, rep.Type(), REPLY) -} -func TestNewReplyFromRebind(t *testing.T) { - reb := DHCPv6Message{} - reb.SetMessage(REPLY) - rep, err := NewReplyFromRebind(&reb) + msg.SetMessage(SOLICIT) + rep, err = NewReplyFromDHCPv6Message(&msg) 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) + relay := DHCPv6Relay{} + rep, err = NewReplyFromDHCPv6Message(&relay) + require.Error(t, err) } // TODO test NewSolicit diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index 7c22642..ef87a43 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -198,102 +198,32 @@ 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 { - return nil, errors.New("REQUEST cannot be nil") - } - if request.Type() != REQUEST { - return nil, errors.New("The passed REQUEST must have REQUEST type set") - } - req, ok := request.(*DHCPv6Message) +// NewReplyFromDHCPv6Message creates a new REPLY packet based on a +// DHCPv6Message. The function is to be used when generating a reply to +// REQUEST, CONFIRM, RENEW, REBIND and RELEASE packets. +func NewReplyFromDHCPv6Message(message DHCPv6, modifiers ...Modifier) (DHCPv6, error) { + if message == nil { + return nil, errors.New("DHCPv6Message cannot be nil") + } + switch message.Type() { + case REQUEST, CONFIRM, RENEW, REBIND, RELEASE: + default: + return nil, errors.New("Cannot create REPLY from the passed message type set") + } + msg, ok := message.(*DHCPv6Message) if !ok { - return nil, errors.New("The passed REQUEST must be of DHCPv6Message type") + return nil, errors.New("The passed MESSAGE must be of DHCPv6Message type") } - // build REPLY from REQUEST + // build REPLY from MESSAGE rep := DHCPv6Message{} rep.SetMessage(REPLY) - rep.SetTransactionID(req.TransactionID()) + rep.SetTransactionID(msg.TransactionID()) // add Client ID - cid := req.GetOneOption(OPTION_CLIENTID) + cid := message.GetOneOption(OPTION_CLIENTID) if cid == nil { - return nil, errors.New("Client ID cannot be nil in REQUEST when building REPLY") + return nil, errors.New("Client ID cannot be nil when building REPLY") } rep.AddOption(cid) - // add Server ID - sid := req.GetOneOption(OPTION_SERVERID) - if sid == nil { - return nil, errors.New("Server ID cannot be nil in REQUEST when building REPLY") - } - rep.AddOption(sid) // apply modifiers d := DHCPv6(&rep) |