blob: ae49c4be339246b6b5f2f28cdade15188f830f3e [file] [log] [blame]
/**
* 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;
/**
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public class ARP extends BasePacket {
public static final short HW_TYPE_ETHERNET = 0x1;
public static final short PROTO_TYPE_IP = 0x800;
public static final short OP_REQUEST = 0x1;
public static final short OP_REPLY = 0x2;
public static final short OP_RARP_REQUEST = 0x3;
public static final short OP_RARP_REPLY = 0x4;
protected short hardwareType;
protected short protocolType;
protected byte hardwareAddressLength;
protected byte protocolAddressLength;
protected short opCode;
protected byte[] senderHardwareAddress;
protected byte[] senderProtocolAddress;
protected byte[] targetHardwareAddress;
protected byte[] targetProtocolAddress;
/**
* @return the hardwareType
*/
public short getHardwareType() {
return hardwareType;
}
/**
* @param hardwareType the hardwareType to set
*/
public ARP setHardwareType(short hardwareType) {
this.hardwareType = hardwareType;
return this;
}
/**
* @return the protocolType
*/
public short getProtocolType() {
return protocolType;
}
/**
* @param protocolType the protocolType to set
*/
public ARP setProtocolType(short protocolType) {
this.protocolType = protocolType;
return this;
}
/**
* @return the hardwareAddressLength
*/
public byte getHardwareAddressLength() {
return hardwareAddressLength;
}
/**
* @param hardwareAddressLength the hardwareAddressLength to set
*/
public ARP setHardwareAddressLength(byte hardwareAddressLength) {
this.hardwareAddressLength = hardwareAddressLength;
return this;
}
/**
* @return the protocolAddressLength
*/
public byte getProtocolAddressLength() {
return protocolAddressLength;
}
/**
* @param protocolAddressLength the protocolAddressLength to set
*/
public ARP setProtocolAddressLength(byte protocolAddressLength) {
this.protocolAddressLength = protocolAddressLength;
return this;
}
/**
* @return the opCode
*/
public short getOpCode() {
return opCode;
}
/**
* @param opCode the opCode to set
*/
public ARP setOpCode(short opCode) {
this.opCode = opCode;
return this;
}
/**
* @return the senderHardwareAddress
*/
public byte[] getSenderHardwareAddress() {
return senderHardwareAddress;
}
/**
* @param senderHardwareAddress the senderHardwareAddress to set
*/
public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
this.senderHardwareAddress = senderHardwareAddress;
return this;
}
/**
* @return the senderProtocolAddress
*/
public byte[] getSenderProtocolAddress() {
return senderProtocolAddress;
}
/**
* @param senderProtocolAddress the senderProtocolAddress to set
*/
public ARP setSenderProtocolAddress(byte[] senderProtocolAddress) {
this.senderProtocolAddress = senderProtocolAddress;
return this;
}
public ARP setSenderProtocolAddress(int address) {
this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
return this;
}
/**
* @return the targetHardwareAddress
*/
public byte[] getTargetHardwareAddress() {
return targetHardwareAddress;
}
/**
* @param targetHardwareAddress the targetHardwareAddress to set
*/
public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
this.targetHardwareAddress = targetHardwareAddress;
return this;
}
/**
* @return the targetProtocolAddress
*/
public byte[] getTargetProtocolAddress() {
return targetProtocolAddress;
}
/**
* @return True if gratuitous ARP (SPA = TPA), false otherwise
*/
public boolean isGratuitous() {
assert (senderProtocolAddress.length == targetProtocolAddress.length);
int indx = 0;
while (indx < senderProtocolAddress.length) {
if (senderProtocolAddress[indx] != targetProtocolAddress[indx]) {
return false;
}
indx++;
}
return true;
}
/**
* @param targetProtocolAddress the targetProtocolAddress to set
*/
public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
this.targetProtocolAddress = targetProtocolAddress;
return this;
}
public ARP setTargetProtocolAddress(int address) {
this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
return this;
}
@Override
public byte[] serialize() {
int length = 8 + (2 * (0xff & this.hardwareAddressLength))
+ (2 * (0xff & this.protocolAddressLength));
byte[] data = new byte[length];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.putShort(this.hardwareType);
bb.putShort(this.protocolType);
bb.put(this.hardwareAddressLength);
bb.put(this.protocolAddressLength);
bb.putShort(this.opCode);
bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.hardwareType = bb.getShort();
this.protocolType = bb.getShort();
this.hardwareAddressLength = bb.get();
this.protocolAddressLength = bb.get();
this.opCode = bb.getShort();
this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
return this;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 13121;
int result = super.hashCode();
result = prime * result + hardwareAddressLength;
result = prime * result + hardwareType;
result = prime * result + opCode;
result = prime * result + protocolAddressLength;
result = prime * result + protocolType;
result = prime * result + Arrays.hashCode(senderHardwareAddress);
result = prime * result + Arrays.hashCode(senderProtocolAddress);
result = prime * result + Arrays.hashCode(targetHardwareAddress);
result = prime * result + Arrays.hashCode(targetProtocolAddress);
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 ARP)) {
return false;
}
ARP other = (ARP) obj;
if (hardwareAddressLength != other.hardwareAddressLength) {
return false;
}
if (hardwareType != other.hardwareType) {
return false;
}
if (opCode != other.opCode) {
return false;
}
if (protocolAddressLength != other.protocolAddressLength) {
return false;
}
if (protocolType != other.protocolType) {
return false;
}
if (!Arrays.equals(senderHardwareAddress, other.senderHardwareAddress)) {
return false;
}
if (!Arrays.equals(senderProtocolAddress, other.senderProtocolAddress)) {
return false;
}
if (!Arrays.equals(targetHardwareAddress, other.targetHardwareAddress)) {
return false;
}
if (!Arrays.equals(targetProtocolAddress, other.targetProtocolAddress)) {
return false;
}
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "ARP [hardwareType=" + hardwareType + ", protocolType="
+ protocolType + ", hardwareAddressLength="
+ hardwareAddressLength + ", protocolAddressLength="
+ protocolAddressLength + ", opCode=" + opCode
+ ", senderHardwareAddress="
+ Arrays.toString(senderHardwareAddress)
+ ", senderProtocolAddress="
+ Arrays.toString(senderProtocolAddress)
+ ", targetHardwareAddress="
+ Arrays.toString(targetHardwareAddress)
+ ", targetProtocolAddress="
+ Arrays.toString(targetProtocolAddress) + "]";
}
}