I'm making a script that is inspecting packets, but headers giving me a headache. I have a DSL connection/Wireless at home, and the data link layer is appearing in Wireshark capture, either PPP or WLAN depending on which one I am currently using.
I've been searching for a thsark, editcap or tcpdump or whatever tutorial but I couldn't find any.
Basically all I need: < program_name_which_nicely_removes_transport_layer > input.pcap < output.pcap_only_containing_ethernet_header+ip+tcp+data > or something similar.
I have found a program named bittwiste, but it's operating with fixed sizes as I realized, but I need something 'universal', where I don't have to determine the used link type + size.
Any help is appreciated!
Thank you in advance.
With Perl and the libraries Net::Pcap and Net::PcapWriter you could do the following to remove the PPPoE layer. This works at least for my router (fritz.box). This needs to be adapted to other encapsulations:
#!/usr/bin/perl
# usage: pcap_remove_pppoe.pl infile.pcap outfile.pcap
use strict;
use warnings;
use Net::Pcap qw(pcap_open_offline pcap_loop pcap_datalink :datalink);
use Net::PcapWriter;
my $infile = shift or die "no input file";
my $outfile = shift; # use stdout if not given
my $err;
my $pcap = pcap_open_offline($infile,\$err) or
die "failed to open $infile: $err";
my $ll = pcap_datalink($pcap);
die "expected DLT_EN10MB, got $ll" if $ll != DLT_EN10MB;
my $offset = 14; # DLT_EN10MB
# open and initialize output
my $pw = Net::PcapWriter->new($outfile);
# process packets
pcap_loop($pcap, -1, sub {
my (undef,$hdr,$data) = @_;
my $dl = substr($data,0,$offset,''); # remove data link layer
my $etype = unpack("n",substr($dl,-2,2)); # get ethernet type
$etype == 0x8864 or return; # ignore any type except PPPoE Session
substr($data,0,8,''); # remove 8 byte PPPoE layer
substr($data,-2,2,pack("n",0x0800)); # set ethernet type to IPv4
# output: data link layer with IP type + IP layer (PPPoE removed)
$pw->packet($data, [ $hdr->{tv_sec},$hdr->{tv_usec} ]);
},undef);