Skip to content
Snippets Groups Projects
Commit 23862a21 authored by Shudong Zhou's avatar Shudong Zhou
Browse files

Add BSN probe packet

parent 71599cdb
No related branches found
No related tags found
No related merge requests found
/**
* Copyright 2012, Big Switch Networks, Inc.
*
* 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 net.floodlightcontroller.packet;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
/**
* @author Shudong Zhou (shudong.zhou@bigswitch.com)
*
*/
public class BSN extends BasePacket {
public static final int BSN_MAGIC = 0x20000604;
public static final short BSN_VERSION_CURRENT = 0x0;
public static final short BSN_TYPE_PROBE = 0x1;
public static Map<Short, Class<? extends IPacket>> typeClassMap;
static {
typeClassMap = new HashMap<Short, Class<? extends IPacket>>();
typeClassMap.put(BSN_TYPE_PROBE, BSNPROBE.class);
}
protected short type;
protected short version;
public BSN() {
version = BSN_VERSION_CURRENT;
}
public BSN(short type) {
this.type = type;
version = BSN_VERSION_CURRENT;
}
public short getType() {
return type;
}
public BSN setType(short type) {
this.type = type;
return this;
}
public short getVersion() {
return version;
}
public BSN setVersion(short version) {
this.version = version;
return this;
}
@Override
public byte[] serialize() {
short length = 4 /* magic */ + 2 /* type */ + 2 /* version */;
byte[] payloadData = null;
if (this.payload != null) {
payload.setParent(this);
payloadData = payload.serialize();
length += payloadData.length;
}
byte[] data = new byte[length];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.putInt(BSN_MAGIC);
bb.putShort(this.type);
bb.putShort(this.version);
if (payloadData != null)
bb.put(payloadData);
if (this.parent != null && this.parent instanceof Ethernet)
((Ethernet)this.parent).setEtherType(Ethernet.TYPE_BSN);
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
int magic = bb.getInt();
if (magic != BSN_MAGIC) {
throw new RuntimeException("Invalid BSN magic " + magic);
}
this.type = bb.getShort();
this.version = bb.getShort();
if (this.version != BSN_VERSION_CURRENT) {
throw new RuntimeException(
"Invalid BSN packet version " + this.version + ", should be "
+ BSN_VERSION_CURRENT);
}
IPacket payload;
if (typeClassMap.containsKey(this.type)) {
Class<? extends IPacket> clazz = typeClassMap.get(this.type);
try {
payload = clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException("Error parsing payload for BSN packet" + e);
}
} else {
payload = new Data();
}
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 = 883;
int result = super.hashCode();
result = prime * result + version;
result = prime * result + type;
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 BSN))
return false;
BSN other = (BSN) obj;
return (type == other.type &&
version == other.version);
}
public String toString() {
StringBuffer sb = new StringBuffer("\n");
sb.append("BSN packet");
if (typeClassMap.containsKey(this.type))
sb.append(" type: " + typeClassMap.get(this.type).getCanonicalName());
else
sb.append(" type: " + this.type);
return sb.toString();
}
}
/**
* Copyright 2012, Big Switch Networks, Inc.
*
* 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 net.floodlightcontroller.packet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.openflow.util.HexString;
/**
* @author Shudong Zhou (shudong.zhou@bigswitch.com)
*
*/
public class BSNPROBE extends BasePacket {
protected long controllerId;
protected int sequenceId;
protected byte[] srcMac;
protected byte[] dstMac;
protected long srcSwDpid;
protected int srcPortNo;
public BSNPROBE() {
srcMac = new byte[6];
dstMac = new byte[6];
}
public long getControllerId() {
return this.controllerId;
}
public BSNPROBE setControllerId(long controllerId) {
this.controllerId = controllerId;
return this;
}
public int getSequenceId() {
return sequenceId;
}
public BSNPROBE setSequenceId(int sequenceId) {
this.sequenceId = sequenceId;
return this;
}
public byte[] getSrcMac() {
return this.srcMac;
}
public BSNPROBE setSrcMac(byte[] srcMac) {
this.srcMac = srcMac;
return this;
}
public byte[] getDstMac() {
return dstMac;
}
public BSNPROBE setDstMac(byte[] dstMac) {
this.dstMac = dstMac;
return this;
}
public long getSrcSwDpid() {
return srcSwDpid;
}
public BSNPROBE setSrcSwDpid(long srcSwDpid) {
this.srcSwDpid = srcSwDpid;
return this;
}
public int getSrcPortNo() {
return srcPortNo;
}
public BSNPROBE setSrcPortNo(int srcPortNo) {
this.srcPortNo = srcPortNo;
return this;
}
@Override
public byte[] serialize() {
short length = 8 /* controllerId */ + 4 /* seqId */
+ 12 /* srcMac dstMac */ + 8 /* srcSwDpid */ + 4 /* srcPortNo */;
byte[] payloadData = null;
if (this.payload != null) {
payload.setParent(this);
payloadData = payload.serialize();
length += payloadData.length;
}
byte[] data = new byte[length];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.putLong(this.controllerId);
bb.putInt(this.sequenceId);
bb.put(this.srcMac);
bb.put(this.dstMac);
bb.putLong(this.srcSwDpid);
bb.putInt(this.srcPortNo);
if (payloadData != null)
bb.put(payloadData);
if (this.parent != null && this.parent instanceof BSN)
((BSN)this.parent).setType(BSN.BSN_TYPE_PROBE);
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
controllerId = bb.getLong();
sequenceId = bb.getInt();
bb.get(this.srcMac, 0, 6);
bb.get(this.dstMac, 0, 6);
this.srcSwDpid = bb.getLong();
this.srcPortNo = bb.getInt();
if (bb.hasRemaining()) {
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 = 883;
int result = super.hashCode();
result = prime * result + srcMac.hashCode();
result = prime * result + dstMac.hashCode();
result = prime * result + (int) (srcSwDpid >> 32) + (int) srcSwDpid;
result = prime * result + srcPortNo;
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 BSNPROBE))
return false;
BSNPROBE other = (BSNPROBE) obj;
if (!Arrays.equals(srcMac, other.srcMac))
return false;
if (!Arrays.equals(dstMac, other.dstMac))
return false;
return (sequenceId == other.sequenceId &&
srcSwDpid == other.srcSwDpid &&
srcPortNo == other.srcPortNo
);
}
public String toString() {
StringBuffer sb = new StringBuffer("\n");
sb.append("BSN Probe packet");
sb.append("\nSource Mac: ");
sb.append(HexString.toHexString(srcMac));
sb.append("\nDestination Mac: ");
sb.append(HexString.toHexString(dstMac));
sb.append("\nSource Switch: ");
sb.append(HexString.toHexString(srcSwDpid));
sb.append(" port: " + srcPortNo);
sb.append("\nSequence No.:" + sequenceId);
return sb.toString();
}
}
......@@ -34,6 +34,7 @@ public class Ethernet extends BasePacket {
public static final short TYPE_ARP = 0x0806;
public static final short TYPE_IPv4 = 0x0800;
public static final short TYPE_LLDP = (short) 0x88cc;
public static final short TYPE_BSN = (short) 0x8950; // Not officially assigned
public static final short VLAN_UNTAGGED = (short)0xffff;
public static final short TYPE_BDDP = (short) 0x01ab;
public static Map<Short, Class<? extends IPacket>> etherTypeClassMap;
......@@ -44,6 +45,7 @@ public class Ethernet extends BasePacket {
etherTypeClassMap.put(TYPE_IPv4, IPv4.class);
etherTypeClassMap.put(TYPE_LLDP, LLDP.class);
etherTypeClassMap.put(TYPE_BDDP, BDDP.class);
etherTypeClassMap.put(TYPE_BSN, BSN.class);
}
protected MACAddress destinationMACAddress;
......
/**
* 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
*
* 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 net.floodlightcontroller.packet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import org.junit.Test;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*
*/
public class BSNTest {
protected byte[] probePkt = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // src mac
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, // dst mac
(byte) 0x89, 0x50, // BSN type
0x20, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, // BSN header
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // controller id
0x00, 0x00, 0x00, 0x03, // sequence id
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // src mac
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, // dst mac
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, // switch dpid
0x00, 0x00, 0x00, 0x01 // port number
};
protected Ethernet getProbePacket() {
return (Ethernet) new Ethernet()
.setSourceMACAddress("00:00:00:00:00:04")
.setDestinationMACAddress("00:00:00:00:00:01")
.setEtherType(Ethernet.TYPE_BSN)
.setPayload(new BSN(BSN.BSN_TYPE_PROBE)
.setPayload(new BSNPROBE()
.setSequenceId(3)
.setSrcMac(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x01})
.setDstMac(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x04})
.setSrcSwDpid(0x06)
.setSrcPortNo(0x01)
)
);
}
@Test
public void testSerialize() throws Exception {
Ethernet pkt = getProbePacket();
byte[] serialized = pkt.serialize();
assertTrue(Arrays.equals(probePkt, serialized));
}
@Test
public void testDeserialize() throws Exception {
Ethernet pkt = (Ethernet) new Ethernet().deserialize(probePkt, 0, probePkt.length);
assertTrue(Arrays.equals(probePkt, pkt.serialize()));
Ethernet expected = getProbePacket();
assertEquals(expected, 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