Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: TCP session recreation from pcap files

by Khen1950fx (Canon)
on Jul 12, 2009 at 06:19 UTC ( #779317=note: print w/ replies, xml ) Need Help??


in reply to TCP session recreation from pcap files

I've looked at the documentation for Net::Analysis. It's confusing and clearly obfuscated. I also tried the one-liners; however, none of them worked:-). Since you are new to Perl, I think that you should experiment with Net::Pcap for a while. It has some quirks, but I've managed to get it to work on occasion. You could start with pcapdump. It had some problems, but I fixed it and put it below for you.

Update: For a one-liner, try something like:

perl /path/to/pcapdump -c 1000 -i eth0 -s 512 -w /path/to/tcpdump

#!/usr/bin/perl use strict; use Data::Hexdumper; use File::Basename; use Getopt::Long qw(:config no_auto_abbrev); use Net::Pcap qw(:functions); use NetPacket::Ethernet qw(:types); use NetPacket::IP qw(:protos); use NetPacket::ICMP; use NetPacket::TCP; use NetPacket::UDP; use Pod::Usage; use Socket qw(inet_ntoa); $::PROGRAM = basename($0); $::VERSION = "0.01"; # globals my $dumper = undef; my %icmp = ( ICMP_ECHO => "echo", ICMP_ECHOREPLY => "echo-reply", ICMP_IREQ => "ireq", ICMP_IREQREPLY => "ireq-reply", ICMP_MASREQ => "mask", ICMP_MASKREPLY => "mask-reply", ICMP_PARAMPROB => "param-prob", ICMP_REDIRECT => "redirect", ICMP_ROUTERADVERT => "router-advert", ICMP_ROUTERSOLICIT => "router-solicit", ICMP_SOURCEQUENCH => "source-quench", ICMP_TIMXCEED => "time-exceeded", ICMP_TSTAMP => "timestamp", ICMP_TSTAMPREPLY => "timestamp-reply", ICMP_UNREACH => "unreachable", ); MAIN: { run(); } sub run { $|++; # get options my %options = ( count => 10, promisc => 0, snaplen => 256, timeout => 10, ); GetOptions(\%options, qw{ help|h! version|V! count|c=i interface|i=s promisc|p! snaplen|s=i writeto|w=s }) or pod2usage(); pod2usage({ -verbose => 2, -exitval => 0 }) if $options{help}; print "$::PROGRAM v$::VERSION\n" if $options{version}; my ($err, $net, $mask, $filter); my $dev = $options{interface} || lookupdev(\$err); my $filter_str = join " ", @ARGV; # open the interface my $pcap = open_live($dev, @options{qw(snaplen promisc timeout)}, +\$err) or die "fatal: can't open network device $dev: $err ", "(do you have the privileges?)\n"; if ($filter_str) { # compile the filter compile($pcap, \$filter, $filter_str, 1, 0) == 0 or die "fatal: filter error\n"; setfilter($pcap, $filter); } if ($options{writeto}) { $dumper = dump_open($pcap, $options{writeto}) or die "fatal: can't write to file '$options{writeto}': $! +\n"; } # print some information about the interface we're currently using lookupnet($dev, \$net, \$mask, \$err); print "listening on $dev (", dotquad($net), "/", dotquad($mask), " +)", ", capture size $options{snaplen} bytes"; print ", filtering on $filter_str" if $filter_str; print $/; # enter the main loop loop($pcap, $options{count}, \&process_packet, ''); pcap_close($pcap); } sub process_packet { my ($user_data, $header, $packet) = @_; my ($proto, $payload, $src_ip, $src_port, $dest_ip, $dest_port, $f +lags); printf "packet: len=%s, caplen=%s, tv_sec=%s, tv_usec=%s\n", map { $header->{$_} } qw(len caplen tv_sec tv_usec); # dump the packet if asked to do so pcap_dump($dumper, $header, $packet) if $dumper; # decode the Ethernet frame my $ethframe = NetPacket::Ethernet->decode($packet); if ($ethframe->{type} == ETH_TYPE_IP) { # decode the IP payload my $ipframe = NetPacket::IP->decode($ethframe->{data}); $src_ip = $ipframe->{src_ip}; $dest_ip = $ipframe->{dest_ip}; if ($ipframe->{proto} == IP_PROTO_ICMP) { my $icmpframe = NetPacket::ICMP->decode($ipframe->{data}); $proto = "ICMP"; $payload = $icmpframe->{data}; } elsif ($ipframe->{proto} == IP_PROTO_TCP) { my $tcpframe = NetPacket::TCP->decode($ipframe->{data}); $proto = "TCP"; $src_port = $tcpframe->{src_port}; $dest_port = $tcpframe->{dest_port}; $payload = $tcpframe->{data}; $flags = flags_of($tcpframe->{flags}); } elsif ($ipframe->{proto} == IP_PROTO_UDP) { my $udpframe = NetPacket::UDP->decode($ipframe->{data}); $proto = "TCP"; $src_port = $udpframe->{src_port}; $dest_port = $udpframe->{dest_port}; $payload = $udpframe->{data}; } printf "IP:%s %s:%d -> %s:%d (%s)\n", $proto, $src_ip, $src_port, $dest_ip, $dest_port, $flags; print hexdump(data => $payload, start_position => 0) if length + $payload; print $/; } } sub flags_of { my ($flags) = @_; my @strarr = (); push @strarr, "urg" if $flags & URG; push @strarr, "ack" if $flags & ACK; push @strarr, "psh" if $flags & PSH; push @strarr, "fin" if $flags & FIN; push @strarr, "syn" if $flags & SYN; push @strarr, "rst" if $flags & RST; push @strarr, "ece" if $flags & ECE; push @strarr, "cwr" if $flags & CWR; return join ",", @strarr } sub dotquad { return inet_ntoa( pack("I", $_[0]) ) } __END__ =head1 NAME pcapdump - Dump packets from the network =head1 SYNOPSIS pcapdump [-c count] [-i interface] [-s snaplen] [-w file] [express +ion] pcapdump --help pcapdump --version =head1 OPTIONS =over =item B<-c>, B<--count> I<N> Exit after receiving I<N> packets. =item B<-i>, B<--interface> I<device> Listen on the specified interface. If unspecified, the program will us +e the interface returned by C<pcap_lookupdev()>. =item B<-s>, B<--snaplen> I<L> Capture I<L> bytes of data for each packet. Defaults to 256. =item B<-w>, B<--writeto> I<file> =back =head1 DESCRIPTION B<pcapdump> mimics the very basic features of B<tcpdump(1)> and provid +es a good example of how to use C<Net::Pcap>. =head1 AUTHOR SE<eacute>bastien Aperghis-Tramoni, E<lt>sebastien@aperghis.netE<gt> =head1 COPYRIGHT Copyright (C) 2005, 2006, 2007, 2008 SE<eacute>bastien Aperghis-Tramon +i. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut


