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.
13 #include <arpa/inet.h>
14 #include <sys/types.h>
23 /* This is a bug in libpcap, they actually use 'unsigned long' instead
25 #define EXTRACT_SHORT(packet) \
26 ((unsigned short) ntohs(*(unsigned short *) packet))
27 #define EXTRACT_LONG(packet) \
28 (ntohl(*(unsigned long *) packet))
30 # define BPF_MEMWORDS 16
33 static char *bpf_dump(const struct sock_filter bpf
, int n
)
37 static char image
[256];
55 case BPF_LD
| BPF_W
| BPF_ABS
:
59 case BPF_LD
| BPF_H
| BPF_ABS
:
63 case BPF_LD
| BPF_B
| BPF_ABS
:
67 case BPF_LD
| BPF_W
| BPF_LEN
:
71 case BPF_LD
| BPF_W
| BPF_IND
:
75 case BPF_LD
| BPF_H
| BPF_IND
:
79 case BPF_LD
| BPF_B
| BPF_IND
:
83 case BPF_LD
| BPF_IMM
:
87 case BPF_LDX
| BPF_IMM
:
91 case BPF_LDX
| BPF_MSH
| BPF_B
:
95 case BPF_LD
| BPF_MEM
:
99 case BPF_LDX
| BPF_MEM
:
111 case BPF_JMP
| BPF_JA
:
116 case BPF_JMP
| BPF_JGT
| BPF_K
:
120 case BPF_JMP
| BPF_JGE
| BPF_K
:
124 case BPF_JMP
| BPF_JEQ
| BPF_K
:
128 case BPF_JMP
| BPF_JSET
| BPF_K
:
132 case BPF_JMP
| BPF_JGT
| BPF_X
:
136 case BPF_JMP
| BPF_JGE
| BPF_X
:
140 case BPF_JMP
| BPF_JEQ
| BPF_X
:
144 case BPF_JMP
| BPF_JSET
| BPF_X
:
148 case BPF_ALU
| BPF_ADD
| BPF_X
:
152 case BPF_ALU
| BPF_SUB
| BPF_X
:
156 case BPF_ALU
| BPF_MUL
| BPF_X
:
160 case BPF_ALU
| BPF_DIV
| BPF_X
:
164 case BPF_ALU
| BPF_AND
| BPF_X
:
168 case BPF_ALU
| BPF_OR
| BPF_X
:
172 case BPF_ALU
| BPF_LSH
| BPF_X
:
176 case BPF_ALU
| BPF_RSH
| BPF_X
:
180 case BPF_ALU
| BPF_ADD
| BPF_K
:
184 case BPF_ALU
| BPF_SUB
| BPF_K
:
188 case BPF_ALU
| BPF_MUL
| BPF_K
:
192 case BPF_ALU
| BPF_DIV
| BPF_K
:
196 case BPF_ALU
| BPF_AND
| BPF_K
:
200 case BPF_ALU
| BPF_OR
| BPF_K
:
204 case BPF_ALU
| BPF_LSH
| BPF_K
:
208 case BPF_ALU
| BPF_RSH
| BPF_K
:
212 case BPF_ALU
| BPF_NEG
:
216 case BPF_MISC
| BPF_TAX
:
220 case BPF_MISC
| BPF_TXA
:
226 slprintf(operand
, sizeof(operand
), fmt
, v
);
227 slprintf(image
, sizeof(image
),
228 (BPF_CLASS(bpf
.code
) == BPF_JMP
&&
229 BPF_OP(bpf
.code
) != BPF_JA
) ?
230 " L%d: %s %s, L%d, L%d" : " L%d: %s %s",
231 n
, op
, operand
, n
+ 1 + bpf
.jt
, n
+ 1 + bpf
.jf
);
236 void bpf_dump_all(struct sock_fprog
*bpf
)
239 for (i
= 0; i
< bpf
->len
; ++i
)
240 printf("%s\n", bpf_dump(bpf
->filter
[i
], i
));
243 void bpf_attach_to_sock(int sock
, struct sock_fprog
*bpf
)
246 if (bpf
->filter
[0].code
== BPF_RET
&&
247 bpf
->filter
[0].k
== 0xFFFFFFFF)
250 int ret
= setsockopt(sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, bpf
,
253 panic("Cannot attach filter to socket!\n");
256 void bpf_detach_from_sock(int sock
)
260 ret
= setsockopt(sock
, SOL_SOCKET
, SO_DETACH_FILTER
, &empty
,
263 panic("Cannot detach filter from socket!\n");
266 void enable_kernel_bpf_jit_compiler(void)
270 char *file
= "/proc/sys/net/core/bpf_jit_enable";
272 fd
= open(file
, O_WRONLY
);
276 ret
= write(fd
, "1", strlen("1"));
283 int bpf_validate(const struct sock_fprog
*bpf
)
286 const struct sock_filter
*p
;
293 for (i
= 0; i
< bpf
->len
; ++i
) {
295 switch (BPF_CLASS(p
->code
)) {
297 * Check that memory operations use valid addresses.
301 switch (BPF_MODE(p
->code
)) {
308 * There's no maximum packet data size
309 * in userland. The runtime packet length
314 if (p
->k
>= BPF_MEMWORDS
)
325 if (p
->k
>= BPF_MEMWORDS
)
329 switch (BPF_OP(p
->code
)) {
341 * Check for constant division by 0.
343 if (BPF_RVAL(p
->code
) == BPF_K
&& p
->k
== 0)
352 * Check that jumps are within the code block,
353 * and that unconditional branches don't go
354 * backwards as a result of an overflow.
355 * Unconditional branches have a 32-bit offset,
356 * so they could overflow; we check to make
357 * sure they don't. Conditional branches have
358 * an 8-bit offset, and the from address is <=
359 * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
360 * is sufficiently small that adding 255 to it
363 * We know that len is <= BPF_MAXINSNS, and we
364 * assume that BPF_MAXINSNS is < the maximum size
365 * of a u_int, so that i + 1 doesn't overflow.
367 * For userland, we don't know that the from
368 * or len are <= BPF_MAXINSNS, but we know that
369 * from <= len, and, except on a 64-bit system,
370 * it's unlikely that len, if it truly reflects
371 * the size of the program we've been handed,
372 * will be anywhere near the maximum size of
373 * a u_int. We also don't check for backward
374 * branches, as we currently support them in
375 * userland for the protochain operation.
378 switch (BPF_OP(p
->code
)) {
380 if (from
+ p
->k
>= bpf
->len
)
387 if (from
+ p
->jt
>= bpf
->len
||
388 from
+ p
->jf
>= bpf
->len
)
404 return BPF_CLASS(bpf
->filter
[bpf
->len
- 1].code
) == BPF_RET
;
407 uint32_t bpf_run_filter(const struct sock_fprog
* fcode
, uint8_t * packet
,
410 /* XXX: caplen == len */
413 struct sock_filter
*bpf
;
414 int32_t mem
[BPF_MEMWORDS
];
416 if (fcode
== NULL
|| fcode
->filter
== NULL
|| fcode
->len
== 0)
431 case BPF_RET
| BPF_K
:
432 return (uint32_t) bpf
->k
;
433 case BPF_RET
| BPF_A
:
435 case BPF_LD
| BPF_W
| BPF_ABS
:
437 if (k
+ sizeof(int32_t) > plen
)
439 A
= EXTRACT_LONG(&packet
[k
]);
441 case BPF_LD
| BPF_H
| BPF_ABS
:
443 if (k
+ sizeof(short) > plen
)
445 A
= EXTRACT_SHORT(&packet
[k
]);
447 case BPF_LD
| BPF_B
| BPF_ABS
:
453 case BPF_LD
| BPF_W
| BPF_LEN
:
456 case BPF_LDX
| BPF_W
| BPF_LEN
:
459 case BPF_LD
| BPF_W
| BPF_IND
:
461 if (k
+ sizeof(int32_t) > plen
)
463 A
= EXTRACT_LONG(&packet
[k
]);
465 case BPF_LD
| BPF_H
| BPF_IND
:
467 if (k
+ sizeof(short) > plen
)
469 A
= EXTRACT_SHORT(&packet
[k
]);
471 case BPF_LD
| BPF_B
| BPF_IND
:
477 case BPF_LDX
| BPF_MSH
| BPF_B
:
481 X
= (packet
[bpf
->k
] & 0xf) << 2;
483 case BPF_LD
| BPF_IMM
:
486 case BPF_LDX
| BPF_IMM
:
489 case BPF_LD
| BPF_MEM
:
492 case BPF_LDX
| BPF_MEM
:
501 case BPF_JMP
| BPF_JA
:
504 case BPF_JMP
| BPF_JGT
| BPF_K
:
505 bpf
+= (A
> bpf
->k
) ? bpf
->jt
: bpf
->jf
;
507 case BPF_JMP
| BPF_JGE
| BPF_K
:
508 bpf
+= (A
>= bpf
->k
) ? bpf
->jt
: bpf
->jf
;
510 case BPF_JMP
| BPF_JEQ
| BPF_K
:
511 bpf
+= (A
== bpf
->k
) ? bpf
->jt
: bpf
->jf
;
513 case BPF_JMP
| BPF_JSET
| BPF_K
:
514 bpf
+= (A
& bpf
->k
) ? bpf
->jt
: bpf
->jf
;
516 case BPF_JMP
| BPF_JGT
| BPF_X
:
517 bpf
+= (A
> X
) ? bpf
->jt
: bpf
->jf
;
519 case BPF_JMP
| BPF_JGE
| BPF_X
:
520 bpf
+= (A
>= X
) ? bpf
->jt
: bpf
->jf
;
522 case BPF_JMP
| BPF_JEQ
| BPF_X
:
523 bpf
+= (A
== X
) ? bpf
->jt
: bpf
->jf
;
525 case BPF_JMP
| BPF_JSET
| BPF_X
:
526 bpf
+= (A
& X
) ? bpf
->jt
: bpf
->jf
;
528 case BPF_ALU
| BPF_ADD
| BPF_X
:
531 case BPF_ALU
| BPF_SUB
| BPF_X
:
534 case BPF_ALU
| BPF_MUL
| BPF_X
:
537 case BPF_ALU
| BPF_DIV
| BPF_X
:
542 case BPF_ALU
| BPF_AND
| BPF_X
:
545 case BPF_ALU
| BPF_OR
| BPF_X
:
548 case BPF_ALU
| BPF_LSH
| BPF_X
:
551 case BPF_ALU
| BPF_RSH
| BPF_X
:
554 case BPF_ALU
| BPF_ADD
| BPF_K
:
557 case BPF_ALU
| BPF_SUB
| BPF_K
:
560 case BPF_ALU
| BPF_MUL
| BPF_K
:
563 case BPF_ALU
| BPF_DIV
| BPF_K
:
566 case BPF_ALU
| BPF_AND
| BPF_K
:
569 case BPF_ALU
| BPF_OR
| BPF_K
:
572 case BPF_ALU
| BPF_LSH
| BPF_K
:
575 case BPF_ALU
| BPF_RSH
| BPF_K
:
578 case BPF_ALU
| BPF_NEG
:
581 case BPF_MISC
| BPF_TAX
:
584 case BPF_MISC
| BPF_TXA
:
591 void bpf_parse_rules(char *rulefile
, struct sock_fprog
*bpf
)
595 struct sock_filter sf_single
= { 0x06, 0, 0, 0xFFFFFFFF };
598 if (rulefile
== NULL
) {
600 bpf
->filter
= xmalloc(sizeof(sf_single
));
601 fmemcpy(&bpf
->filter
[0], &sf_single
, sizeof(sf_single
));
605 fp
= fopen(rulefile
, "r");
607 panic("Cannot read BPF rule file!\n");
609 fmemset(buff
, 0, sizeof(buff
));
610 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
611 buff
[sizeof(buff
) - 1] = 0;
612 if (buff
[0] != '{') {
613 fmemset(buff
, 0, sizeof(buff
));
617 fmemset(&sf_single
, 0, sizeof(sf_single
));
618 ret
= sscanf(buff
, "{ 0x%x, %u, %u, 0x%08x },",
619 (unsigned int *) &sf_single
.code
,
620 (unsigned int *) &sf_single
.jt
,
621 (unsigned int *) &sf_single
.jf
,
622 (unsigned int *) &sf_single
.k
);
624 panic("BPF syntax error!\n");
626 bpf
->filter
= xrealloc(bpf
->filter
, 1,
627 bpf
->len
* sizeof(sf_single
));
628 fmemcpy(&bpf
->filter
[bpf
->len
- 1], &sf_single
,
631 fmemset(buff
, 0, sizeof(buff
));
635 if (bpf_validate(bpf
) == 0)
636 panic("This is not a valid BPF program!\n");