anderam has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

I'm Perl newbie and I'm facing problem with $title. My script reads the pcap file using Net::Pcap and NetPacket. Script reads packet by packet, stripping them out of headers (Ethernet/IP/TCP) and takes only payload part. Then I don't know how to convert payload into readable text.

My code:

use Net::Pcap; use NetPacket::Ethernet; use NetPacket::IP; use NetPacket::TCP; use NetPacket::UDP; use NetPacket::ICMP; use strict; sub parsePayload { my($payload, $text) = @_; # now i don't know what to do my $data = pack("A",$payload); print "Data: $data\n"; } sub getPayload { my ($userdata, $header, $packet) = @_; my $ether_data = NetPacket::Ethernet::strip($packet); my $ip = NetPacket::IP->decode($ether_data); if ( $ip->{'proto'} == 6 ) { print "TCP\n"; my $l4 = NetPacket::IP::strip($ether_data); my $tcp = NetPacket::TCP->decode($l4); my $payload = $tcp->{'data'}; &parsePayload("$payload","$userdata"); } elsif ( $ip->{'proto'} == 17) { print "UDP\n"; my $l4 = NetPacket::IP::strip($ether_data); my $udp = NetPacket::UDP->decode($l4); my $payload = $udp->{'data'}; &parsePayload("$payload","$userdata"); } elsif ( $ip->{'proto'} == 1) { print "ICMP"; my $l4 = NetPacket::IP::strip($ether_data); my $icmp = NetPacket::ICMP->decode($l4); my $payload = $icmp->{'data'}; &parsePayload("$payload","$userdata"); } else { print "Unknown packet!\n"; } } my $err; my $pcap_t; $pcap_t = Net::Pcap::open_offline($ARGV[0],\$err); Net::Pcap::loop($pcap_t, 0, \&getPayload, 1); Net::Pcap::close($pcap_t); print "Done.\n";

Why do I want such a thing? I need to match regular expressions with payloads.

Replies are listed 'Best First'.
Re: Problems with converting raw data to text
by bv (Friar) on Dec 06, 2009 at 15:02 UTC

    Have you tried just using the data as-is? $payload looks to me to be a string already, even though it contains non-printable hex chars. It should still be able to match against regular expressions. To print the packet out, you could do something like this:

    $payload =~ s/[^[:print:]]/./g;

    As a side note, don't quote variables unnecessarily. There is very little difference between "$payload" and $payload, and it's not the difference a shell programmer would expect.


    @_=qw; Just another Perl hacker,; ;$_=q=print "@_"= and eval;

      Many thanks for your solution of my problem. It Works!

      But I don't understand the magic used in that line. Could you please explain that for me?

      $payload =~ s/[^[:print:]]/./g;

        The [:print:] is a character class matching printable characters. See Character Classes and other Special Escapes for more about character classes. So the statement replaces all non-printable characters with periods.


        @_=qw; Just another Perl hacker,; ;$_=q=print "@_"= and eval;
Re: Problems with converting raw data to text
by Anonymous Monk on Dec 06, 2009 at 13:12 UTC
    How does the raw data in the payload part format looks like, what is the output text format you expect???....

      And so this is the worst part of it. I've got some Perl Compatible Regular Expressions (PCREs) and i want to match them with payloads. Regular expression looks like this:

      /http\/(0\.9|1\.0|1\.1) [1-5][0-9][0-9] [\x09-\x0d -~]*(connection:|content-type:|content-length:|date:)|(get|post|head) [\x09-\x0d -~]* http\/[01]\.[019]/i

      Payload data, I don't know if this will help: in C language i'll certainly use unsigned char.

      What I expect is, the data must be in such a format which I can parse with PCREs.