【问题标题】:What are the possible return codes of bpf_filter(), in FreeBSD kernel? What does each return codes mean?FreeBSD 内核中 bpf_filter() 的可能返回码是什么?每个返回码是什么意思?
【发布时间】:2016-08-25 14:00:49
【问题描述】:

FreeBSD 内核中 bpf_filter() 的可能返回码是什么?

每个返回码是什么意思?

man page (link) 对此问题不清楚。

bpf_filter() 函数从 pc 开始执行过滤程序 包包。 wirelen 参数是原始的长度 packet 和 buflen 是存在的数据量。 0的buflen值 很特别;它表明pkt实际上是一个指向mbuf的指针 链 (struct mbuf *)。

返回值

如果没有过滤器,bpf_filter() 函数将返回 -1(转换为无符号整数)。否则返回过滤程序的结果。

当有匹配时我得到65535,当没有匹配时得到0。不知道返回值65535是什么意思。

谁能详细解释bpf_filter()的返回码?

【问题讨论】:

    标签: freebsd tcpdump bpf


    【解决方案1】:

    bpf_filter()的返回值是过滤程序的结果。结果是将被过滤的数据包的字节数复制到任务的缓冲区(过滤器返回指令值)。

    如果数据包不匹配过滤器,该值将为 0。 如果数据包与过滤器匹配,它将是 pcap_open_ 调用中定义的快照长度 (snaplen)。

    默认值为 65535 字节,因为 TCP 数据包的最大大小为 64K(65535 字节)。

    【讨论】:

      【解决方案2】:

      函数bpf_filter() 将指向包含BPF 指令的结构的指针作为参数(手册页上的pc)并在数据包上运行这些指令以过滤它们。

      如果满足以下条件,bpf_filter() 函数将返回 -1(强制转换为无符号整数) 没有过滤器。

      我们可以检查in the source code,当应该包含BPF指令的结构pc为空时,bpf_filter()立即返回-1,转换为u_int

      if (pc == 0)
          /*
           * No filter means accept all.
           */
          return (u_int)-1;
      

      [已编辑] 在内部,对于有符号整数,-1 将存储为“整数的最大值减一”。对于 32 位,由于此处的返回值被强制转换为无符号整数,这将是 2^32 - 1
      由于此处的返回值被强制转换为无符号整数,因此这是您获得的值:@987654331 @ 等于 2**16 - 1,所以 -1 转换为无符号的 16 位长整数(u_int)。所以我倾向于相信,当你看到这个 65535 值时,你实际上并没有为函数提供任何 BPF 程序?这和你的观察一致吗?

      现在有比赛时:

      否则返回过滤程序的结果。

      bpf_filter() 的结果值是从 BPF 程序中获取的结果。所以当你得到一个0的返回值时,就意味着:

      • 您的 BPF 程序已完成并返回 0
      • 或者可能(即使手册页中似乎没有记录),在运行 BPF 程序时遇到了错误。这是一个例子,同样来自源代码:

        case BPF_ALU|BPF_DIV|BPF_X:
            if (X == 0)
                return 0;
            A /= X;
            continue;
        

      “在算术除法的情况下,如果分母X为空,则使bpf_filter()返回0,否则将寄存器A除以寄存器X并继续下一条指令” .

      [已编辑](参见 cmets)正如您所发现的,65535 值也是如此:它是您让 BPF 程序返回的值。

      【讨论】:

      • 感谢您的解释。 u_int bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen) 您可以从上面看到返回值是“u_int”类型,因此它是 32 位无符号整数。当您将 -1 转换为无符号 32 位整数时,它是:4294967295。此外,我在“if(pc == 0)”块周围放置了一些痕迹,其中返回了“-1”。从这些痕迹中我可以看出它根本不会进入这个“如果”块。我猜它应该在成功的情况下返回数据包长度,但每次匹配时它都会返回 65535。(我的 pkt len 是 78)
      • 嗯我不明白为什么它会打印数据包长度,它应该是 BPF 返回值。既然你可以调试函数,那么你能知道bpf_filter()中的哪个“return”语句实际上是使用的吗?也许这会有所帮助。另外,是否可以提供您正在使用的 BPF 程序?
      • 我发现了问题,bpf_filter() 返回 65535,因为我为 pcap open 指定了 65535,如下所示: pcap_open_dead(DLT_EN10MB, 65535);现在,将 65535 替换为 1 后,bpf_filter() 返回 1。Qeole,感谢您的回答。它帮助我变得更加清晰..
      • @KrishnamRajuraju:太好了!这确实是有道理的。很高兴知道我能帮上忙 :-)。
      猜你喜欢
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 2014-07-31
      相关资源
      最近更新 更多