diff options
-rw-r--r-- | dhcpv6/client.go | 1 | ||||
-rw-r--r-- | dhcpv6/dhcpv6.go | 44 | ||||
-rw-r--r-- | dhcpv6/dhcpv6relay.go | 28 |
3 files changed, 53 insertions, 20 deletions
diff --git a/dhcpv6/client.go b/dhcpv6/client.go index e261688..7db543e 100644 --- a/dhcpv6/client.go +++ b/dhcpv6/client.go @@ -17,7 +17,6 @@ var AllDHCPRelayAgentsAndServers = net.ParseIP("ff02::1:2") var AllDHCPServers = net.ParseIP("ff05::1:3") type Client struct { - Dialer *net.Dialer ReadTimeout *time.Duration WriteTimeout *time.Duration LocalAddr net.Addr diff --git a/dhcpv6/dhcpv6.go b/dhcpv6/dhcpv6.go index 146687a..0532690 100644 --- a/dhcpv6/dhcpv6.go +++ b/dhcpv6/dhcpv6.go @@ -2,6 +2,7 @@ package dhcpv6 import ( "fmt" + "net" ) type DHCPv6 interface { @@ -14,6 +15,8 @@ type DHCPv6 interface { IsRelay() bool GetOption(code OptionCode) []Option GetOneOption(code OptionCode) Option + SetOptions(options []Option) + AddOption(Option) } func FromBytes(data []byte) (DHCPv6, error) { @@ -102,3 +105,44 @@ func getOption(options []Option, code OptionCode) Option { } return opts[0] } + +// Decapsulate extracts the content of a relay message. It does not recurse if +// there are nested relay messages. Returns the original packet if is not not a +// relay message +func DecapsulateRelay(l DHCPv6) (DHCPv6, error) { + if !l.IsRelay() { + return l, nil + } + opt := l.GetOneOption(OPTION_RELAY_MSG) + if opt == nil { + return nil, fmt.Errorf("No OptRelayMsg found") + } + relayOpt := opt.(*OptRelayMsg) + if relayOpt.RelayMessage() == nil { + return nil, fmt.Errorf("Relay message cannot be nil") + } + return relayOpt.RelayMessage(), nil +} + +// Encapsulate creates a DHCPv6Relay message containing the passed DHCPv6 object. +// struct 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) { + if mType != RELAY_FORW && mType != RELAY_REPL { + return nil, fmt.Errorf("Message type must be either RELAY_FORW or RELAY_REPL") + } + outer := DHCPv6Relay{ + messageType: RELAY_FORW, + linkAddr: linkAddr, + peerAddr: peerAddr, + } + if d.IsRelay() { + relay := d.(*DHCPv6Relay) + outer.hopCount = relay.hopCount + 1 + } else { + outer.hopCount = 0 + } + orm := OptRelayMsg{relayMessage: d} + outer.AddOption(&orm) + return &outer, nil +} diff --git a/dhcpv6/dhcpv6relay.go b/dhcpv6/dhcpv6relay.go index 0ada513..31249a7 100644 --- a/dhcpv6/dhcpv6relay.go +++ b/dhcpv6/dhcpv6relay.go @@ -80,26 +80,16 @@ func (r *DHCPv6Relay) GetOneOption(code OptionCode) Option { return getOption(r.options, code) } -func (r *DHCPv6Relay) IsRelay() bool { - return true +func (r *DHCPv6Relay) SetOptions(options []Option) { + r.options = options } -// Decapsulate extracts the content of a relay message. It does not recurse if -// there are nested relay messages. Returns the original packet if is not not a -// relay message -func (d *DHCPv6Relay) Decapsulate(l DHCPv6) (DHCPv6, error) { - if !l.IsRelay() { - return l, nil - } - opt := l.GetOneOption(OPTION_RELAY_MSG) - if opt == nil { - return nil, fmt.Errorf("No OptRelayMsg found") - } - relayOpt := opt.(*OptRelayMsg) - if relayOpt.RelayMessage() == nil { - return nil, fmt.Errorf("Relay message cannot be nil") - } - return relayOpt.RelayMessage(), nil +func (r *DHCPv6Relay) AddOption(option Option) { + r.options = append(r.options, option) +} + +func (r *DHCPv6Relay) IsRelay() bool { + return true } // Recurse into a relay message and extract and return the inner DHCPv6Message. @@ -114,7 +104,7 @@ func (d *DHCPv6Relay) GetInnerMessage() (DHCPv6, error) { if !p.IsRelay() { return p, nil } - p, err = d.Decapsulate(p) + p, err = DecapsulateRelay(p) if err != nil { return nil, err } |