This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Perl Net::Pcap Can not parse wireshark saved pcap file

0

hello,
I am writing a perl script to parse pcap file from wireshark with Net::Pcap module, here are the simple code:

use strict;
use warnings;
use utf8;
use NetPacket::Ethernet qw(:types);
use NetPacket::IP qw(:protos);
use NetPacket::TCP;
use Net::Pcap qw(:functions);
my $pcap_file = "test.cap";
my $err = undef;
# read data from pcap file.
my $pcap = pcap_open_offline($pcap_file, \$err)
    or die "Can't read $pcap_file : $err\n";
 #  loop over next 10 packets
pcap_loop($pcap, -1, \&process_packet, "just for the demo");
# close the device
pcap_close($pcap);
sub process_packet {
    my ($user_data, $header, $packet) = @_;
    my $ether_data = NetPacket::Ethernet->decode($packet);
    # Decode contents of TCP/IP packet contained within 
    # captured ethernet packet
    # Print all out where its coming from and where its 
    # going to!
    my $eth_type = $ether_data->{'type'};
    print "prototype is $eth_type\n";
    if ($eth_type != NetPacket::Ethernet::ETH_TYPE_IP) {
        print "non-ip protocol\n";
        exit;
    }
}

I want to get the ethernet type from the pcap file from wireshark, but I just can get 0 any way, so I compare to tcpdump, tshark saved pcap file, it works well, so guess may wireshark save the pcap file in a slight different format, right?
So, do I have to use tshark -w instead wireshark to capture the packets? Any tips?
regards

asked 22 Jul '12, 02:17

liunx's gravatar image

liunx
16336
accept rate: 0%

edited 22 Jul '12, 08:00

Kurt%20Knochner's gravatar image

Kurt Knochner ♦
24.8k1039237

I also used ubuntu12.04LST x86_64, I got libpcap, libnet-pcap-perl from apt,should I compile them from source?

(22 Jul '12, 18:33) liunx

2 Answers:

1

Current Wireshark/tshark versions use the pcapng format for the capture file. Net::Pcap can only read libpcap compatible files.

If that's the problem, please use Wireshark/tshark option -F to write pcap format.

tshark -i eth0 -F libpcap -w /var/tmp/output.cap

UPDATE: It seems that Net::Pcap CAN read pcapng files, if libpcap can read that format (depends on the release of libpcap). I ran your script against the same file. Once in libpcap format and once in pcapng format. The script returned the same output (after I removed the exit statement). The output looks reasonable (correct ether_type).

So it's either a problem with your OS (libpcap version) or the input file (corrupt data).

My test OS: Ubuntu 12.04, latest patches.

Regards
Kurt

answered 22 Jul '12, 03:38

Kurt%20Knochner's gravatar image

Kurt Knochner ♦
24.8k1039237
accept rate: 15%

edited 22 Jul '12, 08:28

Thanks very much for your tips, when I saved as Wireshark - pcapng file, it works well, thanks again!

(22 Jul '12, 19:18) liunx

So what format had you saved it in before? libpcap only handles pcap and pcap-ng format; it doesn't, for example, handle Network Monitor format, at least not currently.

(22 Jul '12, 23:31) Guy Harris ♦♦

you are welcome. good luck with your further scripting efforts...

(23 Jul '12, 00:50) Kurt Knochner ♦

2

If your system has libpcap 1.1.0 or later, code using libpcap will be able to read pcap-ng files (as long as all network interfaces have the same link-layer header type; the current libpcap API doesn't support multiple link-layer header types in one file). If your Perl program was failing in

my $pcap = pcap_open_offline($pcap_file, \$err)
    or die "Can't read $pcap_file : $err\n";

when you handed it a pcap-ng file, then that's probably the problem you had.

If the open succeeded, then either the file is a pcap file or you have libpcap 1.1.0 or later. If you're getting 0 for the Ethernet type, then either the file is not an Ethernet capture, in which case the 12th and 13th bytes of the packet are not an Ethernet type, or the packet is somehow corrupted.

A program that calls pcap_open_live(), pcap_open_offline(), or pcap_create() and pcap_activate(), and does not ever call pcap_datalink(), is almost certainly buggy; only if it does not look at all at the packet data or is a quick hack that opens a wired-in device name for capture is it not buggy.

You should, if pcap_open_offline() succeeds, call pcap_datalink($pcap) and check whether its return value is DLT_EN10MB (as defined by Net::Pcap; I don't know if it's just DLT_EN10MB or Net::Pcap::DLT_EN10MB or something such as that). If it is not DLT_EN10MB, your program should fail with a "this is not an Ethernet capture" error (unless you want to enhance it to handle other link-layer types).

answered 22 Jul '12, 14:04

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

edited 22 Jul '12, 14:05