Chinaunix首页 | 论坛 | 博客
  • 博客访问: 372048
  • 博文数量: 73
  • 博客积分: 3574
  • 博客等级: 中校
  • 技术积分: 1503
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-26 11:17
文章分类

全部博文(73)

文章存档

2012年(14)

2011年(15)

2010年(44)

分类: Python/Ruby

2012-06-17 15:28:59

  python中对2进制文件的解析提供了一个struct的模块,利用这个模块可以实现python对pcap文件的解析


  今天下午闲来无事,就顺手写了一下,写的很粗糙,很多细节没去考虑,找了最简单的icmp包试验了一下,暂时没发现问题。。。

 这个是主要的代码,代码主要打印了ip头部的信息,不过没有考虑到ip扩展头的情况

点击(此处)折叠或打开

  1. #!/usr/bin/env python
  2. # -*- coding = UTF-8 -*-

  3. import sys
  4. from struct import pack,unpack
  5. from ip import print16
  6. from ip import str_to_addr
  7. from ip import addr_to_strn
  8. from ip import addr_to_strh
  9. '''
  10. pcap file = pcap_file_header + pcap_header + skb +...
  11. pcap_file_header 24B, pcap_header 16B
  12. '''

  13. pcap_file_header = ['majic','version_major','version_minor','zone','max_len','time_stap','link_type']

  14. pcap_header = ['gmt_time','micro_time','pcap_len','len']

  15. ip_header = ['version,ihl','tos','tot_len','id','frag_off','ttl','protocol','check','saddr','daddr']

  16. def print_mac_head(skb):
  17.     pass

  18. def print_ip_head(skb):
  19.     head = unpack('!BBHHHBBHII',skb[0:20])
  20.     #print "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x" %(head)
  21.     skb_head = dict(zip(ip_header,head))
  22.     for key in skb_head.keys():
  23.         if(key == 'saddr' or key == 'daddr'):
  24.             print key,addr_to_strh(skb_head[key])
  25.         else:
  26.             print key,skb_head[key]

  27. def main():
  28.     if(len(sys.argv) != 2):
  29.         print 'Usage: ./pcap.py file.pcap'
  30.     else:
  31.         fp = open(sys.argv[1],'rb')
  32.         text = fp.read()
  33.         index = 0

  34.         #pcap file head
  35.         head1 = unpack('IHHIIII',text[index:24 + index])
  36.         index += 24
  37.         file_head = dict(zip(pcap_file_header,head1))
  38.         print file_head

  39.         while(index < len(text)):
  40.             head2 = unpack('IIII',text[index:16 + index])
  41.             index += 16
  42.             pcap_head1 = dict(zip(pcap_header,head2))
  43.             #print pcap_head1
  44.             pcap_len = pcap_head1['pcap_len']
  45.             #print pcap_len
  46.             skb = text[index : pcap_len + index]
  47.             print_mac_head(skb[:14])
  48.             print_ip_head(skb[14:])
  49.             index += pcap_len

  50. if __name__ == '__main__':
  51.     main()
 其中的ip模块是自己写的,主要为了实现C语言中的inet_addr及反向转换的过程,socket模块中应该有类似的实现,不过那个模块还没玩过,暂时将就下。。

点击(此处)折叠或打开

  1. #!/usr/src/env python
  2. # -*- coding = UTF-8 -*-

  3. import sys

  4. ip_mask=[0,8,16,24]
  5. ip_mask2 = [24,16,8,0]

  6. def print16(num):
  7.     print '0x%x'%(num)

  8. #转换成网络字节序    
  9. def str_to_addr(s):
  10.     ip = ( int(i) for i in s.split('.'))
  11.     return reduce(lambda x,y:x+y,map(lambda x:x[0] << x[1],zip(ip,ip_mask)))

  12. #网络字节序显示
  13. def addr_to_strn(s):
  14.     return '.'.join([str((s & (0xff << x)) >> x) for x in ip_mask])

  15. #主机字节序显示    
  16. def addr_to_strh(s):
  17.     return '.'.join([str((s & (0xff << x)) >> x) for x in ip_mask2])

  struct基本上能够完成对于二进制文件的格式解析,但是遇到的一个主要问题就是,它最低解析位是unsigned char类型,即一个字节,对于C语言中的位格式,比如ip头部中的 u8 ihl:4; u8 version:4 , 暂时没发现什么好的方法把它解析出来,这点是使用起来不太爽的地方。
  当然也可能是自己还没发现正确的使用方法。。。

阅读(11377) | 评论(1) | 转发(0) |
0

上一篇:(void) (&_x == &_y)

下一篇:对齐二三事

给主人留下些什么吧!~~

Bean_lee2012-06-24 17:17:08

这个 对我有用,正四处找pcap相关的资料呢。