Skip to content
Snippets Groups Projects
Commit 6cd8ec2e authored by Gregor Maier's avatar Gregor Maier
Browse files

Make IPacket's cloneable.

Cloning is currently implemented using serialize()/deserialize() which
isn't terribly efficient, but one an always revisit if performance
becomes an issue.
parent 1b0ff818
No related branches found
No related tags found
No related merge requests found
......@@ -17,6 +17,7 @@
package net.floodlightcontroller.packet;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
......@@ -85,4 +86,21 @@ public abstract class BasePacket implements IPacket {
return false;
return true;
}
}
@Override
public Object clone() {
IPacket pkt;
try {
pkt = this.getClass().newInstance();
} catch (Exception e) {
throw new RuntimeException("Could not clone packet");
}
// TODO: we are using serialize()/deserialize() to perform the
// cloning. Not the most efficient way but simple. We can revisit
// if we hit performance problems.
byte[] data = this.serialize();
pkt.deserialize(this.serialize(), 0, data.length);
pkt.setParent(this.parent);
return pkt;
}
}
\ No newline at end of file
......@@ -63,4 +63,10 @@ public interface IPacket {
* @return the deserialized data
*/
public IPacket deserialize(byte[] data, int offset, int length);
/** Clone this packet and its payload packet but not its parent.
*
* @return
*/
public Object clone();
}
package net.floodlightcontroller.packet;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class PacketTest {
protected IPacket pkt1, pkt2, pkt3, pkt4;
protected IPacket dummyPkt;
protected IPacket[] packets;
@Before
public void setUp() {
this.pkt1 = new Ethernet()
.setDestinationMACAddress("00:11:22:33:44:55")
.setSourceMACAddress("00:44:33:22:11:00")
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.2")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.pkt2 = new Ethernet()
.setSourceMACAddress("00:44:33:22:11:01")
.setDestinationMACAddress("00:11:22:33:44:55")
.setEtherType(Ethernet.TYPE_ARP)
.setVlanID((short)5)
.setPayload(
new ARP()
.setHardwareType(ARP.HW_TYPE_ETHERNET)
.setProtocolType(ARP.PROTO_TYPE_IP)
.setHardwareAddressLength((byte) 6)
.setProtocolAddressLength((byte) 4)
.setOpCode(ARP.OP_REPLY)
.setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
.setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
this.pkt3 = new Ethernet()
.setSourceMACAddress("00:44:33:22:11:01")
.setDestinationMACAddress("00:11:22:33:44:55")
.setEtherType(Ethernet.TYPE_ARP)
.setPayload(
new ARP()
.setHardwareType(ARP.HW_TYPE_ETHERNET)
.setProtocolType(ARP.PROTO_TYPE_IP)
.setHardwareAddressLength((byte) 6)
.setProtocolAddressLength((byte) 4)
.setOpCode(ARP.OP_REPLY)
.setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
.setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
this.pkt4 = new Ethernet()
.setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
.setSourceMACAddress("00:11:33:55:77:01")
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("192.168.10.1")
.setDestinationAddress("192.168.255.255")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.dummyPkt = new IPv4()
.setTtl((byte) 32)
.setSourceAddress("1.2.3.4")
.setDestinationAddress("5.6.7.8");
this.packets = new IPacket[] { pkt1, pkt2, pkt3, pkt4 };
}
protected void doTestClone(IPacket pkt) {
if (pkt.getPayload() != null)
doTestClone(pkt.getPayload());
IPacket newPkt = (IPacket)pkt.clone();
assertSame(pkt.getClass(), newPkt.getClass());
assertNotSame(pkt, newPkt);
assertSame(pkt.getParent(), newPkt.getParent());
assertEquals(pkt, newPkt);
assertEquals(pkt.getPayload(), newPkt.getPayload());
if (pkt.getPayload() != null)
assertNotSame(pkt.getPayload(), newPkt.getPayload());
if (pkt instanceof Ethernet) {
Ethernet eth = (Ethernet)pkt;
Ethernet newEth = (Ethernet)newPkt;
newEth.setDestinationMACAddress(new byte[] { 1,2,3,4,5,6});
assertEquals(false, newEth.getDestinationMAC()
.equals(eth.getDestinationMAC()));
assertEquals(false, newPkt.equals(pkt));
}
if (pkt instanceof ARP) {
ARP arp = (ARP)pkt;
ARP newArp = (ARP)newPkt;
newArp.setSenderProtocolAddress(new byte[] {1,2,3,4});
assertEquals(false, newArp.getSenderProtocolAddress()
.equals(arp.getSenderProtocolAddress()));
assertEquals(false, newPkt.equals(pkt));
}
byte[] dummyData = dummyPkt.serialize().clone();
newPkt = (IPacket)pkt.clone();
newPkt.deserialize(dummyData, 0, dummyData.length);
assertEquals(false, newPkt.equals(pkt));
}
@Test
public void testClone() {
for (IPacket pkt: packets) {
doTestClone(pkt);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment