我使用这段代码在 pcapy 容器中使用 python docker :

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

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



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

我试图从异常中获取任何消息,但消息似乎是空的。我还浏览了 pcapy source code :由于 PcapyError 对象中的异常为空,而 next 函数中的其他 PcapError 是显式字符串,这意味着我们陷入了 buf 为空的情况。似乎 pcap_geterr 返回一个空字符串,因为 pp->pcap 已关闭并且指向 pcap 异常的指针不再存在(查看 doc )。

当我使用 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

我真的不知道问题的根源或调试它的其他方法。

编辑

我使用 strace 找不到任何错误。这是 strace 输出中错误的 grep:
strace python test_pcap.py 2>&1 1>/dev/null | grep -i error



编辑2

我还通过自己调用 pcap.h 来测试 pcap_next:
 // 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.timeout 调用启用了超时,则不会引发 socket.settimeoutsocket.settimeout 用于将 socket 设置为阻塞、非阻塞或超时状态。

    pcapy 中, open_live 的超时参数至少在 Linux 中被传递给 poll 系统调用,应该因 poll 不可用的操作系统而异。

    如果没有数据包返回,Reader.next 调用会引发 PcapError,因为它还没有捕获任何数据包。这不是错误,只是 StopIteration 之类的指示。它可以被忽略,并且必须再次调用 Reader.next
    Reader.loop 不会返回,直到它至少有一个数据包要返回或发生错误。

    以下代码捕获 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
    

    关于python - 无法在 python pcapy 包装器中跟踪错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29613102/

    10-10 14:34