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