blob: 795c8aad2011fae038c78ddb4b1fd919f90235e1 [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
17package org.onlab.packet.dhcp;
18
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -070021import com.google.common.io.Resources;
22
Yi Tsengca34e1d2017-07-18 16:16:25 -070023import org.junit.Test;
24import org.onlab.packet.DHCP6;
25import org.onlab.packet.Deserializer;
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;
30import org.onlab.packet.PacketTestUtils;
Yi Tsengb4fdb042017-08-07 13:32:32 -070031import org.onlab.packet.UDP;
Yi Tsengca34e1d2017-07-18 16:16:25 -070032
33import java.nio.ByteBuffer;
Yi Tsengca34e1d2017-07-18 16:16:25 -070034import java.util.List;
35
36import static org.junit.Assert.*;
37import static org.junit.Assert.assertNull;
38
39public class Dhcp6Test {
40 private static final String SOLICIT = "dhcp6_solicit.bin";
41 private static final String ADVERTISE = "dhcp6_advertise.bin";
42 private static final String REQUEST = "dhcp6_request.bin";
43 private static final String REPLY = "dhcp6_reply.bin";
44
Yi Tsengb4fdb042017-08-07 13:32:32 -070045 private static final int XID_1 = 13938541;
46 private static final int XID_2 = 11359587;
Yi Tsengca34e1d2017-07-18 16:16:25 -070047 private static final int IA_ID = 1;
48 private static final int T1_CLIENT = 3600;
49 private static final int T2_CLIENT = 5400;
50 private static final int T1_SERVER = 0;
51 private static final int T2_SERVER = 0;
52 private static final Ip6Address IA_ADDRESS = Ip6Address.valueOf("2000::201");
53 private static final int PREFFERRED_LT_SERVER = 375;
54 private static final int VALID_LT_SERVER = 600;
55 private static final int PREFFERRED_LT_REQ = 7200;
Yi Tsengb4fdb042017-08-07 13:32:32 -070056 private static final int VALID_LT_REQ = 10800;
57 private static final int VALID_LT_REQ_2 = 7500;
Yi Tsengca34e1d2017-07-18 16:16:25 -070058 private static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:bb:00:00:00:01");
Yi Tsengb4fdb042017-08-07 13:32:32 -070059 private static final int CLIENT_DUID_TIME = 555636143;
60 private static final MacAddress IPV6_MCAST = MacAddress.valueOf("33:33:00:01:00:02");
61 private static final Ip6Address CLIENT_LL = Ip6Address.valueOf("fe80::2bb:ff:fe00:1");
62 private static final Ip6Address DHCP6_BRC = Ip6Address.valueOf("ff02::1:2");
63 private static final MacAddress SERVER_MAC = MacAddress.valueOf("00:99:66:00:00:01");
64 private static final MacAddress UPSTREAM_MAC = MacAddress.valueOf("de:15:19:e4:d7:35");
65 private static final Ip6Address UPSTREAM_LL = Ip6Address.valueOf("fe80::dc15:19ff:fee4:d735");
Yi Tsengca34e1d2017-07-18 16:16:25 -070066
67
68 private Deserializer<DHCP6> deserializer = DHCP6.deserializer();
69
70
71 @Test
72 public void testDeserializeBadInput() throws Exception {
73 PacketTestUtils.testDeserializeBadInput(deserializer);
74 }
75
76 /**
77 * Truncated a simple DHCPv6 payload.
78 */
79 @Test
80 public void testDeserializeTruncated() throws Exception {
81 ByteBuffer bb = ByteBuffer.allocate(4);
82 bb.put(DHCP6.MsgType.REQUEST.value());
83 bb.put(new byte[]{0x00, 0x00});
84 PacketTestUtils.testDeserializeTruncated(deserializer, bb.array());
85 }
86
87 /**
88 * Test DHCPv6 solicit message.
89 *
90 * @throws Exception exception while deserialize the DHCPv6 payload
91 */
92 @Test
93 public void testDeserializeSolicit() throws Exception {
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -070094 byte[] data = Resources.toByteArray(Dhcp6RelayTest.class.getResource(SOLICIT));
Yi Tsengb4fdb042017-08-07 13:32:32 -070095 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
96 DHCP6 dhcp6 = (DHCP6) eth.getPayload().getPayload().getPayload();
Yi Tsengca34e1d2017-07-18 16:16:25 -070097 assertEquals(dhcp6.getMsgType(), DHCP6.MsgType.SOLICIT.value());
98 assertEquals(dhcp6.getTransactionId(), XID_1);
99 assertEquals(dhcp6.getOptions().size(), 4);
100
101 // Client ID
102 Dhcp6Option option = dhcp6.getOptions().get(0);
103 assertTrue(option instanceof Dhcp6ClientIdOption);
104 Dhcp6ClientIdOption clientIdOption = (Dhcp6ClientIdOption) option;
105 assertEquals(clientIdOption.getCode(), DHCP6.OptionCode.CLIENTID.value());
106 assertEquals(clientIdOption.getLength(), 14);
107 assertEquals(clientIdOption.getDuid().getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
108 assertEquals(clientIdOption.getDuid().getHardwareType(), 1);
109 assertEquals(clientIdOption.getDuid().getDuidTime(), CLIENT_DUID_TIME);
110 assertArrayEquals(clientIdOption.getDuid().getLinkLayerAddress(), CLIENT_MAC.toBytes());
111
112 // ORO
113 option = dhcp6.getOptions().get(1);
114 assertEquals(option.getCode(), DHCP6.OptionCode.ORO.value());
115 assertEquals(option.getLength(), 8);
116 assertArrayEquals(option.getData(),
117 new byte[]{0, 23, 0, 24, 0, 39, 0, 31});
118
119 // ELAPSED_TIME
120 option = dhcp6.getOptions().get(2);
121 assertEquals(option.getCode(), DHCP6.OptionCode.ELAPSED_TIME.value());
122 assertEquals(option.getLength(), 2);
123 assertArrayEquals(option.getData(),
124 new byte[]{0, 0});
125
126 // IA NA
127 option = dhcp6.getOptions().get(3);
128 assertTrue(option instanceof Dhcp6IaNaOption);
129 Dhcp6IaNaOption iaNaOption = (Dhcp6IaNaOption) option;
130 assertEquals(iaNaOption.getCode(), DHCP6.OptionCode.IA_NA.value());
Yi Tsengb4fdb042017-08-07 13:32:32 -0700131 assertEquals(iaNaOption.getLength(), 40);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700132 assertEquals(iaNaOption.getIaId(), IA_ID);
133 assertEquals(iaNaOption.getT1(), T1_CLIENT);
134 assertEquals(iaNaOption.getT2(), T2_CLIENT);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700135 assertEquals(iaNaOption.getOptions().size(), 1);
136 Dhcp6IaAddressOption subOption = (Dhcp6IaAddressOption) iaNaOption.getOptions().get(0);
137 assertEquals(subOption.getIp6Address(), IA_ADDRESS);
138 assertEquals(subOption.getPreferredLifetime(), PREFFERRED_LT_REQ);
139 assertEquals(subOption.getValidLifetime(), VALID_LT_REQ);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700140
Yi Tsengb4fdb042017-08-07 13:32:32 -0700141 assertArrayEquals(data, eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700142 }
143
144 /**
145 * Test serialize solicit message.
146 *
147 * @throws Exception exception while serialize the DHCPv6 payload
148 */
149 @Test
150 public void serializeSolicit() throws Exception {
151 DHCP6 dhcp6 = new DHCP6();
152 dhcp6.setMsgType(DHCP6.MsgType.SOLICIT.value());
153 dhcp6.setTransactionId(XID_1);
154 List<Dhcp6Option> options = Lists.newArrayList();
155
156 // Client ID
157 Dhcp6Duid duid = new Dhcp6Duid();
158 duid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
159 duid.setHardwareType((short) 1);
160 duid.setDuidTime(CLIENT_DUID_TIME);
161 duid.setLinkLayerAddress(CLIENT_MAC.toBytes());
162 Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
163 clientIdOption.setDuid(duid);
164 options.add(clientIdOption);
165
166 // Option request
167 Dhcp6Option option = new Dhcp6Option();
168 option.setCode(DHCP6.OptionCode.ORO.value());
169 option.setLength((short) 8);
170 option.setData(new byte[]{0, 23, 0, 24, 0, 39, 0, 31});
171 options.add(option);
172
173 // Elapsed Time
174 option = new Dhcp6Option();
175 option.setCode(DHCP6.OptionCode.ELAPSED_TIME.value());
176 option.setLength((short) 2);
177 option.setData(new byte[]{0, 0});
178 options.add(option);
179
180 // IA NA
181 Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
182 iaNaOption.setIaId(IA_ID);
183 iaNaOption.setT1(T1_CLIENT);
184 iaNaOption.setT2(T2_CLIENT);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700185 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
186 iaAddressOption.setIp6Address(IA_ADDRESS);
187 iaAddressOption.setPreferredLifetime(PREFFERRED_LT_REQ);
188 iaAddressOption.setValidLifetime(VALID_LT_REQ);
189 iaNaOption.setOptions(ImmutableList.of(iaAddressOption));
Yi Tsengca34e1d2017-07-18 16:16:25 -0700190 options.add(iaNaOption);
191 dhcp6.setOptions(options);
192
Yi Tsengca34e1d2017-07-18 16:16:25 -0700193 Dhcp6RelayOption relayOption = new Dhcp6RelayOption();
194 relayOption.setPayload(dhcp6);
195
Yi Tsengb4fdb042017-08-07 13:32:32 -0700196 UDP udp = new UDP();
197 udp.setSourcePort(UDP.DHCP_V6_CLIENT_PORT);
198 udp.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
199 udp.setPayload(dhcp6);
200 udp.setChecksum((short) 0xffaf);
201
202 IPv6 ipv6 = new IPv6();
203 ipv6.setHopLimit((byte) 1);
204 ipv6.setSourceAddress(CLIENT_LL.toOctets());
205 ipv6.setDestinationAddress(DHCP6_BRC.toOctets());
206 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
207 ipv6.setTrafficClass((byte) 0);
208 ipv6.setFlowLabel(0x000322ad);
209 ipv6.setPayload(udp);
210
211 Ethernet eth = new Ethernet();
212 eth.setDestinationMACAddress(IPV6_MCAST);
213 eth.setSourceMACAddress(CLIENT_MAC);
214 eth.setEtherType(Ethernet.TYPE_IPV6);
215 eth.setPayload(ipv6);
216
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700217 assertArrayEquals(Resources.toByteArray(Dhcp6RelayTest.class.getResource(SOLICIT)),
Yi Tsengb4fdb042017-08-07 13:32:32 -0700218 eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700219 }
220
221 /**
222 * Test deserialize advertise message.
223 *
224 * @throws Exception exception while deserialize the DHCPv6 payload
225 */
226 @Test
227 public void deserializeAdvertise() throws Exception {
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700228 byte[] data = Resources.toByteArray(getClass().getResource(ADVERTISE));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700229 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
230 DHCP6 dhcp6 = (DHCP6) eth.getPayload().getPayload().getPayload();
Yi Tsengca34e1d2017-07-18 16:16:25 -0700231 assertEquals(dhcp6.getMsgType(), DHCP6.MsgType.ADVERTISE.value());
232 assertEquals(dhcp6.getTransactionId(), XID_1);
233 assertEquals(dhcp6.getOptions().size(), 3);
234
235 // IA NA
236 Dhcp6Option option = dhcp6.getOptions().get(0);
237 assertTrue(option instanceof Dhcp6IaNaOption);
238 Dhcp6IaNaOption iaNaOption = (Dhcp6IaNaOption) option;
239 assertEquals(iaNaOption.getCode(), DHCP6.OptionCode.IA_NA.value());
240 assertEquals(iaNaOption.getLength(), 40);
241 assertEquals(iaNaOption.getIaId(), IA_ID);
242 assertEquals(iaNaOption.getT1(), T1_SERVER);
243 assertEquals(iaNaOption.getT2(), T2_SERVER);
244 assertEquals(iaNaOption.getOptions().size(), 1);
245
246 // IA Address (in IA NA)
247 assertTrue(iaNaOption.getOptions().get(0) instanceof Dhcp6IaAddressOption);
248 Dhcp6IaAddressOption iaAddressOption =
249 (Dhcp6IaAddressOption) iaNaOption.getOptions().get(0);
250 assertEquals(iaAddressOption.getIp6Address(), IA_ADDRESS);
251 assertEquals(iaAddressOption.getPreferredLifetime(), PREFFERRED_LT_SERVER);
252 assertEquals(iaAddressOption.getValidLifetime(), VALID_LT_SERVER);
253 assertNull(iaAddressOption.getOptions());
254
255 // Client ID
256 option = dhcp6.getOptions().get(1);
257 assertTrue(option instanceof Dhcp6ClientIdOption);
258 Dhcp6ClientIdOption clientIdOption = (Dhcp6ClientIdOption) option;
259 assertEquals(clientIdOption.getCode(), DHCP6.OptionCode.CLIENTID.value());
260 assertEquals(clientIdOption.getLength(), 14);
261 assertEquals(clientIdOption.getDuid().getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
262 assertEquals(clientIdOption.getDuid().getHardwareType(), 1);
263 assertEquals(clientIdOption.getDuid().getDuidTime(), CLIENT_DUID_TIME);
264 assertArrayEquals(clientIdOption.getDuid().getLinkLayerAddress(), CLIENT_MAC.toBytes());
265
266 // Server ID
267 option = dhcp6.getOptions().get(2);
268 assertEquals(option.getCode(), DHCP6.OptionCode.SERVERID.value());
269 assertEquals(option.getLength(), 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700270 Dhcp6Duid serverDuid =
271 Dhcp6Duid.deserializer().deserialize(option.getData(), 0, option.getData().length);
272 assertEquals(serverDuid.getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
273 assertEquals(serverDuid.getDuidTime(), 0x211e5340);
274 assertEquals(serverDuid.getHardwareType(), 1);
275 assertArrayEquals(serverDuid.getLinkLayerAddress(), SERVER_MAC.toBytes());
276 assertArrayEquals(data, eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700277 }
278
279 /**
280 * Test serialize advertise message.
281 *
282 * @throws Exception exception while serialize the DHCPv6 payload
283 */
284 @Test
285 public void serializeAdvertise() throws Exception {
286 DHCP6 dhcp6 = new DHCP6();
287 dhcp6.setMsgType(DHCP6.MsgType.ADVERTISE.value());
288 dhcp6.setTransactionId(XID_1);
289 List<Dhcp6Option> options = Lists.newArrayList();
290
291 // IA address
292 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
293 iaAddressOption.setIp6Address(IA_ADDRESS);
294 iaAddressOption.setPreferredLifetime(PREFFERRED_LT_SERVER);
295 iaAddressOption.setValidLifetime(VALID_LT_SERVER);
296
297 // IA NA
298 Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
299 iaNaOption.setIaId(IA_ID);
300 iaNaOption.setT1(T1_SERVER);
301 iaNaOption.setT2(T2_SERVER);
302 iaNaOption.setOptions(ImmutableList.of(iaAddressOption));
303 options.add(iaNaOption);
304
305 // Client ID
306 Dhcp6Duid duid = new Dhcp6Duid();
307 duid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
308 duid.setHardwareType((short) 1);
309 duid.setDuidTime(CLIENT_DUID_TIME);
310 duid.setLinkLayerAddress(CLIENT_MAC.toBytes());
311 Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
312 clientIdOption.setDuid(duid);
313 options.add(clientIdOption);
314
315 // Server ID
316 Dhcp6Option option = new Dhcp6Option();
317 option.setCode(DHCP6.OptionCode.SERVERID.value());
318 option.setLength((short) 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700319 Dhcp6Duid serverDuid = new Dhcp6Duid();
320 serverDuid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
321 serverDuid.setLinkLayerAddress(SERVER_MAC.toBytes());
322 serverDuid.setHardwareType((short) 1);
323 serverDuid.setDuidTime(0x211e5340);
324 option.setData(serverDuid.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700325 options.add(option);
326
327 dhcp6.setOptions(options);
328
329 Dhcp6RelayOption relayOption = new Dhcp6RelayOption();
330 relayOption.setPayload(dhcp6);
331
Yi Tsengb4fdb042017-08-07 13:32:32 -0700332 UDP udp = new UDP();
333 udp.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
334 udp.setDestinationPort(UDP.DHCP_V6_CLIENT_PORT);
335 udp.setPayload(dhcp6);
336 udp.setChecksum((short) 0xcb5a);
337
338 IPv6 ipv6 = new IPv6();
339 ipv6.setHopLimit((byte) 64);
340 ipv6.setSourceAddress(UPSTREAM_LL.toOctets());
341 ipv6.setDestinationAddress(CLIENT_LL.toOctets());
342 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
343 ipv6.setTrafficClass((byte) 0);
344 ipv6.setFlowLabel(0x000d935f);
345 ipv6.setPayload(udp);
346
347 Ethernet eth = new Ethernet();
348 eth.setDestinationMACAddress(CLIENT_MAC);
349 eth.setSourceMACAddress(UPSTREAM_MAC);
350 eth.setEtherType(Ethernet.TYPE_IPV6);
351 eth.setPayload(ipv6);
352
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700353 assertArrayEquals(Resources.toByteArray(Dhcp6RelayTest.class.getResource(ADVERTISE)),
Yi Tsengb4fdb042017-08-07 13:32:32 -0700354 eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700355 }
356
357 /**
358 * Test deserialize request message.
359 *
360 * @throws Exception exception while deserialize the DHCPv6 payload
361 */
362 @Test
363 public void deserializeRequest() throws Exception {
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700364 byte[] data = Resources.toByteArray(getClass().getResource(REQUEST));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700365 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
366 DHCP6 dhcp6 = (DHCP6) eth.getPayload().getPayload().getPayload();
Yi Tsengca34e1d2017-07-18 16:16:25 -0700367 assertEquals(dhcp6.getMsgType(), DHCP6.MsgType.REQUEST.value());
368 assertEquals(dhcp6.getTransactionId(), XID_2);
369 assertEquals(dhcp6.getOptions().size(), 5);
370
371 // Client ID
372 Dhcp6Option option = dhcp6.getOptions().get(0);
373 assertTrue(option instanceof Dhcp6ClientIdOption);
374 Dhcp6ClientIdOption clientIdOption = (Dhcp6ClientIdOption) option;
375 assertEquals(clientIdOption.getCode(), DHCP6.OptionCode.CLIENTID.value());
376 assertEquals(clientIdOption.getLength(), 14);
377 assertEquals(clientIdOption.getDuid().getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
378 assertEquals(clientIdOption.getDuid().getHardwareType(), 1);
379 assertEquals(clientIdOption.getDuid().getDuidTime(), CLIENT_DUID_TIME);
380 assertArrayEquals(clientIdOption.getDuid().getLinkLayerAddress(), CLIENT_MAC.toBytes());
381
382 // Server ID
383 option = dhcp6.getOptions().get(1);
384 assertEquals(option.getCode(), DHCP6.OptionCode.SERVERID.value());
385 assertEquals(option.getLength(), 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700386 Dhcp6Duid serverDuid =
387 Dhcp6Duid.deserializer().deserialize(option.getData(), 0, option.getData().length);
388 assertEquals(serverDuid.getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
389 assertEquals(serverDuid.getDuidTime(), 0x211e5340);
390 assertEquals(serverDuid.getHardwareType(), 1);
391 assertArrayEquals(serverDuid.getLinkLayerAddress(), SERVER_MAC.toBytes());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700392
393 // Option Request
394 option = dhcp6.getOptions().get(2);
395 assertEquals(option.getCode(), DHCP6.OptionCode.ORO.value());
396 assertEquals(option.getLength(), 8);
397 assertArrayEquals(option.getData(), new byte[]{0, 23, 0, 24, 0, 39, 0, 31});
398
399 // ELAPSED_TIME
400 option = dhcp6.getOptions().get(3);
401 assertEquals(option.getCode(), DHCP6.OptionCode.ELAPSED_TIME.value());
402 assertEquals(option.getLength(), 2);
403 assertArrayEquals(option.getData(),
404 new byte[]{0, 0});
405
406 // IA NA
407 option = dhcp6.getOptions().get(4);
408 assertTrue(option instanceof Dhcp6IaNaOption);
409 Dhcp6IaNaOption iaNaOption = (Dhcp6IaNaOption) option;
410 assertEquals(iaNaOption.getCode(), DHCP6.OptionCode.IA_NA.value());
411 assertEquals(iaNaOption.getLength(), 40);
412 assertEquals(iaNaOption.getIaId(), IA_ID);
413 assertEquals(iaNaOption.getT1(), T1_CLIENT);
414 assertEquals(iaNaOption.getT2(), T2_CLIENT);
415 assertEquals(iaNaOption.getOptions().size(), 1);
416
417 // IA Address (in IA NA)
418 assertTrue(iaNaOption.getOptions().get(0) instanceof Dhcp6IaAddressOption);
419 Dhcp6IaAddressOption iaAddressOption =
420 (Dhcp6IaAddressOption) iaNaOption.getOptions().get(0);
421 assertEquals(iaAddressOption.getIp6Address(), IA_ADDRESS);
422 assertEquals(iaAddressOption.getPreferredLifetime(), PREFFERRED_LT_REQ);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700423 assertEquals(iaAddressOption.getValidLifetime(), VALID_LT_REQ_2);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700424 assertNull(iaAddressOption.getOptions());
425
Yi Tsengb4fdb042017-08-07 13:32:32 -0700426 assertArrayEquals(data, eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700427 }
428
429 /**
430 * Test serialize request message.
431 *
432 * @throws Exception exception while serialize the DHCPv6 payload
433 */
434 @Test
435 public void serializeRequest() throws Exception {
436 DHCP6 dhcp6 = new DHCP6();
437 dhcp6.setMsgType(DHCP6.MsgType.REQUEST.value());
438 dhcp6.setTransactionId(XID_2);
439 List<Dhcp6Option> options = Lists.newArrayList();
440
441 // Client ID
442 Dhcp6Duid duid = new Dhcp6Duid();
443 duid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
444 duid.setHardwareType((short) 1);
445 duid.setDuidTime(CLIENT_DUID_TIME);
446 duid.setLinkLayerAddress(CLIENT_MAC.toBytes());
447 Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
448 clientIdOption.setDuid(duid);
449 options.add(clientIdOption);
450
451 // Server ID
452 Dhcp6Option option = new Dhcp6Option();
453 option.setCode(DHCP6.OptionCode.SERVERID.value());
454 option.setLength((short) 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700455 Dhcp6Duid serverDuid = new Dhcp6Duid();
456 serverDuid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
457 serverDuid.setLinkLayerAddress(SERVER_MAC.toBytes());
458 serverDuid.setHardwareType((short) 1);
459 serverDuid.setDuidTime(0x211e5340);
460 option.setData(serverDuid.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700461 options.add(option);
462
463 // Option request
464 option = new Dhcp6Option();
465 option.setCode(DHCP6.OptionCode.ORO.value());
466 option.setLength((short) 8);
467 option.setData(new byte[]{0, 23, 0, 24, 0, 39, 0, 31});
468 options.add(option);
469
470 // Elapsed Time
471 option = new Dhcp6Option();
472 option.setCode(DHCP6.OptionCode.ELAPSED_TIME.value());
473 option.setLength((short) 2);
474 option.setData(new byte[]{0, 0});
475 options.add(option);
476
477 // IA address
478 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
479 iaAddressOption.setIp6Address(IA_ADDRESS);
480 iaAddressOption.setPreferredLifetime(PREFFERRED_LT_REQ);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700481 iaAddressOption.setValidLifetime(VALID_LT_REQ_2);
Yi Tsengca34e1d2017-07-18 16:16:25 -0700482
483 // IA NA
484 Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
485 iaNaOption.setIaId(IA_ID);
486 iaNaOption.setT1(T1_CLIENT);
487 iaNaOption.setT2(T2_CLIENT);
488 iaNaOption.setOptions(ImmutableList.of(iaAddressOption));
489 options.add(iaNaOption);
490
491 dhcp6.setOptions(options);
492
493 Dhcp6RelayOption relayOption = new Dhcp6RelayOption();
494 relayOption.setPayload(dhcp6);
495
Yi Tsengb4fdb042017-08-07 13:32:32 -0700496 UDP udp = new UDP();
497 udp.setSourcePort(UDP.DHCP_V6_CLIENT_PORT);
498 udp.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
499 udp.setPayload(dhcp6);
500 udp.setChecksum((short) 0xffc1);
501
502 IPv6 ipv6 = new IPv6();
503 ipv6.setHopLimit((byte) 1);
504 ipv6.setSourceAddress(CLIENT_LL.toOctets());
505 ipv6.setDestinationAddress(DHCP6_BRC.toOctets());
506 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
507 ipv6.setTrafficClass((byte) 0);
508 ipv6.setFlowLabel(0x000322ad);
509 ipv6.setPayload(udp);
510
511 Ethernet eth = new Ethernet();
512 eth.setDestinationMACAddress(IPV6_MCAST);
513 eth.setSourceMACAddress(CLIENT_MAC);
514 eth.setEtherType(Ethernet.TYPE_IPV6);
515 eth.setPayload(ipv6);
516
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700517 assertArrayEquals(Resources.toByteArray(Dhcp6RelayTest.class.getResource(REQUEST)),
Yi Tsengb4fdb042017-08-07 13:32:32 -0700518 eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700519 }
520
521 /**
522 * Test deserialize relay message with reply message.
523 *
524 * @throws Exception exception while deserialize the DHCPv6 payload
525 */
526 @Test
527 public void deserializeReply() throws Exception {
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700528 byte[] data = Resources.toByteArray(getClass().getResource(REPLY));
Yi Tsengb4fdb042017-08-07 13:32:32 -0700529 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
530 DHCP6 dhcp6 = (DHCP6) eth.getPayload().getPayload().getPayload();
Yi Tsengca34e1d2017-07-18 16:16:25 -0700531 assertEquals(dhcp6.getMsgType(), DHCP6.MsgType.REPLY.value());
532 assertEquals(dhcp6.getTransactionId(), XID_2);
533 assertEquals(dhcp6.getOptions().size(), 3);
534
535 // IA NA
536 Dhcp6Option option = dhcp6.getOptions().get(0);
537 assertTrue(option instanceof Dhcp6IaNaOption);
538 Dhcp6IaNaOption iaNaOption = (Dhcp6IaNaOption) option;
539 assertEquals(iaNaOption.getCode(), DHCP6.OptionCode.IA_NA.value());
540 assertEquals(iaNaOption.getLength(), 40);
541 assertEquals(iaNaOption.getIaId(), IA_ID);
542 assertEquals(iaNaOption.getT1(), T1_SERVER);
543 assertEquals(iaNaOption.getT2(), T2_SERVER);
544 assertEquals(iaNaOption.getOptions().size(), 1);
545
546 // IA Address (in IA NA)
547 assertTrue(iaNaOption.getOptions().get(0) instanceof Dhcp6IaAddressOption);
548 Dhcp6IaAddressOption iaAddressOption =
549 (Dhcp6IaAddressOption) iaNaOption.getOptions().get(0);
550 assertEquals(iaAddressOption.getIp6Address(), IA_ADDRESS);
551 assertEquals(iaAddressOption.getPreferredLifetime(), PREFFERRED_LT_SERVER);
552 assertEquals(iaAddressOption.getValidLifetime(), VALID_LT_SERVER);
553 assertNull(iaAddressOption.getOptions());
554
555 // Client ID
556 option = dhcp6.getOptions().get(1);
557 assertTrue(option instanceof Dhcp6ClientIdOption);
558 Dhcp6ClientIdOption clientIdOption = (Dhcp6ClientIdOption) option;
559 assertEquals(clientIdOption.getCode(), DHCP6.OptionCode.CLIENTID.value());
560 assertEquals(clientIdOption.getLength(), 14);
561 assertEquals(clientIdOption.getDuid().getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
562 assertEquals(clientIdOption.getDuid().getHardwareType(), 1);
563 assertEquals(clientIdOption.getDuid().getDuidTime(), CLIENT_DUID_TIME);
564 assertArrayEquals(clientIdOption.getDuid().getLinkLayerAddress(), CLIENT_MAC.toBytes());
565
566 // Server ID
567 option = dhcp6.getOptions().get(2);
568 assertEquals(option.getCode(), DHCP6.OptionCode.SERVERID.value());
569 assertEquals(option.getLength(), 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700570 Dhcp6Duid serverDuid =
571 Dhcp6Duid.deserializer().deserialize(option.getData(), 0, option.getData().length);
572 assertEquals(serverDuid.getDuidType(), Dhcp6Duid.DuidType.DUID_LLT);
573 assertEquals(serverDuid.getDuidTime(), 0x211e5340);
574 assertEquals(serverDuid.getHardwareType(), 1);
575 assertArrayEquals(serverDuid.getLinkLayerAddress(), SERVER_MAC.toBytes());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700576
Yi Tsengb4fdb042017-08-07 13:32:32 -0700577 assertArrayEquals(data, eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700578 }
579
580 @Test
581 public void serializeReply() throws Exception {
582 DHCP6 dhcp6 = new DHCP6();
583 dhcp6.setMsgType(DHCP6.MsgType.REPLY.value());
584 dhcp6.setTransactionId(XID_2);
585 List<Dhcp6Option> options = Lists.newArrayList();
586
587 // IA address
588 Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
589 iaAddressOption.setIp6Address(IA_ADDRESS);
590 iaAddressOption.setPreferredLifetime(PREFFERRED_LT_SERVER);
591 iaAddressOption.setValidLifetime(VALID_LT_SERVER);
592
593 // IA NA
594 Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
595 iaNaOption.setIaId(IA_ID);
596 iaNaOption.setT1(T1_SERVER);
597 iaNaOption.setT2(T2_SERVER);
598 iaNaOption.setOptions(ImmutableList.of(iaAddressOption));
599 options.add(iaNaOption);
600
601 // Client ID
602 Dhcp6Duid duid = new Dhcp6Duid();
603 duid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
604 duid.setHardwareType((short) 1);
605 duid.setDuidTime(CLIENT_DUID_TIME);
606 duid.setLinkLayerAddress(CLIENT_MAC.toBytes());
607 Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
608 clientIdOption.setDuid(duid);
609 options.add(clientIdOption);
610
611 // Server ID
612 Dhcp6Option option = new Dhcp6Option();
613 option.setCode(DHCP6.OptionCode.SERVERID.value());
614 option.setLength((short) 14);
Yi Tsengb4fdb042017-08-07 13:32:32 -0700615 Dhcp6Duid serverDuid = new Dhcp6Duid();
616 serverDuid.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
617 serverDuid.setLinkLayerAddress(SERVER_MAC.toBytes());
618 serverDuid.setHardwareType((short) 1);
619 serverDuid.setDuidTime(0x211e5340);
620 option.setData(serverDuid.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700621 options.add(option);
622
623 dhcp6.setOptions(options);
624
625 Dhcp6RelayOption relayOption = new Dhcp6RelayOption();
626 relayOption.setPayload(dhcp6);
627
Yi Tsengb4fdb042017-08-07 13:32:32 -0700628 UDP udp = new UDP();
629 udp.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
630 udp.setDestinationPort(UDP.DHCP_V6_CLIENT_PORT);
631 udp.setPayload(dhcp6);
632 udp.setChecksum((short) 0xcb5a);
633
634 IPv6 ipv6 = new IPv6();
635 ipv6.setHopLimit((byte) 64);
636 ipv6.setSourceAddress(UPSTREAM_LL.toOctets());
637 ipv6.setDestinationAddress(CLIENT_LL.toOctets());
638 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
639 ipv6.setTrafficClass((byte) 0);
640 ipv6.setFlowLabel(0x000d935f);
641 ipv6.setPayload(udp);
642
643 Ethernet eth = new Ethernet();
644 eth.setDestinationMACAddress(CLIENT_MAC);
645 eth.setSourceMACAddress(UPSTREAM_MAC);
646 eth.setEtherType(Ethernet.TYPE_IPV6);
647 eth.setPayload(ipv6);
648
Yuta HIGUCHI7bfd6072017-08-01 16:23:50 -0700649 assertArrayEquals(Resources.toByteArray(Dhcp6RelayTest.class.getResource(REPLY)),
Yi Tsengb4fdb042017-08-07 13:32:32 -0700650 eth.serialize());
Yi Tsengca34e1d2017-07-18 16:16:25 -0700651 }
652}