KrishnamRaju raju
KrishnamRaju raju

Reputation: 43

What are the possible return codes of bpf_filter(), in FreeBSD kernel? What does each return codes mean?

What are the possible return codes of bpf_filter(), in FreeBSD kernel?

What does each return codes mean?

The man page (link) is not clear on this issue.

The bpf_filter() function executes the filter program starting at pc on the packet pkt. The wirelen argument is the length of the original packet and buflen is the amount of data present. The buflen value of 0 is special; it indicates that the pkt is actually a pointer to an mbuf chain (struct mbuf *).

Return Values

The bpf_filter() function returns -1 (cast to an unsigned integer) if there is no filter. Otherwise, it returns the result of the filter program.

I am getting 65535 when there is a Match and 0 when there is no match. Not sure what is the meaning for the return value 65535.

Can someone please explain the return code of bpf_filter() in detailed?

Upvotes: 1

Views: 880

Answers (2)

C.Sutherland
C.Sutherland

Reputation: 11

The return value of bpf_filter() is the result of the filter program. The result being number of bytes of the packet being filtered to be copied to the buffer for the task (the filter return instruction value).

The value will be 0 if the packet does not match the filter. If the packet matches the filter it will be the snapshot length (snaplen) that was defined in the pcap_open_ call.

The default value is 65535 bytes as the maximum size of a TCP packet is 64K (65535 bytes).

Upvotes: 1

Qeole
Qeole

Reputation: 9124

The function bpf_filter() takes a pointer to a struct containing the BPF instructions as an argument (pc on the man page) and runs these on the packets to filter them.

The bpf_filter() function returns -1 (cast to an unsigned integer) if there is no filter.

We can check in the source code that when pc, the structure that should contain the BPF instructions, is null, then bpf_filter() immediately returns -1, cast to a u_int:

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

[Edited] Internally, for a signed integer, -1 would be stored as “the maximal value for a integer, minus one”. With 32 bits, since the return value here is cast to an unsigned integer, that would be 2^32 - 1.
Since the return value here is cast to an unsigned integer, this is the value you obtain: 65535 equals to 2**16 - 1, so -1 cast to a unsigned 16 bit-long integer (a u_int). So I would tend to believe that when you see this 65535 value, you do not actually provide any BPF program to the function? Would that be consistant with you observations?

Now when there is a match:

Otherwise, it returns the result of the filter program.

The result value of bpf_filter() is the result retreived from the BPF program. So when you get a 0 return value, it means that:

  • Either your BPF program completed and returned 0.
  • Or possibly (even though this does not seem documented in the man page), an error was encountered while running the BPF program. Here is an example, also from the source:

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

“In the case of an arithmetic division, if the denominator X is null, then make bpf_filter() return 0, else divide register A by register X and carry on to the next instruction”.

[Edited] (see comments) As you found out, the same applies for the 65535 value: it is the value you made your BPF program return.

Upvotes: 0

Related Questions