NAME
Socket::Packet
- interface to Linux's PF_PACKET
socket family
SYNOPSIS
use Socket qw( SOCK_RAW );
use Socket::Packet qw(
PF_PACKET
ETH_P_ALL
pack_sockaddr_ll unpack_sockaddr_ll
);
socket( my $sock, PF_PACKET, SOCK_RAW, 0 )
or die "Cannot socket() - $!\n";
bind( $sock, pack_sockaddr_ll( ETH_P_ALL, 0, 0, 0, "" ) )
or die "Cannot bind() - $!\n";
while( my $addr = recv( $sock, my $packet, 8192, 0 ) ) {
my ( $proto, $ifindex, $hatype, $pkttype, $addr )
= unpack_sockaddr_ll( $addr );
...
}
DESCRIPTION
To quote packet(7)
:
Packet sockets are used to receive or send raw packets at the device driver
(OSI Layer 2) level. They allow the user to implement protocol modules in
user space on top of the physical layer.
Sockets in the PF_PACKET
family get direct link-level access to the underlying hardware (i.e. Ethernet or similar). They are usually used to implement packet capturing, or sending of specially-constructed packets or to implement protocols the underlying kernel does not recognise.
The use of PF_PACKET
sockets is usually restricted to privileged users only.
This module also provides various other support functions which wrap ioctl()
s or socket options. This includes support for PACKET_RX_RING
, the high-performance zero-copy packet receive buffering, if the underlying platform supports it.
CONSTANTS
The following constants are exported
- PF_PACKET
-
The packet family (for
socket()
calls) - AF_PACKET
-
The address family
- PACKET_HOST
-
This packet is inbound unicast for this host.
- PACKET_BROADCAST
-
This packet is inbound broadcast.
- PACKET_MULTICAST
-
This packet is inbound multicast.
- PACKET_OTHERHOST
-
This packet is inbound unicast for another host.
- PACKET_OUTGOING
-
This packet is outbound.
- ETH_P_ALL
-
Pseudo-protocol number to capture all protocols.
- SOL_PACKET
-
Socket option level for
getsockopt
andsetsockopt
.
SOCKET OPTIONS
The following constants define socket options
- PACKET_STATISTICS (get; struct tpacket_stats)
-
Packet received and drop counters.
- PACKET_ORIGDEV (get or set; int)
-
Received packets will indicate the originally-received device, rather than the apparent one. This mainly relates to Ethernet bonding or VLANs.
This socket option is optional, and may not be provided on all platforms.
- PACKET_ADD_MEMBERSHIP (set; struct packet_mreq)
- PACKET_DROP_MEMBERSHIP (set; struct packet_mreq)
-
Membership of multicast or broadcast groups, or set promiscuous mode.
The
packet_mreq
type
field should be one of the following:- PACKET_MR_MULTICAST
-
A multicast group
- PACKET_MR_PROMISC
-
Set or clear the promiscuous flag; the address is ignored
- PACKET_MR_ALLMULTI
-
Set or clear the allmulti flag; the address is ignored
FUNCTIONS
The following pair of functions operate on AF_PACKET
address structures. The meanings of the parameters are:
- protocol
-
An ethertype protocol number. When using an address with
bind()
, the constantETH_P_ALL
can be used instead, to capture any protocol. Thepack_sockaddr_ll()
andunpack_sockaddr_ll()
functions byte-swap this value to or from network endian order. - ifindex
-
The index number of the interface on which the packet was sent or received. When using an address with
bind()
, the value0
can be used instead, to watch all interfaces. - hatype
-
The hardware ARP type of hardware address.
- pkttype
-
The type of the packet; indicates if it was sent or received. Will be one of the
PACKET_*
values. - addr
-
The underlying hardware address, in the type given by
hatype
.
pack_sockaddr_ll
$a = pack_sockaddr_ll( $protocol, $ifindex, $hatype, $pkttype, $addr )
Returns a sockaddr_ll
structure with the fields packed into it.
unpack_sockaddr_ll
( $protocol, $ifindex, $hatype, $pkttype, $addr ) = unpack_sockaddr_ll( $a )
Takes a sockaddr_ll
structure and returns the unpacked fields from it.
pack_packet_mreq
$mreq = pack_packet_mreq( $ifindex, $type, $addr )
Returns a packet_mreq
structure with the fields packed into it.
unpack_packet_mreq
( $ifindex, $type, $addr ) = unpack_packet_mreq( $mreq )
Takes a packet_mreq
structure and returns the unpacked fields from it.
unpack_tpacket_stats
( $packets, $drops ) = unpack_tpacket_stats( $stats )
Takes a tpacket_stats
structure from the PACKET_STATISTICS
sockopt and returns the unpacked fields from it.
siocgstamp
$time = siocgstamp( $sock )
( $sec, $usec ) = siocgstamp( $sock )
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.
siocgstampns
$time = siocgstampns( $sock )
( $sec, $nsec ) = siocgstampns( $sock )
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.
siocgifindex
$ifindex = siocgifindex( $sock, $ifname )
Returns the ifindex
of the interface with the given name if one exists, or undef
if not. $sock
does not need to be a PF_PACKET
socket, any socket handle will do.
siocgifname
$ifname = siocgifname( $sock, $ifindex )
Returns the ifname
of the interface at the given index if one exists, or undef
if not. $sock
does not need to be a PF_PACKET
socket, any socket handle will do.
recv_len
( $addr, $len ) = recv_len( $sock, $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.
RING-BUFFER FUNCTIONS
The following functions operate on the high-performance memory-mapped buffer feature of PF_PACKET
, allowing efficient packet-capture applications to share a buffer with the kernel directly, avoiding the need for per-packet system calls to recv()
(and possibly ioctl()
to obtain the timestamp).
The ring-buffer is optional, and may not be implemented on all platforms. If it is not implemented, then all the following functions will die with an error message.
setup_rx_ring
$size = setup_rx_ring( $sock, $frame_size, $frame_nr, $block_size )
Sets up the ring-buffer on the socket. The buffer will store $frame_nr
frames of up to $frame_size
bytes each (including metadata headers), and will be split in the kernel in blocks of $block_size
bytes. $block_size
should be a power of 2, at minimum, 4KiB.
If successful, the overall size of the buffer in bytes is returned. If not, undef
is returned, and $!
will hold the error value.
get_ring_frame_status
$status = get_ring_frame_status( $sock )
Returns the frame status of the next frame in the ring.
The following constants are defined for the status:
- TP_STATUS_KERNEL
-
This frame belongs to the kernel and userland should not touch it.
- TP_STATUS_USER
-
This frame belongs to userland and the kernel will not modify it.
- TP_STATUS_LOSING
-
Bitwise-or'ed with the status if packet loss has occurred since the previous frame.
get_ring_frame
$len = get_ring_frame( $sock, $buffer, \%info )
If the next frame is ready for userland, fills in keys of the %info
hash with its metadata, sets $buffer
to its contents, and return the length of the data. The $buffer
variable has its string backing buffer aliased, rather than the buffer copied into, for performance. The caller should not modify the variable, nor attempt to access it after the socket has been closed.
If the frame is not yet ready, this function returns undef.
The following fields are returned:
- tp_status
-
The status of the frame; see
get_ring_frame_status()
- tp_len
-
The length of the packet on the wire, in bytes
- tp_snaplen
-
The length of the packet captured and stored in the buffer, in bytes. This may be shorter than
tp_len
if, for example, a filter is set on the socket that truncated the packet. - tp_sec
- tp_nsec
-
The seconds and nanoseconds fields of the timestamp. If the underlying platform does not support
TPACKET_V2
, then this field will only have a resolution of microseconds; i.e. it will be a whole multiple of 1000. - tp_vlan_tci
-
VLAN information about the packet, if the underlying platform supports
TPACKET_V2
. If this is not supported, the key will not be present in the hash - sll_protocol
- sll_ifindex
- sll_hatype
- sll_pkttype
- sll_addr
-
Fields from the
struct sockaddr_ll
; see above for more detail
clear_ring_frame
clear_ring_frame( $sock )
Clears the status of current frame to hand it back to the kernel and moves on to the next.
SEE ALSO
IO::Socket::Packet - Object interface to
AF_PACKET
domain socketsLinux::SocketFilter - interface to Linux's socket packet filtering
packet(7)
- packet, AF_PACKET - packet interface on device level
AUTHOR
Paul Evans <leonerd@leonerd.org.uk>