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
new
$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_RAWorSOCK_DGRAM. It not supplied a default ofSOCK_RAWwill be used. - Protocol => INT
-
Ethernet protocol number to bind to. To capture all protocols, use the
ETH_P_ALLconstant (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
recv_len
( $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.
recv_unpack
( $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
$protocol = $sock->protocol;
Returns the ethertype protocol the socket is bound to.
ifindex
$ifindex = $sock->ifindex;
Returns the interface index the socket is bound to.
ifname
$ifname = $sock->ifname;
Returns the name of the interface the socket is bound to.
hatype
$hatype = $sock->hatype;
Returns the hardware address type for the interface the socket is bound to.
timestamp
$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.
timestamp_nano
$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.
ifname2index
$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.
ifindex2name
$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
add_multicast
$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.
drop_multicast
$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.
promisc
$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.
allmulti
$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.
statistics
$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.
origdev
$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.
setup_rx_ring
$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.
get_ring_frame
$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.
wait_ring_frame
$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.
done_ring_frame
$sock->done_ring_frame;
Hands the current ring-buffer frame back to the kernel.
SEE ALSO
Socket::Packet - interface to Linux's
PF_PACKETsocket family
AUTHOR
Paul Evans <leonerd@leonerd.org.uk>