使用 Python 处理 pcap 文件

2014-09-14 21:46:10 +08:00
 wwttc
我从CAIDA下载了一个.pcap文件。想读取其中的内容。

1.使用scapy
>>> from scapy.all import *
>>> pkts = rdpcap("equinix-chicago.dirA.20140320-125911.UTC.anon.pcap")
然后就不断跳出以下的错误
WARNING: bad ihl (0). Assuming ihl=5
WARNING: bad ihl (0). Assuming ihl=5
。。。


2.使用dpkt读取
>>> f = file("equinix-chicago.dirA.20140320-125911.UTC.anon.pcap")
>>> pcap = dpkt.pcap.Reader(f)
>>> for ts, buf in pcap:
>>> eth = dpkt.ethernet.Ethernet(buf)
>>> print eth
输出的结果都是乱码的:
E(uy@94?Q"]X??P?6d??q?4Pl??
E?G?7?2??:JV>[L{a?_?
E<ʪ@:Q??ac??$??PGT?#????
/9?
EGb?@|'^-?&C?LG^CY???K?~D?ub?????D??;?h?
D?J???U?

请问应该怎样才能正确读取pcap文件呢?
20170 次点击
所在节点    问与答
13 条回复
izoabr
2014-09-14 21:53:40 +08:00
type(eth)

dir(eth)
pimin
2014-09-14 22:03:02 +08:00
抓包内容又不都是字符串,你这样打印肯定是乱码啊
%x打印hex
em70
2014-09-14 22:50:44 +08:00
要先去查这种格式的协议是怎样的,读二进制来分析,python这方便比较弱,这时候C的优势就出来了
wwttc
2014-09-14 23:02:40 +08:00
@izoabr
<class 'dpkt.ethernet.Ethernet'>

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__hdr__', '__hdr_defaults__', '__hdr_fields__', '__hdr_fmt__', '__hdr_len__', '__init__', '__len__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_typesw', '_unpack_data', 'data', 'dst', 'get_type', 'pack', 'pack_hdr', 'set_type', 'src', 'type', 'unpack']
izoabr
2014-09-14 23:02:51 +08:00
我倒觉得这个时候python的包很管用,dpkt直接就解析了,eth.data就出来了就
wwttc
2014-09-14 23:03:41 +08:00
@pimin
>>> for ts, buf in pcap:
... eth = dpkt.ethernet.Ethernet(buf)
... print '%x' % eth
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
TypeError: %x format: a number is required, not Ethernet
wwttc
2014-09-14 23:04:59 +08:00
@izoabr
print eth.data 结果都是乱码的
allenforrest
2014-09-15 10:52:36 +08:00
@wwttc eth.data 里面都是二进制数据,直接 print 是没有意义的,建议用 binascii.b2a_hex 转换一下,再 print
s51431980
2014-09-15 12:33:53 +08:00
pcap是有固定格式的二进制文件,前24byte是文件头,之后是一个接一个package,每个package前16字节是package header,之后是package数据,从ip头、tcp头直到应用层数据。搜索pcap文件格式,可以找到相关文章。

我用ruby写过计算没时间间隔数据浏览统计的脚本,仅供参考 https://gist.github.com/t09def/ee79369fe4593d7491ac
wwttc
2014-09-15 15:18:13 +08:00
@allenforrest 转换了那就打印出了一堆十六进制数,还是不能够读取
kapoyegou
2015-09-08 09:15:10 +08:00
虽然已经是一年多以前的文章了,但为给后来人留个参考。我是刚刚也碰到了这种情况,似乎只是单纯的是包的问题,能转成字符串的它就会转,转不了的又不以十六进制数打印,就会出乱码
deepurple
2015-12-26 23:17:00 +08:00
def mac_addr(mac_string):
"""Print out MAC address given a string

Args:
mac_string: the string representation of a MAC address
Returns:
printable MAC address
"""
return ':'.join('%02x' % ord(b) for b in mac_string)


dpkt.ethernet.Ethernet(f) 生成的是 Ethernet 对象,不能直接 print ,需要分别取出对应字段,对于 MAC 地址和 IP 地址这些,还需要转换一下打印格式

具体参考:
https://dpkt.readthedocs.org/en/latest/_modules/examples/print_packets.html#print_packets
http://stackoverflow.com/questions/21015447/how-to-parse-the-header-files-of-the-pcap-file
codeyou
2018-03-05 22:11:42 +08:00
我直接用 scapy 的 sniff 嗅探数据包,将返回的数据包用 str 方法转换成字符串,结果打印是乱码?有人知道怎么解决吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/133419

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX