不能跟踪python pcapy包装中的错误
我在pcapy
容器中使用python pcapy
使用这段代码:
from pcapy import open_live, findalldevs import sys import traceback p = open_live("eth0", 1024, False, 100) dumper = p.dump_open("test.pcap") devices = findalldevs() print dumper, devices while True: try: print p.next() except Exception as e: print dir(e), e.message, e.args[0] traceback.print_exc(file=sys.stdout) break
当我运行它时,我得到以下exception:
回溯(最近一次通话最后):
文件“test_pcap.py”,第12行,
print p.next()
PcapError
我试图通过改变不同的最大数据包大小和设置混杂到True
的参数玩。
我试图从exception中得到任何消息,但似乎这个消息是空的。 我也通过pcapy 源代码浏览 :由于PcapyError对象中的exception是空的, next
函数中的其他PcapErrors是显式string,这意味着我们陷入了buf
为空的情况。 看来pcap_geterr
返回一个空string,因为pp->pcap
已经closures,并且指向pcapexception的指针不再存在(看看文档 )。
当我运行使用loop()
方法,一切工作正常:
# Modified from: http://snipplr.com/view/3579/ import pcapy from impacket.ImpactDecoder import * # list all the network devices pcapy.findalldevs() max_bytes = 1024 promiscuous = False read_timeout = 100 # in milliseconds pc = pcapy.open_live("eth0", max_bytes, promiscuous, read_timeout) # callback for received packets def recv_pkts(hdr, data): packet = EthDecoder().decode(data) print packet packet_limit = -1 # infinite pc.loop(packet_limit, recv_pkts) # capture packets
我真的不知道问题的根源,还有什么可以做的debugging。
编辑
我找不到使用strace
任何错误。 这是strace
输出错误的grep:
strace python test_pcap.py 2>&1 1>/dev/null | grep -i error
(6,“\ 0 \ 0 \ 0t \ 3 \ 0 \ 0 \ 0intt \ n \ 0 \ 0 \ 0ValueErrort \ 23 \ 0 \ 0 \ 0 _”…,4096)= 995
getsockopt(3,SOL_SOCKET,SO_ERROR,[0],[4])= 0
getsockopt(5,SOL_SOCKET,SO_ERROR,[0],[4])= 0
getsockopt(5,SOL_SOCKET,SO_ERROR,[0],[4])= 0
EDIT2
我也通过调用pcap_next
来testingpcap.h
:
// Modified from: http://www.tcpdump.org/pcap.html #include <pcap.h> #include <stdio.h> int main(int argc, char *argv[]) { pcap_t *handle; /* Session handle */ char *dev; /* The device to sniff on */ char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */ bpf_u_int32 mask; /* Our netmask */ bpf_u_int32 net; /* Our IP */ struct pcap_pkthdr header; /* The header that pcap gives us */ const u_char *packet; /* The actual packet */ /* Define the device */ dev = pcap_lookupdev(errbuf); if (dev == NULL) { fprintf(stderr, "Couldn't find default device: %s\n", errbuf); return(2); } /* Find the properties for the device */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); net = 0; mask = 0; } /* Open the session in promiscuous mode */ handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", "eth0", errbuf); return(2); } while (1) { /* Grab a packet */ packet = pcap_next(handle, &header); /* Print its length */ printf("Jacked a packet with length of [%d]\n", header.len); /* Print contents */ printf("\tPacket: %s\n", packet); /* And close the session */ } pcap_close(handle); return(0); }
要编译,将其写入test_sniff.c
并运行:
gcc test_sniff.c -o test_sniff -lpcap
我能够成功捕获数据包。 所以我不知道问题在哪里
其他信息重现行为
- Docker版本:
Docker version 1.5.0, build a8a31ef
- Docker镜像是Docker默认的
Ubuntu
- Python2.7
pcapy
不使用Python socket
模块。 如果以前的socket.settimeout
调用已经启用超时,它将不会引发socket.settimeout
。 socket.settimeout
用于将socket
设置为阻塞,非阻塞或超时状态。
在pcapy
, pcapy
的超时参数至less在Linux中传递到poll
系统调用,应该根据poll
不可用的操作系统而有所不同。
如果没有数据包返回, Reader.next
调用会引发PcapError
,因为它还没有捕获任何数据包。 这不是一个错误,只是像StopIteration
这样的指示。 它可以被忽略, Reader.next
必须再次被调用。
Reader.loop
将不会返回,直到它至less有一个数据包返回或发生错误。
以下代码捕获10个数据包并退出。
from pcapy import open_live, findalldevs, PcapError p = open_live("eth0", 1024, False, 100) dumper = p.dump_open("test.pcap") devices = findalldevs() print dumper, devices count=0 while True: try: packet = p.next() except PcapError: continue else: print packet count += 1 if count == 10: break
答案很简单:
p.next()
会throw
timeout
你的超时时间是100ms
( open_live
最后一个参数)
所以你的except
应该处理超时情况,你可能想要增加timeout
时间或设置为0
为infinite
编辑:
你只是期望PcapError
socket.timeout
但是却抛出了PcapError
。 socket.timeout
是python库中套接字代码抛出的exception,所以它是python特定的。 它正在被封装(也许只是新版本的pcapy),或者它代表了一种不同types的超时(TCP套接字相关)
请参阅示例pcapy代码: 示例