Charles M.C. Chan
Committed by Pavlin Radoslavov

ONOS-512: Implement IPv6 Extension Headers

* Create IExtensionHeader interface
    - setNextHeader, getNextHeader interface for all extension header classes
        - Except EncapSecurityPayload, in which the nextHeader field is encrypted

* Create BaseOptions class
    - Super class of HopByHopOptions and DestinationOptions, since these two are very similar

* Implement following classes with unit test
    - HopByHopOptions
    - DestinationOptions
    - Fragment
    - Routing
    - Authentication
    - EncapSecurityPayload

Change-Id: If65894eccf20ac90f04bc2b0cb42aac6dd5a9674
/*
* 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.
......@@ -18,6 +18,13 @@
package org.onlab.packet;
import org.onlab.packet.ipv6.Authentication;
import org.onlab.packet.ipv6.DestinationOptions;
import org.onlab.packet.ipv6.EncapSecurityPayload;
import org.onlab.packet.ipv6.Fragment;
import org.onlab.packet.ipv6.IExtensionHeader;
import org.onlab.packet.ipv6.HopByHopOptions;
import org.onlab.packet.ipv6.Routing;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
......@@ -26,13 +33,20 @@ import java.util.Map;
/**
* Implements IPv6 packet format. (RFC 2460)
*/
public class IPv6 extends BasePacket {
public class IPv6 extends BasePacket implements IExtensionHeader {
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 byte PROTOCOL_HOPOPT = 0x00;
public static final byte PROTOCOL_ROUTING = 0x2B;
public static final byte PROTOCOL_FRAG = 0x2C;
public static final byte PROTOCOL_ESP = 0x32;
public static final byte PROTOCOL_AH = 0x33;
public static final byte PROTOCOL_DSTOPT = 0x3C;
public static final Map<Byte, Class<? extends IPacket>> PROTOCOL_CLASS_MAP =
new HashMap<>();
......@@ -40,6 +54,12 @@ public class IPv6 extends BasePacket {
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);
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_HOPOPT, HopByHopOptions.class);
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_ROUTING, Routing.class);
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_FRAG, Fragment.class);
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_ESP, EncapSecurityPayload.class);
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_AH, Authentication.class);
IPv6.PROTOCOL_CLASS_MAP.put(IPv6.PROTOCOL_DSTOPT, DestinationOptions.class);
}
protected byte version;
......@@ -119,21 +139,12 @@ public class IPv6 extends BasePacket {
return this;
}
/**
* Gets next header.
*
* @return the next header
*/
@Override
public byte getNextHeader() {
return this.nextHeader;
}
/**
* Sets next header.
*
* @param nextHeader the next header to set
* @return this
*/
@Override
public IPv6 setNextHeader(final byte nextHeader) {
this.nextHeader = nextHeader;
return this;
......
/*
* 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.
* 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.ipv6;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.IPv6;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* Implements IPv6 authentication extension header format. (RFC 4302)
*/
public class Authentication extends BasePacket implements IExtensionHeader {
public static final byte FIXED_HEADER_LENGTH = 12; // bytes
public static final byte LENGTH_UNIT = 4; // bytes per unit
public static final byte MINUS = 2;
protected byte nextHeader;
protected byte payloadLength;
protected int securityParamIndex;
protected int sequence;
protected byte[] integrityCheck;
@Override
public byte getNextHeader() {
return this.nextHeader;
}
@Override
public Authentication setNextHeader(final byte nextHeader) {
this.nextHeader = nextHeader;
return this;
}
/**
* Gets the payload length of this header.
*
* @return the payload length
*/
public byte getPayloadLength() {
return this.payloadLength;
}
/**
* Sets the payload length of this header.
*
* @param payloadLength the payload length to set
* @return this
*/
public Authentication setPayloadLength(final byte payloadLength) {
this.payloadLength = payloadLength;
return this;
}
/**
* Gets the security parameter index of this header.
*
* @return the security parameter index
*/
public int getSecurityParamIndex() {
return this.securityParamIndex;
}
/**
* Sets the security parameter index of this header.
*
* @param securityParamIndex the security parameter index to set
* @return this
*/
public Authentication setSecurityParamIndex(final int securityParamIndex) {
this.securityParamIndex = securityParamIndex;
return this;
}
/**
* Gets the sequence number of this header.
*
* @return the sequence number
*/
public int getSequence() {
return this.sequence;
}
/**
* Sets the sequence number of this header.
*
* @param sequence the sequence number to set
* @return this
*/
public Authentication setSequence(final int sequence) {
this.sequence = sequence;
return this;
}
/**
* Gets the integrity check value of this header.
*
* @return the integrity check value
*/
public byte[] getIntegrityCheck() {
return this.integrityCheck;
}
/**
* Sets the integrity check value of this header.
*
* @param integrityCheck the integrity check value to set
* @return this
*/
public Authentication setIngegrityCheck(final byte[] integrityCheck) {
this.integrityCheck =
Arrays.copyOfRange(integrityCheck, 0, integrityCheck.length);
return this;
}
/**
* Gets the total length of this header.
* According to spec, payload length should be the total length of this AH
* in 4-octet unit, minus 2
*
* @return the total length
*/
public int getTotalLength() {
return (this.payloadLength + MINUS) * LENGTH_UNIT;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
int headerLength = FIXED_HEADER_LENGTH + integrityCheck.length;
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
}
final byte[] data = new byte[headerLength + payloadLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.nextHeader);
bb.put(this.payloadLength);
bb.putShort((short) 0);
bb.putInt(this.securityParamIndex);
bb.putInt(this.sequence);
bb.put(this.integrityCheck, 0, integrityCheck.length);
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IExtensionHeader) {
((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_AH);
}
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.nextHeader = bb.get();
this.payloadLength = bb.get();
bb.getShort();
this.securityParamIndex = bb.getInt();
this.sequence = bb.getInt();
int icvLength = getTotalLength() - FIXED_HEADER_LENGTH;
this.integrityCheck = new byte[icvLength];
bb.get(this.integrityCheck, 0, icvLength);
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 Authentication 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 = 5807;
int result = super.hashCode();
result = prime * result + this.nextHeader;
result = prime * result + this.payloadLength;
result = prime * result + this.securityParamIndex;
result = prime * result + this.sequence;
for (byte b : this.integrityCheck) {
result = prime * result + b;
}
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 Authentication)) {
return false;
}
final Authentication other = (Authentication) obj;
if (this.nextHeader != other.nextHeader) {
return false;
}
if (this.payloadLength != other.payloadLength) {
return false;
}
if (this.securityParamIndex != other.securityParamIndex) {
return false;
}
if (this.sequence != other.sequence) {
return false;
}
if (!Arrays.equals(this.integrityCheck, other.integrityCheck)) {
return false;
}
return true;
}
}
/*
* 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.
* 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.ipv6;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.IPv6;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* Base class for hop-by-hop options and destination options.
*/
public class BaseOptions extends BasePacket implements IExtensionHeader {
public static final byte FIXED_HEADER_LENGTH = 2; // bytes
public static final byte FIXED_OPTIONS_LENGTH = 6; // bytes
public static final byte LENGTH_UNIT = 8; // bytes per unit
protected byte nextHeader;
protected byte headerExtLength;
protected byte[] options;
protected byte type;
@Override
public byte getNextHeader() {
return this.nextHeader;
}
@Override
public BaseOptions setNextHeader(final byte nextHeader) {
this.nextHeader = nextHeader;
return this;
}
/**
* Gets the extension length of this header.
*
* @return header length
*/
public byte getHeaderExtLength() {
return this.headerExtLength;
}
/**
* Sets the extension length of this header.
*
* @param headerExtLength the header length to set
* @return this
*/
public BaseOptions setHeaderExtLength(final byte headerExtLength) {
this.headerExtLength = headerExtLength;
return this;
}
/**
* Gets the options.
*
* @return the options
*/
public byte[] getOptions() {
return this.options;
}
/**
* Sets the options.
*
* @param options the options to set
* @return this
*/
public BaseOptions setOptions(final byte[] options) {
this.options =
Arrays.copyOfRange(options, 0, options.length);
return this;
}
/**
* Gets the type of this option.
*
* @return the type
*/
protected byte getType() {
return this.type;
}
/**
* Sets the type of this option.
* Must be either IPv6.PROTOCOL_HOPOPT or IPv6.PROTOCOL_DSTOPT
*
* @param type the type to set
* @return this
*/
protected BaseOptions setType(final byte type) {
this.type = type;
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
int headerLength = FIXED_HEADER_LENGTH + options.length;
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
}
final byte[] data = new byte[headerLength + payloadLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.nextHeader);
bb.put(this.headerExtLength);
bb.put(this.options, 0, options.length);
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IExtensionHeader) {
((IExtensionHeader) this.parent).setNextHeader(this.type);
}
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.nextHeader = bb.get();
this.headerExtLength = bb.get();
int optionLength =
FIXED_OPTIONS_LENGTH + LENGTH_UNIT * this.headerExtLength;
this.options = new byte[optionLength];
bb.get(this.options, 0, optionLength);
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 BaseOptions 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 = 5807;
int result = super.hashCode();
result = prime * result + this.nextHeader;
result = prime * result + this.headerExtLength;
for (byte b : this.options) {
result = prime * result + b;
}
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 BaseOptions)) {
return false;
}
final BaseOptions other = (BaseOptions) obj;
if (this.nextHeader != other.nextHeader) {
return false;
}
if (this.headerExtLength != other.headerExtLength) {
return false;
}
if (!Arrays.equals(this.options, other.options)) {
return false;
}
if (this.type != other.type) {
return false;
}
return true;
}
}
/*
* 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.
* 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.ipv6;
import org.onlab.packet.IPv6;
/**
* Implements IPv6 Destination Options extension header format. (RFC 2460)
*/
public class DestinationOptions extends BaseOptions {
public DestinationOptions() {
super();
this.setType(IPv6.PROTOCOL_DSTOPT);
}
}
\ No newline at end of file
/*
* 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.
* 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.ipv6;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.IPv6;
import java.nio.ByteBuffer;
/**
* Implements IPv6 Encapsulating Security Payload (ESP) extension header format.
* (RFC 4303)
*/
public class EncapSecurityPayload extends BasePacket {
public static final byte HEADER_LENGTH = 8; // bytes
protected int securityParamIndex;
protected int sequence;
//
// NOTE: The remaining fields including payload data, padding length and
// next header are encrypted and all considered as a payload of ESP.
//
/**
* Gets the security parameter index of this header.
*
* @return the security parameter index
*/
public int getSecurityParamIndex() {
return this.securityParamIndex;
}
/**
* Sets the security parameter index of this header.
*
* @param securityParamIndex the security parameter index to set
* @return this
*/
public EncapSecurityPayload setSecurityParamIndex(final int securityParamIndex) {
this.securityParamIndex = securityParamIndex;
return this;
}
/**
* Gets the sequence number of this header.
*
* @return the sequence number
*/
public int getSequence() {
return this.sequence;
}
/**
* Sets the sequence number of this header.
*
* @param sequence the sequence number to set
* @return this
*/
public EncapSecurityPayload setSequence(final int sequence) {
this.sequence = sequence;
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
}
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.putInt(this.securityParamIndex);
bb.putInt(this.sequence);
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IExtensionHeader) {
((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ESP);
}
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.securityParamIndex = bb.getInt();
this.sequence = bb.getInt();
this.payload = new Data();
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();
result = prime * result + this.securityParamIndex;
result = prime * result + this.sequence;
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 EncapSecurityPayload)) {
return false;
}
final EncapSecurityPayload other = (EncapSecurityPayload) obj;
if (this.securityParamIndex != other.securityParamIndex) {
return false;
}
if (this.sequence != other.sequence) {
return false;
}
return true;
}
}
/*
* 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.
* 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.ipv6;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.IPv6;
import java.nio.ByteBuffer;
/**
* Implements IPv6 fragment extension header format. (RFC 2460)
*/
public class Fragment extends BasePacket implements IExtensionHeader {
public static final byte HEADER_LENGTH = 8; // bytes
protected byte nextHeader;
protected short fragmentOffset;
protected byte moreFragment;
protected int identification;
@Override
public byte getNextHeader() {
return this.nextHeader;
}
@Override
public Fragment setNextHeader(final byte nextHeader) {
this.nextHeader = nextHeader;
return this;
}
/**
* Gets the fragment offset of this header.
*
* @return fragment offset
*/
public short getFragmentOffset() {
return this.fragmentOffset;
}
/**
* Sets the fragment offset of this header.
*
* @param fragmentOffset the fragment offset to set
* @return this
*/
public Fragment setFragmentOffset(final short fragmentOffset) {
this.fragmentOffset = fragmentOffset;
return this;
}
/**
* Gets the more fragment flag of this header.
*
* @return more fragment flag
*/
public byte getMoreFragment() {
return this.moreFragment;
}
/**
* Sets the more fragment flag of this header.
*
* @param moreFragment the more fragment flag to set
* @return this
*/
public Fragment setMoreFragment(final byte moreFragment) {
this.moreFragment = moreFragment;
return this;
}
/**
* Gets the identification of this header.
*
* @return identification
*/
public int getIdentification() {
return this.identification;
}
/**
* Sets the identification of this header.
*
* @param identification the identification to set
* @return this
*/
public Fragment setIdentification(final int identification) {
this.identification = identification;
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
}
final byte[] data = new byte[HEADER_LENGTH + payloadLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.nextHeader);
bb.put((byte) 0);
bb.putShort((short) (
(this.fragmentOffset & 0x1fff) << 3 |
this.moreFragment & 0x1
));
bb.putInt(this.identification);
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IExtensionHeader) {
((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_FRAG);
}
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.nextHeader = bb.get();
bb.get();
short sscratch = bb.getShort();
this.fragmentOffset = (short) (sscratch >> 3 & 0x1fff);
this.moreFragment = (byte) (sscratch & 0x1);
this.identification = bb.getInt();
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 Fragment 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 = 5807;
int result = super.hashCode();
result = prime * result + this.nextHeader;
result = prime * result + this.fragmentOffset;
result = prime * result + this.moreFragment;
result = prime * result + this.identification;
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 Fragment)) {
return false;
}
final Fragment other = (Fragment) obj;
if (this.nextHeader != other.nextHeader) {
return false;
}
if (this.fragmentOffset != other.fragmentOffset) {
return false;
}
if (this.moreFragment != other.moreFragment) {
return false;
}
if (this.identification != other.identification) {
return false;
}
return true;
}
}
/*
* 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.
* 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.ipv6;
import org.onlab.packet.IPv6;
/**
* Implements IPv6 Hop-by-hop Options extension header format. (RFC 2460)
*/
public class HopByHopOptions extends BaseOptions {
public HopByHopOptions() {
super();
this.setType(IPv6.PROTOCOL_HOPOPT);
}
}
\ No newline at end of file
/*
* 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.
* 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.ipv6;
/**
* Interface for IPv6 extension header.
*/
public interface IExtensionHeader {
/**
* Gets the type of next header.
*
* @return next header
*/
public byte getNextHeader();
/**
* Sets the type of next header.
*
* @param nextHeader the next header to set
* @return this
*/
public IExtensionHeader setNextHeader(final byte nextHeader);
}
/*
* 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.
* 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.ipv6;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.IPv6;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* Implements IPv6 routing extension header format. (RFC 2460)
*/
public class Routing extends BasePacket implements IExtensionHeader {
public static final byte FIXED_HEADER_LENGTH = 4; // bytes
public static final byte FIXED_ROUTING_DATA_LENGTH = 4; // bytes
public static final byte LENGTH_UNIT = 8; // bytes per unit
protected byte nextHeader;
protected byte headerExtLength;
protected byte routingType;
protected byte segmentsLeft;
protected byte[] routingData;
@Override
public byte getNextHeader() {
return this.nextHeader;
}
@Override
public Routing setNextHeader(final byte nextHeader) {
this.nextHeader = nextHeader;
return this;
}
/**
* Gets the extension length of this header.
*
* @return header length
*/
public byte getHeaderExtLength() {
return this.headerExtLength;
}
/**
* Sets the extension length of this header.
*
* @param headerExtLength the header length to set
* @return this
*/
public Routing setHeaderExtLength(final byte headerExtLength) {
this.headerExtLength = headerExtLength;
return this;
}
/**
* Gets the routing type of this header.
*
* @return routing type
*/
public byte getRoutingType() {
return this.routingType;
}
/**
* Sets the routing type of this header.
*
* @param routingType the routing type to set
* @return this
*/
public Routing setRoutingType(final byte routingType) {
this.routingType = routingType;
return this;
}
/**
* Gets the number of remaining route segments of this header.
*
* @return number of remaining route segments
*/
public byte getSegmentsLeft() {
return this.segmentsLeft;
}
/**
* Sets the number of remaining route segments of this header.
*
* @param segmentsLeft the number of remaining route segments to set
* @return this
*/
public Routing setSegmntsLeft(final byte segmentsLeft) {
this.segmentsLeft = segmentsLeft;
return this;
}
/**
* Gets the routing data.
*
* @return the routing data
*/
public byte[] getRoutingData() {
return this.routingData;
}
/**
* Sets the routing data.
*
* @param routingData the routing data to set
* @return this
*/
public Routing setRoutingData(final byte[] routingData) {
this.routingData =
Arrays.copyOfRange(routingData, 0, routingData.length);
return this;
}
@Override
public byte[] serialize() {
byte[] payloadData = null;
if (this.payload != null) {
this.payload.setParent(this);
payloadData = this.payload.serialize();
}
int headerLength = FIXED_HEADER_LENGTH + routingData.length;
int payloadLength = 0;
if (payloadData != null) {
payloadLength = payloadData.length;
}
final byte[] data = new byte[headerLength + payloadLength];
final ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(this.nextHeader);
bb.put(this.headerExtLength);
bb.put(this.routingType);
bb.put(this.segmentsLeft);
bb.put(this.routingData, 0, routingData.length);
if (payloadData != null) {
bb.put(payloadData);
}
if (this.parent != null && this.parent instanceof IExtensionHeader) {
((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ROUTING);
}
return data;
}
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
this.nextHeader = bb.get();
this.headerExtLength = bb.get();
this.routingType = bb.get();
this.segmentsLeft = bb.get();
int dataLength =
FIXED_ROUTING_DATA_LENGTH + LENGTH_UNIT * this.headerExtLength;
this.routingData = new byte[dataLength];
bb.get(this.routingData, 0, dataLength);
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 Routing 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 = 5807;
int result = super.hashCode();
result = prime * result + this.nextHeader;
result = prime * result + this.headerExtLength;
result = prime * result + this.routingType;
result = prime * result + this.segmentsLeft;
for (byte b : this.routingData) {
result = prime * result + b;
}
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 Routing)) {
return false;
}
final Routing other = (Routing) obj;
if (this.nextHeader != other.nextHeader) {
return false;
}
if (this.headerExtLength != other.headerExtLength) {
return false;
}
if (this.routingType != other.routingType) {
return false;
}
if (this.segmentsLeft != other.segmentsLeft) {
return false;
}
if (!Arrays.equals(this.routingData, other.routingData)) {
return false;
}
return true;
}
}
\ No newline at end of file
/*
* 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.
*/
/**
* Utilities for decoding and encoding IPv6 extension headers.
*/
package org.onlab.packet.ipv6;
/*
* 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.
* 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.ipv6;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.UDP;
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 Authentication}.
*/
public class AuthenticationTest {
private static Data data;
private static UDP udp;
private static byte[] icv = {
(byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44
};
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) 0x11, (byte) 0x02, (byte) 0x00, (byte) 0x00,
(byte) 0x13, (byte) 0x57, (byte) 0x24, (byte) 0x68,
(byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0x00,
(byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44
};
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() {
Authentication auth = new Authentication();
auth.setNextHeader((byte) 0x11);
auth.setPayloadLength((byte) 0x02);
auth.setSecurityParamIndex(0x13572468);
auth.setSequence(0xffff00);
auth.setIngegrityCheck(icv);
auth.setPayload(udp);
assertArrayEquals(auth.serialize(), bytePacket);
}
/**
* Tests deserialize and getters.
*/
@Test
public void testDeserialize() {
Authentication auth = new Authentication();
auth.deserialize(bytePacket, 0, bytePacket.length);
assertThat(auth.getNextHeader(), is((byte) 0x11));
assertThat(auth.getPayloadLength(), is((byte) 0x02));
assertThat(auth.getSecurityParamIndex(), is(0x13572468));
assertThat(auth.getSequence(), is(0xffff00));
assertArrayEquals(auth.getIntegrityCheck(), icv);
}
/**
* Tests comparator.
*/
@Test
public void testEqual() {
Authentication auth1 = new Authentication();
auth1.setNextHeader((byte) 0x11);
auth1.setPayloadLength((byte) 0x02);
auth1.setSecurityParamIndex(0x13572468);
auth1.setSequence(0xffff00);
auth1.setIngegrityCheck(icv);
Authentication auth2 = new Authentication();
auth2.setNextHeader((byte) 0x11);
auth2.setPayloadLength((byte) 0x02);
auth2.setSecurityParamIndex(0x13572467);
auth2.setSequence(0xffff00);
auth2.setIngegrityCheck(icv);
assertTrue(auth1.equals(auth1));
assertFalse(auth1.equals(auth2));
}
}
/*
* 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.
* 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.ipv6;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.IPv6;
import org.onlab.packet.UDP;
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 BaseOptions}.
*/
public class BaseOptionsTest {
private static Data data;
private static UDP udp;
private static byte[] options = {
(byte) 0x00, (byte) 0x03,
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00
};
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) 0x11, (byte) 0x00, (byte) 0x00, (byte) 0x03,
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00
};
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() {
BaseOptions baseopt = new BaseOptions();
baseopt.setNextHeader((byte) 0x11);
baseopt.setHeaderExtLength((byte) 0x00);
baseopt.setOptions(options);
baseopt.setPayload(udp);
assertArrayEquals(baseopt.serialize(), bytePacket);
}
/**
* Tests deserialize and getters.
*/
@Test
public void testDeserialize() {
BaseOptions baseopt = new BaseOptions();
baseopt.deserialize(bytePacket, 0, bytePacket.length);
assertThat(baseopt.getNextHeader(), is((byte) 0x11));
assertThat(baseopt.getHeaderExtLength(), is((byte) 0x00));
assertArrayEquals(baseopt.getOptions(), options);
}
/**
* Tests comparator.
*/
@Test
public void testEqual() {
BaseOptions baseopt1 = new BaseOptions();
baseopt1.setNextHeader((byte) 0x11);
baseopt1.setHeaderExtLength((byte) 0x00);
baseopt1.setOptions(options);
baseopt1.setType(IPv6.PROTOCOL_HOPOPT);
BaseOptions baseopt2 = new BaseOptions();
baseopt2.setNextHeader((byte) 0x11);
baseopt2.setHeaderExtLength((byte) 0x00);
baseopt2.setOptions(options);
baseopt1.setType(IPv6.PROTOCOL_DSTOPT);
assertTrue(baseopt1.equals(baseopt1));
assertFalse(baseopt1.equals(baseopt2));
}
}
/*
* 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.
* 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.ipv6;
import org.junit.Test;
import org.onlab.packet.IPv6;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
* Tests for class {@link DestinationOptions}.
*/
public class DestinationOptionsTest {
/**
* Tests constructor.
*/
@Test
public void testConstructor() {
DestinationOptions dstopt = new DestinationOptions();
assertThat(dstopt.getType(), is(IPv6.PROTOCOL_DSTOPT));
}
}
/*
* 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.
* 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.ipv6;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import java.util.Arrays;
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 EncapSecurityPayload}.
*/
public class EncapSecurityPayloadTest {
private static Data data;
private static byte[] dataByte = new byte[32];
private static byte[] bytePacket;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
Arrays.fill(dataByte, (byte) 0xff);
data = new Data().setData(dataByte);
byte[] bytePayload = data.serialize();
byte[] byteHeader = {
(byte) 0x13, (byte) 0x57, (byte) 0x24, (byte) 0x68,
(byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0x00
};
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() {
EncapSecurityPayload esp = new EncapSecurityPayload();
esp.setSecurityParamIndex(0x13572468);
esp.setSequence(0xffff00);
esp.setPayload(data);
assertArrayEquals(esp.serialize(), bytePacket);
}
/**
* Tests deserialize and getters.
*/
@Test
public void testDeserialize() {
EncapSecurityPayload esp = new EncapSecurityPayload();
esp.deserialize(bytePacket, 0, bytePacket.length);
assertThat(esp.getSecurityParamIndex(), is(0x13572468));
assertThat(esp.getSequence(), is(0xffff00));
}
/**
* Tests comparator.
*/
@Test
public void testEqual() {
EncapSecurityPayload esp1 = new EncapSecurityPayload();
esp1.setSecurityParamIndex(0x13572468);
esp1.setSequence(0xffff00);
EncapSecurityPayload esp2 = new EncapSecurityPayload();
esp2.setSecurityParamIndex(0x13572468);
esp2.setSequence(0xfffff0);
assertTrue(esp1.equals(esp1));
assertFalse(esp1.equals(esp2));
}
}
/*
* 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.
* 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.ipv6;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.UDP;
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 Fragment}.
*/
public class FragmentTest {
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) 0x11, (byte) 0x00, (byte) 0x00, (byte) 0xf9,
(byte) 0x00, (byte) 0x00, (byte) 0x13, (byte) 0x57
};
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() {
Fragment frag = new Fragment();
frag.setNextHeader((byte) 0x11);
frag.setFragmentOffset((short) 0x1f);
frag.setMoreFragment((byte) 1);
frag.setIdentification(0x1357);
frag.setPayload(udp);
assertArrayEquals(frag.serialize(), bytePacket);
}
/**
* Tests deserialize and getters.
*/
@Test
public void testDeserialize() {
Fragment frag = new Fragment();
frag.deserialize(bytePacket, 0, bytePacket.length);
assertThat(frag.getNextHeader(), is((byte) 0x11));
assertThat(frag.getFragmentOffset(), is((short) 0x1f));
assertThat(frag.getMoreFragment(), is((byte) 1));
assertThat(frag.getIdentification(), is(0x1357));
}
/**
* Tests comparator.
*/
@Test
public void testEqual() {
Fragment frag1 = new Fragment();
frag1.setNextHeader((byte) 0x11);
frag1.setFragmentOffset((short) 0x1f);
frag1.setMoreFragment((byte) 1);
frag1.setIdentification(0x1357);
Fragment frag2 = new Fragment();
frag2.setNextHeader((byte) 0x11);
frag2.setFragmentOffset((short) 0x1f);
frag2.setMoreFragment((byte) 1);
frag2.setIdentification(0x1358);
assertTrue(frag1.equals(frag1));
assertFalse(frag1.equals(frag2));
}
}
/*
* 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.
* 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.ipv6;
import org.junit.Test;
import org.onlab.packet.IPv6;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
* Tests for class {@link HopByHopOptions}.
*/
public class HopByHopOptionsTest {
/**
* Tests constructor.
*/
@Test
public void testConstructor() {
HopByHopOptions hopopt = new HopByHopOptions();
assertThat(hopopt.getType(), is(IPv6.PROTOCOL_HOPOPT));
}
}
/*
* 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.
* 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.ipv6;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.UDP;
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 Routing}.
*/
public class RoutingTest {
private static Data data;
private static UDP udp;
private static byte[] routingData = {
(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
};
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) 0x11, (byte) 0x02, (byte) 0x00, (byte) 0x03,
(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
};
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() {
Routing routing = new Routing();
routing.setNextHeader((byte) 0x11);
routing.setHeaderExtLength((byte) 0x02);
routing.setRoutingType((byte) 0x00);
routing.setSegmntsLeft((byte) 0x03);
routing.setRoutingData(routingData);
routing.setPayload(udp);
assertArrayEquals(routing.serialize(), bytePacket);
}
/**
* Tests deserialize and getters.
*/
@Test
public void testDeserialize() {
Routing routing = new Routing();
routing.deserialize(bytePacket, 0, bytePacket.length);
assertThat(routing.getNextHeader(), is((byte) 0x11));
assertThat(routing.getHeaderExtLength(), is((byte) 0x02));
assertThat(routing.getRoutingType(), is((byte) 0x00));
assertThat(routing.getSegmentsLeft(), is((byte) 0x03));
assertArrayEquals(routing.getRoutingData(), routingData);
}
/**
* Tests comparator.
*/
@Test
public void testEqual() {
Routing routing1 = new Routing();
routing1.setNextHeader((byte) 0x11);
routing1.setHeaderExtLength((byte) 0x02);
routing1.setRoutingType((byte) 0x00);
routing1.setSegmntsLeft((byte) 0x03);
routing1.setRoutingData(routingData);
Routing routing2 = new Routing();
routing2.setNextHeader((byte) 0x11);
routing2.setHeaderExtLength((byte) 0x02);
routing2.setRoutingType((byte) 0x00);
routing2.setSegmntsLeft((byte) 0x02);
routing2.setRoutingData(routingData);
assertTrue(routing1.equals(routing1));
assertFalse(routing1.equals(routing2));
}
}