blob: a9d53cbdd48040e892e57cced5069f3bd9b3e702 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
alshabibc4901cd2014-09-05 16:50:40 -07009 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
Thomas Vachuska24c849c2014-10-27 09:53:05 -070012 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
alshabibc4901cd2014-09-05 16:50:40 -070017 * under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070018 */
19
20
alshabibc4901cd2014-09-05 16:50:40 -070021
22package org.onlab.packet;
23
24import java.nio.ByteBuffer;
25import java.util.Arrays;
26
27/**
28 *
alshabib638dc712014-09-05 18:03:45 -070029 *
alshabibc4901cd2014-09-05 16:50:40 -070030 */
31public class ARP extends BasePacket {
32 public static final short HW_TYPE_ETHERNET = 0x1;
33
34 public static final short PROTO_TYPE_IP = 0x800;
35
36 public static final short OP_REQUEST = 0x1;
37 public static final short OP_REPLY = 0x2;
38 public static final short OP_RARP_REQUEST = 0x3;
39 public static final short OP_RARP_REPLY = 0x4;
40
41 protected short hardwareType;
42 protected short protocolType;
43 protected byte hardwareAddressLength;
44 protected byte protocolAddressLength;
45 protected short opCode;
46 protected byte[] senderHardwareAddress;
47 protected byte[] senderProtocolAddress;
48 protected byte[] targetHardwareAddress;
49 protected byte[] targetProtocolAddress;
50
51 /**
52 * @return the hardwareType
53 */
54 public short getHardwareType() {
55 return this.hardwareType;
56 }
57
58 /**
tom5f18cf32014-09-13 14:10:57 -070059 * @param hwType
alshabibc4901cd2014-09-05 16:50:40 -070060 * the hardwareType to set
61 */
62 public ARP setHardwareType(final short hwType) {
63 this.hardwareType = hwType;
64 return this;
65 }
66
67 /**
68 * @return the protocolType
69 */
70 public short getProtocolType() {
71 return this.protocolType;
72 }
73
74 /**
tom5f18cf32014-09-13 14:10:57 -070075 * @param protoType
alshabibc4901cd2014-09-05 16:50:40 -070076 * the protocolType to set
77 */
78 public ARP setProtocolType(final short protoType) {
79 this.protocolType = protoType;
80 return this;
81 }
82
83 /**
84 * @return the hardwareAddressLength
85 */
86 public byte getHardwareAddressLength() {
87 return this.hardwareAddressLength;
88 }
89
90 /**
91 * @param hwAddressLength
92 * the hardwareAddressLength to set
93 */
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
109 */
110 public ARP setProtocolAddressLength(final byte protoAddressLength) {
111 this.protocolAddressLength = protoAddressLength;
112 return this;
113 }
114
115 /**
116 * @return the opCode
117 */
118 public short getOpCode() {
119 return this.opCode;
120 }
121
122 /**
tom5f18cf32014-09-13 14:10:57 -0700123 * @param op
alshabibc4901cd2014-09-05 16:50:40 -0700124 * the opCode to set
125 */
126 public ARP setOpCode(final short op) {
127 this.opCode = op;
128 return this;
129 }
130
131 /**
132 * @return the senderHardwareAddress
133 */
134 public byte[] getSenderHardwareAddress() {
135 return this.senderHardwareAddress;
136 }
137
138 /**
tom5f18cf32014-09-13 14:10:57 -0700139 * @param senderHWAddress
alshabibc4901cd2014-09-05 16:50:40 -0700140 * the senderHardwareAddress to set
141 */
142 public ARP setSenderHardwareAddress(final byte[] senderHWAddress) {
143 this.senderHardwareAddress = senderHWAddress;
144 return this;
145 }
146
147 /**
148 * @return the senderProtocolAddress
149 */
150 public byte[] getSenderProtocolAddress() {
151 return this.senderProtocolAddress;
152 }
153
154 /**
tom5f18cf32014-09-13 14:10:57 -0700155 * @param senderProtoAddress
alshabibc4901cd2014-09-05 16:50:40 -0700156 * the senderProtocolAddress to set
157 */
158 public ARP setSenderProtocolAddress(final byte[] senderProtoAddress) {
159 this.senderProtocolAddress = senderProtoAddress;
160 return this;
161 }
162
163 public ARP setSenderProtocolAddress(final int address) {
164 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address)
165 .array();
166 return this;
167 }
168
169 /**
170 * @return the targetHardwareAddress
171 */
172 public byte[] getTargetHardwareAddress() {
173 return this.targetHardwareAddress;
174 }
175
176 /**
tom5f18cf32014-09-13 14:10:57 -0700177 * @param targetHWAddress
alshabibc4901cd2014-09-05 16:50:40 -0700178 * the targetHardwareAddress to set
179 */
180 public ARP setTargetHardwareAddress(final byte[] targetHWAddress) {
181 this.targetHardwareAddress = targetHWAddress;
182 return this;
183 }
184
185 /**
186 * @return the targetProtocolAddress
187 */
188 public byte[] getTargetProtocolAddress() {
189 return this.targetProtocolAddress;
190 }
191
192 /**
193 * @return True if gratuitous ARP (SPA = TPA), false otherwise
194 */
195 public boolean isGratuitous() {
196 assert this.senderProtocolAddress.length == this.targetProtocolAddress.length;
197
198 int indx = 0;
199 while (indx < this.senderProtocolAddress.length) {
200 if (this.senderProtocolAddress[indx] != this.targetProtocolAddress[indx]) {
201 return false;
202 }
203 indx++;
204 }
205
206 return true;
207 }
208
209 /**
tom5f18cf32014-09-13 14:10:57 -0700210 * @param targetProtoAddress
alshabibc4901cd2014-09-05 16:50:40 -0700211 * the targetProtocolAddress to set
212 */
213 public ARP setTargetProtocolAddress(final byte[] targetProtoAddress) {
214 this.targetProtocolAddress = targetProtoAddress;
215 return this;
216 }
217
218 public ARP setTargetProtocolAddress(final int address) {
219 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address)
220 .array();
221 return this;
222 }
223
224 @Override
225 public byte[] serialize() {
226 final int length = 8 + 2 * (0xff & this.hardwareAddressLength) + 2
227 * (0xff & this.protocolAddressLength);
228 final byte[] data = new byte[length];
229 final ByteBuffer bb = ByteBuffer.wrap(data);
230 bb.putShort(this.hardwareType);
231 bb.putShort(this.protocolType);
232 bb.put(this.hardwareAddressLength);
233 bb.put(this.protocolAddressLength);
234 bb.putShort(this.opCode);
235 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
236 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
237 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
238 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
239 return data;
240 }
241
242 @Override
243 public IPacket deserialize(final byte[] data, final int offset,
244 final int length) {
245 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
246 this.hardwareType = bb.getShort();
247 this.protocolType = bb.getShort();
248 this.hardwareAddressLength = bb.get();
249 this.protocolAddressLength = bb.get();
250 this.opCode = bb.getShort();
251 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
252 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
253 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
254 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
255 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
256 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
257 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
258 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
259 return this;
260 }
261
262 /*
263 * (non-Javadoc)
264 *
265 * @see java.lang.Object#hashCode()
266 */
267 @Override
268 public int hashCode() {
269 final int prime = 13121;
270 int result = super.hashCode();
271 result = prime * result + this.hardwareAddressLength;
272 result = prime * result + this.hardwareType;
273 result = prime * result + this.opCode;
274 result = prime * result + this.protocolAddressLength;
275 result = prime * result + this.protocolType;
276 result = prime * result + Arrays.hashCode(this.senderHardwareAddress);
277 result = prime * result + Arrays.hashCode(this.senderProtocolAddress);
278 result = prime * result + Arrays.hashCode(this.targetHardwareAddress);
279 result = prime * result + Arrays.hashCode(this.targetProtocolAddress);
280 return result;
281 }
282
283 /*
284 * (non-Javadoc)
285 *
286 * @see java.lang.Object#equals(java.lang.Object)
287 */
288 @Override
289 public boolean equals(final Object obj) {
290 if (this == obj) {
291 return true;
292 }
293 if (!super.equals(obj)) {
294 return false;
295 }
296 if (!(obj instanceof ARP)) {
297 return false;
298 }
299 final ARP other = (ARP) obj;
300 if (this.hardwareAddressLength != other.hardwareAddressLength) {
301 return false;
302 }
303 if (this.hardwareType != other.hardwareType) {
304 return false;
305 }
306 if (this.opCode != other.opCode) {
307 return false;
308 }
309 if (this.protocolAddressLength != other.protocolAddressLength) {
310 return false;
311 }
312 if (this.protocolType != other.protocolType) {
313 return false;
314 }
315 if (!Arrays.equals(this.senderHardwareAddress,
316 other.senderHardwareAddress)) {
317 return false;
318 }
319 if (!Arrays.equals(this.senderProtocolAddress,
320 other.senderProtocolAddress)) {
321 return false;
322 }
323 if (!Arrays.equals(this.targetHardwareAddress,
324 other.targetHardwareAddress)) {
325 return false;
326 }
327 if (!Arrays.equals(this.targetProtocolAddress,
328 other.targetProtocolAddress)) {
329 return false;
330 }
331 return true;
332 }
333
334 /*
335 * (non-Javadoc)
336 *
337 * @see java.lang.Object#toString()
338 */
339 @Override
340 public String toString() {
341 return "ARP [hardwareType=" + this.hardwareType + ", protocolType="
342 + this.protocolType + ", hardwareAddressLength="
343 + this.hardwareAddressLength + ", protocolAddressLength="
344 + this.protocolAddressLength + ", opCode=" + this.opCode
345 + ", senderHardwareAddress="
346 + Arrays.toString(this.senderHardwareAddress)
347 + ", senderProtocolAddress="
348 + Arrays.toString(this.senderProtocolAddress)
349 + ", targetHardwareAddress="
350 + Arrays.toString(this.targetHardwareAddress)
351 + ", targetProtocolAddress="
352 + Arrays.toString(this.targetProtocolAddress) + "]";
353 }
354}