File Coverage

blib/lib/IO/Socket/Packet.pm
Criterion Covered Total %
statement 62 131 47.3
branch 14 58 24.1
condition 5 7 71.4
subroutine 16 28 57.1
pod 18 19 94.7
total 115 243 47.3


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2009-2020 -- leonerd@leonerd.org.uk
5              
6             package IO::Socket::Packet;
7              
8 3     3   74609 use strict;
  3         15  
  3         87  
9 3     3   16 use warnings;
  3         37  
  3         98  
10 3     3   16 use base qw( IO::Socket );
  3         5  
  3         1941  
11              
12             our $VERSION = '0.11';
13              
14 3     3   59283 use Carp;
  3         8  
  3         154  
15              
16 3     3   1092 use POSIX qw( EAGAIN );
  3         13357  
  3         24  
17 3     3   3085 use Socket qw( AF_INET SOCK_STREAM SOCK_RAW );
  3         6  
  3         512  
18              
19 3         5429 use Socket::Packet qw(
20             AF_PACKET ETH_P_ALL
21             pack_sockaddr_ll unpack_sockaddr_ll
22             pack_packet_mreq
23             unpack_tpacket_stats
24             siocgstamp siocgstampns
25             siocgifindex siocgifname
26             recv_len
27              
28             SOL_PACKET
29              
30             PACKET_ADD_MEMBERSHIP
31             PACKET_DROP_MEMBERSHIP
32             PACKET_STATISTICS
33              
34             PACKET_MR_MULTICAST
35             PACKET_MR_PROMISC
36             PACKET_MR_ALLMULTI
37 3     3   595 );
  3         9  
