使用Perl和庫Net :: Pcap和Net :: PcapWriter,您可以執行以下操作來刪除PPPoE圖層。這至少適用於我的路由器(fritz.box)。這需要適應其他封裝:
#!/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);
根據OSI模型,傳輸層是位於網絡層(層3,例如IP)之上的第4層(TCP,UDP),它本身位於數據鏈路和物理層(以太網)的頂部。使用通常的PPPoE,您可以在以太網(數據鏈路)之上的網絡層內部使用各種封裝,例如IP封裝在PPPoE內部封裝的PPP中。 所以你可能不想要的是去除傳輸層(TCP,UDP),而是去掉網絡層中的PPP和PPPoE封裝,這樣只剩下IP。 –
@SteffenUllrich是的,我的錯誤,我想寫數據鏈路層。這就是我想要達到的目標。 – Peter
不,你不想刪除數據鏈路層(以太網),但你想從網絡層去掉一些封裝。所以你不想刪除最底層,但是中間是一些東西。 –