不能跟踪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.settimeoutsocket.settimeout用于将socket设置为阻塞,非阻塞或超时状态。

pcapypcapy的超时参数至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
你的超时时间是100msopen_live最后一个参数)

所以你的except应该处理超时情况,你可能想要增加timeout时间或设置为0infinite

编辑:
你只是期望PcapError socket.timeout但是却抛出了PcapErrorsocket.timeout是python库中套接字代码抛出的exception,所以它是python特定的。 它正在被封装(也许只是新版本的pcapy),或者它代表了一种不同types的超时(TCP套接字相关)
请参阅示例pcapy代码: 示例

Interesting Posts