首页 文章

如何从.pcap文件中获取流的数量,流量和每个流的数据包?

提问于
浏览
-1

我正在处理大的.pcap数据包网络捕获(每个文件大于5GB),我正在尝试对数据包进行流分组(例如,按IP源分组,IP目的地,源端口,目标端口和第4层协议) . 我使用一些软件工具如Scapy,CapLoader,tcpdump,tshark等,但我找不到我想要的解决方案 .

通过.pcap数据包文件我想知道流的数量,流量,然后找出哪些数据包属于每个流

知道最好的方法是什么?

如果解释不是很清楚,我很抱歉,我愿意提供任何进一步的解释或澄清 .

非常感谢 .

问候 .

1 回答

  • 0

    如果您愿意编写一些代码,Perl脚本可能会很有用 . 在Ask Wireshark,有人问了一个类似的问题,got a response建议使用 Net::Pcap 和少数 NetPacket::* 包自己处理文件 . 那个答案有一个针对那里特定问题的示例脚本,但要获取所需信息并不难 .

    编辑:我认为这很有趣所以我写了一个示例脚本 .

    pcapFlows.pl

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use Net::Pcap;
    use NetPacket::Ethernet qw(:types :strip);
    use NetPacket::IP qw(:protos :strip);
    use NetPacket::TCP;
    use NetPacket::UDP;
    
    my $pcap_file = $ARGV[0];
    
    if (not $pcap_file) { 
        die("ERROR: please give pcap file name on the cli\n")
    };
    
    my $err = undef;
    
    my %tracks;
    
    # read data from pcap file.
    my $pcap = pcap_open_offline($pcap_file, \$err) or die "Can't read $pcap_file : $err\n";
    pcap_loop($pcap, -1, \&process_packet, \%tracks);
    
    # close the device
    pcap_close($pcap);
    
    my $flowCount = 0;
    # process tracks here
    
    print "Flows\n";
    
    foreach my $src (keys %tracks) {
        foreach my $dst (keys %{$tracks{$src}}) {
            foreach my $prot (keys %{$tracks{$src}{$dst}}) {
                $flowCount++;
                my $filename = "${src}_to_${dst}_$prot.pcap";
                print "$filename\n";
    
                my ($source, $dest) = ($src, $dst);
    
                $source =~ s/-/:/;
                $dest =~ s/-/:/;
                my $pktCount = 0;
                my $pcap_dumper = pcap_dump_open($pcap, $filename);
                foreach my $packet (@{$tracks{$src}{$dst}{$prot}{'packets'}}) {
                    $pktCount++;
                    pcap_dump($pcap_dumper, $packet->{'hdr'}, $packet->{'pkt'});
                }
                pcap_dump_flush($pcap_dumper);
                pcap_dump_close($pcap_dumper);
    
                print "$source <-> $dest ($pktCount)\n";
            }
        }
    }
    
    print "$flowCount flows found.\n";
    
    sub process_packet {
        my ($user_data, $header, $packet) = @_;
    
        my $ip = NetPacket::IP->decode(eth_strip($packet));
    
        my $src_ip = $ip->{src_ip};
        my $dst_ip = $ip->{dest_ip};
    
        my ($prot, $payload);
    
        if ($ip->{proto} == IP_PROTO_TCP) {
            $prot = 'tcp';
            $payload = NetPacket::TCP->decode($ip->{data});
        } elsif ($ip->{proto} == IP_PROTO_UDP) {
            $prot = 'udp';
            $payload = NetPacket::UDP->decode($ip->{data});
        } else {
            return;
        }
    
        my $src_port = $payload->{src_port};
        my $dst_port = $payload->{dest_port};
    
    
        if (defined($user_data->{"$src_ip-$src_port"}) || !(defined($user_data->{"$src_ip-$src_port"}) || defined($user_data->{"$dst_ip-$dst_port"}))) {
            $user_data->{"$src_ip-$src_port"}{"$dst_ip-$dst_port"}{$prot}{'count'}++;
            push(@{$user_data->{"$src_ip-$src_port"}{"$dst_ip-$dst_port"}{$prot}{'packets'}}, {'hdr' => $header, 'pkt' => $packet});
        } elsif (defined($user_data->{"$dst_ip-$dst_port"})) {
            $user_data->{"$dst_ip-$dst_port"}{"$src_ip-$src_port"}{$prot}{'count'}++;
            push(@{$user_data->{"$dst_ip-$dst_port"}{"$src_ip-$src_port"}{$prot}{'packets'}}, {'hdr' => $header, 'pkt' => $packet});
        }
    }
    

相关问题