summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv6/client.go1
-rw-r--r--dhcpv6/dhcpv6.go44
-rw-r--r--dhcpv6/dhcpv6relay.go28
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
}