Improve the resiliency of the packet deserialization code.
Packet deserializers now check for malformed input while reading the byte
stream. Deserializers are re-implemented as functions that take a byte array
and return a packet object. The old IPacket.deserialize(...) methods have been
deprecated with the goal of eventually moving to immutable packet objects.
Unit tests have been implemented for all Deserializer functions.
ONOS-1589
Change-Id: I9073d5e6e7991e15d43830cfd810989256b71c56
diff --git a/utils/misc/src/test/java/org/onlab/packet/DhcpTest.java b/utils/misc/src/test/java/org/onlab/packet/DhcpTest.java
new file mode 100644
index 0000000..ff48331
--- /dev/null
+++ b/utils/misc/src/test/java/org/onlab/packet/DhcpTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onlab.packet;
+
+import com.google.common.base.Charsets;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Unit tests for DHCP class.
+ */
+public class DhcpTest {
+
+ private Deserializer<DHCP> deserializer = DHCP.deserializer();
+
+ private byte opCode = 1;
+ private byte hardwareType = 1;
+ private byte hardwareAddressLength = Ethernet.DATALAYER_ADDRESS_LENGTH;
+ private byte hops = 0;
+ private int transactionId = 0x2ed4eb50;
+ private short seconds = 0;
+ private short flags = 0;
+ private int clientIpAddress = 1;
+ private int yourIpAddress = 2;
+ private int serverIpAddress = 3;
+ private int gatewayIpAddress = 4;
+ private byte[] clientHardwareAddress = MacAddress.valueOf(500).toBytes();
+ private String serverName = "test-server";
+ private String bootFileName = "test-file";
+
+ private String hostName = "test-host";
+ private DHCPOption hostNameOption = new DHCPOption();
+
+ private byte[] byteHeader;
+
+ @Before
+ public void setUp() {
+ hostNameOption.setCode((byte) 55);
+ hostNameOption.setLength((byte) hostName.length());
+ hostNameOption.setData(hostName.getBytes(Charsets.US_ASCII));
+
+ // Packet length is the fixed DHCP header plus option length plus an
+ // extra byte to indicate 'end of options'.
+ ByteBuffer bb = ByteBuffer.allocate(DHCP.MIN_HEADER_LENGTH +
+ 2 + hostNameOption.getLength() + 1);
+
+ bb.put(opCode);
+ bb.put(hardwareType);
+ bb.put(hardwareAddressLength);
+ bb.put(hops);
+ bb.putInt(transactionId);
+ bb.putShort(seconds);
+ bb.putShort(flags);
+ bb.putInt(clientIpAddress);
+ bb.putInt(yourIpAddress);
+ bb.putInt(serverIpAddress);
+ bb.putInt(gatewayIpAddress);
+ bb.put(clientHardwareAddress);
+
+ // need 16 bytes of zeros to pad out the client hardware address field
+ bb.put(new byte[16 - hardwareAddressLength]);
+
+ // Put server name and pad out to 64 bytes
+ bb.put(serverName.getBytes(Charsets.US_ASCII));
+ bb.put(new byte[64 - serverName.length()]);
+
+ // Put boot file name and pad out to 128 bytes
+ bb.put(bootFileName.getBytes(Charsets.US_ASCII));
+ bb.put(new byte[128 - bootFileName.length()]);
+
+ // Magic cookie
+ bb.put("DHCP".getBytes(Charsets.US_ASCII));
+
+ bb.put(hostNameOption.getCode());
+ bb.put(hostNameOption.getLength());
+ bb.put(hostNameOption.getData());
+
+ // End of options marker
+ bb.put((byte) (0xff & 255));
+
+ byteHeader = bb.array();
+ }
+
+ @Test
+ public void testDeserializeBadInput() throws Exception {
+ PacketTestUtils.testDeserializeBadInput(deserializer);
+ }
+
+ @Test
+ public void testDeserializeTruncated() throws Exception {
+ PacketTestUtils.testDeserializeTruncated(deserializer, byteHeader);
+ }
+
+ @Test
+ public void testDeserialize() throws Exception {
+ DHCP dhcp = deserializer.deserialize(byteHeader, 0, byteHeader.length);
+
+ assertEquals(opCode, dhcp.opCode);
+ assertEquals(hardwareType, dhcp.hardwareType);
+ assertEquals(hardwareAddressLength, dhcp.hardwareAddressLength);
+ assertEquals(hops, dhcp.hops);
+ assertEquals(transactionId, dhcp.transactionId);
+ assertEquals(seconds, dhcp.seconds);
+ assertEquals(flags, dhcp.flags);
+ assertEquals(clientIpAddress, dhcp.clientIPAddress);
+ assertEquals(yourIpAddress, dhcp.yourIPAddress);
+ assertEquals(serverIpAddress, dhcp.serverIPAddress);
+ assertEquals(gatewayIpAddress, dhcp.gatewayIPAddress);
+ assertTrue(Arrays.equals(clientHardwareAddress, dhcp.clientHardwareAddress));
+
+ assertEquals(serverName, dhcp.serverName);
+ assertEquals(bootFileName, dhcp.bootFileName);
+ assertEquals(1, dhcp.options.size());
+ assertEquals(hostNameOption, dhcp.options.get(0));
+ }
+
+}