blob: 3d11649dd7cda767cf44cd294508788e1e39506c [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
Ray Milkey269ffb92014-04-03 14:43:30 -07002 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080017
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070018package net.onrc.onos.core.packet;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080019
20import java.nio.ByteBuffer;
21import java.util.Arrays;
22
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -070023import org.apache.commons.lang.ArrayUtils;
24
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080025/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080026 * @author David Erickson (daviderickson@cs.stanford.edu)
27 */
28public class ARP extends BasePacket {
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070029 public static final short HW_TYPE_ETHERNET = 0x1;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080030
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070031 public static final short PROTO_TYPE_IP = 0x800;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080032
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070033 public static final short OP_REQUEST = 0x1;
34 public static final short OP_REPLY = 0x2;
35 public static final short OP_RARP_REQUEST = 0x3;
36 public static final short OP_RARP_REPLY = 0x4;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080037
38 protected short hardwareType;
39 protected short protocolType;
40 protected byte hardwareAddressLength;
41 protected byte protocolAddressLength;
42 protected short opCode;
43 protected byte[] senderHardwareAddress;
44 protected byte[] senderProtocolAddress;
45 protected byte[] targetHardwareAddress;
46 protected byte[] targetProtocolAddress;
47
48 /**
49 * @return the hardwareType
50 */
51 public short getHardwareType() {
52 return hardwareType;
53 }
54
55 /**
56 * @param hardwareType the hardwareType to set
57 */
58 public ARP setHardwareType(short hardwareType) {
59 this.hardwareType = hardwareType;
60 return this;
61 }
62
63 /**
64 * @return the protocolType
65 */
66 public short getProtocolType() {
67 return protocolType;
68 }
69
70 /**
71 * @param protocolType the protocolType to set
72 */
73 public ARP setProtocolType(short protocolType) {
74 this.protocolType = protocolType;
75 return this;
76 }
77
78 /**
79 * @return the hardwareAddressLength
80 */
81 public byte getHardwareAddressLength() {
82 return hardwareAddressLength;
83 }
84
85 /**
86 * @param hardwareAddressLength the hardwareAddressLength to set
87 */
88 public ARP setHardwareAddressLength(byte hardwareAddressLength) {
89 this.hardwareAddressLength = hardwareAddressLength;
90 return this;
91 }
92
93 /**
94 * @return the protocolAddressLength
95 */
96 public byte getProtocolAddressLength() {
97 return protocolAddressLength;
98 }
99
100 /**
101 * @param protocolAddressLength the protocolAddressLength to set
102 */
103 public ARP setProtocolAddressLength(byte protocolAddressLength) {
104 this.protocolAddressLength = protocolAddressLength;
105 return this;
106 }
107
108 /**
109 * @return the opCode
110 */
111 public short getOpCode() {
112 return opCode;
113 }
114
115 /**
116 * @param opCode the opCode to set
117 */
118 public ARP setOpCode(short opCode) {
119 this.opCode = opCode;
120 return this;
121 }
122
123 /**
124 * @return the senderHardwareAddress
125 */
126 public byte[] getSenderHardwareAddress() {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700127 return ArrayUtils.clone(this.senderHardwareAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800128 }
129
130 /**
131 * @param senderHardwareAddress the senderHardwareAddress to set
132 */
133 public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700134 this.senderHardwareAddress = ArrayUtils.clone(senderHardwareAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800135 return this;
136 }
137
138 /**
139 * @return the senderProtocolAddress
140 */
141 public byte[] getSenderProtocolAddress() {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700142 return ArrayUtils.clone(this.senderProtocolAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800143 }
144
145 /**
146 * @param senderProtocolAddress the senderProtocolAddress to set
147 */
148 public ARP setSenderProtocolAddress(byte[] senderProtocolAddress) {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700149 this.senderProtocolAddress = ArrayUtils.clone(senderProtocolAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800150 return this;
151 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700152
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800153 public ARP setSenderProtocolAddress(int address) {
154 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
155 return this;
156 }
157
158 /**
159 * @return the targetHardwareAddress
160 */
161 public byte[] getTargetHardwareAddress() {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700162 return ArrayUtils.clone(this.targetHardwareAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800163 }
164
165 /**
166 * @param targetHardwareAddress the targetHardwareAddress to set
167 */
168 public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700169 this.targetHardwareAddress = ArrayUtils.clone(targetHardwareAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800170 return this;
171 }
172
173 /**
174 * @return the targetProtocolAddress
175 */
176 public byte[] getTargetProtocolAddress() {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700177 return ArrayUtils.clone(this.targetProtocolAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800178 }
179
180 /**
181 * @return True if gratuitous ARP (SPA = TPA), false otherwise
182 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700183 public boolean isGratuitous() {
184 assert (senderProtocolAddress.length == targetProtocolAddress.length);
185
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800186 int indx = 0;
187 while (indx < senderProtocolAddress.length) {
188 if (senderProtocolAddress[indx] != targetProtocolAddress[indx]) {
189 return false;
190 }
191 indx++;
192 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700193
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800194 return true;
195 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700196
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800197 /**
198 * @param targetProtocolAddress the targetProtocolAddress to set
199 */
200 public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700201 this.targetProtocolAddress = ArrayUtils.clone(targetProtocolAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800202 return this;
203 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700204
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800205 public ARP setTargetProtocolAddress(int address) {
206 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
207 return this;
208 }
209
210 @Override
211 public byte[] serialize() {
212 int length = 8 + (2 * (0xff & this.hardwareAddressLength))
213 + (2 * (0xff & this.protocolAddressLength));
214 byte[] data = new byte[length];
215 ByteBuffer bb = ByteBuffer.wrap(data);
216 bb.putShort(this.hardwareType);
217 bb.putShort(this.protocolType);
218 bb.put(this.hardwareAddressLength);
219 bb.put(this.protocolAddressLength);
220 bb.putShort(this.opCode);
221 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
222 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
223 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
224 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
225 return data;
226 }
227
228 @Override
229 public IPacket deserialize(byte[] data, int offset, int length) {
230 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
231 this.hardwareType = bb.getShort();
232 this.protocolType = bb.getShort();
233 this.hardwareAddressLength = bb.get();
234 this.protocolAddressLength = bb.get();
235 this.opCode = bb.getShort();
236 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
237 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
238 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
239 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
240 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
241 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
242 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
243 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
244 return this;
245 }
246
247 /* (non-Javadoc)
248 * @see java.lang.Object#hashCode()
249 */
250 @Override
251 public int hashCode() {
252 final int prime = 13121;
253 int result = super.hashCode();
254 result = prime * result + hardwareAddressLength;
255 result = prime * result + hardwareType;
256 result = prime * result + opCode;
257 result = prime * result + protocolAddressLength;
258 result = prime * result + protocolType;
259 result = prime * result + Arrays.hashCode(senderHardwareAddress);
260 result = prime * result + Arrays.hashCode(senderProtocolAddress);
261 result = prime * result + Arrays.hashCode(targetHardwareAddress);
262 result = prime * result + Arrays.hashCode(targetProtocolAddress);
263 return result;
264 }
265
266 /* (non-Javadoc)
267 * @see java.lang.Object#equals(java.lang.Object)
268 */
269 @Override
270 public boolean equals(Object obj) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700271 if (this == obj) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800272 return true;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700273 }
274 if (!super.equals(obj)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800275 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700276 }
277 if (!(obj instanceof ARP)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800278 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700279 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800280 ARP other = (ARP) obj;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700281 if (hardwareAddressLength != other.hardwareAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800282 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700283 }
284 if (hardwareType != other.hardwareType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800285 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700286 }
287 if (opCode != other.opCode) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800288 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700289 }
290 if (protocolAddressLength != other.protocolAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800291 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700292 }
293 if (protocolType != other.protocolType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800294 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700295 }
296 if (!Arrays.equals(senderHardwareAddress, other.senderHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800297 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700298 }
299 if (!Arrays.equals(senderProtocolAddress, other.senderProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800300 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700301 }
302 if (!Arrays.equals(targetHardwareAddress, other.targetHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800303 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700304 }
305 if (!Arrays.equals(targetProtocolAddress, other.targetProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800306 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700307 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800308 return true;
309 }
310
311 /* (non-Javadoc)
312 * @see java.lang.Object#toString()
313 */
314 @Override
315 public String toString() {
316 return "ARP [hardwareType=" + hardwareType + ", protocolType="
317 + protocolType + ", hardwareAddressLength="
318 + hardwareAddressLength + ", protocolAddressLength="
319 + protocolAddressLength + ", opCode=" + opCode
320 + ", senderHardwareAddress="
321 + Arrays.toString(senderHardwareAddress)
322 + ", senderProtocolAddress="
323 + Arrays.toString(senderProtocolAddress)
324 + ", targetHardwareAddress="
325 + Arrays.toString(targetHardwareAddress)
326 + ", targetProtocolAddress="
327 + Arrays.toString(targetProtocolAddress) + "]";
328 }
329}