diff options
-rw-r--r-- | dhcpv6/dhcpv6_test.go | 21 | ||||
-rw-r--r-- | dhcpv6/dhcpv6message.go | 11 | ||||
-rw-r--r-- | dhcpv6/dhcpv6relay_test.go | 2 | ||||
-rw-r--r-- | dhcpv6/iputils.go | 5 | ||||
-rw-r--r-- | dhcpv6/modifiers.go | 3 | ||||
-rw-r--r-- | dhcpv6/modifiers_test.go | 6 | ||||
-rw-r--r-- | dhcpv6/option_clientid.go | 31 | ||||
-rw-r--r-- | dhcpv6/option_clientid_test.go | 34 | ||||
-rw-r--r-- | dhcpv6/options.go | 2 |
9 files changed, 55 insertions, 60 deletions
diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go index b23a858..6f476a1 100644 --- a/dhcpv6/dhcpv6_test.go +++ b/dhcpv6/dhcpv6_test.go @@ -165,11 +165,9 @@ func TestNewAdvertiseFromSolicit(t *testing.T) { MessageType: MessageTypeSolicit, TransactionID: TransactionID{0xa, 0xb, 0xc}, } - cid := OptClientId{} - s.AddOption(&cid) - duid := Duid{} + s.AddOption(OptClientID(Duid{})) - a, err := NewAdvertiseFromSolicit(&s, WithServerID(duid)) + a, err := NewAdvertiseFromSolicit(&s, WithServerID(Duid{})) require.NoError(t, err) require.Equal(t, a.TransactionID, s.TransactionID) require.Equal(t, a.Type(), MessageTypeAdvertise) @@ -180,11 +178,10 @@ func TestNewReplyFromMessage(t *testing.T) { TransactionID: TransactionID{0xa, 0xb, 0xc}, MessageType: MessageTypeConfirm, } - cid := OptClientId{} - msg.AddOption(&cid) + var duid Duid + msg.AddOption(OptClientID(duid)) sid := OptServerId{} - duid := Duid{} - sid.Sid = duid + sid.Sid = Duid{} msg.AddOption(&sid) rep, err := NewReplyFromMessage(&msg, WithServerID(duid)) @@ -242,11 +239,9 @@ func TestNewMessageTypeSolicit(t *testing.T) { 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) + cduid := s.Options.ClientID() + require.NotNil(t, cduid) + require.Equal(t, cduid, &duid) // Check ORO oroOption := s.GetOneOption(OptionORO) diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index d67882a..00452dc 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -29,6 +29,15 @@ func (mo MessageOptions) ArchTypes() iana.Archs { return opt.(*optClientArchType).Archs } +// ClientID returns the client identifier option. +func (mo MessageOptions) ClientID() *Duid { + opt := mo.GetOne(OptionClientID) + if opt == nil { + return nil + } + return &opt.(*optClientID).Duid +} + // Message represents a DHCPv6 Message as defined by RFC 3315 Section 6. type Message struct { MessageType MessageType @@ -72,7 +81,7 @@ func NewSolicit(hwaddr net.HardwareAddr, modifiers ...Modifier) (*Message, error return nil, err } m.MessageType = MessageTypeSolicit - m.AddOption(&OptClientId{Cid: duid}) + m.AddOption(OptClientID(duid)) oro := new(OptRequestedOption) oro.SetRequestedOptions([]OptionCode{ OptionDNSRecursiveNameServer, diff --git a/dhcpv6/dhcpv6relay_test.go b/dhcpv6/dhcpv6relay_test.go index 4070f54..773c047 100644 --- a/dhcpv6/dhcpv6relay_test.go +++ b/dhcpv6/dhcpv6relay_test.go @@ -91,7 +91,7 @@ func TestNewRelayRepFromRelayForw(t *testing.T) { // create the inner message s, err := NewMessage() require.NoError(t, err) - s.AddOption(&OptClientId{}) + s.AddOption(OptClientID(Duid{})) orm := OptRelayMsg{} orm.SetRelayMessage(s) rf.AddOption(&orm) diff --git a/dhcpv6/iputils.go b/dhcpv6/iputils.go index b8c5876..9c18da2 100644 --- a/dhcpv6/iputils.go +++ b/dhcpv6/iputils.go @@ -83,11 +83,10 @@ func ExtractMAC(packet DHCPv6) (net.HardwareAddr, error) { return nil, err } } - optclientid := msg.GetOneOption(OptionClientID) - if optclientid == nil { + duid := msg.(*Message).Options.ClientID() + if duid == nil { return nil, fmt.Errorf("client ID not found in packet") } - duid := optclientid.(*OptClientId).Cid if duid.LinkLayerAddr == nil { return nil, fmt.Errorf("failed to extract MAC") } diff --git a/dhcpv6/modifiers.go b/dhcpv6/modifiers.go index d5e24c0..4d00a0c 100644 --- a/dhcpv6/modifiers.go +++ b/dhcpv6/modifiers.go @@ -11,8 +11,7 @@ import ( // WithClientID adds a client ID option to a DHCPv6 packet func WithClientID(duid Duid) Modifier { return func(d DHCPv6) { - cid := OptClientId{Cid: duid} - d.UpdateOption(&cid) + d.UpdateOption(OptClientID(duid)) } } diff --git a/dhcpv6/modifiers_test.go b/dhcpv6/modifiers_test.go index ec8ff0b..ff3a87a 100644 --- a/dhcpv6/modifiers_test.go +++ b/dhcpv6/modifiers_test.go @@ -17,10 +17,8 @@ func TestWithClientID(t *testing.T) { } m, err := NewMessage(WithClientID(duid)) require.NoError(t, err) - opt := m.GetOneOption(OptionClientID) - require.NotNil(t, opt) - cid := opt.(*OptClientId) - require.Equal(t, cid.Cid, duid) + cid := m.Options.ClientID() + require.Equal(t, cid, &duid) } func TestWithServerID(t *testing.T) { diff --git a/dhcpv6/option_clientid.go b/dhcpv6/option_clientid.go index 200d1a6..0941bcc 100644 --- a/dhcpv6/option_clientid.go +++ b/dhcpv6/option_clientid.go @@ -4,36 +4,31 @@ import ( "fmt" ) -// OptClientId represents a Client ID option -// -// This module defines the OptClientId and DUID structures. -// https://www.ietf.org/rfc/rfc3315.txt -type OptClientId struct { - Cid Duid +// OptClientID represents a Client Identifier option as defined by RFC 3315 +// Section 22.2. +func OptClientID(d Duid) Option { + return &optClientID{d} } -func (op *OptClientId) Code() OptionCode { - return OptionClientID +type optClientID struct { + Duid } -// ToBytes marshals the Client ID option as defined by RFC 3315, Section 22.2. -func (op *OptClientId) ToBytes() []byte { - return op.Cid.ToBytes() +func (*optClientID) Code() OptionCode { + return OptionClientID } -func (op *OptClientId) String() string { - return fmt.Sprintf("OptClientId{cid=%v}", op.Cid.String()) +func (op *optClientID) String() string { + return fmt.Sprintf("ClientID: %v", op.Duid.String()) } -// ParseOptClientId builds an OptClientId structure from a sequence +// parseOptClientID builds an OptClientId structure from a sequence // of bytes. The input data does not include option code and length // bytes. -func ParseOptClientId(data []byte) (*OptClientId, error) { - var opt OptClientId +func parseOptClientID(data []byte) (*optClientID, error) { cid, err := DuidFromBytes(data) if err != nil { return nil, err } - opt.Cid = *cid - return &opt, nil + return &optClientID{*cid}, nil } diff --git a/dhcpv6/option_clientid_test.go b/dhcpv6/option_clientid_test.go index 69a60d1..2f1f1f0 100644 --- a/dhcpv6/option_clientid_test.go +++ b/dhcpv6/option_clientid_test.go @@ -8,27 +8,27 @@ import ( "github.com/stretchr/testify/require" ) -func TestParseOptClientId(t *testing.T) { +func TestParseOptClientID(t *testing.T) { data := []byte{ 0, 3, // DUID_LL 0, 1, // hwtype ethernet 0, 1, 2, 3, 4, 5, // hw addr } - opt, err := ParseOptClientId(data) + opt, err := parseOptClientID(data) require.NoError(t, err) - require.Equal(t, DUID_LL, opt.Cid.Type) - require.Equal(t, iana.HWTypeEthernet, opt.Cid.HwType) - require.Equal(t, net.HardwareAddr([]byte{0, 1, 2, 3, 4, 5}), opt.Cid.LinkLayerAddr) + require.Equal(t, DUID_LL, opt.Type) + require.Equal(t, iana.HWTypeEthernet, opt.HwType) + require.Equal(t, net.HardwareAddr([]byte{0, 1, 2, 3, 4, 5}), opt.LinkLayerAddr) } func TestOptClientIdToBytes(t *testing.T) { - opt := OptClientId{ - Cid: Duid{ + opt := OptClientID( + Duid{ Type: DUID_LL, HwType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr([]byte{5, 4, 3, 2, 1, 0}), }, - } + ) expected := []byte{ 0, 3, // DUID_LL 0, 1, // hwtype ethernet @@ -43,42 +43,42 @@ func TestOptClientIdDecodeEncode(t *testing.T) { 0, 1, // hwtype ethernet 5, 4, 3, 2, 1, 0, // hw addr } - opt, err := ParseOptClientId(data) + opt, err := parseOptClientID(data) require.NoError(t, err) require.Equal(t, data, opt.ToBytes()) } func TestOptionClientId(t *testing.T) { - opt := OptClientId{ - Cid: Duid{ + opt := OptClientID( + Duid{ Type: DUID_LL, HwType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr([]byte{0xde, 0xad, 0, 0, 0xbe, 0xef}), }, - } + ) require.Equal(t, OptionClientID, opt.Code()) require.Contains( t, opt.String(), - "cid=DUID{type=DUID-LL hwtype=Ethernet hwaddr=de:ad:00:00:be:ef}", + "ClientID: DUID{type=DUID-LL hwtype=Ethernet hwaddr=de:ad:00:00:be:ef}", "String() should contain the correct cid output", ) } -func TestOptClientIdParseOptClientIdBogusDUID(t *testing.T) { +func TestOptClientIdparseOptClientIDBogusDUID(t *testing.T) { data := []byte{ 0, 4, // DUID_UUID 1, 2, 3, 4, 5, 6, 7, 8, 9, // a UUID should be 18 bytes not 17 10, 11, 12, 13, 14, 15, 16, 17, } - _, err := ParseOptClientId(data) + _, err := parseOptClientID(data) require.Error(t, err, "A truncated OptClientId DUID should return an error") } -func TestOptClientIdParseOptClientIdInvalidTooShort(t *testing.T) { +func TestOptClientIdparseOptClientIDInvalidTooShort(t *testing.T) { data := []byte{ 0, // truncated: DUIDs are at least 2 bytes } - _, err := ParseOptClientId(data) + _, err := parseOptClientID(data) require.Error(t, err, "A truncated OptClientId should return an error") } diff --git a/dhcpv6/options.go b/dhcpv6/options.go index bf37600..ef7c23a 100644 --- a/dhcpv6/options.go +++ b/dhcpv6/options.go @@ -40,7 +40,7 @@ func ParseOption(code OptionCode, optData []byte) (Option, error) { ) switch code { case OptionClientID: - opt, err = ParseOptClientId(optData) + opt, err = parseOptClientID(optData) case OptionServerID: opt, err = ParseOptServerId(optData) case OptionIANA: |