Savarese.Org

org.savarese.rocksaw.net
Class RawSocket

java.lang.Object
  extended by org.savarese.rocksaw.net.RawSocket

public class RawSocket
extends java.lang.Object

The RawSocket class provides a strictly utilitarian API for performing I/O with IPv4 and IPv6 raw sockets. The API is currently crude, but functional. It should evolve into something more feature-complete and flexible.

We throw java.io.InterruptedIOException when read/write operations time out because java.net.SocketTimeoutException is present only in J2SE 1.4 and up. By using InterruptedIOException, we allow programmers to use the software with J2SE 1.2 and 1.3.

Socket options should not be set until the socket has been opened.

Important! On most operating systems, you must have root access or administrative privileges to use raw sockets.

Author:
Daniel F. Savarese

Field Summary
static int PF_INET
          A protocol family constant for open(int, int) indicating IPv4.
static int PF_INET6
          A protocol family constant for open(int, int) indicating IPv6.
 
Constructor Summary
RawSocket()
          Creates an uninitialized socket.
 
Method Summary
 void bind(java.net.InetAddress address)
          Binds a local network address to a previously opened raw socket.
 void bindDevice(java.lang.String device)
          Binds a network device (e.g., eth0) to a previously opened raw socket.
 void close()
          Closes the socket.
 boolean getIPHeaderInclude()
          Retrieves the current setting of the IP_HDRINCL option.
static int getProtocolByName(java.lang.String name)
          Returns the protocol number corresponding to the given protocol name.
 int getReceiveBufferSize()
          Retrieves the receive buffer size (SO_RCVBUF).
 int getReceiveTimeout()
          Retrieves the receive timeout (SO_RCVTIMEO).
 int getSendBufferSize()
          Retrieves the send buffer size (SO_SNDBUF).
 int getSendTimeout()
          Retrieves the send timeout (SO_SNDTIMEO).
 void getSourceAddressForDestination(java.net.InetAddress destination, byte[] source)
          Returns by out parameter the address of the network interface that will be used to send a packet to the given destination.
 boolean getUseSelectTimeout()
          Determines whether or not socket send/receive timeouts are emulated by using the POSIX select system function.
 boolean isOpen()
          Tests if the socket has been opened.
 void open(int protocolFamily, int protocol)
          Opens a raw socket.
 int read(byte[] data)
          Same as read(address, data, 0, data.length, null);
 int read(byte[] data, byte[] address)
          Same as read(data, 0, data.length, address);
 int read(byte[] data, int offset, int length)
          Same as read(data, 0, length, null);
 int read(byte[] data, int offset, int length, byte[] address)
          Reads packet data from the socket.
 void setIPHeaderInclude(boolean on)
          Sets or unsets the IP_HDRINCL socket option.
 void setReceiveBufferSize(int size)
          Sets the receive buffer size (SO_RCVBUF).
 void setReceiveTimeout(int timeout)
          Sets the receive timeout (SO_RCVTIMEO).
 void setSendBufferSize(int size)
          Sets the send buffer size (SO_SNDBUF).
 void setSendTimeout(int timeout)
          Sets the send timeout (SO_SNDTIMEO).
 void setUseSelectTimeout(boolean useSelect)
          Sets whether or not socket send/receive timeouts should be emulated by using the POSIX select function.
 int write(java.net.InetAddress address, byte[] data)
          Same as write(address, data, 0, data.length);
 int write(java.net.InetAddress address, byte[] data, int offset, int length)
          Writes packet data to the socket.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

PF_INET

public static final int PF_INET
A protocol family constant for open(int, int) indicating IPv4. This should be moved to another class.


PF_INET6

public static final int PF_INET6
A protocol family constant for open(int, int) indicating IPv6. This should be moved to another class.

Constructor Detail

RawSocket

public RawSocket()
Creates an uninitialized socket. If the os.name system property starts with the string "SunOS", setUseSelectTimeout(boolean) is set to true (because Solaris does not support socket send and receive timeouts), otherwise it is false by default.

Method Detail

isOpen

public boolean isOpen()
Tests if the socket has been opened.

Returns:
True if the socket is open.

getProtocolByName

public static final int getProtocolByName(java.lang.String name)

Returns the protocol number corresponding to the given protocol name. For example, getProtocolByName("icmp"); should return 1 and getProtocolByName("udp"); should return 17. The native system protocol database is used to look up the protocol numbers.

This method really belongs in another class, probably in vserv-tcpip, but is currently included here as a convenience. It may be moved elsewhere in the 1.0 release API.

Returns:
The protocol number corresponding to the given protocol name. If the protocol name cannot be found, returns a negative value.