38              
39             __PACKAGE__->register_domain( AF_PACKET );
40              
41             =head1 NAME
42              
43             C - Object interface to C domain sockets
44              
45             =head1 SYNOPSIS
46              
47             use IO::Socket::Packet;
48             use Socket::Packet qw( unpack_sockaddr_ll );
49              
50             my $sock = IO::Socket::Packet->new( IfIndex => 0 );
51              
52             while( my ( $protocol, $ifindex, $hatype, $pkttype, $addr ) =
53             $sock->recv_unpack( my $packet, 8192, 0 ) ) {
54              
55             ...
56             }
57              
58             =head1 DESCRIPTION
59              
60             This class provides an object interface to C sockets on Linux. It
61             is built upon L and inherits all the methods defined by this base
62             class.
63              
64             =cut
65              
66             =head1 CONSTRUCTOR
67              
68             =cut
69              
70             =head2 new
71              
72             $sock = IO::Socket::Packet->new( %args )
73              
74             Creates a new C object. If any arguments are passed it
75             will be configured to contain a newly created socket handle, and be Ced
76             as required by the arguments. The recognised arguments are:
77              
78             =over 8
79              
80             =item Type => INT
81              
82             The socktype to use; should be either C or C. It not
83             supplied a default of C will be used.
84              
85             =item Protocol => INT
86              
87             Ethernet protocol number to bind to. To capture all protocols, use the
88             C constant (or omit this key, which implies that as a default).
89              
90             =item IfIndex => INT
91              
92             If supplied, binds the socket to the specified interface index. To bind to all
93             interfaces, use 0 (or omit this key, which implies that as a default).
94              
95             =item IfName => STRING
96              
97             If supplied, binds the socket to the interface with the specified name.
98              
99             =back
100              
101             =cut
102              
103             sub configure
104             {
105 3     3 0 16084 my $self = shift;
106 3         7 my ( $arg ) = @_;
107              
108 3   50     22 my $type = $arg->{Type} || SOCK_RAW;
109              
110 3 50       13 $self->socket( AF_PACKET, $type, 0 ) or return undef;
111              
112             # bind() arguments
113 3         202 my ( $protocol, $ifindex );
114              
115 3 50       10 $protocol = $arg->{Protocol} if exists $arg->{Protocol};
116 3 100       8 $ifindex = $arg->{IfIndex} if exists $arg->{IfIndex};
117              
118 3 50 66     16 if( !defined $ifindex and exists $arg->{IfName} ) {
119 1         23 $ifindex = siocgifindex( $self, $arg->{IfName} );
120 1 50       7 defined $ifindex or return undef;
121             }
122              
123 3 50 100     38 $self->bind( pack_sockaddr_ll(
    50          
124             defined $protocol ? $protocol : ETH_P_ALL,
125             $ifindex || 0,
126             0, 0, '' ) ) or return undef;
127              
128 3         86 return $self;
129             }
130              
131             =head1 METHODS
132              
133             =cut
134              
135             =head2 recv_len
136              
137             ( $addr, $len ) = $sock->recv_len( $buffer, $maxlen, $flags )
138              
139             Similar to Perl's C builtin, except it returns the packet length as an
140             explict return value. This may be useful if C<$flags> contains the
141             C flag, obtaining the true length of the packet on the wire, even
142             if this is longer than the data written in the buffer.
143              
144             =cut
145              
146             # don't actually need to implement it; the imported symbol works fine
147              
148             =head2 recv_unpack
149              
150             ( $protocol, $ifindex, $hatype, $pkttype, $addr, $len ) =
151             $sock->recv_unpack( $buffer, $size, $flags )
152              
153             This method is a combination of C and C. If it
154             successfully receives a packet, it unpacks the address and returns the fields
155             from it, and the length of the received packet. If it fails, it returns an
156             empty list.
157              
158             If the ring-buffer has been set using C, it will automatically
159             be used by this method.
160              
161             =cut
162              
163             sub recv_unpack
164             {
165 0     0 1 0 my $self = shift;
166              
167 0 0       0 if( defined ${*$self}{packet_rx_ring} ) {
  0         0  
168 0 0       0 defined $self->wait_ring_frame( my $buffer, \my %info ) or return;
169              
170             # Copy to caller
171 0         0 $_[0] = $buffer;
172              
173 0         0 $self->done_ring_frame;
174              
175 0         0 ${*$self}{packet_ts_sec} = $info{tp_sec};
  0         0  
176 0         0 ${*$self}{packet_ts_nsec} = $info{tp_nsec};
  0         0  
177              
178             return ( $info{sll_protocol},
179             $info{sll_ifindex},
180             $info{sll_hatype},
181             $info{sll_pkttype},
182             $info{sll_addr},
183 0         0 $info{tp_len} );
184             }
185              
186 0 0       0 my ( $addr, $len ) = $self->recv_len( @_ ) or return;
187 0         0 return unpack_sockaddr_ll( $addr ), $len;
188             }
189              
190             =head2 protocol
191              
192             $protocol = $sock->protocol
193              
194             Returns the ethertype protocol the socket is bound to.
195              
196             =cut
197              
198             sub protocol
199             {
200 2     2 1 3257 my $self = shift;
201 2         11 return (unpack_sockaddr_ll($self->sockname))[0];
202             }
203              
204             =head2 ifindex
205              
206             $ifindex = $sock->ifindex
207              
208             Returns the interface index the socket is bound to.
209              
210             =cut
211              
212             sub ifindex
213             {
214 5     5 1 1175 my $self = shift;
215 5         17 return (unpack_sockaddr_ll($self->sockname))[1];
216             }
217              
218             =head2 ifname
219              
220             $ifname = $sock->ifname
221              
222             Returns the name of the interface the socket is bound to.
223              
224             =cut
225              
226             sub ifname
227             {
228 3     3 1 1210 my $self = shift;
229 3         7 return siocgifname( $self, $self->ifindex );
230             }
231              
232             =head2 hatype
233              
234             $hatype = $sock->hatype
235              
236             Returns the hardware address type for the interface the socket is bound to.
237              
238             =cut
239              
240             sub hatype
241             {
242 2     2 1 1081 my $self = shift;
243 2         7 return (unpack_sockaddr_ll($self->sockname))[2];
244             }
245              
246             =head2 timestamp
247              
248             $time = $sock->timestamp
249              
250             ( $sec, $usec ) = $sock->timestamp
251              
252             Returns the timestamp of the last received packet on the socket (as obtained
253             by the C C). In scalar context, returns a single
254             floating-point value in UNIX epoch seconds. In list context, returns the
255             number of seconds, and the number of microseconds.
256              
257             If the ring-buffer has been set using C, this method returns
258             the timestamp of the last packet received from it.
259              
260             =cut
261              
262             sub timestamp
263             {
264 1     1 1 543 my $self = shift;
265              
266 1 50       2 if( defined ${*$self}{packet_ts_sec} ) {
  1         6  
267 0         0 my $sec = delete ${*$self}{packet_ts_sec};
  0         0  
268 0         0 my $nsec = delete ${*$self}{packet_ts_nsec};
  0         0  
269              
270 0 0       0 return wantarray ? ( $sec, int($nsec/1000) ) : $sec + $nsec/1_000_000_000;
271             }
272              
273 1         15 return siocgstamp( $self );
274             }
275              
276             =head2 timestamp_nano
277              
278             $time = $sock->timestamp_nano
279              
280             ( $sec, $nsec ) = $sock->timestamp_nano
281              
282             Returns the nanosecond-precise timestamp of the last received packet on the
283             socket (as obtained by the C C). In scalar context,
284             returns a single floating-point value in UNIX epoch seconds. In list context,
285             returns the number of seconds, and the number of nanoseconds.
286              
287             If the ring-buffer has been set using C, this method returns
288             the timestamp of the last packet received from it.
289              
290             =cut
291              
292             sub timestamp_nano
293             {
294 0     0 1 0 my $self = shift;
295              
296 0 0       0 if( defined ${*$self}{packet_ts_sec} ) {
  0         0  
297 0         0 my $sec = delete ${*$self}{packet_ts_sec};
  0         0  
298 0         0 my $nsec = delete ${*$self}{packet_ts_nsec};
  0         0  
299              
300 0 0       0 return wantarray ? ( $sec, $nsec ) : $sec + $nsec/1_000_000_000;
301             }
302              
303 0         0 return siocgstampns( $self );
304             }
305              
306             =head1 INTERFACE NAME UTILITIES
307              
308             The following methods are utilities around C and C.
309             If called on an object, they use the encapsulated socket. If called as class
310             methods, they will create a temporary socket to pass to the kernel, then close
311             it again.
312              
313             =cut
314              
315             =head2 ifname2index
316              
317             $ifindex = $sock->ifname2index( $ifname )
318              
319             $ifindex = IO::Socket::Packet->ifname2index( $ifname )
320              
321             Returns the name for the given interface index, or C if it doesn't
322             exist.
323              
324             =cut
325              
326             sub ifname2index
327             {
328 1     1 1 924 my $self = shift;
329 1         3 my ( $ifname ) = @_;
330              
331 1         1 my $sock;
332 1 50       5 if( ref $self ) {
333 0         0 $sock = $self;
334             }
335             else {
336 1 50       35 socket( $sock, AF_INET, SOCK_STREAM, 0 ) or
337             croak "Cannot socket(AF_INET) - $!";
338             }
339              
340 1         34 return siocgifindex( $sock, $ifname );
341             }
342              
343             =head2 ifindex2name
344              
345             $ifname = $sock->ifindex2name( $ifindex )
346              
347             $ifname = IO::Socket::Packet->ifindex2name( $ifindex )
348              
349             Returns the index for the given interface name, or C if it doesn't
350             exist.
351              
352             =cut
353              
354             sub ifindex2name
355             {
356 2     2 1 107 my $self = shift;
357 2         5 my ( $ifindex ) = @_;
358              
359 2         3 my $sock;
360 2 50       6 if( ref $self ) {
361 0         0 $sock = $self;
362             }
363             else {
364 2 50       81 socket( $sock, AF_INET, SOCK_STREAM, 0 ) or
365             croak "Cannot socket(AF_INET) - $!";
366             }
367              
368 2         67 return siocgifname( $sock, $ifindex );
369             }
370              
371             sub _make_sockopt_int
372             {
373 0     0   0 my ( $optname ) = @_;
374              
375             # IO::Socket automatically handles the pack/unpack in this case
376              
377             sub {
378 0     0   0 my $sock = shift;
379              
380 0 0       0 if( @_ ) {
381 0         0 $sock->setsockopt( SOL_PACKET, $optname, $_[0] );
382             }
383             else {
384 0         0 return $sock->getsockopt( SOL_PACKET, $optname );
385             }
386 0         0 };
387             }
388              
389             =head1 SOCKET OPTION ACCESSORS
390              
391             =cut
392              
393             =head2 add_multicast
394              
395             $sock->add_multicast( $addr, $ifindex )
396              
397             Adds the given multicast address on the given interface index. If the
398             interface index is not supplied, C<< $sock->ifindex >> is used.
399              
400             =cut
401              
402             sub add_multicast
403             {
404 0     0 1 0 my $self = shift;
405 0         0 my ( $addr, $ifindex ) = @_;
406 0 0       0 defined $ifindex or $ifindex = $self->ifindex;
407              
408 0         0 $self->setsockopt( SOL_PACKET, PACKET_ADD_MEMBERSHIP,
409             pack_packet_mreq( $ifindex, PACKET_MR_MULTICAST, $addr )
410             );
411             }
412              
413             =head2 drop_multicast
414              
415             $sock->drop_multicast( $addr, $ifindex )
416              
417             Drops the given multicast address on the given interface index. If the
418             interface index is not supplied, C<< $sock->ifindex >> is used.
419              
420             =cut
421              
422             sub drop_multicast
423             {
424 0     0 1 0 my $self = shift;
425 0         0 my ( $addr, $ifindex ) = @_;
426 0 0       0 defined $ifindex or $ifindex = $self->ifindex;
427              
428 0         0 $self->setsockopt( SOL_PACKET, PACKET_DROP_MEMBERSHIP,
429             pack_packet_mreq( $ifindex, PACKET_MR_MULTICAST, $addr )
430             );
431             }
432              
433             =head2 promisc
434              
435             $sock->promisc( $promisc, $ifindex )
436              
437             Sets or clears the PACKET_MR_PROMISC flag on the given interface. If the
438             interface index is not supplied, C<< $sock->ifindex >> is used.
439              
440             =cut
441              
442             sub promisc
443             {
444 0     0 1 0 my $self = shift;
445 0         0 my ( $value, $ifindex ) = @_;
446 0 0       0 defined $ifindex or $ifindex = $self->ifindex;
447              
448 0 0       0 $self->setsockopt( SOL_PACKET, $value ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
449             pack_packet_mreq( $ifindex, PACKET_MR_PROMISC, "" )
450             );
451             }
452              
453             =head2 allmulti
454              
455             $sock->allmulti( $allmulti, $ifindex )
456              
457             Sets or clears the PACKET_MR_ALLMULTI flag on the given interface. If the
458             interface index is not supplied, C<< $sock->ifindex >> is used.
459              
460             =cut
461              
462             sub allmulti
463             {
464 0     0 1 0 my $self = shift;
465 0         0 my ( $value, $ifindex ) = @_;
466 0 0       0 defined $ifindex or $ifindex = $self->ifindex;
467              
468 0 0       0 $self->setsockopt( SOL_PACKET, $value ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
469             pack_packet_mreq( $ifindex, PACKET_MR_ALLMULTI, "" )
470             );
471             }
472              
473             =head2 statistics
474              
475             $stats = $sock->statistics
476              
477             Returns the socket statistics. This will be a two-field hash containing
478             counts C, the total number of packets the socket has seen, and
479             C, the number of packets that could not stored because the buffer was
480             full.
481              
482             =cut
483              
484             sub statistics
485             {
486 1     1 1 16661 my $self = shift;
487              
488 1 50       16 my $stats = $self->getsockopt( SOL_PACKET, PACKET_STATISTICS )
489             or return;
490              
491 1         227 my %stats;
492 1         13 @stats{qw( packets drops)} = unpack_tpacket_stats( $stats );
493              
494 1         23 return \%stats;
495             }
496              
497             =head2 origdev
498              
499             $val = $sock->origdev
500              
501             $sock->origdev( $val )
502              
503             Return or set the value of the C socket option.
504              
505             =cut
506              
507             if( defined &Socket::Packet::PACKET_ORIGDEV ) {
508             *origdev = _make_sockopt_int( Socket::Packet::PACKET_ORIGDEV() );
509             }
510              
511             =head1 RING-BUFFER METHODS
512              
513             These methods operate on the high-performance memory-mapped capture buffer.
514              
515             An example of how to use these methods for packet capture is included in the
516             module distribution; see F for more detail.
517              
518             =cut
519              
520             =head2 setup_rx_ring
521              
522             $size = $sock->setup_rx_ring( $frame_size, $frame_nr, $block_size )
523              
524             Sets up the ring-buffer on the object. This method is identical to the
525             C function C, except that the ring-buffer
526             variable is stored transparently within the C<$sock> object; the caller does
527             not need to manage it.
528              
529             Once this buffer is enabled, the C, C and
530             C methods will automatically use it instead of the regular
531             C+C interface.
532              
533             =cut
534              
535             sub setup_rx_ring
536             {
537 0     0 1   my $self = shift;
538 0           my ( $frame_size, $frame_nr, $block_size ) = @_;
539              
540 0           my $ret = Socket::Packet::setup_rx_ring( $self, $frame_size, $frame_nr, $block_size );
541 0 0         ${*$self}{packet_rx_ring} = 1 if defined $ret;
  0            
542              
543 0           return $ret;
544             }
545              
546             =head2 get_ring_frame
547              
548             $len = $sock->get_ring_frame( $buffer, \%info )
549              
550             Receives the next packet from the ring-buffer. If there are no packets waiting
551             it will return undef. This method aliases the C<$buffer> variable to the
552             Ced packet buffer.
553              
554             For detail on the C<%info> hash, see L's C
555             function.
556              
557             Once the caller has finished with the C<$buffer> data, the C
558             method should be called to hand the frame buffer back to the kernel.
559              
560             =cut
561              
562             sub get_ring_frame
563             {
564 0     0 1   my $self = shift;
565              
566 0           return Socket::Packet::get_ring_frame( $self, $_[0], $_[1] );
567             }
568              
569             =head2 wait_ring_frame
570              
571             $len = $sock->wait_ring_frame( $buffer, \%info )
572              
573             If a packet is ready, this method sets C<$buffer> and C<%info> as per the
574             C method. If there are no packets waiting and the socket is
575             in blocking mode, it will C on the socket until a packet is
576             available. If the socket is in non-blocking mode, it will return false with
577             C<$!> set to C.
578              
579             For detail on the C<%info> hash, see L's C
580             function.
581              
582             Once the caller has finished with the C<$buffer> data, the C
583             method should be called to hand the frame buffer back to the kernel.
584              
585             =cut
586              
587             sub wait_ring_frame
588             {
589 0     0 1   my $self = shift;
590              
591 0           my $len;
592 0           while( !defined( $len = $self->get_ring_frame( $_[0], $_[1] ) ) ) {
593 0 0         $! = EAGAIN, return if not $self->blocking;
594              
595 0           my $rvec = '';
596 0           vec( $rvec, fileno $self, 1 ) = 1;
597 0 0         select( $rvec, undef, undef, undef ) or return;
598             }
599              
600 0           return $len;
601             }
602              
603             =head2 done_ring_frame
604              
605             $sock->done_ring_frame
606              
607             Hands the current ring-buffer frame back to the kernel.
608              
609             =cut
610              
611             sub done_ring_frame
612             {
613 0     0 1   my $self = shift;
614              
615 0           Socket::Packet::done_ring_frame( $self );
616             }
617              
618             =head1 SEE ALSO
619              
620             =over 4
621              
622             =item *
623              
624             L - interface to Linux's C socket family
625              
626             =back
627              
628             =head1 AUTHOR
629              
630             Paul Evans
631              
632             =cut
633              
634             0x55AA;