diff --git a/src/main/java/net/floodlightcontroller/packet/BasePacket.java b/src/main/java/net/floodlightcontroller/packet/BasePacket.java index 6df676d6bf5eb3e74eb0b14e9d3ea6189636fd6b..4ecfdedddd813b1fbd42a3ad1a2dbc48eafc45ed 100644 --- a/src/main/java/net/floodlightcontroller/packet/BasePacket.java +++ b/src/main/java/net/floodlightcontroller/packet/BasePacket.java @@ -29,6 +29,7 @@ public abstract class BasePacket implements IPacket { /** * @return the parent */ + @Override public IPacket getParent() { return parent; } @@ -36,6 +37,7 @@ public abstract class BasePacket implements IPacket { /** * @param parent the parent to set */ + @Override public IPacket setParent(IPacket parent) { this.parent = parent; return this; @@ -44,6 +46,7 @@ public abstract class BasePacket implements IPacket { /** * @return the payload */ + @Override public IPacket getPayload() { return payload; } @@ -51,10 +54,17 @@ public abstract class BasePacket implements IPacket { /** * @param payload the payload to set */ + @Override public IPacket setPayload(IPacket payload) { this.payload = payload; return this; } + + @Override + public void resetChecksum() { + if (this.parent != null) + this.parent.resetChecksum(); + } /* (non-Javadoc) * @see java.lang.Object#hashCode() diff --git a/src/main/java/net/floodlightcontroller/packet/DHCP.java b/src/main/java/net/floodlightcontroller/packet/DHCP.java index 2001b4ff9dca8de0e0838aeb6647966747e744d8..f73d9c968019ab99ebfb4d5712c0e2a95a01e297 100644 --- a/src/main/java/net/floodlightcontroller/packet/DHCP.java +++ b/src/main/java/net/floodlightcontroller/packet/DHCP.java @@ -355,6 +355,9 @@ public class DHCP extends BasePacket { @Override public byte[] serialize() { + // not guaranteed to retain length/exact format + resetChecksum(); + // minimum size 240 including magic cookie, options generally padded to 300 int optionsLength = 0; for (DHCPOption option : this.options) { diff --git a/src/main/java/net/floodlightcontroller/packet/IPacket.java b/src/main/java/net/floodlightcontroller/packet/IPacket.java index 094cfc700a10a4aab4d1ca7531333aed3309ace9..02376cd990cbd1c1980b78bb7815323a46480cf2 100644 --- a/src/main/java/net/floodlightcontroller/packet/IPacket.java +++ b/src/main/java/net/floodlightcontroller/packet/IPacket.java @@ -48,6 +48,11 @@ public interface IPacket { */ public IPacket setParent(IPacket packet); + /** + * Reset any checksums as needed, and call resetChecksum on all parents + */ + public void resetChecksum(); + /** * Sets all payloads parent packet if applicable, then serializes this * packet and all payloads diff --git a/src/main/java/net/floodlightcontroller/packet/IPv4.java b/src/main/java/net/floodlightcontroller/packet/IPv4.java index ccfce792b3271d2aff56aee32b816d2ea45d6277..01f886da252bd59fa641f56b4684a0ce28087fdb 100644 --- a/src/main/java/net/floodlightcontroller/packet/IPv4.java +++ b/src/main/java/net/floodlightcontroller/packet/IPv4.java @@ -209,6 +209,11 @@ public class IPv4 extends BasePacket { this.checksum = checksum; return this; } + @Override + public void resetChecksum() { + this.checksum = 0; + super.resetChecksum(); + } /** * @return the sourceAddress diff --git a/src/main/java/net/floodlightcontroller/packet/TCP.java b/src/main/java/net/floodlightcontroller/packet/TCP.java index 5fc6279bc76f2d3aa66949c8b8f77b5a915e517d..889e4c6a88292d3e2ea704aa3b49e38e93054fdd 100644 --- a/src/main/java/net/floodlightcontroller/packet/TCP.java +++ b/src/main/java/net/floodlightcontroller/packet/TCP.java @@ -114,6 +114,13 @@ public class TCP extends BasePacket { this.checksum = checksum; return this; } + + @Override + public void resetChecksum() { + this.checksum = 0; + super.resetChecksum(); + } + public short getUrgentPointer(short urgentPointer) { return this.urgentPointer; } diff --git a/src/main/java/net/floodlightcontroller/packet/UDP.java b/src/main/java/net/floodlightcontroller/packet/UDP.java index 66f6b63307b296ed0b93a116b4dfa52870f6d33d..cbeeedfd18add16d1f657c7930cadf4bf08da6b8 100644 --- a/src/main/java/net/floodlightcontroller/packet/UDP.java +++ b/src/main/java/net/floodlightcontroller/packet/UDP.java @@ -97,6 +97,12 @@ public class UDP extends BasePacket { return this; } + @Override + public void resetChecksum() { + this.checksum = 0; + super.resetChecksum(); + } + /** * Serializes the packet. Will compute and set the following fields if they * are set to specific values at the time serialize is called: diff --git a/src/test/java/net/floodlightcontroller/packet/DHCPTest.java b/src/test/java/net/floodlightcontroller/packet/DHCPTest.java index 1f3a48585bcfa2b949dec07570ae25e71d912949..b83ffa816e196873b00158426a0177347c92905a 100644 --- a/src/test/java/net/floodlightcontroller/packet/DHCPTest.java +++ b/src/test/java/net/floodlightcontroller/packet/DHCPTest.java @@ -216,7 +216,71 @@ public class DHCPTest extends TestCase { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; - + + public byte[] dhcpPacket3 = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0x74, (byte) 0x44, (byte) 0x01, (byte) 0x72, + (byte) 0xd8, (byte) 0x41, (byte) 0x08, (byte) 0x00, (byte) 0x45, + (byte) 0x00, (byte) 0x01, (byte) 0x1f, (byte) 0x48, (byte) 0xcd, + (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x11, (byte) 0x6f, + (byte) 0x6a, (byte) 0xc0, (byte) 0xa8, (byte) 0x00, (byte) 0xef, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, + (byte) 0x44, (byte) 0x00, (byte) 0x43, (byte) 0x01, (byte) 0x0b, + (byte) 0xb3, (byte) 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0x06, + (byte) 0x00, (byte) 0x82, (byte) 0x88, (byte) 0xa6, (byte) 0xc9, + (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x74, (byte) 0x44, (byte) 0x01, (byte) 0x72, (byte) 0xd8, + (byte) 0x41, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x63, (byte) 0x82, + (byte) 0x53, (byte) 0x63, (byte) 0x35, (byte) 0x01, (byte) 0x01, + (byte) 0x32, (byte) 0x04, (byte) 0xc0, (byte) 0xa8, (byte) 0x0a, + (byte) 0xa9, (byte) 0x39, (byte) 0x02, (byte) 0x02, (byte) 0x40, + (byte) 0x37, (byte) 0x03, (byte) 0x01, (byte) 0x03, (byte) 0x06, + (byte) 0xff + }; + public byte[] dhcpPacketPXE = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x19, (byte) 0xb9, (byte) 0xb0, (byte) 0x01, (byte) 0x44, @@ -444,6 +508,24 @@ public class DHCPTest extends TestCase { resetChecksumsAndLengths(ipv4, udp); assertEquals(DHCP.OPCODE_REQUEST, dhcp.getOpCode()); } + + public void testDeSerializeReSerialize() { + Ethernet eth = new Ethernet(); + eth.deserialize(dhcpPacket3, 0, dhcpPacket3.length); + assertTrue(eth.getPayload() instanceof IPv4); + IPv4 ipv4 = (IPv4) eth.getPayload(); + assertTrue(ipv4.getPayload() instanceof UDP); + + byte[] serializedPacket = eth.serialize(); + Ethernet eth2 = new Ethernet(); + eth2.deserialize(serializedPacket, 0, serializedPacket.length); + IPv4 ipv42 = (IPv4) eth2.getPayload(); + + short ipchecksum = ipv42.getChecksum(); + ipv42.setChecksum((short) 0); + eth2.serialize(); + assertEquals(ipchecksum, ipv42.getChecksum()); + } public void testDeSerializePXE() { Ethernet eth = new Ethernet();