summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv6/async/client.go2
-rw-r--r--dhcpv6/async/client_test.go2
-rw-r--r--dhcpv6/client6/client.go10
-rw-r--r--dhcpv6/dhcpv6.go49
-rw-r--r--dhcpv6/dhcpv6_test.go99
-rw-r--r--dhcpv6/dhcpv6message.go192
-rw-r--r--dhcpv6/dhcpv6relay.go114
-rw-r--r--dhcpv6/dhcpv6relay_test.go72
-rw-r--r--dhcpv6/iputils.go2
-rw-r--r--dhcpv6/modifiers.go30
-rw-r--r--dhcpv6/modifiers_test.go29
-rw-r--r--dhcpv6/option_relaymsg_test.go16
-rw-r--r--dhcpv6/server6/server_test.go3
-rw-r--r--examples/packetcrafting6/main.go4
-rw-r--r--netboot/netconf_test.go3
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) {