首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法跟踪python pcapy包装器中的错误

无法跟踪python pcapy包装器中的错误
EN

Stack Overflow用户
提问于 2015-04-13 19:05:59
回答 2查看 1.4K关注 0票数 4

我使用以下代码在docker容器中使用python pcapy

代码语言:javascript
复制
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

当我运行它时,我会得到以下异常:

回溯(最近一次调用): 文件"test_pcap.py",第12行 打印p.next() PcapError

我试图通过更改不同的最大数据包大小并将杂乱设置为True来处理参数。

我试着从异常中得到任何消息,但是消息似乎是空的。我还浏览了pcapy 源代码:由于PcapyError对象中的异常是空的,而next函数中的其他PcapErrors是显式字符串,这意味着我们陷入了buf为空的状态。pcap_geterr似乎返回一个空字符串,因为pp->pcap已经关闭,指向pcap的指针不再存在(查看文档)。

当我使用loop()方法运行时,一切都很好:

代码语言:javascript
复制
# 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

我真的不知道问题的根源,也不知道要做什么来调试它。

编辑

我使用strace找不到任何错误。这是strace输出中错误的grep:

代码语言:javascript
复制
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,4) =0 getsockopt(5,SOL_SOCKET,SO_ERROR,4) =0 getsockopt(5,SOL_SOCKET,SO_ERROR,4) =0

EDIT2

我还通过亲自调用pcap.h来测试pcap_next

代码语言:javascript
复制
 // 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并运行:

代码语言:javascript
复制
gcc test_sniff.c -o test_sniff -lpcap

我成功地捕获了数据包。所以我不知道问题出在哪里..。

其他信息以复制行为

  • 码头版本:Docker version 1.5.0, build a8a31ef
  • 码头形象是码头默认Ubuntu
  • Python2.7
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-20 16:24:54

pcapy不使用Python socket模块。如果以前的socket.timeout调用已启用超时,则不会引发socket.settimeoutsocket.settimeout用于将socket设置为阻塞、非阻塞或超时状态.

pcapy中,open_live的超时参数至少在Linux中传递给poll syscall,在poll不可用的操作系统中应该有所不同。

如果没有要返回的数据包,Reader.next调用将引发PcapError,因为它尚未捕获任何数据包。这不是一个错误,只是一个像StopIteration这样的指示。可以忽略它,并且必须再次调用Reader.next

Reader.loop将不会返回,直到它有至少一个包要返回或发生错误。

下面的代码捕获10个数据包和出口。

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2015-04-17 17:27:25

答案很简单:

p.next() will throw on timeout

超时是100ms (open_live的最后一个参数)

因此,您的except应该处理超时情况,您可能希望增加timeout时间,或者将其设置为0 for infinite

编辑:

您只是期望使用socket.timeout,但是会抛出PcapErrorsocket.timeout是python中的套接字代码引发的异常,因此它是特定于python的。它正在被包装(可能只是使用新版本的pcapy),或者jsut代表了一种不同类型的超时(与TCP套接字相关)。

参见示例pcapy代码:示例

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29613102

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档