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 {
Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_ARP, ARP.class);
Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_RARP, ARP.class);
Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_IPV4, IPv4.class);
Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_IPV6, IPv6.class);
Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_LLDP, LLDP.class);
Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_BSN, LLDP.class);
}
......
/*
* Copyright 2014 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;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
/**
* Implements ICMPv6 packet format.
*
*/
public class ICMP6 extends BasePacket {
public static final byte HEADER_LENGTH = 4; // bytes
public static final byte ROUTER_SOLICITATION = (byte) 0x85;
public static final byte ROUTER_ADVERTISEMENT = (byte) 0x86;
public static final byte NEIGHBOR_SOLICITATION = (byte) 0x87;
public static final byte NEIGHBOR_ADVERTISEMENT = (byte) 0x88;
public static final Map<Byte, Class<? extends IPacket>> PROTOCOL_CLASS_MAP =
new HashMap<>();
static {
ICMP6.PROTOCOL_CLASS_MAP.put(ICMP6.NEIGHBOR_ADVERTISEMENT, NeighborAdvertisement.class);
}
protected byte icmpType;
protected byte icmpCode;
protected short checksum;
/**
* @return the icmpType
*/
public byte getIcmpType() {
return this.icmpType;
}
/**
* @param icmpType
* to set
* @return this
*/
public ICMP6 setIcmpType(final byte icmpType) {
this.icmpType = icmpType;
return this;
}
/**
* @return the icmp code
*/
public byte getIcmpCode() {
return this.icmpCode;
}
/**
* @param icmpCode
* code to set
* @return this
*/
public ICMP6 setIcmpCode(final byte icmpCode) {
this.icmpCode = icmpCode;
return this;
}
/**
* @return the checksum
*/
public short getChecksum() {
return this.checksum;
}
/**
* @param checksum
* the checksum to set
* @return this
*/
public ICMP6 setChecksum(final short checksum) {
this.checksum = checksum;
return this;
}
/**
* Serializes the packet. Will compute and set the following fields if they
* are set to specific values at the time serialize is called: -checksum : 0
* -length : 0
*/
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
int payloadLength = payloadData == null ? 0 : (short) payloadData.length;
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.icmpType);
bb.put(this.icmpCode);
bb.putShort(this.checksum);
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IPv6) {
((IPv6) this.parent).setNextHeader(IPv6.PROTOCOL_ICMP6);
}
// compute checksum if needed
if (this.checksum == 0) {
bb.rewind();
int accumulation = 0;
for (int i = 0; i < data.length / 2; ++i) {
accumulation += 0xffff & bb.getShort();
}
// pad to an even number of shorts
if (data.length % 2 > 0) {
accumulation += (bb.get() & 0xff) << 8;
}
accumulation = (accumulation >> 16 & 0xffff)
+ (accumulation & 0xffff);
this.checksum = (short) (~accumulation & 0xffff);
bb.putShort(2, this.checksum);
}
return data;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 5807;
int result = super.hashCode();
result = prime * result + this.icmpType;
result = prime * result + this.icmpCode;
result = prime * result + this.checksum;
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof ICMP6)) {
return false;
}
final ICMP6 other = (ICMP6) obj;
if (this.icmpType != other.icmpType) {
return false;
}
if (this.icmpCode != other.icmpCode) {
return false;
}
if (this.checksum != other.checksum) {
return false;
}
return true;
}
@Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.icmpType = bb.get();
this.icmpCode = bb.get();
this.checksum = bb.getShort();
IPacket payload;
if (ICMP6.PROTOCOL_CLASS_MAP.containsKey(this.icmpType)) {
final Class<? extends IPacket> clazz = ICMP6.PROTOCOL_CLASS_MAP
.get(this.icmpType);
try {
payload = clazz.newInstance();
} catch (final Exception e) {
throw new RuntimeException(
"Error parsing payload for ICMP6 packet", e);
}
} else {
payload = new Data();
}
this.payload = payload.deserialize(data, bb.position(),
bb.limit() - bb.position());
this.payload.setParent(this);
return this;
}
}
/*
* Copyright 2014 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;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
public class IPv6 extends BasePacket {
public static final byte FIXED_HEADER_LENGTH = 40; // bytes
// TODO: Implement extension header.
public static final byte PROTOCOL_TCP = 0x6;
public static final byte PROTOCOL_UDP = 0x11;
public static final byte PROTOCOL_ICMP6 = 0x3A;
public static final Map<Byte, Class<? extends IPacket>> PROTOCOL_CLASS_MAP =
new HashMap<>();
static {
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_ICMP6, ICMP6.class);
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_TCP, TCP.class);
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_UDP, UDP.class);
}
protected byte version;
protected byte diffServ;
protected int flowLabel;
protected short payloadLength;
protected byte nextHeader;
protected byte hopLimit;
protected byte[] sourceAddress = new byte[Ip6Address.BYTE_LENGTH];
protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH];
/**
* Default constructor that sets the version to 4.
*/
public IPv6() {
super();
this.version = 6;
}
/**
* @return the version
*/
public byte getVersion() {
return this.version;
}
/**
* @param version
* the version to set
* @return this
*/
public IPv6 setVersion(final byte version) {
this.version = version;
return this;
}
/**
* @return the diffServ
*/
public byte getDiffServ() {
return this.diffServ;
}
/**
* @param diffServ
* the diffServ to set
* @return this
*/
public IPv6 setDiffServ(final byte diffServ) {
this.diffServ = diffServ;
return this;
}
/**
* @return the flowLabel
*/
public int getFlowLabel() {
return this.flowLabel;
}
/**
* @param flowLabel
* the flowLabel to set
* @return this
*/
public IPv6 setFlowLabel(final int flowLabel) {
this.flowLabel = flowLabel;
return this;
}
/**
* @return the nextHeader
*/
public byte getNextHeader() {
return this.nextHeader;
}
/**
* @param nextHeader
* the nextHeader to set
* @return this
*/
public IPv6 setNextHeader(final byte nextHeader) {
this.nextHeader = nextHeader;
return this;
}
/**
* @return the hopLimit
*/
public byte getHopLimit() {
return this.hopLimit;
}
/**
* @param hopLimit
* the hopLimit to set
* @return this
*/
public IPv6 setHopLimit(final byte hopLimit) {
this.hopLimit = hopLimit;
return this;
}
/**
* @return the sourceAddress
*/
public byte[] getSourceAddress() {
return this.sourceAddress;
}
/**
* @param sourceAddress
* the sourceAddress to set
* @return this
*/
public IPv6 setSourceAddress(final byte[] sourceAddress) {
this.sourceAddress = Arrays.copyOfRange(sourceAddress, 0, Ip6Address.BYTE_LENGTH);
return this;
}
/**
* @return the destinationAddress
*/
public byte[] getDestinationAddress() {
return this.destinationAddress;
}
/**
* @param destinationAddress
* the destinationAddress to set
* @return this
*/
public IPv6 setDestinationAddress(final byte[] destinationAddress) {
this.destinationAddress = Arrays.copyOfRange(destinationAddress, 0, Ip6Address.BYTE_LENGTH);
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
this.payloadLength = payloadData == null ? 0 : (short) payloadData.length;
final byte[] data = new byte[FIXED_HEADER_LENGTH + payloadLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putInt((this.version & 0xf) << 28 | (this.diffServ & 0xff) << 20 | this.flowLabel & 0xfffff);
bb.putShort(this.payloadLength);
bb.put(this.nextHeader);
bb.put(this.hopLimit);
bb.put(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
bb.put(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
if (payloadData != null) {
bb.put(payloadData);
}
return data;
}
@Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
int iscratch;
iscratch = bb.getInt();
this.version = (byte) (iscratch >> 28 & 0xf);
this.diffServ = (byte) (iscratch >> 20 & 0xff);
this.flowLabel = iscratch & 0xfffff;
this.payloadLength = bb.getShort();
this.nextHeader = bb.get();
this.hopLimit = bb.get();
bb.get(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
IPacket payload;
if (IPv6.PROTOCOL_CLASS_MAP.containsKey(this.nextHeader)) {
final Class<? extends IPacket> clazz = IPv6.PROTOCOL_CLASS_MAP
.get(this.nextHeader);
try {
payload = clazz.newInstance();
} catch (final Exception e) {
throw new RuntimeException(
"Error parsing payload for IPv6 packet", e);
}
} else {
payload = new Data();
}
this.payload = payload.deserialize(data, bb.position(),
bb.limit() - bb.position());
this.payload.setParent(this);
return this;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 2521;
int result = super.hashCode();
ByteBuffer bb;
bb = ByteBuffer.wrap(this.destinationAddress);
for (int i = 0; i < 4; i++) {
result = prime * result + bb.getInt();
}
result = prime * result + this.diffServ;
result = prime * result + this.flowLabel;
result = prime * result + this.hopLimit;
result = prime * result + this.nextHeader;
result = prime * result + this.payloadLength;
bb = ByteBuffer.wrap(this.sourceAddress);
for (int i = 0; i < 4; i++) {
result = prime * result + bb.getInt();
}
result = prime * result + this.version;
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof IPv6)) {
return false;
}
final IPv6 other = (IPv6) obj;
if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) {
return false;
}
if (this.diffServ != other.diffServ) {
return false;
}
if (this.flowLabel != other.flowLabel) {
return false;
}
if (this.hopLimit != other.hopLimit) {
return false;
}
if (this.nextHeader != other.nextHeader) {
return false;
}
if (this.payloadLength != other.payloadLength) {
return false;
}
if (!Arrays.equals(this.sourceAddress, other.sourceAddress)) {
return false;
}
return true;
}
}
/*
* Copyright 2014 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;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* Implements ICMPv6 Neighbor Solicitation packet format.
*/
public class NeighborAdvertisement extends BasePacket {
public static final byte HEADER_LENGTH = 20; // bytes
protected byte routerFlag;
protected byte solicitedFlag;
protected byte overrideFlag;
protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
/**
*
* @return true if router flag is set
*/
public byte getRouterFlag() {
return this.routerFlag;
}
/**
* @param routerFlag
* the routerFlag to set
* @return this
*/
public NeighborAdvertisement setRouterFlag(final byte routerFlag) {
this.routerFlag = routerFlag;
return this;
}
/**
*
* @return true if solicited flag is set
*/
public byte getSolicitedFlag() {
return this.solicitedFlag;
}
/**
* @param solicitedFlag
* the routerFlag to set
* @return this
*/
public NeighborAdvertisement setSolicitedFlag(final byte solicitedFlag) {
this.solicitedFlag = solicitedFlag;
return this;
}
/**
*
* @return true if override flag is set
*/
public byte getOverrideFlag() {
return this.overrideFlag;
}
/**
* @param overrideFlag
* the routerFlag to set
* @return this
*/
public NeighborAdvertisement setOverrideFlag(final byte overrideFlag) {
this.overrideFlag = overrideFlag;
return this;
}
/**
*
* @return the target IPv6 address
*/
public byte[] getTargetAddress() {
return this.targetAddress;
}
/**
* @param targetAddress
* the sourceAddress to set
* @return this
*/
public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) {
this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
return this;
}
/**
* Serializes the packet. Will compute and set the following fields if they
* are set to specific values at the time serialize is called: -routerFlag : 0
* -solicitedFlag : 0 -overrideFlag : 0
*/
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
int payloadLength = payloadData == null ? 0 : (short) payloadData.length;
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
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);
}
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
int iscratch;
iscratch = bb.getInt();
this.routerFlag = (byte) (iscratch >> 31 & 0x1);
this.solicitedFlag = (byte) (iscratch >> 30 & 0x1);
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);
return this;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 5807;
int result = super.hashCode();
ByteBuffer bb;
result = prime * result + this.routerFlag;
result = prime * result + this.solicitedFlag;
result = prime * result + this.overrideFlag;
bb = ByteBuffer.wrap(this.targetAddress);
for (int i = 0; i < 4; i++) {
result = prime * result + bb.getInt();
}
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof NeighborAdvertisement)) {
return false;
}
final NeighborAdvertisement other = (NeighborAdvertisement) obj;
if (this.routerFlag != other.routerFlag) {
return false;
}
if (this.solicitedFlag != other.solicitedFlag) {
return false;
}
if (this.overrideFlag != other.overrideFlag) {
return false;
}
if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
return false;
}
return true;
}
}
/*
* Copyright 2014 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;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
/**
* Tests for class {@link IPv6}.
*/
public class IPv6Test {
private static final byte[] SOURCE_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
};
private static final byte[] DESTINATION_ADDRESS = {
(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 UDP udp;
private static byte[] bytePacket;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
data = new Data();
data.setData("testSerialize".getBytes());
udp = new UDP();
udp.setPayload(data);
byte[] bytePayload = udp.serialize();
byte[] byteHeader = {
(byte) 0x69, (byte) 0x31, (byte) 0x35, (byte) 0x79,
(byte) (bytePayload.length >> 8 & 0xff), (byte) (bytePayload.length & 0xff),
(byte) 0x11, (byte) 0x20,
(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) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8,
};
bytePacket = new byte[byteHeader.length + bytePayload.length];
System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
}
/**
* Tests serialize and setters.
*/
@Test
public void testSerialize() {
IPv6 ipv6 = new IPv6();
ipv6.setPayload(udp);
ipv6.setVersion((byte) 6);
ipv6.setDiffServ((byte) 0x93);
ipv6.setFlowLabel(0x13579);
ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
ipv6.setHopLimit((byte) 32);
ipv6.setSourceAddress(SOURCE_ADDRESS);
ipv6.setDestinationAddress(DESTINATION_ADDRESS);
assertArrayEquals(ipv6.serialize(), bytePacket);
}
/**
* Tests deserialize and getters.
*/
@Test
public void testDeserialize() {
IPv6 ipv6 = new IPv6();
ipv6.deserialize(bytePacket, 0, bytePacket.length);
assertThat(ipv6.getVersion(), is((byte) 6));
assertThat(ipv6.getDiffServ(), is((byte) 0x93));
assertThat(ipv6.getFlowLabel(), is(0x13579));
assertThat(ipv6.getNextHeader(), is(IPv6.PROTOCOL_UDP));
assertThat(ipv6.getHopLimit(), is((byte) 32));
assertArrayEquals(ipv6.getSourceAddress(), SOURCE_ADDRESS);
assertArrayEquals(ipv6.getDestinationAddress(), DESTINATION_ADDRESS);
}
/**
* Tests comparator.
*/
@Test
public void testEqual() {
IPv6 packet1 = new IPv6();
packet1.setPayload(udp);
packet1.setVersion((byte) 6);
packet1.setDiffServ((byte) 0x93);
packet1.setFlowLabel(0x13579);
packet1.setNextHeader(IPv6.PROTOCOL_UDP);
packet1.setHopLimit((byte) 32);
packet1.setSourceAddress(SOURCE_ADDRESS);
packet1.setDestinationAddress(DESTINATION_ADDRESS);
IPv6 packet2 = new IPv6();
packet2.setPayload(udp);
packet2.setVersion((byte) 6);
packet2.setDiffServ((byte) 0x93);
packet2.setFlowLabel(0x13579);
packet2.setNextHeader(IPv6.PROTOCOL_UDP);
packet2.setHopLimit((byte) 32);
packet2.setSourceAddress(DESTINATION_ADDRESS);
packet2.setDestinationAddress(SOURCE_ADDRESS);
assertTrue(packet1.equals(packet1));
assertFalse(packet1.equals(packet2));
}
}
/*
* Copyright 2014 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;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
/**
* 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
};
private static Data data;
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
};
bytePacket = new byte[byteHeader.length + bytePayload.length];
System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
}
/**
* Tests serialize and setters.
*/
@Test
public void testSerialize() {
NeighborAdvertisement na = new NeighborAdvertisement();
na.setRouterFlag((byte) 1);
na.setSolicitedFlag((byte) 1);
na.setOverrideFlag((byte) 1);
na.setTargetAddress(TARGET_ADDRESS);
assertArrayEquals(na.serialize(), bytePacket);
}
/**
* Tests deserialize and getters.
*/
@Test
public void testDeserialize() {
NeighborAdvertisement na = new NeighborAdvertisement();
na.deserialize(bytePacket, 0, bytePacket.length);
assertThat(na.getRouterFlag(), is((byte) 1));
assertThat(na.getSolicitedFlag(), is((byte) 1));
assertThat(na.getOverrideFlag(), is((byte) 1));
assertArrayEquals(na.getTargetAddress(), TARGET_ADDRESS);
}
/**
* Tests comparator.
*/
@Test
public void testEqual() {
NeighborAdvertisement na1 = new NeighborAdvertisement();
na1.setRouterFlag((byte) 1);
na1.setSolicitedFlag((byte) 1);
na1.setOverrideFlag((byte) 1);
na1.setTargetAddress(TARGET_ADDRESS);
NeighborAdvertisement na2 = new NeighborAdvertisement();
na2.setRouterFlag((byte) 1);
na2.setSolicitedFlag((byte) 1);
na2.setOverrideFlag((byte) 0);
na2.setTargetAddress(TARGET_ADDRESS);
assertTrue(na1.equals(na1));
assertFalse(na1.equals(na2));
}
}