内容简介:关于
关于 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文件的生成
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
编译原理
Alfred V.Aho、Jeffrey D.Ullman、Ravi Sethi / 李建中 / 机械工业出版社 / 2003-8 / 55.00元
《编译原理》作者Alfred V.Aho、Ravi Sethi和Jeffrey D.Ullman是世界著名的计算机 科学家,他们在计算机科学理论、数据库等很多领域都做出了杰出贡献。《编译原理》 是编译领域无可替代的经典著作,被广大计算机专业人士誉为“龙书”。《编译原理》一 直被世界各地的著名高等院校和科研机构(如贝尔实验室、哥伦比亚大学、普 林斯顿大学和斯坦福大学等)广泛用作本科生和研究生编译原理......一起来看看 《编译原理》 这本书的介绍吧!