Question

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.

Was it helpful?

Solution

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top