Reading packages with Linux :: TunTap

I put together a perl script that reads packages in user space via Linux :: TunTap, and it all works fine:

#!/usr/bin/perl use warnings; use strict; use Linux::TunTap; $tun = new Linux::TunTap(NAME => 'localtun') or die "Couldn't connect to IF\n"; while (my $packet = $tun->get_raw()) { print Dumper($packet); } 

Now the question arises: how to turn a string representing a raw IP packet, as read from a tuntap device, into the correct data structure for processing? In particular, I get the source, target and serial number.

Obviously, the source IP packet is not very readable by the person in its source format. Here is the output after sending the ping via the tuntap interface:

{{{ }/ 8V | !"#$%&'()*+,-./0123456ET @@4

How can I go from here to be able to process this data programmatically?

+6
source share
1 answer

Based on a comment made by SteffenUlrich , I looked at NetPacket :: IP , which helped through its decode() method. It worked quite a bit out of the box after baking it into my code, with the only caveat that the first four bytes should come from raw data (see Lazy regex below), as these bytes form an additional header added by TunTap layer.

Now my code looks like this and works as intended:

 #!/usr/bin/perl use warnings; use strict; use Linux::TunTap; use NetPacket::IP; $tun = new Linux::TunTap(NAME => 'localtun') or die "Couldn't connect to IF\n"; while (my $rawdata = $tun->get_raw()) { $rawdata =~ s/^....//; # Using regex to strip 4 bytes, because I'm lazy my $packet = NetPacket::IP->decode($rawdata); print "$packet->{id} $packet->{src_ip} -> $packet->{dest_ip} $packet->{proto} $packet->{len}\n"; } 

The above code prints the sequence, source IP address, destination IP address, protocol number and packet length.

+4
source

All Articles