getSourceAddressForDestination

public void getSourceAddressForDestination(java.net.InetAddress destination,
                                           byte[] source)
                                    throws java.io.IOException

Returns by out parameter the address of the network interface that will be used to send a packet to the given destination. This works on Windows only and is necessary in order to compute ICMPv6 checksums.

This method really belongs in another class,, but is currently included here for expediency. It may be moved elsewhere in the 1.0 release API.

Parameters:
destination - The address of the destination.
source - A byte array in which to store the returned source address. On platforms other than Microsoft Windows, the array is left unchanged.
Throws:
java.io.IOException - If an I/O error occurs.

open

public void open(int protocolFamily,
                 int protocol)
          throws java.lang.IllegalStateException,
                 java.io.IOException
Opens a raw socket.

Parameters:
protocolFamily - The protocol family of the socket (e.g., PF_INET or PF_INET6).
protocol - The protocol within the protocol family. getProtocolByName(java.lang.String) should be used to obtain protocol numbers.
Throws:
java.lang.IllegalStateException - If the object instance is already open.
java.io.IOException - If an error occurs while opening the socket.

bind

public void bind(java.net.InetAddress address)
          throws java.lang.IllegalStateException,
                 java.io.IOException
Binds a local network address to a previously opened raw socket. On most operating systems, binding a raw socket to an address causes only packets with a destination matching the address to be delivered to the socket. Also, the kernel will set the source address of outbound packets to the bound address (unless setIPHeaderInclude(true) has been called).

Parameters:
address - The address to bind.
Throws:
java.lang.IllegalStateException - If the socket has not been opened first.
java.io.IOException - If the address cannot be bound.

bindDevice

public void bindDevice(java.lang.String device)
                throws java.lang.UnsupportedOperationException,
                       java.lang.IllegalStateException,
                       java.io.IOException
Binds a network device (e.g., eth0) to a previously opened raw socket. This is implemented currently only for Linux using the SO_BINDTODEVICE socket option. Sent packets will leave through the bound device and only packets arriving via the device will be delivered to the socket.

Parameters:
device - The name of the device to bind (e.g., "eth0"). Passing a zero-length string will remove the current binding. The loopback interface ("lo") and device aliases (e.g., "eth0:1") cannot be bound.
Throws:
java.lang.IllegalStateException - If the socket has not been opened first.
java.lang.UnsupportedOperationException - If binding a device name is not supported on the runtime platform.
java.io.IOException - If the device cannot be bound.

close

public void close()
           throws java.io.IOException
Closes the socket.

Throws:
java.io.IOException - If an I/O error occurs.

setIPHeaderInclude

public void setIPHeaderInclude(boolean on)
                        throws java.net.SocketException
Sets or unsets the IP_HDRINCL socket option. Setting this option causes IPv4 packet writes to expect the entire IP packet, starting from the header. The default behavior is to only expect the data payload. This option is valid only for IPv4 sockets.

Parameters:
on - True if headers should be included, false if not.
Throws:
java.net.SocketException - If the option setting could not be altered.

getIPHeaderInclude

public boolean getIPHeaderInclude()
                           throws java.net.SocketException
Retrieves the current setting of the IP_HDRINCL option.

Returns:
True if the IP_HDRINCL option is set, false if not.
Throws:
java.net.SocketException - If the option value could not be retrieved.

setSendBufferSize

public void setSendBufferSize(int size)
                       throws java.net.SocketException
Sets the send buffer size (SO_SNDBUF).

Parameters:
size - The size of the send buffer.
Throws:
java.net.SocketException - If the option value could not be set.

getSendBufferSize

public int getSendBufferSize()
                      throws java.net.SocketException
Retrieves the send buffer size (SO_SNDBUF).

Returns:
The size of the send buffer.
Throws:
java.net.SocketException - If the option value could not be retrieved.

setReceiveBufferSize

public void setReceiveBufferSize(int size)
                          throws java.net.SocketException
Sets the receive buffer size (SO_RCVBUF).

Parameters:
size - The size of the receive buffer.
Throws:
java.net.SocketException - If the option value could not be set.

getReceiveBufferSize

public int getReceiveBufferSize()
                         throws java.net.SocketException
Retrieves the receive buffer size (SO_RCVBUF).

Returns:
The size of the receive buffer.
Throws:
java.net.SocketException - If the option value could not be retrieved.

setUseSelectTimeout

public void setUseSelectTimeout(boolean useSelect)

Sets whether or not socket send/receive timeouts should be emulated by using the POSIX select function. Not all platforms support socket send/receive timeouts and this method provides a means to reproduce the same effect.

