Charles M.C. Chan

ONOS-508: Implement IPv6, ICMP6 and NeighborAdvertisement class

Create ICMP6 class, which is mostly like ICMP

Change-Id: I11d7abec4a8f1fd202e5dfb0a500f621773c2c3a

Create IPv6 class, which is mostly like IPv4

Change-Id: I7a301a0f94263df5d6d30f73050332ec7acfe611

Register handler class of IPv6 to Ethernet

Change-Id: Iccdef1680664520f9d66360a289809710982ce54

Fix FIXED_HEADER_LENGTH

Change-Id: Iff4fb22638416595f2865ff46b682a0579ba33d5

Fix payloadLength

Change-Id: I8dea4dd52f0bb5926fbff0d9e74fdd19404cabff

Add unittest for serialize

Change-Id: If194aa2530ce517a33b36b97b8478b0a4c463954

Add unittest for deserialize. Fix assertArrayEquals. Refine test structure.

Change-Id: I94f2a348b2be2f5907d8bac6b9029b37eb31456d

Payload length should be handled during serializing/deserializing procedure

Change-Id: Ib079bf939a01a38356c824ed972793293ed8ca1e

Add unittest for comparator

Change-Id: I937dd9330d7c23a81ecd8434ac0fcf7345cc5c00

Fix typo. Fix checkstyle error

Change-Id: I2fe1af81c65416b0fddaa0fb9ae206b87b889628

Add implementation and unittest for NeighborAdvertisement

Change-Id: I7610462a5712f9fee5be0416c08e1de302e0780d

Register handler class of NeighborAdvertisement to ICMP6

