diff --git a/ext/vserv-tcpip/README b/ext/vserv-tcpip/README new file mode 100755 index 00000000..20f38ac8 --- /dev/null +++ b/ext/vserv-tcpip/README @@ -0,0 +1,57 @@ +$Id: README 6024 2005-12-10 23:04:56Z dfs $ + +ABOUT +----- + +Virtual Services TCP/IP, or VServ TCP/IP for short, is a Java library that +enables you to easily manipulate IP and TCP packets. It is intended for +use in conjunction with a library which generates packets, such as +VServ IPQ, as byte arrays. At the moment it supports only IPv4 packet +manipulation. + +The API is still in flux; some methods are missing and some existing +methods will likely be renamed. If you would like something added, +please submit a patch in unified diff format. + + +REQUIREMENTS +------------ + +VServ TCP/IP requires J2SE 1.4 or greater to compile and run. + + +COMPILING +--------- + +The source code requires Apache Ant (http://ant.apache.org/) to compile. + + ant -projecthelp + +will list all build targets in build.xml. There are very few files +in the source tree: + + src/java Java source code + +When you compile the source with + + ant jar + +the following jar file will be created and placed in the lib/ directory: + + vserv-tcpip-version.jar + + +LICENSING +--------- + +VServ TCP/IP is Copyright 2004-2005 by Daniel F. Savarese and licensed +under the Apache License 2.0 as described in the files: + + LICENSE + NOTICE + + +CONTACT +------- + +To contact me see http://www.savarese.org/contact.html diff --git a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/ICMPEchoPacket.java b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/ICMPEchoPacket.java index ec197dae..343a9755 100755 --- a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/ICMPEchoPacket.java +++ b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/ICMPEchoPacket.java @@ -1,5 +1,5 @@ /* - * $Id: ICMPEchoPacket.java,v 1.1 2005/09/13 20:15:53 angryziber Exp $ + * $Id: ICMPEchoPacket.java 5260 2005-05-10 21:01:16Z dfs $ * * Copyright 2004-2005 Daniel F. Savarese * Contact Information: http://www.savarese.org/contact.html diff --git a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/ICMPPacket.java b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/ICMPPacket.java index f906c10e..159ce74a 100755 --- a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/ICMPPacket.java +++ b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/ICMPPacket.java @@ -1,5 +1,5 @@ /* - * $Id: ICMPPacket.java,v 1.1 2005/09/13 20:15:53 angryziber Exp $ + * $Id: ICMPPacket.java 5347 2005-05-25 22:45:54Z dfs $ * * Copyright 2004-2005 Daniel F. Savarese * Contact Information: http://www.savarese.org/contact.html @@ -206,37 +206,8 @@ public abstract class ICMPPacket extends IPPacket { * @return The computed ICMP checksum. */ public final int computeICMPChecksum(boolean update) { - int total = 0; - int len = getIPPacketLength(); - int i = _offset; - int imax = _offset + OFFSET_ICMP_CHECKSUM; - - while(i < imax) - total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); - - // Skip existing checksum. - i = _offset + OFFSET_ICMP_CHECKSUM + 2; - - imax = len - (len % 2); - - while(i < imax) - total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); - - if(i < len) - total+=((_data_[i] & 0xff) << 8); - - // Fold to 16 bits - while((total & 0xffff0000) != 0) - total = (total & 0xffff) + (total >>> 16); - - total = (~total & 0xffff); - - if(update) { - _data_[_offset + OFFSET_ICMP_CHECKSUM] = (byte)(total >> 8); - _data_[_offset + OFFSET_ICMP_CHECKSUM + 1] = (byte)(total & 0xff); - } - - return total; + return _computeChecksum_(_offset, _offset + OFFSET_ICMP_CHECKSUM, + getIPPacketLength(), 0, update); } diff --git a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/IPPacket.java b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/IPPacket.java index c06842f6..99d1cc23 100755 --- a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/IPPacket.java +++ b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/IPPacket.java @@ -1,5 +1,5 @@ /* - * $Id: IPPacket.java,v 1.1 2005/09/13 20:15:53 angryziber Exp $ + * $Id: IPPacket.java 6025 2005-12-10 23:21:25Z dfs $ * * Copyright 2004-2005 Daniel F. Savarese * Contact Information: http://www.savarese.org/contact.html @@ -34,9 +34,18 @@ import java.net.*; public class IPPacket { + /** Offset into byte array of the type of service header value. */ + public static final int OFFSET_TYPE_OF_SERVICE = 1; + /** Offset into byte array of total packet length header value. */ public static final int OFFSET_TOTAL_LENGTH = 2; + /** Offset into byte array of the identification header value. */ + public static final int OFFSET_IDENTIFICATION = 4; + + /** Offset into byte array of the flags header value. */ + public static final int OFFSET_FLAGS = 6; + /** Offset into byte array of source address header value. */ public static final int OFFSET_SOURCE_ADDRESS = 12; @@ -132,6 +141,79 @@ public class IPPacket { } + /** + * Sets the IP version header value. + * + * @param version A 4-bit unsigned integer. + */ + public final void setIPVersion(int version) { + _data_[0] &= 0x0f; + _data_[0] |= ((version << 4) & 0xf0); + } + + + /** + * Returns the IP version header value. + * + * @return The IP version header value. + */ + public final int getIPVersion() { + return ((_data_[0] & 0xf0) >> 4); + } + + + /** + * Sets the IP header length field. At most, this can be a + * four-bit value. The high order bits beyond the fourth bit + * will be ignored. + * + * @param length The length of the IP header in 32-bit words. + */ + public void setIPHeaderLength(int length) { + // Clear low order bits and then set + _data_[0] &= 0xf0; + _data_[0] |= (length & 0x0f); + } + + + /** + * @return The length of the IP header in 32-bit words. + */ + public final int getIPHeaderLength() { + return (_data_[0] & 0x0f); + } + + + /** + * @return The length of the IP header in bytes. + */ + public final int getIPHeaderByteLength() { + return getIPHeaderLength() << 2; + } + + + /** + * Sets the IP type of service header value. You have to set the individual + * service bits yourself. Convenience methods for setting the service + * bit fields directly may be added in a future version. + * + * @param service An 8-bit unsigned integer. + */ + public final void setTypeOfService(int service) { + _data_[OFFSET_TYPE_OF_SERVICE] = (byte)(service & 0xff); + } + + + /** + * Returns the IP type of service header value. + * + * @return The IP type of service header value. + */ + public final int getTypeOfService() { + return (_data_[OFFSET_TYPE_OF_SERVICE] & 0xff); + } + + /** * Sets the IP packet total length header value. * @@ -153,32 +235,71 @@ public class IPPacket { /** - * Sets the IP header length field. At most, this can be a - * four-bit value. The high order bits beyond the fourth bit - * will be ignored. + * Sets the IP identification header value. * - * @param length The length of the IP header in 32-bit words. + * @param id A 16-bit unsigned integer. */ - public void setIPHeaderLength(int length) { - // Clear low order bits and then set - _data_[0] &= 0xf0; - _data_[0] |= (length & 0xf); + public void setIdentification(int id) { + _data_[OFFSET_IDENTIFICATION] = (byte)((id >> 8) & 0xff); + _data_[OFFSET_IDENTIFICATION + 1] = (byte)(id & 0xff); } /** - * @return The length of the IP header in 32-bit words. + * Returns the IP identification header value. + * + * @return The IP identification header value. */ - public final int getIPHeaderLength() { - return (_data_[0] & 0xf); + public final int getIdentification() { + return (((_data_[OFFSET_IDENTIFICATION] & 0xff) << 8) | + (_data_[OFFSET_IDENTIFICATION + 1] & 0xff)); } /** - * @return The length of the IP header in bytes. + * Sets the IP flags header value. You have to set the individual + * flag bits yourself. Convenience methods for setting the flag + * bit fields directly may be added in a future version. + * + * @param flags A 3-bit unsigned integer. */ - public final int getIPHeaderByteLength() { - return getIPHeaderLength() << 2; + public final void setIPFlags(int flags) { + _data_[OFFSET_FLAGS] &= 0x1f; + _data_[OFFSET_FLAGS] |= ((flags << 5) & 0xe0); + } + + + /** + * Returns the IP flags header value. + * + * @return The IP flags header value. + */ + public final int getIPFlags() { + return ((_data_[OFFSET_FLAGS] & 0xe0) >> 5); + } + + + /** + * Sets the fragment offset header value. The offset specifies a + * number of octets (i.e., bytes). + * + * @param offset A 13-bit unsigned integer. + */ + public void setFragmentOffset(int offset) { + _data_[OFFSET_FLAGS] &= 0xe0; + _data_[OFFSET_FLAGS] |= ((offset >> 8) & 0x1f); + _data_[OFFSET_FLAGS + 1] = (byte)(offset & 0xff); + } + + + /** + * Returns the fragment offset header value. + * + * @return The fragment offset header value. + */ + public final int getFragmentOffset() { + return (((_data_[OFFSET_FLAGS] & 0x1f) << 8) | + (_data_[OFFSET_FLAGS + 1] & 0xff)); } @@ -200,6 +321,16 @@ public class IPPacket { } + /** + * Sets the time to live value in seconds. + * + * @param ttl The time to live value in seconds. + */ + public final void setTTL(int ttl) { + _data_[OFFSET_TTL] = (byte)ttl; + } + + /** * @return The time to live value in seconds. */ @@ -208,6 +339,52 @@ public class IPPacket { } + /** + * Calculates checksums assuming the checksum is a 16-bit header field. + * This method is generalized to work for IP, ICMP, UDP, and TCP packets + * given the proper parameters. + */ + protected int _computeChecksum_(int startOffset, + int checksumOffset, + int length, + int virtualHeaderTotal, + boolean update) + { + int total = 0; + int i = startOffset; + int imax = checksumOffset; + + while(i < imax) + total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); + + // Skip existing checksum. + i = checksumOffset + 2; + + imax = length - (length % 2); + + while(i < imax) + total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); + + if(i < length) + total+=((_data_[i] & 0xff) << 8); + + total+=virtualHeaderTotal; + + // Fold to 16 bits + while((total & 0xffff0000) != 0) + total = (total & 0xffff) + (total >>> 16); + + total = (~total & 0xffff); + + if(update) { + _data_[checksumOffset] = (byte)(total >> 8); + _data_[checksumOffset + 1] = (byte)(total & 0xff); + } + + return total; + } + + /** * Computes the IP checksum, optionally updating the IP checksum header. * @@ -218,31 +395,8 @@ public class IPPacket { * @return The computed IP checksum. */ public final int computeIPChecksum(boolean update) { - int i = 0; - int len = getIPHeaderByteLength(); - int total = 0; - - while(i < OFFSET_IP_CHECKSUM) - total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); - - // Skip existing checksum. - i = OFFSET_IP_CHECKSUM + 2; - - while(i < len) - total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); - - // Fold to 16 bits - while((total & 0xffff0000) != 0) - total = (total & 0xffff) + (total >>> 16); - - total = (~total & 0xffff); - - if(update) { - _data_[OFFSET_IP_CHECKSUM] = (byte)(total >> 8); - _data_[OFFSET_IP_CHECKSUM + 1] = (byte)(total & 0xff); - } - - return total; + return _computeChecksum_(0, OFFSET_IP_CHECKSUM, getIPHeaderByteLength(), + 0, update); } diff --git a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/OctetConverter.java b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/OctetConverter.java index bde902db..bcfb459d 100755 --- a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/OctetConverter.java +++ b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/OctetConverter.java @@ -1,5 +1,5 @@ /* - * $Id: OctetConverter.java,v 1.1 2005/09/13 20:15:53 angryziber Exp $ + * $Id: OctetConverter.java 5067 2005-03-24 06:10:10Z dfs $ * * Copyright 2004-2005 Daniel F. Savarese * Contact Information: http://www.savarese.org/contact.html diff --git a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/TCPPacket.java b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/TCPPacket.java index 0cd9cc18..1a9ee380 100755 --- a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/TCPPacket.java +++ b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/TCPPacket.java @@ -1,5 +1,5 @@ /* - * $Id: TCPPacket.java,v 1.1 2005/09/13 20:15:53 angryziber Exp $ + * $Id: TCPPacket.java 6023 2005-12-10 20:42:15Z dfs $ * * Copyright 2004-2005 Daniel F. Savarese * Contact Information: http://www.savarese.org/contact.html @@ -337,6 +337,17 @@ public class TCPPacket extends IPPacket { } + /** + * Sets te TCP header length (i.e., the data offset field) in 32-bit words. + * + * @param length The TCP header length in 32-bit words. + */ + public final void setTCPHeaderLength(int length) { + _data_[__offset + OFFSET_HEADER_LENGTH] &= 0x0f; + _data_[__offset + OFFSET_HEADER_LENGTH] |= ((length << 4) & 0xf0); + } + + /** * @return The TCP header length in 32-bit words. */ @@ -353,6 +364,17 @@ public class TCPPacket extends IPPacket { } + /** + * Sets the TCP window size. + * + * @param window The TCP window size. + */ + public final void setWindowSize(int window) { + _data_[__offset + OFFSET_WINDOW_SIZE] = (byte)((window >> 8) & 0xff); + _data_[__offset + OFFSET_WINDOW_SIZE + 1] = (byte)(window & 0xff); + } + + /** * @return The TCP window size. */ @@ -362,6 +384,26 @@ public class TCPPacket extends IPPacket { } + /** + * Sets the urgent pointer. + * + * @param pointer The urgent pointer value. + */ + public final void setUrgentPointer(int pointer) { + _data_[__offset + OFFSET_URG_POINTER] = (byte)((pointer >> 8) & 0xff); + _data_[__offset + OFFSET_URG_POINTER + 1] = (byte)(pointer & 0xff); + } + + + /** + * @return The urgent pointer value. + */ + public final int getUrgentPointer() { + return (((_data_[__offset + OFFSET_URG_POINTER] & 0xff) << 8) | + (_data_[__offset + OFFSET_URG_POINTER + 1] & 0xff)); + } + + /** * @return The TCP checksum. */ @@ -433,39 +475,9 @@ public class TCPPacket extends IPPacket { * @return The computed TCP checksum. */ public final int computeTCPChecksum(boolean update) { - int total = 0; - int len = getIPPacketLength(); - int i = __offset; - int imax = __offset + OFFSET_TCP_CHECKSUM; - - while(i < imax) - total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); - - // Skip existing checksum. - i = __offset + OFFSET_URG_POINTER; - - imax = len - (len % 2); - - while(i < imax) - total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); - - if(i < len) - total+=((_data_[i] & 0xff) << 8); - - total+=__getVirtualHeaderTotal(); - - // Fold to 16 bits - while((total & 0xffff0000) != 0) - total = (total & 0xffff) + (total >>> 16); - - total = (~total & 0xffff); - - if(update) { - _data_[__offset + OFFSET_TCP_CHECKSUM] = (byte)(total >> 8); - _data_[__offset + OFFSET_TCP_CHECKSUM + 1] = (byte)(total & 0xff); - } - - return total; + return _computeChecksum_(__offset, __offset + OFFSET_TCP_CHECKSUM, + getIPPacketLength(), __getVirtualHeaderTotal(), + update); } diff --git a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/UDPPacket.java b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/UDPPacket.java index 90bdaa10..360e5f3c 100755 --- a/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/UDPPacket.java +++ b/ext/vserv-tcpip/src/java/org/savarese/vserv/tcpip/UDPPacket.java @@ -1,5 +1,5 @@ /* - * $Id: UDPPacket.java,v 1.1 2005/09/13 20:15:53 angryziber Exp $ + * $Id: UDPPacket.java 5347 2005-05-25 22:45:54Z dfs $ * * Copyright 2005 Daniel F. Savarese * Contact Information: http://www.savarese.org/contact.html @@ -235,39 +235,9 @@ public class UDPPacket extends IPPacket { * @return The computed UDP checksum. */ public final int computeUDPChecksum(boolean update) { - int total = 0; - int len = getIPPacketLength(); - int i = __offset; - int imax = __offset + OFFSET_UDP_CHECKSUM; - - while(i < imax) - total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); - - // Skip existing checksum. - i = __offset + LENGTH_UDP_HEADER; - - imax = len - (len % 2); - - while(i < imax) - total+=(((_data_[i++] & 0xff) << 8) | (_data_[i++] & 0xff)); - - if(i < len) - total+=((_data_[i] & 0xff) << 8); - - total+=__getVirtualHeaderTotal(); - - // Fold to 16 bits - while((total & 0xffff0000) != 0) - total = (total & 0xffff) + (total >>> 16); - - total = (~total & 0xffff); - - if(update) { - _data_[__offset + OFFSET_UDP_CHECKSUM] = (byte)(total >> 8); - _data_[__offset + OFFSET_UDP_CHECKSUM + 1] = (byte)(total & 0xff); - } - - return total; + return _computeChecksum_(__offset, __offset + OFFSET_UDP_CHECKSUM, + getIPPacketLength(), __getVirtualHeaderTotal(), + update); }