Paul Evans

NAME

IO::Socket::Packet - Object interface to AF_PACKET domain sockets

SYNOPSIS

 use IO::Socket::Packet;
 use Socket::Packet qw( unpack_sockaddr_ll );

 my $sock = IO::Socket::Packet->new( IfIndex => 0 );

 while( my ( $protocol, $ifindex, $hatype, $pkttype, $addr ) = 
    $sock->recv_unpack( my $packet, 8192, 0 ) ) {

    ...
 }

DESCRIPTION

This class provides an object interface to PF_PACKET sockets on Linux. It is built upon IO::Socket and inherits all the methods defined by this base class.

CONSTRUCTOR

$sock = IO::Socket::Packet->new( %args )

Creates a new IO::Socket::Packet object. If any arguments are passed it will be configured to contain a newly created socket handle, and be binded as required by the arguments. The recognised arguments are:

Type => INT

The socktype to use; should be either SOCK_RAW or SOCK_DGRAM. It not supplied a default of SOCK_RAW will be used.

Protocol => INT

Ethernet protocol number to bind to. To capture all protocols, use the ETH_P_ALL constant (or omit this key, which implies that as a default).

IfIndex => INT

If supplied, binds the socket to the specified interface index. To bind to all interfaces, use 0 (or omit this key, which implies that as a default).

IfName => STRING

If supplied, binds the socket to the interface with the specified name.

METHODS

( $addr, $len ) = $sock->recv_len( $buffer, $maxlen, $flags )

Similar to Perl's recv builtin, except it returns the packet length as an explict return value. This may be useful if $flags contains the MSG_TRUNC flag, obtaining the true length of the packet on the wire, even if this is longer than the data written in the buffer.

( $protocol, $ifindex, $hatype, $pkttype, $addr, $len ) = $sock->recv_unpack( $buffer, $size, $flags )

This method is a combination of recv_len and unpack_sockaddr_ll. If it successfully receives a packet, it unpacks the address and returns the fields from it, and the length of the received packet. If it fails, it returns an empty list.

If the ring-buffer has been set using setup_rx_ring, it will automatically be used by this method.

$protocol = $sock->protocol

Returns the ethertype protocol the socket is bound to.

$ifindex = $sock->ifindex

Returns the interface index the socket is bound to.

$ifname = $sock->ifname

Returns the name of the interface the socket is bound to.

$hatype = $sock->hatype

Returns the hardware address type for the interface the socket is bound to.

$time = $sock->timestamp

( $sec, $usec ) = $sock->timestamp

Returns the timestamp of the last received packet on the socket (as obtained by the SIOCGSTAMP ioctl). In scalar context, returns a single floating-point value in UNIX epoch seconds. In list context, returns the number of seconds, and the number of microseconds.

If the ring-buffer has been set using setup_rx_ring, this method returns the timestamp of the last packet received from it.

$time = $sock->timestamp_nano

( $sec, $nsec ) = $sock->timestamp_nano

Returns the nanosecond-precise timestamp of the last received packet on the socket (as obtained by the SIOCGSTAMPNS ioctl). In scalar context, returns a single floating-point value in UNIX epoch seconds. In list context, returns the number of seconds, and the number of nanoseconds.

If the ring-buffer has been set using setup_rx_ring, this method returns the timestamp of the last packet received from it.

INTERFACE NAME UTILITIES

The following methods are utilities around siocgifindex and siocgifname. If called on an object, they use the encapsulated socket. If called as class methods, they will create a temporary socket to pass to the kernel, then close it again.

$ifindex = $sock->ifname2index( $ifname )

$ifindex = IO::Socket::Packet->ifname2index( $ifname )

Returns the name for the given interface index, or undef if it doesn't exist.

$ifname = $sock->ifindex2name( $ifindex )

$ifname = IO::Socket::Packet->ifindex2name( $ifindex )

Returns the index for the given interface name, or undef if it doesn't exist.

SOCKET OPTION ACCESSORS

$sock->add_multicast( $addr, $ifindex )

Adds the given multicast address on the given interface index. If the interface index is not supplied, $sock->ifindex is used.

$sock->drop_multicast( $addr, $ifindex )

Drops the given multicast address on the given interface index. If the interface index is not supplied, $sock->ifindex is used.

$sock->promisc( $promisc, $ifindex )

Sets or clears the PACKET_MR_PROMISC flag on the given interface. If the interface index is not supplied, $sock->ifindex is used.

$sock->allmulti( $allmulti, $ifindex )

Sets or clears the PACKET_MR_ALLMULTI flag on the given interface. If the interface index is not supplied, $sock->ifindex is used.

$stats = $sock->statistics

Returns the socket statistics. This will be a two-field hash containing counts packets, the total number of packets the socket has seen, and drops, the number of packets that could not stored because the buffer was full.

$val = $sock->origdev

$sock->origdev( $val )

Return or set the value of the PACKET_ORIGDEV socket option.

RING-BUFFER METHODS

These methods operate on the high-performance memory-mapped capture buffer.

An example of how to use these methods for packet capture is included in the module distribution; see examples/capture-rxring.pl for more detail.

$size = $sock->setup_rx_ring( $frame_size, $frame_nr, $block_size )

Sets up the ring-buffer on the object. This method is identical to the Socket::Packet function setup_rx_ring, except that the ring-buffer variable is stored transparently within the $sock object; the caller does not need to manage it.

Once this buffer is enabled, the recv_len, timestamp and timestamp_nano methods will automatically use it instead of the regular recv()+ioctl() interface.

$len = $sock->get_ring_frame( $buffer, \%info )

Receives the next packet from the ring-buffer. If there are no packets waiting it will return undef. This method aliases the $buffer variable to the mmap()ed packet buffer.

For detail on the %info hash, see Socket::Packet's get_ring_frame() function.

Once the caller has finished with the $buffer data, the done_ring_frame method should be called to hand the frame buffer back to the kernel.

$len = $sock->wait_ring_frame( $buffer, \%info )

If a packet is ready, this method sets $buffer and %info as per the get_ring_frame method. If there are no packets waiting and the socket is in blocking mode, it will select() on the socket until a packet is available. If the socket is in non-blocking mode, it will return false with $! set to EAGAIN.

For detail on the %info hash, see Socket::Packet's get_ring_frame() function.

Once the caller has finished with the $buffer data, the done_ring_frame method should be called to hand the frame buffer back to the kernel.

$sock->done_ring_frame

Hands the current ring-buffer frame back to the kernel.

SEE ALSO

AUTHOR

Paul Evans <leonerd@leonerd.org.uk>