This method is not guaranteed to be retained in the 1.0 API. We may find a better way to provide support for read/write timeouts on all platforms. Technically, it's better to simply use non-blocking I/O rather than rely on socket timeouts, but we have yet to add a non-blocking I/O interface.

Parameters:
useSelect - true if select should be used to implement timeouts, false if not.

getUseSelectTimeout

public boolean getUseSelectTimeout()

Determines whether or not socket send/receive timeouts are emulated by using the POSIX select system function. Not all platforms support socket send/receive timeouts. The default value is false except for platforms where the os.name property starts with the string "SunOS".

Returns:
True if send/receive timeouts are emulated with select, false if not.

setSendTimeout

public void setSendTimeout(int timeout)
                    throws java.net.SocketException
Sets the send timeout (SO_SNDTIMEO). A timeout of zero indicates an infinite timeout. A negative timeout is undefined.

Parameters:
timeout - The send timeout in milliseconds.
Throws:
java.net.SocketException - If the option value could not be set.

getSendTimeout

public int getSendTimeout()
                   throws java.net.SocketException
Retrieves the send timeout (SO_SNDTIMEO).

Returns:
The send timeout in milliseconds.
Throws:
java.net.SocketException - If the option value could not be set.

setReceiveTimeout

public void setReceiveTimeout(int timeout)
                       throws java.net.SocketException
Sets the receive timeout (SO_RCVTIMEO). A timeout of zero indicates an infinite timeout. A negative timeout is undefined.

Parameters:
timeout - The receive timeout in milliseconds.
Throws:
java.net.SocketException - If the option value could not be set.

getReceiveTimeout

public int getReceiveTimeout()
                      throws java.net.SocketException
Retrieves the receive timeout (SO_RCVTIMEO).

Returns:
The receive timeout in milliseconds.
Throws:
java.net.SocketException - If the option value could not be set.

read

public int read(byte[] data,
                int offset,
                int length,
                byte[] address)
         throws java.lang.IllegalArgumentException,
                java.io.IOException,
                java.io.InterruptedIOException
Reads packet data from the socket. IPv4 (PF_INET) packets will be delivered in their entirety, including the IP header. IPv6 (PF_INET6) packet data will not include the IPV6 header.

Parameters:
data - The buffer in which to store the packet data.
offset - The offset into the buffer where the data should be stored.
length - The number of bytes to read.
address - A byte array in which to store the source address of the received packet. It may be null if you don't want to retrieve the source address. Otherwise, it must be the right size to store the address (e.g., 4 bytes for an IPv4 address).
Returns:
The number of bytes read.
Throws:
java.lang.IllegalArgumentException - If the offset or lengths are invalid or if the address parameter is the wrong length.
java.io.IOException - If an I/O error occurs.
java.io.InterruptedIOException - If the read operation times out.

read

public int read(byte[] data,
                int offset,
                int length)
         throws java.lang.IllegalArgumentException,
                java.io.IOException,
                java.io.InterruptedIOException
Same as read(data, 0, length, null);

Throws:
java.lang.IllegalArgumentException
java.io.IOException
java.io.InterruptedIOException

read

public int read(byte[] data,
                byte[] address)
         throws java.io.IOException,
                java.io.InterruptedIOException
Same as read(data, 0, data.length, address);

Throws:
java.io.IOException
java.io.InterruptedIOException

read

public int read(byte[] data)
         throws java.io.IOException,
                java.io.InterruptedIOException
Same as read(address, data, 0, data.length, null);

Throws:
java.io.IOException
java.io.InterruptedIOException

write

public int write(java.net.InetAddress address,
                 byte[] data,
                 int offset,
                 int length)
          throws java.lang.IllegalArgumentException,
                 java.io.IOException,
                 java.io.InterruptedIOException
Writes packet data to the socket. The data should not include the IP header. IPv4 (PF_INET) sockets may set the IP_HDRINCL option with setIPHeaderInclude(boolean), in which case the packet data should include the IP header.

Parameters:
address - The destination to write to.
data - The buffer from which to copy the packet data.
offset - The offset into the buffer where the data starts.
length - The number of bytes to write.
Returns:
The number of bytes written.
Throws:
java.lang.IllegalArgumentException - If the offset or lengths are invalid.
java.io.IOException - If an I/O error occurs.
java.io.InterruptedIOException - If the write operation times out.

write

public int write(java.net.InetAddress address,
                 byte[] data)
          throws java.io.IOException,
                 java.io.InterruptedIOException
Same as write(address, data, 0, data.length);

Throws:
java.io.IOException
java.io.InterruptedIOException

Savarese.Org

Copyright © 2004-2007 Daniel F. Savarese. All Rights Reserved.