内容简介:关于
关于 Pcap
文件解析的方法网上有很多相关文章, Pcap
文件的格式以及使用 Wireshark
查看Pcap文件的方法也都有详细教程。然而利用 Perl
脚本语言对 Pcap
文件进行解析的相关代码和文章并没有。本文介绍了如何使用 Perl
脚本语言对 Pcap
文件进行解析。
模块安装
Net::Pcap
模块封装了用于解析Pcap文件的一些方法,首先介绍如何使用CPAN安装 Net::Pcap
模块。
//CPAN相关命令 //获得帮助 cpan>h //列出CPAN上所有模块的列表 cpan>m //安装模块 cpan>install Net::Pcap //退出 cpan>q
读取Pcap文件
pcap_loop($pcap, $count, \&callback, $user_data)
从pcap读取count个包,并且调用使用参数user_data调取callback函数。如果count为负,则循环读取直到错误发生。
my $pcap = pcap_open_offline($fileDir, \$err) || die "failed to open pcap file $pcap!"; while(1) { $ret = pcap_loop($pcap, -1, \&load_pcap, $this); if($ret == -1) { print "error on processing packets in pcap file: $@!\n"; die "error on processing packets in pcap file: $@!\n"; last; } elsif($ret == 0 || $ret == -2) { print "end of pcap processing: $@!\n"; last; } }
解析数据包
网络数据包格式如下图所示:
unpack (packformat, formatstr)
函数将以机器格式存贮的值转化成 Perl 中值。packformat代表解析格式,formatstr为要解析的对象。
通过判断各个位置上的值从而确定包的类型。通过记录连接的状态,确定TCP三次握手的建立与解除。具体代码如下:
foreach my $event (sort(keys(%{$packets}))) { print "testlog: a new packet begin----------------------- \n"; my $packet = $packets->{$event}->{pkt}; my $proto = unpack("H*", substr($packet, 12, 2)); if($proto eq "0800") #ipv4 { $count ++; my $off = 14; my $iphl = (unpack("C", substr($packet, $off, 1)) & 0x0f); # header length , <<2 is the actual length my $ip_payload_len = unpack("n", substr($packet, $off + 2, 2)); #total length #print "testlog: packet total length: ". $ip_payload_len ."\n"; $proto = unpack("C", substr($packet, $off + 9, 1)); #net proto my $sip = inet_ntoa(substr($packet, $off + 12, 4)); #source ip addr my $dip = inet_ntoa(substr($packet, $off + 16, 4)); #dest ip addr # chop the padding bytes off $packet = substr($packet, 0, $off + $ip_payload_len); #a full packet if($iphl > 5) {print "Warning: ip packet with ip option\n";} my $ipPayloadLen = unpack("n", substr($packet, $off + 2, 2)) - ($iphl << 2); #total length - header length # skip ipv4 header $off += ($iphl << 2); if($proto == 6) # tcp session { my $tcp_hdrl = unpack("C", substr($packet, $off + 12, 1)) >> 2; # tcp header length , <<2 is the actual length my $tcp_flag = unpack("C", substr($packet, $off + 13, 1)); #tcp flag #print $tcp_flag . "\n"; my $sport = unpack("n", substr($packet, $off, 2)); #source port my $dport = unpack("n", substr($packet, $off + 2, 2)); #dest port if($ipPayloadLen - $tcp_hdrl < 0) # eq 0 { print "invalid tcp packet: $proto packet not supported!\n"; last; } my $c = "$sip:$sport<->$dip:$dport"; my $s = "$dip:$dport<->$sip:$sport"; # recode session state if(!defined($session)) { print "testlog: session will be defined! \n"; $session = { id => $c, cstate => "closed", sip => $sip, dip => $dip, sport => $sport, dport => $dport }; } if($tcp_flag & 0x04) { print "Warning: tcp session with RST, need mannual checking!Stop session analyzing: $frameID!\n"; $session->{cstate} = "closed"; } print "testlog: session state: ". $session->{cstate} ."\n"; if($session->{cstate} eq "closed") # open session { if(($tcp_flag & 0x02)) # syn open sesstion { $session->{cstate} = "syn_sent"; } else { if(length(substr($packet, $off + $tcp_hdrl)) > 0) {print "Warning: tcp session disordered on closed, need mannual checking!Stop session analyzing: $sip : $sport <-> $dip : $dport \n";} } } elsif($session->{cstate} eq "syn_sent") { #print ($tcp_flag); #print "\n"; if(($tcp_flag & 0x12)==0x12){ print "ok"; }; print "\n"; if(($tcp_flag & 0x02) && ($sip eq $session->{sip}) && ($sport eq $session->{sport})) # syn from client retransmission {print "tcp retransmission detected!\n";} elsif(($tcp_flag & 0x12) && ($sip eq $session->{dip}) && ($sport eq $session->{dport})) # syn_ack from server {$session->{cstate} = "syn_rcvd";} else { print "Warning: tcp session disordered on syn_sent, need mannual checking!Stop session analyzing!\n"; } } elsif($session->{cstate} eq "syn_rcvd") { if(($tcp_flag & 0x10) && ($sip eq $session->{sip}) && ($sport eq $session->{sport})) # ack from client { $session->{cstate} = "connected"; # won't check ack print(FD "CONNECT twoarm 1 0 tcp $dip $dport $sip $sport\n\n"); } else {print "Warning: none ack packet on syn_rcvd!\n";} } elsif($session->{cstate} eq "connected") { #print "testlog: $sip ---- $session->{sip} ----- $session->{dip}"; if($sip eq $session->{sip} && ($sport eq $session->{sport})) # from client { if($tcp_flag & 0x01) { $session->{FIN} += 1; $session->{FINFrom} = 1; # this is the second FIN, disconnect begin from server } else { if(length(substr($packet, $off + $tcp_hdrl)) > 0) #TCP payload is not empty { $str_temp = unpack('H*',substr($packet, $off + $tcp_hdrl)); my @str_temp2 = split(//, $str_temp); my $str_temp3; for($i=0; $i<@str_temp2; $i=$i+2){ $str_temp3 = $str_temp3 . "\\x" . $str_temp2[$i] . $str_temp2[$i+1]; } print "$str_temp3 \n"; print(FD "SEND 0 #\"$str_temp3\" NOW\n\n"); } } } elsif($sip eq $session->{dip} && ($sport eq $session->{dport})) { if($tcp_flag & 0x01) { $session->{FIN} += 1; $session->{FINFrom} = 0; # this is the second FIN, disconnect begin from client } else { if(length(substr($packet, $off + $tcp_hdrl)) > 0) { $str_temp = unpack('H*',substr($packet, $off + $tcp_hdrl)); my @str_temp2 = split(//, $str_temp); my $str_temp3; for($i=0; $i<@str_temp2; $i=$i+2){ $str_temp3 = $str_temp3 . "\\x" . $str_temp2[$i] . $str_temp2[$i+1]; } print "$str_temp3 \n"; print(FD "SEND 1 #\"$str_temp3\" NOW\n\n"); } } } else { print "invalid packet on connected tcp session\n"; } } if($session->{cstate} eq "connected" && $session->{FIN} == 2) { $FINFrom = $session->{FINFrom}; print(FD "DISCONNECT $FINFrom\n"); $session->{cstate} = "closed"; delete($session->{FIN}); } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- mybatis源码配置文件解析之三:解析typeAliases标签
- 安卓 so 文件解析详解
- Nginx 源码:配置文件解析
- 要解析一个配置文件,当打开文件的时候我崩溃了
- 使用pdfminer解析pdf文件
- Django源码解析|Migrations文件的生成
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Wireshark网络分析实战
[以色列 Yoram Orzach / 古宏霞、孙余强 / 人民邮电出版社 / 2015-1 / 79.00元
本书采用步骤式为读者讲解了一些使用Wireshark来解决网络实际问题的技巧。 本书共分为14章,其内容涵盖了Wireshark的基础知识,抓包过滤器的用法,显示过滤器的用法,基本/高级信息统计工具的用法,Expert Info工具的用法,Wiresahrk在Ethernet、LAN及无线LAN中的用法,ARP和IP故障分析,TCP/UDP故障分析,HTTP和DNS故障分析,企业网应用程序行......一起来看看 《Wireshark网络分析实战》 这本书的介绍吧!