blob: 3b315f3ff23bb9330d3d56480d3c4f08408ab6dd [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
23/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080024 * @author David Erickson (daviderickson@cs.stanford.edu)
25 */
26public class ARP extends BasePacket {
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070027 public static final short HW_TYPE_ETHERNET = 0x1;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080028
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070029 public static final short PROTO_TYPE_IP = 0x800;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080030
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070031 public static final short OP_REQUEST = 0x1;
32 public static final short OP_REPLY = 0x2;
33 public static final short OP_RARP_REQUEST = 0x3;
34 public static final short OP_RARP_REPLY = 0x4;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080035
36 protected short hardwareType;
37 protected short protocolType;
38 protected byte hardwareAddressLength;
39 protected byte protocolAddressLength;
40 protected short opCode;
41 protected byte[] senderHardwareAddress;
42 protected byte[] senderProtocolAddress;
43 protected byte[] targetHardwareAddress;
44 protected byte[] targetProtocolAddress;
45
46 /**
47 * @return the hardwareType
48 */
49 public short getHardwareType() {
50 return hardwareType;
51 }
52
53 /**
54 * @param hardwareType the hardwareType to set
55 */
56 public ARP setHardwareType(short hardwareType) {
57 this.hardwareType = hardwareType;
58 return this;
59 }
60
61 /**
62 * @return the protocolType
63 */
64 public short getProtocolType() {
65 return protocolType;
66 }
67
68 /**
69 * @param protocolType the protocolType to set
70 */
71 public ARP setProtocolType(short protocolType) {
72 this.protocolType = protocolType;
73 return this;
74 }
75
76 /**
77 * @return the hardwareAddressLength
78 */
79 public byte getHardwareAddressLength() {
80 return hardwareAddressLength;
81 }
82
83 /**
84 * @param hardwareAddressLength the hardwareAddressLength to set
85 */
86 public ARP setHardwareAddressLength(byte hardwareAddressLength) {
87 this.hardwareAddressLength = hardwareAddressLength;
88 return this;
89 }
90
91 /**
92 * @return the protocolAddressLength
93 */
94 public byte getProtocolAddressLength() {
95 return protocolAddressLength;
96 }
97
98 /**
99 * @param protocolAddressLength the protocolAddressLength to set
100 */
101 public ARP setProtocolAddressLength(byte protocolAddressLength) {
102 this.protocolAddressLength = protocolAddressLength;
103 return this;
104 }
105
106 /**
107 * @return the opCode
108 */
109 public short getOpCode() {
110 return opCode;
111 }
112
113 /**
114 * @param opCode the opCode to set
115 */
116 public ARP setOpCode(short opCode) {
117 this.opCode = opCode;
118 return this;
119 }
120
121 /**
122 * @return the senderHardwareAddress
123 */
124 public byte[] getSenderHardwareAddress() {
Pavlin Radoslavov0a9d5c32014-04-15 17:45:23 -0700125 if (this.senderHardwareAddress == null) {
126 return null;
127 }
128 return this.senderHardwareAddress.clone();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800129 }
130
131 /**
132 * @param senderHardwareAddress the senderHardwareAddress to set
133 */
134 public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
Pavlin Radoslavov0a9d5c32014-04-15 17:45:23 -0700135 if (senderHardwareAddress == null) {
136 this.senderHardwareAddress = null;
137 } else {
138 this.senderHardwareAddress = senderHardwareAddress.clone();
139 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800140 return this;
141 }
142
143 /**
144 * @return the senderProtocolAddress
145 */
146 public byte[] getSenderProtocolAddress() {
Pavlin Radoslavov0a9d5c32014-04-15 17:45:23 -0700147 if (this.senderProtocolAddress == null) {
148 return null;
149 }
150 return this.senderProtocolAddress.clone();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800151 }
152
153 /**
154 * @param senderProtocolAddress the senderProtocolAddress to set
155 */
156 public ARP setSenderProtocolAddress(byte[] senderProtocolAddress) {
Pavlin Radoslavov0a9d5c32014-04-15 17:45:23 -0700157 if (senderProtocolAddress == null) {
158 this.senderProtocolAddress = null;
159 } else {
160 this.senderProtocolAddress = senderProtocolAddress.clone();
161 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800162 return this;
163 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700164
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800165 public ARP setSenderProtocolAddress(int address) {
166 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
167 return this;
168 }
169
170 /**
171 * @return the targetHardwareAddress
172 */
173 public byte[] getTargetHardwareAddress() {
Pavlin Radoslavov0a9d5c32014-04-15 17:45:23 -0700174 if (this.targetHardwareAddress == null) {
175 return null;
176 }
177 return this.targetHardwareAddress.clone();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800178 }
179
180 /**
181 * @param targetHardwareAddress the targetHardwareAddress to set
182 */
183 public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
Pavlin Radoslavov0a9d5c32014-04-15 17:45:23 -0700184 if (targetHardwareAddress == null) {
185 this.targetHardwareAddress = null;
186 } else {
187 this.targetHardwareAddress = targetHardwareAddress.clone();
188 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800189 return this;
190 }
191
192 /**
193 * @return the targetProtocolAddress
194 */
195 public byte[] getTargetProtocolAddress() {
Pavlin Radoslavov0a9d5c32014-04-15 17:45:23 -0700196 if (this.targetProtocolAddress == null) {
197 return null;
198 }
199 return this.targetProtocolAddress.clone();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800200 }
201
202 /**
203 * @return True if gratuitous ARP (SPA = TPA), false otherwise
204 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700205 public boolean isGratuitous() {
206 assert (senderProtocolAddress.length == targetProtocolAddress.length);
207
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800208 int indx = 0;
209 while (indx < senderProtocolAddress.length) {
210 if (senderProtocolAddress[indx] != targetProtocolAddress[indx]) {
211 return false;
212 }
213 indx++;
214 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700215
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800216 return true;
217 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700218
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800219 /**
220 * @param targetProtocolAddress the targetProtocolAddress to set
221 */
222 public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
Pavlin Radoslavov0a9d5c32014-04-15 17:45:23 -0700223 if (targetProtocolAddress == null) {
224 this.targetProtocolAddress = null;
225 } else {
226 this.targetProtocolAddress = targetProtocolAddress.clone();
227 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800228 return this;
229 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700230
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800231 public ARP setTargetProtocolAddress(int address) {
232 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
233 return this;
234 }
235
236 @Override
237 public byte[] serialize() {
238 int length = 8 + (2 * (0xff & this.hardwareAddressLength))
239 + (2 * (0xff & this.protocolAddressLength));
240 byte[] data = new byte[length];
241 ByteBuffer bb = ByteBuffer.wrap(data);
242 bb.putShort(this.hardwareType);
243 bb.putShort(this.protocolType);
244 bb.put(this.hardwareAddressLength);
245 bb.put(this.protocolAddressLength);
246 bb.putShort(this.opCode);
247 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
248 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
249 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
250 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
251 return data;
252 }
253
254 @Override
255 public IPacket deserialize(byte[] data, int offset, int length) {
256 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
257 this.hardwareType = bb.getShort();
258 this.protocolType = bb.getShort();
259 this.hardwareAddressLength = bb.get();
260 this.protocolAddressLength = bb.get();
261 this.opCode = bb.getShort();
262 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
263 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
264 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
265 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
266 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
267 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
268 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
269 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
270 return this;
271 }
272
273 /* (non-Javadoc)
274 * @see java.lang.Object#hashCode()
275 */
276 @Override
277 public int hashCode() {
278 final int prime = 13121;
279 int result = super.hashCode();
280 result = prime * result + hardwareAddressLength;
281 result = prime * result + hardwareType;
282 result = prime * result + opCode;
283 result = prime * result + protocolAddressLength;
284 result = prime * result + protocolType;
285 result = prime * result + Arrays.hashCode(senderHardwareAddress);
286 result = prime * result + Arrays.hashCode(senderProtocolAddress);
287 result = prime * result + Arrays.hashCode(targetHardwareAddress);
288 result = prime * result + Arrays.hashCode(targetProtocolAddress);
289 return result;
290 }
291
292 /* (non-Javadoc)
293 * @see java.lang.Object#equals(java.lang.Object)
294 */
295 @Override
296 public boolean equals(Object obj) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700297 if (this == obj) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800298 return true;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700299 }
300 if (!super.equals(obj)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800301 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700302 }
303 if (!(obj instanceof ARP)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800304 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700305 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800306 ARP other = (ARP) obj;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700307 if (hardwareAddressLength != other.hardwareAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800308 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700309 }
310 if (hardwareType != other.hardwareType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800311 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700312 }
313 if (opCode != other.opCode) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800314 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700315 }
316 if (protocolAddressLength != other.protocolAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800317 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700318 }
319 if (protocolType != other.protocolType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800320 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700321 }
322 if (!Arrays.equals(senderHardwareAddress, other.senderHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800323 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700324 }
325 if (!Arrays.equals(senderProtocolAddress, other.senderProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800326 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700327 }
328 if (!Arrays.equals(targetHardwareAddress, other.targetHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800329 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700330 }
331 if (!Arrays.equals(targetProtocolAddress, other.targetProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800332 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700333 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800334 return true;
335 }
336
337 /* (non-Javadoc)
338 * @see java.lang.Object#toString()
339 */
340 @Override
341 public String toString() {
342 return "ARP [hardwareType=" + hardwareType + ", protocolType="
343 + protocolType + ", hardwareAddressLength="
344 + hardwareAddressLength + ", protocolAddressLength="
345 + protocolAddressLength + ", opCode=" + opCode
346 + ", senderHardwareAddress="
347 + Arrays.toString(senderHardwareAddress)
348 + ", senderProtocolAddress="
349 + Arrays.toString(senderProtocolAddress)
350 + ", targetHardwareAddress="
351 + Arrays.toString(targetHardwareAddress)
352 + ", targetProtocolAddress="
353 + Arrays.toString(targetProtocolAddress) + "]";
354 }
355}