blob: e6fcecc3e1b5a1fc036a3b3b2195c93b4b6c7b18 [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
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -070023import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
24
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080025/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080026 * @author David Erickson (daviderickson@cs.stanford.edu)
27 */
28public class ARP extends BasePacket {
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070029 public static final short HW_TYPE_ETHERNET = 0x1;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080030
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070031 public static final short PROTO_TYPE_IP = 0x800;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080032
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070033 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;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080037
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 hardwareType;
53 }
54
55 /**
56 * @param hardwareType the hardwareType to set
57 */
58 public ARP setHardwareType(short hardwareType) {
59 this.hardwareType = hardwareType;
60 return this;
61 }
62
63 /**
64 * @return the protocolType
65 */
66 public short getProtocolType() {
67 return protocolType;
68 }
69
70 /**
71 * @param protocolType the protocolType to set
72 */
73 public ARP setProtocolType(short protocolType) {
74 this.protocolType = protocolType;
75 return this;
76 }
77
78 /**
79 * @return the hardwareAddressLength
80 */
81 public byte getHardwareAddressLength() {
82 return hardwareAddressLength;
83 }
84
85 /**
86 * @param hardwareAddressLength the hardwareAddressLength to set
87 */
88 public ARP setHardwareAddressLength(byte hardwareAddressLength) {
89 this.hardwareAddressLength = hardwareAddressLength;
90 return this;
91 }
92
93 /**
94 * @return the protocolAddressLength
95 */
96 public byte getProtocolAddressLength() {
97 return protocolAddressLength;
98 }
99
100 /**
101 * @param protocolAddressLength the protocolAddressLength to set
102 */
103 public ARP setProtocolAddressLength(byte protocolAddressLength) {
104 this.protocolAddressLength = protocolAddressLength;
105 return this;
106 }
107
108 /**
109 * @return the opCode
110 */
111 public short getOpCode() {
112 return opCode;
113 }
114
115 /**
116 * @param opCode the opCode to set
117 */
118 public ARP setOpCode(short opCode) {
119 this.opCode = opCode;
120 return this;
121 }
122
123 /**
124 * @return the senderHardwareAddress
125 */
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -0700126 @SuppressFBWarnings(value = "EI_EXPOSE_REP",
127 justification = "TODO: Return a copy of the object?")
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800128 public byte[] getSenderHardwareAddress() {
129 return senderHardwareAddress;
130 }
131
132 /**
133 * @param senderHardwareAddress the senderHardwareAddress to set
134 */
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -0700135 @SuppressFBWarnings(value = "EI_EXPOSE_REP2",
136 justification = "TODO: Store a copy of the object?")
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800137 public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
138 this.senderHardwareAddress = senderHardwareAddress;
139 return this;
140 }
141
142 /**
143 * @return the senderProtocolAddress
144 */
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -0700145 @SuppressFBWarnings(value = "EI_EXPOSE_REP",
146 justification = "TODO: Return a copy of the object?")
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800147 public byte[] getSenderProtocolAddress() {
148 return senderProtocolAddress;
149 }
150
151 /**
152 * @param senderProtocolAddress the senderProtocolAddress to set
153 */
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -0700154 @SuppressFBWarnings(value = "EI_EXPOSE_REP2",
155 justification = "TODO: Store a copy of the object?")
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800156 public ARP setSenderProtocolAddress(byte[] senderProtocolAddress) {
157 this.senderProtocolAddress = senderProtocolAddress;
158 return this;
159 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700160
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800161 public ARP setSenderProtocolAddress(int address) {
162 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
163 return this;
164 }
165
166 /**
167 * @return the targetHardwareAddress
168 */
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -0700169 @SuppressFBWarnings(value = "EI_EXPOSE_REP",
170 justification = "TODO: Return a copy of the object?")
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800171 public byte[] getTargetHardwareAddress() {
172 return targetHardwareAddress;
173 }
174
175 /**
176 * @param targetHardwareAddress the targetHardwareAddress to set
177 */
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -0700178 @SuppressFBWarnings(value = "EI_EXPOSE_REP2",
179 justification = "TODO: Store a copy of the object?")
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800180 public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
181 this.targetHardwareAddress = targetHardwareAddress;
182 return this;
183 }
184
185 /**
186 * @return the targetProtocolAddress
187 */
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -0700188 @SuppressFBWarnings(value = "EI_EXPOSE_REP",
189 justification = "TODO: Return a copy of the object?")
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800190 public byte[] getTargetProtocolAddress() {
191 return targetProtocolAddress;
192 }
193
194 /**
195 * @return True if gratuitous ARP (SPA = TPA), false otherwise
196 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700197 public boolean isGratuitous() {
198 assert (senderProtocolAddress.length == targetProtocolAddress.length);
199
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800200 int indx = 0;
201 while (indx < senderProtocolAddress.length) {
202 if (senderProtocolAddress[indx] != targetProtocolAddress[indx]) {
203 return false;
204 }
205 indx++;
206 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700207
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800208 return true;
209 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700210
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800211 /**
212 * @param targetProtocolAddress the targetProtocolAddress to set
213 */
Pavlin Radoslavovc9bacee2014-04-11 19:02:17 -0700214 @SuppressFBWarnings(value = "EI_EXPOSE_REP2",
215 justification = "TODO: Store a copy of the object?")
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800216 public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
217 this.targetProtocolAddress = targetProtocolAddress;
218 return this;
219 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700220
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800221 public ARP setTargetProtocolAddress(int address) {
222 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
223 return this;
224 }
225
226 @Override
227 public byte[] serialize() {
228 int length = 8 + (2 * (0xff & this.hardwareAddressLength))
229 + (2 * (0xff & this.protocolAddressLength));
230 byte[] data = new byte[length];
231 ByteBuffer bb = ByteBuffer.wrap(data);
232 bb.putShort(this.hardwareType);
233 bb.putShort(this.protocolType);
234 bb.put(this.hardwareAddressLength);
235 bb.put(this.protocolAddressLength);
236 bb.putShort(this.opCode);
237 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
238 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
239 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
240 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
241 return data;
242 }
243
244 @Override
245 public IPacket deserialize(byte[] data, int offset, int length) {
246 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
247 this.hardwareType = bb.getShort();
248 this.protocolType = bb.getShort();
249 this.hardwareAddressLength = bb.get();
250 this.protocolAddressLength = bb.get();
251 this.opCode = bb.getShort();
252 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
253 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
254 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
255 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
256 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
257 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
258 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
259 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
260 return this;
261 }
262
263 /* (non-Javadoc)
264 * @see java.lang.Object#hashCode()
265 */
266 @Override
267 public int hashCode() {
268 final int prime = 13121;
269 int result = super.hashCode();
270 result = prime * result + hardwareAddressLength;
271 result = prime * result + hardwareType;
272 result = prime * result + opCode;
273 result = prime * result + protocolAddressLength;
274 result = prime * result + protocolType;
275 result = prime * result + Arrays.hashCode(senderHardwareAddress);
276 result = prime * result + Arrays.hashCode(senderProtocolAddress);
277 result = prime * result + Arrays.hashCode(targetHardwareAddress);
278 result = prime * result + Arrays.hashCode(targetProtocolAddress);
279 return result;
280 }
281
282 /* (non-Javadoc)
283 * @see java.lang.Object#equals(java.lang.Object)
284 */
285 @Override
286 public boolean equals(Object obj) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700287 if (this == obj) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800288 return true;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700289 }
290 if (!super.equals(obj)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800291 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700292 }
293 if (!(obj instanceof ARP)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800294 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700295 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800296 ARP other = (ARP) obj;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700297 if (hardwareAddressLength != other.hardwareAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800298 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700299 }
300 if (hardwareType != other.hardwareType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800301 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700302 }
303 if (opCode != other.opCode) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800304 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700305 }
306 if (protocolAddressLength != other.protocolAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800307 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700308 }
309 if (protocolType != other.protocolType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800310 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700311 }
312 if (!Arrays.equals(senderHardwareAddress, other.senderHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800313 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700314 }
315 if (!Arrays.equals(senderProtocolAddress, other.senderProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800316 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700317 }
318 if (!Arrays.equals(targetHardwareAddress, other.targetHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800319 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700320 }
321 if (!Arrays.equals(targetProtocolAddress, other.targetProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800322 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700323 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800324 return true;
325 }
326
327 /* (non-Javadoc)
328 * @see java.lang.Object#toString()
329 */
330 @Override
331 public String toString() {
332 return "ARP [hardwareType=" + hardwareType + ", protocolType="
333 + protocolType + ", hardwareAddressLength="
334 + hardwareAddressLength + ", protocolAddressLength="
335 + protocolAddressLength + ", opCode=" + opCode
336 + ", senderHardwareAddress="
337 + Arrays.toString(senderHardwareAddress)
338 + ", senderProtocolAddress="
339 + Arrays.toString(senderProtocolAddress)
340 + ", targetHardwareAddress="
341 + Arrays.toString(targetHardwareAddress)
342 + ", targetProtocolAddress="
343 + Arrays.toString(targetProtocolAddress) + "]";
344 }
345}