无法使用libpcap

时间:2019-05-03 07:09:05

标签: c system-calls ethernet libpcap raw-sockets

我是新来使用libpcap的人。

我正在使用此库来捕获数据包,而我写给捕获数据包的代码如下。

我正在窃听的接口总是被arp数据包淹没,因此总是有数据包进入接口,但是我无法窃听这些数据包。接口已启动并正在运行。 pcap_open_live函数没有错误。

代码在C中。我正在32位FreeBSD10机器上运行此代码。

void captutre_packet(char* ifname , int snaplen) {

    char ebuf[PCAP_ERRBUF_SIZE];
    int pflag = 0;/*promiscuous mode*/
    snaplen  = 100;
    pcap_t* pcap =  pcap_open_live(ifname, snaplen, !pflag , 0, ebuf);
    if(pcap!=NULL) {
            printf("pcap_open_live for %s  \n" ,ifname );   
    }

    int fd = pcap_get_selectable_fd(pcap);
    pcap_setnonblock(pcap, 1, ebuf);

    fd_set fds;
    struct timeval tv;

    FD_ZERO(&fds);
    FD_SET(fd, &fds);

    tv.tv_sec = 3;
    tv.tv_usec = 0;
    int retval = select(fd + 1, &fds, NULL, NULL, &tv);

    if (retval == -1)
            perror("select()");
        else if (retval) {
            printf("Data is available now.\n");
            printf("calling pcap_dispatch \n");
            pcap_dispatch(pcap , -1 , (pcap_handler) callback , NULL);
        }
        else
            printf("No data within 3 seconds.\n");
 }  
    void
    callback(const char *unused, struct pcap_pkthdr *h, uint8_t *packet)
    {
            printf("got some packet \n");
    }

我总是将retval设为0,这是超时。 我不知道我在遵循本教程的内容是怎么回事,他们所做的事情也完全一样,我不知道我在想什么。

我还想了解一旦收到以太网层的数据包,如何将其复制到此打开的bpf套接字/设备中(使用pcap_open_live),以及如何将缓冲区从内核空间复制到用户空间?

在内核消耗或拒绝数据包之前,我们可以窃听数据包多长时间?

1 个答案:

答案 0 :(得分:0)

pcap_open_live()调用提供了0作为包缓冲区超时值(第四个参数)。 libpcap没有指定值0的含义,因为在不同的操作系统上,不同的数据包捕获机制会对该值进行不同的处理。

在使用BPF的系统(例如BSD和macOS)上,它的意思是“等到数据包缓冲区完全填满后再提供数据包。如果数据包缓冲区很大(在FreeBSD上默认为256K),并且数据包很小(ARP数据包为60字节),缓冲区可能需要花费大量时间来填充-比您要交给select()的超时时间还要长。

最好将超时值设置在100毫秒至1秒之间,因此传递一个介于100到1000之间的参数,而不是0。