Change-Id: I3a7a9cf044cfdcd8908579942c159c2f0aad198d
...@@ -49,6 +49,7 @@ public class Ethernet extends BasePacket { ...@@ -49,6 +49,7 @@ public class Ethernet extends BasePacket {
49 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_ARP, ARP.class); 49 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_ARP, ARP.class);
50 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_RARP, ARP.class); 50 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_RARP, ARP.class);
51 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_IPV4, IPv4.class); 51 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_IPV4, IPv4.class);
52 + Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_IPV6, IPv6.class);
52 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_LLDP, LLDP.class); 53 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_LLDP, LLDP.class);
53 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_BSN, LLDP.class); 54 Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_BSN, LLDP.class);
54 } 55 }
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +
17 +
18 +
19 +package org.onlab.packet;
20 +
21 +import java.nio.ByteBuffer;
22 +import java.util.HashMap;
23 +import java.util.Map;
24 +
25 +/**
26 + * Implements ICMPv6 packet format.
27 + *
28 + */
29 +public class ICMP6 extends BasePacket {
30 + public static final byte HEADER_LENGTH = 4; // bytes
31 +
32 + public static final byte ROUTER_SOLICITATION = (byte) 0x85;
33 + public static final byte ROUTER_ADVERTISEMENT = (byte) 0x86;
34 + public static final byte NEIGHBOR_SOLICITATION = (byte) 0x87;
35 + public static final byte NEIGHBOR_ADVERTISEMENT = (byte) 0x88;
36 + public static final Map<Byte, Class<? extends IPacket>> PROTOCOL_CLASS_MAP =
37 + new HashMap<>();
38 +
39 + static {
40 + ICMP6.PROTOCOL_CLASS_MAP.put(ICMP6.NEIGHBOR_ADVERTISEMENT, NeighborAdvertisement.class);
41 + }
42 +
43 + protected byte icmpType;
44 + protected byte icmpCode;
45 + protected short checksum;
46 +
47 + /**
48 + * @return the icmpType
49 + */
50 + public byte getIcmpType() {
51 + return this.icmpType;
52 + }
53 +
54 + /**
55 + * @param icmpType
56 + * to set
57 + * @return this
58 + */
59 + public ICMP6 setIcmpType(final byte icmpType) {
60 + this.icmpType = icmpType;
61 + return this;
62 + }
63 +
64 + /**
65 + * @return the icmp code
66 + */
67 + public byte getIcmpCode() {
68 + return this.icmpCode;
69 + }
70 +
71 + /**
72 + * @param icmpCode
73 + * code to set
74 + * @return this
75 + */
76 + public ICMP6 setIcmpCode(final byte icmpCode) {
77 + this.icmpCode = icmpCode;
78 + return this;
79 + }
80 +
81 + /**
82 + * @return the checksum
83 + */
84 + public short getChecksum() {
85 + return this.checksum;
86 + }
87 +
88 + /**
89 + * @param checksum
90 + * the checksum to set
91 + * @return this
92 + */
93 + public ICMP6 setChecksum(final short checksum) {
94 + this.checksum = checksum;
95 + return this;
96 + }
97 +
98 + /**
99 + * Serializes the packet. Will compute and set the following fields if they
100 + * are set to specific values at the time serialize is called: -checksum : 0
101 + * -length : 0
102 + */
103 + @Override
104 + public byte[] serialize() {
105 + byte[] payloadData = null;
106 + if (this.payload != null) {
107 + this.payload.setParent(this);
108 + payloadData = this.payload.serialize();
109 + }
110 +
111 + int payloadLength = payloadData == null ? 0 : (short) payloadData.length;
112 +
113 + final byte[] data = new byte[HEADER_LENGTH + payloadLength];
114 + final ByteBuffer bb = ByteBuffer.wrap(data);
115 +
116 + bb.put(this.icmpType);
117 + bb.put(this.icmpCode);
118 + bb.putShort(this.checksum);
119 + if (payloadData != null) {
120 + bb.put(payloadData);
121 + }
122 +
123 + if (this.parent != null && this.parent instanceof IPv6) {
124 + ((IPv6) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6);
125 + }
126 +
127 + // compute checksum if needed
128 + if (this.checksum == 0) {
129 + bb.rewind();
130 + int accumulation = 0;
131 +
132 + for (int i = 0; i < data.length / 2; ++i) {
133 + accumulation += 0xffff & bb.getShort();
134 + }
135 + // pad to an even number of shorts
136 + if (data.length % 2 > 0) {
137 + accumulation += (bb.get() & 0xff) << 8;
138 + }
139 +
140 + accumulation = (accumulation >> 16 & 0xffff)
141 + + (accumulation & 0xffff);
142 + this.checksum = (short) (~accumulation & 0xffff);
143 + bb.putShort(2, this.checksum);
144 + }
145 + return data;
146 + }
147 +
148 + /*
149 + * (non-Javadoc)
150 + *
151 + * @see java.lang.Object#hashCode()
152 + */
153 + @Override
154 + public int hashCode() {
155 + final int prime = 5807;
156 + int result = super.hashCode();
157 + result = prime * result + this.icmpType;
158 + result = prime * result + this.icmpCode;
159 + result = prime * result + this.checksum;
160 + return result;
161 + }
162 +
163 + /*
164 + * (non-Javadoc)
165 + *
166 + * @see java.lang.Object#equals(java.lang.Object)
167 + */
168 + @Override
169 + public boolean equals(final Object obj) {
170 + if (this == obj) {
171 + return true;
172 + }
173 + if (!super.equals(obj)) {
174 + return false;
175 + }
176 + if (!(obj instanceof ICMP6)) {
177 + return false;
178 + }
179 + final ICMP6 other = (ICMP6) obj;
180 + if (this.icmpType != other.icmpType) {
181 + return false;
182 + }
183 + if (this.icmpCode != other.icmpCode) {
184 + return false;
185 + }
186 + if (this.checksum != other.checksum) {
187 + return false;
188 + }
189 + return true;
190 + }
191 +
192 + @Override
193 + public IPacket deserialize(final byte[] data, final int offset,
194 + final int length) {
195 + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
196 + this.icmpType = bb.get();
197 + this.icmpCode = bb.get();
198 + this.checksum = bb.getShort();
199 +
200 + IPacket payload;
201 + if (ICMP6.PROTOCOL_CLASS_MAP.containsKey(this.icmpType)) {
202 + final Class<? extends IPacket> clazz = ICMP6.PROTOCOL_CLASS_MAP
203 + .get(this.icmpType);
204 + try {
205 + payload = clazz.newInstance();
206 + } catch (final Exception e) {
207 + throw new RuntimeException(
208 + "Error parsing payload for ICMP6 packet", e);
209 + }
210 + } else {
211 + payload = new Data();
212 + }
213 + this.payload = payload.deserialize(data, bb.position(),
214 + bb.limit() - bb.position());
215 + this.payload.setParent(this);
216 +
217 + return this;
218 + }
219 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +
17 +
18 +
19 +package org.onlab.packet;
20 +
21 +import java.nio.ByteBuffer;
22 +import java.util.Arrays;
23 +import java.util.HashMap;
24 +import java.util.Map;
25 +
26 +/**
27 + *
28 + */
29 +public class IPv6 extends BasePacket {
30 + public static final byte FIXED_HEADER_LENGTH = 40; // bytes
31 +
32 + // TODO: Implement extension header.
33 + public static final byte PROTOCOL_TCP = 0x6;
34 + public static final byte PROTOCOL_UDP = 0x11;
35 + public static final byte PROTOCOL_ICMP6 = 0x3A;
36 + public static final Map<Byte, Class<? extends IPacket>> PROTOCOL_CLASS_MAP =
37 + new HashMap<>();
38 +
39 + static {
40 + IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_ICMP6, ICMP6.class);
41 + IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_TCP, TCP.class);
42 + IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_UDP, UDP.class);
43 + }
44 +
45 + protected byte version;
46 + protected byte diffServ;
47 + protected int flowLabel;
48 + protected short payloadLength;
49 + protected byte nextHeader;
50 + protected byte hopLimit;
51 + protected byte[] sourceAddress = new byte[Ip6Address.BYTE_LENGTH];
52 + protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH];
53 +
54 + /**
55 + * Default constructor that sets the version to 4.
56 + */
57 + public IPv6() {
58 + super();
59 + this.version = 6;
60 + }
61 +
62 + /**
63 + * @return the version
64 + */
65 + public byte getVersion() {
66 + return this.version;
67 + }
68 +
69 + /**
70 + * @param version
71 + * the version to set
72 + * @return this
73 + */
74 + public IPv6 setVersion(final byte version) {
75 + this.version = version;
76 + return this;
77 + }
78 +
79 + /**
80 + * @return the diffServ
81 + */
82 + public byte getDiffServ() {
83 + return this.diffServ;
84 + }
85 +
86 + /**
87 + * @param diffServ
88 + * the diffServ to set
89 + * @return this
90 + */
91 + public IPv6 setDiffServ(final byte diffServ) {
92 + this.diffServ = diffServ;
93 + return this;
94 + }
95 +
96 + /**
97 + * @return the flowLabel
98 + */
99 + public int getFlowLabel() {
100 + return this.flowLabel;
101 + }
102 +
103 + /**
104 + * @param flowLabel
105 + * the flowLabel to set
106 + * @return this
107 + */
108 + public IPv6 setFlowLabel(final int flowLabel) {
109 + this.flowLabel = flowLabel;
110 + return this;
111 + }
112 +
113 + /**
114 + * @return the nextHeader
115 + */
116 + public byte getNextHeader() {
117 + return this.nextHeader;
118 + }
119 +
120 + /**
121 + * @param nextHeader
122 + * the nextHeader to set
123 + * @return this
124 + */
125 + public IPv6 setNextHeader(final byte nextHeader) {
126 + this.nextHeader = nextHeader;
127 + return this;
128 + }
129 +
130 + /**
131 + * @return the hopLimit
132 + */
133 + public byte getHopLimit() {
134 + return this.hopLimit;
135 + }
136 +
137 + /**
138 + * @param hopLimit
139 + * the hopLimit to set
140 + * @return this
141 + */
142 + public IPv6 setHopLimit(final byte hopLimit) {
143 + this.hopLimit = hopLimit;
144 + return this;
145 + }
146 +
147 + /**
148 + * @return the sourceAddress
149 + */
150 + public byte[] getSourceAddress() {
151 + return this.sourceAddress;
152 + }
153 +
154 + /**
155 + * @param sourceAddress
156 + * the sourceAddress to set
157 + * @return this
158 + */
159 + public IPv6 setSourceAddress(final byte[] sourceAddress) {
160 + this.sourceAddress = Arrays.copyOfRange(sourceAddress, 0, Ip6Address.BYTE_LENGTH);
161 + return this;
162 + }
163 +
164 + /**
165 + * @return the destinationAddress
166 + */
167 + public byte[] getDestinationAddress() {
168 + return this.destinationAddress;
169 + }
170 +
171 + /**
172 + * @param destinationAddress
173 + * the destinationAddress to set
174 + * @return this
175 + */
176 + public IPv6 setDestinationAddress(final byte[] destinationAddress) {
177 + this.destinationAddress = Arrays.copyOfRange(destinationAddress, 0, Ip6Address.BYTE_LENGTH);
178 + return this;
179 + }
180 +
181 + @Override
182 + public byte[] serialize() {
183 + byte[] payloadData = null;
184 + if (this.payload != null) {
185 + this.payload.setParent(this);
186 + payloadData = this.payload.serialize();
187 + }
188 +
189 + this.payloadLength = payloadData == null ? 0 : (short) payloadData.length;
190 +
191 + final byte[] data = new byte[FIXED_HEADER_LENGTH + payloadLength];
192 + final ByteBuffer bb = ByteBuffer.wrap(data);
193 +
194 + bb.putInt((this.version & 0xf) << 28 | (this.diffServ & 0xff) << 20 | this.flowLabel & 0xfffff);
195 + bb.putShort(this.payloadLength);
196 + bb.put(this.nextHeader);
197 + bb.put(this.hopLimit);
198 + bb.put(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
199 + bb.put(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
200 +
201 + if (payloadData != null) {
202 + bb.put(payloadData);
203 + }
204 +
205 + return data;
206 + }
207 +
208 + @Override
209 + public IPacket deserialize(final byte[] data, final int offset,
210 + final int length) {
211 + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
212 + int iscratch;
213 +
214 + iscratch = bb.getInt();
215 + this.version = (byte) (iscratch >> 28 & 0xf);
216 + this.diffServ = (byte) (iscratch >> 20 & 0xff);
217 + this.flowLabel = iscratch & 0xfffff;
218 + this.payloadLength = bb.getShort();
219 + this.nextHeader = bb.get();
220 + this.hopLimit = bb.get();
221 + bb.get(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
222 + bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
223 +
224 + IPacket payload;
225 + if (IPv6.PROTOCOL_CLASS_MAP.containsKey(this.nextHeader)) {
226 + final Class<? extends IPacket> clazz = IPv6.PROTOCOL_CLASS_MAP
227 + .get(this.nextHeader);
228 + try {
229 + payload = clazz.newInstance();
230 + } catch (final Exception e) {
231 + throw new RuntimeException(
232 + "Error parsing payload for IPv6 packet", e);
233 + }
234 + } else {
235 + payload = new Data();
236 + }
237 + this.payload = payload.deserialize(data, bb.position(),
238 + bb.limit() - bb.position());
239 + this.payload.setParent(this);
240 +
241 + return this;
242 + }
243 +
244 + /*
245 + * (non-Javadoc)
246 + *
247 + * @see java.lang.Object#hashCode()
248 + */
249 + @Override
250 + public int hashCode() {
251 + final int prime = 2521;
252 + int result = super.hashCode();
253 + ByteBuffer bb;
254 + bb = ByteBuffer.wrap(this.destinationAddress);
255 + for (int i = 0; i < 4; i++) {
256 + result = prime * result + bb.getInt();
257 + }
258 + result = prime * result + this.diffServ;
259 + result = prime * result + this.flowLabel;
260 + result = prime * result + this.hopLimit;
261 + result = prime * result + this.nextHeader;
262 + result = prime * result + this.payloadLength;
263 + bb = ByteBuffer.wrap(this.sourceAddress);
264 + for (int i = 0; i < 4; i++) {
265 + result = prime * result + bb.getInt();
266 + }
267 + result = prime * result + this.version;
268 + return result;
269 + }
270 +
271 + /*
272 + * (non-Javadoc)
273 + *
274 + * @see java.lang.Object#equals(java.lang.Object)
275 + */
276 + @Override
277 + public boolean equals(final Object obj) {
278 + if (this == obj) {
279 + return true;
280 + }
281 + if (!super.equals(obj)) {
282 + return false;
283 + }
284 + if (!(obj instanceof IPv6)) {
285 + return false;
286 + }
287 + final IPv6 other = (IPv6) obj;
288 + if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) {
289 + return false;
290 + }
291 + if (this.diffServ != other.diffServ) {
292 + return false;
293 + }
294 + if (this.flowLabel != other.flowLabel) {
295 + return false;
296 + }
297 + if (this.hopLimit != other.hopLimit) {
298 + return false;
299 + }
300 + if (this.nextHeader != other.nextHeader) {
301 + return false;
302 + }
303 + if (this.payloadLength != other.payloadLength) {
304 + return false;
305 + }
306 + if (!Arrays.equals(this.sourceAddress, other.sourceAddress)) {
307 + return false;
308 + }
309 + return true;
310 + }
311 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +
17 +
18 +
19 +package org.onlab.packet;
20 +
21 +import java.nio.ByteBuffer;
22 +import java.util.Arrays;
23 +
24 +/**
25 + * Implements ICMPv6 Neighbor Solicitation packet format.
26 + */
27 +public class NeighborAdvertisement extends BasePacket {
28 + public static final byte HEADER_LENGTH = 20; // bytes
29 +
30 + protected byte routerFlag;
31 + protected byte solicitedFlag;
32 + protected byte overrideFlag;
33 + protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
34 +
35 + /**
36 + *
37 + * @return true if router flag is set
38 + */
39 + public byte getRouterFlag() {
40 + return this.routerFlag;
41 + }
42 +
43 + /**
44 + * @param routerFlag
45 + * the routerFlag to set
46 + * @return this
47 + */
48 + public NeighborAdvertisement setRouterFlag(final byte routerFlag) {
49 + this.routerFlag = routerFlag;
50 + return this;
51 + }
52 +
53 + /**
54 + *
55 + * @return true if solicited flag is set
56 + */
57 + public byte getSolicitedFlag() {
58 + return this.solicitedFlag;
59 + }
60 +
61 + /**
62 + * @param solicitedFlag
63 + * the routerFlag to set
64 + * @return this
65 + */
66 + public NeighborAdvertisement setSolicitedFlag(final byte solicitedFlag) {
67 + this.solicitedFlag = solicitedFlag;
68 + return this;
69 + }
70 +
71 + /**
72 + *
73 + * @return true if override flag is set
74 + */
75 + public byte getOverrideFlag() {
76 + return this.overrideFlag;
77 + }
78 +
79 + /**
80 + * @param overrideFlag
81 + * the routerFlag to set
82 + * @return this
83 + */
84 + public NeighborAdvertisement setOverrideFlag(final byte overrideFlag) {
85 + this.overrideFlag = overrideFlag;
86 + return this;
87 + }
88 +
89 + /**
90 + *
91 + * @return the target IPv6 address
92 + */
93 + public byte[] getTargetAddress() {
94 + return this.targetAddress;
95 + }
96 +
97 + /**
98 + * @param targetAddress
99 + * the sourceAddress to set
100 + * @return this
101 + */
102 + public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) {
103 + this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
104 + return this;
105 + }
106 +
107 + /**
108 + * Serializes the packet. Will compute and set the following fields if they
109 + * are set to specific values at the time serialize is called: -routerFlag : 0
110 + * -solicitedFlag : 0 -overrideFlag : 0
111 + */
112 + @Override
113 + public byte[] serialize() {
114 + byte[] payloadData = null;
115 + if (this.payload != null) {
116 + this.payload.setParent(this);
117 + payloadData = this.payload.serialize();
118 + }
119 +
120 + int payloadLength = payloadData == null ? 0 : (short) payloadData.length;
121 +
122 + final byte[] data = new byte[HEADER_LENGTH + payloadLength];
123 + final ByteBuffer bb = ByteBuffer.wrap(data);
124 +
125 + bb.putInt((this.routerFlag & 0x1) << 31 | (this.solicitedFlag & 0x1) << 30 | (this.overrideFlag & 0x1) << 29);
126 + bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
127 + if (payloadData != null) {
128 + bb.put(payloadData);
129 + }
130 +
131 + return data;
132 + }
133 +
134 + @Override
135 + public IPacket deserialize(byte[] data, int offset, int length) {
136 + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
137 + int iscratch;
138 +
139 + iscratch = bb.getInt();
140 + this.routerFlag = (byte) (iscratch >> 31 & 0x1);
141 + this.solicitedFlag = (byte) (iscratch >> 30 & 0x1);
142 + this.overrideFlag = (byte) (iscratch >> 29 & 0x1);
143 + bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
144 +
145 + this.payload = new Data();
146 + this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
147 + - bb.position());
148 + this.payload.setParent(this);
149 +
150 + return this;
151 + }
152 +
153 + /*
154 + * (non-Javadoc)
155 + *
156 + * @see java.lang.Object#hashCode()
157 + */
158 + @Override
159 + public int hashCode() {
160 + final int prime = 5807;
161 + int result = super.hashCode();
162 + ByteBuffer bb;
163 + result = prime * result + this.routerFlag;
164 + result = prime * result + this.solicitedFlag;
165 + result = prime * result + this.overrideFlag;
166 + bb = ByteBuffer.wrap(this.targetAddress);
167 + for (int i = 0; i < 4; i++) {
168 + result = prime * result + bb.getInt();
169 + }
170 + return result;
171 + }
172 +
173 + /*
174 + * (non-Javadoc)
175 + *
176 + * @see java.lang.Object#equals(java.lang.Object)
177 + */
178 + @Override
179 + public boolean equals(final Object obj) {
180 + if (this == obj) {
181 + return true;
182 + }
183 + if (!super.equals(obj)) {
184 + return false;
185 + }
186 + if (!(obj instanceof NeighborAdvertisement)) {
187 + return false;
188 + }
189 + final NeighborAdvertisement other = (NeighborAdvertisement) obj;
190 + if (this.routerFlag != other.routerFlag) {
191 + return false;
192 + }
193 + if (this.solicitedFlag != other.solicitedFlag) {
194 + return false;
195 + }
196 + if (this.overrideFlag != other.overrideFlag) {
197 + return false;
198 + }
199 + if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
200 + return false;
201 + }
202 + return true;
203 + }
204 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +
17 +
18 +
19 +package org.onlab.packet;
20 +
21 +import org.junit.BeforeClass;
22 +import org.junit.Test;
23 +
24 +import static org.hamcrest.Matchers.is;
25 +import static org.junit.Assert.assertThat;
26 +import static org.junit.Assert.assertArrayEquals;
27 +import static org.junit.Assert.assertTrue;
28 +import static org.junit.Assert.assertFalse;
29 +
30 +/**
31 + * Tests for class {@link IPv6}.
32 + */
33 +public class IPv6Test {
34 + private static final byte[] SOURCE_ADDRESS = {
35 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
36 + (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
37 + };
38 + private static final byte[] DESTINATION_ADDRESS = {
39 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
40 + (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
41 + };
42 + private static Data data;
43 + private static UDP udp;
44 + private static byte[] bytePacket;
45 +
46 + @BeforeClass
47 + public static void setUpBeforeClass() throws Exception {
48 + data = new Data();
49 + data.setData("testSerialize".getBytes());
50 + udp = new UDP();
51 + udp.setPayload(data);
52 +
53 + byte[] bytePayload = udp.serialize();
54 + byte[] byteHeader = {
55 + (byte) 0x69, (byte) 0x31, (byte) 0x35, (byte) 0x79,
56 + (byte) (bytePayload.length >> 8 & 0xff), (byte) (bytePayload.length & 0xff),
57 + (byte) 0x11, (byte) 0x20,
58 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
59 + (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
60 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
61 + (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8,
62 + };
63 + bytePacket = new byte[byteHeader.length + bytePayload.length];
64 + System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
65 + System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
66 + }
67 +
68 + /**
69 + * Tests serialize and setters.
70 + */
71 + @Test
72 + public void testSerialize() {
73 + IPv6 ipv6 = new IPv6();
74 + ipv6.setPayload(udp);
75 + ipv6.setVersion((byte) 6);
76 + ipv6.setDiffServ((byte) 0x93);
77 + ipv6.setFlowLabel(0x13579);
78 + ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
79 + ipv6.setHopLimit((byte) 32);
80 + ipv6.setSourceAddress(SOURCE_ADDRESS);
81 + ipv6.setDestinationAddress(DESTINATION_ADDRESS);
82 +
83 + assertArrayEquals(ipv6.serialize(), bytePacket);
84 + }
85 +
86 + /**
87 + * Tests deserialize and getters.
88 + */
89 + @Test
90 + public void testDeserialize() {
91 + IPv6 ipv6 = new IPv6();
92 + ipv6.deserialize(bytePacket, 0, bytePacket.length);
93 +
94 + assertThat(ipv6.getVersion(), is((byte) 6));
95 + assertThat(ipv6.getDiffServ(), is((byte) 0x93));
96 + assertThat(ipv6.getFlowLabel(), is(0x13579));
97 + assertThat(ipv6.getNextHeader(), is(IPv6.PROTOCOL_UDP));
98 + assertThat(ipv6.getHopLimit(), is((byte) 32));
99 + assertArrayEquals(ipv6.getSourceAddress(), SOURCE_ADDRESS);
100 + assertArrayEquals(ipv6.getDestinationAddress(), DESTINATION_ADDRESS);
101 + }
102 +
103 + /**
104 + * Tests comparator.
105 + */
106 + @Test
107 + public void testEqual() {
108 + IPv6 packet1 = new IPv6();
109 + packet1.setPayload(udp);
110 + packet1.setVersion((byte) 6);
111 + packet1.setDiffServ((byte) 0x93);
112 + packet1.setFlowLabel(0x13579);
113 + packet1.setNextHeader(IPv6.PROTOCOL_UDP);
114 + packet1.setHopLimit((byte) 32);
115 + packet1.setSourceAddress(SOURCE_ADDRESS);
116 + packet1.setDestinationAddress(DESTINATION_ADDRESS);
117 +
118 + IPv6 packet2 = new IPv6();
119 + packet2.setPayload(udp);
120 + packet2.setVersion((byte) 6);
121 + packet2.setDiffServ((byte) 0x93);
122 + packet2.setFlowLabel(0x13579);
123 + packet2.setNextHeader(IPv6.PROTOCOL_UDP);
124 + packet2.setHopLimit((byte) 32);
125 + packet2.setSourceAddress(DESTINATION_ADDRESS);
126 + packet2.setDestinationAddress(SOURCE_ADDRESS);
127 +
128 + assertTrue(packet1.equals(packet1));
129 + assertFalse(packet1.equals(packet2));
130 + }
131 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +
17 +
18 +
19 +package org.onlab.packet;
20 +
21 +import org.junit.BeforeClass;
22 +import org.junit.Test;
23 +
24 +import static org.hamcrest.Matchers.is;
25 +import static org.junit.Assert.*;
26 +
27 +/**
28 + * Tests for class {@link NeighborAdvertisement}.
29 + */
30 +public class NeighborAdvertisementTest {
31 + private static final byte[] TARGET_ADDRESS = {
32 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
33 + (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
34 + };
35 + private static Data data;
36 + private static byte[] bytePacket;
37 +
38 + @BeforeClass
39 + public static void setUpBeforeClass() throws Exception {
40 + data = new Data();
41 + data.setData("".getBytes());
42 +
43 + byte[] bytePayload = data.serialize();
44 + byte[] byteHeader = {
45 + (byte) 0xe0, (byte) 0x00, (byte) 0x00, (byte) 0x00,
46 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
47 + (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
48 + };
49 + bytePacket = new byte[byteHeader.length + bytePayload.length];
50 + System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
51 + System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
52 + }
53 +
54 + /**
55 + * Tests serialize and setters.
56 + */
57 + @Test
58 + public void testSerialize() {
59 + NeighborAdvertisement na = new NeighborAdvertisement();
60 + na.setRouterFlag((byte) 1);
61 + na.setSolicitedFlag((byte) 1);
62 + na.setOverrideFlag((byte) 1);
63 + na.setTargetAddress(TARGET_ADDRESS);
64 +
65 + assertArrayEquals(na.serialize(), bytePacket);
66 + }
67 +
68 + /**
69 + * Tests deserialize and getters.
70 + */
71 + @Test
72 + public void testDeserialize() {
73 + NeighborAdvertisement na = new NeighborAdvertisement();
74 + na.deserialize(bytePacket, 0, bytePacket.length);
75 +
76 + assertThat(na.getRouterFlag(), is((byte) 1));
77 + assertThat(na.getSolicitedFlag(), is((byte) 1));
78 + assertThat(na.getOverrideFlag(), is((byte) 1));
79 + assertArrayEquals(na.getTargetAddress(), TARGET_ADDRESS);
80 + }
81 +
82 + /**
83 + * Tests comparator.
84 + */
85 + @Test
86 + public void testEqual() {
87 + NeighborAdvertisement na1 = new NeighborAdvertisement();
88 + na1.setRouterFlag((byte) 1);
89 + na1.setSolicitedFlag((byte) 1);
90 + na1.setOverrideFlag((byte) 1);
91 + na1.setTargetAddress(TARGET_ADDRESS);
92 +
93 + NeighborAdvertisement na2 = new NeighborAdvertisement();
94 + na2.setRouterFlag((byte) 1);
95 + na2.setSolicitedFlag((byte) 1);
96 + na2.setOverrideFlag((byte) 0);
97 + na2.setTargetAddress(TARGET_ADDRESS);
98 +
99 + assertTrue(na1.equals(na1));
100 + assertFalse(na1.equals(na2));
101 + }
102 +}