bpf: dump Linux specific arguments
[netsniff-ng.git] / src / bpf.c
blob9b7193eeef820247e08cbd1afdcca90eee7dc183
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Copyright 2009, 2010 Emmanuel Roullit.
6 * Copyright 1990-1996 The Regents of the University of
7 * California. All rights reserved. (3-clause BSD license)
8 * Subject to the GPL, version 2.
9 */
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <arpa/inet.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
18 #include "bpf.h"
19 #include "xmalloc.h"
20 #include "xutils.h"
21 #include "die.h"
23 /* This is a bug in libpcap, they actually use 'unsigned long' instead
24 * of short! */
25 #define EXTRACT_SHORT(packet) \
26 ((unsigned short) ntohs(*(unsigned short *) packet))
27 #define EXTRACT_LONG(packet) \
28 (ntohl(*(unsigned long *) packet))
29 #ifndef BPF_MEMWORDS
30 # define BPF_MEMWORDS 16
31 #endif
33 static const char *op_table[] = {
34 [BPF_LD | BPF_B] = "ldb",
35 [BPF_LD | BPF_H] = "ldh",
36 [BPF_LD | BPF_W] = "ld",
37 [BPF_LDX ] = "ldx",
38 [BPF_LDX | BPF_B] = "ldxb",
39 [BPF_ST] = "st",
40 [BPF_STX] = "stx",
41 [BPF_JMP | BPF_JA] = "ja",
42 [BPF_JMP | BPF_JEQ] = "jeq",
43 [BPF_JMP | BPF_JGT] = "jgt",
44 [BPF_JMP | BPF_JGE] = "jge",
45 [BPF_JMP | BPF_JSET] = "jset",
46 [BPF_ALU | BPF_ADD] = "add",
47 [BPF_ALU | BPF_SUB] = "sub",
48 [BPF_ALU | BPF_MUL] = "mul",
49 [BPF_ALU | BPF_DIV] = "div",
50 [BPF_ALU | BPF_MOD] = "mod",
51 [BPF_ALU | BPF_AND] = "and",
52 [BPF_ALU | BPF_OR] = "or",
53 [BPF_ALU | BPF_LSH] = "lsh",
54 [BPF_ALU | BPF_RSH] = "rsh",
55 [BPF_RET] = "ret",
56 [BPF_MISC | BPF_TAX] = "tax",
57 [BPF_MISC | BPF_TXA] = "txa",
60 void bpf_dump_op_table(void)
62 int i;
63 for (i = 0; i < array_size(op_table); ++i) {
64 if (op_table[i])
65 printf("%s\n", op_table[i]);
69 static const char *bpf_dump_linux_k(uint32_t k)
71 switch (k) {
72 default:
73 return "[%d]";
74 /* Linux specific arguments */
75 case SKF_AD_OFF + SKF_AD_PROTOCOL:
76 return "#proto";
77 case SKF_AD_OFF + SKF_AD_PKTTYPE:
78 return "#type";
79 case SKF_AD_OFF + SKF_AD_IFINDEX:
80 return "#ifidx";
81 case SKF_AD_OFF + SKF_AD_NLATTR:
82 return "#nla";
83 case SKF_AD_OFF + SKF_AD_NLATTR_NEST:
84 return "#nlan";
85 case SKF_AD_OFF + SKF_AD_MARK:
86 return "#mark";
87 case SKF_AD_OFF + SKF_AD_QUEUE:
88 return "#queue";
89 case SKF_AD_OFF + SKF_AD_HATYPE:
90 return "#hatype";
91 case SKF_AD_OFF + SKF_AD_RXHASH:
92 return "#rxhash";
93 case SKF_AD_OFF + SKF_AD_CPU:
94 return "#cpu";
98 static char *bpf_dump(const struct sock_filter bpf, int n)
100 int v;
101 const char *fmt, *op;
102 static char image[256];
103 char operand[64];
105 v = bpf.k;
106 switch (bpf.code) {
107 default:
108 op = "unimp";
109 fmt = "0x%x";
110 v = bpf.code;
111 break;
112 case BPF_RET | BPF_K:
113 op = op_table[BPF_RET];
114 fmt = "#0x%x";
115 break;
116 case BPF_RET | BPF_A:
117 op = op_table[BPF_RET];
118 fmt = "";
119 break;
120 case BPF_LD | BPF_W | BPF_ABS:
121 op = op_table[BPF_LD | BPF_W];
122 fmt = bpf_dump_linux_k(bpf.k);
123 break;
124 case BPF_LD | BPF_H | BPF_ABS:
125 op = op_table[BPF_LD | BPF_H];
126 fmt = bpf_dump_linux_k(bpf.k);
127 break;
128 case BPF_LD | BPF_B | BPF_ABS:
129 op = op_table[BPF_LD | BPF_B];
130 fmt = bpf_dump_linux_k(bpf.k);
131 break;
132 case BPF_LD | BPF_W | BPF_LEN:
133 op = op_table[BPF_LD | BPF_W];
134 fmt = "#len";
135 break;
136 case BPF_LD | BPF_W | BPF_IND:
137 op = op_table[BPF_LD | BPF_W];
138 fmt = "[x + %d]";
139 break;
140 case BPF_LD | BPF_H | BPF_IND:
141 op = op_table[BPF_LD | BPF_H];
142 fmt = "[x + %d]";
143 break;
144 case BPF_LD | BPF_B | BPF_IND:
145 op = op_table[BPF_LD | BPF_B];
146 fmt = "[x + %d]";
147 break;
148 case BPF_LD | BPF_IMM:
149 op = op_table[BPF_LD | BPF_W];
150 fmt = "#0x%x";
151 break;
152 case BPF_LDX | BPF_IMM:
153 op = op_table[BPF_LDX];
154 fmt = "#0x%x";
155 break;
156 case BPF_LDX | BPF_B | BPF_MSH:
157 op = op_table[BPF_LDX | BPF_B];
158 fmt = "4*([%d]&0xf)";
159 break;
160 case BPF_LD | BPF_MEM:
161 op = op_table[BPF_LD | BPF_W];
162 fmt = "M[%d]";
163 break;
164 case BPF_LDX | BPF_MEM:
165 op = op_table[BPF_LDX];
166 fmt = "M[%d]";
167 break;
168 case BPF_ST:
169 op = op_table[BPF_ST];
170 fmt = "M[%d]";
171 break;
172 case BPF_STX:
173 op = op_table[BPF_STX];
174 fmt = "M[%d]";
175 break;
176 case BPF_JMP | BPF_JA:
177 op = op_table[BPF_JMP | BPF_JA];
178 fmt = "%d";
179 v = n + 1 + bpf.k;
180 break;
181 case BPF_JMP | BPF_JGT | BPF_K:
182 op = op_table[BPF_JMP | BPF_JGT];
183 fmt = "#0x%x";
184 break;
185 case BPF_JMP | BPF_JGE | BPF_K:
186 op = op_table[BPF_JMP | BPF_JGE];
187 fmt = "#0x%x";
188 break;
189 case BPF_JMP | BPF_JEQ | BPF_K:
190 op = op_table[BPF_JMP | BPF_JEQ];
191 fmt = "#0x%x";
192 break;
193 case BPF_JMP | BPF_JSET | BPF_K:
194 op = op_table[BPF_JMP | BPF_JSET];
195 fmt = "#0x%x";
196 break;
197 case BPF_JMP | BPF_JGT | BPF_X:
198 op = op_table[BPF_JMP | BPF_JGT];
199 fmt = "x";
200 break;
201 case BPF_JMP | BPF_JGE | BPF_X:
202 op = op_table[BPF_JMP | BPF_JGE];
203 fmt = "x";
204 break;
205 case BPF_JMP | BPF_JEQ | BPF_X:
206 op = op_table[BPF_JMP | BPF_JEQ];
207 fmt = "x";
208 break;
209 case BPF_JMP | BPF_JSET | BPF_X:
210 op = op_table[BPF_JMP | BPF_JSET];
211 fmt = "x";
212 break;
213 case BPF_ALU | BPF_ADD | BPF_X:
214 op = op_table[BPF_ALU | BPF_ADD];
215 fmt = "x";
216 break;
217 case BPF_ALU | BPF_SUB | BPF_X:
218 op = op_table[BPF_ALU | BPF_SUB];
219 fmt = "x";
220 break;
221 case BPF_ALU | BPF_MUL | BPF_X:
222 op = op_table[BPF_ALU | BPF_MUL];
223 fmt = "x";
224 break;
225 case BPF_ALU | BPF_DIV | BPF_X:
226 op = op_table[BPF_ALU | BPF_DIV];
227 fmt = "x";
228 break;
229 case BPF_ALU | BPF_MOD | BPF_X:
230 op = op_table[BPF_ALU | BPF_MOD];
231 fmt = "x";
232 break;
233 case BPF_ALU | BPF_AND | BPF_X:
234 op = op_table[BPF_ALU | BPF_AND];
235 fmt = "x";
236 break;
237 case BPF_ALU | BPF_OR | BPF_X:
238 op = op_table[BPF_ALU | BPF_OR];
239 fmt = "x";
240 break;
241 case BPF_ALU | BPF_LSH | BPF_X:
242 op = op_table[BPF_ALU | BPF_LSH];
243 fmt = "x";
244 break;
245 case BPF_ALU | BPF_RSH | BPF_X:
246 op = op_table[BPF_ALU | BPF_RSH];
247 fmt = "x";
248 break;
249 case BPF_ALU | BPF_ADD | BPF_K:
250 op = op_table[BPF_ALU | BPF_ADD];
251 fmt = "#%d";
252 break;
253 case BPF_ALU | BPF_SUB | BPF_K:
254 op = op_table[BPF_ALU | BPF_SUB];
255 fmt = "#%d";
256 break;
257 case BPF_ALU | BPF_MUL | BPF_K:
258 op = op_table[BPF_ALU | BPF_MUL];
259 fmt = "#%d";
260 break;
261 case BPF_ALU | BPF_DIV | BPF_K:
262 op = op_table[BPF_ALU | BPF_DIV];
263 fmt = "#%d";
264 break;
265 case BPF_ALU | BPF_MOD | BPF_K:
266 op = op_table[BPF_ALU | BPF_MOD];
267 fmt = "#%d";
268 break;
269 case BPF_ALU | BPF_AND | BPF_K:
270 op = op_table[BPF_ALU | BPF_AND];
271 fmt = "#0x%x";
272 break;
273 case BPF_ALU | BPF_OR | BPF_K:
274 op = op_table[BPF_ALU | BPF_OR];
275 fmt = "#0x%x";
276 break;
277 case BPF_ALU | BPF_LSH | BPF_K:
278 op = op_table[BPF_ALU | BPF_LSH];
279 fmt = "#%d";
280 break;
281 case BPF_ALU | BPF_RSH | BPF_K:
282 op = op_table[BPF_ALU | BPF_RSH];
283 fmt = "#%d";
284 break;
285 case BPF_ALU | BPF_NEG:
286 op = op_table[BPF_ALU | BPF_NEG];
287 fmt = "";
288 break;
289 case BPF_MISC | BPF_TAX:
290 op = op_table[BPF_MISC | BPF_TAX];
291 fmt = "";
292 break;
293 case BPF_MISC | BPF_TXA:
294 op = op_table[BPF_MISC | BPF_TXA];
295 fmt = "";
296 break;
299 slprintf(operand, sizeof(operand), fmt, v);
300 slprintf(image, sizeof(image),
301 (BPF_CLASS(bpf.code) == BPF_JMP &&
302 BPF_OP(bpf.code) != BPF_JA) ?
303 " L%d: %s %s, L%d, L%d" : " L%d: %s %s",
304 n, op, operand, n + 1 + bpf.jt, n + 1 + bpf.jf);
306 return image;
309 void bpf_dump_all(struct sock_fprog *bpf)
311 int i;
312 for (i = 0; i < bpf->len; ++i)
313 printf("%s\n", bpf_dump(bpf->filter[i], i));
316 void bpf_attach_to_sock(int sock, struct sock_fprog *bpf)
318 int ret;
320 if (bpf->len == 1)
321 if (bpf->filter[0].code == BPF_RET &&
322 bpf->filter[0].k == 0xFFFFFFFF)
323 return;
325 ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, bpf, sizeof(*bpf));
326 if (ret < 0)
327 panic("Cannot attach filter to socket!\n");
330 void bpf_detach_from_sock(int sock)
332 int ret, empty = 0;
334 ret = setsockopt(sock, SOL_SOCKET, SO_DETACH_FILTER, &empty,
335 sizeof(empty));
336 if (ret < 0)
337 panic("Cannot detach filter from socket!\n");
340 void enable_kernel_bpf_jit_compiler(void)
342 int fd;
343 ssize_t ret;
344 char *file = "/proc/sys/net/core/bpf_jit_enable";
346 fd = open(file, O_WRONLY);
347 if (fd < 0)
348 return;
350 ret = write(fd, "1", strlen("1"));
351 if (ret > 0)
352 printf("BPF JIT\n");
354 close(fd);
357 int bpf_validate(const struct sock_fprog *bpf)
359 uint32_t i, from;
360 const struct sock_filter *p;
362 if (!bpf)
363 return 0;
364 if (bpf->len < 1)
365 return 0;
367 for (i = 0; i < bpf->len; ++i) {
368 p = &bpf->filter[i];
369 switch (BPF_CLASS(p->code)) {
371 * Check that memory operations use valid addresses.
373 case BPF_LD:
374 case BPF_LDX:
375 switch (BPF_MODE(p->code)) {
376 case BPF_IMM:
377 break;
378 case BPF_ABS:
379 case BPF_IND:
380 case BPF_MSH:
382 * There's no maximum packet data size
383 * in userland. The runtime packet length
384 * check suffices.
386 break;
387 case BPF_MEM:
388 if (p->k >= BPF_MEMWORDS)
389 return 0;
390 break;
391 case BPF_LEN:
392 break;
393 default:
394 return 0;
396 break;
397 case BPF_ST:
398 case BPF_STX:
399 if (p->k >= BPF_MEMWORDS)
400 return 0;
401 break;
402 case BPF_ALU:
403 switch (BPF_OP(p->code)) {
404 case BPF_ADD:
405 case BPF_SUB:
406 case BPF_MUL:
407 case BPF_OR:
408 case BPF_AND:
409 case BPF_LSH:
410 case BPF_RSH:
411 case BPF_NEG:
412 break;
413 case BPF_DIV:
414 case BPF_MOD:
415 /* Check for constant division by 0 (undefined
416 * for div and mod).
418 if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
419 return 0;
420 break;
421 default:
422 return 0;
424 break;
425 case BPF_JMP:
427 * Check that jumps are within the code block,
428 * and that unconditional branches don't go
429 * backwards as a result of an overflow.
430 * Unconditional branches have a 32-bit offset,
431 * so they could overflow; we check to make
432 * sure they don't. Conditional branches have
433 * an 8-bit offset, and the from address is <=
434 * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
435 * is sufficiently small that adding 255 to it
436 * won't overflow.
438 * We know that len is <= BPF_MAXINSNS, and we
439 * assume that BPF_MAXINSNS is < the maximum size
440 * of a u_int, so that i + 1 doesn't overflow.
442 * For userland, we don't know that the from
443 * or len are <= BPF_MAXINSNS, but we know that
444 * from <= len, and, except on a 64-bit system,
445 * it's unlikely that len, if it truly reflects
446 * the size of the program we've been handed,
447 * will be anywhere near the maximum size of
448 * a u_int. We also don't check for backward
449 * branches, as we currently support them in
450 * userland for the protochain operation.
452 from = i + 1;
453 switch (BPF_OP(p->code)) {
454 case BPF_JA:
455 if (from + p->k >= bpf->len)
456 return 0;
457 break;
458 case BPF_JEQ:
459 case BPF_JGT:
460 case BPF_JGE:
461 case BPF_JSET:
462 if (from + p->jt >= bpf->len ||
463 from + p->jf >= bpf->len)
464 return 0;
465 break;
466 default:
467 return 0;
469 break;
470 case BPF_RET:
471 break;
472 case BPF_MISC:
473 break;
474 default:
475 return 0;
479 return BPF_CLASS(bpf->filter[bpf->len - 1].code) == BPF_RET;
482 uint32_t bpf_run_filter(const struct sock_fprog * fcode, uint8_t * packet,
483 size_t plen)
485 /* XXX: caplen == len */
486 uint32_t A, X;
487 uint32_t k;
488 struct sock_filter *bpf;
489 int32_t mem[BPF_MEMWORDS];
491 if (fcode == NULL || fcode->filter == NULL || fcode->len == 0)
492 return 0xFFFFFFFF;
494 A = 0;
495 X = 0;
497 bpf = fcode->filter;
498 --bpf;
500 while (1) {
501 ++bpf;
503 switch (bpf->code) {
504 default:
505 return 0;
506 case BPF_RET | BPF_K:
507 return (uint32_t) bpf->k;
508 case BPF_RET | BPF_A:
509 return (uint32_t) A;
510 case BPF_LD | BPF_W | BPF_ABS:
511 k = bpf->k;
512 if (k + sizeof(int32_t) > plen)
513 return 0;
514 A = EXTRACT_LONG(&packet[k]);
515 continue;
516 case BPF_LD | BPF_H | BPF_ABS:
517 k = bpf->k;
518 if (k + sizeof(short) > plen)
519 return 0;
520 A = EXTRACT_SHORT(&packet[k]);
521 continue;
522 case BPF_LD | BPF_B | BPF_ABS:
523 k = bpf->k;
524 if (k >= plen)
525 return 0;
526 A = packet[k];
527 continue;
528 case BPF_LD | BPF_W | BPF_LEN:
529 A = plen;
530 continue;
531 case BPF_LDX | BPF_W | BPF_LEN:
532 X = plen;
533 continue;
534 case BPF_LD | BPF_W | BPF_IND:
535 k = X + bpf->k;
536 if (k + sizeof(int32_t) > plen)
537 return 0;
538 A = EXTRACT_LONG(&packet[k]);
539 continue;
540 case BPF_LD | BPF_H | BPF_IND:
541 k = X + bpf->k;
542 if (k + sizeof(short) > plen)
543 return 0;
544 A = EXTRACT_SHORT(&packet[k]);
545 continue;
546 case BPF_LD | BPF_B | BPF_IND:
547 k = X + bpf->k;
548 if (k >= plen)
549 return 0;
550 A = packet[k];
551 continue;
552 case BPF_LDX | BPF_MSH | BPF_B:
553 k = bpf->k;
554 if (k >= plen)
555 return 0;
556 X = (packet[bpf->k] & 0xf) << 2;
557 continue;
558 case BPF_LD | BPF_IMM:
559 A = bpf->k;
560 continue;
561 case BPF_LDX | BPF_IMM:
562 X = bpf->k;
563 continue;
564 case BPF_LD | BPF_MEM:
565 A = mem[bpf->k];
566 continue;
567 case BPF_LDX | BPF_MEM:
568 X = mem[bpf->k];
569 continue;
570 case BPF_ST:
571 mem[bpf->k] = A;
572 continue;
573 case BPF_STX:
574 mem[bpf->k] = X;
575 continue;
576 case BPF_JMP | BPF_JA:
577 bpf += bpf->k;
578 continue;
579 case BPF_JMP | BPF_JGT | BPF_K:
580 bpf += (A > bpf->k) ? bpf->jt : bpf->jf;
581 continue;
582 case BPF_JMP | BPF_JGE | BPF_K:
583 bpf += (A >= bpf->k) ? bpf->jt : bpf->jf;
584 continue;
585 case BPF_JMP | BPF_JEQ | BPF_K:
586 bpf += (A == bpf->k) ? bpf->jt : bpf->jf;
587 continue;
588 case BPF_JMP | BPF_JSET | BPF_K:
589 bpf += (A & bpf->k) ? bpf->jt : bpf->jf;
590 continue;
591 case BPF_JMP | BPF_JGT | BPF_X:
592 bpf += (A > X) ? bpf->jt : bpf->jf;
593 continue;
594 case BPF_JMP | BPF_JGE | BPF_X:
595 bpf += (A >= X) ? bpf->jt : bpf->jf;
596 continue;
597 case BPF_JMP | BPF_JEQ | BPF_X:
598 bpf += (A == X) ? bpf->jt : bpf->jf;
599 continue;
600 case BPF_JMP | BPF_JSET | BPF_X:
601 bpf += (A & X) ? bpf->jt : bpf->jf;
602 continue;
603 case BPF_ALU | BPF_ADD | BPF_X:
604 A += X;
605 continue;
606 case BPF_ALU | BPF_SUB | BPF_X:
607 A -= X;
608 continue;
609 case BPF_ALU | BPF_MUL | BPF_X:
610 A *= X;
611 continue;
612 case BPF_ALU | BPF_DIV | BPF_X:
613 if (X == 0)
614 return 0;
615 A /= X;
616 continue;
617 case BPF_ALU | BPF_MOD | BPF_X:
618 if (X == 0)
619 return 0;
620 A %= X;
621 continue;
622 case BPF_ALU | BPF_AND | BPF_X:
623 A &= X;
624 continue;
625 case BPF_ALU | BPF_OR | BPF_X:
626 A |= X;
627 continue;
628 case BPF_ALU | BPF_LSH | BPF_X:
629 A <<= X;
630 continue;
631 case BPF_ALU | BPF_RSH | BPF_X:
632 A >>= X;
633 continue;
634 case BPF_ALU | BPF_ADD | BPF_K:
635 A += bpf->k;
636 continue;
637 case BPF_ALU | BPF_SUB | BPF_K:
638 A -= bpf->k;
639 continue;
640 case BPF_ALU | BPF_MUL | BPF_K:
641 A *= bpf->k;
642 continue;
643 case BPF_ALU | BPF_DIV | BPF_K:
644 A /= bpf->k;
645 continue;
646 case BPF_ALU | BPF_MOD | BPF_K:
647 A %= bpf->k;
648 continue;
649 case BPF_ALU | BPF_AND | BPF_K:
650 A &= bpf->k;
651 continue;
652 case BPF_ALU | BPF_OR | BPF_K:
653 A |= bpf->k;
654 continue;
655 case BPF_ALU | BPF_LSH | BPF_K:
656 A <<= bpf->k;
657 continue;
658 case BPF_ALU | BPF_RSH | BPF_K:
659 A >>= bpf->k;
660 continue;
661 case BPF_ALU | BPF_NEG:
662 A = -A;
663 continue;
664 case BPF_MISC | BPF_TAX:
665 X = A;
666 continue;
667 case BPF_MISC | BPF_TXA:
668 A = X;
669 continue;
674 void bpf_parse_rules(char *rulefile, struct sock_fprog *bpf)
676 int ret;
677 char buff[256];
678 struct sock_filter sf_single = { 0x06, 0, 0, 0xFFFFFFFF };
679 FILE *fp;
681 if (rulefile == NULL) {
682 bpf->len = 1;
683 bpf->filter = xmalloc(sizeof(sf_single));
684 fmemcpy(&bpf->filter[0], &sf_single, sizeof(sf_single));
685 return;
688 fp = fopen(rulefile, "r");
689 if (!fp)
690 panic("Cannot read BPF rule file!\n");
692 fmemset(buff, 0, sizeof(buff));
693 while (fgets(buff, sizeof(buff), fp) != NULL) {
694 buff[sizeof(buff) - 1] = 0;
695 if (buff[0] != '{') {
696 fmemset(buff, 0, sizeof(buff));
697 continue;
700 fmemset(&sf_single, 0, sizeof(sf_single));
701 ret = sscanf(buff, "{ 0x%x, %u, %u, 0x%08x },",
702 (unsigned int *) &sf_single.code,
703 (unsigned int *) &sf_single.jt,
704 (unsigned int *) &sf_single.jf,
705 (unsigned int *) &sf_single.k);
706 if (ret != 4)
707 panic("BPF syntax error!\n");
708 bpf->len++;
709 bpf->filter = xrealloc(bpf->filter, 1,
710 bpf->len * sizeof(sf_single));
711 fmemcpy(&bpf->filter[bpf->len - 1], &sf_single,
712 sizeof(sf_single));
714 fmemset(buff, 0, sizeof(buff));
717 fclose(fp);
718 if (bpf_validate(bpf) == 0)
719 panic("This is not a valid BPF program!\n");