pcap_next_ex()从不设置指向原始数据包的指针?

时间:2014-02-06 12:50:57

标签: c++ c linux network-programming libpcap

我尝试使用libpcap(CentOS 6上的1.4.0)读取原始数据包。

但是,由于某些原因,pcap_next_ex()之后rawPacket始终为NULL。

然而,pcap_next_ex()确实返回1,虽然它可能意味着超时到期(其中超时设置方式是什么?)。

首先,我认为传递给pcap_compile()的过滤字符串是错误的。但我尝试将相同的字符串复制并粘贴到tcpdump,它工作正常 - 我看到预期的数据包被捕获。


    struct pcap_pkthdr *pHeader;
    const u_char* rawPacket = NULL;
    int rc = 0;
    while (1) {
        rc = pcap_next_ex(pDevice, &pHeader, &rawPacket);
        if (-1 != rc && NULL != rawPacket) {
            // process
            struct ether_header* eptr = (struct ether_header *) rawPacket;
            if (ntohs (eptr->ether_type) == ETHERTYPE_IP) {
                    printf("Ethernet type hex:%x dec:%d is an IP packet\n",
                            ntohs(eptr->ether_type),
                            ntohs(eptr->ether_type));
            }
        }
    }


有什么想法吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

实际上,pcap_next_ex()手册页所说的是

   pcap_next_ex() returns 1 if the packet was read without problems, 0  if
   packets are being read from a live capture, and the timeout expired, -1
   if an error occurred while reading the packet, and -2  if  packets  are
   being  read  from a ``savefile'', and there are no more packets to read
   from the savefile.  If -1 is returned, pcap_geterr()  or  pcap_perror()
   may be called with p as an argument to fetch or display the error text.

我需要编辑它以删除“实时捕获”和“超时过期”之间的注释,因为这意味着pcap_next_ex()返回:

  • 1,如果读取或捕获数据包,在这种情况下指针应设置为原始数据包;
  • 0,如果这是实时捕获并且超时(在pcap_open_live()中指定,或者,如果您使用pcap_create()pcap_activate()pcap_set_timeout())在等待时已过期一个数据包,在这种情况下没有读取数据包,指针将被设置为NULL;
  • -1,如果在读取或捕获时发生错误,在这种情况下没有读取数据包,指针将被设置为NULL;
  • -2,如果这是一个正在读取的文件,并且没有剩余的数据包可供读取,在这种情况下,没有读取数据包,指针将被设置为NULL。

所以,在pcap_next_ex()电话之后你应该做的是:

    if (1 == rc) {
        // process
        struct ether_header* eptr = (struct ether_header *) rawPacket;
        if (ntohs (eptr->ether_type) == ETHERTYPE_IP) {
                printf("Ethernet type hex:%x dec:%d is an IP packet\n",
                        ntohs(eptr->ether_type),
                        ntohs(eptr->ether_type));
        }
    } else if (0 == rc) {
        // do nothing here - this isn't an error, but you have no packet
        ;
    } else if (-1 == rc) {
        // error
        fprintf(stderr, "Error capturing or reading: %s\n", pcap_geterr(pDevice));
        // quit trying to read or capture packets here
    } else if (-2 == rc) {
        // end of file if you're reading from a file
        // this isn't an error, but there are no more packets to read
        // so quit trying to read packets here
    }