ThatGuy
ThatGuy

Reputation: 303

Bind to an interface in perl

Alright so I am looking at perls Socket module but it does not seem to support listening for all traffic on an interface...Say eth1.

I am basically doing a dump of all traffic on my core router to a linux box, this is not being done via ip though. I am able to watch all traffic with tcpdump and could build a wrapper around that but I would rather perl actually listen on the interface and parse all of the traffic. Any ideas?

Upvotes: 1

Views: 834

Answers (2)

LeoNerd
LeoNerd

Reputation: 8532

If you're wanting to implement some kind of packet-capture system, you don't want to be using the normal IP layer. Instead, you'll be wanting a PF_PACKET socket.

For that you may wish to use IO::Socket::Packet. For example, to quote the supplied example program capture.pl:

#!/usr/bin/perl

use strict;
use warnings;

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

my $sock = IO::Socket::Packet->new( IfIndex => 0 )
   or die "Cannot create PF_PACKET socket - $!";

while( my ( $proto, $ifindex, $hatype, $pkttype, $addr ) = $sock->recv_unpack( my $packet, 8192, 0 ) ) {
   my ( $ts, $ts_usec ) = $sock->timestamp;
   my @ts = localtime $ts;
   printf "[%4d/%02d/%02d %02d:%02d:%02d.%06d] ", $ts[5]+1900, $ts[4]+1, @ts[3,2,1,0], $ts_usec;

   # Reformat nicely for printing
   $addr = join( ":", map sprintf("%02x", ord $_), split //, $addr );

   if( $pkttype == PACKET_OUTGOING ) {
      print "Sent a packet to $addr";
   }
   else {
      print "Received a packet from $addr";
   }

   printf " of protocol %04x on %s:\n", $proto, $sock->ifindex2name( $ifindex );

   printf "  %v02x\n", $1 while $packet =~ m/(.{1,16})/sg;
}

Upvotes: 1

SzG
SzG

Reputation: 12609

I think you are confusing the listen() system call, also implemented in Perl, with tcpdump listening on a network interface and capturing raw TCP or UDP packets.

The listen() system call, used in servers, is called after you've created a proto-socket and bound it to an IP:port combo. After that the accept() system call returns real socket fds for each incoming connection.

The Unix socket interface totally abstracts away raw TCP/UDP IP packets. The socket interface is not what you want.

Upvotes: 0

Related Questions