blob: c2bbeb604364ec23e9ad11ec1c9eb89dd9476e67 [file] [log] [blame]
Yi Tsengb4fdb042017-08-07 13:32:32 -07001/*
2 * Copyright 2015-present Open Networking Foundation
3 *
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.io.Resources;
20import org.apache.commons.io.Charsets;
21import org.apache.commons.lang.ArrayUtils;
22import org.junit.Test;
23import org.onlab.packet.DHCP;
24import org.onlab.packet.Ethernet;
25import org.onlab.packet.Ip4Address;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.PacketTestUtils;
28
29import java.nio.ByteBuffer;
30import java.util.Arrays;
31import java.util.stream.IntStream;
32
33import static org.junit.Assert.*;
34
35/**
36 * Unit tests for DHCP class.
37 */
38public class DhcpTest {
39 private static final String DISCOVER = "dhcp_discover.bin";
40 private static final String OFFER = "dhcp_offer.bin";
41 private static final String REQUEST = "dhcp_request.bin";
42 private static final String ACK = "dhcp_ack.bin";
43 private static final String LONG_OPT = "dhcp_long_opt.bin";
44 private static final String EMPTY = "";
45 private static final byte HW_TYPE = 1;
46 private static final byte HW_ADDR_LEN = 6;
47 private static final byte HOPS = 1;
48 private static final int XID = 0x8f5a186c;
49 private static final short SECS = 0;
50 private static final short FLAGS = 0;
51 private static final int NO_IP = 0;
52 private static final Ip4Address GW_IP = Ip4Address.valueOf("10.0.4.254");
53 private static final Ip4Address SERVER_IP = Ip4Address.valueOf("10.0.99.3");
54 private static final MacAddress CLIENT_HW_ADDR = MacAddress.valueOf("00:aa:00:00:00:01");
55 private static final Ip4Address CLIENT_IP = Ip4Address.valueOf("10.0.4.1");
56 private static final Ip4Address DNS_1 = Ip4Address.valueOf("8.8.8.8");
57 private static final Ip4Address DNS_2 = Ip4Address.valueOf("8.8.4.4");
58 private static final Ip4Address SUBNET_MASK = Ip4Address.valueOf("255.255.255.0");
59 private static final String HOSTNAME = "charlie-n";
60 private static final String CIRCUIT_ID = "relay-eth0";
61 private static final String DOMAIN_NAME = "trellis.local";
62
63 @Test
64 public void testDeserializeBadInput() throws Exception {
65 PacketTestUtils.testDeserializeBadInput(DHCP.deserializer());
66 }
67
68 @Test
69 public void testDeserializeTruncated() throws Exception {
70 byte[] byteHeader = ByteBuffer.allocate(241)
71 .put((byte) 0x01) // op code
72 .put((byte) 0x01) // hardware type
73 .put((byte) 0x06) // hardware address len
74 .put((byte) 0x00) // hops
75 .putInt(0x3e8) // transaction id
76 .putShort((short) 0x0) // seconds
77 .putShort((short) 0x0) // flags
78 .putInt(0) // client ip
79 .putInt(0) // your ip
80 .putInt(0) // server ip
81 .putInt(0) // gateway ip
82 .put(MacAddress.valueOf("1a:1a:1a:1a:1a:1a").toBytes()) // client hardware address
83 .put(new byte[10]) // pad
84 .put(new byte[64]) // server name
85 .put(new byte[128]) // boot file name
86 .putInt(0x63825363) // magic cookie
87 .put((byte) 0xff) // end of options
88 .array();
89 PacketTestUtils.testDeserializeTruncated(DHCP.deserializer(), byteHeader);
90 }
91
92 /**
93 * Tests deserialize discover packet.
94 */
95 @Test
96 public void testDeserializeDiscover() throws Exception {
97 byte[] data = Resources.toByteArray(Dhcp6RelayTest.class.getResource(DISCOVER));
98 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
99 DHCP dhcp = (DHCP) eth.getPayload().getPayload().getPayload();
100
101 assertEquals(DHCP.OPCODE_REQUEST, dhcp.getOpCode());
102 assertEquals(HW_TYPE, dhcp.getHardwareType());
103 assertEquals(HW_ADDR_LEN, dhcp.getHardwareAddressLength());
104 assertEquals(HOPS, dhcp.getHops());
105 assertEquals(XID, dhcp.getTransactionId());
106 assertEquals(SECS, dhcp.getSeconds());
107 assertEquals(FLAGS, dhcp.getFlags());
108 assertEquals(NO_IP, dhcp.getClientIPAddress());
109 assertEquals(NO_IP, dhcp.getYourIPAddress());
110 assertEquals(NO_IP, dhcp.getServerIPAddress());
111 assertEquals(GW_IP.toInt(), dhcp.getGatewayIPAddress());
112 assertTrue(Arrays.equals(CLIENT_HW_ADDR.toBytes(), dhcp.getClientHardwareAddress()));
113 assertEquals(EMPTY, dhcp.getServerName());
114 assertEquals(EMPTY, dhcp.getBootFileName());
115 assertEquals(6, dhcp.getOptions().size());
116
117 DhcpOption option = dhcp.getOptions().get(0);
118 assertEquals(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue(), option.code);
119 assertEquals(1, option.length);
120 assertEquals(DHCP.MsgType.DHCPDISCOVER.getValue(), (int) option.getData()[0]);
121
122 option = dhcp.getOptions().get(1);
123 assertEquals(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue(), option.code);
124 assertEquals(4, option.length);
125 assertArrayEquals(CLIENT_IP.toOctets(), option.getData());
126
127 option = dhcp.getOptions().get(2);
128 assertEquals(DHCP.DHCPOptionCode.OptionCode_HostName.getValue(), option.code);
129 assertEquals(9, option.length);
130 assertArrayEquals(HOSTNAME.getBytes(Charsets.US_ASCII), option.getData());
131
132 option = dhcp.getOptions().get(3);
133 assertEquals(DHCP.DHCPOptionCode.OptionCode_RequestedParameters.getValue(),
134 option.code);
135 assertEquals(13, option.length);
136 assertArrayEquals(new byte[]{1, 28, 2, 3, 15, 6, 119, 12, 44, 47, 26, 121, 42},
137 option.getData());
138
139 option = dhcp.getOptions().get(4);
140 assertTrue(option instanceof DhcpRelayAgentOption);
141 DhcpRelayAgentOption relayAgentOption = (DhcpRelayAgentOption) option;
142 assertEquals(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue(), relayAgentOption.code);
143 assertEquals(12, relayAgentOption.length);
144 DhcpOption subOption = relayAgentOption
145 .getSubOption(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
146 assertEquals(10, subOption.getLength());
147 assertArrayEquals(CIRCUIT_ID.getBytes(Charsets.US_ASCII), subOption.getData());
148
149 option = dhcp.getOptions().get(5);
150 assertEquals(DHCP.DHCPOptionCode.OptionCode_END.getValue(), option.code);
151 assertEquals(0, option.length);
152 }
153
154 /**
155 * Tests deserialize discover packet.
156 */
157 @Test
158 public void testDeserializeOffer() throws Exception {
159 byte[] data = Resources.toByteArray(Dhcp6RelayTest.class.getResource(OFFER));
160 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
161 DHCP dhcp = (DHCP) eth.getPayload().getPayload().getPayload();
162
163 assertEquals(DHCP.OPCODE_REPLY, dhcp.getOpCode());
164 assertEquals(HW_TYPE, dhcp.getHardwareType());
165 assertEquals(HW_ADDR_LEN, dhcp.getHardwareAddressLength());
166 assertEquals(HOPS, dhcp.getHops());
167 assertEquals(XID, dhcp.getTransactionId());
168 assertEquals(SECS, dhcp.getSeconds());
169 assertEquals(FLAGS, dhcp.getFlags());
170 assertEquals(NO_IP, dhcp.getClientIPAddress());
171 assertEquals(CLIENT_IP.toInt(), dhcp.getYourIPAddress());
172 assertEquals(SERVER_IP.toInt(), dhcp.getServerIPAddress());
173 assertEquals(GW_IP.toInt(), dhcp.getGatewayIPAddress());
174 assertTrue(Arrays.equals(CLIENT_HW_ADDR.toBytes(), dhcp.getClientHardwareAddress()));
175 assertEquals(EMPTY, dhcp.getServerName());
176 assertEquals(EMPTY, dhcp.getBootFileName());
177 assertEquals(9, dhcp.getOptions().size());
178
179 DhcpOption option = dhcp.getOptions().get(0);
180 assertEquals(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue(), option.code);
181 assertEquals(1, option.length);
182 assertEquals(DHCP.MsgType.DHCPOFFER.getValue(), (int) option.getData()[0]);
183
184 option = dhcp.getOptions().get(1);
185 assertEquals(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue(), option.code);
186 assertEquals(4, option.length);
187 assertArrayEquals(SERVER_IP.toOctets(), option.getData());
188
189 option = dhcp.getOptions().get(2);
190 assertEquals(DHCP.DHCPOptionCode.OptionCode_LeaseTime.getValue(), option.code);
191 assertEquals(4, option.length);
192 assertArrayEquals(new byte[]{0, 0, 2, 88}, option.getData());
193
194 option = dhcp.getOptions().get(3);
195 assertEquals(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue(), option.code);
196 assertEquals(4, option.length);
197 assertArrayEquals(SUBNET_MASK.toOctets(), option.getData());
198
199 option = dhcp.getOptions().get(4);
200 assertEquals(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue(), option.code);
201 assertEquals(4, option.length);
202 assertArrayEquals(GW_IP.toOctets(), option.getData());
203
204 option = dhcp.getOptions().get(5);
205 assertEquals(DHCP.DHCPOptionCode.OptionCode_DomainName.getValue(), option.code);
206 assertEquals(13, option.length);
207 assertArrayEquals(DOMAIN_NAME.getBytes(Charsets.US_ASCII), option.getData());
208
209 option = dhcp.getOptions().get(6);
210 assertEquals(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue(), option.code);
211 assertEquals(8, option.length);
212 assertArrayEquals(ArrayUtils.addAll(DNS_1.toOctets(), DNS_2.toOctets()),
213 option.getData());
214
215 option = dhcp.getOptions().get(7);
216 assertTrue(option instanceof DhcpRelayAgentOption);
217 DhcpRelayAgentOption relayAgentOption = (DhcpRelayAgentOption) option;
218 assertEquals(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue(), relayAgentOption.code);
219 assertEquals(12, relayAgentOption.length);
220 DhcpOption subOption = relayAgentOption
221 .getSubOption(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
222 assertEquals(10, subOption.getLength());
223 assertArrayEquals(CIRCUIT_ID.getBytes(Charsets.US_ASCII), subOption.getData());
224
225 option = dhcp.getOptions().get(8);
226 assertEquals(DHCP.DHCPOptionCode.OptionCode_END.getValue(), option.code);
227 assertEquals(0, option.length);
228 }
229
230 /**
231 * Tests deserialize discover packet.
232 */
233 @Test
234 public void testDeserializeRequest() throws Exception {
235 byte[] data = Resources.toByteArray(Dhcp6RelayTest.class.getResource(REQUEST));
236 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
237 DHCP dhcp = (DHCP) eth.getPayload().getPayload().getPayload();
238
239 assertEquals(DHCP.OPCODE_REQUEST, dhcp.getOpCode());
240 assertEquals(HW_TYPE, dhcp.getHardwareType());
241 assertEquals(HW_ADDR_LEN, dhcp.getHardwareAddressLength());
242 assertEquals(HOPS, dhcp.getHops());
243 assertEquals(XID, dhcp.getTransactionId());
244 assertEquals(SECS, dhcp.getSeconds());
245 assertEquals(FLAGS, dhcp.getFlags());
246 assertEquals(NO_IP, dhcp.getClientIPAddress());
247 assertEquals(NO_IP, dhcp.getYourIPAddress());
248 assertEquals(NO_IP, dhcp.getServerIPAddress());
249 assertEquals(GW_IP.toInt(), dhcp.getGatewayIPAddress());
250 assertTrue(Arrays.equals(CLIENT_HW_ADDR.toBytes(), dhcp.getClientHardwareAddress()));
251 assertEquals(EMPTY, dhcp.getServerName());
252 assertEquals(EMPTY, dhcp.getBootFileName());
253 assertEquals(7, dhcp.getOptions().size());
254
255 DhcpOption option = dhcp.getOptions().get(0);
256 assertEquals(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue(), option.code);
257 assertEquals(1, option.length);
258 assertEquals(DHCP.MsgType.DHCPREQUEST.getValue(), (int) option.getData()[0]);
259
260 option = dhcp.getOptions().get(1);
261 assertEquals(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue(), option.code);
262 assertEquals(4, option.length);
263 assertArrayEquals(SERVER_IP.toOctets(), option.getData());
264
265 option = dhcp.getOptions().get(2);
266 assertEquals(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue(), option.code);
267 assertEquals(4, option.length);
268 assertArrayEquals(CLIENT_IP.toOctets(), option.getData());
269
270 option = dhcp.getOptions().get(3);
271 assertEquals(DHCP.DHCPOptionCode.OptionCode_HostName.getValue(), option.code);
272 assertEquals(9, option.length);
273 assertArrayEquals(HOSTNAME.getBytes(Charsets.US_ASCII), option.getData());
274
275 option = dhcp.getOptions().get(4);
276 assertEquals(DHCP.DHCPOptionCode.OptionCode_RequestedParameters.getValue(),
277 option.code);
278 assertEquals(13, option.length);
279 assertArrayEquals(new byte[]{1, 28, 2, 3, 15, 6, 119, 12, 44, 47, 26, 121, 42},
280 option.getData());
281
282 option = dhcp.getOptions().get(5);
283 assertTrue(option instanceof DhcpRelayAgentOption);
284 DhcpRelayAgentOption relayAgentOption = (DhcpRelayAgentOption) option;
285 assertEquals(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue(), relayAgentOption.code);
286 assertEquals(12, relayAgentOption.length);
287 DhcpOption subOption = relayAgentOption
288 .getSubOption(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
289 assertEquals(10, subOption.getLength());
290 assertArrayEquals(CIRCUIT_ID.getBytes(Charsets.US_ASCII), subOption.getData());
291
292 option = dhcp.getOptions().get(6);
293 assertEquals(DHCP.DHCPOptionCode.OptionCode_END.getValue(), option.code);
294 assertEquals(0, option.length);
295 }
296
297 /**
298 * Tests deserialize discover packet.
299 */
300 @Test
301 public void testDeserializeAck() throws Exception {
302 byte[] data = Resources.toByteArray(Dhcp6RelayTest.class.getResource(ACK));
303 Ethernet eth = Ethernet.deserializer().deserialize(data, 0, data.length);
304 DHCP dhcp = (DHCP) eth.getPayload().getPayload().getPayload();
305
306 assertEquals(DHCP.OPCODE_REPLY, dhcp.getOpCode());
307 assertEquals(HW_TYPE, dhcp.getHardwareType());
308 assertEquals(HW_ADDR_LEN, dhcp.getHardwareAddressLength());
309 assertEquals(HOPS, dhcp.getHops());
310 assertEquals(XID, dhcp.getTransactionId());
311 assertEquals(SECS, dhcp.getSeconds());
312 assertEquals(FLAGS, dhcp.getFlags());
313 assertEquals(NO_IP, dhcp.getClientIPAddress());
314 assertEquals(CLIENT_IP.toInt(), dhcp.getYourIPAddress());
315 assertEquals(SERVER_IP.toInt(), dhcp.getServerIPAddress());
316 assertEquals(GW_IP.toInt(), dhcp.getGatewayIPAddress());
317 assertTrue(Arrays.equals(CLIENT_HW_ADDR.toBytes(), dhcp.getClientHardwareAddress()));
318 assertEquals(EMPTY, dhcp.getServerName());
319 assertEquals(EMPTY, dhcp.getBootFileName());
320 assertEquals(9, dhcp.getOptions().size());
321
322 DhcpOption option = dhcp.getOptions().get(0);
323 assertEquals(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue(), option.code);
324 assertEquals(1, option.length);
325 assertEquals(DHCP.MsgType.DHCPACK.getValue(), (int) option.getData()[0]);
326
327 option = dhcp.getOptions().get(1);
328 assertEquals(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue(), option.code);
329 assertEquals(4, option.length);
330 assertArrayEquals(SERVER_IP.toOctets(), option.getData());
331
332 option = dhcp.getOptions().get(2);
333 assertEquals(DHCP.DHCPOptionCode.OptionCode_LeaseTime.getValue(), option.code);
334 assertEquals(4, option.length);
335 assertArrayEquals(new byte[]{0, 0, 2, 88}, option.getData());
336
337 option = dhcp.getOptions().get(3);
338 assertEquals(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue(), option.code);
339 assertEquals(4, option.length);
340 assertArrayEquals(SUBNET_MASK.toOctets(), option.getData());
341
342 option = dhcp.getOptions().get(4);
343 assertEquals(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue(), option.code);
344 assertEquals(4, option.length);
345 assertArrayEquals(GW_IP.toOctets(), option.getData());
346
347 option = dhcp.getOptions().get(5);
348 assertEquals(DHCP.DHCPOptionCode.OptionCode_DomainName.getValue(), option.code);
349 assertEquals(13, option.length);
350 assertArrayEquals(DOMAIN_NAME.getBytes(Charsets.US_ASCII), option.getData());
351
352 option = dhcp.getOptions().get(6);
353 assertEquals(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue(), option.code);
354 assertEquals(8, option.length);
355 assertArrayEquals(ArrayUtils.addAll(DNS_1.toOctets(), DNS_2.toOctets()),
356 option.getData());
357
358 option = dhcp.getOptions().get(7);
359 assertTrue(option instanceof DhcpRelayAgentOption);
360 DhcpRelayAgentOption relayAgentOption = (DhcpRelayAgentOption) option;
361 assertEquals(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue(), relayAgentOption.code);
362 assertEquals(12, relayAgentOption.length);
363 DhcpOption subOption = relayAgentOption
364 .getSubOption(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
365 assertEquals(10, subOption.getLength());
366 assertArrayEquals(CIRCUIT_ID.getBytes(Charsets.US_ASCII), subOption.getData());
367
368 option = dhcp.getOptions().get(8);
369 assertEquals(DHCP.DHCPOptionCode.OptionCode_END.getValue(), option.code);
370 assertEquals(0, option.length);
371 }
372
373 /**
374 * Test option with option length > 128.
375 */
376 @Test
377 public void longOptionTest() throws Exception {
378 byte[] data = Resources.toByteArray(Dhcp6RelayTest.class.getResource(LONG_OPT));
379 DHCP dhcp = DHCP.deserializer().deserialize(data, 0, data.length);
380 assertEquals(2, dhcp.getOptions().size());
381 DhcpOption hostnameOption = dhcp.getOption(DHCP.DHCPOptionCode.OptionCode_HostName);
382 DhcpOption endOption = dhcp.getOption(DHCP.DHCPOptionCode.OptionCode_END);
383 assertNotNull(hostnameOption);
384 assertNotNull(endOption);
385
386 // Host name contains 200 "A"
387 StringBuilder hostnameBuilder = new StringBuilder();
388 IntStream.range(0, 200).forEach(i -> hostnameBuilder.append("A"));
389 String hostname = hostnameBuilder.toString();
390
391 assertEquals((byte) 200, hostnameOption.getLength());
392 assertArrayEquals(hostname.getBytes(Charsets.US_ASCII), hostnameOption.getData());
393 }
394}