Refactor org.onlab.packet.{TCP,UDP,ICMP6}
- ONOS-1012: Fix TCP checksum when using IPv6
- ONOS-1013: Fix UDP checksum when using IPv6
- ONOS-1593: Remove get/setTcpChecksum
- Remove unnecessary parameter of getUrgentPointer() in TCP
- Complete javadoc for TCP
- Add unit test for {TCP,UDP,ICMP6}
Change-Id: Iad5eeb35812ede6764a9a9a4a57b9837e5ea5dd6
diff --git a/utils/misc/src/main/java/org/onlab/packet/ICMP6.java b/utils/misc/src/main/java/org/onlab/packet/ICMP6.java
index 03d3102..5c2a6e6 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ICMP6.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ICMP6.java
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -34,6 +34,8 @@
public class ICMP6 extends BasePacket {
public static final byte HEADER_LENGTH = 4; // bytes
+ public static final byte ECHO_REQUEST = (byte) 0x80;
+ public static final byte ECHO_REPLY = (byte) 0x81;
public static final byte ROUTER_SOLICITATION = (byte) 0x85;
public static final byte ROUTER_ADVERTISEMENT = (byte) 0x86;
public static final byte NEIGHBOR_SOLICITATION = (byte) 0x87;
@@ -149,8 +151,8 @@
}
}
if (ipv6Parent != null) {
- bbChecksum.put(((IPv6) ipv6Parent).getSourceAddress());
- bbChecksum.put(((IPv6) ipv6Parent).getDestinationAddress());
+ bbChecksum.put(ipv6Parent.getSourceAddress());
+ bbChecksum.put(ipv6Parent.getDestinationAddress());
} else {
// NOTE: IPv6 source and destination addresses unknown. Use zeroes.
bbChecksum.put(ZERO_ADDRESS);
diff --git a/utils/misc/src/main/java/org/onlab/packet/TCP.java b/utils/misc/src/main/java/org/onlab/packet/TCP.java
index 5e0cfb2..3b92c83 100644
--- a/utils/misc/src/main/java/org/onlab/packet/TCP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/TCP.java
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -21,7 +21,7 @@
import java.nio.ByteBuffer;
/**
- *
+ * Implements TCP packet format.
*/
public class TCP extends BasePacket {
@@ -37,15 +37,18 @@
protected byte[] options;
/**
- * @return the sourcePort
+ * Gets TCP source port.
+ *
+ * @return TCP source port
*/
public short getSourcePort() {
return this.sourcePort;
}
/**
- * @param sourcePort
- * the sourcePort to set
+ * Sets TCP source port.
+ *
+ * @param sourcePort the sourcePort to set
* @return this
*/
public TCP setSourcePort(final short sourcePort) {
@@ -54,6 +57,8 @@
}
/**
+ * Gets TCP destination port.
+ *
* @return the destinationPort
*/
public short getDestinationPort() {
@@ -61,8 +66,9 @@
}
/**
- * @param destinationPort
- * the destinationPort to set
+ * Sets TCP destination port.
+ *
+ * @param destinationPort the destinationPort to set
* @return this
*/
public TCP setDestinationPort(final short destinationPort) {
@@ -71,85 +77,166 @@
}
/**
+ * Gets checksum.
+ *
* @return the checksum
*/
public short getChecksum() {
return this.checksum;
}
+ /**
+ * Sets checksum.
+ *
+ * @param checksum the checksum to set
+ * @return this
+ */
+ public TCP setChecksum(final short checksum) {
+ this.checksum = checksum;
+ return this;
+ }
+
+ /**
+ * Gets sequence number.
+ *
+ * @return the sequence number
+ */
public int getSequence() {
return this.sequence;
}
+ /**
+ * Sets sequence number.
+ *
+ * @param seq the sequence number to set
+ * @return this
+ */
public TCP setSequence(final int seq) {
this.sequence = seq;
return this;
}
+ /**
+ * Gets acknowledge number.
+ *
+ * @return the acknowledge number
+ */
public int getAcknowledge() {
return this.acknowledge;
}
+ /**
+ * Sets acknowledge number.
+ *
+ * @param ack the acknowledge number to set
+ * @return this
+ */
public TCP setAcknowledge(final int ack) {
this.acknowledge = ack;
return this;
}
+ /**
+ * Gets offset.
+ *
+ * @return the offset
+ */
public byte getDataOffset() {
return this.dataOffset;
}
+ /**
+ * Sets offset.
+ *
+ * @param offset the offset to set
+ * @return this
+ */
public TCP setDataOffset(final byte offset) {
this.dataOffset = offset;
return this;
}
+ /**
+ * Gets TCP flags.
+ *
+ * @return the TCP flags
+ */
public short getFlags() {
return this.flags;
}
+ /**
+ * Sets TCP flags.
+ *
+ * @param flags the TCP flags to set
+ * @return this
+ */
public TCP setFlags(final short flags) {
this.flags = flags;
return this;
}
+ /**
+ * Gets TCP window size.
+ *
+ * @return the TCP window size
+ */
public short getWindowSize() {
return this.windowSize;
}
+ /**
+ * Sets TCP window size.
+ *
+ * @param windowSize the TCP window size to set
+ * @return this
+ */
public TCP setWindowSize(final short windowSize) {
this.windowSize = windowSize;
return this;
}
- public short getTcpChecksum() {
- return this.checksum;
- }
-
- public TCP setTcpChecksum(final short checksum) {
- this.checksum = checksum;
- return this;
- }
-
@Override
public void resetChecksum() {
this.checksum = 0;
super.resetChecksum();
}
- public short getUrgentPointer(final short urgentPointer) {
+ /**
+ * Gets urgent pointer.
+ *
+ * @return the urgent pointer
+ */
+ public short getUrgentPointer() {
return this.urgentPointer;
}
+ /**
+ * Sets urgent pointer.
+ *
+ * @param urgentPointer the urgent pointer to set
+ * @return this
+ */
public TCP setUrgentPointer(final short urgentPointer) {
this.urgentPointer = urgentPointer;
return this;
}
+ /**
+ * Gets TCP options.
+ *
+ * @return the TCP options
+ */
public byte[] getOptions() {
return this.options;
}
+ /**
+ * Sets TCP options.
+ *
+ * @param options the options to set
+ * @return this
+ */
public TCP setOptions(final byte[] options) {
this.options = options;
this.dataOffset = (byte) (20 + options.length + 3 >> 2);
@@ -157,16 +244,6 @@
}
/**
- * @param checksum
- * the checksum to set
- * @return this
- */
- public TCP 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
@@ -218,14 +295,32 @@
int accumulation = 0;
// compute pseudo header mac
- if (this.parent != null && this.parent instanceof IPv4) {
- final IPv4 ipv4 = (IPv4) this.parent;
- accumulation += (ipv4.getSourceAddress() >> 16 & 0xffff)
- + (ipv4.getSourceAddress() & 0xffff);
- accumulation += (ipv4.getDestinationAddress() >> 16 & 0xffff)
- + (ipv4.getDestinationAddress() & 0xffff);
- accumulation += ipv4.getProtocol() & 0xff;
- accumulation += length & 0xffff;
+ if (this.parent != null) {
+ if (this.parent instanceof IPv4) {
+ final IPv4 ipv4 = (IPv4) this.parent;
+ accumulation += (ipv4.getSourceAddress() >> 16 & 0xffff)
+ + (ipv4.getSourceAddress() & 0xffff);
+ accumulation += (ipv4.getDestinationAddress() >> 16 & 0xffff)
+ + (ipv4.getDestinationAddress() & 0xffff);
+ accumulation += ipv4.getProtocol() & 0xff;
+ accumulation += length & 0xffff;
+ } else if (this.parent instanceof IPv6) {
+ final IPv6 ipv6 = (IPv6) this.parent;
+ final int bbLength =
+ Ip6Address.BYTE_LENGTH * 2 // IPv6 src, dst
+ + 2 // nextHeader (with padding)
+ + 4; // length
+ final ByteBuffer bbChecksum = ByteBuffer.allocate(bbLength);
+ bbChecksum.put(ipv6.getSourceAddress());
+ bbChecksum.put(ipv6.getDestinationAddress());
+ bbChecksum.put((byte) 0); // padding
+ bbChecksum.put(ipv6.getNextHeader());
+ bbChecksum.putInt(length);
+ bbChecksum.rewind();
+ for (int i = 0; i < bbLength / 2; ++i) {
+ accumulation += 0xffff & bbChecksum.getShort();
+ }
+ }
}
for (int i = 0; i < length / 2; ++i) {
diff --git a/utils/misc/src/main/java/org/onlab/packet/UDP.java b/utils/misc/src/main/java/org/onlab/packet/UDP.java
index 19e23c0..c743f09 100644
--- a/utils/misc/src/main/java/org/onlab/packet/UDP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/UDP.java
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -148,14 +148,32 @@
int accumulation = 0;
// compute pseudo header mac
- if (this.parent != null && this.parent instanceof IPv4) {
- final IPv4 ipv4 = (IPv4) this.parent;
- accumulation += (ipv4.getSourceAddress() >> 16 & 0xffff)
- + (ipv4.getSourceAddress() & 0xffff);
- accumulation += (ipv4.getDestinationAddress() >> 16 & 0xffff)
- + (ipv4.getDestinationAddress() & 0xffff);
- accumulation += ipv4.getProtocol() & 0xff;
- accumulation += this.length & 0xffff;
+ if (this.parent != null) {
+ if (this.parent instanceof IPv4) {
+ final IPv4 ipv4 = (IPv4) this.parent;
+ accumulation += (ipv4.getSourceAddress() >> 16 & 0xffff)
+ + (ipv4.getSourceAddress() & 0xffff);
+ accumulation += (ipv4.getDestinationAddress() >> 16 & 0xffff)
+ + (ipv4.getDestinationAddress() & 0xffff);
+ accumulation += ipv4.getProtocol() & 0xff;
+ accumulation += length & 0xffff;
+ } else if (this.parent instanceof IPv6) {
+ final IPv6 ipv6 = (IPv6) this.parent;
+ final int bbLength =
+ Ip6Address.BYTE_LENGTH * 2 // IPv6 src, dst
+ + 2 // nextHeader (with padding)
+ + 4; // length
+ final ByteBuffer bbChecksum = ByteBuffer.allocate(bbLength);
+ bbChecksum.put(ipv6.getSourceAddress());
+ bbChecksum.put(ipv6.getDestinationAddress());
+ bbChecksum.put((byte) 0); // padding
+ bbChecksum.put(ipv6.getNextHeader());
+ bbChecksum.putInt(length);
+ bbChecksum.rewind();
+ for (int i = 0; i < bbLength / 2; ++i) {
+ accumulation += 0xffff & bbChecksum.getShort();
+ }
+ }
}
for (int i = 0; i < this.length / 2; ++i) {