Skip to content

Commit

Permalink
remove MarshalDhclient, add support for additional dhclient format
Browse files Browse the repository at this point in the history
  • Loading branch information
bonan committed Nov 20, 2016
1 parent 95a5740 commit 9e5d8fc
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 30 deletions.
66 changes: 37 additions & 29 deletions dhcp6rd.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package dhcp6rd provides utils for decoding the dhcp 6rd option (option 212)
package dhcp6rd

import (
Expand All @@ -15,7 +16,8 @@ type Option6RD struct {
Relay []net.IP
}

// IPNet returns the 6rd-prefix that should be used for argument ip
// IPNet returns the usable 6rd-prefix based on your current IPv4 address
// which is provided as an argument to the function.
func (o *Option6RD) IPNet(ip net.IP) (*net.IPNet, error) {
// Make sure that the argument is a valid IPv4 address
ip4 := ip.To4()
Expand Down Expand Up @@ -62,24 +64,6 @@ func (o *Option6RD) Marshal() []byte {
return ret
}

// MarshalDhclient returns the 6RD DHCP Option in dhclient-format
func (o *Option6RD) MarshalDhclient() string {
str := strconv.Itoa(o.MaskLen) + " " +
strconv.Itoa(o.PrefixLen) + " " +
strconv.Itoa(int(o.Prefix[0])<<8+int(o.Prefix[1])) + " " +
strconv.Itoa(int(o.Prefix[2])<<8+int(o.Prefix[3])) + " " +
strconv.Itoa(int(o.Prefix[4])<<8+int(o.Prefix[5])) + " " +
strconv.Itoa(int(o.Prefix[6])<<8+int(o.Prefix[7])) + " " +
strconv.Itoa(int(o.Prefix[8])<<8+int(o.Prefix[9])) + " " +
strconv.Itoa(int(o.Prefix[10])<<8+int(o.Prefix[11])) + " " +
strconv.Itoa(int(o.Prefix[12])<<8+int(o.Prefix[13])) + " " +
strconv.Itoa(int(o.Prefix[14])<<8+int(o.Prefix[15]))
for _, v := range o.Relay {
str = str + " " + v.String()
}
return str
}

// Unmarshal parses the raw 6RD DHCP Option and returns a Option6RD struct
func Unmarshal(b []byte) (*Option6RD, error) {
if len(b) < 18 {
Expand All @@ -99,13 +83,23 @@ func Unmarshal(b []byte) (*Option6RD, error) {
return o, nil
}

// UnmarshalDhclient parses the 6RD DHCP Option (from dhclient format) and returns a Option6RD struct
// UnmarshalDhclient parses the string-formatted 6RD DHCP Option and returns a Option6RD struct
// The formats from dhclient that's supported are:
//
// option option-6rd code 212 = { integer 8, integer 8, integer 16, integer 16,
// integer 16, integer 16, integer 16, integer 16, integer 16, integer 16,
// array of ip-address
// };
//
// or:
//
// option option-6rd code 212 = { integer 8, integer 8, ip6-address, array of ip-address };
func UnmarshalDhclient(s string) (*Option6RD, error) {
parts := strings.Split(s, " ")
if len(parts) < 10 {
if len(parts) < 4 {
return nil, errors.New("Unable to parse 6RD Option (not enough parameters)")
}
b := make([]byte, 18)
b := make([]byte, 2)

maskLen, err := strconv.Atoi(parts[0])
if err != nil {
Expand All @@ -118,15 +112,29 @@ func UnmarshalDhclient(s string) (*Option6RD, error) {
}
b[0] = byte(maskLen)
b[1] = byte(prefixLen)
for i := 0; i < 8; i++ {
p, err := strconv.Atoi(parts[i+2])
if err != nil {
return nil, err

var relayStart int
ip6prefix := make(net.IP, 16)

if strings.Contains(parts[2], ":") {
relayStart = 3
ip6prefix = net.ParseIP(parts[2])
} else {
if len(parts) < 10 {
return nil, errors.New("Unable to parse 6RD Option (not enough parameters)")
}
for i := 0; i < 8; i++ {
p, err := strconv.Atoi(parts[i+2])
if err != nil {
return nil, err
}
ip6prefix[i*2] = byte((p >> 8) & 0xff)
ip6prefix[1+i*2] = byte(p & 0xff)
}
b[2+i*2] = byte((p >> 8) & 0xff)
b[3+i*2] = byte(p & 0xff)
relayStart = 10
}
for i := 10; i < len(parts); i++ {
b = append(b, ip6prefix...)
for i := relayStart; i < len(parts); i++ {
ip := net.ParseIP(parts[i])
b = append(b, ip.To4()...)
}
Expand Down
28 changes: 27 additions & 1 deletion dhcp6rd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,33 @@ func TestMarshalDhclient(t *testing.T) {
t.Fatal(err)
}

if opt.MarshalDhclient() != b {
addr := net.ParseIP("212.113.65.123")
net, err := opt.IPNet(addr)
if err != nil {
t.Fatal(err)
}

if opt.Prefix.String() != "2001:2002::" {
t.Fail()
}

if net.String() != "2001:2002:d471:417b::/64" {
t.Fail()
}

if ones, size := net.Mask.Size(); ones != 64 || size != 128 {
t.Fail()
}

}

func TestMarshalDhclientShort(t *testing.T) {
b := "0 32 2001:2002:: 217.209.228.166"
opt, err := UnmarshalDhclient(b)
if err != nil {
t.Fatal(err)
}

addr := net.ParseIP("212.113.65.123")
net, err := opt.IPNet(addr)
if err != nil {
Expand All @@ -32,6 +55,9 @@ func TestMarshalDhclient(t *testing.T) {
t.Fail()
}

if ones, size := net.Mask.Size(); ones != 64 || size != 128 {
t.Fail()
}
}

func TestMarshal(t *testing.T) {
Expand Down

0 comments on commit 9e5d8fc

Please sign in to comment.