blob: ae49c4be339246b6b5f2f28cdade15188f830f3e [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
23/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080024 * @author David Erickson (daviderickson@cs.stanford.edu)
25 */
26public class ARP extends BasePacket {
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070027 public static final short HW_TYPE_ETHERNET = 0x1;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080028
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070029 public static final short PROTO_TYPE_IP = 0x800;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080030
Pavlin Radoslavov608fac32014-04-09 12:40:24 -070031 public static final short OP_REQUEST = 0x1;
32 public static final short OP_REPLY = 0x2;
33 public static final short OP_RARP_REQUEST = 0x3;
34 public static final short OP_RARP_REPLY = 0x4;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080035
36 protected short hardwareType;
37 protected short protocolType;
38 protected byte hardwareAddressLength;
39 protected byte protocolAddressLength;
40 protected short opCode;
41 protected byte[] senderHardwareAddress;
42 protected byte[] senderProtocolAddress;
43 protected byte[] targetHardwareAddress;
44 protected byte[] targetProtocolAddress;
45
46 /**
47 * @return the hardwareType
48 */
49 public short getHardwareType() {
50 return hardwareType;
51 }
52
53 /**
54 * @param hardwareType the hardwareType to set
55 */
56 public ARP setHardwareType(short hardwareType) {
57 this.hardwareType = hardwareType;
58 return this;
59 }
60
61 /**
62 * @return the protocolType
63 */
64 public short getProtocolType() {
65 return protocolType;
66 }
67
68 /**
69 * @param protocolType the protocolType to set
70 */
71 public ARP setProtocolType(short protocolType) {
72 this.protocolType = protocolType;
73 return this;
74 }
75
76 /**
77 * @return the hardwareAddressLength
78 */
79 public byte getHardwareAddressLength() {
80 return hardwareAddressLength;
81 }
82
83 /**
84 * @param hardwareAddressLength the hardwareAddressLength to set
85 */
86 public ARP setHardwareAddressLength(byte hardwareAddressLength) {
87 this.hardwareAddressLength = hardwareAddressLength;
88 return this;
89 }
90
91 /**
92 * @return the protocolAddressLength
93 */
94 public byte getProtocolAddressLength() {
95 return protocolAddressLength;
96 }
97
98 /**
99 * @param protocolAddressLength the protocolAddressLength to set
100 */
101 public ARP setProtocolAddressLength(byte protocolAddressLength) {
102 this.protocolAddressLength = protocolAddressLength;
103 return this;
104 }
105
106 /**
107 * @return the opCode
108 */
109 public short getOpCode() {
110 return opCode;
111 }
112
113 /**
114 * @param opCode the opCode to set
115 */
116 public ARP setOpCode(short opCode) {
117 this.opCode = opCode;
118 return this;
119 }
120
121 /**
122 * @return the senderHardwareAddress
123 */
124 public byte[] getSenderHardwareAddress() {
125 return senderHardwareAddress;
126 }
127
128 /**
129 * @param senderHardwareAddress the senderHardwareAddress to set
130 */
131 public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
132 this.senderHardwareAddress = senderHardwareAddress;
133 return this;
134 }
135
136 /**
137 * @return the senderProtocolAddress
138 */
139 public byte[] getSenderProtocolAddress() {
140 return senderProtocolAddress;
141 }
142
143 /**
144 * @param senderProtocolAddress the senderProtocolAddress to set
145 */
146 public ARP setSenderProtocolAddress(byte[] senderProtocolAddress) {
147 this.senderProtocolAddress = senderProtocolAddress;
148 return this;
149 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700150
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800151 public ARP setSenderProtocolAddress(int address) {
152 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
153 return this;
154 }
155
156 /**
157 * @return the targetHardwareAddress
158 */
159 public byte[] getTargetHardwareAddress() {
160 return targetHardwareAddress;
161 }
162
163 /**
164 * @param targetHardwareAddress the targetHardwareAddress to set
165 */
166 public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
167 this.targetHardwareAddress = targetHardwareAddress;
168 return this;
169 }
170
171 /**
172 * @return the targetProtocolAddress
173 */
174 public byte[] getTargetProtocolAddress() {
175 return targetProtocolAddress;
176 }
177
178 /**
179 * @return True if gratuitous ARP (SPA = TPA), false otherwise
180 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700181 public boolean isGratuitous() {
182 assert (senderProtocolAddress.length == targetProtocolAddress.length);
183
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800184 int indx = 0;
185 while (indx < senderProtocolAddress.length) {
186 if (senderProtocolAddress[indx] != targetProtocolAddress[indx]) {
187 return false;
188 }
189 indx++;
190 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700191
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800192 return true;
193 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700194
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800195 /**
196 * @param targetProtocolAddress the targetProtocolAddress to set
197 */
198 public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
199 this.targetProtocolAddress = targetProtocolAddress;
200 return this;
201 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700202
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800203 public ARP setTargetProtocolAddress(int address) {
204 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
205 return this;
206 }
207
208 @Override
209 public byte[] serialize() {
210 int length = 8 + (2 * (0xff & this.hardwareAddressLength))
211 + (2 * (0xff & this.protocolAddressLength));
212 byte[] data = new byte[length];
213 ByteBuffer bb = ByteBuffer.wrap(data);
214 bb.putShort(this.hardwareType);
215 bb.putShort(this.protocolType);
216 bb.put(this.hardwareAddressLength);
217 bb.put(this.protocolAddressLength);
218 bb.putShort(this.opCode);
219 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
220 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
221 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
222 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
223 return data;
224 }
225
226 @Override
227 public IPacket deserialize(byte[] data, int offset, int length) {
228 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
229 this.hardwareType = bb.getShort();
230 this.protocolType = bb.getShort();
231 this.hardwareAddressLength = bb.get();
232 this.protocolAddressLength = bb.get();
233 this.opCode = bb.getShort();
234 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
235 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
236 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
237 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
238 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
239 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
240 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
241 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
242 return this;
243 }
244
245 /* (non-Javadoc)
246 * @see java.lang.Object#hashCode()
247 */
248 @Override
249 public int hashCode() {
250 final int prime = 13121;
251 int result = super.hashCode();
252 result = prime * result + hardwareAddressLength;
253 result = prime * result + hardwareType;
254 result = prime * result + opCode;
255 result = prime * result + protocolAddressLength;
256 result = prime * result + protocolType;
257 result = prime * result + Arrays.hashCode(senderHardwareAddress);
258 result = prime * result + Arrays.hashCode(senderProtocolAddress);
259 result = prime * result + Arrays.hashCode(targetHardwareAddress);
260 result = prime * result + Arrays.hashCode(targetProtocolAddress);
261 return result;
262 }
263
264 /* (non-Javadoc)
265 * @see java.lang.Object#equals(java.lang.Object)
266 */
267 @Override
268 public boolean equals(Object obj) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700269 if (this == obj) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800270 return true;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700271 }
272 if (!super.equals(obj)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800273 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700274 }
275 if (!(obj instanceof ARP)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800276 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700277 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800278 ARP other = (ARP) obj;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700279 if (hardwareAddressLength != other.hardwareAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800280 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700281 }
282 if (hardwareType != other.hardwareType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800283 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700284 }
285 if (opCode != other.opCode) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800286 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700287 }
288 if (protocolAddressLength != other.protocolAddressLength) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800289 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700290 }
291 if (protocolType != other.protocolType) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800292 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700293 }
294 if (!Arrays.equals(senderHardwareAddress, other.senderHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800295 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700296 }
297 if (!Arrays.equals(senderProtocolAddress, other.senderProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800298 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700299 }
300 if (!Arrays.equals(targetHardwareAddress, other.targetHardwareAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800301 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700302 }
303 if (!Arrays.equals(targetProtocolAddress, other.targetProtocolAddress)) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800304 return false;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700305 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800306 return true;
307 }
308
309 /* (non-Javadoc)
310 * @see java.lang.Object#toString()
311 */
312 @Override
313 public String toString() {
314 return "ARP [hardwareType=" + hardwareType + ", protocolType="
315 + protocolType + ", hardwareAddressLength="
316 + hardwareAddressLength + ", protocolAddressLength="
317 + protocolAddressLength + ", opCode=" + opCode
318 + ", senderHardwareAddress="
319 + Arrays.toString(senderHardwareAddress)
320 + ", senderProtocolAddress="
321 + Arrays.toString(senderProtocolAddress)
322 + ", targetHardwareAddress="
323 + Arrays.toString(targetHardwareAddress)
324 + ", targetProtocolAddress="
325 + Arrays.toString(targetProtocolAddress) + "]";
326 }
327}