1BPFC(8) netsniff-ng toolkit BPFC(8)
2
3
4
6 bpfc - a Berkeley Packet Filter assembler and compiler
7
9 bpfc { [options] | [source-file] }
10
12 bpfc is a small Berkeley Packet Filter assembler and compiler which is
13 able to translate BPF assembler-like mnemonics into a numerical or C-
14 like format, that can be read by tools such as netsniff-ng, iptables
15 (xt_bpf) and many others. BPF is the one and only upstream filtering
16 construct that is used in combination with packet(7) sockets, but also
17 seccomp-BPF for system call sandboxing.
18
19 The Linux kernel and also BSD kernels implement "virtual machine" like
20 constructs and JIT compilers that mimic a small register-based machine
21 in BPF architecture and execute filter code that is, for example, com‐
22 posed by bpfc on a data buffer that is given by network packets. The
23 purpose of this is to shift computation in time, so that the kernel can
24 drop or truncate incoming packets as early as possible without having
25 to push them to user space for further analysis first. Meanwhile, BPF
26 constructs also find application in other areas such as in the communi‐
27 cation between user and kernel space like system call sand-boxing.
28
29 At the time of writing this man page, the only other available BPF com‐
30 piler is part of the pcap(3) library and accessible through a high-
31 level filter language that might be familiar to many people as tcpdump-
32 like filters.
33
34 However, it is quite often useful to bypass that compiler and write
35 optimized code that cannot be produced by the pcap(3) compiler, or is
36 wrongly optimized, or is defective on purpose in order to debug test
37 kernel code. Also, a reason to use bpfc could be to try out some new
38 BPF extensions that are not supported by other compilers. Furthermore,
39 bpfc can be useful to verify JIT compiler behavior or to find possible
40 bugs that need to be fixed.
41
42 bpfc is implemented with the help of flex(1) and bison(1), tokenizes
43 the source file in the first stage and parses its content into an AST.
44 In two code generation stages it emits target opcodes. bpfc furthermore
45 supports Linux kernel BPF extensions. More about that can be found in
46 the syntax section.
47
48 The Linux kernel BPF JIT compiler is automatically turned on if
49 detected by netsniff-ng. However, it can also be manually turned on
50 through the command ''echo "1" > /proc/sys/net/core/bpf_jit_enable''
51 (normal working mode) or ''echo "2" >
52 /proc/sys/net/core/bpf_jit_enable'' (debug mode where emitted opcodes
53 of the image are printed to the kernel log). An architecture agnostic
54 BPF JIT image disassembler can be found in the kernel source tree under
55 ''tools/net/bpf_jit_disasm.c'' or within the netsniff-ng Git reposi‐
56 tory.
57
59 -i <source-file/->, --input <source-file/->
60 Read BPF assembly instruction from an input file or from stdin.
61
62 -p, --cpp
63 Pass the bpf program through the C preprocessor before reading
64 it in bpfc. This allows #define and #include directives (e.g. to
65 include definitions from system headers) to be used in the bpf
66 program.
67
68 -D <name>=<definition>, --define <name>=<definition>
69 Add macro definition for the C preprocessor to use it within bpf
70 file. This option is used in combination with the -p/--cpp
71 option.
72
73 -f <format>, --format <format>
74 Specify a different output format than the default that is net‐
75 sniff-ng compatible. The <format> specifier can be: C, netsniff-
76 ng, xt_bpf, tcpdump.
77
78 -b, --bypass
79 Bypass basic filter validation when emitting opcodes. This can
80 be useful for explicitly creating malformed BPF expressions for
81 injecting into the kernel, for example, for bug testing.
82
83 -V, --verbose
84 Be more verbose and display some bpfc debugging information.
85
86 -d, --dump
87 Dump all supported instructions to stdout.
88
89 -v, --version
90 Show version information and exit.
91
92 -h, --help
93 Show user help and exit.
94
96 The BPF architecture resp. register machine consists of the following
97 elements:
98
99 Element Description
100
101 A 32 bit wide accumulator
102 X 32 bit wide X register
103 M[] 16 x 32 bit wide misc registers aka “scratch mem‐
104 ory store”, addressable from 0 to 15
105
106 A program, that is translated by bpfc into ''opcodes'' is an array that
107 consists of the following elements:
108
109 o:16, jt:8, jf:8, k:32
110
111 The element o is a 16 bit wide opcode that has a particular instruction
112 encoded, jt and jf are two 8 bit wide jump targets, one for condition
113 ''true'', one for condition ''false''. Last but not least the 32 bit
114 wide element k contains a miscellaneous argument that can be inter‐
115 preted in different ways depending on the given instruction resp.
116 opcode.
117
118 The instruction set consists of load, store, branch, alu, miscellaneous
119 and return instructions that are also represented in bpfc syntax. This
120 table also includes bpfc's own extensions. All operations are based on
121 unsigned data structures:
122
123 Instruction Addressing mode Description
124
125 ld 1, 2, 3, 4, 10 Load word into A
126 ldi 4 Load word into A
127 ldh 1, 2 Load half-word into A
128 ldb 1, 2 Load byte into A
129 ldx 3, 4, 5, 10 Load word into X
130 ldxi 4 Load word into X
131 ldxb 5 Load byte into X
132
133 st 3 Copy A into M[]
134 stx 3 Copy X into M[]
135
136 jmp 6 Jump to label
137 ja 6 Jump to label
138 jeq 7, 8 Jump on k == A
139 jneq 8 Jump on k != A
140 jne 8 Jump on k != A
141 jlt 8 Jump on k < A
142 jle 8 Jump on k <= A
143 jgt 7, 8 Jump on k > A
144 jge 7, 8 Jump on k >= A
145 jset 7, 8 Jump on k & A
146
147 add 0, 4 A + <x>
148 sub 0, 4 A - <x>
149 mul 0, 4 A * <x>
150 div 0, 4 A / <x>
151 mod 0, 4 A % <x>
152 neg 0, 4 !A
153 and 0, 4 A & <x>
154 or 0, 4 A | <x>
155 xor 0, 4 A ^ <x>
156 lsh 0, 4 A << <x>
157 rsh 0, 4 A >> <x>
158
159 tax Copy A into X
160 txa Copy X into A
161
162 ret 4, 9 Return
163
164 Addressing mode Syntax Description
165
166 0 x/%x Register X
167 1 [k] BHW at byte offset k in the
168 packet
169 2 [x + k] BHW at the offset X + k in the
170 packet
171 3 M[k] Word at offset k in M[]
172 4 #k Literal value stored in k
173 5 4*([k]&0xf) Lower nibble * 4 at byte off‐
174 set k in the packet
175 6 L Jump label L
176 7 #k,Lt,Lf Jump to Lt if true, otherwise
177 jump to Lf
178 8 #k,Lt Jump to Lt if predicate is
179 true
180 9 a/%a Accumulator A
181 10 extension BPF extension (see next table)
182
183 Extension (and alias) Description
184
185 #len, len, #pktlen, pktlen Length of packet (skb->len)
186 #pto, pto, #proto, proto Ethernet type field (skb->pro‐
187 tocol)
188 #type, type Packet type (**)
189 (skb->pkt_type)
190 #poff, poff Detected payload start offset
191 #ifx, ifx, #ifidx, ifidx Interface index
192 (skb->dev->ifindex)
193 #nla, nla Netlink attribute of type X
194 with offset A
195 #nlan, nlan Nested Netlink attribute of
196 type X with offset A
197 #mark, mark Packet mark (skb->mark)
198 #que, que, #queue, queue, #Q, Q NIC queue index
199 (skb->queue_mapping)
200 #hat, hat, #hatype, hatype NIC hardware type (**)
201 (skb->dev->type)
202 #rxh, rxh, #rxhash, rxhash Receive hash (skb->rxhash)
203 #cpu, cpu Current CPU (raw_smp_proces‐
204 sor_id())
205 #vlant, vlant, #vlan_tci, vlan_tci VLAN TCI value
206 (vlan_tx_tag_get(skb))
207 #vlanp, vlanp VLAN present
208 (vlan_tx_tag_present(skb))
209
210 Further extension details (**) Value
211
212 #type, type 0 - to us / host
213 1 - to all / broadcast
214 2 - to group / multicast
215 3 - to others (promiscuous
216 mode)
217 4 - outgoing of any type
218
219 #hat, hat, #hatype, hatype 1 - Ethernet 10Mbps
220 8 - APPLEtalk
221 19 - ATM
222 24 - IEEE 1394 IPv4 - RFC 2734
223 32 - InfiniBand
224 768 - IPIP tunnel
225 769 - IP6IP6 tunnel
226 772 - Loopback device
227 778 - GRE over IP
228 783 - Linux-IrDA
229 801 - IEEE 802.11
230 802 - IEEE 802.11 + Prism2
231 header
232 803 - IEEE 802.11 + radiotap
233 header
234 823 - GRE over IP6
235 824 - Netlink
236 [...] See
237 include/uapi/linux/if_arp.h
238
239 Note that the majority of BPF extensions are available on Linux only.
240
241 There are two types of comments in bpfc source-files:
242
243 1. Multi-line C-style comments: /* put comment here */
244 2. Single-line ASM-style comments: ; put comment here
245
246 Used Abbreviations:
247
248 BHW: byte, half-word, or word
249
251 In this section, we give a couple of examples of bpfc source files, in
252 other words, some small example filter programs:
253
254 Only return packet headers (truncate packets):
255
256 ld poff
257 ret a
258
259 Only allow ARP packets:
260
261 ldh [12]
262 jne #0x806, drop
263 ret #-1
264 drop: ret #0
265
266 Only allow IPv4 TCP packets:
267
268 ldh [12]
269 jne #0x800, drop
270 ldb [23]
271 jneq #6, drop
272 ret #-1
273 drop: ret #0
274
275 Only allow IPv4 TCP SSH traffic:
276
277 ldh [12]
278 jne #0x800, drop
279 ldb [23]
280 jneq #6, drop
281 ldh [20]
282 jset #0x1fff, drop
283 ldxb 4 * ([14] & 0xf)
284 ldh [x + 14]
285 jeq #0x16, pass
286 ldh [x + 16]
287 jne #0x16, drop
288 pass: ret #-1
289 drop: ret #0
290
291 A loadable x86_64 seccomp-BPF filter to allow a given set of syscalls:
292
293 ld [4] /* offsetof(struct seccomp_data, arch) */
294 jne #0xc000003e, bad /* AUDIT_ARCH_X86_64 */
295 ld [0] /* offsetof(struct seccomp_data, nr) */
296 jeq #15, good /* __NR_rt_sigreturn */
297 jeq #231, good /* __NR_exit_group */
298 jeq #60, good /* __NR_exit */
299 jeq #0, good /* __NR_read */
300 jeq #1, good /* __NR_write */
301 jeq #5, good /* __NR_fstat */
302 jeq #9, good /* __NR_mmap */
303 jeq #14, good /* __NR_rt_sigprocmask */
304 jeq #13, good /* __NR_rt_sigaction */
305 jeq #35, good /* __NR_nanosleep */
306 bad: ret #0 /* SECCOMP_RET_KILL */
307 good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */
308
309 Allow any (hardware accelerated) VLAN:
310
311 ld vlanp
312 jeq #0, drop
313 ret #-1
314 drop: ret #0
315
316 Only allow traffic for (hardware accelerated) VLAN 10:
317
318 ld vlant
319 jneq #10, drop
320 ret #-1
321 drop: ret #0
322
323 More pedantic check for the above VLAN example:
324
325 ld vlanp
326 jeq #0, drop
327 ld vlant
328 jneq #10, drop
329 ret #-1
330 drop: ret #0
331
332 Filter rtnetlink messages:
333
334 ldh #proto /* A = skb->protocol */
335
336 jneq #0, skip /* check for NETLINK_ROUTE */
337 ldb [4] /* A = nlmsg_type */
338
339 jneq #0x10, skip /* check type == RTNL_NEWLINK */
340 ldx #16 /* X = offset(ifinfomsg) */
341
342 ldb [x + 4] /* offset(ifi_index) */
343 jneq #0x3, skip /* check ifindex == 3 */
344
345 ld #32 /* A = len(nlmsghdr) + len(ifinfomsg), payload off‐
346 set */
347 ldx #16 /* X = IFLA_OPERSTATE */
348 ld #nla /* A = offset(IFLA_OPERSTATE) */
349 jeq #0, skip
350 tax
351 ldb [x + 4] /* A = value(IFLA_OPERSTATE) */
352 jneq #0x6, skip /* check oper state is UP */
353
354 ret #-1
355 skip: ret #0
356
358 bpfc fubar
359 Compile the source file ''fubar'' into BPF opcodes. Opcodes will
360 be directed to stdout.
361
362 bpfc -f xt_bpf -b -p -i fubar, resp. iptables -A INPUT -m bpf --byte‐
363 code `bpfc -f xt_bpf -i fubar` -j LOG
364 Compile the source file ''fubar'' into BPF opcodes, bypass basic
365 filter validation and emit opcodes in netfilter's xt_bpf read‐
366 able format. Note that the source file ''fubar'' is first passed
367 to the C preprocessor for textual replacements before handing
368 over to the bpfc compiler.
369
370 cat fubar | bpfc -
371 Read bpfc instruction from stdin and emit opcodes to stdout.
372
373 bpfc foo > bar && netsniff-ng -f bar ...
374 Compile filter instructions from file foo and redirect bpfc's
375 output into the file bar, that can then be read by netsniff-
376 ng(8) through option -f.
377
378 bpfc -f tcpdump -i fubar
379 Output opcodes from source file fubar in the same behavior as
380 ''tcpdump -ddd''.
381
383 bpfc is licensed under the GNU GPL version 2.0.
384
386 bpfc was originally written for the netsniff-ng toolkit by Daniel Bork‐
387 mann. It is currently maintained by Tobias Klauser <tklauser@dis‐
388 tanz.ch> and Daniel Borkmann <dborkma@tik.ee.ethz.ch>.
389
391 netsniff-ng(8), trafgen(8), mausezahn(8), ifpps(8), flowtop(8),
392 astraceroute(8), curvetun(8)
393
395 Manpage was written by Daniel Borkmann.
396
398 This page is part of the Linux netsniff-ng toolkit project. A descrip‐
399 tion of the project, and information about reporting bugs, can be found
400 at http://netsniff-ng.org/.
401
402
403
404Linux 03 March 2013 BPFC(8)