内容简介:关于
关于 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文件的生成
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Perl语言入门
[美] Randal L.Schwartz、Tom Phoenix / 李晓峰 / 中国电力出版社 / 2002-8 / 48.00元
本书第一版于1993年问世,并从此成为畅销书。本书由Perl社区最著名、最活跃的两位成员写成,是Perl程序设计语言的精髓指南。 Perl最初只是Unix系统管理员的一个工具,在工作日里被用在无数的小任务中。从那以后,它逐步发展成为一种全功能的程序设计语言,特别是在各种计算平台上,它被用作Web编程、数据库处理、XML处理以及系统管理——它能够完成所有这些工作,同时仍然是处理小的日常工作的完......一起来看看 《Perl语言入门》 这本书的介绍吧!