blob: 86fb289696a35af7e0601b46355e8a1499e4075f [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
alshabibc4901cd2014-09-05 16:50:40 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
alshabibc4901cd2014-09-05 16:50:40 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
16
17
alshabibc4901cd2014-09-05 16:50:40 -070018
19package org.onlab.packet;
20
21import java.nio.ByteBuffer;
22import java.util.Arrays;
23
24/**
25 *
alshabib638dc712014-09-05 18:03:45 -070026 *
alshabibc4901cd2014-09-05 16:50:40 -070027 */
28public class ARP extends BasePacket {
29 public static final short HW_TYPE_ETHERNET = 0x1;
30
31 public static final short PROTO_TYPE_IP = 0x800;
32
33 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;
37
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 this.hardwareType;
53 }
54
55 /**
tom5f18cf32014-09-13 14:10:57 -070056 * @param hwType
alshabibc4901cd2014-09-05 16:50:40 -070057 * the hardwareType to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -080058 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070059 */
60 public ARP setHardwareType(final short hwType) {
61 this.hardwareType = hwType;
62 return this;
63 }
64
65 /**
66 * @return the protocolType
67 */
68 public short getProtocolType() {
69 return this.protocolType;
70 }
71
72 /**
tom5f18cf32014-09-13 14:10:57 -070073 * @param protoType
alshabibc4901cd2014-09-05 16:50:40 -070074 * the protocolType to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -080075 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070076 */
77 public ARP setProtocolType(final short protoType) {
78 this.protocolType = protoType;
79 return this;
80 }
81
82 /**
83 * @return the hardwareAddressLength
84 */
85 public byte getHardwareAddressLength() {
86 return this.hardwareAddressLength;
87 }
88
89 /**
90 * @param hwAddressLength
91 * the hardwareAddressLength to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -080092 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070093 */
94 public ARP setHardwareAddressLength(final byte hwAddressLength) {
95 this.hardwareAddressLength = hwAddressLength;
96 return this;
97 }
98
99 /**
100 * @return the protocolAddressLength
101 */
102 public byte getProtocolAddressLength() {
103 return this.protocolAddressLength;
104 }
105
106 /**
tom5f18cf32014-09-13 14:10:57 -0700107 * @param protoAddressLength
alshabibc4901cd2014-09-05 16:50:40 -0700108 * the protocolAddressLength to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800109 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700110 */
111 public ARP setProtocolAddressLength(final byte protoAddressLength) {
112 this.protocolAddressLength = protoAddressLength;
113 return this;
114 }
115
116 /**
117 * @return the opCode
118 */
119 public short getOpCode() {
120 return this.opCode;
121 }
122
123 /**
tom5f18cf32014-09-13 14:10:57 -0700124 * @param op
alshabibc4901cd2014-09-05 16:50:40 -0700125 * the opCode to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800126 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700127 */
128 public ARP setOpCode(final short op) {
129 this.opCode = op;
130 return this;
131 }
132
133 /**
134 * @return the senderHardwareAddress
135 */
136 public byte[] getSenderHardwareAddress() {
137 return this.senderHardwareAddress;
138 }
139
140 /**
tom5f18cf32014-09-13 14:10:57 -0700141 * @param senderHWAddress
alshabibc4901cd2014-09-05 16:50:40 -0700142 * the senderHardwareAddress to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800143 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700144 */
145 public ARP setSenderHardwareAddress(final byte[] senderHWAddress) {
146 this.senderHardwareAddress = senderHWAddress;
147 return this;
148 }
149
150 /**
151 * @return the senderProtocolAddress
152 */
153 public byte[] getSenderProtocolAddress() {
154 return this.senderProtocolAddress;
155 }
156
157 /**
tom5f18cf32014-09-13 14:10:57 -0700158 * @param senderProtoAddress
alshabibc4901cd2014-09-05 16:50:40 -0700159 * the senderProtocolAddress to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800160 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700161 */
162 public ARP setSenderProtocolAddress(final byte[] senderProtoAddress) {
163 this.senderProtocolAddress = senderProtoAddress;
164 return this;
165 }
166
167 public ARP setSenderProtocolAddress(final int address) {
168 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address)
169 .array();
170 return this;
171 }
172
173 /**
174 * @return the targetHardwareAddress
175 */
176 public byte[] getTargetHardwareAddress() {
177 return this.targetHardwareAddress;
178 }
179
180 /**
tom5f18cf32014-09-13 14:10:57 -0700181 * @param targetHWAddress
alshabibc4901cd2014-09-05 16:50:40 -0700182 * the targetHardwareAddress to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800183 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700184 */
185 public ARP setTargetHardwareAddress(final byte[] targetHWAddress) {
186 this.targetHardwareAddress = targetHWAddress;
187 return this;
188 }
189
190 /**
191 * @return the targetProtocolAddress
192 */
193 public byte[] getTargetProtocolAddress() {
194 return this.targetProtocolAddress;
195 }
196
197 /**
198 * @return True if gratuitous ARP (SPA = TPA), false otherwise
199 */
200 public boolean isGratuitous() {
201 assert this.senderProtocolAddress.length == this.targetProtocolAddress.length;
202
203 int indx = 0;
204 while (indx < this.senderProtocolAddress.length) {
205 if (this.senderProtocolAddress[indx] != this.targetProtocolAddress[indx]) {
206 return false;
207 }
208 indx++;
209 }
210
211 return true;
212 }
213
214 /**
tom5f18cf32014-09-13 14:10:57 -0700215 * @param targetProtoAddress
alshabibc4901cd2014-09-05 16:50:40 -0700216 * the targetProtocolAddress to set
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800217 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700218 */
219 public ARP setTargetProtocolAddress(final byte[] targetProtoAddress) {
220 this.targetProtocolAddress = targetProtoAddress;
221 return this;
222 }
223
224 public ARP setTargetProtocolAddress(final int address) {
225 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address)
226 .array();
227 return this;
228 }
229
230 @Override
231 public byte[] serialize() {
232 final int length = 8 + 2 * (0xff & this.hardwareAddressLength) + 2
233 * (0xff & this.protocolAddressLength);
234 final byte[] data = new byte[length];
235 final ByteBuffer bb = ByteBuffer.wrap(data);
236 bb.putShort(this.hardwareType);
237 bb.putShort(this.protocolType);
238 bb.put(this.hardwareAddressLength);
239 bb.put(this.protocolAddressLength);
240 bb.putShort(this.opCode);
241 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
242 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
243 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
244 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
245 return data;
246 }
247
248 @Override
249 public IPacket deserialize(final byte[] data, final int offset,
250 final int length) {
251 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
252 this.hardwareType = bb.getShort();
253 this.protocolType = bb.getShort();
254 this.hardwareAddressLength = bb.get();
255 this.protocolAddressLength = bb.get();
256 this.opCode = bb.getShort();
257 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
258 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
259 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
260 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
261 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
262 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
263 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
264 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
265 return this;
266 }
267
268 /*
269 * (non-Javadoc)
270 *
271 * @see java.lang.Object#hashCode()
272 */
273 @Override
274 public int hashCode() {
275 final int prime = 13121;
276 int result = super.hashCode();
277 result = prime * result + this.hardwareAddressLength;
278 result = prime * result + this.hardwareType;
279 result = prime * result + this.opCode;
280 result = prime * result + this.protocolAddressLength;
281 result = prime * result + this.protocolType;
282 result = prime * result + Arrays.hashCode(this.senderHardwareAddress);
283 result = prime * result + Arrays.hashCode(this.senderProtocolAddress);
284 result = prime * result + Arrays.hashCode(this.targetHardwareAddress);
285 result = prime * result + Arrays.hashCode(this.targetProtocolAddress);
286 return result;
287 }
288
289 /*
290 * (non-Javadoc)
291 *
292 * @see java.lang.Object#equals(java.lang.Object)
293 */
294 @Override
295 public boolean equals(final Object obj) {
296 if (this == obj) {
297 return true;
298 }
299 if (!super.equals(obj)) {
300 return false;
301 }
302 if (!(obj instanceof ARP)) {
303 return false;
304 }
305 final ARP other = (ARP) obj;
306 if (this.hardwareAddressLength != other.hardwareAddressLength) {
307 return false;
308 }
309 if (this.hardwareType != other.hardwareType) {
310 return false;
311 }
312 if (this.opCode != other.opCode) {
313 return false;
314 }
315 if (this.protocolAddressLength != other.protocolAddressLength) {
316 return false;
317 }
318 if (this.protocolType != other.protocolType) {
319 return false;
320 }
321 if (!Arrays.equals(this.senderHardwareAddress,
322 other.senderHardwareAddress)) {
323 return false;
324 }
325 if (!Arrays.equals(this.senderProtocolAddress,
326 other.senderProtocolAddress)) {
327 return false;
328 }
329 if (!Arrays.equals(this.targetHardwareAddress,
330 other.targetHardwareAddress)) {
331 return false;
332 }
333 if (!Arrays.equals(this.targetProtocolAddress,
334 other.targetProtocolAddress)) {
335 return false;
336 }
337 return true;
338 }
339
340 /*
341 * (non-Javadoc)
342 *
343 * @see java.lang.Object#toString()
344 */
345 @Override
346 public String toString() {
347 return "ARP [hardwareType=" + this.hardwareType + ", protocolType="
348 + this.protocolType + ", hardwareAddressLength="
349 + this.hardwareAddressLength + ", protocolAddressLength="
350 + this.protocolAddressLength + ", opCode=" + this.opCode
351 + ", senderHardwareAddress="
352 + Arrays.toString(this.senderHardwareAddress)
353 + ", senderProtocolAddress="
354 + Arrays.toString(this.senderProtocolAddress)
355 + ", targetHardwareAddress="
356 + Arrays.toString(this.targetHardwareAddress)
357 + ", targetProtocolAddress="
358 + Arrays.toString(this.targetProtocolAddress) + "]";
359 }
360}