在1 Gig流量下使用Libpcap在C中丢弃数据包

问题描述

我正在使用libpcap库在C中编写数据包解析器。这是简单的代码


int main(int argc,char *argv[])
{
    pcap_t *pcap;
    const unsigned char *packet;
    char errbuf[PCAP_ERRBUF_SIZE];
    struct pcap_pkthdr header;
    clock_t begin = clock();

    // Type your interface name here 
    
    char *device = "ens33";
    char error_buffer[PCAP_ERRBUF_SIZE];

    pcap_t *handle;
    int timeout_limit = 10000; // milliseconds

    if (device == NULL)
    {
        printf("Error finding device: %s\n",error_buffer);
        return 1;
    }

    // For live packet capturing
    handle = pcap_open_live(
        device,BUFSIZ,timeout_limit,error_buffer);

    if (handle == NULL)
    {
        printf("Error getting handle%s\n",error_buffer);
        return 2;
    }

    pcap_loop(handle,dump_UDP_packet,NULL);

    clock_t end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;


    printf("Program completed: total packets processed: %d (non UDP/Radius packets: %d) in %f seconds\n",count,non_packets,time_spent);
    return 0;
}


我正在使用tcpreplay播放pcap文件中的实时流量。但是,我的程序只能从240,000个数据包的文件中处理/读取大约80,000个数据包。当我尝试从tcpdump读取相同的数据包时,没有任何数据包丢失。

这是由于缓冲区大小引起的吗?如何确保数据包不丢失?

tcpreplay高速(约500MB /秒)大约需要1.5到2秒

我正在Ubuntu 18.04(32 GB RAM,24核处理器)上运行它

解决方法

当我尝试从tcpdump读取相同的数据包时,没有任何数据包丢失。

这是因为缓冲区大小吗?

除非您使用-B命令行选项,否则tcpdump不会设置内核缓冲区大小(您也没有这样做,因为您正在使用pcap_open_live(),而后者没有一种设置方式;快照长度为不是缓冲区大小),因此它使用的是程序使用的默认缓冲区大小(2 MiB),因此它可能不是缓冲区大小。 / p>

如何确保数据包不丢失?

尝试使用tcpdump的1秒(1000毫秒)超时,而不是10秒(10000毫秒),这是您当前正在使用的时间。

此外,请确保dump_UDP_packet()的工作量不大(您没有提供源代码让我们知道它在做什么)。

我正在Ubuntu 18.04(32 GB RAM,24核处理器)上运行它

您的程序和tcpdump都使用一个内核。 (在上下文切换之后,它们可能在与上下文切换之前所运行的内核不同的内核上运行,但是一次仍是一个内核;除非它们中有一些线程,否则它们都不是多线程的。您未显示的应用程序中的内容。)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...