Pavlin Radoslavov

Implemented a mechanism to easily add and access Neighbor Discovery protocol

packet options.

Fixes ONOS-1011

Change-Id: I94daa3f3c1297fb9a7b44901927738a29aff030a
......@@ -25,7 +25,6 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.ARP;
import org.onlab.packet.Data;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ICMP6;
import org.onlab.packet.IPv6;
......@@ -35,6 +34,7 @@ import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.packet.ndp.NeighborAdvertisement;
import org.onlab.packet.ndp.NeighborDiscoveryOptions;
import org.onlab.packet.ndp.NeighborSolicitation;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
......@@ -548,21 +548,10 @@ public class ProxyArpManager implements ProxyArpService {
nadv.setTargetAddress(srcIp.toOctets());
nadv.setSolicitedFlag((byte) 1);
nadv.setOverrideFlag((byte) 1);
byte[] nadvData =
new byte[NeighborAdvertisement.OPTION_LENGTH_IEEE802_ADDRESS];
ByteBuffer bbNadv = ByteBuffer.wrap(nadvData);
byte nadvOptionType =
NeighborAdvertisement.OPTION_TYPE_TARGET_LL_ADDRESS;
// The Option length in 8-octets units
byte nadvOptionLength =
(NeighborAdvertisement.OPTION_LENGTH_IEEE802_ADDRESS + 7) / 8;
bbNadv.put(nadvOptionType);
bbNadv.put(nadvOptionLength);
bbNadv.put(srcMac.toBytes());
Data nadvPayload = new Data();
nadv.setPayload(nadvPayload.deserialize(nadvData, 0, nadvData.length));
icmp6.setPayload(nadv);
nadv.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
srcMac.toBytes());
icmp6.setPayload(nadv);
ipv6.setPayload(icmp6);
eth.setPayload(ipv6);
return eth;
......
......@@ -16,30 +16,27 @@
package org.onlab.packet.ndp;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.Ip6Address;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
/**
* Implements ICMPv6 Neighbor Advertisement packet format (RFC 4861).
*/
public class NeighborAdvertisement extends BasePacket {
public static final byte HEADER_LENGTH = 20; // bytes
public static final byte OPTION_TYPE_SOURCE_LL_ADDRESS = 1;
public static final byte OPTION_TYPE_TARGET_LL_ADDRESS = 2;
public static final byte OPTION_TYPE_PREFIX_INFORMATION = 3;
public static final byte OPTION_TYPE_REDIRECTED_HEADER = 4;
public static final byte OPTION_TYPE_MTU = 5;
public static final byte OPTION_LENGTH_IEEE802_ADDRESS = 8;
protected byte routerFlag;
protected byte solicitedFlag;
protected byte overrideFlag;
protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
private final NeighborDiscoveryOptions options =
new NeighborDiscoveryOptions();
/**
* Gets router flag.
*
......@@ -116,30 +113,54 @@ public class NeighborAdvertisement extends BasePacket {
* @return this
*/
public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) {
this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
this.targetAddress =
Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
return this;
}
/**
* Gets the Neighbor Discovery Protocol packet options.
*
* @return the Neighbor Discovery Protocol packet options
*/
public List<NeighborDiscoveryOptions.Option> getOptions() {
return this.options.options();
}
/**
* Adds a Neighbor Discovery Protocol packet option.
*
* @param type the option type
* @param data the option data
* @return this
*/
public NeighborAdvertisement addOption(final byte type,
final byte[] data) {
this.options.addOption(type, data);
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
byte[] optionsData = null;
if (this.options.hasOptions()) {
optionsData = this.options.serialize();
}
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
int optionsLength = 0;
if (optionsData != null) {
optionsLength = optionsData.length;
}
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final byte[] data = new byte[HEADER_LENGTH + optionsLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putInt((this.routerFlag & 0x1) << 31 | (this.solicitedFlag & 0x1) << 30 | (this.overrideFlag & 0x1) << 29);
bb.putInt((this.routerFlag & 0x1) << 31 |
(this.solicitedFlag & 0x1) << 30 |
(this.overrideFlag & 0x1) << 29);
bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
if (payloadData != null) {
bb.put(payloadData);
if (optionsData != null) {
bb.put(optionsData);
}
return data;
......@@ -156,10 +177,8 @@ public class NeighborAdvertisement extends BasePacket {
this.overrideFlag = (byte) (iscratch >> 29 & 0x1);
bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
this.payload = new Data();
this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- bb.position());
this.payload.setParent(this);
this.options.deserialize(data, bb.position(),
bb.limit() - bb.position());
return this;
}
......@@ -178,9 +197,10 @@ public class NeighborAdvertisement extends BasePacket {
result = prime * result + this.solicitedFlag;
result = prime * result + this.overrideFlag;
bb = ByteBuffer.wrap(this.targetAddress);
for (int i = 0; i < 4; i++) {
for (int i = 0; i < this.targetAddress.length / 4; i++) {
result = prime * result + bb.getInt();
}
result = prime * result + this.options.hashCode();
return result;
}
......@@ -213,6 +233,9 @@ public class NeighborAdvertisement extends BasePacket {
if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
return false;
}
if (!this.options.equals(other.options)) {
return false;
}
return true;
}
}
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.onlab.packet.BasePacket;
import org.onlab.packet.IPacket;
/**
* Neighbor Discovery Protocol packet options.
*/
public class NeighborDiscoveryOptions extends BasePacket {
public static final byte TYPE_SOURCE_LL_ADDRESS = 1;
public static final byte TYPE_TARGET_LL_ADDRESS = 2;
public static final byte TYPE_PREFIX_INFORMATION = 3;
public static final byte TYPE_REDIRECTED_HEADER = 4;
public static final byte TYPE_MTU = 5;
private final List<Option> options = new ArrayList<>();
/**
* Packet option.
*/
public final class Option {
private final byte type;
private final byte[] data;
/**
* Constructor.
*
* @param type the option type
* @param data the option data
*/
private Option(byte type, byte[] data) {
this.type = type;
this.data = Arrays.copyOfRange(data, 0, data.length);
}
/**
* Gets the option type.
*
* @return the option type
*/
public byte type() {
return this.type;
}
/**
* Gets the option data.
*
* @return the option data
*/
public byte[] data() {
return this.data;
}
/**
* Gets the option data length (in number of octets).
*
* @return the option data length (in number of octets)
*/
public int dataLength() {
return data.length;
}
/**
* Gets the option length (in number of octets), including the type and
* length fields (one octet each).
*
* @return the option length (in number of octets), including the type
* and length fields
*/
private int optionLength() {
return 2 + dataLength();
}
/**
* Gets the option length field value (in units of 8 octets).
*
* @return the option length field value (in units of 8 octets)
*/
private byte optionLengthField() {
return (byte) ((optionLength() + 7) / 8);
}
/**
* Gets the option length on the wire (in number of octets).
*
* @return the option length on the wire (in number of octets)
*/
private int optionWireLength() {
return 8 * optionLengthField();
}
}
/**
* Adds a Neighbor Discovery Protocol packet option.
*
* @param type the option type
* @param data the option data
* @return this
*/
public NeighborDiscoveryOptions addOption(byte type, byte[] data) {
options.add(new Option(type, data));
return this;
}
/**
* Gets the Neighbor Discovery Protocol packet options.
*
* @return the Neighbor Discovery Protocol packet options
*/
public List<NeighborDiscoveryOptions.Option> options() {
return this.options;
}
/**
* Checks whether any options are included.
*
* @return true if options are included, otherwise false
*/
public boolean hasOptions() {
return !this.options.isEmpty();
}
@Override
public byte[] serialize() {
// Compute first the total length on the wire for all options
int wireLength = 0;
for (Option option : this.options) {
wireLength += option.optionWireLength();
}
final byte[] data = new byte[wireLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
//
// Serialize all options
//
for (Option option : this.options) {
bb.put(option.type());
bb.put(option.optionLengthField());
bb.put(option.data());
// Add the padding
int paddingLength =
option.optionWireLength() - option.optionLength();
for (int i = 0; i < paddingLength; i++) {
bb.put((byte) 0);
}
}
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
options.clear();
//
// Deserialize all options
//
while (bb.hasRemaining()) {
byte type = bb.get();
if (!bb.hasRemaining()) {
break;
}
byte lengthField = bb.get();
int dataLength = lengthField * 8; // The data length field is in
// unit of 8 octets
// Exclude the type and length fields
if (dataLength < 2) {
break;
}
dataLength -= 2;
if (bb.remaining() < dataLength) {
break;
}
byte[] optionData = new byte[dataLength];
bb.get(optionData, 0, optionData.length);
addOption(type, optionData);
}
return this;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
for (Option option : this.options) {
result = prime * result + option.type();
result = prime * result + Arrays.hashCode(option.data());
}
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof NeighborDiscoveryOptions) {
NeighborDiscoveryOptions other = (NeighborDiscoveryOptions) obj;
return this.options.equals(other.options);
}
return false;
}
}
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,18 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.Ip6Address;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
/**
* Implements ICMPv6 Neighbor Solicitation packet format. (RFC 4861)
......@@ -34,6 +31,9 @@ public class NeighborSolicitation extends BasePacket {
protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
private final NeighborDiscoveryOptions options =
new NeighborDiscoveryOptions();
/**
* Gets target address.
*
......@@ -50,30 +50,52 @@ public class NeighborSolicitation extends BasePacket {
* @return this
*/
public NeighborSolicitation setTargetAddress(final byte[] targetAddress) {
this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
this.targetAddress =
Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
return this;
}
/**
* Gets the Neighbor Discovery Protocol packet options.
*
* @return the Neighbor Discovery Protocol packet options
*/
public List<NeighborDiscoveryOptions.Option> getOptions() {
return this.options.options();
}
/**
* Adds a Neighbor Discovery Protocol packet option.
*
* @param type the option type
* @param data the option data
* @return this
*/
public NeighborSolicitation addOption(final byte type,
final byte[] data) {
this.options.addOption(type, data);
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
byte[] optionsData = null;
if (this.options.hasOptions()) {
optionsData = this.options.serialize();
}
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
int optionsLength = 0;
if (optionsData != null) {
optionsLength = optionsData.length;
}
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final byte[] data = new byte[HEADER_LENGTH + optionsLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putInt(0);
bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
if (payloadData != null) {
bb.put(payloadData);
if (optionsData != null) {
bb.put(optionsData);
}
return data;
......@@ -86,10 +108,8 @@ public class NeighborSolicitation extends BasePacket {
bb.getInt();
bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
this.payload = new Data();
this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- bb.position());
this.payload.setParent(this);
this.options.deserialize(data, bb.position(),
bb.limit() - bb.position());
return this;
}
......@@ -105,9 +125,10 @@ public class NeighborSolicitation extends BasePacket {
int result = super.hashCode();
ByteBuffer bb;
bb = ByteBuffer.wrap(this.targetAddress);
for (int i = 0; i < 4; i++) {
for (int i = 0; i < this.targetAddress.length / 4; i++) {
result = prime * result + bb.getInt();
}
result = prime * result + this.options.hashCode();
return result;
}
......@@ -131,6 +152,9 @@ public class NeighborSolicitation extends BasePacket {
if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
return false;
}
if (!this.options.equals(other.options)) {
return false;
}
return true;
}
}
......
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,18 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.Ip6Address;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
/**
* Implements ICMPv6 Redirect packet format. (RFC 4861)
......@@ -35,6 +32,9 @@ public class Redirect extends BasePacket {
protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH];
private final NeighborDiscoveryOptions options =
new NeighborDiscoveryOptions();
/**
* Gets target address.
*
......@@ -51,7 +51,8 @@ public class Redirect extends BasePacket {
* @return this
*/
public Redirect setTargetAddress(final byte[] targetAddress) {
this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
this.targetAddress =
Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
return this;
}
......@@ -71,32 +72,52 @@ public class Redirect extends BasePacket {
* @return this
*/
public Redirect setDestinationAddress(final byte[] destinationAddress) {
this.destinationAddress = Arrays.copyOfRange(destinationAddress, 0, Ip6Address.BYTE_LENGTH);
this.destinationAddress =
Arrays.copyOfRange(destinationAddress, 0, Ip6Address.BYTE_LENGTH);
return this;
}
/**
* Gets the Neighbor Discovery Protocol packet options.
*
* @return the Neighbor Discovery Protocol packet options
*/
public List<NeighborDiscoveryOptions.Option> getOptions() {
return this.options.options();
}
/**
* Adds a Neighbor Discovery Protocol packet option.
*
* @param type the option type
* @param data the option data
* @return this
*/
public Redirect addOption(final byte type, final byte[] data) {
this.options.addOption(type, data);
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
byte[] optionsData = null;
if (this.options.hasOptions()) {
optionsData = this.options.serialize();
}
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
int optionsLength = 0;
if (optionsData != null) {
optionsLength = optionsData.length;
}
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final byte[] data = new byte[HEADER_LENGTH + optionsLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putInt(0);
bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
bb.put(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
if (payloadData != null) {
bb.put(payloadData);
if (optionsData != null) {
bb.put(optionsData);
}
return data;
......@@ -110,10 +131,8 @@ public class Redirect extends BasePacket {
bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
this.payload = new Data();
this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- bb.position());
this.payload.setParent(this);
this.options.deserialize(data, bb.position(),
bb.limit() - bb.position());
return this;
}
......@@ -129,13 +148,14 @@ public class Redirect extends BasePacket {
int result = super.hashCode();
ByteBuffer bb;
bb = ByteBuffer.wrap(this.targetAddress);
for (int i = 0; i < 4; i++) {
for (int i = 0; i < this.targetAddress.length / 4; i++) {
result = prime * result + bb.getInt();
}
bb = ByteBuffer.wrap(this.destinationAddress);
for (int i = 0; i < 4; i++) {
for (int i = 0; i < this.destinationAddress.length / 4; i++) {
result = prime * result + bb.getInt();
}
result = prime * result + this.options.hashCode();
return result;
}
......@@ -159,7 +179,11 @@ public class Redirect extends BasePacket {
if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
return false;
}
if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) {
if (!Arrays.equals(this.destinationAddress,
other.destinationAddress)) {
return false;
}
if (!this.options.equals(other.options)) {
return false;
}
return true;
......
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,16 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import java.nio.ByteBuffer;
import java.util.List;
/**
* Implements ICMPv6 Router Advertisement packet format. (RFC 4861)
......@@ -37,6 +34,9 @@ public class RouterAdvertisement extends BasePacket {
protected int reachableTime;
protected int retransmitTimer;
private final NeighborDiscoveryOptions options =
new NeighborDiscoveryOptions();
/**
* Gets current hop limit.
*
......@@ -157,20 +157,40 @@ public class RouterAdvertisement extends BasePacket {
return this;
}
/**
* Gets the Neighbor Discovery Protocol packet options.
*
* @return the Neighbor Discovery Protocol packet options
*/
public List<NeighborDiscoveryOptions.Option> getOptions() {
return this.options.options();
}
/**
* Adds a Neighbor Discovery Protocol packet option.
*
* @param type the option type
* @param data the option data
* @return this
*/
public RouterAdvertisement addOption(final byte type, final byte[] data) {
this.options.addOption(type, data);
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
byte[] optionsData = null;
if (this.options.hasOptions()) {
optionsData = this.options.serialize();
}
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
int optionsLength = 0;
if (optionsData != null) {
optionsLength = optionsData.length;
}
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final byte[] data = new byte[HEADER_LENGTH + optionsLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.currentHopLimit);
......@@ -179,8 +199,8 @@ public class RouterAdvertisement extends BasePacket {
bb.putInt(reachableTime);
bb.putInt(retransmitTimer);
if (payloadData != null) {
bb.put(payloadData);
if (optionsData != null) {
bb.put(optionsData);
}
return data;
......@@ -199,10 +219,8 @@ public class RouterAdvertisement extends BasePacket {
this.reachableTime = bb.getInt();
this.retransmitTimer = bb.getInt();
this.payload = new Data();
this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- bb.position());
this.payload.setParent(this);
this.options.deserialize(data, bb.position(),
bb.limit() - bb.position());
return this;
}
......@@ -222,6 +240,7 @@ public class RouterAdvertisement extends BasePacket {
result = prime * result + this.routerLifetime;
result = prime * result + this.reachableTime;
result = prime * result + this.retransmitTimer;
result = prime * result + this.options.hashCode();
return result;
}
......@@ -260,6 +279,9 @@ public class RouterAdvertisement extends BasePacket {
if (this.retransmitTimer != other.retransmitTimer) {
return false;
}
if (!this.options.equals(other.options)) {
return false;
}
return true;
}
}
......
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,16 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import java.nio.ByteBuffer;
import java.util.List;
/**
* Implements ICMPv6 Router Solicitation packet format. (RFC 4861)
......@@ -30,26 +27,49 @@ import java.nio.ByteBuffer;
public class RouterSolicitation extends BasePacket {
public static final byte HEADER_LENGTH = 4; // bytes
private final NeighborDiscoveryOptions options =
new NeighborDiscoveryOptions();
/**
* Gets the Neighbor Discovery Protocol packet options.
*
* @return the Neighbor Discovery Protocol packet options
*/
public List<NeighborDiscoveryOptions.Option> getOptions() {
return this.options.options();
}
/**
* Adds a Neighbor Discovery Protocol packet option.
*
* @param type the option type
* @param data the option data
* @return this
*/
public RouterSolicitation addOption(final byte type, final byte[] data) {
this.options.addOption(type, data);
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
byte[] optionsData = null;
if (this.options.hasOptions()) {
optionsData = this.options.serialize();
}
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
int optionsLength = 0;
if (optionsData != null) {
optionsLength = optionsData.length;
}
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final byte[] data = new byte[HEADER_LENGTH + optionsLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putInt(0);
if (payloadData != null) {
bb.put(payloadData);
if (optionsData != null) {
bb.put(optionsData);
}
return data;
......@@ -61,10 +81,8 @@ public class RouterSolicitation extends BasePacket {
bb.getInt();
this.payload = new Data();
this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
- bb.position());
this.payload.setParent(this);
this.options.deserialize(data, bb.position(),
bb.limit() - bb.position());
return this;
}
......@@ -76,7 +94,10 @@ public class RouterSolicitation extends BasePacket {
*/
@Override
public int hashCode() {
return super.hashCode();
final int prime = 5807;
int result = super.hashCode();
result = prime * result + this.options.hashCode();
return result;
}
/*
......@@ -95,6 +116,10 @@ public class RouterSolicitation extends BasePacket {
if (!(obj instanceof RouterSolicitation)) {
return false;
}
final RouterSolicitation other = (RouterSolicitation) obj;
if (!this.options.equals(other.options)) {
return false;
}
return true;
}
}
......
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,46 +13,46 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.MacAddress;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Tests for class {@link NeighborAdvertisement}.
*/
public class NeighborAdvertisementTest {
private static final byte[] TARGET_ADDRESS = {
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
(byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
};
private static Data data;
private static final MacAddress MAC_ADDRESS =
MacAddress.valueOf("11:22:33:44:55:66");
private static byte[] bytePacket;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
data = new Data();
data.setData("".getBytes());
byte[] bytePayload = data.serialize();
byte[] byteHeader = {
(byte) 0xe0, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
(byte) 0xe0, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
(byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
(byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
(byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
};
bytePacket = new byte[byteHeader.length + bytePayload.length];
bytePacket = new byte[byteHeader.length];
System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
}
/**
......@@ -65,7 +65,8 @@ public class NeighborAdvertisementTest {
na.setSolicitedFlag((byte) 1);
na.setOverrideFlag((byte) 1);
na.setTargetAddress(TARGET_ADDRESS);
na.setPayload(data);
na.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
assertArrayEquals(na.serialize(), bytePacket);
}
......@@ -82,6 +83,13 @@ public class NeighborAdvertisementTest {
assertThat(na.getSolicitedFlag(), is((byte) 1));
assertThat(na.getOverrideFlag(), is((byte) 1));
assertArrayEquals(na.getTargetAddress(), TARGET_ADDRESS);
// Check the option(s)
assertThat(na.getOptions().size(), is(1));
NeighborDiscoveryOptions.Option option = na.getOptions().get(0);
assertThat(option.type(),
is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
assertArrayEquals(option.data(), MAC_ADDRESS.toBytes());
}
/**
......@@ -94,12 +102,16 @@ public class NeighborAdvertisementTest {
na1.setSolicitedFlag((byte) 1);
na1.setOverrideFlag((byte) 1);
na1.setTargetAddress(TARGET_ADDRESS);
na1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
NeighborAdvertisement na2 = new NeighborAdvertisement();
na2.setRouterFlag((byte) 1);
na2.setSolicitedFlag((byte) 1);
na2.setOverrideFlag((byte) 0);
na2.setTargetAddress(TARGET_ADDRESS);
na2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
assertTrue(na1.equals(na1));
assertFalse(na1.equals(na2));
......
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,47 +13,52 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.MacAddress;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Tests for class {@link NeighborSolicitation}.
*/
public class NeighborSolicitationTest {
private static final byte[] TARGET_ADDRESS = {
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
(byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
};
private static final byte[] TARGET_ADDRESS2 = {
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff,
(byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
};
private static Data data;
private static final MacAddress MAC_ADDRESS =
MacAddress.valueOf("11:22:33:44:55:66");
private static byte[] bytePacket;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
data = new Data();
data.setData("".getBytes());
byte[] bytePayload = data.serialize();
byte[] byteHeader = {
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
(byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
(byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
(byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
};
bytePacket = new byte[byteHeader.length + bytePayload.length];
bytePacket = new byte[byteHeader.length];
System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
}
/**
......@@ -63,7 +68,8 @@ public class NeighborSolicitationTest {
public void testSerialize() {
NeighborSolicitation ns = new NeighborSolicitation();
ns.setTargetAddress(TARGET_ADDRESS);
ns.setPayload(data);
ns.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
assertArrayEquals(ns.serialize(), bytePacket);
}
......@@ -77,6 +83,13 @@ public class NeighborSolicitationTest {
ns.deserialize(bytePacket, 0, bytePacket.length);
assertArrayEquals(ns.getTargetAddress(), TARGET_ADDRESS);
// Check the option(s)
assertThat(ns.getOptions().size(), is(1));
NeighborDiscoveryOptions.Option option = ns.getOptions().get(0);
assertThat(option.type(),
is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
assertArrayEquals(option.data(), MAC_ADDRESS.toBytes());
}
/**
......@@ -86,9 +99,13 @@ public class NeighborSolicitationTest {
public void testEqual() {
NeighborSolicitation ns1 = new NeighborSolicitation();
ns1.setTargetAddress(TARGET_ADDRESS);
ns1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
NeighborSolicitation ns2 = new NeighborSolicitation();
ns2.setTargetAddress(TARGET_ADDRESS2);
ns2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
assertTrue(ns1.equals(ns1));
assertFalse(ns1.equals(ns2));
......
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,54 +13,62 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.MacAddress;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Tests for class {@link Redirect}.
*/
public class RedirectTest {
private static final byte[] TARGET_ADDRESS = {
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
};
private static final byte[] DESTINATION_ADDRESS = {
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
(byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
};
private static final byte[] DESTINATION_ADDRESS2 = {
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff,
(byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
};
private static Data data;
private static final MacAddress MAC_ADDRESS =
MacAddress.valueOf("11:22:33:44:55:66");
private static byte[] bytePacket;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
data = new Data();
data.setData("".getBytes());
byte[] bytePayload = data.serialize();
byte[] byteHeader = {
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18,
(byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
(byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff,
(byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
(byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
(byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
};
bytePacket = new byte[byteHeader.length + bytePayload.length];
bytePacket = new byte[byteHeader.length];
System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
}
/**
......@@ -71,7 +79,8 @@ public class RedirectTest {
Redirect rd = new Redirect();
rd.setTargetAddress(TARGET_ADDRESS);
rd.setDestinationAddress(DESTINATION_ADDRESS);
rd.setPayload(data);
rd.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
assertArrayEquals(rd.serialize(), bytePacket);
}
......@@ -86,6 +95,13 @@ public class RedirectTest {
assertArrayEquals(rd.getTargetAddress(), TARGET_ADDRESS);
assertArrayEquals(rd.getDestinationAddress(), DESTINATION_ADDRESS);
// Check the option(s)
assertThat(rd.getOptions().size(), is(1));
NeighborDiscoveryOptions.Option option = rd.getOptions().get(0);
assertThat(option.type(),
is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
assertArrayEquals(option.data(), MAC_ADDRESS.toBytes());
}
/**
......@@ -96,10 +112,14 @@ public class RedirectTest {
Redirect rd1 = new Redirect();
rd1.setTargetAddress(TARGET_ADDRESS);
rd1.setDestinationAddress(DESTINATION_ADDRESS);
rd1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
Redirect rd2 = new Redirect();
rd2.setTargetAddress(TARGET_ADDRESS);
rd2.setDestinationAddress(DESTINATION_ADDRESS2);
rd2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
assertTrue(rd1.equals(rd1));
assertFalse(rd1.equals(rd2));
......
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,14 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.MacAddress;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertArrayEquals;
......@@ -32,23 +29,22 @@ import static org.junit.Assert.assertTrue;
* Tests for class {@link RouterAdvertisement}.
*/
public class RouterAdvertisementTest {
private static Data data;
private static final MacAddress MAC_ADDRESS =
MacAddress.valueOf("11:22:33:44:55:66");
private static byte[] bytePacket;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
data = new Data();
data.setData("".getBytes());
byte[] bytePayload = data.serialize();
byte[] byteHeader = {
(byte) 0x03, (byte) 0xc0, (byte) 0x02, (byte) 0x58,
(byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0xe8,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0xf4
(byte) 0x03, (byte) 0xc0, (byte) 0x02, (byte) 0x58,
(byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0xe8,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0xf4,
(byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
(byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
};
bytePacket = new byte[byteHeader.length + bytePayload.length];
bytePacket = new byte[byteHeader.length];
System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
}
/**
......@@ -63,7 +59,8 @@ public class RouterAdvertisementTest {
ra.setRouterLifetime((short) 0x258);
ra.setReachableTime(0x3e8);
ra.setRetransmitTimer(0x1f4);
ra.setPayload(data);
ra.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
assertArrayEquals(ra.serialize(), bytePacket);
}
......@@ -82,6 +79,13 @@ public class RouterAdvertisementTest {
assertThat(ra.getRouterLifetime(), is((short) 0x258));
assertThat(ra.getReachableTime(), is(0x3e8));
assertThat(ra.getRetransmitTimer(), is(0x1f4));
// Check the option(s)
assertThat(ra.getOptions().size(), is(1));
NeighborDiscoveryOptions.Option option = ra.getOptions().get(0);
assertThat(option.type(),
is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
assertArrayEquals(option.data(), MAC_ADDRESS.toBytes());
}
/**
......@@ -96,6 +100,8 @@ public class RouterAdvertisementTest {
ra1.setRouterLifetime((short) 0x258);
ra1.setReachableTime(0x3e8);
ra1.setRetransmitTimer(0x1f4);
ra1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
RouterAdvertisement ra2 = new RouterAdvertisement();
ra2.setCurrentHopLimit((byte) 3);
......@@ -104,6 +110,8 @@ public class RouterAdvertisementTest {
ra2.setRouterLifetime((short) 0x1f4);
ra2.setReachableTime(0x3e8);
ra2.setRetransmitTimer(0x1f4);
ra2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS.toBytes());
assertTrue(ra1.equals(ra1));
assertFalse(ra1.equals(ra2));
......
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,38 +13,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.packet.ndp;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.MacAddress;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Tests for class {@link RouterSolicitation}.
*/
public class RouterSolicitationTest {
private static final byte[] OPTION = {
(byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01
};
private static Data data;
private static final MacAddress MAC_ADDRESS1 =
MacAddress.valueOf("11:22:33:44:55:66");
private static final MacAddress MAC_ADDRESS2 =
MacAddress.valueOf("11:22:33:44:55:00");
private static byte[] bytePacket;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
data = new Data();
data.setData(OPTION);
byte[] bytePayload = data.serialize();
byte[] byteHeader = {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
bytePacket = new byte[byteHeader.length + bytePayload.length];
byte[] byteHeader = {
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x02, (byte) 0x01, (byte) 0x11, (byte) 0x22,
(byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66
};
bytePacket = new byte[byteHeader.length];
System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
}
/**
......@@ -53,7 +53,8 @@ public class RouterSolicitationTest {
@Test
public void testSerialize() {
RouterSolicitation rs = new RouterSolicitation();
rs.setPayload(data);
rs.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS1.toBytes());
assertArrayEquals(rs.serialize(), bytePacket);
}
......@@ -65,6 +66,13 @@ public class RouterSolicitationTest {
public void testDeserialize() {
RouterSolicitation rs = new RouterSolicitation();
rs.deserialize(bytePacket, 0, bytePacket.length);
// Check the option(s)
assertThat(rs.getOptions().size(), is(1));
NeighborDiscoveryOptions.Option option = rs.getOptions().get(0);
assertThat(option.type(),
is(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS));
assertArrayEquals(option.data(), MAC_ADDRESS1.toBytes());
}
/**
......@@ -73,7 +81,14 @@ public class RouterSolicitationTest {
@Test
public void testEqual() {
RouterSolicitation rs1 = new RouterSolicitation();
rs1.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS1.toBytes());
RouterSolicitation rs2 = new RouterSolicitation();
rs2.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
MAC_ADDRESS2.toBytes());
assertTrue(rs1.equals(rs1));
assertFalse(rs1.equals(rs2));
}
}
......