blob: e8428ead22fa27697a254ee3c7ce4bda3694a2dd [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
2* 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**/
17
18package net.floodlightcontroller.packet;
19
20import java.nio.ByteBuffer;
21import java.util.Arrays;
22
23/**
24 *
25 * @author David Erickson (daviderickson@cs.stanford.edu)
26 */
27public class ARP extends BasePacket {
28 public static short HW_TYPE_ETHERNET = 0x1;
29
30 public static short PROTO_TYPE_IP = 0x800;
31
32 public static short OP_REQUEST = 0x1;
33 public static short OP_REPLY = 0x2;
34 public static short OP_RARP_REQUEST = 0x3;
35 public static short OP_RARP_REPLY = 0x4;
36
37 protected short hardwareType;
38 protected short protocolType;
39 protected byte hardwareAddressLength;
40 protected byte protocolAddressLength;
41 protected short opCode;
42 protected byte[] senderHardwareAddress;
43 protected byte[] senderProtocolAddress;
44 protected byte[] targetHardwareAddress;
45 protected byte[] targetProtocolAddress;
46
47 /**
48 * @return the hardwareType
49 */
50 public short getHardwareType() {
51 return hardwareType;
52 }
53
54 /**
55 * @param hardwareType the hardwareType to set
56 */
57 public ARP setHardwareType(short hardwareType) {
58 this.hardwareType = hardwareType;
59 return this;
60 }
61
62 /**
63 * @return the protocolType
64 */
65 public short getProtocolType() {
66 return protocolType;
67 }
68
69 /**
70 * @param protocolType the protocolType to set
71 */
72 public ARP setProtocolType(short protocolType) {
73 this.protocolType = protocolType;
74 return this;
75 }
76
77 /**
78 * @return the hardwareAddressLength
79 */
80 public byte getHardwareAddressLength() {
81 return hardwareAddressLength;
82 }
83
84 /**
85 * @param hardwareAddressLength the hardwareAddressLength to set
86 */
87 public ARP setHardwareAddressLength(byte hardwareAddressLength) {
88 this.hardwareAddressLength = hardwareAddressLength;
89 return this;
90 }
91
92 /**
93 * @return the protocolAddressLength
94 */
95 public byte getProtocolAddressLength() {
96 return protocolAddressLength;
97 }
98
99 /**
100 * @param protocolAddressLength the protocolAddressLength to set
101 */
102 public ARP setProtocolAddressLength(byte protocolAddressLength) {
103 this.protocolAddressLength = protocolAddressLength;
104 return this;
105 }
106
107 /**
108 * @return the opCode
109 */
110 public short getOpCode() {
111 return opCode;
112 }
113
114 /**
115 * @param opCode the opCode to set
116 */
117 public ARP setOpCode(short opCode) {
118 this.opCode = opCode;
119 return this;
120 }
121
122 /**
123 * @return the senderHardwareAddress
124 */
125 public byte[] getSenderHardwareAddress() {
126 return senderHardwareAddress;
127 }
128
129 /**
130 * @param senderHardwareAddress the senderHardwareAddress to set
131 */
132 public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
133 this.senderHardwareAddress = senderHardwareAddress;
134 return this;
135 }
136
137 /**
138 * @return the senderProtocolAddress
139 */
140 public byte[] getSenderProtocolAddress() {
141 return senderProtocolAddress;
142 }
143
144 /**
145 * @param senderProtocolAddress the senderProtocolAddress to set
146 */
147 public ARP setSenderProtocolAddress(byte[] senderProtocolAddress) {
148 this.senderProtocolAddress = senderProtocolAddress;
149 return this;
150 }
151
152 public ARP setSenderProtocolAddress(int address) {
153 this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
154 return this;
155 }
156
157 /**
158 * @return the targetHardwareAddress
159 */
160 public byte[] getTargetHardwareAddress() {
161 return targetHardwareAddress;
162 }
163
164 /**
165 * @param targetHardwareAddress the targetHardwareAddress to set
166 */
167 public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
168 this.targetHardwareAddress = targetHardwareAddress;
169 return this;
170 }
171
172 /**
173 * @return the targetProtocolAddress
174 */
175 public byte[] getTargetProtocolAddress() {
176 return targetProtocolAddress;
177 }
178
179 /**
180 * @return True if gratuitous ARP (SPA = TPA), false otherwise
181 */
182 public boolean isGratuitous() {
183 assert(senderProtocolAddress.length == targetProtocolAddress.length);
184
185 int indx = 0;
186 while (indx < senderProtocolAddress.length) {
187 if (senderProtocolAddress[indx] != targetProtocolAddress[indx]) {
188 return false;
189 }
190 indx++;
191 }
192
193 return true;
194 }
195
196 /**
197 * @param targetProtocolAddress the targetProtocolAddress to set
198 */
199 public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
200 this.targetProtocolAddress = targetProtocolAddress;
201 return this;
202 }
203
204 public ARP setTargetProtocolAddress(int address) {
205 this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
206 return this;
207 }
208
209 @Override
210 public byte[] serialize() {
211 int length = 8 + (2 * (0xff & this.hardwareAddressLength))
212 + (2 * (0xff & this.protocolAddressLength));
213 byte[] data = new byte[length];
214 ByteBuffer bb = ByteBuffer.wrap(data);
215 bb.putShort(this.hardwareType);
216 bb.putShort(this.protocolType);
217 bb.put(this.hardwareAddressLength);
218 bb.put(this.protocolAddressLength);
219 bb.putShort(this.opCode);
220 bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
221 bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
222 bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
223 bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
224 return data;
225 }
226
227 @Override
228 public IPacket deserialize(byte[] data, int offset, int length) {
229 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
230 this.hardwareType = bb.getShort();
231 this.protocolType = bb.getShort();
232 this.hardwareAddressLength = bb.get();
233 this.protocolAddressLength = bb.get();
234 this.opCode = bb.getShort();
235 this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
236 bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
237 this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
238 bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
239 this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
240 bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
241 this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
242 bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
243 return this;
244 }
245
246 /* (non-Javadoc)
247 * @see java.lang.Object#hashCode()
248 */
249 @Override
250 public int hashCode() {
251 final int prime = 13121;
252 int result = super.hashCode();
253 result = prime * result + hardwareAddressLength;
254 result = prime * result + hardwareType;
255 result = prime * result + opCode;
256 result = prime * result + protocolAddressLength;
257 result = prime * result + protocolType;
258 result = prime * result + Arrays.hashCode(senderHardwareAddress);
259 result = prime * result + Arrays.hashCode(senderProtocolAddress);
260 result = prime * result + Arrays.hashCode(targetHardwareAddress);
261 result = prime * result + Arrays.hashCode(targetProtocolAddress);
262 return result;
263 }
264
265 /* (non-Javadoc)
266 * @see java.lang.Object#equals(java.lang.Object)
267 */
268 @Override
269 public boolean equals(Object obj) {
270 if (this == obj)
271 return true;
272 if (!super.equals(obj))
273 return false;
274 if (!(obj instanceof ARP))
275 return false;
276 ARP other = (ARP) obj;
277 if (hardwareAddressLength != other.hardwareAddressLength)
278 return false;
279 if (hardwareType != other.hardwareType)
280 return false;
281 if (opCode != other.opCode)
282 return false;
283 if (protocolAddressLength != other.protocolAddressLength)
284 return false;
285 if (protocolType != other.protocolType)
286 return false;
287 if (!Arrays.equals(senderHardwareAddress, other.senderHardwareAddress))
288 return false;
289 if (!Arrays.equals(senderProtocolAddress, other.senderProtocolAddress))
290 return false;
291 if (!Arrays.equals(targetHardwareAddress, other.targetHardwareAddress))
292 return false;
293 if (!Arrays.equals(targetProtocolAddress, other.targetProtocolAddress))
294 return false;
295 return true;
296 }
297
298 /* (non-Javadoc)
299 * @see java.lang.Object#toString()
300 */
301 @Override
302 public String toString() {
303 return "ARP [hardwareType=" + hardwareType + ", protocolType="
304 + protocolType + ", hardwareAddressLength="
305 + hardwareAddressLength + ", protocolAddressLength="
306 + protocolAddressLength + ", opCode=" + opCode
307 + ", senderHardwareAddress="
308 + Arrays.toString(senderHardwareAddress)
309 + ", senderProtocolAddress="
310 + Arrays.toString(senderProtocolAddress)
311 + ", targetHardwareAddress="
312 + Arrays.toString(targetHardwareAddress)
313 + ", targetProtocolAddress="
314 + Arrays.toString(targetProtocolAddress) + "]";
315 }
316}