blob: 49421085206c528e1d5e71e3f22cd4ac57c0d9e8 [file] [log] [blame]
Yi Tsengca34e1d2017-07-18 16:16:25 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Yi Tsengca34e1d2017-07-18 16:16:25 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.onlab.packet.dhcp;
19
20import com.google.common.collect.ImmutableList;
21import com.google.common.collect.Lists;
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -070022import com.google.common.io.Resources;
23
Yi Tsengca34e1d2017-07-18 16:16:25 -070024import org.junit.Test;
25import org.onlab.packet.DHCP6;
Yi Tsengb4fdb042017-08-07 13:32:32 -070026import org.onlab.packet.Ethernet;
27import org.onlab.packet.IPv6;
Yi Tsengca34e1d2017-07-18 16:16:25 -070028import org.onlab.packet.Ip6Address;
29import org.onlab.packet.MacAddress;
Yi Tsengb4fdb042017-08-07 13:32:32 -070030import org.onlab.packet.UDP;
Yi Tsengca34e1d2017-07-18 16:16:25 -070031
Yi Tsengca34e1d2017-07-18 16:16:25 -070032import java.util.List;
33
Yuta HIGUCHI544afb12017-08-25 10:40:00 -070034import static java.nio.charset.StandardCharsets.US_ASCII;
Yi Tsengca34e1d2017-07-18 16:16:25 -070035import static org.junit.Assert.*;
36
37/**
38 * Test serializing/deserializing DHCPv6 relay message.
39 */
40public class Dhcp6RelayTest {
41 private static final String SOLICIT = "dhcp6_relay_solicit.bin";
42 private static final String ADVERTISE = "dhcp6_relay_advertise.bin";
43 private static final String REQUEST = "dhcp6_relay_request.bin";
44 private static final String REPLY = "dhcp6_relay_reply.bin";
45
46 private static final int HOP_COUNT = 0;
47 private static final Ip6Address LINK_ADDRESS = Ip6Address.valueOf("2000::2ff");
Yi Tsengb4fdb042017-08-07 13:32:32 -070048 private static final Ip6Address PEER_ADDRESS = Ip6Address.valueOf("fe80::2bb:ff:fe00:1");
49 private static final int XID_1 = 8135067;
50 private static final int XID_2 = 14742082;
Yi Tsengca34e1d2017-07-18 16:16:25 -070051 private static final int IA_ID = 1;
52 private static final int T1_CLIENT = 3600;
53 private static final int T2_CLIENT = 5400;
54 private static final int T1_SERVER = 0;
55 private static final int T2_SERVER = 0;
56 private static final Ip6Address IA_ADDRESS = Ip6Address.valueOf("2000::201");
57 private static final int PREFFERRED_LT_SERVER = 375;
58 private static final int VALID_LT_SERVER = 600;
59 private static final int PREFFERRED_LT_REQ = 7200;
Yi Tsengb4fdb042017-08-07 13:32:32 -070060 private static final int VALID_LT_REQ = 10800;
61 private static final int VALID_LT_REQ_2 = 7500;
62 private static final MacAddress DOWNSTREAM_MAC = MacAddress.valueOf("4a:c0:c2:78:92:34");
Yi Tsengca34e1d2017-07-18 16:16:25 -070063 private static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:bb:00:00:00:01");
Yi Tsengb4fdb042017-08-07 13:32:32 -070064 private static final int CLIENT_DUID_TIME = 555636143;
65 private static final MacAddress IPV6_MCAST = MacAddress.valueOf("33:33:00:01:00:03");
66 private static final Ip6Address DOWNSTREAM_LL = Ip6Address.valueOf("fe80::48c0:c2ff:fe78:9234");
67 private static final Ip6Address DHCP6_BRC = Ip6Address.valueOf("ff05::1:3");
68 private static final Ip6Address SERVER_IP = Ip6Address.valueOf("2000::9903");
69 private static final MacAddress SERVER_MAC = MacAddress.valueOf("00:99:66:00:00:01");
70 private static final Ip6Address SERVER_LL = Ip6Address.valueOf("fe80::299:66ff:fe00:1");
71
Yi Tsengca34e1d2017-07-18 16:16:25 -070072
73 /**
74 * Test deserialize relay message with solicit message.
75 *
76 * @throws Exception exception while deserialize the DHCPv6 payload
77 */
78 @Test
79 public void deserializeSolicit() throws Exception {
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -070080 byte[] data = Resources.toByteArray(Dhcp6RelayTest.class.getResource(SOLICIT));
Yi Tsengb4fdb042017-08-07 13:32:32 -070081 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
82 DHCP6 relayMsg = (DHCP6) eth.getPayload().getPayload().getPayload();
Yi Tsengca34e1d2017-07-18 16:16:25 -070083 assertEquals(relayMsg.getMsgType(), DHCP6.MsgType.RELAY_FORW.value());
84 assertEquals(relayMsg.getHopCount(), HOP_COUNT);
85 assertEquals(relayMsg.getIp6LinkAddress(), LINK_ADDRESS);
86 assertEquals(relayMsg.getIp6PeerAddress(), PEER_ADDRESS);
87
Yi Tsengb4fdb042017-08-07 13:32:32 -070088 assertEquals(relayMsg.getOptions().size(), 2);
Yi Tsengca34e1d2017-07-18 16:16:25 -070089 Dhcp6Option option = relayMsg.getOptions().get(0);
Yi Tsengb4fdb042017-08-07 13:32:32 -070090 assertEquals(option.getCode(), DHCP6.OptionCode.SUBSCRIBER_ID.value());
91 assertEquals(option.getLength(), 10);
Yuta HIGUCHI544afb12017-08-25 10:40:00 -070092 assertArrayEquals(option.getData(), SERVER_IP.toString().getBytes(US_ASCII));
Yi Tsengb4fdb042017-08-07 13:32:32 -070093
94 option = relayMsg.getOptions().get(1);
Yi Tsengca34e1d2017-07-18 16:16:25 -070095 assertEquals(option.getCode(), DHCP6.OptionCode.RELAY_MSG.value());
Yi Tsengb4fdb042017-08-07 13:32:32 -070096 assertEquals(option.getLength(), 84);
Yi Tsengca34e1d2017-07-18 16:16:25 -070097 assertTrue(option.getPayload() instanceof DHCP6);
98
99 DHCP6 relaiedDhcp6 = (DHCP6) option.getPayload();
100 assertEquals(relaiedDhcp6.getMsgType(), DHCP6.MsgType.SOLICIT.value());
101 assertEquals(relaiedDhcp6.getTransactionId(), XID_1);
102 assertEquals(relaiedDhcp6.getOptions().size(), 4);
103
104 // Client ID
105 option = relaiedDhcp6.getOptions().get(0);
106 assertTrue(option instanceof Dhcp6ClientIdOption);
107 Dhcp6ClientIdOption clientIdOption = (Dhcp6ClientIdOption) option;
108 assertEquals(clientIdOption.getCode(), DHCP6.OptionCode.CLIENTID.value());
109 assertEquals(clientIdOption.getLength(), 14);
110 assertEquals(clientIdOption.getDuid().getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
111 assertEquals(clientIdOption.getDuid().getHardwareType(), 1);
112 assertEquals(clientIdOption.getDuid().getDuidTime(), CLIENT_DUID_TIME);
113 assertArrayEquals(clientIdOption.getDuid().getLinkLayerAddress(), CLIENT_MAC.toBytes());
114
115 // ORO
116 option = relaiedDhcp6.getOptions().get(1);
117 assertEquals(option.getCode(), DHCP6.OptionCode.ORO.value());
118 assertEquals(option.getLength(), 8);
119 assertArrayEquals(option.getData(),
120 new byte[]{0, 23, 0, 24, 0, 39, 0, 31});
121
122 // ELAPSED_TIME
123 option = relaiedDhcp6.getOptions().get(2);
124 assertEquals(option.getCode(), DHCP6.OptionCode.ELAPSED_TIME.value());
125 assertEquals(option.getLength(), 2);
126 assertArrayEquals(option.getData(),
127 new byte[]{0, 0});
128
129 // IA NA
130 option = relaiedDhcp6.getOptions().get(3);
131 assertTrue(option instanceof Dhcp6IaNaOption);
132 Dhcp6IaNaOption iaNaOption = (Dhcp6IaNaOption) option;
133 assertEquals(iaNaOption.getCode(), DHCP6.OptionCode.IA_NA.value());
Yi Tsengb4fdb042017-08-07 13:32:32 -0700134 assertEquals(iaNaOption.getLength(), 40);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700135 assertEquals(iaNaOption.getIaId(), IA_ID);
136 assertEquals(iaNaOption.getT1(), T1_CLIENT);
137 assertEquals(iaNaOption.getT2(), T2_CLIENT);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700138 assertEquals(iaNaOption.getOptions().size(), 1);
139 Dhcp6IaAddressOption subOption = (Dhcp6IaAddressOption) iaNaOption.getOptions().get(0);
140 assertEquals(subOption.getIp6Address(), IA_ADDRESS);
141 assertEquals(subOption.getPreferredLifetime(), PREFFERRED_LT_REQ);
142 assertEquals(subOption.getValidLifetime(), VALID_LT_REQ);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700143
Yi Tsengb4fdb042017-08-07 13:32:32 -0700144 assertArrayEquals(data, eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700145 }
146
147 /**
148 * Test serialize relay message with solicit message.
149 *
150 * @throws Exception exception while serialize the DHCPv6 payload
151 */
152 @Test
153 public void serializeSolicit() throws Exception {
154 DHCP6 relayMsg = new DHCP6();
155 relayMsg.setMsgType(DHCP6.MsgType.RELAY_FORW.value());
156 relayMsg.setHopCount((byte) HOP_COUNT);
157 relayMsg.setLinkAddress(LINK_ADDRESS.toOctets());
158 relayMsg.setPeerAddress(PEER_ADDRESS.toOctets());
159
160 DHCP6 relaiedDhcp6 = new DHCP6();
161 relaiedDhcp6.setMsgType(DHCP6.MsgType.SOLICIT.value());
162 relaiedDhcp6.setTransactionId(XID_1);
163 List<Dhcp6Option> options = Lists.newArrayList();
164
165 // Client ID
166 Dhcp6Duid duid = new Dhcp6Duid();
167 duid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
168 duid.setHardwareType((short) 1);
169 duid.setDuidTime(CLIENT_DUID_TIME);
170 duid.setLinkLayerAddress(CLIENT_MAC.toBytes());
171 Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
172 clientIdOption.setDuid(duid);
173 options.add(clientIdOption);
174
175 // Option request
176 Dhcp6Option option = new Dhcp6Option();
177 option.setCode(DHCP6.OptionCode.ORO.value());
178 option.setLength((short) 8);
179 option.setData(new byte[]{0, 23, 0, 24, 0, 39, 0, 31});
180 options.add(option);
181
182 // Elapsed Time
183 option = new Dhcp6Option();
184 option.setCode(DHCP6.OptionCode.ELAPSED_TIME.value());
185 option.setLength((short) 2);
186 option.setData(new byte[]{0, 0});
187 options.add(option);
188
189 // IA NA
190 Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
191 iaNaOption.setIaId(IA_ID);
192 iaNaOption.setT1(T1_CLIENT);
193 iaNaOption.setT2(T2_CLIENT);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700194 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
195 iaAddressOption.setIp6Address(IA_ADDRESS);
196 iaAddressOption.setPreferredLifetime(PREFFERRED_LT_REQ);
197 iaAddressOption.setValidLifetime(VALID_LT_REQ);
198 iaNaOption.setOptions(ImmutableList.of(iaAddressOption));
Yi Tsengca34e1d2017-07-18 16:16:25 -0700199 options.add(iaNaOption);
200 relaiedDhcp6.setOptions(options);
201
Yi Tsengca34e1d2017-07-18 16:16:25 -0700202 Dhcp6RelayOption relayOption = new Dhcp6RelayOption();
203 relayOption.setPayload(relaiedDhcp6);
204
Yi Tsengb4fdb042017-08-07 13:32:32 -0700205 Dhcp6Option subscriberId = new Dhcp6Option();
206 subscriberId.setCode(DHCP6.OptionCode.SUBSCRIBER_ID.value());
207 subscriberId.setLength((short) 10);
Yuta HIGUCHI544afb12017-08-25 10:40:00 -0700208 subscriberId.setData(SERVER_IP.toString().getBytes(US_ASCII));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700209
210 relayMsg.setOptions(ImmutableList.of(subscriberId, relayOption));
211
212 UDP udp = new UDP();
213 udp.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
214 udp.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
215 udp.setPayload(relayMsg);
216 udp.setChecksum((short) 0x9a99);
217
218 IPv6 ipv6 = new IPv6();
219 ipv6.setHopLimit((byte) 32);
220 ipv6.setSourceAddress(DOWNSTREAM_LL.toOctets());
221 ipv6.setDestinationAddress(DHCP6_BRC.toOctets());
222 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
223 ipv6.setTrafficClass((byte) 0);
224 ipv6.setFlowLabel(0x000cbf64);
225 ipv6.setPayload(udp);
226
227 Ethernet eth = new Ethernet();
228 eth.setDestinationMACAddress(IPV6_MCAST);
229 eth.setSourceMACAddress(DOWNSTREAM_MAC);
230 eth.setEtherType(Ethernet.TYPE_IPV6);
231 eth.setPayload(ipv6);
232
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700233 assertArrayEquals(Resources.toByteArray(Dhcp6RelayTest.class.getResource(SOLICIT)),
Yi Tsengb4fdb042017-08-07 13:32:32 -0700234 eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700235 }
236
237 /**
238 * Test deserialize relay message with advertise message.
239 *
240 * @throws Exception exception while deserialize the DHCPv6 payload
241 */
242 @Test
243 public void deserializeAdvertise() throws Exception {
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700244 byte[] data = Resources.toByteArray(getClass().getResource(ADVERTISE));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700245 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
246 DHCP6 relayMsg = (DHCP6) eth.getPayload().getPayload().getPayload();
Yi Tsengca34e1d2017-07-18 16:16:25 -0700247 assertEquals(relayMsg.getMsgType(), DHCP6.MsgType.RELAY_REPL.value());
248 assertEquals(relayMsg.getHopCount(), HOP_COUNT);
249 assertEquals(relayMsg.getIp6LinkAddress(), LINK_ADDRESS);
250 assertEquals(relayMsg.getIp6PeerAddress(), PEER_ADDRESS);
251
252 assertEquals(relayMsg.getOptions().size(), 1);
253 Dhcp6Option option = relayMsg.getOptions().get(0);
254 assertEquals(option.getCode(), DHCP6.OptionCode.RELAY_MSG.value());
255 assertEquals(option.getLength(), 84);
256 assertTrue(option.getPayload() instanceof DHCP6);
257
258 DHCP6 relaiedDhcp6 = (DHCP6) option.getPayload();
259 assertEquals(relaiedDhcp6.getMsgType(), DHCP6.MsgType.ADVERTISE.value());
260 assertEquals(relaiedDhcp6.getTransactionId(), XID_1);
261 assertEquals(relaiedDhcp6.getOptions().size(), 3);
262
263 // IA NA
264 option = relaiedDhcp6.getOptions().get(0);
265 assertTrue(option instanceof Dhcp6IaNaOption);
266 Dhcp6IaNaOption iaNaOption = (Dhcp6IaNaOption) option;
267 assertEquals(iaNaOption.getCode(), DHCP6.OptionCode.IA_NA.value());
268 assertEquals(iaNaOption.getLength(), 40);
269 assertEquals(iaNaOption.getIaId(), IA_ID);
270 assertEquals(iaNaOption.getT1(), T1_SERVER);
271 assertEquals(iaNaOption.getT2(), T2_SERVER);
272 assertEquals(iaNaOption.getOptions().size(), 1);
273
274 // IA Address (in IA NA)
275 assertTrue(iaNaOption.getOptions().get(0) instanceof Dhcp6IaAddressOption);
276 Dhcp6IaAddressOption iaAddressOption =
277 (Dhcp6IaAddressOption) iaNaOption.getOptions().get(0);
278 assertEquals(iaAddressOption.getIp6Address(), IA_ADDRESS);
279 assertEquals(iaAddressOption.getPreferredLifetime(), PREFFERRED_LT_SERVER);
280 assertEquals(iaAddressOption.getValidLifetime(), VALID_LT_SERVER);
281 assertNull(iaAddressOption.getOptions());
282
283 // Client ID
284 option = relaiedDhcp6.getOptions().get(1);
285 assertTrue(option instanceof Dhcp6ClientIdOption);
286 Dhcp6ClientIdOption clientIdOption = (Dhcp6ClientIdOption) option;
287 assertEquals(clientIdOption.getCode(), DHCP6.OptionCode.CLIENTID.value());
288 assertEquals(clientIdOption.getLength(), 14);
289 assertEquals(clientIdOption.getDuid().getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
290 assertEquals(clientIdOption.getDuid().getHardwareType(), 1);
291 assertEquals(clientIdOption.getDuid().getDuidTime(), CLIENT_DUID_TIME);
292 assertArrayEquals(clientIdOption.getDuid().getLinkLayerAddress(), CLIENT_MAC.toBytes());
293
294 // Server ID
295 option = relaiedDhcp6.getOptions().get(2);
296 assertEquals(option.getCode(), DHCP6.OptionCode.SERVERID.value());
297 assertEquals(option.getLength(), 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700298 Dhcp6Duid serverDuid =
299 Dhcp6Duid.deserializer().deserialize(option.getData(), 0, option.getData().length);
300 assertEquals(serverDuid.getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
301 assertEquals(serverDuid.getDuidTime(), 0x211e5340);
302 assertEquals(serverDuid.getHardwareType(), 1);
303 assertArrayEquals(serverDuid.getLinkLayerAddress(), SERVER_MAC.toBytes());
304 assertArrayEquals(data, eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700305 }
306
307 /**
308 * Test serialize relay message with advertise message.
309 *
310 * @throws Exception exception while serialize the DHCPv6 payload
311 */
312 @Test
313 public void serializeAdvertise() throws Exception {
314 DHCP6 relayMsg = new DHCP6();
315 relayMsg.setMsgType(DHCP6.MsgType.RELAY_REPL.value());
316 relayMsg.setHopCount((byte) HOP_COUNT);
317 relayMsg.setLinkAddress(LINK_ADDRESS.toOctets());
318 relayMsg.setPeerAddress(PEER_ADDRESS.toOctets());
319
320 DHCP6 relaiedDhcp6 = new DHCP6();
321 relaiedDhcp6.setMsgType(DHCP6.MsgType.ADVERTISE.value());
322 relaiedDhcp6.setTransactionId(XID_1);
323 List<Dhcp6Option> options = Lists.newArrayList();
324
325 // IA address
326 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
327 iaAddressOption.setIp6Address(IA_ADDRESS);
328 iaAddressOption.setPreferredLifetime(PREFFERRED_LT_SERVER);
329 iaAddressOption.setValidLifetime(VALID_LT_SERVER);
330
331 // IA NA
332 Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
333 iaNaOption.setIaId(IA_ID);
334 iaNaOption.setT1(T1_SERVER);
335 iaNaOption.setT2(T2_SERVER);
336 iaNaOption.setOptions(ImmutableList.of(iaAddressOption));
337 options.add(iaNaOption);
338
339 // Client ID
340 Dhcp6Duid duid = new Dhcp6Duid();
341 duid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
342 duid.setHardwareType((short) 1);
343 duid.setDuidTime(CLIENT_DUID_TIME);
344 duid.setLinkLayerAddress(CLIENT_MAC.toBytes());
345 Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
346 clientIdOption.setDuid(duid);
347 options.add(clientIdOption);
348
349 // Server ID
350 Dhcp6Option option = new Dhcp6Option();
351 option.setCode(DHCP6.OptionCode.SERVERID.value());
352 option.setLength((short) 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700353 Dhcp6Duid serverDuid = new Dhcp6Duid();
354 serverDuid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
355 serverDuid.setLinkLayerAddress(SERVER_MAC.toBytes());
356 serverDuid.setHardwareType((short) 1);
357 serverDuid.setDuidTime(0x211e5340);
358 option.setData(serverDuid.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700359 options.add(option);
360
361 relaiedDhcp6.setOptions(options);
362
363 Dhcp6RelayOption relayOption = new Dhcp6RelayOption();
364 relayOption.setPayload(relaiedDhcp6);
365
366 relayMsg.setOptions(ImmutableList.of(relayOption));
367
Yi Tsengb4fdb042017-08-07 13:32:32 -0700368 UDP udp = new UDP();
369 udp.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
370 udp.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
371 udp.setPayload(relayMsg);
372 udp.setChecksum((short) 0x0000019d);
373
374 IPv6 ipv6 = new IPv6();
375 ipv6.setHopLimit((byte) 64);
376 ipv6.setSourceAddress(SERVER_LL.toOctets());
377 ipv6.setDestinationAddress(DOWNSTREAM_LL.toOctets());
378 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
379 ipv6.setTrafficClass((byte) 0);
380 ipv6.setFlowLabel(0x000c72ef);
381 ipv6.setPayload(udp);
382
383 Ethernet eth = new Ethernet();
384 eth.setDestinationMACAddress(DOWNSTREAM_MAC);
385 eth.setSourceMACAddress(SERVER_MAC);
386 eth.setEtherType(Ethernet.TYPE_IPV6);
387 eth.setPayload(ipv6);
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700388 assertArrayEquals(Resources.toByteArray(Dhcp6RelayTest.class.getResource(ADVERTISE)),
Yi Tsengb4fdb042017-08-07 13:32:32 -0700389 eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700390 }
391
392 /**
393 * Test deserialize relay message with request message.
394 *
395 * @throws Exception exception while deserialize the DHCPv6 payload
396 */
397 @Test
398 public void deserializeRequest() throws Exception {
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700399 byte[] data = Resources.toByteArray(getClass().getResource(REQUEST));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700400 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
401 DHCP6 relayMsg = (DHCP6) eth.getPayload().getPayload().getPayload();
Yi Tsengca34e1d2017-07-18 16:16:25 -0700402 assertEquals(relayMsg.getMsgType(), DHCP6.MsgType.RELAY_FORW.value());
403 assertEquals(relayMsg.getHopCount(), HOP_COUNT);
404 assertEquals(relayMsg.getIp6LinkAddress(), LINK_ADDRESS);
405 assertEquals(relayMsg.getIp6PeerAddress(), PEER_ADDRESS);
406
Yi Tsengb4fdb042017-08-07 13:32:32 -0700407 assertEquals(relayMsg.getOptions().size(), 2);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700408 Dhcp6Option option = relayMsg.getOptions().get(0);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700409 assertEquals(option.getCode(), DHCP6.OptionCode.SUBSCRIBER_ID.value());
410 assertEquals(option.getLength(), 10);
Yuta HIGUCHI544afb12017-08-25 10:40:00 -0700411 assertArrayEquals(option.getData(), SERVER_IP.toString().getBytes(US_ASCII));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700412
413 option = relayMsg.getOptions().get(1);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700414 assertEquals(option.getCode(), DHCP6.OptionCode.RELAY_MSG.value());
415 assertEquals(option.getLength(), 102);
416 assertTrue(option.getPayload() instanceof DHCP6);
417
418 DHCP6 relaiedDhcp6 = (DHCP6) option.getPayload();
419 assertEquals(relaiedDhcp6.getMsgType(), DHCP6.MsgType.REQUEST.value());
420 assertEquals(relaiedDhcp6.getTransactionId(), XID_2);
421 assertEquals(relaiedDhcp6.getOptions().size(), 5);
422
423 // Client ID
424 option = relaiedDhcp6.getOptions().get(0);
425 assertTrue(option instanceof Dhcp6ClientIdOption);
426 Dhcp6ClientIdOption clientIdOption = (Dhcp6ClientIdOption) option;
427 assertEquals(clientIdOption.getCode(), DHCP6.OptionCode.CLIENTID.value());
428 assertEquals(clientIdOption.getLength(), 14);
429 assertEquals(clientIdOption.getDuid().getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
430 assertEquals(clientIdOption.getDuid().getHardwareType(), 1);
431 assertEquals(clientIdOption.getDuid().getDuidTime(), CLIENT_DUID_TIME);
432 assertArrayEquals(clientIdOption.getDuid().getLinkLayerAddress(), CLIENT_MAC.toBytes());
433
434 // Server ID
435 option = relaiedDhcp6.getOptions().get(1);
436 assertEquals(option.getCode(), DHCP6.OptionCode.SERVERID.value());
437 assertEquals(option.getLength(), 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700438 Dhcp6Duid serverDuid =
439 Dhcp6Duid.deserializer().deserialize(option.getData(), 0, option.getData().length);
440 assertEquals(serverDuid.getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
441 assertEquals(serverDuid.getDuidTime(), 0x211e5340);
442 assertEquals(serverDuid.getHardwareType(), 1);
443 assertArrayEquals(serverDuid.getLinkLayerAddress(), SERVER_MAC.toBytes());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700444
445 // Option Request
446 option = relaiedDhcp6.getOptions().get(2);
447 assertEquals(option.getCode(), DHCP6.OptionCode.ORO.value());
448 assertEquals(option.getLength(), 8);
449 assertArrayEquals(option.getData(), new byte[]{0, 23, 0, 24, 0, 39, 0, 31});
450
451 // ELAPSED_TIME
452 option = relaiedDhcp6.getOptions().get(3);
453 assertEquals(option.getCode(), DHCP6.OptionCode.ELAPSED_TIME.value());
454 assertEquals(option.getLength(), 2);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700455 assertArrayEquals(option.getData(), new byte[]{0, 0});
Yi Tsengca34e1d2017-07-18 16:16:25 -0700456
457 // IA NA
458 option = relaiedDhcp6.getOptions().get(4);
459 assertTrue(option instanceof Dhcp6IaNaOption);
460 Dhcp6IaNaOption iaNaOption = (Dhcp6IaNaOption) option;
461 assertEquals(iaNaOption.getCode(), DHCP6.OptionCode.IA_NA.value());
462 assertEquals(iaNaOption.getLength(), 40);
463 assertEquals(iaNaOption.getIaId(), IA_ID);
464 assertEquals(iaNaOption.getT1(), T1_CLIENT);
465 assertEquals(iaNaOption.getT2(), T2_CLIENT);
466 assertEquals(iaNaOption.getOptions().size(), 1);
467
468 // IA Address (in IA NA)
469 assertTrue(iaNaOption.getOptions().get(0) instanceof Dhcp6IaAddressOption);
470 Dhcp6IaAddressOption iaAddressOption =
471 (Dhcp6IaAddressOption) iaNaOption.getOptions().get(0);
472 assertEquals(iaAddressOption.getIp6Address(), IA_ADDRESS);
473 assertEquals(iaAddressOption.getPreferredLifetime(), PREFFERRED_LT_REQ);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700474 assertEquals(iaAddressOption.getValidLifetime(), VALID_LT_REQ_2);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700475 assertNull(iaAddressOption.getOptions());
476
Yi Tsengb4fdb042017-08-07 13:32:32 -0700477 assertArrayEquals(data, eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700478 }
479
480 /**
481 * Test serialize relay message with request message.
482 *
483 * @throws Exception exception while serialize the DHCPv6 payload
484 */
485 @Test
486 public void serializeRequest() throws Exception {
487 DHCP6 relayMsg = new DHCP6();
488 relayMsg.setMsgType(DHCP6.MsgType.RELAY_FORW.value());
489 relayMsg.setHopCount((byte) HOP_COUNT);
490 relayMsg.setLinkAddress(LINK_ADDRESS.toOctets());
491 relayMsg.setPeerAddress(PEER_ADDRESS.toOctets());
492
493 DHCP6 relaiedDhcp6 = new DHCP6();
494 relaiedDhcp6.setMsgType(DHCP6.MsgType.REQUEST.value());
495 relaiedDhcp6.setTransactionId(XID_2);
496 List<Dhcp6Option> options = Lists.newArrayList();
497
498 // Client ID
499 Dhcp6Duid duid = new Dhcp6Duid();
500 duid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
501 duid.setHardwareType((short) 1);
502 duid.setDuidTime(CLIENT_DUID_TIME);
503 duid.setLinkLayerAddress(CLIENT_MAC.toBytes());
504 Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
505 clientIdOption.setDuid(duid);
506 options.add(clientIdOption);
507
508 // Server ID
509 Dhcp6Option option = new Dhcp6Option();
510 option.setCode(DHCP6.OptionCode.SERVERID.value());
511 option.setLength((short) 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700512 Dhcp6Duid serverDuid = new Dhcp6Duid();
513 serverDuid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
514 serverDuid.setLinkLayerAddress(SERVER_MAC.toBytes());
515 serverDuid.setHardwareType((short) 1);
516 serverDuid.setDuidTime(0x211e5340);
517 option.setData(serverDuid.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700518 options.add(option);
519
520 // Option request
521 option = new Dhcp6Option();
522 option.setCode(DHCP6.OptionCode.ORO.value());
523 option.setLength((short) 8);
524 option.setData(new byte[]{0, 23, 0, 24, 0, 39, 0, 31});
525 options.add(option);
526
527 // Elapsed Time
528 option = new Dhcp6Option();
529 option.setCode(DHCP6.OptionCode.ELAPSED_TIME.value());
530 option.setLength((short) 2);
531 option.setData(new byte[]{0, 0});
532 options.add(option);
533
534 // IA address
535 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
536 iaAddressOption.setIp6Address(IA_ADDRESS);
537 iaAddressOption.setPreferredLifetime(PREFFERRED_LT_REQ);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700538 iaAddressOption.setValidLifetime(VALID_LT_REQ_2);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700539
540 // IA NA
541 Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
542 iaNaOption.setIaId(IA_ID);
543 iaNaOption.setT1(T1_CLIENT);
544 iaNaOption.setT2(T2_CLIENT);
545 iaNaOption.setOptions(ImmutableList.of(iaAddressOption));
546 options.add(iaNaOption);
547
548 relaiedDhcp6.setOptions(options);
549
Yi Tsengb4fdb042017-08-07 13:32:32 -0700550 Dhcp6Option subscriberId = new Dhcp6Option();
551 subscriberId.setCode(DHCP6.OptionCode.SUBSCRIBER_ID.value());
552 subscriberId.setLength((short) 10);
Yuta HIGUCHI544afb12017-08-25 10:40:00 -0700553 subscriberId.setData(SERVER_IP.toString().getBytes(US_ASCII));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700554
Yi Tsengca34e1d2017-07-18 16:16:25 -0700555 Dhcp6RelayOption relayOption = new Dhcp6RelayOption();
556 relayOption.setPayload(relaiedDhcp6);
557
Yi Tsengb4fdb042017-08-07 13:32:32 -0700558 relayMsg.setOptions(ImmutableList.of(subscriberId, relayOption));
559
560 UDP udp = new UDP();
561 udp.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
562 udp.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
563 udp.setPayload(relayMsg);
564 udp.setChecksum((short) 0x9aab);
565
566 IPv6 ipv6 = new IPv6();
567 ipv6.setHopLimit((byte) 32);
568 ipv6.setSourceAddress(DOWNSTREAM_LL.toOctets());
569 ipv6.setDestinationAddress(DHCP6_BRC.toOctets());
570 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
571 ipv6.setTrafficClass((byte) 0);
572 ipv6.setFlowLabel(0x000cbf64);
573 ipv6.setPayload(udp);
574
575 Ethernet eth = new Ethernet();
576 eth.setDestinationMACAddress(IPV6_MCAST);
577 eth.setSourceMACAddress(DOWNSTREAM_MAC);
578 eth.setEtherType(Ethernet.TYPE_IPV6);
579 eth.setPayload(ipv6);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700580
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700581 assertArrayEquals(Resources.toByteArray(Dhcp6RelayTest.class.getResource(REQUEST)),
Yi Tsengb4fdb042017-08-07 13:32:32 -0700582 eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700583 }
584
585 /**
586 * Test deserialize relay message with reply message.
587 *
588 * @throws Exception exception while deserialize the DHCPv6 payload
589 */
590 @Test
591 public void deserializeReply() throws Exception {
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700592 byte[] data = Resources.toByteArray(getClass().getResource(REPLY));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700593 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
594 DHCP6 relayMsg = (DHCP6) eth.getPayload().getPayload().getPayload();
Yi Tsengca34e1d2017-07-18 16:16:25 -0700595 assertEquals(relayMsg.getMsgType(), DHCP6.MsgType.RELAY_REPL.value());
596 assertEquals(relayMsg.getHopCount(), HOP_COUNT);
597 assertEquals(relayMsg.getIp6LinkAddress(), LINK_ADDRESS);
598 assertEquals(relayMsg.getIp6PeerAddress(), PEER_ADDRESS);
599
600 assertEquals(relayMsg.getOptions().size(), 1);
601 Dhcp6Option option = relayMsg.getOptions().get(0);
602 assertEquals(option.getCode(), DHCP6.OptionCode.RELAY_MSG.value());
603 assertEquals(option.getLength(), 84);
604 assertTrue(option.getPayload() instanceof DHCP6);
605
606 DHCP6 relaiedDhcp6 = (DHCP6) option.getPayload();
607 assertEquals(relaiedDhcp6.getMsgType(), DHCP6.MsgType.REPLY.value());
608 assertEquals(relaiedDhcp6.getTransactionId(), XID_2);
609 assertEquals(relaiedDhcp6.getOptions().size(), 3);
610
611 // IA NA
612 option = relaiedDhcp6.getOptions().get(0);
613 assertTrue(option instanceof Dhcp6IaNaOption);
614 Dhcp6IaNaOption iaNaOption = (Dhcp6IaNaOption) option;
615 assertEquals(iaNaOption.getCode(), DHCP6.OptionCode.IA_NA.value());
616 assertEquals(iaNaOption.getLength(), 40);
617 assertEquals(iaNaOption.getIaId(), IA_ID);
618 assertEquals(iaNaOption.getT1(), T1_SERVER);
619 assertEquals(iaNaOption.getT2(), T2_SERVER);
620 assertEquals(iaNaOption.getOptions().size(), 1);
621
622 // IA Address (in IA NA)
623 assertTrue(iaNaOption.getOptions().get(0) instanceof Dhcp6IaAddressOption);
624 Dhcp6IaAddressOption iaAddressOption =
625 (Dhcp6IaAddressOption) iaNaOption.getOptions().get(0);
626 assertEquals(iaAddressOption.getIp6Address(), IA_ADDRESS);
627 assertEquals(iaAddressOption.getPreferredLifetime(), PREFFERRED_LT_SERVER);
628 assertEquals(iaAddressOption.getValidLifetime(), VALID_LT_SERVER);
629 assertNull(iaAddressOption.getOptions());
630
631 // Client ID
632 option = relaiedDhcp6.getOptions().get(1);
633 assertTrue(option instanceof Dhcp6ClientIdOption);
634 Dhcp6ClientIdOption clientIdOption = (Dhcp6ClientIdOption) option;
635 assertEquals(clientIdOption.getCode(), DHCP6.OptionCode.CLIENTID.value());
636 assertEquals(clientIdOption.getLength(), 14);
637 assertEquals(clientIdOption.getDuid().getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
638 assertEquals(clientIdOption.getDuid().getHardwareType(), 1);
639 assertEquals(clientIdOption.getDuid().getDuidTime(), CLIENT_DUID_TIME);
640 assertArrayEquals(clientIdOption.getDuid().getLinkLayerAddress(), CLIENT_MAC.toBytes());
641
642 // Server ID
643 option = relaiedDhcp6.getOptions().get(2);
644 assertEquals(option.getCode(), DHCP6.OptionCode.SERVERID.value());
645 assertEquals(option.getLength(), 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700646 Dhcp6Duid serverDuid =
647 Dhcp6Duid.deserializer().deserialize(option.getData(), 0, option.getData().length);
648 assertEquals(serverDuid.getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
649 assertEquals(serverDuid.getDuidTime(), 0x211e5340);
650 assertEquals(serverDuid.getHardwareType(), 1);
651 assertArrayEquals(serverDuid.getLinkLayerAddress(), SERVER_MAC.toBytes());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700652
Yi Tsengb4fdb042017-08-07 13:32:32 -0700653 assertArrayEquals(data, eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700654 }
655
656 @Test
657 public void serializeReply() throws Exception {
658 DHCP6 relayMsg = new DHCP6();
659 relayMsg.setMsgType(DHCP6.MsgType.RELAY_REPL.value());
660 relayMsg.setHopCount((byte) HOP_COUNT);
661 relayMsg.setLinkAddress(LINK_ADDRESS.toOctets());
662 relayMsg.setPeerAddress(PEER_ADDRESS.toOctets());
663
664 DHCP6 relaiedDhcp6 = new DHCP6();
665 relaiedDhcp6.setMsgType(DHCP6.MsgType.REPLY.value());
666 relaiedDhcp6.setTransactionId(XID_2);
667 List<Dhcp6Option> options = Lists.newArrayList();
668
669 // IA address
670 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
671 iaAddressOption.setIp6Address(IA_ADDRESS);
672 iaAddressOption.setPreferredLifetime(PREFFERRED_LT_SERVER);
673 iaAddressOption.setValidLifetime(VALID_LT_SERVER);
674
675 // IA NA
676 Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
677 iaNaOption.setIaId(IA_ID);
678 iaNaOption.setT1(T1_SERVER);
679 iaNaOption.setT2(T2_SERVER);
680 iaNaOption.setOptions(ImmutableList.of(iaAddressOption));
681 options.add(iaNaOption);
682
683 // Client ID
684 Dhcp6Duid duid = new Dhcp6Duid();
685 duid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
686 duid.setHardwareType((short) 1);
687 duid.setDuidTime(CLIENT_DUID_TIME);
688 duid.setLinkLayerAddress(CLIENT_MAC.toBytes());
689 Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
690 clientIdOption.setDuid(duid);
691 options.add(clientIdOption);
692
693 // Server ID
694 Dhcp6Option option = new Dhcp6Option();
695 option.setCode(DHCP6.OptionCode.SERVERID.value());
696 option.setLength((short) 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700697 Dhcp6Duid serverDuid = new Dhcp6Duid();
698 serverDuid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
699 serverDuid.setLinkLayerAddress(SERVER_MAC.toBytes());
700 serverDuid.setHardwareType((short) 1);
701 serverDuid.setDuidTime(0x211e5340);
702 option.setData(serverDuid.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700703 options.add(option);
704
705 relaiedDhcp6.setOptions(options);
706
707 Dhcp6RelayOption relayOption = new Dhcp6RelayOption();
708 relayOption.setPayload(relaiedDhcp6);
709
710 relayMsg.setOptions(ImmutableList.of(relayOption));
711
Yi Tsengb4fdb042017-08-07 13:32:32 -0700712 UDP udp = new UDP();
713 udp.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
714 udp.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
715 udp.setPayload(relayMsg);
716 udp.setChecksum((short) 0x019d);
717
718 IPv6 ipv6 = new IPv6();
719 ipv6.setHopLimit((byte) 64);
720 ipv6.setSourceAddress(SERVER_LL.toOctets());
721 ipv6.setDestinationAddress(DOWNSTREAM_LL.toOctets());
722 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
723 ipv6.setTrafficClass((byte) 0);
724 ipv6.setFlowLabel(0x000c72ef);
725 ipv6.setPayload(udp);
726
727 Ethernet eth = new Ethernet();
728 eth.setDestinationMACAddress(DOWNSTREAM_MAC);
729 eth.setSourceMACAddress(SERVER_MAC);
730 eth.setEtherType(Ethernet.TYPE_IPV6);
731 eth.setPayload(ipv6);
732
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700733 assertArrayEquals(Resources.toByteArray(Dhcp6RelayTest.class.getResource(REPLY)),
Yi Tsengb4fdb042017-08-07 13:32:32 -0700734 eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700735 }
736}