我已经配置了一个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可以完美地读取它们。任何帮助深表感谢! :)
答案 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)