blob: 7652333aefb4a13a0cbe4172083981575e6c4ef7 [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
Yuta HIGUCHI498e1532014-08-20 21:30:28 -070023import org.apache.commons.lang3.ArrayUtils;
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -070024
Yuta HIGUCHIaa132f52014-06-26 10:18:39 -070025// CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080026/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080027 * @author David Erickson (daviderickson@cs.stanford.edu)
28 */
29public class ARP extends BasePacket {
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070030 public static final short HW_TYPE_ETHERNET = 0x1;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080031
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070032 public static final short PROTO_TYPE_IP = 0x800;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080033
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070034 public static final short OP_REQUEST = 0x1;
35 public static final short OP_REPLY = 0x2;
36 public static final short OP_RARP_REQUEST = 0x3;
37 public static final short OP_RARP_REPLY = 0x4;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080038
39 protected short hardwareType;
40 protected short protocolType;
41 protected byte hardwareAddressLength;
42 protected byte protocolAddressLength;
43 protected short opCode;
44 protected byte[] senderHardwareAddress;
45 protected byte[] senderProtocolAddress;
46 protected byte[] targetHardwareAddress;
47 protected byte[] targetProtocolAddress;
48
49 /**
50 * @return the hardwareType
51 */
52 public short getHardwareType() {
53 return hardwareType;
54 }
55
56 /**
57 * @param hardwareType the hardwareType to set
58 */
59 public ARP setHardwareType(short hardwareType) {
60 this.hardwareType = hardwareType;
61 return this;
62 }
63
64 /**
65 * @return the protocolType
66 */
67 public short getProtocolType() {
68 return protocolType;
69 }
70
71 /**
72 * @param protocolType the protocolType to set
73 */
74 public ARP setProtocolType(short protocolType) {
75 this.protocolType = protocolType;
76 return this;
77 }
78
79 /**
80 * @return the hardwareAddressLength
81 */
82 public byte getHardwareAddressLength() {
83 return hardwareAddressLength;
84 }
85
86 /**
87 * @param hardwareAddressLength the hardwareAddressLength to set
88 */
89 public ARP setHardwareAddressLength(byte hardwareAddressLength) {
90 this.hardwareAddressLength = hardwareAddressLength;
91 return this;
92 }
93
94 /**
95 * @return the protocolAddressLength
96 */
97 public byte getProtocolAddressLength() {
98 return protocolAddressLength;
99 }
100
101 /**
102 * @param protocolAddressLength the protocolAddressLength to set
103 */
104 public ARP setProtocolAddressLength(byte protocolAddressLength) {
105 this.protocolAddressLength = protocolAddressLength;
106 return this;
107 }
108
109 /**
110 * @return the opCode
111 */
112 public short getOpCode() {
113 return opCode;
114 }
115
116 /**
117 * @param opCode the opCode to set
118 */
119 public ARP setOpCode(short opCode) {
120 this.opCode = opCode;
121 return this;
122 }
123
124 /**
125 * @return the senderHardwareAddress
126 */
127 public byte[] getSenderHardwareAddress() {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700128 return ArrayUtils.clone(this.senderHardwareAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800129 }
130
131 /**
132 * @param senderHardwareAddress the senderHardwareAddress to set
133 */
134 public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700135 this.senderHardwareAddress = ArrayUtils.clone(senderHardwareAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800136 return this;
137 }
138
139 /**
140 * @return the senderProtocolAddress
141 */
142 public byte[] getSenderProtocolAddress() {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700143 return ArrayUtils.clone(this.senderProtocolAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800144 }
145
146 /**
147 * @param senderProtocolAddress the senderProtocolAddress to set
148 */
149 public ARP setSenderProtocolAddress(byte[] senderProtocolAddress) {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700150 this.senderProtocolAddress = ArrayUtils.clone(senderProtocolAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800151 return this;
152 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700153
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800154 public ARP setSenderProtocolAddress(int address) {
155 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
156 return this;
157 }
158
159 /**
160 * @return the targetHardwareAddress
161 */
162 public byte[] getTargetHardwareAddress() {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700163 return ArrayUtils.clone(this.targetHardwareAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800164 }
165
166 /**
167 * @param targetHardwareAddress the targetHardwareAddress to set
168 */
169 public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700170 this.targetHardwareAddress = ArrayUtils.clone(targetHardwareAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800171 return this;
172 }
173
174 /**
175 * @return the targetProtocolAddress
176 */
177 public byte[] getTargetProtocolAddress() {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700178 return ArrayUtils.clone(this.targetProtocolAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800179 }
180
181 /**
182 * @return True if gratuitous ARP (SPA = TPA), false otherwise
183 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700184 public boolean isGratuitous() {
185 assert (senderProtocolAddress.length == targetProtocolAddress.length);
186
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800187 int indx = 0;
188 while (indx < senderProtocolAddress.length) {
189 if (senderProtocolAddress[indx] != targetProtocolAddress[indx]) {
190 return false;
191 }
192 indx++;
193 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700194
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800195 return true;
196 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700197
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800198 /**
199 * @param targetProtocolAddress the targetProtocolAddress to set
200 */
201 public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
Pavlin Radoslavov1d595c02014-04-16 14:11:54 -0700202 this.targetProtocolAddress = ArrayUtils.clone(targetProtocolAddress);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800203 return this;
204 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700205
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800206 public ARP setTargetProtocolAddress(int address) {
207 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
208 return this;
209 }
210
211 @Override
212 public byte[] serialize() {
213 int length = 8 + (2 * (0xff & this.hardwareAddressLength))
214 + (2 * (0xff & this.protocolAddressLength));
215 byte[] data = new byte[length];
216 ByteBuffer bb = ByteBuffer.wrap(data);
217 bb.putShort(this.hardwareType);
218 bb.putShort(this.protocolType);
219 bb.put(this.hardwareAddressLength);
220 bb.put(this.protocolAddressLength);
221 bb.putShort(this.opCode);
222 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
223 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
224 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
225 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
226 return data;
227 }
228
229 @Override
230 public IPacket deserialize(byte[] data, int offset, int length) {
231 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
232 this.hardwareType = bb.getShort();
233 this.protocolType = bb.getShort();
234 this.hardwareAddressLength = bb.get();
235 this.protocolAddressLength = bb.get();
236 this.opCode = bb.getShort();
237 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
238 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
239 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
240 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
241 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
242 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
243 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
244 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
245 return this;
246 }
247
248 /* (non-Javadoc)
249 * @see java.lang.Object#hashCode()
250 */
251 @Override
252 public int hashCode() {
253 final int prime = 13121;
254 int result = super.hashCode();
255 result = prime * result + hardwareAddressLength;
256 result = prime * result + hardwareType;
257 result = prime * result + opCode;
258 result = prime * result + protocolAddressLength;
259 result = prime * result + protocolType;
260 result = prime * result + Arrays.hashCode(senderHardwareAddress);
261 result = prime * result + Arrays.hashCode(senderProtocolAddress);
262 result = prime * result + Arrays.hashCode(targetHardwareAddress);
263 result = prime * result + Arrays.hashCode(targetProtocolAddress);
264 return result;
265 }
266
267 /* (non-Javadoc)
268 * @see java.lang.Object#equals(java.lang.Object)
269 */
270 @Override
271 public boolean equals(Object obj) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700272 if (this == obj) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800273 return true;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700274 }
275 if (!super.equals(obj)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800276 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700277 }
278 if (!(obj instanceof ARP)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800279 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700280 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800281 ARP other = (ARP) obj;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700282 if (hardwareAddressLength != other.hardwareAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800283 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700284 }
285 if (hardwareType != other.hardwareType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800286 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700287 }
288 if (opCode != other.opCode) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800289 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700290 }
291 if (protocolAddressLength != other.protocolAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800292 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700293 }
294 if (protocolType != other.protocolType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800295 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700296 }
297 if (!Arrays.equals(senderHardwareAddress, other.senderHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800298 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700299 }
300 if (!Arrays.equals(senderProtocolAddress, other.senderProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800301 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700302 }
303 if (!Arrays.equals(targetHardwareAddress, other.targetHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800304 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700305 }
306 if (!Arrays.equals(targetProtocolAddress, other.targetProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800307 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700308 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800309 return true;
310 }
311
312 /* (non-Javadoc)
313 * @see java.lang.Object#toString()
314 */
315 @Override
316 public String toString() {
317 return "ARP [hardwareType=" + hardwareType + ", protocolType="
318 + protocolType + ", hardwareAddressLength="
319 + hardwareAddressLength + ", protocolAddressLength="
320 + protocolAddressLength + ", opCode=" + opCode
321 + ", senderHardwareAddress="
322 + Arrays.toString(senderHardwareAddress)
323 + ", senderProtocolAddress="
324 + Arrays.toString(senderProtocolAddress)
325 + ", targetHardwareAddress="
326 + Arrays.toString(targetHardwareAddress)
327 + ", targetProtocolAddress="
328 + Arrays.toString(targetProtocolAddress) + "]";
329 }
330}