1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
package dhcpv6
import (
"reflect"
"testing"
)
func TestRelayMsgParseOptRelayMsg(t *testing.T) {
opt, err := ParseOptRelayMsg([]byte{
1, // SOLICIT
0xaa, 0xbb, 0xcc, // transaction ID
0, 8, // option: elapsed time
0, 2, // option length
0, 0, // option value
})
if err != nil {
t.Fatal(err)
}
if code := opt.Code(); code != OPTION_RELAY_MSG {
t.Fatalf("Invalid option code. Expected OPTION_RELAY_MSG (%v), got %v",
OPTION_RELAY_MSG, code,
)
}
}
func TestRelayMsgOptionsFromBytes(t *testing.T) {
opts, err := OptionsFromBytes([]byte{
0, 9, // option: relay message
0, 10, // relayed message length
1, // SOLICIT
0xaa, 0xbb, 0xcc, // transaction ID
0, 8, // option: elapsed time
0, 2, // option length
0, 0, // option value
})
if err != nil {
t.Fatal(err)
}
if len(opts) != 1 {
t.Fatalf("Invalid number of options. Expected 1, got %v", len(opts))
}
opt := opts[0]
if code := opt.Code(); code != OPTION_RELAY_MSG {
t.Fatalf("Invalid option code. Expected OPTION_RELAY_MSG (%v), got %v",
OPTION_RELAY_MSG, code,
)
}
}
func TestRelayMsgParseOptRelayMsgSingleEncapsulation(t *testing.T) {
d, err := FromBytes([]byte{
12, // RELAY-FORW
0, // hop count
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // linkAddr
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, // peerAddr
0, 9, // option: relay message
0, 10, // relayed message length
1, // SOLICIT
0xaa, 0xbb, 0xcc, // transaction ID
0, 8, // option: elapsed time
0, 2, // option length
0x11, 0x22, // option value
})
if err != nil {
t.Fatal(err)
}
r, ok := d.(*DHCPv6Relay)
if !ok {
t.Fatalf("Invalid DHCPv6 type. Expected DHCPv6Relay, got %v",
reflect.TypeOf(d),
)
}
if mType := r.Type(); mType != RELAY_FORW {
t.Fatalf("Invalid messge type for relay. Expected %v, got %v", RELAY_FORW, mType)
}
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 != OPTION_RELAY_MSG {
t.Fatalf("Invalid option code. Expected OPTION_RELAY_MSG (%v), got %v",
OPTION_RELAY_MSG, code,
)
}
opt := r.options[0]
ro, ok := opt.(*OptRelayMsg)
if !ok {
t.Fatalf("Invalid option type. Expected OptRelayMsg, got %v",
reflect.TypeOf(ro),
)
}
innerDHCP, ok := ro.RelayMessage().(*DHCPv6Message)
if !ok {
t.Fatalf("Invalid relay message type. Expected DHCPv6Message, got %v",
reflect.TypeOf(innerDHCP),
)
}
if dType := innerDHCP.Type(); dType != SOLICIT {
t.Fatalf("Invalid inner DHCP type. Expected SOLICIT (%v), got %v",
SOLICIT, dType,
)
}
if tID := innerDHCP.TransactionID(); tID != 0xaabbcc {
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))
}
innerOpt := innerDHCP.options[0]
eto, ok := innerOpt.(*OptElapsedTime)
if !ok {
t.Fatalf("Invalid inner option type. Expected OptElapsedTime, got %v",
reflect.TypeOf(innerOpt),
)
}
if eTime := eto.ElapsedTime; eTime != 0x1122 {
t.Fatalf("Invalid elapsed time. Expected 0x1122, got 0x%04x", eTime)
}
}
func TestSample(t *testing.T) {
// Nested relay message. This test only checks if it parses correctly, but
// could/should be extended to check all the fields like done in other tests
buf := []byte{
12, // relay
1, // hop count
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // linkAddr
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // peerAddr
// relay msg
0, 9, // opt relay msg
0, 66, // opt len
// relay fwd
12, // relay
0, // hop count
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // linkAddr
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // peerAddr
// opt interface ID
0, 18, // interface id
0, 6, // opt len
0xba, 0xbe, 0xb1, 0xb0, 0xbe, 0xbe, // opt value
// relay msg
0, 9, // relay msg
0, 18, // msg len
// dhcpv6 msg
1, // solicit
0xaa, 0xbb, 0xcc, // transaction ID
// client ID
0, 1, // opt client id
0, 10, // opt len
0, 3, // duid type
0, 1, // hw type
5, 6, 7, 8, 9, 10, // duid value
}
_, err := FromBytes(buf)
if err != nil {
t.Fatal(err)
}
}
|