diff options
Diffstat (limited to 'dhcpv6')
-rw-r--r-- | dhcpv6/duid.go | 27 | ||||
-rw-r--r-- | dhcpv6/duid_test.go | 40 |
2 files changed, 61 insertions, 6 deletions
diff --git a/dhcpv6/duid.go b/dhcpv6/duid.go index 112412d..8572349 100644 --- a/dhcpv6/duid.go +++ b/dhcpv6/duid.go @@ -9,16 +9,19 @@ import ( type DuidType uint16 +// DUID types const ( - DUID_LLT DuidType = 1 - DUID_EN DuidType = 2 - DUID_LL DuidType = 3 + DUID_LLT DuidType = 1 + DUID_EN DuidType = 2 + DUID_LL DuidType = 3 + DUID_UUID DuidType = 4 ) var DuidTypeToString = map[DuidType]string{ - DUID_LL: "DUID-LL", - DUID_LLT: "DUID-LLT", - DUID_EN: "DUID-EN", + DUID_LL: "DUID-LL", + DUID_LLT: "DUID-LLT", + DUID_EN: "DUID-EN", + DUID_UUID: "DUID-UUID", } type Duid struct { @@ -28,6 +31,7 @@ type Duid struct { LinkLayerAddr []byte EnterpriseNumber uint32 // for DUID-EN. Ignored otherwise EnterpriseIdentifier []byte // for DUID-EN. Ignored otherwise + Uuid []byte // for DUID-UUID. Ignored otherwise } func (d *Duid) Length() int { @@ -37,6 +41,8 @@ func (d *Duid) Length() int { return 4 + len(d.LinkLayerAddr) } else if d.Type == DUID_EN { return 6 + len(d.EnterpriseIdentifier) + } else if d.Type == DUID_UUID { + return 18 } panic(fmt.Sprintf("Unknown DUID type: %v", d.Type)) } @@ -58,6 +64,10 @@ func (d *Duid) ToBytes() []byte { binary.BigEndian.PutUint16(buf[0:2], uint16(d.Type)) binary.BigEndian.PutUint32(buf[2:6], d.EnterpriseNumber) return append(buf, d.EnterpriseIdentifier...) + } else if d.Type == DUID_UUID { + buf := make([]byte, 2) + binary.BigEndian.PutUint16(buf[0:2], uint16(d.Type)) + return append(buf, d.Uuid...) } panic(fmt.Sprintf("Unknown DUID type: %v", d.Type)) } @@ -108,6 +118,11 @@ func DuidFromBytes(data []byte) (*Duid, error) { } d.EnterpriseNumber = binary.BigEndian.Uint32(data[2:6]) d.EnterpriseIdentifier = data[6:] + } else if d.Type == DUID_UUID { + if len(data) != 18 { + return nil, fmt.Errorf("Invalid DUID-UUID length. Expected 18, got %v", len(data)) + } + d.Uuid = data[2:18] } return &d, nil } diff --git a/dhcpv6/duid_test.go b/dhcpv6/duid_test.go new file mode 100644 index 0000000..23ce709 --- /dev/null +++ b/dhcpv6/duid_test.go @@ -0,0 +1,40 @@ +package dhcpv6 + +import ( + "bytes" + "testing" +) + +func TestDuidUuid(t *testing.T) { + buf := []byte{ + 0x00, 0x04, // type + 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, // uuid + } + duid, err := DuidFromBytes(buf) + if err != nil { + t.Fatal(err) + } + if dt := duid.Type; dt != DUID_UUID { + t.Fatalf("Invalid Preferred Lifetime. Expected 4, got %d", dt) + } + if uuid := duid.Uuid; !bytes.Equal(uuid, buf[2:]) { + t.Fatalf("Invalid UUID. Expected %v, got %v", buf[2:], uuid) + } + if mac := duid.LinkLayerAddr; mac != nil { + t.Fatalf("Invalid MAC. Expected nil, got %v", mac) + } +} + +func TestDuidUuidToBytes(t *testing.T) { + uuid := []byte{0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09} + expected := []byte{00, 04} + expected = append(expected, uuid...) + duid := Duid{ + Type: DUID_UUID, + Uuid: uuid, + } + toBytes := duid.ToBytes() + if !bytes.Equal(toBytes, expected) { + t.Fatalf("Invalid ToBytes result. Expected %v, got %v", expected, toBytes) + } +} |