diff options
-rw-r--r-- | dhcpv6/async/client.go | 2 | ||||
-rw-r--r-- | dhcpv6/async/client_test.go | 2 | ||||
-rw-r--r-- | dhcpv6/client6/client.go | 10 | ||||
-rw-r--r-- | dhcpv6/dhcpv6.go | 49 | ||||
-rw-r--r-- | dhcpv6/dhcpv6_test.go | 99 | ||||
-rw-r--r-- | dhcpv6/dhcpv6message.go | 192 | ||||
-rw-r--r-- | dhcpv6/dhcpv6relay.go | 114 | ||||
-rw-r--r-- | dhcpv6/dhcpv6relay_test.go | 72 | ||||
-rw-r--r-- | dhcpv6/iputils.go | 2 | ||||
-rw-r--r-- | dhcpv6/modifiers.go | 30 | ||||
-rw-r--r-- | dhcpv6/modifiers_test.go | 29 | ||||
-rw-r--r-- | dhcpv6/option_relaymsg_test.go | 16 | ||||
-rw-r--r-- | dhcpv6/server6/server_test.go | 3 | ||||
-rw-r--r-- | examples/packetcrafting6/main.go | 4 | ||||
-rw-r--r-- | netboot/netconf_test.go | 3 |
15 files changed, 234 insertions, 393 deletions
diff --git a/dhcpv6/async/client.go b/dhcpv6/async/client.go index 4c73383..4749e70 100644 --- a/dhcpv6/async/client.go +++ b/dhcpv6/async/client.go @@ -210,7 +210,7 @@ func (c *Client) remoteAddr() (*net.UDPAddr, error) { // Returns a future which resolves to response and error. func (c *Client) Send(message dhcpv6.DHCPv6, modifiers ...dhcpv6.Modifier) *promise.Future { for _, mod := range modifiers { - message = mod(message) + mod(message) } transactionID, err := dhcpv6.GetTransactionID(message) diff --git a/dhcpv6/async/client_test.go b/dhcpv6/async/client_test.go index a49623e..9b58112 100644 --- a/dhcpv6/async/client_test.go +++ b/dhcpv6/async/client_test.go @@ -15,7 +15,7 @@ import ( const retries = 5 // solicit creates new solicit based on the mac address -func solicit(input string) (dhcpv6.DHCPv6, error) { +func solicit(input string) (*dhcpv6.Message, error) { mac, err := net.ParseMAC(input) if err != nil { return nil, err diff --git a/dhcpv6/client6/client.go b/dhcpv6/client6/client.go index c5b522d..3ede17e 100644 --- a/dhcpv6/client6/client.go +++ b/dhcpv6/client6/client.go @@ -65,7 +65,7 @@ func (c *Client) Exchange(ifname string, modifiers ...dhcpv6.Modifier) ([]dhcpv6 return conversation, err } } - request, reply, err := c.Request(ifname, advertise, modifiers...) + request, reply, err := c.Request(ifname, advertise.(*dhcpv6.Message), modifiers...) if request != nil { conversation = append(conversation, request) } @@ -172,7 +172,7 @@ func (c *Client) sendReceive(ifname string, packet dhcpv6.DHCPv6, expectedType d // if a regular message, check the transaction ID first // XXX should this unpack relay messages and check the XID of the // inner packet too? - if msg.TransactionID() != recvMsg.TransactionID() { + if msg.TransactionID != recvMsg.TransactionID { // different XID, we don't want this packet for sure continue } @@ -196,7 +196,7 @@ func (c *Client) Solicit(ifname string, modifiers ...dhcpv6.Modifier) (dhcpv6.DH return nil, nil, err } for _, mod := range modifiers { - solicit = mod(solicit) + mod(solicit) } advertise, err := c.sendReceive(ifname, solicit, dhcpv6.MessageTypeNone) return solicit, advertise, err @@ -205,13 +205,13 @@ func (c *Client) Solicit(ifname string, modifiers ...dhcpv6.Modifier) (dhcpv6.DH // Request sends a Request built from an Advertise. It returns the Request, a // Reply (if not nil), and an error if any. The modifiers will be applied to // the Request before sending it, see modifiers.go -func (c *Client) Request(ifname string, advertise dhcpv6.DHCPv6, modifiers ...dhcpv6.Modifier) (dhcpv6.DHCPv6, dhcpv6.DHCPv6, error) { +func (c *Client) Request(ifname string, advertise *dhcpv6.Message, modifiers ...dhcpv6.Modifier) (dhcpv6.DHCPv6, dhcpv6.DHCPv6, error) { request, err := dhcpv6.NewRequestFromAdvertise(advertise) if err != nil { return nil, nil, err } for _, mod := range modifiers { - request = mod(request) + mod(request) } reply, err := c.sendReceive(ifname, request, dhcpv6.MessageTypeNone) return request, reply, err diff --git a/dhcpv6/dhcpv6.go b/dhcpv6/dhcpv6.go index 41fbda8..3c5e193 100644 --- a/dhcpv6/dhcpv6.go +++ b/dhcpv6/dhcpv6.go @@ -13,20 +13,18 @@ import ( type DHCPv6 interface { Type() MessageType ToBytes() []byte - Options() []Option String() string Summary() string IsRelay() bool GetOption(code OptionCode) []Option GetOneOption(code OptionCode) Option - SetOptions(options []Option) AddOption(Option) UpdateOption(Option) } // Modifier defines the signature for functions that can modify DHCPv6 // structures. This is used to simplify packet manipulation -type Modifier func(d DHCPv6) DHCPv6 +type Modifier func(d DHCPv6) // MessageFromBytes parses a DHCPv6 message from a byte stream. func MessageFromBytes(data []byte) (*Message, error) { @@ -38,10 +36,10 @@ func MessageFromBytes(data []byte) (*Message, error) { } d := &Message{ - messageType: messageType, + MessageType: messageType, } - buf.ReadBytes(d.transactionID[:]) - if err := d.options.FromBytes(buf.Data()); err != nil { + buf.ReadBytes(d.TransactionID[:]) + if err := d.Options.FromBytes(buf.Data()); err != nil { return nil, err } return d, nil @@ -57,14 +55,14 @@ func RelayMessageFromBytes(data []byte) (*RelayMessage, error) { } d := &RelayMessage{ - messageType: messageType, - hopCount: buf.Read8(), + MessageType: messageType, + HopCount: buf.Read8(), } - d.linkAddr = net.IP(buf.CopyN(net.IPv6len)) - d.peerAddr = net.IP(buf.CopyN(net.IPv6len)) + d.LinkAddr = net.IP(buf.CopyN(net.IPv6len)) + d.PeerAddr = net.IP(buf.CopyN(net.IPv6len)) // TODO: fail if no OptRelayMessage is present. - if err := d.options.FromBytes(buf.Data()); err != nil { + if err := d.Options.FromBytes(buf.Data()); err != nil { return nil, err } return d, nil @@ -83,21 +81,20 @@ func FromBytes(data []byte) (DHCPv6, error) { } // NewMessage creates a new DHCPv6 message with default options -func NewMessage(modifiers ...Modifier) (DHCPv6, error) { +func NewMessage(modifiers ...Modifier) (*Message, error) { tid, err := GenerateTransactionID() if err != nil { return nil, err } - msg := Message{ - messageType: MessageTypeSolicit, - transactionID: tid, + msg := &Message{ + MessageType: MessageTypeSolicit, + TransactionID: tid, } // apply modifiers - d := DHCPv6(&msg) for _, mod := range modifiers { - d = mod(d) + mod(msg) } - return d, nil + return msg, nil } // DecapsulateRelay extracts the content of a relay message. It does not recurse @@ -153,20 +150,20 @@ func DecapsulateRelayIndex(l DHCPv6, index int) (DHCPv6, error) { // EncapsulateRelay creates a RelayMessage message containing the passed DHCPv6 // message as payload. The passed message type must be either RELAY_FORW or // RELAY_REPL -func EncapsulateRelay(d DHCPv6, mType MessageType, linkAddr, peerAddr net.IP) (DHCPv6, error) { +func EncapsulateRelay(d DHCPv6, mType MessageType, linkAddr, peerAddr net.IP) (*RelayMessage, error) { if mType != MessageTypeRelayForward && mType != MessageTypeRelayReply { return nil, fmt.Errorf("Message type must be either RELAY_FORW or RELAY_REPL") } outer := RelayMessage{ - messageType: mType, - linkAddr: linkAddr, - peerAddr: peerAddr, + MessageType: mType, + LinkAddr: linkAddr, + PeerAddr: peerAddr, } if d.IsRelay() { relay := d.(*RelayMessage) - outer.hopCount = relay.hopCount + 1 + outer.HopCount = relay.HopCount + 1 } else { - outer.hopCount = 0 + outer.HopCount = 0 } orm := OptRelayMsg{relayMessage: d} outer.AddOption(&orm) @@ -175,7 +172,7 @@ func EncapsulateRelay(d DHCPv6, mType MessageType, linkAddr, peerAddr net.IP) (D // 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 { +func IsUsingUEFI(msg *Message) bool { // RFC 4578 says: // As of the writing of this document, the following pre-boot // architecture types have been requested. @@ -215,7 +212,7 @@ func IsUsingUEFI(msg DHCPv6) bool { // in case of relay func GetTransactionID(packet DHCPv6) (TransactionID, error) { if message, ok := packet.(*Message); ok { - return message.TransactionID(), nil + return message.TransactionID, nil } if relay, ok := packet.(*RelayMessage); ok { message, err := relay.GetInnerMessage() diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go index f33f0e9..166fa7d 100644 --- a/dhcpv6/dhcpv6_test.go +++ b/dhcpv6/dhcpv6_test.go @@ -63,8 +63,8 @@ func TestNewMessage(t *testing.T) { require.NoError(t, err) require.NotNil(t, d) require.Equal(t, MessageTypeSolicit, d.Type()) - require.NotEqual(t, 0, d.(*Message).transactionID) - require.Empty(t, d.(*Message).options) + require.NotEqual(t, 0, d.TransactionID) + require.Empty(t, d.Options) } func TestDecapsulateRelayIndex(t *testing.T) { @@ -80,17 +80,17 @@ func TestDecapsulateRelayIndex(t *testing.T) { require.NoError(t, err) relay, ok := first.(*RelayMessage) require.True(t, ok) - require.Equal(t, relay.HopCount(), uint8(1)) - require.Equal(t, relay.LinkAddr(), net.IPv6loopback) - require.Equal(t, relay.PeerAddr(), net.IPv6linklocalallnodes) + require.Equal(t, relay.HopCount, uint8(1)) + require.Equal(t, relay.LinkAddr, net.IPv6loopback) + require.Equal(t, relay.PeerAddr, net.IPv6linklocalallnodes) second, err := DecapsulateRelayIndex(r3, 1) require.NoError(t, err) relay, ok = second.(*RelayMessage) require.True(t, ok) - require.Equal(t, relay.HopCount(), uint8(0)) - require.Equal(t, relay.LinkAddr(), net.IPv6linklocalallnodes) - require.Equal(t, relay.PeerAddr(), net.IPv6interfacelocalallnodes) + require.Equal(t, relay.HopCount, uint8(0)) + require.Equal(t, relay.LinkAddr, net.IPv6linklocalallnodes) + require.Equal(t, relay.PeerAddr, net.IPv6interfacelocalallnodes) third, err := DecapsulateRelayIndex(r3, 2) require.NoError(t, err) @@ -101,46 +101,27 @@ func TestDecapsulateRelayIndex(t *testing.T) { require.NoError(t, err) relay, ok = rfirst.(*RelayMessage) require.True(t, ok) - require.Equal(t, relay.HopCount(), uint8(0)) - require.Equal(t, relay.LinkAddr(), net.IPv6linklocalallnodes) - require.Equal(t, relay.PeerAddr(), net.IPv6interfacelocalallnodes) + require.Equal(t, relay.HopCount, uint8(0)) + require.Equal(t, relay.LinkAddr, net.IPv6linklocalallnodes) + require.Equal(t, relay.PeerAddr, net.IPv6interfacelocalallnodes) _, err = DecapsulateRelayIndex(r3, -2) require.Error(t, err) } -func TestSettersAndGetters(t *testing.T) { - d := Message{} - // Message - d.SetMessage(MessageTypeSolicit) - require.Equal(t, MessageTypeSolicit, d.Type()) - d.SetMessage(MessageTypeAdvertise) - require.Equal(t, MessageTypeAdvertise, d.Type()) - - // TransactionID - xid := TransactionID{0xa, 0xb, 0xc} - d.SetTransactionID(xid) - require.Equal(t, xid, d.TransactionID()) - - // Options - require.Empty(t, d.Options()) - expectedOptions := []Option{&OptionGeneric{OptionCode: 0, OptionData: []byte{}}} - d.SetOptions(expectedOptions) - require.Equal(t, expectedOptions, d.Options()) -} - func TestAddOption(t *testing.T) { d := Message{} - require.Empty(t, d.Options()) + require.Empty(t, d.Options) opt := OptionGeneric{OptionCode: 0, OptionData: []byte{}} d.AddOption(&opt) - require.Equal(t, []Option{&opt}, d.Options()) + require.Equal(t, Options{&opt}, d.Options) } func TestToBytes(t *testing.T) { - d := Message{} - d.SetMessage(MessageTypeSolicit) - d.SetTransactionID(TransactionID{0xa, 0xb, 0xc}) + d := Message{ + MessageType: MessageTypeSolicit, + TransactionID: TransactionID{0xa, 0xb, 0xc}, + } d.AddOption(&OptionGeneric{OptionCode: 0, OptionData: []byte{}}) bytes := d.ToBytes() @@ -157,24 +138,25 @@ func TestFromAndToBytes(t *testing.T) { } func TestNewAdvertiseFromSolicit(t *testing.T) { - s := Message{} - s.SetMessage(MessageTypeSolicit) - xid := TransactionID{0xa, 0xb, 0xc} - s.SetTransactionID(xid) + s := Message{ + MessageType: MessageTypeSolicit, + TransactionID: TransactionID{0xa, 0xb, 0xc}, + } cid := OptClientId{} s.AddOption(&cid) duid := Duid{} a, err := NewAdvertiseFromSolicit(&s, WithServerID(duid)) require.NoError(t, err) - require.Equal(t, a.(*Message).TransactionID(), s.TransactionID()) + require.Equal(t, a.TransactionID, s.TransactionID) require.Equal(t, a.Type(), MessageTypeAdvertise) } func TestNewReplyFromMessage(t *testing.T) { - msg := Message{} - xid := TransactionID{0xa, 0xb, 0xc} - msg.SetTransactionID(xid) + msg := Message{ + TransactionID: TransactionID{0xa, 0xb, 0xc}, + MessageType: MessageTypeConfirm, + } cid := OptClientId{} msg.AddOption(&cid) sid := OptServerId{} @@ -182,43 +164,38 @@ func TestNewReplyFromMessage(t *testing.T) { sid.Sid = duid msg.AddOption(&sid) - msg.SetMessage(MessageTypeConfirm) rep, err := NewReplyFromMessage(&msg, WithServerID(duid)) require.NoError(t, err) - require.Equal(t, rep.(*Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.TransactionID, msg.TransactionID) require.Equal(t, rep.Type(), MessageTypeReply) - msg.SetMessage(MessageTypeRenew) + msg.MessageType = MessageTypeRenew rep, err = NewReplyFromMessage(&msg, WithServerID(duid)) require.NoError(t, err) - require.Equal(t, rep.(*Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.TransactionID, msg.TransactionID) require.Equal(t, rep.Type(), MessageTypeReply) - msg.SetMessage(MessageTypeRebind) + msg.MessageType = MessageTypeRebind rep, err = NewReplyFromMessage(&msg, WithServerID(duid)) require.NoError(t, err) - require.Equal(t, rep.(*Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.TransactionID, msg.TransactionID) require.Equal(t, rep.Type(), MessageTypeReply) - msg.SetMessage(MessageTypeRelease) + msg.MessageType = MessageTypeRelease rep, err = NewReplyFromMessage(&msg, WithServerID(duid)) require.NoError(t, err) - require.Equal(t, rep.(*Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.TransactionID, msg.TransactionID) require.Equal(t, rep.Type(), MessageTypeReply) - msg.SetMessage(MessageTypeInformationRequest) + msg.MessageType = MessageTypeInformationRequest rep, err = NewReplyFromMessage(&msg, WithServerID(duid)) require.NoError(t, err) - require.Equal(t, rep.(*Message).TransactionID(), msg.TransactionID()) + require.Equal(t, rep.TransactionID, msg.TransactionID) require.Equal(t, rep.Type(), MessageTypeReply) - msg.SetMessage(MessageTypeSolicit) + msg.MessageType = MessageTypeSolicit rep, err = NewReplyFromMessage(&msg) require.Error(t, err) - - relay := RelayMessage{} - rep, err = NewReplyFromMessage(&relay) - require.Error(t, err) } func TestNewMessageTypeSolicitWithCID(t *testing.T) { @@ -286,7 +263,7 @@ func TestGetTransactionIDMessage(t *testing.T) { require.NoError(t, err) transactionID, err := GetTransactionID(message) require.NoError(t, err) - require.Equal(t, transactionID, message.(*Message).TransactionID()) + require.Equal(t, transactionID, message.TransactionID) } func TestGetTransactionIDRelay(t *testing.T) { @@ -296,7 +273,7 @@ func TestGetTransactionIDRelay(t *testing.T) { require.NoError(t, err) transactionID, err := GetTransactionID(relay) require.NoError(t, err) - require.Equal(t, transactionID, message.(*Message).TransactionID()) + require.Equal(t, transactionID, message.TransactionID) } // TODO test NewMessageTypeSolicit diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index 795e9fc..c367d36 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -4,7 +4,6 @@ import ( "crypto/rand" "errors" "fmt" - "log" "net" "time" @@ -16,9 +15,9 @@ const MessageHeaderSize = 4 // Message represents a DHCPv6 Message as defined by RFC 3315 Section 6. type Message struct { - messageType MessageType - transactionID TransactionID - options Options + MessageType MessageType + TransactionID TransactionID + Options Options } var randomRead = rand.Read @@ -44,36 +43,36 @@ func GetTime() uint32 { } // NewSolicitWithCID creates a new SOLICIT message with CID. -func NewSolicitWithCID(duid Duid, modifiers ...Modifier) (DHCPv6, error) { - d, err := NewMessage() +func NewSolicitWithCID(duid Duid, modifiers ...Modifier) (*Message, error) { + m, err := NewMessage() if err != nil { return nil, err } - d.(*Message).SetMessage(MessageTypeSolicit) - d.AddOption(&OptClientId{Cid: duid}) + m.MessageType = MessageTypeSolicit + m.AddOption(&OptClientId{Cid: duid}) oro := new(OptRequestedOption) oro.SetRequestedOptions([]OptionCode{ OptionDNSRecursiveNameServer, OptionDomainSearchList, }) - d.AddOption(oro) - d.AddOption(&OptElapsedTime{}) + m.AddOption(oro) + m.AddOption(&OptElapsedTime{}) // FIXME use real values for IA_NA iaNa := &OptIANA{} iaNa.IaId = [4]byte{0xfa, 0xce, 0xb0, 0x0c} iaNa.T1 = 0xe10 iaNa.T2 = 0x1518 - d.AddOption(iaNa) + m.AddOption(iaNa) // Apply modifiers for _, mod := range modifiers { - d = mod(d) + mod(m) } - return d, nil + return m, nil } // NewSolicitForInterface creates a new SOLICIT message with DUID-LLT, using the // given network interface's hardware address and current time -func NewSolicitForInterface(ifname string, modifiers ...Modifier) (DHCPv6, error) { +func NewSolicitForInterface(ifname string, modifiers ...Modifier) (*Message, error) { iface, err := net.InterfaceByName(ifname) if err != nil { return nil, err @@ -88,21 +87,18 @@ func NewSolicitForInterface(ifname string, modifiers ...Modifier) (DHCPv6, error } // NewAdvertiseFromSolicit creates a new ADVERTISE packet based on an SOLICIT packet. -func NewAdvertiseFromSolicit(solicit DHCPv6, modifiers ...Modifier) (DHCPv6, error) { - if solicit == nil { +func NewAdvertiseFromSolicit(sol *Message, modifiers ...Modifier) (*Message, error) { + if sol == nil { return nil, errors.New("SOLICIT cannot be nil") } - if solicit.Type() != MessageTypeSolicit { + if sol.Type() != MessageTypeSolicit { return nil, errors.New("The passed SOLICIT must have SOLICIT type set") } - sol, ok := solicit.(*Message) - if !ok { - return nil, errors.New("The passed SOLICIT must be of Message type") - } // build ADVERTISE from SOLICIT - adv := Message{} - adv.SetMessage(MessageTypeAdvertise) - adv.SetTransactionID(sol.TransactionID()) + adv := &Message{ + MessageType: MessageTypeAdvertise, + TransactionID: sol.TransactionID, + } // add Client ID cid := sol.GetOneOption(OptionClientID) if cid == nil { @@ -111,30 +107,26 @@ func NewAdvertiseFromSolicit(solicit DHCPv6, modifiers ...Modifier) (DHCPv6, err adv.AddOption(cid) // apply modifiers - d := DHCPv6(&adv) for _, mod := range modifiers { - d = mod(d) + mod(adv) } - return d, nil + return adv, nil } // NewRequestFromAdvertise creates a new REQUEST packet based on an ADVERTISE // packet options. -func NewRequestFromAdvertise(advertise DHCPv6, modifiers ...Modifier) (DHCPv6, error) { - if advertise == nil { - return nil, fmt.Errorf("ADVERTISE cannot be nil") +func NewRequestFromAdvertise(adv *Message, modifiers ...Modifier) (*Message, error) { + if adv == nil { + return nil, errors.New("ADVERTISE cannot be nil") } - if advertise.Type() != MessageTypeAdvertise { + if adv.MessageType != MessageTypeAdvertise { return nil, fmt.Errorf("The passed ADVERTISE must have ADVERTISE type set") } - adv, ok := advertise.(*Message) - if !ok { - return nil, fmt.Errorf("The passed ADVERTISE must be of Message type") - } // build REQUEST from ADVERTISE - req := Message{} - req.SetMessage(MessageTypeRequest) - req.SetTransactionID(adv.TransactionID()) + req := &Message{ + MessageType: MessageTypeRequest, + TransactionID: adv.TransactionID, + } // add Client ID cid := adv.GetOneOption(OptionClientID) if cid == nil { @@ -170,102 +162,70 @@ func NewRequestFromAdvertise(advertise DHCPv6, modifiers ...Modifier) (DHCPv6, e } // apply modifiers - d := DHCPv6(&req) for _, mod := range modifiers { - d = mod(d) + mod(req) } - return d, nil + return req, nil } // NewReplyFromMessage creates a new REPLY packet based on a // Message. The function is to be used when generating a reply to // REQUEST, CONFIRM, RENEW, REBIND, RELEASE and INFORMATION-REQUEST packets. -func NewReplyFromMessage(message DHCPv6, modifiers ...Modifier) (DHCPv6, error) { - if message == nil { +func NewReplyFromMessage(msg *Message, modifiers ...Modifier) (*Message, error) { + if msg == nil { return nil, errors.New("Message cannot be nil") } - switch message.Type() { + switch msg.Type() { case MessageTypeRequest, MessageTypeConfirm, MessageTypeRenew, MessageTypeRebind, MessageTypeRelease, MessageTypeInformationRequest: default: return nil, errors.New("Cannot create REPLY from the passed message type set") } - msg, ok := message.(*Message) - if !ok { - return nil, errors.New("The passed MESSAGE must be of Message type") - } + // build REPLY from MESSAGE - rep := Message{} - rep.SetMessage(MessageTypeReply) - rep.SetTransactionID(msg.TransactionID()) + rep := &Message{ + MessageType: MessageTypeReply, + TransactionID: msg.TransactionID, + } // add Client ID - cid := message.GetOneOption(OptionClientID) + cid := msg.GetOneOption(OptionClientID) if cid == nil { return nil, errors.New("Client ID cannot be nil when building REPLY") } rep.AddOption(cid) // apply modifiers - d := DHCPv6(&rep) for _, mod := range modifiers { - d = mod(d) - } - return d, nil -} - -// Type is the DHCPv6 message type. -func (d *Message) Type() MessageType { - return d.messageType -} - -// SetMessage sets the DHCP message type. -func (d *Message) SetMessage(messageType MessageType) { - msgString := messageType.String() - if msgString == "" { - log.Printf("Warning: unknown DHCPv6 message type: %v", messageType) - } - if messageType == MessageTypeRelayForward || messageType == MessageTypeRelayReply { - log.Printf("Warning: using a RELAY message type with a non-relay message: %v (%v)", - msgString, messageType) + mod(rep) } - d.messageType = messageType -} - -// TransactionID returns this message's transaction id. -func (d *Message) TransactionID() TransactionID { - return d.transactionID + return rep, nil } -// SetTransactionID sets this message's transaction id. -func (d *Message) SetTransactionID(tid TransactionID) { - d.transactionID = tid -} - -// SetOptions replaces this message's options. -func (d *Message) SetOptions(options []Option) { - d.options = options +// Type returns this message's message type. +func (m Message) Type() MessageType { + return m.MessageType } // AddOption adds an option to this message. -func (d *Message) AddOption(option Option) { - d.options.Add(option) +func (m *Message) AddOption(option Option) { + m.Options.Add(option) } // UpdateOption updates the existing options with the passed option, adding it // at the end if not present already -func (d *Message) UpdateOption(option Option) { - d.options.Update(option) +func (m *Message) UpdateOption(option Option) { + m.Options.Update(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 *Message) IsNetboot() bool { - if d.IsOptionRequested(OptionBootfileURL) { +func (m *Message) IsNetboot() bool { + if m.IsOptionRequested(OptionBootfileURL) { return true } - if optbf := d.GetOneOption(OptionBootfileURL); optbf != nil { + if optbf := m.GetOneOption(OptionBootfileURL); optbf != nil { return true } return false @@ -273,8 +233,8 @@ func (d *Message) IsNetboot() bool { // IsOptionRequested takes an OptionCode and returns true if that option is // within the requested options of the DHCPv6 message. -func (d *Message) IsOptionRequested(requested OptionCode) bool { - for _, optoro := range d.GetOption(OptionORO) { +func (m *Message) IsOptionRequested(requested OptionCode) bool { + for _, optoro := range m.GetOption(OptionORO) { for _, o := range optoro.(*OptRequestedOption).RequestedOptions() { if o == requested { return true @@ -285,26 +245,25 @@ func (d *Message) IsOptionRequested(requested OptionCode) bool { } // String returns a short human-readable string for this message. -func (d *Message) String() string { - return fmt.Sprintf("Message(messageType=%v transactionID=%s, %d options)", - d.Type().String(), d.TransactionID(), len(d.options), - ) +func (m *Message) String() string { + return fmt.Sprintf("Message(messageType=%s transactionID=%s, %d options)", + m.MessageType, m.TransactionID, len(m.Options)) } // Summary prints all options associated with this message. -func (d *Message) Summary() string { +func (m *Message) Summary() string { ret := fmt.Sprintf( "Message\n"+ - " messageType=%v\n"+ + " messageType=%s\n"+ " transactionid=%s\n", - d.Type().String(), - d.TransactionID(), + m.MessageType, + m.TransactionID, ) ret += " options=[" - if len(d.options) > 0 { + if len(m.Options) > 0 { ret += "\n" } - for _, opt := range d.options { + for _, opt := range m.Options { ret += fmt.Sprintf(" %v\n", opt.String()) } ret += " ]\n" @@ -313,31 +272,26 @@ func (d *Message) Summary() string { // ToBytes returns the serialized version of this message as defined by RFC // 3315, Section 5. -func (d *Message) ToBytes() []byte { +func (m *Message) ToBytes() []byte { buf := uio.NewBigEndianBuffer(nil) - buf.Write8(uint8(d.messageType)) - buf.WriteBytes(d.transactionID[:]) - buf.WriteBytes(d.options.ToBytes()) + buf.Write8(uint8(m.MessageType)) + buf.WriteBytes(m.TransactionID[:]) + buf.WriteBytes(m.Options.ToBytes()) return buf.Data() } -// Options returns the current set of options associated with this message. -func (d *Message) Options() []Option { - return d.options -} - // GetOption returns the options associated with the code. -func (d *Message) GetOption(code OptionCode) []Option { - return d.options.Get(code) +func (m *Message) GetOption(code OptionCode) []Option { + return m.Options.Get(code) } // GetOneOption returns the first associated option with the code from this // message. -func (d *Message) GetOneOption(code OptionCode) Option { - return d.options.GetOne(code) +func (m *Message) GetOneOption(code OptionCode) Option { + return m.Options.GetOne(code) } // IsRelay returns whether this is a relay message or not. -func (d *Message) IsRelay() bool { +func (m *Message) IsRelay() bool { return false } diff --git a/dhcpv6/dhcpv6relay.go b/dhcpv6/dhcpv6relay.go index 5bca431..497ef64 100644 --- a/dhcpv6/dhcpv6relay.go +++ b/dhcpv6/dhcpv6relay.go @@ -13,23 +13,23 @@ const RelayHeaderSize = 34 // RelayMessage is a DHCPv6 relay agent message as defined by RFC 3315 Section // 7. type RelayMessage struct { - messageType MessageType - hopCount uint8 - linkAddr net.IP - peerAddr net.IP - options Options + MessageType MessageType + HopCount uint8 + LinkAddr net.IP + PeerAddr net.IP + Options Options } // Type is this relay message's types. func (r *RelayMessage) Type() MessageType { - return r.messageType + return r.MessageType } // String prints a short human-readable relay message. func (r *RelayMessage) String() string { ret := fmt.Sprintf( - "RelayMessage(messageType=%v hopcount=%v, linkaddr=%v, peeraddr=%v, %d options)", - r.Type().String(), r.hopCount, r.linkAddr, r.peerAddr, len(r.options), + "RelayMessage(messageType=%s hopcount=%d, linkaddr=%s, peeraddr=%s, %d options)", + r.Type(), r.HopCount, r.LinkAddr, r.PeerAddr, len(r.Options), ) return ret } @@ -43,11 +43,11 @@ func (r *RelayMessage) Summary() string { " linkaddr=%v\n"+ " peeraddr=%v\n"+ " options=%v\n", - r.Type().String(), - r.hopCount, - r.linkAddr, - r.peerAddr, - r.options, + r.Type(), + r.HopCount, + r.LinkAddr, + r.PeerAddr, + r.Options, ) return ret } @@ -56,79 +56,33 @@ func (r *RelayMessage) Summary() string { // RFC 3315, Section 7. func (r *RelayMessage) ToBytes() []byte { buf := uio.NewBigEndianBuffer(make([]byte, 0, RelayHeaderSize)) - buf.Write8(byte(r.messageType)) - buf.Write8(byte(r.hopCount)) - buf.WriteBytes(r.linkAddr.To16()) - buf.WriteBytes(r.peerAddr.To16()) - buf.WriteBytes(r.options.ToBytes()) + buf.Write8(byte(r.MessageType)) + buf.Write8(byte(r.HopCount)) + buf.WriteBytes(r.LinkAddr.To16()) + buf.WriteBytes(r.PeerAddr.To16()) + buf.WriteBytes(r.Options.ToBytes()) return buf.Data() } -// SetMessageType sets the message type of this relay message. -func (r *RelayMessage) SetMessageType(messageType MessageType) { - // not enforcing if message type is not a RELAY_FORW or a RELAY_REPL message - r.messageType = messageType -} - -// HopCount returns the hop count. -func (r *RelayMessage) HopCount() uint8 { - return r.hopCount -} - -// SetHopCount sets the hop count. -func (r *RelayMessage) SetHopCount(hopCount uint8) { - r.hopCount = hopCount -} - -// LinkAddr returns the link address for this relay message. -func (r *RelayMessage) LinkAddr() net.IP { - return r.linkAddr -} - -// SetLinkAddr sets the link address. -func (r *RelayMessage) SetLinkAddr(linkAddr net.IP) { - r.linkAddr = linkAddr -} - -// PeerAddr returns the peer address for this relay message. -func (r *RelayMessage) PeerAddr() net.IP { - return r.peerAddr -} - -// SetPeerAddr sets the peer address. -func (r *RelayMessage) SetPeerAddr(peerAddr net.IP) { - r.peerAddr = peerAddr -} - -// Options returns the current set of options associated with this message. -func (r *RelayMessage) Options() []Option { - return r.options -} - // GetOption returns the options associated with the code. func (r *RelayMessage) GetOption(code OptionCode) []Option { - return r.options.Get(code) + return r.Options.Get(code) } // GetOneOption returns the first associated option with the code from this // message. func (r *RelayMessage) GetOneOption(code OptionCode) Option { - return r.options.GetOne(code) -} - -// SetOptions replaces this message's options. -func (r *RelayMessage) SetOptions(options []Option) { - r.options = options + return r.Options.GetOne(code) } // AddOption adds an option to this message. func (r *RelayMessage) AddOption(option Option) { - r.options.Add(option) + r.Options.Add(option) } // UpdateOption replaces the first option of the same type as the specified one. func (r *RelayMessage) UpdateOption(option Option) { - r.options.Update(option) + r.Options.Update(option) } // IsRelay returns whether this is a relay message or not. @@ -159,32 +113,25 @@ func (r *RelayMessage) GetInnerMessage() (DHCPv6, error) { // MessageTypeRelayForward and replaces the inner message with the passed // DHCPv6 message. It copies the OptionInterfaceID and OptionRemoteID if the // options are present in the Relay packet. -func NewRelayReplFromRelayForw(relayForw, msg DHCPv6) (DHCPv6, error) { +func NewRelayReplFromRelayForw(relay *RelayMessage, msg *Message) (DHCPv6, error) { var ( err error linkAddr, peerAddr []net.IP optiid []Option optrid []Option ) - if relayForw == nil { + if relay == nil { return nil, errors.New("Relay message cannot be nil") } - relay, ok := relayForw.(*RelayMessage) - if !ok { - return nil, errors.New("Not a RelayMessage") - } if relay.Type() != MessageTypeRelayForward { return nil, errors.New("The passed packet is not of type MessageTypeRelayForward") } if msg == nil { return nil, errors.New("The passed message cannot be nil") } - if msg.IsRelay() { - return nil, errors.New("The passed message cannot be a relay") - } for { - linkAddr = append(linkAddr, relay.LinkAddr()) - peerAddr = append(peerAddr, relay.PeerAddr()) + linkAddr = append(linkAddr, relay.LinkAddr) + peerAddr = append(peerAddr, relay.PeerAddr) optiid = append(optiid, relay.GetOneOption(OptionInterfaceID)) optrid = append(optrid, relay.GetOneOption(OptionRemoteID)) decap, err := DecapsulateRelay(relay) @@ -197,17 +144,18 @@ func NewRelayReplFromRelayForw(relayForw, msg DHCPv6) (DHCPv6, error) { break } } + m := DHCPv6(msg) for i := len(linkAddr) - 1; i >= 0; i-- { - msg, err = EncapsulateRelay(msg, MessageTypeRelayReply, linkAddr[i], peerAddr[i]) + m, err = EncapsulateRelay(m, MessageTypeRelayReply, linkAddr[i], peerAddr[i]) if err != nil { return nil, err } if opt := optiid[i]; opt != nil { - msg.AddOption(opt) + m.AddOption(opt) } if opt := optrid[i]; opt != nil { - msg.AddOption(opt) + m.AddOption(opt) } } - return msg, nil + return m, nil } diff --git a/dhcpv6/dhcpv6relay_test.go b/dhcpv6/dhcpv6relay_test.go index 87eabbf..270dd52 100644 --- a/dhcpv6/dhcpv6relay_test.go +++ b/dhcpv6/dhcpv6relay_test.go @@ -12,60 +12,30 @@ func TestRelayMessage(t *testing.T) { ll := net.IP{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xbb, 0xcc, 0xff, 0xfe, 0xdd, 0xee, 0xff} ma := net.IP{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} r := RelayMessage{ - messageType: MessageTypeRelayForward, - hopCount: 10, - linkAddr: ll, - peerAddr: ma, + MessageType: MessageTypeRelayForward, + HopCount: 10, + LinkAddr: ll, + PeerAddr: ma, // options is left empty here for testing purposes, even if it's // mandatory to have at least a relay message option } if mt := r.Type(); mt != MessageTypeRelayForward { t.Fatalf("Invalid message type. Expected %v, got %v", MessageTypeRelayForward, mt) } - if hc := r.HopCount(); hc != 10 { + if hc := r.HopCount; hc != 10 { t.Fatalf("Invalid hop count. Expected 10, got %v", hc) } - if la := r.LinkAddr(); !bytes.Equal(la, ll) { + if la := r.LinkAddr; !bytes.Equal(la, ll) { t.Fatalf("Invalid link address. Expected %v, got %v", ll, la) } - if pa := r.PeerAddr(); !bytes.Equal(pa, ma) { + if pa := r.PeerAddr; !bytes.Equal(pa, ma) { t.Fatalf("Invalid peer address. Expected %v, got %v", ma, pa) } - if opts := r.Options(); len(opts) != 0 { + if opts := r.Options; len(opts) != 0 { t.Fatalf("Invalid options. Expected none, got %v", opts) } } -func TestRelayMessageSettersAndGetters(t *testing.T) { - r := RelayMessage{} - // set and get message type - r.SetMessageType(MessageTypeRelayReply) - if mt := r.Type(); mt != MessageTypeRelayReply { - t.Fatalf("Invalid message type. Expected %v, got %v", MessageTypeRelayReply, mt) - } - // set and get hop count - r.SetHopCount(5) - if hc := r.HopCount(); hc != 5 { - t.Fatalf("Invalid hop count. Expected 5, got %v", hc) - } - // set and get link address - r.SetLinkAddr(net.IPv6loopback) - if la := r.LinkAddr(); !bytes.Equal(la, net.IPv6loopback) { - t.Fatalf("Invalid link address. Expected %v, got %v", net.IPv6loopback, la) - } - // set and get peer address - r.SetPeerAddr(net.IPv6loopback) - if pa := r.PeerAddr(); !bytes.Equal(pa, net.IPv6loopback) { - t.Fatalf("Invalid peer address. Expected %v, got %v", net.IPv6loopback, pa) - } - // set and get options - oneOpt := []Option{&OptRelayMsg{relayMessage: &Message{}}} - r.SetOptions(oneOpt) - if opts := r.Options(); len(opts) != 1 || opts[0] != oneOpt[0] { - t.Fatalf("Invalid options. Expected %v, got %v", oneOpt, opts) - } -} - func TestRelayMessageToBytes(t *testing.T) { expected := []byte{ 12, // MessageTypeRelayForward @@ -84,16 +54,16 @@ func TestRelayMessageToBytes(t *testing.T) { 0, 0, } r := RelayMessage{ - messageType: MessageTypeRelayForward, - hopCount: 1, - linkAddr: net.IPv6interfacelocalallnodes, - peerAddr: net.IPv6linklocalallrouters, + MessageType: MessageTypeRelayForward, + HopCount: 1, + LinkAddr: net.IPv6interfacelocalallnodes, + PeerAddr: net.IPv6linklocalallrouters, } opt := OptRelayMsg{ relayMessage: &Message{ - messageType: MessageTypeSolicit, - transactionID: TransactionID{0xaa, 0xbb, 0xcc}, - options: []Option{ + MessageType: MessageTypeSolicit, + TransactionID: TransactionID{0xaa, 0xbb, 0xcc}, + Options: []Option{ &OptElapsedTime{ ElapsedTime: 0, }, @@ -110,9 +80,9 @@ func TestRelayMessageToBytes(t *testing.T) { func TestNewRelayRepFromRelayForw(t *testing.T) { // create a new relay forward rf := RelayMessage{} - rf.SetMessageType(MessageTypeRelayForward) - rf.SetPeerAddr(net.IPv6linklocalallrouters) - rf.SetLinkAddr(net.IPv6interfacelocalallnodes) + rf.MessageType = MessageTypeRelayForward + rf.PeerAddr = net.IPv6linklocalallrouters + rf.LinkAddr = net.IPv6interfacelocalallnodes rf.AddOption(&OptInterfaceId{}) rf.AddOption(&OptRemoteId{}) @@ -130,9 +100,9 @@ func TestNewRelayRepFromRelayForw(t *testing.T) { require.NoError(t, err) relay := rr.(*RelayMessage) require.Equal(t, rr.Type(), MessageTypeRelayReply) - require.Equal(t, relay.HopCount(), rf.HopCount()) - require.Equal(t, relay.PeerAddr(), rf.PeerAddr()) - require.Equal(t, relay.LinkAddr(), rf.LinkAddr()) + require.Equal(t, relay.HopCount, rf.HopCount) + require.Equal(t, relay.PeerAddr, rf.PeerAddr) + require.Equal(t, relay.LinkAddr, rf.LinkAddr) require.NotNil(t, rr.GetOneOption(OptionInterfaceID)) require.NotNil(t, rr.GetOneOption(OptionRemoteID)) m, err := relay.GetInnerMessage() diff --git a/dhcpv6/iputils.go b/dhcpv6/iputils.go index e04a9a7..b8c5876 100644 --- a/dhcpv6/iputils.go +++ b/dhcpv6/iputils.go @@ -74,7 +74,7 @@ func ExtractMAC(packet DHCPv6) (net.HardwareAddr, error) { if err != nil { return nil, err } - ip := inner.(*RelayMessage).PeerAddr() + ip := inner.(*RelayMessage).PeerAddr if mac, err := GetMacAddressFromEUI64(ip); err == nil { return mac, nil } diff --git a/dhcpv6/modifiers.go b/dhcpv6/modifiers.go index f1be702..8c75ea5 100644 --- a/dhcpv6/modifiers.go +++ b/dhcpv6/modifiers.go @@ -10,28 +10,26 @@ import ( // WithClientID adds a client ID option to a DHCPv6 packet func WithClientID(duid Duid) Modifier { - return func(d DHCPv6) DHCPv6 { + return func(d DHCPv6) { cid := OptClientId{Cid: duid} d.UpdateOption(&cid) - return d } } // WithServerID adds a client ID option to a DHCPv6 packet func WithServerID(duid Duid) Modifier { - return func(d DHCPv6) DHCPv6 { + return func(d DHCPv6) { sid := OptServerId{Sid: duid} d.UpdateOption(&sid) - return d } } // WithNetboot adds bootfile URL and bootfile param options to a DHCPv6 packet. -func WithNetboot(d DHCPv6) DHCPv6 { +func WithNetboot(d DHCPv6) { msg, ok := d.(*Message) if !ok { log.Printf("WithNetboot: not a Message") - return d + return } // add OptionBootfileURL and OptionBootfileParam opt := msg.GetOneOption(OptionORO) @@ -43,32 +41,30 @@ func WithNetboot(d DHCPv6) DHCPv6 { oro.AddRequestedOption(OptionBootfileURL) oro.AddRequestedOption(OptionBootfileParam) msg.UpdateOption(oro) - return d + return } // WithUserClass adds a user class option to the packet func WithUserClass(uc []byte) Modifier { // TODO let the user specify multiple user classes - return func(d DHCPv6) DHCPv6 { + return func(d DHCPv6) { ouc := OptUserClass{UserClasses: [][]byte{uc}} d.AddOption(&ouc) - return d } } // WithArchType adds an arch type option to the packet func WithArchType(at iana.Arch) Modifier { - return func(d DHCPv6) DHCPv6 { + return func(d DHCPv6) { ao := OptClientArchType{ArchTypes: []iana.Arch{at}} d.AddOption(&ao) - return d } } // WithIANA adds or updates an OptIANA option with the provided IAAddress // options func WithIANA(addrs ...OptIAAddress) Modifier { - return func(d DHCPv6) DHCPv6 { + return func(d DHCPv6) { opt := d.GetOneOption(OptionIANA) if opt == nil { opt = &OptIANA{} @@ -78,37 +74,34 @@ func WithIANA(addrs ...OptIAAddress) Modifier { iaNa.AddOption(&addr) } d.UpdateOption(iaNa) - return d } } // WithDNS adds or updates an OptDNSRecursiveNameServer func WithDNS(dnses ...net.IP) Modifier { - return func(d DHCPv6) DHCPv6 { + return func(d DHCPv6) { odns := OptDNSRecursiveNameServer{ NameServers: append([]net.IP{}, dnses[:]...), } d.UpdateOption(&odns) - return d } } // WithDomainSearchList adds or updates an OptDomainSearchList func WithDomainSearchList(searchlist ...string) Modifier { - return func(d DHCPv6) DHCPv6 { + return func(d DHCPv6) { osl := OptDomainSearchList{ DomainSearchList: &rfc1035label.Labels{ Labels: searchlist, }, } d.UpdateOption(&osl) - return d } } // WithRequestedOptions adds requested options to the packet func WithRequestedOptions(optionCodes ...OptionCode) Modifier { - return func(d DHCPv6) DHCPv6 { + return func(d DHCPv6) { opt := d.GetOneOption(OptionORO) if opt == nil { opt = &OptRequestedOption{} @@ -118,6 +111,5 @@ func WithRequestedOptions(optionCodes ...OptionCode) Modifier { oro.AddRequestedOption(optionCode) } d.UpdateOption(oro) - return d } } diff --git a/dhcpv6/modifiers_test.go b/dhcpv6/modifiers_test.go index d505113..324c425 100644 --- a/dhcpv6/modifiers_test.go +++ b/dhcpv6/modifiers_test.go @@ -46,7 +46,7 @@ func TestWithRequestedOptions(t *testing.T) { oro := opt.(*OptRequestedOption) require.ElementsMatch(t, oro.RequestedOptions(), []OptionCode{OptionClientID}) // Check if already set options are preserved - m = WithRequestedOptions(OptionServerID)(m) + WithRequestedOptions(OptionServerID)(m) opt = m.GetOneOption(OptionORO) require.NotNil(t, opt) oro = opt.(*OptRequestedOption) @@ -54,22 +54,24 @@ func TestWithRequestedOptions(t *testing.T) { } func TestWithIANA(t *testing.T) { - d := WithIANA(OptIAAddress{ + var d Message + WithIANA(OptIAAddress{ IPv6Addr: net.ParseIP("::1"), PreferredLifetime: 3600, ValidLifetime: 5200, - })(&Message{}) - require.Equal(t, 1, len(d.Options())) - require.Equal(t, OptionIANA, d.Options()[0].Code()) + })(&d) + require.Equal(t, 1, len(d.Options)) + require.Equal(t, OptionIANA, d.Options[0].Code()) } func TestWithDNS(t *testing.T) { - d := WithDNS([]net.IP{ + var d Message + WithDNS([]net.IP{ net.ParseIP("fe80::1"), net.ParseIP("fe80::2"), - }...)(&Message{}) - require.Equal(t, 1, len(d.Options())) - dns := d.Options()[0].(*OptDNSRecursiveNameServer) + }...)(&d) + require.Equal(t, 1, len(d.Options)) + dns := d.Options[0].(*OptDNSRecursiveNameServer) log.Printf("DNS %+v", dns) require.Equal(t, OptionDNSRecursiveNameServer, dns.Code()) require.Equal(t, 2, len(dns.NameServers)) @@ -79,12 +81,13 @@ func TestWithDNS(t *testing.T) { } func TestWithDomainSearchList(t *testing.T) { - d := WithDomainSearchList([]string{ + var d Message + WithDomainSearchList([]string{ "slackware.it", "dhcp.slackware.it", - }...)(&Message{}) - require.Equal(t, 1, len(d.Options())) - osl := d.Options()[0].(*OptDomainSearchList) + }...)(&d) + require.Equal(t, 1, len(d.Options)) + osl := d.Options[0].(*OptDomainSearchList) require.Equal(t, OptionDomainSearchList, osl.Code()) require.NotNil(t, osl.DomainSearchList) labels := osl.DomainSearchList.Labels diff --git a/dhcpv6/option_relaymsg_test.go b/dhcpv6/option_relaymsg_test.go index 654cdb8..dd82d28 100644 --- a/dhcpv6/option_relaymsg_test.go +++ b/dhcpv6/option_relaymsg_test.go @@ -76,15 +76,15 @@ func TestRelayMsgParseOptRelayMsgSingleEncapsulation(t *testing.T) { if mType := r.Type(); mType != MessageTypeRelayForward { t.Fatalf("Invalid messge type for relay. Expected %v, got %v", MessageTypeRelayForward, mType) } - if len(r.options) != 1 { - t.Fatalf("Invalid number of options. Expected 1, got %v", len(r.options)) + if len(r.Options) != 1 { + t.Fatalf("Invalid number of options. Expected 1, got %v", len(r.Options)) } - if code := r.options[0].Code(); code != OptionRelayMsg { + if code := r.Options[0].Code(); code != OptionRelayMsg { t.Fatalf("Invalid option code. Expected OptionRelayMsg (%v), got %v", OptionRelayMsg, code, ) } - opt := r.options[0] + opt := r.Options[0] ro, ok := opt.(*OptRelayMsg) if !ok { t.Fatalf("Invalid option type. Expected OptRelayMsg, got %v", @@ -103,13 +103,13 @@ func TestRelayMsgParseOptRelayMsgSingleEncapsulation(t *testing.T) { ) } xid := TransactionID{0xaa, 0xbb, 0xcc} - if tID := innerDHCP.TransactionID(); tID != xid { + if tID := innerDHCP.TransactionID; tID != xid { t.Fatalf("Invalid inner DHCP transaction ID. Expected 0xaabbcc, got %v", tID) } - if len(innerDHCP.options) != 1 { - t.Fatalf("Invalid inner DHCP options length. Expected 1, got %v", len(innerDHCP.options)) + if len(innerDHCP.Options) != 1 { + t.Fatalf("Invalid inner DHCP options length. Expected 1, got %v", len(innerDHCP.Options)) } - innerOpt := innerDHCP.options[0] + innerOpt := innerDHCP.Options[0] eto, ok := innerOpt.(*OptElapsedTime) if !ok { t.Fatalf("Invalid inner option type. Expected OptElapsedTime, got %v", diff --git a/dhcpv6/server6/server_test.go b/dhcpv6/server6/server_test.go index 2365b96..3d2a365 100644 --- a/dhcpv6/server6/server_test.go +++ b/dhcpv6/server6/server_test.go @@ -58,7 +58,8 @@ func TestNewServer(t *testing.T) { func TestServerActivateAndServe(t *testing.T) { handler := func(conn net.PacketConn, peer net.Addr, m dhcpv6.DHCPv6) { - adv, err := dhcpv6.NewAdvertiseFromSolicit(m) + msg := m.(*dhcpv6.Message) + adv, err := dhcpv6.NewAdvertiseFromSolicit(msg) if err != nil { log.Printf("NewAdvertiseFromSolicit failed: %v", err) return diff --git a/examples/packetcrafting6/main.go b/examples/packetcrafting6/main.go index 9ec0d85..7e2fb1b 100644 --- a/examples/packetcrafting6/main.go +++ b/examples/packetcrafting6/main.go @@ -43,8 +43,8 @@ func main() { LinkLayerAddr: mac, } // As suggested above, an alternative is to call - // dhcpv6.NewSolicitForInterface("eth0", dhcpv6.WithCLientID(duid)) - msg = dhcpv6.WithClientID(duid)(msg) + // dhcpv6.NewSolicitForInterface("eth0", dhcpv6.WithClientID(duid)) + dhcpv6.WithClientID(duid)(msg) // Now encapsulate the message in a DHCPv6 relay. // As per RFC3315, the link-address and peer-address have diff --git a/netboot/netconf_test.go b/netboot/netconf_test.go index b267101..69d58ad 100644 --- a/netboot/netconf_test.go +++ b/netboot/netconf_test.go @@ -31,8 +31,7 @@ func getAdv(modifiers ...dhcpv6.Modifier) *dhcpv6.Message { if err != nil { log.Panic(err) } - adv := d.(*dhcpv6.Message) - return adv + return d } func TestGetNetConfFromPacketv6Invalid(t *testing.T) { |