BPF Berkeley Packet Filter Question

Daniel Janzon janzon at gmail.com
Wed Dec 30 16:27:33 UTC 2015


Hi again,

It's a long time since I used BPF so I might be wrong but I think what you
want to do is to (syntax from bpf man page in parenthesis)

1. Load from packet where the length is specified to the ackumulator (A <-
P[k:4]).
2. Store the value in the ackumulator to scratch memory (M[k] <- A).
3. Copy value from scratch memory to the index (X <- M[k]).
4. Store the value in the packet at the dynamic position we now have in the
index (A <- P[X+k:4]).

Each step explained a bit below. Suppose the packet is an array P, at P[47]
we can read the position of the value we want to filter on. In this case
P[47] = 189. So P[189] contains the value we want to use as basis for
filtering.

1. Store P[47] in ackumulator A.
2. Store A in M[0].
3. Store M[0] in index X.
4. Store P[X] in A (let k=0).

Now you can branch depending on the value in A. Under the section "Filter
machine" in the BPF manual you can see how to translate the above to BPF
macros. Beware if you want to read bytes or words.

Regards,
Daniel




On Wed, Dec 30, 2015 at 4:37 PM Juan Herrera <mybsdmailing at gmail.com> wrote:

> Hello Julian, Daniel
>
> I am using raw ethernet, and testing with ARP
>
> Brief Explanation of what I want to do
>
> I am sending ARP requests packets(encapsulated with my metadata at the
> end), so it is Raw Ethernet like this "ARP Req bytes + Metadata bytes", I
> already did a test to filter with BPF jumbo ethernet packets and I can
> filter if I want against the last byte in the packet, but to do this I need
> to place in my program code the C filter code (generated with tcpdump),
> exacly the byte position I want to use for filtering, so the issue with
> this is that when I receive another ethernet frame that it is not an ARP
> Req, the byte position to filter will not be the right one(because it
> moves) to use because the packet is bigger or smaller so my metadata has
> shift left or shift right depending on the case, so I want BPF to read the
> total packet length to return it in a variable, and then I use this
> variable to calculate the right byte to use for filtering, depending on the
> packet length.
>
> I need to match with a specific metadata field base on length, but dont
> know how to use BPF to read packet's length.
>
>
> Thanks!
>
> 2015-12-30 6:11 GMT-06:00 Daniel Janzon <janzon at gmail.com>:
>
>> Hello Julian,
>>
>> I'm not sure I follow what you want to do but maybe I can help you get in
>> the right direction.
>>
>> You can define a BPF program with macros, like
>>
>> struct bpf_insn instructions[] = {
>>     ...
>>     BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, proto, 0, 1),
>>     BPF_STMT(BPF_RET + BPF_K, (uint16_t)-1),
>>     BPF_STMT(BPF_RET + BPF_K, 0)
>> };
>>
>> struct bpf_program bpf_program = { 4, (struct bpf_insn*)&instructions };
>> ioctl(fd, BIOCSETF, (struct bpf_program*)&bpf_program);
>>
>> etc, google for a complete example.
>>
>> Then you can use the -d option of tcpdump to get some help to find the
>> right instructions, for instance
>>
>> tcpdump -i em0 -d host 10.10.10.1 and greater 150  # capture packets
>> greater than 150
>>
>> You will probably have to modify the output a bit to get what you want so
>> you will have to learn a bit how it works. See the section Filter machine
>> in the bpf manual (man 4 bpf).
>>
>> Hope that helps.
>>
>> All the best,
>> Daniel Janzon
>>
>>
>> On Wed, Dec 30, 2015 at 9:58 AM Julian Elischer <julian at freebsd.org>
>> wrote:
>>
>>> On 30/12/2015 12:46 PM, Juan Herrera wrote:
>>> > Hello BSD folks,
>>> >
>>> > I am developing a networking application in C and I have a question
>>> > regarding BPF (Berkeley Packet Filters), I will give you an idea of
>>> the app
>>> > first,  I need to send a packet from machine A to machine B (any kind
>>> of
>>> > packet) so for this I wrote a packet generator application which will
>>> send
>>> > a packet to machine B, but before sending the packet I need to append
>>> some
>>> > metadata values at the end of the packet, already done, so in machine
>>> B I
>>> > have a raw socket listener app ready to receive incoming packets from
>>> > machine A, however I want to implement filtering with BPF on machine
>>> B, but
>>> > as my metadata was appended at the end of the packet (have to be at the
>>> > end), I need to read the packet length with(using) Berkeley Packet
>>> Filter
>>> > to match a specific field to filter one of the bytes at the end of my
>>> > packet (metadata appended), in other words I need to know the incoming
>>> > packet length to filtered against one of the metadatas fields and be
>>> able
>>> > to drop the packet before reaching user space applications(drop it in
>>> > kernel space).
>>> >
>>> > So my question is, Can I use BPF to read the packet length ?
>>> to continue on my previous mail.
>>>
>>> you can also use netgraph to do this in several ways as well.
>>> But I'd need more information to be able to explain what to do.
>>>
>>> >
>>> > TIA!
>>> > _______________________________________________
>>> > freebsd-hackers at freebsd.org mailing list
>>> > https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>>> > To unsubscribe, send any mail to "
>>> freebsd-hackers-unsubscribe at freebsd.org"
>>> >
>>>
>>> _______________________________________________
>>> freebsd-hackers at freebsd.org mailing list
>>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>>> To unsubscribe, send any mail to "
>>> freebsd-hackers-unsubscribe at freebsd.org"
>>>
>>
>


More information about the freebsd-hackers mailing list