Charles M.C. Chan
Committed by Gerrit Code Review

Trace IPv6 hosts

ONOS-511: Implement NeighborSolicitation

Change-Id: I9aaf35d499cfc7885c74f9c4bf281210ef9f3969

ONOS-507: Trace NeighborSolicitation/NeighborAdvertisement/IPv6 packets in HostLocationProvider
	* Complete Javadoc of IPv6, ICMP6, NeighborAdvertisement and NeighborSolicitation
		- The Javadoc for serialize() is removed since the one in its superclass just works fine.
	* Change 'diffServ' in IPv6 to 'trafficClass' to meet the field name in RFC.
		- The setter method, getter method and unit test are also updated accordingly.
	* Add IpAddress.isZero() to determine if this address is zero.
		- The unit test is also updated accordingly.
	* Fix misuse of IpAddress.valueOf(int) in HostLocationProvider

Change-Id: Id0d873aeb1bc61bf26d4964e7aab4bb06ccd0a38
...@@ -46,6 +46,10 @@ import org.onosproject.net.topology.TopologyService; ...@@ -46,6 +46,10 @@ import org.onosproject.net.topology.TopologyService;
46 import org.onlab.packet.ARP; 46 import org.onlab.packet.ARP;
47 import org.onlab.packet.Ethernet; 47 import org.onlab.packet.Ethernet;
48 import org.onlab.packet.IpAddress; 48 import org.onlab.packet.IpAddress;
49 +import org.onlab.packet.IPacket;
50 +import org.onlab.packet.IPv6;
51 +import org.onlab.packet.NeighborAdvertisement;
52 +import org.onlab.packet.NeighborSolicitation;
49 import org.onlab.packet.VlanId; 53 import org.onlab.packet.VlanId;
50 import org.osgi.service.component.ComponentContext; 54 import org.osgi.service.component.ComponentContext;
51 import org.slf4j.Logger; 55 import org.slf4j.Logger;
...@@ -155,22 +159,43 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid ...@@ -155,22 +159,43 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
155 159
156 HostId hid = HostId.hostId(eth.getSourceMAC(), vlan); 160 HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
157 161
158 - // Potentially a new or moved host 162 + // ARP: possible new hosts, update both location and IP
159 if (eth.getEtherType() == Ethernet.TYPE_ARP) { 163 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
160 ARP arp = (ARP) eth.getPayload(); 164 ARP arp = (ARP) eth.getPayload();
161 - IpAddress ip = 165 + IpAddress ip = IpAddress.valueOf(IpAddress.Version.INET, arp.getSenderProtocolAddress());
162 - IpAddress.valueOf(IpAddress.Version.INET,
163 - arp.getSenderProtocolAddress());
164 HostDescription hdescr = 166 HostDescription hdescr =
165 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip); 167 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
166 providerService.hostDetected(hid, hdescr); 168 providerService.hostDetected(hid, hdescr);
167 169
170 + // IPv4: update location only
168 } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) { 171 } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
169 - //Do not learn new ip from ip packet.
170 HostDescription hdescr = 172 HostDescription hdescr =
171 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc); 173 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc);
172 providerService.hostDetected(hid, hdescr); 174 providerService.hostDetected(hid, hdescr);
173 175
176 + // NeighborAdvertisement and NeighborSolicitation: possible new hosts, update both location and IP
177 + // IPv6: update location only
178 + } else if (eth.getEtherType() == Ethernet.TYPE_IPV6) {
179 + IpAddress ip = null;
180 + IPv6 ipv6 = (IPv6) eth.getPayload();
181 +
182 + IPacket iPkt = ipv6;
183 + while (iPkt != null) {
184 + if (iPkt instanceof NeighborAdvertisement || iPkt instanceof NeighborSolicitation) {
185 + IpAddress sourceAddress =
186 + IpAddress.valueOf(IpAddress.Version.INET6, ipv6.getSourceAddress());
187 + // Ignore DAD packets, in which source address is all zeros.
188 + if (!sourceAddress.isZero()) {
189 + ip = sourceAddress;
190 + break;
191 + }
192 + }
193 + iPkt = iPkt.getPayload();
194 + }
195 + HostDescription hdescr = (ip == null) ?
196 + new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc) :
197 + new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
198 + providerService.hostDetected(hid, hdescr);
174 } 199 }
175 } 200 }
176 } 201 }
......
...@@ -23,8 +23,7 @@ import java.util.HashMap; ...@@ -23,8 +23,7 @@ import java.util.HashMap;
23 import java.util.Map; 23 import java.util.Map;
24 24
25 /** 25 /**
26 - * Implements ICMPv6 packet format. 26 + * Implements ICMPv6 packet format. (RFC 4443)
27 - *
28 */ 27 */
29 public class ICMP6 extends BasePacket { 28 public class ICMP6 extends BasePacket {
30 public static final byte HEADER_LENGTH = 4; // bytes 29 public static final byte HEADER_LENGTH = 4; // bytes
...@@ -37,6 +36,7 @@ public class ICMP6 extends BasePacket { ...@@ -37,6 +36,7 @@ public class ICMP6 extends BasePacket {
37 new HashMap<>(); 36 new HashMap<>();
38 37
39 static { 38 static {
39 + ICMP6.PROTOCOL_CLASS_MAP.put(ICMP6.NEIGHBOR_SOLICITATION, NeighborSolicitation.class);
40 ICMP6.PROTOCOL_CLASS_MAP.put(ICMP6.NEIGHBOR_ADVERTISEMENT, NeighborAdvertisement.class); 40 ICMP6.PROTOCOL_CLASS_MAP.put(ICMP6.NEIGHBOR_ADVERTISEMENT, NeighborAdvertisement.class);
41 } 41 }
42 42
...@@ -45,15 +45,18 @@ public class ICMP6 extends BasePacket { ...@@ -45,15 +45,18 @@ public class ICMP6 extends BasePacket {
45 protected short checksum; 45 protected short checksum;
46 46
47 /** 47 /**
48 - * @return the icmpType 48 + * Gets ICMP6 type.
49 + *
50 + * @return the ICMP6 type
49 */ 51 */
50 public byte getIcmpType() { 52 public byte getIcmpType() {
51 return this.icmpType; 53 return this.icmpType;
52 } 54 }
53 55
54 /** 56 /**
55 - * @param icmpType 57 + * Sets ICMP6 type.
56 - * to set 58 + *
59 + * @param icmpType the ICMP type to set
57 * @return this 60 * @return this
58 */ 61 */
59 public ICMP6 setIcmpType(final byte icmpType) { 62 public ICMP6 setIcmpType(final byte icmpType) {
...@@ -62,15 +65,18 @@ public class ICMP6 extends BasePacket { ...@@ -62,15 +65,18 @@ public class ICMP6 extends BasePacket {
62 } 65 }
63 66
64 /** 67 /**
65 - * @return the icmp code 68 + * Gets ICMP6 code.
69 + *
70 + * @return the ICMP6 code
66 */ 71 */
67 public byte getIcmpCode() { 72 public byte getIcmpCode() {
68 return this.icmpCode; 73 return this.icmpCode;
69 } 74 }
70 75
71 /** 76 /**
72 - * @param icmpCode 77 + * Sets ICMP6 code.
73 - * code to set 78 + *
79 + * @param icmpCode the ICMP6 code to set
74 * @return this 80 * @return this
75 */ 81 */
76 public ICMP6 setIcmpCode(final byte icmpCode) { 82 public ICMP6 setIcmpCode(final byte icmpCode) {
...@@ -79,6 +85,8 @@ public class ICMP6 extends BasePacket { ...@@ -79,6 +85,8 @@ public class ICMP6 extends BasePacket {
79 } 85 }
80 86
81 /** 87 /**
88 + * Gets checksum.
89 + *
82 * @return the checksum 90 * @return the checksum
83 */ 91 */
84 public short getChecksum() { 92 public short getChecksum() {
...@@ -86,8 +94,9 @@ public class ICMP6 extends BasePacket { ...@@ -86,8 +94,9 @@ public class ICMP6 extends BasePacket {
86 } 94 }
87 95
88 /** 96 /**
89 - * @param checksum 97 + * Sets checksum.
90 - * the checksum to set 98 + *
99 + * @param checksum the checksum to set
91 * @return this 100 * @return this
92 */ 101 */
93 public ICMP6 setChecksum(final short checksum) { 102 public ICMP6 setChecksum(final short checksum) {
...@@ -95,11 +104,6 @@ public class ICMP6 extends BasePacket { ...@@ -95,11 +104,6 @@ public class ICMP6 extends BasePacket {
95 return this; 104 return this;
96 } 105 }
97 106
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 107 @Override
104 public byte[] serialize() { 108 public byte[] serialize() {
105 byte[] payloadData = null; 109 byte[] payloadData = null;
......
...@@ -24,7 +24,7 @@ import java.util.HashMap; ...@@ -24,7 +24,7 @@ import java.util.HashMap;
24 import java.util.Map; 24 import java.util.Map;
25 25
26 /** 26 /**
27 - * 27 + * Implements IPv6 packet format. (RFC 2460)
28 */ 28 */
29 public class IPv6 extends BasePacket { 29 public class IPv6 extends BasePacket {
30 public static final byte FIXED_HEADER_LENGTH = 40; // bytes 30 public static final byte FIXED_HEADER_LENGTH = 40; // bytes
...@@ -43,7 +43,7 @@ public class IPv6 extends BasePacket { ...@@ -43,7 +43,7 @@ public class IPv6 extends BasePacket {
43 } 43 }
44 44
45 protected byte version; 45 protected byte version;
46 - protected byte diffServ; 46 + protected byte trafficClass;
47 protected int flowLabel; 47 protected int flowLabel;
48 protected short payloadLength; 48 protected short payloadLength;
49 protected byte nextHeader; 49 protected byte nextHeader;
...@@ -52,7 +52,7 @@ public class IPv6 extends BasePacket { ...@@ -52,7 +52,7 @@ public class IPv6 extends BasePacket {
52 protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH]; 52 protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH];
53 53
54 /** 54 /**
55 - * Default constructor that sets the version to 4. 55 + * Default constructor that sets the version to 6.
56 */ 56 */
57 public IPv6() { 57 public IPv6() {
58 super(); 58 super();
...@@ -60,15 +60,18 @@ public class IPv6 extends BasePacket { ...@@ -60,15 +60,18 @@ public class IPv6 extends BasePacket {
60 } 60 }
61 61
62 /** 62 /**
63 - * @return the version 63 + * Gets IP version.
64 + *
65 + * @return the IP version
64 */ 66 */
65 public byte getVersion() { 67 public byte getVersion() {
66 return this.version; 68 return this.version;
67 } 69 }
68 70
69 /** 71 /**
70 - * @param version 72 + * Sets IP version.
71 - * the version to set 73 + *
74 + * @param version the IP version to set
72 * @return this 75 * @return this
73 */ 76 */
74 public IPv6 setVersion(final byte version) { 77 public IPv6 setVersion(final byte version) {
...@@ -77,32 +80,38 @@ public class IPv6 extends BasePacket { ...@@ -77,32 +80,38 @@ public class IPv6 extends BasePacket {
77 } 80 }
78 81
79 /** 82 /**
80 - * @return the diffServ 83 + * Gets traffic class.
84 + *
85 + * @return the traffic class
81 */ 86 */
82 - public byte getDiffServ() { 87 + public byte getTrafficClass() {
83 - return this.diffServ; 88 + return this.trafficClass;
84 } 89 }
85 90
86 /** 91 /**
87 - * @param diffServ 92 + * Sets traffic class.
88 - * the diffServ to set 93 + *
94 + * @param trafficClass the traffic class to set
89 * @return this 95 * @return this
90 */ 96 */
91 - public IPv6 setDiffServ(final byte diffServ) { 97 + public IPv6 setTrafficClass(final byte trafficClass) {
92 - this.diffServ = diffServ; 98 + this.trafficClass = trafficClass;
93 return this; 99 return this;
94 } 100 }
95 101
96 /** 102 /**
97 - * @return the flowLabel 103 + * Gets flow label.
104 + *
105 + * @return the flow label
98 */ 106 */
99 public int getFlowLabel() { 107 public int getFlowLabel() {
100 return this.flowLabel; 108 return this.flowLabel;
101 } 109 }
102 110
103 /** 111 /**
104 - * @param flowLabel 112 + * Sets flow label.
105 - * the flowLabel to set 113 + *
114 + * @param flowLabel the flow label to set
106 * @return this 115 * @return this
107 */ 116 */
108 public IPv6 setFlowLabel(final int flowLabel) { 117 public IPv6 setFlowLabel(final int flowLabel) {
...@@ -111,15 +120,18 @@ public class IPv6 extends BasePacket { ...@@ -111,15 +120,18 @@ public class IPv6 extends BasePacket {
111 } 120 }
112 121
113 /** 122 /**
114 - * @return the nextHeader 123 + * Gets next header.
124 + *
125 + * @return the next header
115 */ 126 */
116 public byte getNextHeader() { 127 public byte getNextHeader() {
117 return this.nextHeader; 128 return this.nextHeader;
118 } 129 }
119 130
120 /** 131 /**
121 - * @param nextHeader 132 + * Sets next header.
122 - * the nextHeader to set 133 + *
134 + * @param nextHeader the next header to set
123 * @return this 135 * @return this
124 */ 136 */
125 public IPv6 setNextHeader(final byte nextHeader) { 137 public IPv6 setNextHeader(final byte nextHeader) {
...@@ -128,15 +140,18 @@ public class IPv6 extends BasePacket { ...@@ -128,15 +140,18 @@ public class IPv6 extends BasePacket {
128 } 140 }
129 141
130 /** 142 /**
131 - * @return the hopLimit 143 + * Gets hop limit.
144 + *
145 + * @return the hop limit
132 */ 146 */
133 public byte getHopLimit() { 147 public byte getHopLimit() {
134 return this.hopLimit; 148 return this.hopLimit;
135 } 149 }
136 150
137 /** 151 /**
138 - * @param hopLimit 152 + * Sets hop limit.
139 - * the hopLimit to set 153 + *
154 + * @param hopLimit the hop limit to set
140 * @return this 155 * @return this
141 */ 156 */
142 public IPv6 setHopLimit(final byte hopLimit) { 157 public IPv6 setHopLimit(final byte hopLimit) {
...@@ -145,15 +160,18 @@ public class IPv6 extends BasePacket { ...@@ -145,15 +160,18 @@ public class IPv6 extends BasePacket {
145 } 160 }
146 161
147 /** 162 /**
148 - * @return the sourceAddress 163 + * Gets source address.
164 + *
165 + * @return the IPv6 source address
149 */ 166 */
150 public byte[] getSourceAddress() { 167 public byte[] getSourceAddress() {
151 return this.sourceAddress; 168 return this.sourceAddress;
152 } 169 }
153 170
154 /** 171 /**
155 - * @param sourceAddress 172 + * Sets source address.
156 - * the sourceAddress to set 173 + *
174 + * @param sourceAddress the IPv6 source address to set
157 * @return this 175 * @return this
158 */ 176 */
159 public IPv6 setSourceAddress(final byte[] sourceAddress) { 177 public IPv6 setSourceAddress(final byte[] sourceAddress) {
...@@ -162,15 +180,18 @@ public class IPv6 extends BasePacket { ...@@ -162,15 +180,18 @@ public class IPv6 extends BasePacket {
162 } 180 }
163 181
164 /** 182 /**
165 - * @return the destinationAddress 183 + * Gets destination address.
184 + *
185 + * @return the IPv6 destination address
166 */ 186 */
167 public byte[] getDestinationAddress() { 187 public byte[] getDestinationAddress() {
168 return this.destinationAddress; 188 return this.destinationAddress;
169 } 189 }
170 190
171 /** 191 /**
172 - * @param destinationAddress 192 + * Sets destination address.
173 - * the destinationAddress to set 193 + *
194 + * @param destinationAddress the IPv6 destination address to set
174 * @return this 195 * @return this
175 */ 196 */
176 public IPv6 setDestinationAddress(final byte[] destinationAddress) { 197 public IPv6 setDestinationAddress(final byte[] destinationAddress) {
...@@ -191,7 +212,7 @@ public class IPv6 extends BasePacket { ...@@ -191,7 +212,7 @@ public class IPv6 extends BasePacket {
191 final byte[] data = new byte[FIXED_HEADER_LENGTH + payloadLength]; 212 final byte[] data = new byte[FIXED_HEADER_LENGTH + payloadLength];
192 final ByteBuffer bb = ByteBuffer.wrap(data); 213 final ByteBuffer bb = ByteBuffer.wrap(data);
193 214
194 - bb.putInt((this.version & 0xf) << 28 | (this.diffServ & 0xff) << 20 | this.flowLabel & 0xfffff); 215 + bb.putInt((this.version & 0xf) << 28 | (this.trafficClass & 0xff) << 20 | this.flowLabel & 0xfffff);
195 bb.putShort(this.payloadLength); 216 bb.putShort(this.payloadLength);
196 bb.put(this.nextHeader); 217 bb.put(this.nextHeader);
197 bb.put(this.hopLimit); 218 bb.put(this.hopLimit);
...@@ -213,7 +234,7 @@ public class IPv6 extends BasePacket { ...@@ -213,7 +234,7 @@ public class IPv6 extends BasePacket {
213 234
214 iscratch = bb.getInt(); 235 iscratch = bb.getInt();
215 this.version = (byte) (iscratch >> 28 & 0xf); 236 this.version = (byte) (iscratch >> 28 & 0xf);
216 - this.diffServ = (byte) (iscratch >> 20 & 0xff); 237 + this.trafficClass = (byte) (iscratch >> 20 & 0xff);
217 this.flowLabel = iscratch & 0xfffff; 238 this.flowLabel = iscratch & 0xfffff;
218 this.payloadLength = bb.getShort(); 239 this.payloadLength = bb.getShort();
219 this.nextHeader = bb.get(); 240 this.nextHeader = bb.get();
...@@ -255,7 +276,7 @@ public class IPv6 extends BasePacket { ...@@ -255,7 +276,7 @@ public class IPv6 extends BasePacket {
255 for (int i = 0; i < 4; i++) { 276 for (int i = 0; i < 4; i++) {
256 result = prime * result + bb.getInt(); 277 result = prime * result + bb.getInt();
257 } 278 }
258 - result = prime * result + this.diffServ; 279 + result = prime * result + this.trafficClass;
259 result = prime * result + this.flowLabel; 280 result = prime * result + this.flowLabel;
260 result = prime * result + this.hopLimit; 281 result = prime * result + this.hopLimit;
261 result = prime * result + this.nextHeader; 282 result = prime * result + this.nextHeader;
...@@ -288,7 +309,7 @@ public class IPv6 extends BasePacket { ...@@ -288,7 +309,7 @@ public class IPv6 extends BasePacket {
288 if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) { 309 if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) {
289 return false; 310 return false;
290 } 311 }
291 - if (this.diffServ != other.diffServ) { 312 + if (this.trafficClass != other.trafficClass) {
292 return false; 313 return false;
293 } 314 }
294 if (this.flowLabel != other.flowLabel) { 315 if (this.flowLabel != other.flowLabel) {
......
...@@ -274,6 +274,20 @@ public class IpAddress implements Comparable<IpAddress> { ...@@ -274,6 +274,20 @@ public class IpAddress implements Comparable<IpAddress> {
274 } 274 }
275 } 275 }
276 276
277 + /**
278 + * Check if this IP address is zero.
279 + *
280 + * @return true if this address is zero.
281 + */
282 + public boolean isZero() {
283 + for (byte b : octets) {
284 + if (b != 0) {
285 + return false;
286 + }
287 + }
288 + return true;
289 + }
290 +
277 @Override 291 @Override
278 public int compareTo(IpAddress o) { 292 public int compareTo(IpAddress o) {
279 // Compare first the version 293 // Compare first the version
......
...@@ -22,7 +22,7 @@ import java.nio.ByteBuffer; ...@@ -22,7 +22,7 @@ import java.nio.ByteBuffer;
22 import java.util.Arrays; 22 import java.util.Arrays;
23 23
24 /** 24 /**
25 - * Implements ICMPv6 Neighbor Solicitation packet format. 25 + * Implements ICMPv6 Neighbor Solicitation packet format. (RFC 4861)
26 */ 26 */
27 public class NeighborAdvertisement extends BasePacket { 27 public class NeighborAdvertisement extends BasePacket {
28 public static final byte HEADER_LENGTH = 20; // bytes 28 public static final byte HEADER_LENGTH = 20; // bytes
...@@ -33,16 +33,18 @@ public class NeighborAdvertisement extends BasePacket { ...@@ -33,16 +33,18 @@ public class NeighborAdvertisement extends BasePacket {
33 protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH]; 33 protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
34 34
35 /** 35 /**
36 + * Gets router flag.
36 * 37 *
37 - * @return true if router flag is set 38 + * @return the router flag
38 */ 39 */
39 public byte getRouterFlag() { 40 public byte getRouterFlag() {
40 return this.routerFlag; 41 return this.routerFlag;
41 } 42 }
42 43
43 /** 44 /**
44 - * @param routerFlag 45 + * Sets router flag.
45 - * the routerFlag to set 46 + *
47 + * @param routerFlag the router flag to set
46 * @return this 48 * @return this
47 */ 49 */
48 public NeighborAdvertisement setRouterFlag(final byte routerFlag) { 50 public NeighborAdvertisement setRouterFlag(final byte routerFlag) {
...@@ -51,16 +53,18 @@ public class NeighborAdvertisement extends BasePacket { ...@@ -51,16 +53,18 @@ public class NeighborAdvertisement extends BasePacket {
51 } 53 }
52 54
53 /** 55 /**
56 + * Gets solicited flag.
54 * 57 *
55 - * @return true if solicited flag is set 58 + * @return the solicited flag
56 */ 59 */
57 public byte getSolicitedFlag() { 60 public byte getSolicitedFlag() {
58 return this.solicitedFlag; 61 return this.solicitedFlag;
59 } 62 }
60 63
61 /** 64 /**
62 - * @param solicitedFlag 65 + * Sets solicited flag.
63 - * the routerFlag to set 66 + *
67 + * @param solicitedFlag the solicited flag to set
64 * @return this 68 * @return this
65 */ 69 */
66 public NeighborAdvertisement setSolicitedFlag(final byte solicitedFlag) { 70 public NeighborAdvertisement setSolicitedFlag(final byte solicitedFlag) {
...@@ -69,16 +73,18 @@ public class NeighborAdvertisement extends BasePacket { ...@@ -69,16 +73,18 @@ public class NeighborAdvertisement extends BasePacket {
69 } 73 }
70 74
71 /** 75 /**
76 + * Gets override flag.
72 * 77 *
73 - * @return true if override flag is set 78 + * @return the override flag
74 */ 79 */
75 public byte getOverrideFlag() { 80 public byte getOverrideFlag() {
76 return this.overrideFlag; 81 return this.overrideFlag;
77 } 82 }
78 83
79 /** 84 /**
80 - * @param overrideFlag 85 + * Sets override flag.
81 - * the routerFlag to set 86 + *
87 + * @param overrideFlag the override flag to set
82 * @return this 88 * @return this
83 */ 89 */
84 public NeighborAdvertisement setOverrideFlag(final byte overrideFlag) { 90 public NeighborAdvertisement setOverrideFlag(final byte overrideFlag) {
...@@ -87,6 +93,7 @@ public class NeighborAdvertisement extends BasePacket { ...@@ -87,6 +93,7 @@ public class NeighborAdvertisement extends BasePacket {
87 } 93 }
88 94
89 /** 95 /**
96 + * Gets target address.
90 * 97 *
91 * @return the target IPv6 address 98 * @return the target IPv6 address
92 */ 99 */
...@@ -95,8 +102,9 @@ public class NeighborAdvertisement extends BasePacket { ...@@ -95,8 +102,9 @@ public class NeighborAdvertisement extends BasePacket {
95 } 102 }
96 103
97 /** 104 /**
98 - * @param targetAddress 105 + * Sets target address.
99 - * the sourceAddress to set 106 + *
107 + * @param targetAddress the target IPv6 address to set
100 * @return this 108 * @return this
101 */ 109 */
102 public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) { 110 public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) {
...@@ -104,11 +112,6 @@ public class NeighborAdvertisement extends BasePacket { ...@@ -104,11 +112,6 @@ public class NeighborAdvertisement extends BasePacket {
104 return this; 112 return this;
105 } 113 }
106 114
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 115 @Override
113 public byte[] serialize() { 116 public byte[] serialize() {
114 byte[] payloadData = null; 117 byte[] payloadData = null;
......
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. (RFC 4861)
26 + */
27 +public class NeighborSolicitation extends BasePacket {
28 + public static final byte HEADER_LENGTH = 20; // bytes
29 +
30 + protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
31 +
32 + /**
33 + * Gets target address.
34 + *
35 + * @return the target IPv6 address
36 + */
37 + public byte[] getTargetAddress() {
38 + return this.targetAddress;
39 + }
40 +
41 + /**
42 + * Sets target address.
43 + *
44 + * @param targetAddress the target IPv6 address to set
45 + * @return this
46 + */
47 + public NeighborSolicitation setTargetAddress(final byte[] targetAddress) {
48 + this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
49 + return this;
50 + }
51 +
52 + @Override
53 + public byte[] serialize() {
54 + byte[] payloadData = null;
55 + if (this.payload != null) {
56 + this.payload.setParent(this);
57 + payloadData = this.payload.serialize();
58 + }
59 +
60 + int payloadLength = payloadData == null ? 0 : (short) payloadData.length;
61 +
62 + final byte[] data = new byte[HEADER_LENGTH + payloadLength];
63 + final ByteBuffer bb = ByteBuffer.wrap(data);
64 +
65 + bb.putInt(0);
66 + bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
67 + if (payloadData != null) {
68 + bb.put(payloadData);
69 + }
70 +
71 + return data;
72 + }
73 +
74 + @Override
75 + public IPacket deserialize(byte[] data, int offset, int length) {
76 + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
77 +
78 + bb.getInt();
79 + bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
80 +
81 + this.payload = new Data();
82 + this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
83 + - bb.position());
84 + this.payload.setParent(this);
85 +
86 + return this;
87 + }
88 +
89 + /*
90 + * (non-Javadoc)
91 + *
92 + * @see java.lang.Object#hashCode()
93 + */
94 + @Override
95 + public int hashCode() {
96 + final int prime = 5807;
97 + int result = super.hashCode();
98 + ByteBuffer bb;
99 + bb = ByteBuffer.wrap(this.targetAddress);
100 + for (int i = 0; i < 4; i++) {
101 + result = prime * result + bb.getInt();
102 + }
103 + return result;
104 + }
105 +
106 + /*
107 + * (non-Javadoc)
108 + *
109 + * @see java.lang.Object#equals(java.lang.Object)
110 + */
111 + @Override
112 + public boolean equals(final Object obj) {
113 + if (this == obj) {
114 + return true;
115 + }
116 + if (!super.equals(obj)) {
117 + return false;
118 + }
119 + if (!(obj instanceof NeighborSolicitation)) {
120 + return false;
121 + }
122 + final NeighborSolicitation other = (NeighborSolicitation) obj;
123 + if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
124 + return false;
125 + }
126 + return true;
127 + }
128 +}
...@@ -73,7 +73,7 @@ public class IPv6Test { ...@@ -73,7 +73,7 @@ public class IPv6Test {
73 IPv6 ipv6 = new IPv6(); 73 IPv6 ipv6 = new IPv6();
74 ipv6.setPayload(udp); 74 ipv6.setPayload(udp);
75 ipv6.setVersion((byte) 6); 75 ipv6.setVersion((byte) 6);
76 - ipv6.setDiffServ((byte) 0x93); 76 + ipv6.setTrafficClass((byte) 0x93);
77 ipv6.setFlowLabel(0x13579); 77 ipv6.setFlowLabel(0x13579);
78 ipv6.setNextHeader(IPv6.PROTOCOL_UDP); 78 ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
79 ipv6.setHopLimit((byte) 32); 79 ipv6.setHopLimit((byte) 32);
...@@ -92,7 +92,7 @@ public class IPv6Test { ...@@ -92,7 +92,7 @@ public class IPv6Test {
92 ipv6.deserialize(bytePacket, 0, bytePacket.length); 92 ipv6.deserialize(bytePacket, 0, bytePacket.length);
93 93
94 assertThat(ipv6.getVersion(), is((byte) 6)); 94 assertThat(ipv6.getVersion(), is((byte) 6));
95 - assertThat(ipv6.getDiffServ(), is((byte) 0x93)); 95 + assertThat(ipv6.getTrafficClass(), is((byte) 0x93));
96 assertThat(ipv6.getFlowLabel(), is(0x13579)); 96 assertThat(ipv6.getFlowLabel(), is(0x13579));
97 assertThat(ipv6.getNextHeader(), is(IPv6.PROTOCOL_UDP)); 97 assertThat(ipv6.getNextHeader(), is(IPv6.PROTOCOL_UDP));
98 assertThat(ipv6.getHopLimit(), is((byte) 32)); 98 assertThat(ipv6.getHopLimit(), is((byte) 32));
...@@ -108,7 +108,7 @@ public class IPv6Test { ...@@ -108,7 +108,7 @@ public class IPv6Test {
108 IPv6 packet1 = new IPv6(); 108 IPv6 packet1 = new IPv6();
109 packet1.setPayload(udp); 109 packet1.setPayload(udp);
110 packet1.setVersion((byte) 6); 110 packet1.setVersion((byte) 6);
111 - packet1.setDiffServ((byte) 0x93); 111 + packet1.setTrafficClass((byte) 0x93);
112 packet1.setFlowLabel(0x13579); 112 packet1.setFlowLabel(0x13579);
113 packet1.setNextHeader(IPv6.PROTOCOL_UDP); 113 packet1.setNextHeader(IPv6.PROTOCOL_UDP);
114 packet1.setHopLimit((byte) 32); 114 packet1.setHopLimit((byte) 32);
...@@ -118,7 +118,7 @@ public class IPv6Test { ...@@ -118,7 +118,7 @@ public class IPv6Test {
118 IPv6 packet2 = new IPv6(); 118 IPv6 packet2 = new IPv6();
119 packet2.setPayload(udp); 119 packet2.setPayload(udp);
120 packet2.setVersion((byte) 6); 120 packet2.setVersion((byte) 6);
121 - packet2.setDiffServ((byte) 0x93); 121 + packet2.setTrafficClass((byte) 0x93);
122 packet2.setFlowLabel(0x13579); 122 packet2.setFlowLabel(0x13579);
123 packet2.setNextHeader(IPv6.PROTOCOL_UDP); 123 packet2.setNextHeader(IPv6.PROTOCOL_UDP);
124 packet2.setHopLimit((byte) 32); 124 packet2.setHopLimit((byte) 32);
......
...@@ -26,6 +26,7 @@ import static org.hamcrest.Matchers.is; ...@@ -26,6 +26,7 @@ import static org.hamcrest.Matchers.is;
26 import static org.junit.Assert.assertNull; 26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertThat; 27 import static org.junit.Assert.assertThat;
28 import static org.junit.Assert.assertTrue; 28 import static org.junit.Assert.assertTrue;
29 +import static org.junit.Assert.assertFalse;
29 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutableBaseClass; 30 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutableBaseClass;
30 31
31 /** 32 /**
...@@ -703,6 +704,28 @@ public class IpAddressTest { ...@@ -703,6 +704,28 @@ public class IpAddressTest {
703 } 704 }
704 705
705 /** 706 /**
707 + * Tests if address is zero for IPv4.
708 + */
709 + @Test
710 + public void testIsZeroIPv4() {
711 + IpAddress normalIP = IpAddress.valueOf("10.0.0.1");
712 + IpAddress zeroIP = IpAddress.valueOf("0.0.0.0");
713 + assertFalse(normalIP.isZero());
714 + assertTrue(zeroIP.isZero());
715 + }
716 +
717 + /**
718 + * Tests if address is zero for IPv6.
719 + */
720 + @Test
721 + public void testIsZeroIPv6() {
722 + IpAddress normalIP = IpAddress.valueOf("fe80::1");
723 + IpAddress zeroIP = IpAddress.valueOf("::");
724 + assertFalse(normalIP.isZero());
725 + assertTrue(zeroIP.isZero());
726 + }
727 +
728 + /**
706 * Tests comparison of {@link IpAddress} for IPv4. 729 * Tests comparison of {@link IpAddress} for IPv4.
707 */ 730 */
708 @Test 731 @Test
......
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.junit.Assert.*;
25 +
26 +/**
27 + * Tests for class {@link org.onlab.packet.NeighborSolicitation}.
28 + */
29 +public class NeighborSolicitationTest {
30 + private static final byte[] TARGET_ADDRESS = {
31 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
32 + (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
33 + };
34 + private static final byte[] TARGET_ADDRESS2 = {
35 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
36 + (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
37 + };
38 + private static Data data;
39 + private static byte[] bytePacket;
40 +
41 + @BeforeClass
42 + public static void setUpBeforeClass() throws Exception {
43 + data = new Data();
44 + data.setData("".getBytes());
45 +
46 + byte[] bytePayload = data.serialize();
47 + byte[] byteHeader = {
48 + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
49 + (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
50 + (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
51 + };
52 + bytePacket = new byte[byteHeader.length + bytePayload.length];
53 + System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
54 + System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
55 + }
56 +
57 + /**
58 + * Tests serialize and setters.
59 + */
60 + @Test
61 + public void testSerialize() {
62 + NeighborSolicitation ns = new NeighborSolicitation();
63 + ns.setTargetAddress(TARGET_ADDRESS);
64 +
65 + assertArrayEquals(ns.serialize(), bytePacket);
66 + }
67 +
68 + /**
69 + * Tests deserialize and getters.
70 + */
71 + @Test
72 + public void testDeserialize() {
73 + NeighborSolicitation ns = new NeighborSolicitation();
74 + ns.deserialize(bytePacket, 0, bytePacket.length);
75 +
76 + assertArrayEquals(ns.getTargetAddress(), TARGET_ADDRESS);
77 + }
78 +
79 + /**
80 + * Tests comparator.
81 + */
82 + @Test
83 + public void testEqual() {
84 + NeighborSolicitation ns1 = new NeighborSolicitation();
85 + ns1.setTargetAddress(TARGET_ADDRESS);
86 +
87 + NeighborSolicitation ns2 = new NeighborSolicitation();
88 + ns2.setTargetAddress(TARGET_ADDRESS2);
89 +
90 + assertTrue(ns1.equals(ns1));
91 + assertFalse(ns1.equals(ns2));
92 + }
93 +}