Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
libpcap:select始终返回fd计数_C_Linux_Select_Pcap_Libpcap - Fatal编程技术网

libpcap:select始终返回fd计数

libpcap:select始终返回fd计数,c,linux,select,pcap,libpcap,C,Linux,Select,Pcap,Libpcap,我正在使用select2函数监视pcap\u get\u selectable\u fd获取的文件描述符的更改。当select2在指定为超时的时间量之后返回时,将返回等于fdset中文件描述符数量的值。对pcap_next_ex的后续调用返回0,表示没有可用的数据包。我使用pcap_统计数据检查了一些数据包是否被丢弃,但“drop”和“ifdrop”计数器都是空的 我还在pcap资源句柄上应用了Berkeley数据包过滤器,根据pcap_get_Selective_fd的文档,这在BSD和Mac

我正在使用select2函数监视pcap\u get\u selectable\u fd获取的文件描述符的更改。当select2在指定为超时的时间量之后返回时,将返回等于fdset中文件描述符数量的值。对pcap_next_ex的后续调用返回0,表示没有可用的数据包。我使用pcap_统计数据检查了一些数据包是否被丢弃,但“drop”和“ifdrop”计数器都是空的

我还在pcap资源句柄上应用了Berkeley数据包过滤器,根据pcap_get_Selective_fd的文档,这在BSD和Mac OS X上引起了一些问题。即使我运行的是Linux,它是否也与此相关

我的测试机器运行Linux内核3.13.3-1-ARCH,并使用libpcap-1.6.2。在我的开发机器上,一切都按照我期望的内核3.17.7-200.fc20.x86_64、libpcap-1.5.3运行

数据包捕获初始化摘录 摘自主循环
如果rval=-1{如果errno==EINTR continue;否则break;}您当前的代码将失效;可能是fd_集合不变。这没有任何意义,你能详细说明一下吗?如果select失败,返回-1程序终止,主循环中断。如果select被信号中断,它也会自动终止。除此之外,我可以在调试输出中清楚地看到,从select.return-1//EAGAIN返回后,rval立即获取值>0不是一个错误。只需重新启动或至少跳到select的正上方,也要注意BSD/SYSV语义的差异。BSD用于自动重启,IIRC。顺便说一句:EAGAIN==EINTR你是对的,把EINTR当作错误是胡说八道。我已经在代码库中修复了,谢谢。但正如我早些时候所写,这与我在问题中描述的行为无关,我不会为你做任何事。我刚才指出了第一个明显的错误,这是一个严重的错误,与问题的标题/主题“早安”密切相关。圣诞快乐!
for ( i = 0; i < etherpoke_conf->filter_cnt; i++ ){
    struct bpf_program bpf_prog;

    session_data_init (&(pcap_session[i]));

    pcap_session[i].handle = pcap_create (etherpoke_conf->filter[i].interface, pcap_errbuff);

    rval = pcap_set_promisc (pcap_session[i].handle, !etherpoke_conf->filter[i].rfmon);

    if ( etherpoke_conf->filter[i].rfmon ){
        rval = pcap_can_set_rfmon (pcap_session[i].handle);

        if ( rval == 1 ){
            rval = pcap_set_rfmon (pcap_session[i].handle, 1);
        } else {
            fprintf (stderr, "%s: cannot enable monitor mode on interface '%s': %s\n", argv[0], etherpoke_conf->filter[i].interface, pcap_geterr (pcap_session[i].handle));
            exitno = EXIT_FAILURE;
            goto cleanup;
        }
    }

    rval = pcap_set_timeout (pcap_session[i].handle, SELECT_TIMEOUT_MS);

    rval = pcap_setnonblock (pcap_session[i].handle, 1, pcap_errbuff);

    rval = pcap_activate (pcap_session[i].handle);

    rval = pcap_compile (pcap_session[i].handle, &bpf_prog, etherpoke_conf->filter[i].match, 0, PCAP_NETMASK_UNKNOWN);

    rval = pcap_setfilter (pcap_session[i].handle, &bpf_prog);

    pcap_freecode (&bpf_prog);

    pcap_session[i].fd = pcap_get_selectable_fd (pcap_session[i].handle);
}
while ( main_loop ){
    time_t current_time;
    struct pcap_pkthdr *pkt_header;
    const u_char *pkt_data;
    struct timeval timeout;
    fd_set fdset_read;
    int last_fd;

    FD_ZERO (&fdset_read);
    last_fd = 0;
    timeout.tv_sec = 0;
    timeout.tv_usec = SELECT_TIMEOUT_MS * 1000;

    for ( i = 0; i < etherpoke_conf->filter_cnt; i++ ){
        if ( pcap_session[i].fd == -1 )
            continue;

        FD_SET (pcap_session[i].fd, &fdset_read);
        last_fd = pcap_session[i].fd;
    }

    if ( last_fd == 0 ){
        syslog (LOG_ERR, "no more applicable filters left to use. Dying!");
        break;
    }

    rval = select (last_fd + 1, &fdset_read, NULL, NULL, &timeout);

    if ( rval == -1 ){
        if ( errno != EINTR )
            syslog (LOG_ERR, "select system call failed: %s", strerror (errno));
        break;
    }

    time (&current_time);

    for ( i = 0; i < etherpoke_conf->filter_cnt; i++ ){
        if ( FD_ISSET (pcap_session[i].fd, &fdset_read) ){
            rval = pcap_next_ex (pcap_session[i].handle, &pkt_header, &pkt_data);

            if ( rval < 0 ){
                syslog (LOG_ERR, "could not obtain packet from the queue: %s", pcap_geterr (pcap_session[i].handle));
                main_loop = 0;
                break;
            } else if ( rval == 0 ){
                continue;
            }
        }

        if ( (pcap_session[i].ts > 0)
                && (difftime (current_time, pcap_session[i].ts) >= etherpoke_conf->filter[i].session_timeout) ){
            pcap_session[i].evt_flag = FILTER_EVENT_END;
        }
    }
}