Comment on Re: TCP session recreation from pcap files
Select or Download Code
Replies are listed 'Best First'.
Re^2: TCP session recreation from pcap files
by narcos (Initiate) on Jul 14, 2009 at 11:13 UTC
    Ah thanks very much for the help Khen. I played a little with pcapdump. Seems similar to tcpdump and I'd been using that. So, the situation I'm in is that I already have a large number of dump files from a large network and I want to do some analysis on them (as opposed to capturing new data with something like pcapdump).

    Whilst I have managed to script some stuff to extract individual packet information (headers+payload) from pcap files:

    use strict; use Net::TcpDumpLog; use NetPacket::IP qw(:strip); use NetPacket::TCP qw(:strip); my $log = Net::TcpDumpLog->new(); $log->read($ARGV[0]); my @Indexes = $log->indexes; my $index; my ($length_orig,$length_incl,$drops,$secs,$msecs); my $data; print ("IP SRC,IP DST, IP LENGTH, IP TOS, IP TTL, IP Offset, TCP ACK, +TCP flags, TCP Winsize, TCP Chksum, TCP URG\n"); foreach $index (@Indexes) { ($length_orig,$length_incl,$drops,$secs,$msecs) = $log->header($in +dex); $data = $log->data($index); my ($ether_dest,$ether_src,$ether_type,$ether_data) = unpack('H12H +12H4a*',$data); my $ip_obj = NetPacket::IP->decode($ether_data); my $tcp_obj = NetPacket::TCP->decode( $ip_obj->{data}); print ("$i $ip_obj->{src_ip} ($tmpIPs),$ip_obj->{dest_ip} ($tmpIP +d),$ip_obj->{len},$ip_obj->{tos},$ip_obj->{ttl},$ip_obj->{foffset},$t +cp_obj->{acknum},$tcp_obj->{flags}, $tcp_obj->{winsize}, $tcp_obj->{c +ksum}, $tcp_obj->{urg}\n");
    ...I'm struggling a bit to recreate the sessions in a nice way. I figured out with that Net::Analysis tool that the following command:
    $perl -MNet::Analysis -e main TCP,v=7 google.dump
    gives the output:
    = ( 0 23:28:09.091264 163.1.236.180:47262-209.85.227.99:80) *AP + SEQ:4094724362 ACK:3316076611 1072b ====[23:28:09.091264] tcp session start [163.1.236.180:47262 -> 209. +85.227.99:80] ==[23:28:09.091264] [Mono from 163.1.236.180:47262] 0.000000s, + 1pkts, 1072b = ( 1 23:28:09.119041 209.85.227.99:80-163.1.236.180:47262) *A + SEQ:3316076611 ACK:4094725434 1368b = ( 2 23:28:09.119097 163.1.236.180:47262-209.85.227.99:80) _A [......] ====[--:--:--.------] tcp session end [163.1.236.180:47263-209.85.22 +7.99:80]
    i.e. it's reconstructing sessions as well as monologues within each session and listing each packet. Now what I really want to do is to figure out how to 'code' the above command such that I can tweak it. Instead of outputting each packet to the console, for example, I'd like to insert it into a database. Also I'd like additional header information.

    The kludge approach I'm about to take is to dump the whole output to a file and then parse it with another script, and then try and match each packet in the Net::Analysis output to each packet in my above scripts output. Not so ideal...

    Thanks and sorry for rambling!
    -N

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://779317]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2015-07-28 03:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (251 votes), past polls