1 .\" netsniff-ng - the packet sniffing beast
2 .\" Copyright 2013 Daniel Borkmann.
3 .\" Subject to the GPL, version 2.
4 .TH BPFC 8 "03 March 2013" "Linux" "netsniff-ng toolkit"
6 bpfc \- a Berkeley Packet Filter assembler and compiler
10 \fBbpfc\fP { [\fIoptions\fP] | [\fIsource-file\fP] }
14 bpfc is a small Berkeley Packet Filter assembler and compiler which is able to
15 translate BPF assembler-like mnemonics into a numerical or C-like format,
16 that can be read by tools such as netsniff-ng, iptables (xt_bpf) and many
17 others. BPF is the one and only upstream filtering construct that is used
20 sockets, but also seccomp-BPF for system call sandboxing.
22 The Linux kernel and also BSD kernels implement "virtual machine" like
23 constructs and JIT compilers that mimic a small register-based machine in
24 BPF architecture and execute filter code that is, for example, composed by
25 bpfc on a data buffer that is given by network packets. The purpose of this
26 is to shift computation in time, so that the kernel can drop or truncate
27 incoming packets as early as possible without having to push them to user
28 space for further analysis first. Meanwhile, BPF constructs also find
29 application in other areas such as in the communication between user and
30 kernel space like system call sand-boxing.
32 At the time of writing this man page, the only other available BPF compiler
35 library and accessible through a high-level filter language that might be
36 familiar to many people as tcpdump-like filters.
38 However, it is quite often useful to bypass that compiler and write
39 optimized code that cannot be produced by the
41 compiler, or is wrongly optimized, or is defective on purpose in order to debug
42 test kernel code. Also, a reason to use bpfc could be to try out some new BPF
43 extensions that are not supported by other compilers. Furthermore, bpfc can be
44 useful to verify JIT compiler behavior or to find possible bugs that need to be
47 bpfc is implemented with the help of
51 tokenizes the source file in the first stage and parses its content into an AST.
52 In two code generation stages it emits target opcodes. bpfc furthermore supports
53 Linux kernel BPF extensions. More about that can be found in the syntax section.
55 The Linux kernel BPF JIT compiler is automatically turned on if detected
56 by netsniff-ng. However, it can also be manually turned on through the
57 command ''echo "1" > /proc/sys/net/core/bpf_jit_enable'' (normal working
58 mode) or ''echo "2" > /proc/sys/net/core/bpf_jit_enable'' (debug mode
59 where emitted opcodes of the image are printed to the kernel log). An
60 architecture agnostic BPF JIT image disassembler can be found in the kernel
61 source tree under ''tools/net/bpf_jit_disasm.c'' or within the netsniff-ng
66 .B -i <source-file/->, --input <source-file/->
67 Read BPF assembly instruction from an input file or from stdin.
70 Pass the bpf program through the C preprocessor before reading it in
71 bpfc. This allows #define and #include directives (e.g. to include
72 definitions from system headers) to be used in the bpf program.
74 .B -D <name>=<definition>, --define <name>=<definition>
75 Add macro definition for the C preprocessor to use it within bpf file. This
76 option is used in combination with the \fB-p\fP/\fB--cpp\fP option.
78 .B -f <format>, --format <format>
79 Specify a different output format than the default that is netsniff-ng
80 compatible. The <format> specifier can be: C, netsniff-ng, xt_bpf, tcpdump.
83 Bypass basic filter validation when emitting opcodes. This can be useful
84 for explicitly creating malformed BPF expressions for injecting
85 into the kernel, for example, for bug testing.
88 Be more verbose and display some bpfc debugging information.
91 Dump all supported instructions to stdout.
94 Show version information and exit.
97 Show user help and exit.
101 The BPF architecture resp. register machine consists of the following
106 A 32 bit wide accumulator
107 X 32 bit wide X register
108 M[] 16 x 32 bit wide misc registers aka \[lq]scratch
109 memory store\[rq], addressable from 0 to 15
111 A program, that is translated by bpfc into ''opcodes'' is an array that
112 consists of the following elements:
114 o:16, jt:8, jf:8, k:32
116 The element o is a 16 bit wide opcode that has a particular instruction
117 encoded, jt and jf are two 8 bit wide jump targets, one for condition
118 ''true'', one for condition ''false''. Last but not least the 32 bit wide
119 element k contains a miscellaneous argument that can be interpreted in
120 different ways depending on the given instruction resp. opcode.
122 The instruction set consists of load, store, branch, alu, miscellaneous
123 and return instructions that are also represented in bpfc syntax. This
124 table also includes bpfc's own extensions. All operations are based on
125 unsigned data structures:
127 Instruction Addressing mode Description
129 ld 1, 2, 3, 4, 10 Load word into A
130 ldi 4 Load word into A
131 ldh 1, 2 Load half-word into A
132 ldb 1, 2 Load byte into A
133 ldx 3, 4, 5, 10 Load word into X
134 ldxi 4 Load word into X
135 ldxb 5 Load byte into X
138 stx 3 Copy X into M[]
142 jeq 7, 8 Jump on k == A
143 jneq 8 Jump on k != A
147 jgt 7, 8 Jump on k > A
148 jge 7, 8 Jump on k >= A
149 jset 7, 8 Jump on k & A
168 Addressing mode Syntax Description
171 1 [k] BHW at byte offset k in the packet
172 2 [x + k] BHW at the offset X + k in the packet
173 3 M[k] Word at offset k in M[]
174 4 #k Literal value stored in k
175 5 4*([k]&0xf) Lower nibble * 4 at byte offset k in the packet
177 7 #k,Lt,Lf Jump to Lt if true, otherwise jump to Lf
178 8 #k,Lt Jump to Lt if predicate is true
180 10 extension BPF extension (see next table)
182 Extension (and alias) Description
184 #len, len, #pktlen, pktlen Length of packet (skb->len)
185 #pto, pto, #proto, proto Ethernet type field (skb->protocol)
186 #type, type Packet type (**) (skb->pkt_type)
187 #poff, poff Detected payload start offset
188 #ifx, ifx, #ifidx, ifidx Interface index (skb->dev->ifindex)
189 #nla, nla Netlink attribute of type X with offset A
190 #nlan, nlan Nested Netlink attribute of type X with offset A
191 #mark, mark Packet mark (skb->mark)
192 #que, que, #queue, queue, #Q, Q NIC queue index (skb->queue_mapping)
193 #hat, hat, #hatype, hatype NIC hardware type (**) (skb->dev->type)
194 #rxh, rxh, #rxhash, rxhash Receive hash (skb->rxhash)
195 #cpu, cpu Current CPU (raw_smp_processor_id())
196 #vlant, vlant, #vlan_tci, vlan_tci VLAN TCI value (vlan_tx_tag_get(skb))
197 #vlanp, vlanp VLAN present (vlan_tx_tag_present(skb))
199 Further extension details (**) Value
201 #type, type 0 - to us / host
202 1 - to all / broadcast
203 2 - to group / multicast
204 3 - to others (promiscuous mode)
205 4 - outgoing of any type
207 #hat, hat, #hatype, hatype 1 - Ethernet 10Mbps
210 24 - IEEE 1394 IPv4 - RFC 2734
214 772 - Loopback device
218 802 - IEEE 802.11 + Prism2 header
219 803 - IEEE 802.11 + radiotap header
222 [...] See include/uapi/linux/if_arp.h
224 Note that the majority of BPF extensions are available on Linux only.
226 There are two types of comments in bpfc source-files:
228 1. Multi-line C-style comments: /* put comment here */
229 2. Single-line ASM-style comments: ; put comment here
233 BHW: byte, half-word, or word
237 In this section, we give a couple of examples of bpfc source files, in other
238 words, some small example filter programs:
240 .B Only return packet headers (truncate packets):
245 .B Only allow ARP packets:
252 .B Only allow IPv4 TCP packets:
261 .B Only allow IPv4 TCP SSH traffic:
269 ldxb 4 * ([14] & 0xf)
277 .B A loadable x86_64 seccomp-BPF filter to allow a given set of syscalls:
279 ld [4] /* offsetof(struct seccomp_data, arch) */
280 jne #0xc000003e, bad /* AUDIT_ARCH_X86_64 */
281 ld [0] /* offsetof(struct seccomp_data, nr) */
282 jeq #15, good /* __NR_rt_sigreturn */
283 jeq #231, good /* __NR_exit_group */
284 jeq #60, good /* __NR_exit */
285 jeq #0, good /* __NR_read */
286 jeq #1, good /* __NR_write */
287 jeq #5, good /* __NR_fstat */
288 jeq #9, good /* __NR_mmap */
289 jeq #14, good /* __NR_rt_sigprocmask */
290 jeq #13, good /* __NR_rt_sigaction */
291 jeq #35, good /* __NR_nanosleep */
292 bad: ret #0 /* SECCOMP_RET_KILL */
293 good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */
295 .B Allow any (hardware accelerated) VLAN:
302 .B Only allow traffic for (hardware accelerated) VLAN 10:
309 .B More pedantic check for the above VLAN example:
318 .B Filter rtnetlink messages:
320 ldh #proto /* A = skb->protocol */
322 jneq #0, skip /* check for NETLINK_ROUTE */
323 ldb [4] /* A = nlmsg_type */
325 jneq #0x10, skip /* check type == RTNL_NEWLINK */
326 ldx #16 /* X = offset(ifinfomsg) */
328 ldb [x + 4] /* offset(ifi_index) */
329 jneq #0x3, skip /* check ifindex == 3 */
331 ld #32 /* A = len(nlmsghdr) + len(ifinfomsg), payload offset */
332 ldx #16 /* X = IFLA_OPERSTATE */
333 ld #nla /* A = offset(IFLA_OPERSTATE) */
336 ldb [x + 4] /* A = value(IFLA_OPERSTATE) */
337 jneq #0x6, skip /* check oper state is UP */
345 Compile the source file ''fubar'' into BPF opcodes. Opcodes will be
348 .B bpfc -f xt_bpf -b -p -i fubar, resp. iptables -A INPUT -m bpf --bytecode "`bpfc -f xt_bpf -i fubar`" -j LOG
349 Compile the source file ''fubar'' into BPF opcodes, bypass basic filter
350 validation and emit opcodes in netfilter's xt_bpf readable format. Note
351 that the source file ''fubar'' is first passed to the C preprocessor for
352 textual replacements before handing over to the bpfc compiler.
354 .B cat fubar | bpfc -
355 Read bpfc instruction from stdin and emit opcodes to stdout.
357 .B bpfc foo > bar && netsniff-ng -f bar ...
358 Compile filter instructions from file foo and redirect bpfc's output into
359 the file bar, that can then be read by
361 through option \fB-f\fP.
363 .B bpfc -f tcpdump -i fubar
364 Output opcodes from source file fubar in the same behavior as ''tcpdump \-ddd''.
367 bpfc is licensed under the GNU GPL version 2.0.
371 was originally written for the netsniff-ng toolkit by Daniel Borkmann. It
372 is currently maintained by Tobias Klauser <tklauser@distanz.ch> and Daniel
373 Borkmann <dborkma@tik.ee.ethz.ch>.
381 .BR astraceroute (8),
385 Manpage was written by Daniel Borkmann.
388 This page is part of the Linux netsniff-ng toolkit project. A description of the project,
389 and information about reporting bugs, can be found at http://netsniff-ng.org/.