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 and setsockopt.

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
      constant ETH_P_ALL can be used instead, to capture any protocol. The
      pack_sockaddr_ll() and unpack_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 value 0 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 sockets

      * Linux::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>

