thread1:使用pcap_next的EXC_BAD_ACCESS(代码= 1,地址= 0x0)

时间:2014-04-08 20:03:25

标签: objective-c exc-bad-access pcap

我正在尝试使用pcap_next,但我的程序在此行停止:

packet = pcap_next([self pcap_socket], hdr);

错误:

thread1: EXC_BAD_ACCESS (code=1, address=0x0)

这是我的代码:

-(const u_char*)readOnPcapDescriptor
{
    if([self pcap_is_open]) {
        struct pcap_pkthdr *hdr = NULL;
        const u_char *packet;

        // read for the next packet
        packet = pcap_next([self pcap_socket], hdr);

        if(packet==NULL)
            return NULL;
        else
            return packet;
    }

    printf("NOK\nOpen descriptor First!\n\n");
    exit(1);
}

我不明白我的错误在哪里。之前打开了pcap_t描述符:

pcap_t * open_socket = pcap_open_live(if_name,BUFSIZ,1,1,pcap_errbuf);

受影响的实例变量:

[self setPcap_socket:open_socket];

3 个答案:

答案 0 :(得分:1)

pcap_next documentation并未说明pcap_pkthdr参数允许为NULL。尝试将有效指针传递给pcap_pkthdr结构:

struct pcap_pkthdr hdr = {0};
packet = pcap_next([self pcap_socket], &hdr);

答案 1 :(得分:0)

pcap_next()的文档告诉您“h指向的pcap_pkthdr结构填入了适当的数据包值。”

在您的示例中,h被称为hdr,您将其初始化为:

struct pcap_pkthdr *hdr = NULL;

换句话说,pcap_next()尝试访问NULL处的地址,这正是错误消息中所述的内容。

答案 2 :(得分:0)

  

我只能阅读2个包

引用pcap_next()手册页:

   pcap_next() returns a pointer  to  the  packet  data  on  success,  and
   returns  NULL  if  an  error occured, or if no packets were read from a
   live capture (if, for example, they were discarded because they  didn't
   pass the packet filter, or if, on platforms that support a read timeout
   that starts before any packets arrive, the timeout expires  before  any
   packets  arrive, or if the file descriptor for the capture device is in
   non-blocking mode and no packets were available to be read), or  if  no
   more  packets are available in a ``savefile.''  Unfortunately, there is
   no way to determine whether an error occured or not.

这里重要的是"如果......或者如果没有从实时捕获中读取数据包,则返回NULL(...或者,如果在支持在任何数据包到达之前启动的读取超时的平台上,超时在任何数据包到达之前到期......"

BSD风格的操作系统,例如OS X和iOS,支持在任何数据包到达之前开始的读取超时,因此如果现在没有任何数据包,您可能会返回NULL 。那意味着永远不会成为任何数据包;你必须继续循环。

pcap_next()不区分错误和超时;正如手册页所说,"不幸的是,无法确定是否发生错误。"。因此,它不是,而且从来就不是一个很好的例程。

如果您不想使用接受回调的例程,例如pcap_dispatch()pcap_loop(),我建议您使用pcap_next_ex() >区分错误和"没有数据包在超时间隔内到达"。