Reading BPF Assembly


I'm trying to read some BPF syntax for a filter to try and figure out what it does. One thing I cannot find is where the "byte offset starts". Meaning, that if we have the following assembler code:

 0000: 0x28 0x00 0x00 0x00000004   ldh $data[4]
 0001: 0x15 0x00 0x61 0x00000028   jeq 40   true:0002 false:0099
 0002: 0x30 0x00 0x00 0x0000000d   ldb $data[13]
 0003: 0x14 0x00 0x00 0x00000033   sub 51
 0004: 0x15 0x00 0x5e 0x00000006   jeq 6    true:0005 false:0099
  1. Question 1

For byte offset 4, does that put me in the middle of the destination MAC address of an 802.3 frame? Or is it in the preamble? Where in the packet do I start from, then walk 4 bytes to my half word is what I am asking.

  1. Question 2

If it is in the MAC address, would scapy be a viable option to write my own packet's ethernet frame? The goal of this is to write a client that will connect and pass all of the BPF requirements.


1 Answer


For your first question: it depends on where, and how, you attach your BPF program.

  • If you attach it to the TC (traffic control) interface as a classifier, it will start working on the L2 Ethernet header (destination MAC address).

  • If you attach it to a socket, I think there are several cases:

    • If the protocol you passed when creating your socket is, for example, TCP, then the program starts on the L3 (IP) header. See for example this question.
    • If the protocol required is “every packet”, then the program starts working on the MAC header. See the example in the BPF kernel documentation (grep for ETH_P_ALL).

    Edit: Rather than the protocol, this is more likely the socket domain in use (AF_PACKET vs. AF_INET) that makes the difference here.

For your second question, you can build Ethernet headers and payloads with scapy, but I'm sorry, I don't understand what you mean by “connect and pass all of the BPF requirements”… Could you please detail a bit more?

answered on Stack Overflow Mar 30, 2018 by Qeole • edited Apr 1, 2018 by Qeole

User contributions licensed under CC BY-SA 3.0