Skip to content
Snippets Groups Projects
Commit 9c6750b4 authored by Ryan Izard's avatar Ryan Izard
Browse files

Merge pull request #569 from phpHavok/spud

Add support for SPUD
parents 62c62e3b 90b5a389
No related branches found
No related tags found
No related merge requests found
Showing
with 298 additions and 12 deletions
......@@ -53,13 +53,14 @@
<patternset id="lib">
<include name="logback-classic-1.0.0.jar"/>
<include name="logback-core-1.0.0.jar"/>
<include name="jackson-core-2.1.4.jar"/>
<include name="jackson-annotations-2.1.4.jar"/>
<include name="jackson-databind-2.1.4.jar"/>
<include name="jackson-dataformat-smile-2.1.4.jar"/>
<include name="jackson-dataformat-xml-2.1.4.jar"/>
<include name="jackson-dataformat-yaml-2.1.4.jar"/>
<include name="jackson-dataformat-csv-2.1.4.jar"/>
<include name="jackson-core-2.4.4.jar"/>
<include name="jackson-annotations-2.4.4.jar"/>
<include name="jackson-databind-2.4.4.jar"/>
<include name="jackson-dataformat-smile-2.4.4.jar"/>
<include name="jackson-dataformat-xml-2.4.4.jar"/>
<include name="jackson-dataformat-yaml-2.4.4.jar"/>
<include name="jackson-dataformat-csv-2.4.4.jar"/>
<include name="jackson-dataformat-cbor-2.4.4.jar"/>
<include name="slf4j-api-1.6.4.jar"/>
<include name="org.restlet.jar"/>
<include name="org.restlet.ext.jackson.jar"/>
......
File deleted
File added
File deleted
File added
File deleted
File added
File added
File deleted
File added
File deleted
File added
File deleted
File added
File deleted
File added
......@@ -219,9 +219,15 @@
<artifactId>netty</artifactId>
<version>3.9.0.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId>
<version>${lib-jackson-version}</version>
</dependency>
</dependencies>
<properties>
<lib-restlet-version>2.3.2</lib-restlet-version>
<lib-jackson-version>2.4.4</lib-jackson-version>
<lib-hamcrest-version>1.3</lib-hamcrest-version>
</properties>
</project>
package net.floodlightcontroller.packet;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* @author Jacob Chappell (jacob.chappell@uky.edu)
*/
public class SPUD extends BasePacket {
public static final byte[] MAGIC_CONSTANT =
{ (byte) 0xd8, 0x00, 0x00, (byte) 0xd8 };
public static final int HEADER_LENGTH = 13;
public static final byte COMMAND_DATA = 0x0;
public static final byte COMMAND_OPEN = 0x1;
public static final byte COMMAND_CLOSE = 0x2;
public static final byte COMMAND_ACK = 0x3;
protected long tubeID;
protected byte command;
protected boolean adec;
protected boolean pdec;
protected byte reserved;
public long getTubeID() {
return tubeID;
}
public SPUD setTubeID(long tubeID) {
this.tubeID = tubeID;
return this;
}
public byte getCommand() {
return command;
}
public SPUD setCommand(byte command) {
this.command = command;
return this;
}
public boolean getADEC() {
return adec;
}
public SPUD setADEC(boolean adec) {
this.adec = adec;
return this;
}
public boolean getPDEC() {
return pdec;
}
public SPUD setPDEC(boolean pdec) {
this.pdec = pdec;
return this;
}
public byte getReserved() {
return reserved;
}
public SPUD setReserved(byte reserved) {
this.reserved = reserved;
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (payload != null) {
payload.setParent(this);
payloadData = payload.serialize();
}
int length = HEADER_LENGTH + ((payloadData == null) ? 0 : payloadData.length);
byte[] data = new byte[length];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(MAGIC_CONSTANT);
bb.putLong(tubeID);
byte adecBit = (byte) ((adec) ? 1 : 0);
byte pdecBit = (byte) ((pdec) ? 1 : 0);
byte lastByte = (byte) (((command & 0x3) << 6) | ((adecBit & 0x1) << 5)
| ((pdecBit & 0x1) << 4) | (reserved & 0xf));
bb.put(lastByte);
if (payloadData != null) {
bb.put(payloadData);
}
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length)
throws PacketParsingException {
ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
byte[] magicConstant = new byte[MAGIC_CONSTANT.length];
bb.get(magicConstant, 0, MAGIC_CONSTANT.length);
if (!Arrays.equals(magicConstant, MAGIC_CONSTANT)) {
throw new PacketParsingException("Magic constant is incorrect.");
}
tubeID = bb.getLong();
byte lastByte = bb.get();
command = (byte) ((lastByte & 0xc0) >>> 6);
adec = ((lastByte & 0x20) != 0);
pdec = ((lastByte & 0x10) != 0);
reserved = (byte) (lastByte & 0xF);
// TODO: make sure reserved bits are 0 for this version.
this.payload = new Data();
this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
this.payload.setParent(this);
return this;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + (adec ? 1231 : 1237);
result = prime * result + command;
result = prime * result + (pdec ? 1231 : 1237);
result = prime * result + reserved;
result = prime * result + (int) (tubeID ^ (tubeID >>> 32));
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof SPUD))
return false;
SPUD other = (SPUD) obj;
if (adec != other.adec)
return false;
if (command != other.command)
return false;
if (pdec != other.pdec)
return false;
if (reserved != other.reserved)
return false;
if (tubeID != other.tubeID)
return false;
return true;
}
}
/**
* Copyright 2011, Big Switch Networks, Inc.
* Copyright 2011, Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
*
* 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
......@@ -18,6 +18,7 @@
package net.floodlightcontroller.packet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
......@@ -39,7 +40,7 @@ public class UDP extends BasePacket {
*/
UDP.decodeMap.put(DHCP_CLIENT_PORT, DHCP.class);
UDP.decodeMap.put(DHCP_SERVER_PORT, DHCP.class);
}
protected TransportPort sourcePort;
......@@ -61,7 +62,7 @@ public class UDP extends BasePacket {
this.sourcePort = sourcePort;
return this;
}
/**
* @param sourcePort the sourcePort to set
*/
......@@ -84,7 +85,7 @@ public class UDP extends BasePacket {
this.destinationPort = destinationPort;
return this;
}
/**
* @param destinationPort the destinationPort to set
*/
......@@ -227,6 +228,14 @@ public class UDP extends BasePacket {
this.destinationPort = TransportPort.of((int) (bb.getShort() & 0xffff)); // convert range 0 to 65534, not -32768 to 32767
this.length = bb.getShort();
this.checksum = bb.getShort();
// Grab a snapshot of the first four bytes of the UDP payload.
// We will use these to see if the payload is SPUD, without
// disturbing the existing byte buffer's offsets.
ByteBuffer bb_spud = bb.slice();
byte[] maybe_spud_bytes = new byte[SPUD.MAGIC_CONSTANT.length];
if (bb_spud.remaining() >= SPUD.MAGIC_CONSTANT.length) {
bb_spud.get(maybe_spud_bytes, 0, SPUD.MAGIC_CONSTANT.length);
}
if (UDP.decodeMap.containsKey(this.destinationPort)) {
try {
......@@ -240,6 +249,9 @@ public class UDP extends BasePacket {
} catch (Exception e) {
throw new RuntimeException("Failure instantiating class", e);
}
} else if (Arrays.equals(maybe_spud_bytes, SPUD.MAGIC_CONSTANT)
&& bb.remaining() >= SPUD.HEADER_LENGTH) {
this.payload = new SPUD();
} else {
this.payload = new Data();
}
......
package net.floodlightcontroller.packet;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import org.junit.Test;
/**
* @author Jacob Chappell (jacob.chappell@uky.edu)
*/
public class SPUDTest {
@Test
public void testSerializeCommandOpen() {
byte[] expected = new byte[] {
(byte) 0xd8, 0x00, 0x00, (byte) 0xd8,
(byte) 0xb6, 0x40, 0x17, (byte) 0x88,
0x0a, 0x51, 0x01, 0x07, 0x40
};
SPUD packet = (new SPUD())
.setTubeID(0xb64017880a510107L)
.setCommand(SPUD.COMMAND_OPEN)
.setADEC(false)
.setPDEC(false)
.setReserved((byte) 0);
byte[] actual = packet.serialize();
assertTrue(Arrays.equals(expected, actual));
}
@Test
public void testSerializeCommandDataEmpty() {
byte[] expected = new byte[] {
(byte) 0xd8, 0x00, 0x00, (byte) 0xd8,
(byte) 0xb6, 0x40, 0x17, (byte) 0x88,
0x0a, 0x51, 0x01, 0x07, 0x00
};
SPUD packet = (new SPUD())
.setTubeID(0xb64017880a510107L)
.setCommand(SPUD.COMMAND_DATA)
.setADEC(false)
.setPDEC(false)
.setReserved((byte) 0);
byte[] actual = packet.serialize();
assertTrue(Arrays.equals(expected, actual));
}
@Test
public void testSerializeCommandDataEmptyWithADEC() {
byte[] expected = new byte[] {
(byte) 0xd8, 0x00, 0x00, (byte) 0xd8,
(byte) 0xb6, 0x40, 0x17, (byte) 0x88,
0x0a, 0x51, 0x01, 0x07, 0x20
};
SPUD packet = (new SPUD())
.setTubeID(0xb64017880a510107L)
.setCommand(SPUD.COMMAND_DATA)
.setADEC(true)
.setPDEC(false)
.setReserved((byte) 0);
byte[] actual = packet.serialize();
assertTrue(Arrays.equals(expected, actual));
}
@Test
public void testSerializeCommandDataEmptyWithPDEC() {
byte[] expected = new byte[] {
(byte) 0xd8, 0x00, 0x00, (byte) 0xd8,
(byte) 0xb6, 0x40, 0x17, (byte) 0x88,
0x0a, 0x51, 0x01, 0x07, 0x10
};
SPUD packet = (new SPUD())
.setTubeID(0xb64017880a510107L)
.setCommand(SPUD.COMMAND_DATA)
.setADEC(false)
.setPDEC(true)
.setReserved((byte) 0);
byte[] actual = packet.serialize();
assertTrue(Arrays.equals(expected, actual));
}
@Test
public void testSerializeCommandDataEmptyWithBoth() {
byte[] expected = new byte[] {
(byte) 0xd8, 0x00, 0x00, (byte) 0xd8,
(byte) 0xb6, 0x40, 0x17, (byte) 0x88,
0x0a, 0x51, 0x01, 0x07, 0x30
};
SPUD packet = (new SPUD())
.setTubeID(0xb64017880a510107L)
.setCommand(SPUD.COMMAND_DATA)
.setADEC(true)
.setPDEC(true)
.setReserved((byte) 0);
byte[] actual = packet.serialize();
assertTrue(Arrays.equals(expected, actual));
}
@Test
public void testDeserialize() throws PacketParsingException {
byte[] spudPacket = {
(byte) 0xd8, 0x00, 0x00, (byte) 0xd8, (byte) 0xb6,
0x40, 0x17, (byte) 0x88, 0x0a, 0x51, 0x01, 0x07,
0x00, (byte) 0xa1, 0x00, (byte) 0xa2, 0x68, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x65,
0x4a, 0x61, 0x63, 0x6f, 0x62, 0x67, 0x6d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x68, 0x61,
0x73, 0x20, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64,
0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, 0x6f,
0x6d
};
SPUD packet = new SPUD();
packet.deserialize(spudPacket, 0, spudPacket.length);
byte[] packetSerialized = packet.serialize();
assertTrue(Arrays.equals(spudPacket, packetSerialized));
}
}
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