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