Renamed registry and packet packages
net.onrc.onos.registry.controller.* => net.onrc.onos.core.registry.*
net.onrc.onos.packet => net.onrc.onos.core.packet
Change-Id: I595e325a2c0bab709f248dde5d84ff7b6185cf8b
diff --git a/src/main/java/net/onrc/onos/core/packet/IPv4.java b/src/main/java/net/onrc/onos/core/packet/IPv4.java
new file mode 100644
index 0000000..7f9db1a
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/packet/IPv4.java
@@ -0,0 +1,559 @@
+/**
+* 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.onrc.onos.core.packet;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class IPv4 extends BasePacket {
+ public static final int ADDRESS_LENGTH = 4;
+ public static final byte PROTOCOL_ICMP = 0x1;
+ public static final byte PROTOCOL_TCP = 0x6;
+ public static final byte PROTOCOL_UDP = 0x11;
+ public static Map<Byte, Class<? extends IPacket>> protocolClassMap;
+
+ static {
+ protocolClassMap = new HashMap<Byte, Class<? extends IPacket>>();
+ protocolClassMap.put(PROTOCOL_ICMP, ICMP.class);
+ protocolClassMap.put(PROTOCOL_TCP, TCP.class);
+ protocolClassMap.put(PROTOCOL_UDP, UDP.class);
+ }
+
+ protected byte version;
+ protected byte headerLength;
+ protected byte diffServ;
+ protected short totalLength;
+ protected short identification;
+ protected byte flags;
+ protected short fragmentOffset;
+ protected byte ttl;
+ protected byte protocol;
+ protected short checksum;
+ protected int sourceAddress;
+ protected int destinationAddress;
+ protected byte[] options;
+
+ protected boolean isTruncated;
+
+ /**
+ * Default constructor that sets the version to 4.
+ */
+ public IPv4() {
+ super();
+ this.version = 4;
+ isTruncated = false;
+ }
+
+ /**
+ * @return the version
+ */
+ public byte getVersion() {
+ return version;
+ }
+
+ /**
+ * @param version the version to set
+ */
+ public IPv4 setVersion(byte version) {
+ this.version = version;
+ return this;
+ }
+
+ /**
+ * @return the headerLength
+ */
+ public byte getHeaderLength() {
+ return headerLength;
+ }
+
+ /**
+ * @return the diffServ
+ */
+ public byte getDiffServ() {
+ return diffServ;
+ }
+
+ /**
+ * @param diffServ the diffServ to set
+ */
+ public IPv4 setDiffServ(byte diffServ) {
+ this.diffServ = diffServ;
+ return this;
+ }
+
+ /**
+ * @return the totalLength
+ */
+ public short getTotalLength() {
+ return totalLength;
+ }
+
+ /**
+ * @return the identification
+ */
+ public short getIdentification() {
+ return identification;
+ }
+
+ public boolean isTruncated() {
+ return isTruncated;
+ }
+
+ public void setTruncated(boolean isTruncated) {
+ this.isTruncated = isTruncated;
+ }
+
+ /**
+ * @param identification the identification to set
+ */
+ public IPv4 setIdentification(short identification) {
+ this.identification = identification;
+ return this;
+ }
+
+ /**
+ * @return the flags
+ */
+ public byte getFlags() {
+ return flags;
+ }
+
+ /**
+ * @param flags the flags to set
+ */
+ public IPv4 setFlags(byte flags) {
+ this.flags = flags;
+ return this;
+ }
+
+ /**
+ * @return the fragmentOffset
+ */
+ public short getFragmentOffset() {
+ return fragmentOffset;
+ }
+
+ /**
+ * @param fragmentOffset the fragmentOffset to set
+ */
+ public IPv4 setFragmentOffset(short fragmentOffset) {
+ this.fragmentOffset = fragmentOffset;
+ return this;
+ }
+
+ /**
+ * @return the ttl
+ */
+ public byte getTtl() {
+ return ttl;
+ }
+
+ /**
+ * @param ttl the ttl to set
+ */
+ public IPv4 setTtl(byte ttl) {
+ this.ttl = ttl;
+ return this;
+ }
+
+ /**
+ * @return the protocol
+ */
+ public byte getProtocol() {
+ return protocol;
+ }
+
+ /**
+ * @param protocol the protocol to set
+ */
+ public IPv4 setProtocol(byte protocol) {
+ this.protocol = protocol;
+ return this;
+ }
+
+ /**
+ * @return the checksum
+ */
+ public short getChecksum() {
+ return checksum;
+ }
+
+ /**
+ * @param checksum the checksum to set
+ */
+ public IPv4 setChecksum(short checksum) {
+ this.checksum = checksum;
+ return this;
+ }
+ @Override
+ public void resetChecksum() {
+ this.checksum = 0;
+ super.resetChecksum();
+ }
+
+ /**
+ * @return the sourceAddress
+ */
+ public int getSourceAddress() {
+ return sourceAddress;
+ }
+
+ /**
+ * @param sourceAddress the sourceAddress to set
+ */
+ public IPv4 setSourceAddress(int sourceAddress) {
+ this.sourceAddress = sourceAddress;
+ return this;
+ }
+
+ /**
+ * @param sourceAddress the sourceAddress to set
+ */
+ public IPv4 setSourceAddress(String sourceAddress) {
+ this.sourceAddress = IPv4.toIPv4Address(sourceAddress);
+ return this;
+ }
+
+ /**
+ * @return the destinationAddress
+ */
+ public int getDestinationAddress() {
+ return destinationAddress;
+ }
+
+ /**
+ * @param destinationAddress the destinationAddress to set
+ */
+ public IPv4 setDestinationAddress(int destinationAddress) {
+ this.destinationAddress = destinationAddress;
+ return this;
+ }
+
+ /**
+ * @param destinationAddress the destinationAddress to set
+ */
+ public IPv4 setDestinationAddress(String destinationAddress) {
+ this.destinationAddress = IPv4.toIPv4Address(destinationAddress);
+ return this;
+ }
+
+ /**
+ * @return the options
+ */
+ public byte[] getOptions() {
+ return options;
+ }
+
+ /**
+ * @param options the options to set
+ */
+ public IPv4 setOptions(byte[] options) {
+ if (options != null && (options.length % 4) > 0)
+ throw new IllegalArgumentException(
+ "Options length must be a multiple of 4");
+ this.options = options;
+ 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
+ * -headerLength : 0
+ * -totalLength : 0
+ */
+ public byte[] serialize() {
+ byte[] payloadData = null;
+ if (payload != null) {
+ payload.setParent(this);
+ payloadData = payload.serialize();
+ }
+
+ int optionsLength = 0;
+ if (this.options != null)
+ optionsLength = this.options.length / 4;
+ this.headerLength = (byte) (5 + optionsLength);
+
+ this.totalLength = (short) (this.headerLength * 4 + ((payloadData == null) ? 0
+ : payloadData.length));
+
+ byte[] data = new byte[this.totalLength];
+ ByteBuffer bb = ByteBuffer.wrap(data);
+
+ bb.put((byte) (((this.version & 0xf) << 4) | (this.headerLength & 0xf)));
+ bb.put(this.diffServ);
+ bb.putShort(this.totalLength);
+ bb.putShort(this.identification);
+ bb.putShort((short) (((this.flags & 0x7) << 13) | (this.fragmentOffset & 0x1fff)));
+ bb.put(this.ttl);
+ bb.put(this.protocol);
+ bb.putShort(this.checksum);
+ bb.putInt(this.sourceAddress);
+ bb.putInt(this.destinationAddress);
+ if (this.options != null)
+ bb.put(this.options);
+ if (payloadData != null)
+ bb.put(payloadData);
+
+ // compute checksum if needed
+ if (this.checksum == 0) {
+ bb.rewind();
+ int accumulation = 0;
+ for (int i = 0; i < this.headerLength * 2; ++i) {
+ accumulation += 0xffff & bb.getShort();
+ }
+ accumulation = ((accumulation >> 16) & 0xffff)
+ + (accumulation & 0xffff);
+ this.checksum = (short) (~accumulation & 0xffff);
+ bb.putShort(10, this.checksum);
+ }
+ return data;
+ }
+
+ @Override
+ public IPacket deserialize(byte[] data, int offset, int length) {
+ ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
+ short sscratch;
+
+ this.version = bb.get();
+ this.headerLength = (byte) (this.version & 0xf);
+ this.version = (byte) ((this.version >> 4) & 0xf);
+ this.diffServ = bb.get();
+ this.totalLength = bb.getShort();
+ this.identification = bb.getShort();
+ sscratch = bb.getShort();
+ this.flags = (byte) ((sscratch >> 13) & 0x7);
+ this.fragmentOffset = (short) (sscratch & 0x1fff);
+ this.ttl = bb.get();
+ this.protocol = bb.get();
+ this.checksum = bb.getShort();
+ this.sourceAddress = bb.getInt();
+ this.destinationAddress = bb.getInt();
+
+ if (this.headerLength > 5) {
+ int optionsLength = (this.headerLength - 5) * 4;
+ this.options = new byte[optionsLength];
+ bb.get(this.options);
+ }
+
+ IPacket payload;
+ if (IPv4.protocolClassMap.containsKey(this.protocol)) {
+ Class<? extends IPacket> clazz = IPv4.protocolClassMap.get(this.protocol);
+ try {
+ payload = clazz.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException("Error parsing payload for IPv4 packet", e);
+ }
+ } else {
+ payload = new Data();
+ }
+ this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
+ this.payload.setParent(this);
+
+ if (this.totalLength != length)
+ this.isTruncated = true;
+ else
+ this.isTruncated = false;
+
+ return this;
+ }
+
+ /**
+ * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
+ * returns the corresponding 32 bit integer.
+ * @param ipAddress
+ * @return
+ */
+ public static int toIPv4Address(String ipAddress) {
+ if (ipAddress == null)
+ throw new IllegalArgumentException("Specified IPv4 address must" +
+ "contain 4 sets of numerical digits separated by periods");
+ String[] octets = ipAddress.split("\\.");
+ if (octets.length != 4)
+ throw new IllegalArgumentException("Specified IPv4 address must" +
+ "contain 4 sets of numerical digits separated by periods");
+
+ int result = 0;
+ for (int i = 0; i < 4; ++i) {
+ result |= Integer.valueOf(octets[i]) << ((3-i)*8);
+ }
+ return result;
+ }
+
+ /**
+ * Accepts an IPv4 address in a byte array and returns the corresponding
+ * 32-bit integer value.
+ * @param ipAddress
+ * @return
+ */
+ public static int toIPv4Address(byte[] ipAddress) {
+ int ip = 0;
+ for (int i = 0; i < 4; i++) {
+ int t = (ipAddress[i] & 0xff) << ((3-i)*8);
+ ip |= t;
+ }
+ return ip;
+ }
+
+ /**
+ * Accepts an IPv4 address and returns of string of the form xxx.xxx.xxx.xxx
+ * ie 192.168.0.1
+ *
+ * @param ipAddress
+ * @return
+ */
+ public static String fromIPv4Address(int ipAddress) {
+ StringBuffer sb = new StringBuffer();
+ int result = 0;
+ for (int i = 0; i < 4; ++i) {
+ result = (ipAddress >> ((3-i)*8)) & 0xff;
+ sb.append(Integer.valueOf(result).toString());
+ if (i != 3)
+ sb.append(".");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Accepts a collection of IPv4 addresses as integers and returns a single
+ * String useful in toString method's containing collections of IP
+ * addresses.
+ *
+ * @param ipAddresses collection
+ * @return
+ */
+ public static String fromIPv4AddressCollection(Collection<Integer> ipAddresses) {
+ if (ipAddresses == null)
+ return "null";
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ for (Integer ip : ipAddresses) {
+ sb.append(fromIPv4Address(ip));
+ sb.append(",");
+ }
+ sb.replace(sb.length()-1, sb.length(), "]");
+ return sb.toString();
+ }
+
+ /**
+ * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
+ * returns the corresponding byte array.
+ * @param ipAddress The IP address in the form xx.xxx.xxx.xxx.
+ * @return The IP address separated into bytes
+ */
+ public static byte[] toIPv4AddressBytes(String ipAddress) {
+ String[] octets = ipAddress.split("\\.");
+ if (octets.length != 4)
+ throw new IllegalArgumentException("Specified IPv4 address must" +
+ "contain 4 sets of numerical digits separated by periods");
+
+ byte[] result = new byte[4];
+ for (int i = 0; i < 4; ++i) {
+ result[i] = Integer.valueOf(octets[i]).byteValue();
+ }
+ return result;
+ }
+
+ /**
+ * Accepts an IPv4 address in the form of an integer and
+ * returns the corresponding byte array.
+ * @param ipAddress The IP address as an integer.
+ * @return The IP address separated into bytes.
+ */
+ public static byte[] toIPv4AddressBytes(int ipAddress) {
+ return new byte[] {
+ (byte)(ipAddress >>> 24),
+ (byte)(ipAddress >>> 16),
+ (byte)(ipAddress >>> 8),
+ (byte)ipAddress};
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 2521;
+ int result = super.hashCode();
+ result = prime * result + checksum;
+ result = prime * result + destinationAddress;
+ result = prime * result + diffServ;
+ result = prime * result + flags;
+ result = prime * result + fragmentOffset;
+ result = prime * result + headerLength;
+ result = prime * result + identification;
+ result = prime * result + Arrays.hashCode(options);
+ result = prime * result + protocol;
+ result = prime * result + sourceAddress;
+ result = prime * result + totalLength;
+ result = prime * result + ttl;
+ result = prime * result + version;
+ 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 IPv4))
+ return false;
+ IPv4 other = (IPv4) obj;
+ if (checksum != other.checksum)
+ return false;
+ if (destinationAddress != other.destinationAddress)
+ return false;
+ if (diffServ != other.diffServ)
+ return false;
+ if (flags != other.flags)
+ return false;
+ if (fragmentOffset != other.fragmentOffset)
+ return false;
+ if (headerLength != other.headerLength)
+ return false;
+ if (identification != other.identification)
+ return false;
+ if (!Arrays.equals(options, other.options))
+ return false;
+ if (protocol != other.protocol)
+ return false;
+ if (sourceAddress != other.sourceAddress)
+ return false;
+ if (totalLength != other.totalLength)
+ return false;
+ if (ttl != other.ttl)
+ return false;
+ if (version != other.version)
+ return false;
+ return true;
+ }
+}