blob: 4d3e02f17556d8edec5d107af848cf69abb4f441 [file] [log] [blame]
alshabibc4901cd2014-09-05 16:50:40 -07001/*******************************************************************************
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * 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
7 *
8 * 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.
15 ******************************************************************************/
16/**
17 * Copyright 2011, Big Switch Networks, Inc.
18 * Originally created by David Erickson, Stanford University
19 *
20 * Licensed under the Apache License, Version 2.0 (the "License"); you may
21 * not use this file except in compliance with the License. You may obtain
22 * a copy of the License at
23 *
24 * http://www.apache.org/licenses/LICENSE-2.0
25 *
26 * Unless required by applicable law or agreed to in writing, software
27 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
28 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
29 * License for the specific language governing permissions and limitations
30 * under the License.
31 **/
32
33package org.onlab.packet;
34
35import java.nio.ByteBuffer;
36import java.util.Arrays;
37
38/**
39 *
alshabib638dc712014-09-05 18:03:45 -070040 *
alshabibc4901cd2014-09-05 16:50:40 -070041 */
42public class ARP extends BasePacket {
43 public static final short HW_TYPE_ETHERNET = 0x1;
44
45 public static final short PROTO_TYPE_IP = 0x800;
46
47 public static final short OP_REQUEST = 0x1;
48 public static final short OP_REPLY = 0x2;
49 public static final short OP_RARP_REQUEST = 0x3;
50 public static final short OP_RARP_REPLY = 0x4;
51
52 protected short hardwareType;
53 protected short protocolType;
54 protected byte hardwareAddressLength;
55 protected byte protocolAddressLength;
56 protected short opCode;
57 protected byte[] senderHardwareAddress;
58 protected byte[] senderProtocolAddress;
59 protected byte[] targetHardwareAddress;
60 protected byte[] targetProtocolAddress;
61
62 /**
63 * @return the hardwareType
64 */
65 public short getHardwareType() {
66 return this.hardwareType;
67 }
68
69 /**
tom5f18cf32014-09-13 14:10:57 -070070 * @param hwType
alshabibc4901cd2014-09-05 16:50:40 -070071 * the hardwareType to set
72 */
73 public ARP setHardwareType(final short hwType) {
74 this.hardwareType = hwType;
75 return this;
76 }
77
78 /**
79 * @return the protocolType
80 */
81 public short getProtocolType() {
82 return this.protocolType;
83 }
84
85 /**
tom5f18cf32014-09-13 14:10:57 -070086 * @param protoType
alshabibc4901cd2014-09-05 16:50:40 -070087 * the protocolType to set
88 */
89 public ARP setProtocolType(final short protoType) {
90 this.protocolType = protoType;
91 return this;
92 }
93
94 /**
95 * @return the hardwareAddressLength
96 */
97 public byte getHardwareAddressLength() {
98 return this.hardwareAddressLength;
99 }
100
101 /**
102 * @param hwAddressLength
103 * the hardwareAddressLength to set
104 */
105 public ARP setHardwareAddressLength(final byte hwAddressLength) {
106 this.hardwareAddressLength = hwAddressLength;
107 return this;
108 }
109
110 /**
111 * @return the protocolAddressLength
112 */
113 public byte getProtocolAddressLength() {
114 return this.protocolAddressLength;
115 }
116
117 /**
tom5f18cf32014-09-13 14:10:57 -0700118 * @param protoAddressLength
alshabibc4901cd2014-09-05 16:50:40 -0700119 * the protocolAddressLength to set
120 */
121 public ARP setProtocolAddressLength(final byte protoAddressLength) {
122 this.protocolAddressLength = protoAddressLength;
123 return this;
124 }
125
126 /**
127 * @return the opCode
128 */
129 public short getOpCode() {
130 return this.opCode;
131 }
132
133 /**
tom5f18cf32014-09-13 14:10:57 -0700134 * @param op
alshabibc4901cd2014-09-05 16:50:40 -0700135 * the opCode to set
136 */
137 public ARP setOpCode(final short op) {
138 this.opCode = op;
139 return this;
140 }
141
142 /**
143 * @return the senderHardwareAddress
144 */
145 public byte[] getSenderHardwareAddress() {
146 return this.senderHardwareAddress;
147 }
148
149 /**
tom5f18cf32014-09-13 14:10:57 -0700150 * @param senderHWAddress
alshabibc4901cd2014-09-05 16:50:40 -0700151 * the senderHardwareAddress to set
152 */
153 public ARP setSenderHardwareAddress(final byte[] senderHWAddress) {
154 this.senderHardwareAddress = senderHWAddress;
155 return this;
156 }
157
158 /**
159 * @return the senderProtocolAddress
160 */
161 public byte[] getSenderProtocolAddress() {
162 return this.senderProtocolAddress;
163 }
164
165 /**
tom5f18cf32014-09-13 14:10:57 -0700166 * @param senderProtoAddress
alshabibc4901cd2014-09-05 16:50:40 -0700167 * the senderProtocolAddress to set
168 */
169 public ARP setSenderProtocolAddress(final byte[] senderProtoAddress) {
170 this.senderProtocolAddress = senderProtoAddress;
171 return this;
172 }
173
174 public ARP setSenderProtocolAddress(final int address) {
175 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address)
176 .array();
177 return this;
178 }
179
180 /**
181 * @return the targetHardwareAddress
182 */
183 public byte[] getTargetHardwareAddress() {
184 return this.targetHardwareAddress;
185 }
186
187 /**
tom5f18cf32014-09-13 14:10:57 -0700188 * @param targetHWAddress
alshabibc4901cd2014-09-05 16:50:40 -0700189 * the targetHardwareAddress to set
190 */
191 public ARP setTargetHardwareAddress(final byte[] targetHWAddress) {
192 this.targetHardwareAddress = targetHWAddress;
193 return this;
194 }
195
196 /**
197 * @return the targetProtocolAddress
198 */
199 public byte[] getTargetProtocolAddress() {
200 return this.targetProtocolAddress;
201 }
202
203 /**
204 * @return True if gratuitous ARP (SPA = TPA), false otherwise
205 */
206 public boolean isGratuitous() {
207 assert this.senderProtocolAddress.length == this.targetProtocolAddress.length;
208
209 int indx = 0;
210 while (indx < this.senderProtocolAddress.length) {
211 if (this.senderProtocolAddress[indx] != this.targetProtocolAddress[indx]) {
212 return false;
213 }
214 indx++;
215 }
216
217 return true;
218 }
219
220 /**
tom5f18cf32014-09-13 14:10:57 -0700221 * @param targetProtoAddress
alshabibc4901cd2014-09-05 16:50:40 -0700222 * the targetProtocolAddress to set
223 */
224 public ARP setTargetProtocolAddress(final byte[] targetProtoAddress) {
225 this.targetProtocolAddress = targetProtoAddress;
226 return this;
227 }
228
229 public ARP setTargetProtocolAddress(final int address) {
230 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address)
231 .array();
232 return this;
233 }
234
235 @Override
236 public byte[] serialize() {
237 final int length = 8 + 2 * (0xff & this.hardwareAddressLength) + 2
238 * (0xff & this.protocolAddressLength);
239 final byte[] data = new byte[length];
240 final ByteBuffer bb = ByteBuffer.wrap(data);
241 bb.putShort(this.hardwareType);
242 bb.putShort(this.protocolType);
243 bb.put(this.hardwareAddressLength);
244 bb.put(this.protocolAddressLength);
245 bb.putShort(this.opCode);
246 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
247 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
248 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
249 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
250 return data;
251 }
252
253 @Override
254 public IPacket deserialize(final byte[] data, final int offset,
255 final int length) {
256 final 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 /*
274 * (non-Javadoc)
275 *
276 * @see java.lang.Object#hashCode()
277 */
278 @Override
279 public int hashCode() {
280 final int prime = 13121;
281 int result = super.hashCode();
282 result = prime * result + this.hardwareAddressLength;
283 result = prime * result + this.hardwareType;
284 result = prime * result + this.opCode;
285 result = prime * result + this.protocolAddressLength;
286 result = prime * result + this.protocolType;
287 result = prime * result + Arrays.hashCode(this.senderHardwareAddress);
288 result = prime * result + Arrays.hashCode(this.senderProtocolAddress);
289 result = prime * result + Arrays.hashCode(this.targetHardwareAddress);
290 result = prime * result + Arrays.hashCode(this.targetProtocolAddress);
291 return result;
292 }
293
294 /*
295 * (non-Javadoc)
296 *
297 * @see java.lang.Object#equals(java.lang.Object)
298 */
299 @Override
300 public boolean equals(final Object obj) {
301 if (this == obj) {
302 return true;
303 }
304 if (!super.equals(obj)) {
305 return false;
306 }
307 if (!(obj instanceof ARP)) {
308 return false;
309 }
310 final ARP other = (ARP) obj;
311 if (this.hardwareAddressLength != other.hardwareAddressLength) {
312 return false;
313 }
314 if (this.hardwareType != other.hardwareType) {
315 return false;
316 }
317 if (this.opCode != other.opCode) {
318 return false;
319 }
320 if (this.protocolAddressLength != other.protocolAddressLength) {
321 return false;
322 }
323 if (this.protocolType != other.protocolType) {
324 return false;
325 }
326 if (!Arrays.equals(this.senderHardwareAddress,
327 other.senderHardwareAddress)) {
328 return false;
329 }
330 if (!Arrays.equals(this.senderProtocolAddress,
331 other.senderProtocolAddress)) {
332 return false;
333 }
334 if (!Arrays.equals(this.targetHardwareAddress,
335 other.targetHardwareAddress)) {
336 return false;
337 }
338 if (!Arrays.equals(this.targetProtocolAddress,
339 other.targetProtocolAddress)) {
340 return false;
341 }
342 return true;
343 }
344
345 /*
346 * (non-Javadoc)
347 *
348 * @see java.lang.Object#toString()
349 */
350 @Override
351 public String toString() {
352 return "ARP [hardwareType=" + this.hardwareType + ", protocolType="
353 + this.protocolType + ", hardwareAddressLength="
354 + this.hardwareAddressLength + ", protocolAddressLength="
355 + this.protocolAddressLength + ", opCode=" + this.opCode
356 + ", senderHardwareAddress="
357 + Arrays.toString(this.senderHardwareAddress)
358 + ", senderProtocolAddress="
359 + Arrays.toString(this.senderProtocolAddress)
360 + ", targetHardwareAddress="
361 + Arrays.toString(this.targetHardwareAddress)
362 + ", targetProtocolAddress="
363 + Arrays.toString(this.targetProtocolAddress) + "]";
364 }
365}