wincap函数用法简述
函數說明:
Net::Pcap的功能由winpcap提供.
?
Net::Pcap::findalldevs(\$err [,\%description])
返回一個能被函數Net::Pcap::open_live()利用的所有網絡設備的名字的列表,這些名字分別是%description中的鍵,如果提供了可選參數-散列%description,則它存放所有對應與前面的網絡設備的描述信息;如果發生錯誤,則$err中會存放相應的錯誤消息。
?
Net::Pcap::open_live($dev, $snaplen, $promisc, $to_ms, \$err)
該函數返回一個用來在網絡上捕獲包的描述符,$dev指定從哪個網絡接口上捕獲包,$snaplen設定捕獲包的最大字節數,$promisc指定是否將該網絡接口設置為混合模式,$to_ms設定以毫秒度量的讀超時時間,這是每次讀取的時間閥值,如果有錯誤發生,則不會定義這個描述符,同時將這個錯誤信息寫入參數$err中。
?
Net::Pcap::sendpacket($pcap_t, $packet)
該函數用來發送數據包,$pcap_t是指定通過哪個網絡接口來發送數據包的設備描述符,$packet是要發送的數據,這個數據中不需要包含MAC CRC ,因為網絡接口的驅動會自動完成計算并添加。
?
Net::Pcap::close($pcap_t)
關閉描述符$pcap_t所對應的的網絡接口。
?
Net::Pcap::next($pcap_t, \%hdr)
從描述符$pcap_t關聯的的接口上抓取包,這些包的一些信息被放到hash表%hdr中。如果沒有獲取包,則返回值和頭部都會被設成無定義。
%hdr內容:
len--
報文的總長度
caplen--
包數據的實際長度
tv_sec
秒級別的時間戳值
tv_usec
毫秒級別的時間戳值
?
Net::Pcap::compile($pcap_t, \$filter_t, $filter_str, $optimize, $netmask) $pcap_t 關聯一個網絡接口,$filter_str存放過濾字段描述,函數執行后把編譯的結果放到\$filter_t中,如果$optimize為真,則對$filter_str進行優化處理。
?
Net::Pcap::setfilter($pcap_t, $filter_t);
將過濾規則$filter_t應用到$pcap_t上去。
?
Net::Pcap::stats($pcap, \%stats)
該函數返回指定接口上的報文捕獲的信息,$pcap關聯設備,%stats為一散列,存放報文捕獲信息,它的結構如下:
ps_recv
由抓包軟件捕獲的報文數量,但是報文較多是會不準
ps_drop
由抓包軟件丟棄的報文的數量
ps_ifdrop
由網絡接口丟棄的報文的數量
?
?
常用過濾器寫法:
ether proto \ip(由于ip是關鍵字,前面要加”\”,“\ip”也可以用相應的協議對應的數值來代替)
?
\ip src? a.b.c.d
\ip dst? a.b.c.d
3.過濾封裝在ip包內的特定報文,如icmp,igmp等
?\ip proto 1 (過濾icmp,也可直接用關鍵字 \icmp)?
4.過濾特定的端口號,如
Port? port_num?? 雙向過濾
Src? port? port_num 只過濾源端口號匹配的報文
dst? port? port_num 只過濾目的端口號匹配的報文
混合使用:
可以通過and ,or,not來合理組合過濾字段,如過濾源ip為a.b.c.d,目的ip為e.f.g.h的報文
\ip src a.b.c.d and dst e.f.g.h
?
?
?
Packet Decoders
?
這是介紹幾個簡單的協議解碼函數,是參考NetPacket模塊中的相關函數修改的。如Windows下通常使用winpcap庫抓包,使用模塊是????????
Net::Pcap和Net::PcapUtils,其中Net::Pcap是Perl的winpcap庫接口,Net::PcapUtils里映射了一些Net::Pcap中常用的函數,
提供了更方便些的接口。寫協議分析程序一般步驟是:
?
1、打開設備;
2、循環抓包,對每個包進行逐層解碼,在每層解碼后進行相關字段的過濾;
3、最后將滿足過濾條件的包輸出;
4、加上對中斷信號的處理,各種統計Counter等其他特性;
?
舉例來說,打開Eth0設備,循環抓包,最初獲得eth frame,用eth_decode函數處理,獲得幀的src_mac、dest_mac、type和data字段,
其中data字段里是上層協議數據。然后根據type字段指示的上層協議類型,對data字段的值應用相應的解碼函數,如type是“0x0800”,
則表明這個以太幀里面是IP包-對應就是以太幀的data字段,用ip_decode函數處理這個字段,繼而獲得這個IP包中的各個字段,
同理它的data字段就是IP層的上層協議包的內容,又IP包中的proto字段指示四層協議的類型,如IP的proto字段是6,
則表明四層是TCP協議,那么就對IP包data字段應用tcp_decode函數進行解析,依此類推。
?
綜上,每層協議頭中必定定義了某個字段(如eth.type,ip.proto,ppp.code, etc.)指示如何解析該層攜帶的上層數據包(data)。
具體解碼做法就是參考協議的RFC文檔,使用unpack逐層解碼、計算生成每層相關字段。當編寫某個協議的解碼函數時,
可以參考下面幾個decode函數,其中關鍵是unpack的使用,因為是解析網絡中的數據包,當然使用網絡字節順序來unpack,
常用下面幾個字符:
?
N - 32bits 網絡字節順序
n - 16bits 網絡字節順序
C - 8bits 網絡字節順序
a - 任意二進制
?
對于非整字節的字段(如4bits和13bits等),按C或n取得整字節后移位獲得,如IP Header的結構是:
?
??? 0?????????????????? 1?????????????????? 2?????????????????? 3??
??? 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |Version|? IHL? |Type of Service|????????? Total Length???????? | <-CCn
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |???????? Identification??????? |Flags|????? Fragment Offset??? | <-nn
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |? Time to Live |??? Protocol?? |???????? Header Checksum?????? | <-CCn
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |?????????????????????? Source Address????????????????????????? | <-N
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |??????????????????? Destination Address??????????????????????? | <-N
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?? |??????????????????? Options??????????????????? |??? Padding??? | <-a*
?? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
?
??????????????????? Example Internet Datagram Header
?
參考rfc791.txt,對應的解碼函數可以寫成:
?
sub ip_decode {
??? my $packet = shift;
??? my $ippkt_ref = {};
??? my @fields = qw/tmp tos len id foffset ttl proto cksum src_ip dest_ip options/;
??? my @values = unpack("CCnnnCCnNNa*" , $packet);
?
??? map { $ippkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
?
??? #Extract bit fields
??? $ippkt_ref->{ver} = ($ippkt_ref->{tmp} & 0xf0) >> 4;
??? $ippkt_ref->{hlen} = $ippkt_ref->{tmp} & 0x0f;
??? $ippkt_ref->{flags} = $ippkt_ref->{foffset} >> 13;
??? $ippkt_ref->{foffset} = ($ippkt_ref->{foffset} & 0x1fff) << 3;
?
??? #Decode variable length header options and remaining data in field
??? #Option length is number of 32 bits words
??? my $olen = ($ippkt_ref->{hlen} - 5) ? ($ippkt_ref->{hlen} - 5) * 4 : 0;
?
??? ($ippkt_ref->{options}, $ippkt_ref->{data}) = unpack("a".$olen."a*", $ippkt_ref->{options});
?
??? #Convert 32 bit ip addresses to dotted quad notation
??? $ippkt_ref->{src_ip} = to_dotquad($ippkt_ref->{src_ip});
??? $ippkt_ref->{dest_ip} = to_dotquad($ippkt_ref->{dest_ip});
?
??? undef $ippkt_ref->{tmp};
??? return $ippkt_ref;
}
?
--Packet Decoders eXamples--
?
#Packets decoders
sub eth_decode {
??? my $packet = shift;
??? my $ethframe_ref = {};
??? my @fields = qw/sm_lo sm_hi dm_lo dm_hi type data/;
??? my @values = unpack("NnNnna*", $packet);
??? map { $ethframe_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
?
??? #Convert MAC addresses to hex string to avoid representation problems
??? $ethframe_ref->{src_mac} = sprintf("%08x%04x", $ethframe_ref->{sm_hi}, $ethframe_ref->{sm_lo});
??? $ethframe_ref->{dest_mac}= sprintf("%08x%04x", $ethframe_ref->{dm_hi}, $ethframe_ref->{dm_lo});
?
??? undef $ethframe_ref->{$_} foreach(qw/sm_lo sm_hi dm_lo dm_hi/);
??? return $ethframe_ref;
}
?
sub arp_decode {
??? my $packet = shift;
??? my $arppkt_ref = {};
??? my @fields = qw/htype proto hlen plen opcode sha spa tha tpa data/;
??? my @values = (unpack("nnCCnH12H8H12H8", $packet), undef);
?
??? map { $arppkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
?
??? return $arppkt_ref;
}
?
sub ppp_decode {
??? my $packet = shift;
??? my $ppppkt_ref = {};
??? my @fields = qw/code id length data/;
??? my @values = unpack("ccna*", $packet);
?
??? map { $ppppkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
?
??? if($ppppkt_ref->{code} =~ m/[1-4]/) {
??? ????$ppppkt_ref->{type} = unpack("c", $ppppkt_ref->{data});
?
??????? my @fields;
?
??????? @fields = qw/type length MRU data/ if($ppppkt_ref->{type} == PPP_TYPE_MRU);
??????? @fields = qw/type length auth data/ if($ppppkt_ref->{type} == PPP_TYPE_AUTHPROTO);
??????? @fields = qw/type length quality data/ if($ppppkt_ref->{type} == PPP_TYPE_QUALPROTO);
??????? @fields = qw/type length magic data/ if($ppppkt_ref->{type} == PPP_TYPE_MAGICNUM);
?
??????? my @values = unpack("ccna*", $ppppkt_ref->{data});
?
??????? map { $ppppkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
??? }
?
??? if($ppppkt_ref->{code} == PPP_CODE_ECHOREQ or $ppppkt_ref->{code} == PPP_CODE_ECHOREPLY) {
??????? my @fields = qw/magic data/;
??????? my @values = unpack("Na*", $ppppkt_ref->{data});
?
??????? map { $ppppkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
??? }
?
??? return $ppppkt_ref;
}
?
sub ip_decode {
??? my $packet = shift;
??? my $ippkt_ref = {};
??? my @fields = qw/tmp tos len id foffset ttl proto cksum src_ip dest_ip options/;
??? my @values = unpack("CCnnnCCnNNa*" , $packet);
?
??? map { $ippkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
?
??? #Extract bit fields
??? $ippkt_ref->{ver} = ($ippkt_ref->{tmp} & 0xf0) >> 4;
??? $ippkt_ref->{hlen} = $ippkt_ref->{tmp} & 0x0f;
??? $ippkt_ref->{flags} = $ippkt_ref->{foffset} >> 13;
??? $ippkt_ref->{foffset} = ($ippkt_ref->{foffset} & 0x1fff) << 3;
?
??? #Decode variable length header options and remaining data in field
??? #Option length is number of 32 bits words
??? my $olen = ($ippkt_ref->{hlen} - 5) ? ($ippkt_ref->{hlen} - 5) * 4 : 0;
?
??? ($ippkt_ref->{options}, $ippkt_ref->{data}) = unpack("a".$olen."a*", $ippkt_ref->{options});
?
??? #Convert 32 bit ip addresses to dotted quad notation
??? $ippkt_ref->{src_ip} = to_dotquad($ippkt_ref->{src_ip});
??? $ippkt_ref->{dest_ip} = to_dotquad($ippkt_ref->{dest_ip});
?
??? undef $ippkt_ref->{tmp};
??? return $ippkt_ref;
}
?
sub icmp_decode {
??? my $packet = shift;
??? my $icmppkt_ref = {};
??? my @fields = qw/type code cksum data/;
??? my @values = unpack("CCna*", $packet);
?
??? map { $icmppkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
?
??? return $icmppkt_ref;
}
?
sub tcp_decode {
??? my $packet = shift;
??? my $tcppkt_ref = {};
??? my @fields = qw/src_port dest_port seqnum acknum tmp winsize cksum urg options/;
??? my @values = unpack("nnNNnnnna*", $packet);
?
??? map { $tcppkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
?
??? #Extract flags
??? $tcppkt_ref->{hlen} = ($tcppkt_ref->{tmp} & 0xf000) >> 12;
??? $tcppkt_ref->{reserved} = ($tcppkt_ref->{tmp} & 0x0f00) >> 8;
??? $tcppkt_ref->{flags} = $tcppkt_ref->{tmp} & 0x00ff;
?
??? #Decode variable length header and remaining data
??? my $olen = ($tcppkt_ref->{hlen} - 5) ? ($tcppkt_ref->{hlen} - 5) * 4 : 0;
?
??? ($tcppkt_ref->{options}, $tcppkt_ref->{data}) = unpack("a".$olen."a*", $tcppkt_ref->{options});
?
??? undef $tcppkt_ref->{tmp};
??? return $tcppkt_ref;
}
?
sub udp_decode {
??? my $packet = shift;
??? my $udppkt_ref = {};
??? my @fields = qw/src_port dest_port len cksum data/;
??? my @values = unpack("nnnna*", $packet);
?
??? map { $udppkt_ref->{$fields[$_]} = $values[$_] } (0..$#fields);
?
??? return $udppkt_ref;
}
---
#who"s r00t?
my $r00t = "fat root";
總結
以上是生活随笔為你收集整理的wincap函数用法简述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: error C2504 base cla
- 下一篇: CKA认证考题+解析