无法使用dpkt和Python解析数据包捕获

时间:2013-12-25 23:44:58

标签: python parsing pcap

我已经配置了一个Cisco路由器来转储pcap文件以获取我尝试使用dpkt和Python(2.7)解析的特定接口上的流量。基本代码是:

f = open('pktrace1.pcap','rb')
pcap = dpkt.pcap.Reader(f)

for ts,buf in pcap:
    eth = dpkt.ethernet.Ethernet(buf)
    ip = eth.data
    tcp = ip.data

f.close()

现在不幸的是,无论出于何种原因,路由器的pcap转储都将第2层信息留空,并且帧以原始IP格式封装。上面的代码在第7行失败,出现以下AttributeError: 'str'对象没有属性'data'

我想这是有道理的,因为它希望解析不存在的第2层以太网信息。

我对Python比较陌生,dpkt文档对我没什么帮助。有谁知道我怎么能让dpkt处理这些缺少以太网信息的数据包?或者也许如何让路由器(Cisco 2911,IOS 15.0)用以太网信息导出它们?

我觉得必须有一个简单的方法让dpkt处理这些转储,因为Wireshark可以完美地读取它们。任何帮助深表感谢! :)

2 个答案:

答案 0 :(得分:3)

为解析原始IP pcap,我发现(非常逻辑地)必须跳过dpkt以太网解码并直接跳转到IP解码,如下所示:

f = open('tun0.pcap')
pcap = dpkt.pcap.Reader(f)

for ts,buf in pcap:
    ip = dpkt.ip.IP(buf)
    tcp = ip.data

f.close()

当我遇到同样的问题时,我遇到了问题,这是因为在tun0虚拟隧道接口上运行tcpdump造成的

unix'文件'命令将捕获文件类型显示为:

tun0.pcap: tcpdump capture file (little-endian) - version 2.4 (raw IP, capture length 8192)

来自真实界面的转储给出了:

eth0.pcap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)

我相信你现在已经找到了答案,但是如果其他人有同样的问题,我会发布这个问题。这是我的第一次"给予回馈"所以我希望它真的有用!

答案 1 :(得分:2)

我的声誉太低,无法发表评论,但我想我可能会分享一些相关数据,所以请在答案框中

顺便说一下,您能否提供一些有关用于生成pcap文件的工具以及示例“pktrace1.pcap”数据的详细信息?而且:如果您使用AirPCAP适配器捕获,您可以配置它如何通过自己的设置捕获数据。如果您需要访问数据,则需要确保为AirPCAP加密狗正确启用了网络密钥(或者您的Cisco路由器必须禁用网络安全性),否则也无法访问数据。

然后这篇文章的主要原因是:我以前曾使用过impacket lib,并认为这对你也有帮助。以下是一个例子:

'''
Packet sniffer in python using the pcapy python library
python filter compile from http://carnivore.it/2010/06/12/python3_-_ctypes
pcapy compile from http://www.salstar.sk/pub/salpack/usr/sbin/httop.py and http://bytes.com/topic/python/answers/681254-python-packet-filter-pcapy
actual filtering answer on https://github.com/LeonB/dabbler/blob/master/pcapy-test.py ??
'''

import socket
from struct import *
import datetime
import sys
import radiotap
import pcapy
from impacket import ImpactDecoder, ImpactPacket

AIRPCAP_ADAPTER = '\\\\.\\airpcap00'
filter_string = '' # do not use with airpcap00 as this requires adapter to be on network so it seems (decryption key etc)

def main(argv):
    cap = pcapy.open_live(AIRPCAP_ADAPTER, 65536, 1, 0)
    #bpf = pcapy.compile (cap, 1500, filter_string, 0, 1)
    cap.setfilter(filter_string)
    print "Listening on %s: net=%s, mask=%s, linktype=%d" % (AIRPCAP_ADAPTER, cap.getnet(), cap.getmask(), cap.datalink())

    # Read packets -- header contains information about the data from pcap,
    # payload is the actual packet as a string
    # callback for received packets
    def recv_pkts(hdr, data):
        decoder = ImpactDecoder.EthDecoder()
        ether = decoder.decode(data)
        print ether
        # Parse the IP packet inside the Ethernet packet

    packet_limit = -1 # infinite
    cap.loop(packet_limit, recv_pkts) # capture packets


if __name__ == "__main__":
    main(sys.argv)