blob: 91713c100950cb46cb69f8a23e0bc22a08af90e8 [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
58 */
59 public ARP setHardwareType(final short hwType) {
60 this.hardwareType = hwType;
61 return this;
62 }
63
64 /**
65 * @return the protocolType
66 */
67 public short getProtocolType() {
68 return this.protocolType;
69 }
70
71 /**
tom5f18cf32014-09-13 14:10:57 -070072 * @param protoType
alshabibc4901cd2014-09-05 16:50:40 -070073 * the protocolType to set
74 */
75 public ARP setProtocolType(final short protoType) {
76 this.protocolType = protoType;
77 return this;
78 }
79
80 /**
81 * @return the hardwareAddressLength
82 */
83 public byte getHardwareAddressLength() {
84 return this.hardwareAddressLength;
85 }
86
87 /**
88 * @param hwAddressLength
89 * the hardwareAddressLength to set
90 */
91 public ARP setHardwareAddressLength(final byte hwAddressLength) {
92 this.hardwareAddressLength = hwAddressLength;
93 return this;
94 }
95
96 /**
97 * @return the protocolAddressLength
98 */
99 public byte getProtocolAddressLength() {
100 return this.protocolAddressLength;
101 }
102
103 /**
tom5f18cf32014-09-13 14:10:57 -0700104 * @param protoAddressLength
alshabibc4901cd2014-09-05 16:50:40 -0700105 * the protocolAddressLength to set
106 */
107 public ARP setProtocolAddressLength(final byte protoAddressLength) {
108 this.protocolAddressLength = protoAddressLength;
109 return this;
110 }
111
112 /**
113 * @return the opCode
114 */
115 public short getOpCode() {
116 return this.opCode;
117 }
118
119 /**
tom5f18cf32014-09-13 14:10:57 -0700120 * @param op
alshabibc4901cd2014-09-05 16:50:40 -0700121 * the opCode to set
122 */
123 public ARP setOpCode(final short op) {
124 this.opCode = op;
125 return this;
126 }
127
128 /**
129 * @return the senderHardwareAddress
130 */
131 public byte[] getSenderHardwareAddress() {
132 return this.senderHardwareAddress;
133 }
134
135 /**
tom5f18cf32014-09-13 14:10:57 -0700136 * @param senderHWAddress
alshabibc4901cd2014-09-05 16:50:40 -0700137 * the senderHardwareAddress to set
138 */
139 public ARP setSenderHardwareAddress(final byte[] senderHWAddress) {
140 this.senderHardwareAddress = senderHWAddress;
141 return this;
142 }
143
144 /**
145 * @return the senderProtocolAddress
146 */
147 public byte[] getSenderProtocolAddress() {
148 return this.senderProtocolAddress;
149 }
150
151 /**
tom5f18cf32014-09-13 14:10:57 -0700152 * @param senderProtoAddress
alshabibc4901cd2014-09-05 16:50:40 -0700153 * the senderProtocolAddress to set
154 */
155 public ARP setSenderProtocolAddress(final byte[] senderProtoAddress) {
156 this.senderProtocolAddress = senderProtoAddress;
157 return this;
158 }
159
160 public ARP setSenderProtocolAddress(final int address) {
161 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address)
162 .array();
163 return this;
164 }
165
166 /**
167 * @return the targetHardwareAddress
168 */
169 public byte[] getTargetHardwareAddress() {
170 return this.targetHardwareAddress;
171 }
172
173 /**
tom5f18cf32014-09-13 14:10:57 -0700174 * @param targetHWAddress
alshabibc4901cd2014-09-05 16:50:40 -0700175 * the targetHardwareAddress to set
176 */
177 public ARP setTargetHardwareAddress(final byte[] targetHWAddress) {
178 this.targetHardwareAddress = targetHWAddress;
179 return this;
180 }
181
182 /**
183 * @return the targetProtocolAddress
184 */
185 public byte[] getTargetProtocolAddress() {
186 return this.targetProtocolAddress;
187 }
188
189 /**
190 * @return True if gratuitous ARP (SPA = TPA), false otherwise
191 */
192 public boolean isGratuitous() {
193 assert this.senderProtocolAddress.length == this.targetProtocolAddress.length;
194
195 int indx = 0;
196 while (indx < this.senderProtocolAddress.length) {
197 if (this.senderProtocolAddress[indx] != this.targetProtocolAddress[indx]) {
198 return false;
199 }
200 indx++;
201 }
202
203 return true;
204 }
205
206 /**
tom5f18cf32014-09-13 14:10:57 -0700207 * @param targetProtoAddress
alshabibc4901cd2014-09-05 16:50:40 -0700208 * the targetProtocolAddress to set
209 */
210 public ARP setTargetProtocolAddress(final byte[] targetProtoAddress) {
211 this.targetProtocolAddress = targetProtoAddress;
212 return this;
213 }
214
215 public ARP setTargetProtocolAddress(final int address) {
216 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address)
217 .array();
218 return this;
219 }
220
221 @Override
222 public byte[] serialize() {
223 final int length = 8 + 2 * (0xff & this.hardwareAddressLength) + 2
224 * (0xff & this.protocolAddressLength);
225 final byte[] data = new byte[length];
226 final ByteBuffer bb = ByteBuffer.wrap(data);
227 bb.putShort(this.hardwareType);
228 bb.putShort(this.protocolType);
229 bb.put(this.hardwareAddressLength);
230 bb.put(this.protocolAddressLength);
231 bb.putShort(this.opCode);
232 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
233 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
234 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
235 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
236 return data;
237 }
238
239 @Override
240 public IPacket deserialize(final byte[] data, final int offset,
241 final int length) {
242 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
243 this.hardwareType = bb.getShort();
244 this.protocolType = bb.getShort();
245 this.hardwareAddressLength = bb.get();
246 this.protocolAddressLength = bb.get();
247 this.opCode = bb.getShort();
248 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
249 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
250 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
251 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
252 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
253 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
254 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
255 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
256 return this;
257 }
258
259 /*
260 * (non-Javadoc)
261 *
262 * @see java.lang.Object#hashCode()
263 */
264 @Override
265 public int hashCode() {
266 final int prime = 13121;
267 int result = super.hashCode();
268 result = prime * result + this.hardwareAddressLength;
269 result = prime * result + this.hardwareType;
270 result = prime * result + this.opCode;
271 result = prime * result + this.protocolAddressLength;
272 result = prime * result + this.protocolType;
273 result = prime * result + Arrays.hashCode(this.senderHardwareAddress);
274 result = prime * result + Arrays.hashCode(this.senderProtocolAddress);
275 result = prime * result + Arrays.hashCode(this.targetHardwareAddress);
276 result = prime * result + Arrays.hashCode(this.targetProtocolAddress);
277 return result;
278 }
279
280 /*
281 * (non-Javadoc)
282 *
283 * @see java.lang.Object#equals(java.lang.Object)
284 */
285 @Override
286 public boolean equals(final Object obj) {
287 if (this == obj) {
288 return true;
289 }
290 if (!super.equals(obj)) {
291 return false;
292 }
293 if (!(obj instanceof ARP)) {
294 return false;
295 }
296 final ARP other = (ARP) obj;
297 if (this.hardwareAddressLength != other.hardwareAddressLength) {
298 return false;
299 }
300 if (this.hardwareType != other.hardwareType) {
301 return false;
302 }
303 if (this.opCode != other.opCode) {
304 return false;
305 }
306 if (this.protocolAddressLength != other.protocolAddressLength) {
307 return false;
308 }
309 if (this.protocolType != other.protocolType) {
310 return false;
311 }
312 if (!Arrays.equals(this.senderHardwareAddress,
313 other.senderHardwareAddress)) {
314 return false;
315 }
316 if (!Arrays.equals(this.senderProtocolAddress,
317 other.senderProtocolAddress)) {
318 return false;
319 }
320 if (!Arrays.equals(this.targetHardwareAddress,
321 other.targetHardwareAddress)) {
322 return false;
323 }
324 if (!Arrays.equals(this.targetProtocolAddress,
325 other.targetProtocolAddress)) {
326 return false;
327 }
328 return true;
329 }
330
331 /*
332 * (non-Javadoc)
333 *
334 * @see java.lang.Object#toString()
335 */
336 @Override
337 public String toString() {
338 return "ARP [hardwareType=" + this.hardwareType + ", protocolType="
339 + this.protocolType + ", hardwareAddressLength="
340 + this.hardwareAddressLength + ", protocolAddressLength="
341 + this.protocolAddressLength + ", opCode=" + this.opCode
342 + ", senderHardwareAddress="
343 + Arrays.toString(this.senderHardwareAddress)
344 + ", senderProtocolAddress="
345 + Arrays.toString(this.senderProtocolAddress)
346 + ", targetHardwareAddress="
347 + Arrays.toString(this.targetHardwareAddress)
348 + ", targetProtocolAddress="
349 + Arrays.toString(this.targetProtocolAddress) + "]";
350 }
351}