alshabib

adding packet types

Showing 34 changed files with 2504 additions and 60 deletions
......@@ -21,6 +21,10 @@
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
</dependency>
<dependency>
<groupId>org.onlab.onos</groupId>
<artifactId>onlab-misc</artifactId>
</dependency>
</dependencies>
</project>
......
......@@ -56,7 +56,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
......
package org.onlab.onos.of.controller;
import org.onlab.packet.Ethernet;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPacketOut;
import org.projectfloodlight.openflow.types.OFPort;
public class DefaultPacketContext implements PacketContext {
private boolean free = true;
private boolean isBuilt = false;
private final OpenFlowSwitch sw;
private final OFPacketIn pktin;
private final OFPacketOut pktout = null;
private DefaultPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
this.sw = s;
this.pktin = pkt;
}
@Override
public void block() {
free = false;
}
@Override
public void send() {
if (free && isBuilt) {
sw.sendMsg(pktout);
}
}
@Override
public void build(OFPort outPort) {
isBuilt = true;
}
@Override
public void build(Ethernet ethFrame, OFPort outPort) {
// TODO Auto-generated method stub
}
@Override
public Ethernet parsed() {
// TODO Auto-generated method stub
return null;
}
@Override
public Dpid dpid() {
// TODO Auto-generated method stub
return null;
}
public static PacketContext PacketContextFromPacketIn(OpenFlowSwitch s, OFPacketIn pkt) {
return new DefaultPacketContext(s, pkt);
}
}
......@@ -87,9 +87,10 @@ public interface OpenFlowController {
/**
* Process a message and notify the appropriate listeners.
*
* @param dpid the dpid the message arrived on
* @param msg the message to process.
*/
public void processPacket(OFMessage msg);
public void processPacket(Dpid dpid, OFMessage msg);
/**
* Sets the role for a given switch.
......
package org.onlab.onos.of.controller;
import org.onlab.packet.Ethernet;
import org.projectfloodlight.openflow.types.OFPort;
/**
......@@ -34,13 +35,13 @@ public interface PacketContext {
* @param ethFrame the actual packet to send out.
* @param outPort the out port to send to packet out of.
*/
public void build(Object ethFrame, OFPort outPort);
public void build(Ethernet ethFrame, OFPort outPort);
/**
* Provided a handle onto the parsed payload.
* @return the parsed form of the payload.
*/
public Object parsed();
public Ethernet parsed();
/**
* Provide the dpid of the switch where the packet in arrived.
......
......@@ -159,7 +159,7 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
*/
@Override
public final void handleMessage(OFMessage m) {
this.agent.processMessage(m);
this.agent.processMessage(dpid, m);
}
@Override
......
......@@ -69,7 +69,9 @@ public interface OpenFlowAgent {
/**
* Process a message coming from a switch.
*
* @param dpid the dpid the message came on.
* @param m the message to process
*/
public void processMessage(OFMessage m);
public void processMessage(Dpid dpid, OFMessage m);
}
......
# See: http://rolf-engelhard.de/2011/04/using-the-same-suppression-filter-for-checkstyle-in-eclipse-and-maven/
config_loc=conf/checkstyle
This diff is collapsed. Click to expand it.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN" "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<!--
Note: Exclusion definition exists in multiple places.
- In file ${findbugs.excludeFilterFile} defined at top of pom.xml
- In file conf/checkstyle/onos_suppressions.xml (this file)
- maven-pmd-plugin configuration in pom.xml
(under build and reporting)
-->
<suppress files=".*" checks="FinalParametersCheck"/>
<suppress files=".*" checks="MagicNumbersCheck"/>
<suppress files=".*" checks="DesignForExtensionCheck"/>
<suppress files=".*" checks="TodoCommentCheck"/>
<suppress files=".*" checks="AvoidInlineConditionalsCheck"/>
<suppress files=".*" checks="OperatorWrapCheck"/>
</suppressions>
<FindBugsFilter>
<!--
Note: Exclusion definition exists in multiple places.
- In file ${findbugs.excludeFilterFile} defined at top of pom.xml (this file)
- In file conf/checkstyle/onos_suppressions.xml
- maven-pmd-plugin configuration in pom.xml
(under build and reporting)
-->
<Match>
<Class name="~net\.onrc\.onos\.core\.datastore\.serializers\..*" />
</Match>
<Match>
<Class name="~.*edu\.stanford\..*"/>
</Match>
<Match>
<Class name="~.org\.projectfloodlight\..*"/>
</Match>
</FindBugsFilter>
......@@ -6,9 +6,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.of.controller.Dpid;
import org.onlab.onos.of.controller.OpenFlowController;
import org.onlab.onos.of.controller.OpenFlowSwitch;
......@@ -17,11 +15,10 @@ import org.onlab.onos.of.controller.PacketListener;
import org.onlab.onos.of.controller.RoleState;
import org.onlab.onos.of.controller.driver.OpenFlowAgent;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(immediate = true)
@Service
public class OpenFlowControllerImpl implements OpenFlowController {
private static final Logger log =
......@@ -38,6 +35,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
protected ArrayList<OpenFlowSwitchListener> ofEventListener =
new ArrayList<OpenFlowSwitchListener>();
protected ArrayList<PacketListener> ofPacketListener =
new ArrayList<PacketListener>();
private final Controller ctrl = new Controller();
@Activate
......@@ -94,14 +94,12 @@ public class OpenFlowControllerImpl implements OpenFlowController {
@Override
public void addPacketListener(int priority, PacketListener listener) {
// TODO Auto-generated method stub
ofPacketListener.add(priority, listener);
}
@Override
public void removePacketListener(PacketListener listener) {
// TODO Auto-generated method stub
ofPacketListener.remove(listener);
}
@Override
......@@ -110,8 +108,22 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
@Override
public void processPacket(OFMessage msg) {
log.info("Got message {}", msg);
public void processPacket(Dpid dpid, OFMessage msg) {
switch (msg.getType()) {
case PORT_STATUS:
for (OpenFlowSwitchListener l : ofEventListener) {
l.portChanged(dpid, (OFPortStatus) msg);
}
break;
case PACKET_IN:
for (PacketListener p : ofPacketListener) {
//TODO fix me!
p.handlePacket(null);
}
break;
default:
log.warn("Handling message type {} not yet implemented", msg.getType());
}
}
@Override
......@@ -252,8 +264,8 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
@Override
public void processMessage(OFMessage m) {
processPacket(m);
public void processMessage(Dpid dpid, OFMessage m) {
processPacket(dpid, m);
}
}
......
......@@ -22,6 +22,13 @@
<module>drivers</module>
</modules>
<dependencies>
<dependency>
<groupId>org.onlab.onos</groupId>
<artifactId>onlab-misc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
......
package org.onlab.onos.provider.of.link.impl;
import static org.slf4j.LoggerFactory.getLogger;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -11,10 +13,10 @@ import org.onlab.onos.net.link.LinkProviderService;
import org.onlab.onos.net.provider.AbstractProvider;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.of.controller.OpenFlowController;
import org.onlab.onos.of.controller.PacketContext;
import org.onlab.onos.of.controller.PacketListener;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Provider which uses an OpenFlow controller to detect network
* infrastructure links.
......@@ -32,6 +34,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
private LinkProviderService providerService;
private final PacketListener listener = new InternalLinkProvider();
/**
* Creates an OpenFlow link provider.
*/
......@@ -42,14 +46,26 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
@Activate
public void activate() {
providerService = providerRegistry.register(this);
controller.addPacketListener(0, listener);
log.info("Started");
}
@Deactivate
public void deactivate() {
providerRegistry.unregister(this);
controller.removePacketListener(listener);
providerService = null;
log.info("Stopped");
}
private class InternalLinkProvider implements PacketListener {
@Override
public void handlePacket(PacketContext pktCtx) {
}
}
}
......
......@@ -25,5 +25,7 @@
<suppress files=".*" checks="TodoCommentCheck"/>
<suppress files=".*" checks="AvoidInlineConditionalsCheck"/>
<suppress files=".*" checks="OperatorWrapCheck"/>
<suppress files=".*" checks="HiddenField"/>
</suppressions>
......
This diff is collapsed. Click to expand it.
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public abstract class BasePacket implements IPacket {
protected IPacket parent;
protected IPacket payload;
/**
* @return the parent
*/
@Override
public IPacket getParent() {
return this.parent;
}
/**
* @param parent
* the parent to set
*/
@Override
public IPacket setParent(final IPacket parent) {
this.parent = parent;
return this;
}
/**
* @return the payload
*/
@Override
public IPacket getPayload() {
return this.payload;
}
/**
* @param payload
* the payload to set
*/
@Override
public IPacket setPayload(final 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()
*/
@Override
public int hashCode() {
final int prime = 6733;
int result = 1;
result = prime * result
+ (this.payload == null ? 0 : this.payload.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof BasePacket)) {
return false;
}
final BasePacket other = (BasePacket) obj;
if (this.payload == null) {
if (other.payload != null) {
return false;
}
} else if (!this.payload.equals(other.payload)) {
return false;
}
return true;
}
@Override
public Object clone() {
IPacket pkt;
try {
pkt = this.getClass().newInstance();
} catch (final 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.
final byte[] data = this.serialize();
pkt.deserialize(this.serialize(), 0, data.length);
pkt.setParent(this.parent);
return pkt;
}
}
This diff is collapsed. Click to expand it.
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
import java.util.Arrays;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public class DHCPOption {
protected byte code;
protected byte length;
protected byte[] data;
/**
* @return the code
*/
public byte getCode() {
return this.code;
}
/**
* @param code
* the code to set
*/
public DHCPOption setCode(final byte code) {
this.code = code;
return this;
}
/**
* @return the length
*/
public byte getLength() {
return this.length;
}
/**
* @param length
* the length to set
*/
public DHCPOption setLength(final byte length) {
this.length = length;
return this;
}
/**
* @return the data
*/
public byte[] getData() {
return this.data;
}
/**
* @param data
* the data to set
*/
public DHCPOption setData(final byte[] data) {
this.data = data;
return this;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.code;
result = prime * result + Arrays.hashCode(this.data);
result = prime * result + this.length;
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof DHCPOption)) {
return false;
}
final DHCPOption other = (DHCPOption) obj;
if (this.code != other.code) {
return false;
}
if (!Arrays.equals(this.data, other.data)) {
return false;
}
if (this.length != other.length) {
return false;
}
return true;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "DHCPOption [code=" + this.code + ", length=" + this.length
+ ", data=" + Arrays.toString(this.data) + "]";
}
}
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
public enum DHCPPacketType {
// From RFC 1533
DHCPDISCOVER(1), DHCPOFFER(2), DHCPREQUEST(3), DHCPDECLINE(4), DHCPACK(5), DHCPNAK(
6), DHCPRELEASE(7),
// From RFC2132
DHCPINFORM(8),
// From RFC3203
DHCPFORCERENEW(9),
// From RFC4388
DHCPLEASEQUERY(10), DHCPLEASEUNASSIGNED(11), DHCPLEASEUNKNOWN(12), DHCPLEASEACTIVE(
13);
protected int value;
private DHCPPacketType(final int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
@Override
public String toString() {
switch (this.value) {
case 1:
return "DHCPDISCOVER";
case 2:
return "DHCPOFFER";
case 3:
return "DHCPREQUEST";
case 4:
return "DHCPDECLINE";
case 5:
return "DHCPACK";
case 6:
return "DHCPNAK";
case 7:
return "DHCPRELEASE";
case 8:
return "DHCPINFORM";
case 9:
return "DHCPFORCERENEW";
case 10:
return "DHCPLEASEQUERY";
case 11:
return "DHCPLEASEUNASSIGNED";
case 12:
return "DHCPLEASEUNKNOWN";
case 13:
return "DHCPLEASEACTIVE";
default:
break;
}
return null;
}
public static DHCPPacketType getType(final int value) {
switch (value) {
case 1:
return DHCPDISCOVER;
case 2:
return DHCPOFFER;
case 3:
return DHCPREQUEST;
case 4:
return DHCPDECLINE;
case 5:
return DHCPACK;
case 6:
return DHCPNAK;
case 7:
return DHCPRELEASE;
case 8:
return DHCPINFORM;
case 9:
return DHCPFORCERENEW;
case 10:
return DHCPLEASEQUERY;
case 11:
return DHCPLEASEUNASSIGNED;
case 12:
return DHCPLEASEUNKNOWN;
case 13:
return DHCPLEASEACTIVE;
default:
break;
}
return null;
}
}
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
import java.util.Arrays;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public class Data extends BasePacket {
protected byte[] data;
/**
*
*/
public Data() {
}
/**
* @param data
*/
public Data(final byte[] data) {
this.data = data;
}
/**
* @return the data
*/
public byte[] getData() {
return this.data;
}
/**
* @param data
* the data to set
*/
public Data setData(final byte[] data) {
this.data = data;
return this;
}
@Override
public byte[] serialize() {
return this.data;
}
@Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
this.data = Arrays.copyOfRange(data, offset, data.length);
return this;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 1571;
int result = super.hashCode();
result = prime * result + Arrays.hashCode(this.data);
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof Data)) {
return false;
}
final Data other = (Data) obj;
if (!Arrays.equals(this.data, other.data)) {
return false;
}
return true;
}
}
This diff is collapsed. Click to expand it.
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
import java.nio.ByteBuffer;
/**
* Implements ICMP packet format.
*
* @author shudong.zhou@bigswitch.com
*/
public class ICMP extends BasePacket {
protected byte icmpType;
protected byte icmpCode;
protected short checksum;
/**
* @return the icmpType
*/
public byte getIcmpType() {
return this.icmpType;
}
/**
* @param icmpType
* to set
*/
public ICMP setIcmpType(final byte icmpType) {
this.icmpType = icmpType;
return this;
}
/**
* @return the icmp code
*/
public byte getIcmpCode() {
return this.icmpCode;
}
/**
* @param icmpCode
* code to set
*/
public ICMP setIcmpCode(final byte icmpCode) {
this.icmpCode = icmpCode;
return this;
}
/**
* @return the checksum
*/
public short getChecksum() {
return this.checksum;
}
/**
* @param checksum
* the checksum to set
*/
public ICMP setChecksum(final short checksum) {
this.checksum = checksum;
return this;
}
/**
* Serializes the packet. Will compute and set the following fields if they
* are set to specific values at the time serialize is called: -checksum : 0
* -length : 0
*/
@Override
public byte[] serialize() {
int length = 4;
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
length += payloadData.length;
}
final byte[] data = new byte[length];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.icmpType);
bb.put(this.icmpCode);
bb.putShort(this.checksum);
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IPv4) {
((IPv4) this.parent).setProtocol(IPv4.PROTOCOL_ICMP);
}
// compute checksum if needed
if (this.checksum == 0) {
bb.rewind();
int accumulation = 0;
for (int i = 0; i < length / 2; ++i) {
accumulation += 0xffff & bb.getShort();
}
// pad to an even number of shorts
if (length % 2 > 0) {
accumulation += (bb.get() & 0xff) << 8;
}
accumulation = (accumulation >> 16 & 0xffff)
+ (accumulation & 0xffff);
this.checksum = (short) (~accumulation & 0xffff);
bb.putShort(2, this.checksum);
}
return data;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 5807;
int result = super.hashCode();
result = prime * result + this.icmpType;
result = prime * result + this.icmpCode;
result = prime * result + this.checksum;
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof ICMP)) {
return false;
}
final ICMP other = (ICMP) obj;
if (this.icmpType != other.icmpType) {
return false;
}
if (this.icmpCode != other.icmpCode) {
return false;
}
if (this.checksum != other.checksum) {
return false;
}
return true;
}
@Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.icmpType = bb.get();
this.icmpCode = bb.get();
this.checksum = bb.getShort();
this.payload = new Data();
this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- bb.position());
this.payload.setParent(this);
return this;
}
}
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public interface IPacket {
/**
*
* @return
*/
public IPacket getPayload();
/**
*
* @param packet
* @return
*/
public IPacket setPayload(IPacket packet);
/**
*
* @return
*/
public IPacket getParent();
/**
*
* @param packet
* @return
*/
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.
*
* @return a byte[] containing this packet and payloads
*/
public byte[] serialize();
/**
* Deserializes this packet layer and all possible payloads.
*
* @param data
* @param offset
* offset to start deserializing from
* @param length
* length of the data to deserialize
* @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();
}
This diff is collapsed. Click to expand it.
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
import java.nio.ByteBuffer;
/**
* This class represents an Link Local Control header that is used in Ethernet
* 802.3.
*
* @author alexreimers
*
*/
public class LLC extends BasePacket {
private byte dsap = 0;
private byte ssap = 0;
private byte ctrl = 0;
public byte getDsap() {
return this.dsap;
}
public void setDsap(final byte dsap) {
this.dsap = dsap;
}
public byte getSsap() {
return this.ssap;
}
public void setSsap(final byte ssap) {
this.ssap = ssap;
}
public byte getCtrl() {
return this.ctrl;
}
public void setCtrl(final byte ctrl) {
this.ctrl = ctrl;
}
@Override
public byte[] serialize() {
final byte[] data = new byte[3];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.dsap);
bb.put(this.ssap);
bb.put(this.ctrl);
return data;
}
@Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.dsap = bb.get();
this.ssap = bb.get();
this.ctrl = bb.get();
return this;
}
}
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* @author David Erickson (daviderickson@cs.stanford.edu)
*
*/
public class LLDP extends BasePacket {
protected LLDPTLV chassisId;
protected LLDPTLV portId;
protected LLDPTLV ttl;
protected List<LLDPTLV> optionalTLVList;
protected short ethType;
public LLDP() {
this.optionalTLVList = new ArrayList<LLDPTLV>();
this.ethType = Ethernet.TYPE_LLDP;
}
/**
* @return the chassisId
*/
public LLDPTLV getChassisId() {
return this.chassisId;
}
/**
* @param chassisId
* the chassisId to set
*/
public LLDP setChassisId(final LLDPTLV chassis) {
this.chassisId = chassis;
return this;
}
/**
* @return the portId
*/
public LLDPTLV getPortId() {
return this.portId;
}
/**
* @param portId
* the portId to set
*/
public LLDP setPortId(final LLDPTLV portId) {
this.portId = portId;
return this;
}
/**
* @return the ttl
*/
public LLDPTLV getTtl() {
return this.ttl;
}
/**
* @param ttl
* the ttl to set
*/
public LLDP setTtl(final LLDPTLV ttl) {
this.ttl = ttl;
return this;
}
/**
* @return the optionalTLVList
*/
public List<LLDPTLV> getOptionalTLVList() {
return this.optionalTLVList;
}
/**
* @param optionalTLVList
* the optionalTLVList to set
*/
public LLDP setOptionalTLVList(final List<LLDPTLV> optionalTLVList) {
this.optionalTLVList = optionalTLVList;
return this;
}
@Override
public byte[] serialize() {
int length = 2 + this.chassisId.getLength() + 2
+ this.portId.getLength() + 2 + this.ttl.getLength() + 2;
for (final LLDPTLV tlv : this.optionalTLVList) {
length += 2 + tlv.getLength();
}
final byte[] data = new byte[length];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.chassisId.serialize());
bb.put(this.portId.serialize());
bb.put(this.ttl.serialize());
for (final LLDPTLV tlv : this.optionalTLVList) {
bb.put(tlv.serialize());
}
bb.putShort((short) 0); // End of LLDPDU
/*
* if (this.parent != null && this.parent instanceof Ethernet) {
* ((Ethernet) this.parent).setEtherType(this.ethType); }
*/
return data;
}
@Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
LLDPTLV tlv;
do {
tlv = new LLDPTLV().deserialize(bb);
// if there was a failure to deserialize stop processing TLVs
if (tlv == null) {
break;
}
switch (tlv.getType()) {
case 0x0:
// can throw this one away, its just an end delimiter
break;
case 0x1:
this.chassisId = tlv;
break;
case 0x2:
this.portId = tlv;
break;
case 0x3:
this.ttl = tlv;
break;
default:
this.optionalTLVList.add(tlv);
break;
}
} while (tlv.getType() != 0 && bb.hasRemaining());
return this;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 883;
int result = super.hashCode();
result = prime * result
+ (this.chassisId == null ? 0 : this.chassisId.hashCode());
result = prime * result + this.optionalTLVList.hashCode();
result = prime * result
+ (this.portId == null ? 0 : this.portId.hashCode());
result = prime * result + (this.ttl == null ? 0 : this.ttl.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof LLDP)) {
return false;
}
final LLDP other = (LLDP) obj;
if (this.chassisId == null) {
if (other.chassisId != null) {
return false;
}
} else if (!this.chassisId.equals(other.chassisId)) {
return false;
}
if (!this.optionalTLVList.equals(other.optionalTLVList)) {
return false;
}
if (this.portId == null) {
if (other.portId != null) {
return false;
}
} else if (!this.portId.equals(other.portId)) {
return false;
}
if (this.ttl == null) {
if (other.ttl != null) {
return false;
}
} else if (!this.ttl.equals(other.ttl)) {
return false;
}
return true;
}
}
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
* The class representing LLDP Organizationally Specific TLV.
*
* @author Sho Shimizu (sho.shimizu@gmail.com)
*/
public class LLDPOrganizationalTLV extends LLDPTLV {
public static final int OUI_LENGTH = 3;
public static final int SUBTYPE_LENGTH = 1;
public static final byte ORGANIZATIONAL_TLV_TYPE = 127;
public static final int MAX_INFOSTRING_LENGTH = 507;
protected byte[] oui;
protected byte subType;
private byte[] infoString;
public LLDPOrganizationalTLV() {
this.type = LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE;
}
/**
* Set the value of OUI.
*
* @param oui
* The value of OUI to be set.
* @return This LLDP Organizationally Specific TLV.
*/
public LLDPOrganizationalTLV setOUI(final byte[] oui) {
if (oui.length != LLDPOrganizationalTLV.OUI_LENGTH) {
throw new IllegalArgumentException("The length of OUI must be "
+ LLDPOrganizationalTLV.OUI_LENGTH + ", but it is "
+ oui.length);
}
this.oui = Arrays.copyOf(oui, oui.length);
return this;
}
/**
* Returns the value of the OUI.
*
* @return The value of the OUI .
*/
public byte[] getOUI() {
return Arrays.copyOf(this.oui, this.oui.length);
}
/**
* Set the value of sub type.
*
* @param subType
* The value of sub type to be set.
* @return This LLDP Organizationally Specific TLV.
*/
public LLDPOrganizationalTLV setSubType(final byte subType) {
this.subType = subType;
return this;
}
/**
* Returns the value of the sub type.
*
* @return The value of the sub type.
*/
public byte getSubType() {
return this.subType;
}
/**
* Set the value of information string.
*
* @param infoString
* the byte array of the value of information string.
* @return This LLDP Organizationally Specific TLV.
*/
public LLDPOrganizationalTLV setInfoString(final byte[] infoString) {
if (infoString.length > LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH) {
throw new IllegalArgumentException(
"The length of infoString cannot exceed "
+ LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH);
}
this.infoString = Arrays.copyOf(infoString, infoString.length);
return this;
}
/**
* Set the value of information string. The String value is automatically
* converted into byte array with UTF-8 encoding.
*
* @param infoString
* the String value of information string.
* @return This LLDP Organizationally Specific TLV.
*/
public LLDPOrganizationalTLV setInfoString(final String infoString) {
final byte[] infoStringBytes = infoString.getBytes(Charset
.forName("UTF-8"));
return this.setInfoString(infoStringBytes);
}
/**
* Returns the value of information string.
*
* @return the value of information string.
*/
public byte[] getInfoString() {
return Arrays.copyOf(this.infoString, this.infoString.length);
}
@Override
public byte[] serialize() {
final int valueLength = LLDPOrganizationalTLV.OUI_LENGTH
+ LLDPOrganizationalTLV.SUBTYPE_LENGTH + this.infoString.length;
this.value = new byte[valueLength];
final ByteBuffer bb = ByteBuffer.wrap(this.value);
bb.put(this.oui);
bb.put(this.subType);
bb.put(this.infoString);
return super.serialize();
}
@Override
public LLDPTLV deserialize(final ByteBuffer bb) {
super.deserialize(bb);
final ByteBuffer optionalField = ByteBuffer.wrap(this.value);
final byte[] oui = new byte[LLDPOrganizationalTLV.OUI_LENGTH];
optionalField.get(oui);
this.setOUI(oui);
this.setSubType(optionalField.get());
final byte[] infoString = new byte[this.getLength()
- LLDPOrganizationalTLV.OUI_LENGTH
- LLDPOrganizationalTLV.SUBTYPE_LENGTH];
optionalField.get(infoString);
this.setInfoString(infoString);
return this;
}
@Override
public int hashCode() {
final int prime = 1423;
int result = 1;
result = prime * result + this.type;
result = prime * result + this.length;
result = prime * result + Arrays.hashCode(this.oui);
result = prime * result + this.subType;
result = prime * result + Arrays.hashCode(this.infoString);
return result;
}
@Override
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof LLDPOrganizationalTLV)) {
return false;
}
final LLDPOrganizationalTLV other = (LLDPOrganizationalTLV) o;
if (this.type != other.type) {
return false;
}
if (this.length != other.length) {
return false;
}
if (!Arrays.equals(this.oui, other.oui)) {
return false;
}
if (this.subType != other.subType) {
return false;
}
if (!Arrays.equals(this.infoString, other.infoString)) {
return false;
}
return true;
}
}
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
*
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public class LLDPTLV {
protected byte type;
protected short length;
protected byte[] value;
/**
* @return the type
*/
public byte getType() {
return this.type;
}
/**
* @param type
* the type to set
*/
public LLDPTLV setType(final byte type) {
this.type = type;
return this;
}
/**
* @return the length
*/
public short getLength() {
return this.length;
}
/**
* @param length
* the length to set
*/
public LLDPTLV setLength(final short length) {
this.length = length;
return this;
}
/**
* @return the value
*/
public byte[] getValue() {
return this.value;
}
/**
* @param value
* the value to set
*/
public LLDPTLV setValue(final byte[] value) {
this.value = value;
return this;
}
public byte[] serialize() {
// type = 7 bits
// info string length 9 bits, each value == byte
// info string
final short scratch = (short) ((0x7f & this.type) << 9 | 0x1ff & this.length);
final byte[] data = new byte[2 + this.length];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putShort(scratch);
if (this.value != null) {
bb.put(this.value);
}
return data;
}
public LLDPTLV deserialize(final ByteBuffer bb) {
short sscratch;
sscratch = bb.getShort();
this.type = (byte) (sscratch >> 9 & 0x7f);
this.length = (short) (sscratch & 0x1ff);
if (this.length > 0) {
this.value = new byte[this.length];
// if there is an underrun just toss the TLV
if (bb.remaining() < this.length) {
return null;
}
bb.get(this.value);
}
return this;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 1423;
int result = 1;
result = prime * result + this.length;
result = prime * result + this.type;
result = prime * result + Arrays.hashCode(this.value);
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof LLDPTLV)) {
return false;
}
final LLDPTLV other = (LLDPTLV) obj;
if (this.length != other.length) {
return false;
}
if (this.type != other.type) {
return false;
}
if (!Arrays.equals(this.value, other.value)) {
return false;
}
return true;
}
}
/*******************************************************************************
* Copyright 2014 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 java.util.Arrays;
/**
* The class representing MAC address.
*
* @author Sho Shimizu (sho.shimizu@gmail.com)
*/
public class MACAddress {
public static final int MAC_ADDRESS_LENGTH = 6;
private byte[] address = new byte[MACAddress.MAC_ADDRESS_LENGTH];
public MACAddress(final byte[] address) {
this.address = Arrays.copyOf(address, MACAddress.MAC_ADDRESS_LENGTH);
}
/**
* Returns a MAC address instance representing the value of the specified
* {@code String}.
*
* @param address
* the String representation of the MAC Address to be parsed.
* @return a MAC Address instance representing the value of the specified
* {@code String}.
* @throws IllegalArgumentException
* if the string cannot be parsed as a MAC address.
*/
public static MACAddress valueOf(final String address) {
final String[] elements = address.split(":");
if (elements.length != MACAddress.MAC_ADDRESS_LENGTH) {
throw new IllegalArgumentException(
"Specified MAC Address must contain 12 hex digits"
+ " separated pairwise by :'s.");
}
final byte[] addressInBytes = new byte[MACAddress.MAC_ADDRESS_LENGTH];
for (int i = 0; i < MACAddress.MAC_ADDRESS_LENGTH; i++) {
final String element = elements[i];
addressInBytes[i] = (byte) Integer.parseInt(element, 16);
}
return new MACAddress(addressInBytes);
}
/**
* Returns a MAC address instance representing the specified {@code byte}
* array.
*
* @param address
* the byte array to be parsed.
* @return a MAC address instance representing the specified {@code byte}
* array.
* @throws IllegalArgumentException
* if the byte array cannot be parsed as a MAC address.
*/
public static MACAddress valueOf(final byte[] address) {
if (address.length != MACAddress.MAC_ADDRESS_LENGTH) {
throw new IllegalArgumentException("the length is not "
+ MACAddress.MAC_ADDRESS_LENGTH);
}
return new MACAddress(address);
}
/**
* Returns a MAC address instance representing the specified {@code long}
* value. The lower 48 bits of the long value are used to parse as a MAC
* address.
*
* @param address
* the long value to be parsed. The lower 48 bits are used for a
* MAC address.
* @return a MAC address instance representing the specified {@code long}
* value.
* @throws IllegalArgumentException
* if the long value cannot be parsed as a MAC address.
*/
public static MACAddress valueOf(final long address) {
final byte[] addressInBytes = new byte[] {
(byte) (address >> 40 & 0xff), (byte) (address >> 32 & 0xff),
(byte) (address >> 24 & 0xff), (byte) (address >> 16 & 0xff),
(byte) (address >> 8 & 0xff), (byte) (address >> 0 & 0xff) };
return new MACAddress(addressInBytes);
}
/**
* Returns the length of the {@code MACAddress}.
*
* @return the length of the {@code MACAddress}.
*/
public int length() {
return this.address.length;
}
/**
* Returns the value of the {@code MACAddress} as a {@code byte} array.
*
* @return the numeric value represented by this object after conversion to
* type {@code byte} array.
*/
public byte[] toBytes() {
return Arrays.copyOf(this.address, this.address.length);
}
/**
* Returns the value of the {@code MACAddress} as a {@code long}.
*
* @return the numeric value represented by this object after conversion to
* type {@code long}.
*/
public long toLong() {
long mac = 0;
for (int i = 0; i < 6; i++) {
final long t = (this.address[i] & 0xffL) << (5 - i) * 8;
mac |= t;
}
return mac;
}
/**
* Returns {@code true} if the MAC address is the broadcast address.
*
* @return {@code true} if the MAC address is the broadcast address.
*/
public boolean isBroadcast() {
for (final byte b : this.address) {
if (b != -1) {
return false;
}
}
return true;
}
/**
* Returns {@code true} if the MAC address is the multicast address.
*
* @return {@code true} if the MAC address is the multicast address.
*/
public boolean isMulticast() {
if (this.isBroadcast()) {
return false;
}
return (this.address[0] & 0x01) != 0;
}
@Override
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof MACAddress)) {
return false;
}
final MACAddress other = (MACAddress) o;
return Arrays.equals(this.address, other.address);
}
@Override
public int hashCode() {
return Arrays.hashCode(this.address);
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
for (final byte b : this.address) {
if (builder.length() > 0) {
builder.append(":");
}
builder.append(String.format("%02X", b & 0xFF));
}
return builder.toString();
}
/**
* @return MAC address in string representation without colons (useful for
* radix tree storage)
*/
public String toStringNoColon() {
final StringBuilder builder = new StringBuilder();
for (final byte b : this.address) {
builder.append(String.format("%02X", b & 0xFF));
}
return builder.toString();
}
public byte[] getAddress() {
return this.address;
}
}
This diff is collapsed. Click to expand it.
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
import java.nio.ByteBuffer;
/**
*
* @author shudong.zhou@bigswitch.com
*/
public class TCP extends BasePacket {
protected short sourcePort;
protected short destinationPort;
protected int sequence;
protected int acknowledge;
protected byte dataOffset;
protected short flags;
protected short windowSize;
protected short checksum;
protected short urgentPointer;
protected byte[] options;
/**
* @return the sourcePort
*/
public short getSourcePort() {
return this.sourcePort;
}
/**
* @param sourcePort
* the sourcePort to set
*/
public TCP setSourcePort(final short sourcePort) {
this.sourcePort = sourcePort;
return this;
}
/**
* @return the destinationPort
*/
public short getDestinationPort() {
return this.destinationPort;
}
/**
* @param destinationPort
* the destinationPort to set
*/
public TCP setDestinationPort(final short destinationPort) {
this.destinationPort = destinationPort;
return this;
}
/**
* @return the checksum
*/
public short getChecksum() {
return this.checksum;
}
public int getSequence() {
return this.sequence;
}
public TCP setSequence(final int seq) {
this.sequence = seq;
return this;
}
public int getAcknowledge() {
return this.acknowledge;
}
public TCP setAcknowledge(final int ack) {
this.acknowledge = ack;
return this;
}
public byte getDataOffset() {
return this.dataOffset;
}
public TCP setDataOffset(final byte offset) {
this.dataOffset = offset;
return this;
}
public short getFlags() {
return this.flags;
}
public TCP setFlags(final short flags) {
this.flags = flags;
return this;
}
public short getWindowSize() {
return this.windowSize;
}
public TCP setWindowSize(final short windowSize) {
this.windowSize = windowSize;
return this;
}
public short getTcpChecksum() {
return this.checksum;
}
public TCP setTcpChecksum(final short checksum) {
this.checksum = checksum;
return this;
}
@Override
public void resetChecksum() {
this.checksum = 0;
super.resetChecksum();
}
public short getUrgentPointer(final short urgentPointer) {
return this.urgentPointer;
}
public TCP setUrgentPointer(final short urgentPointer) {
this.urgentPointer = urgentPointer;
return this;
}
public byte[] getOptions() {
return this.options;
}
public TCP setOptions(final byte[] options) {
this.options = options;
this.dataOffset = (byte) (20 + options.length + 3 >> 2);
return this;
}
/**
* @param checksum
* the checksum to set
*/
public TCP setChecksum(final short checksum) {
this.checksum = checksum;
return this;
}
/**
* Serializes the packet. Will compute and set the following fields if they
* are set to specific values at the time serialize is called: -checksum : 0
* -length : 0
*/
@Override
public byte[] serialize() {
int length;
if (this.dataOffset == 0) {
this.dataOffset = 5; // default header length
}
length = this.dataOffset << 2;
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
length += payloadData.length;
}
final byte[] data = new byte[length];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putShort(this.sourcePort);
bb.putShort(this.destinationPort);
bb.putInt(this.sequence);
bb.putInt(this.acknowledge);
bb.putShort((short) (this.flags | this.dataOffset << 12));
bb.putShort(this.windowSize);
bb.putShort(this.checksum);
bb.putShort(this.urgentPointer);
if (this.dataOffset > 5) {
int padding;
bb.put(this.options);
padding = (this.dataOffset << 2) - 20 - this.options.length;
for (int i = 0; i < padding; i++) {
bb.put((byte) 0);
}
}
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IPv4) {
((IPv4) this.parent).setProtocol(IPv4.PROTOCOL_TCP);
}
// compute checksum if needed
if (this.checksum == 0) {
bb.rewind();
int accumulation = 0;
// compute pseudo header mac
if (this.parent != null && this.parent instanceof IPv4) {
final IPv4 ipv4 = (IPv4) this.parent;
accumulation += (ipv4.getSourceAddress() >> 16 & 0xffff)
+ (ipv4.getSourceAddress() & 0xffff);
accumulation += (ipv4.getDestinationAddress() >> 16 & 0xffff)
+ (ipv4.getDestinationAddress() & 0xffff);
accumulation += ipv4.getProtocol() & 0xff;
accumulation += length & 0xffff;
}
for (int i = 0; i < length / 2; ++i) {
accumulation += 0xffff & bb.getShort();
}
// pad to an even number of shorts
if (length % 2 > 0) {
accumulation += (bb.get() & 0xff) << 8;
}
accumulation = (accumulation >> 16 & 0xffff)
+ (accumulation & 0xffff);
this.checksum = (short) (~accumulation & 0xffff);
bb.putShort(16, this.checksum);
}
return data;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 5807;
int result = super.hashCode();
result = prime * result + this.checksum;
result = prime * result + this.destinationPort;
result = prime * result + this.sourcePort;
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof TCP)) {
return false;
}
final TCP other = (TCP) obj;
// May want to compare fields based on the flags set
return this.checksum == other.checksum
&& this.destinationPort == other.destinationPort
&& this.sourcePort == other.sourcePort
&& this.sequence == other.sequence
&& this.acknowledge == other.acknowledge
&& this.dataOffset == other.dataOffset
&& this.flags == other.flags
&& this.windowSize == other.windowSize
&& this.urgentPointer == other.urgentPointer
&& (this.dataOffset == 5 || this.options.equals(other.options));
}
@Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.sourcePort = bb.getShort();
this.destinationPort = bb.getShort();
this.sequence = bb.getInt();
this.acknowledge = bb.getInt();
this.flags = bb.getShort();
this.dataOffset = (byte) (this.flags >> 12 & 0xf);
this.flags = (short) (this.flags & 0x1ff);
this.windowSize = bb.getShort();
this.checksum = bb.getShort();
this.urgentPointer = bb.getShort();
if (this.dataOffset > 5) {
int optLength = (this.dataOffset << 2) - 20;
if (bb.limit() < bb.position() + optLength) {
optLength = bb.limit() - bb.position();
}
try {
this.options = new byte[optLength];
bb.get(this.options, 0, optLength);
} catch (final IndexOutOfBoundsException e) {
this.options = null;
}
}
this.payload = new Data();
this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- bb.position());
this.payload.setParent(this);
return this;
}
}
/*******************************************************************************
* Copyright 2014 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.
******************************************************************************/
/**
* 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 org.onlab.packet;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public class UDP extends BasePacket {
public static Map<Short, Class<? extends IPacket>> decodeMap;
public static final short DHCP_SERVER_PORT = (short) 67;
public static final short DHCP_CLIENT_PORT = (short) 68;
static {
UDP.decodeMap = new HashMap<Short, Class<? extends IPacket>>();
/*
* Disable DHCP until the deserialize code is hardened to deal with
* garbage input
*/
UDP.decodeMap.put(UDP.DHCP_SERVER_PORT, DHCP.class);
UDP.decodeMap.put(UDP.DHCP_CLIENT_PORT, DHCP.class);
}
protected short sourcePort;
protected short destinationPort;
protected short length;
protected short checksum;
/**
* @return the sourcePort
*/
public short getSourcePort() {
return this.sourcePort;
}
/**
* @param sourcePort
* the sourcePort to set
*/
public UDP setSourcePort(final short sourcePort) {
this.sourcePort = sourcePort;
return this;
}
/**
* @return the destinationPort
*/
public short getDestinationPort() {
return this.destinationPort;
}
/**
* @param destinationPort
* the destinationPort to set
*/
public UDP setDestinationPort(final short destinationPort) {
this.destinationPort = destinationPort;
return this;
}
/**
* @return the length
*/
public short getLength() {
return this.length;
}
/**
* @return the checksum
*/
public short getChecksum() {
return this.checksum;
}
/**
* @param checksum
* the checksum to set
*/
public UDP setChecksum(final short checksum) {
this.checksum = checksum;
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: -checksum : 0
* -length : 0
*/
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
this.length = (short) (8 + (payloadData == null ? 0
: payloadData.length));
final byte[] data = new byte[this.length];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putShort(this.sourcePort);
bb.putShort(this.destinationPort);
bb.putShort(this.length);
bb.putShort(this.checksum);
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IPv4) {
((IPv4) this.parent).setProtocol(IPv4.PROTOCOL_UDP);
}
// compute checksum if needed
if (this.checksum == 0) {
bb.rewind();
int accumulation = 0;
// compute pseudo header mac
if (this.parent != null && this.parent instanceof IPv4) {
final IPv4 ipv4 = (IPv4) this.parent;
accumulation += (ipv4.getSourceAddress() >> 16 & 0xffff)
+ (ipv4.getSourceAddress() & 0xffff);
accumulation += (ipv4.getDestinationAddress() >> 16 & 0xffff)
+ (ipv4.getDestinationAddress() & 0xffff);
accumulation += ipv4.getProtocol() & 0xff;
accumulation += this.length & 0xffff;
}
for (int i = 0; i < this.length / 2; ++i) {
accumulation += 0xffff & bb.getShort();
}
// pad to an even number of shorts
if (this.length % 2 > 0) {
accumulation += (bb.get() & 0xff) << 8;
}
accumulation = (accumulation >> 16 & 0xffff)
+ (accumulation & 0xffff);
this.checksum = (short) (~accumulation & 0xffff);
bb.putShort(6, this.checksum);
}
return data;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 5807;
int result = super.hashCode();
result = prime * result + this.checksum;
result = prime * result + this.destinationPort;
result = prime * result + this.length;
result = prime * result + this.sourcePort;
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof UDP)) {
return false;
}
final UDP other = (UDP) obj;
if (this.checksum != other.checksum) {
return false;
}
if (this.destinationPort != other.destinationPort) {
return false;
}
if (this.length != other.length) {
return false;
}
if (this.sourcePort != other.sourcePort) {
return false;
}
return true;
}
@Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.sourcePort = bb.getShort();
this.destinationPort = bb.getShort();
this.length = bb.getShort();
this.checksum = bb.getShort();
if (UDP.decodeMap.containsKey(this.destinationPort)) {
try {
this.payload = UDP.decodeMap.get(this.destinationPort)
.getConstructor().newInstance();
} catch (final Exception e) {
throw new RuntimeException("Failure instantiating class", e);
}
} else if (UDP.decodeMap.containsKey(this.sourcePort)) {
try {
this.payload = UDP.decodeMap.get(this.sourcePort)
.getConstructor().newInstance();
} catch (final Exception e) {
throw new RuntimeException("Failure instantiating class", e);
}
} else {
this.payload = new Data();
}
this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- bb.position());
this.payload.setParent(this);
return this;
}
}
......@@ -27,6 +27,11 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
......