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 const char *op_table
[] = {
34 [BPF_LD
| BPF_B
] = "ldb",
35 [BPF_LD
| BPF_H
] = "ldh",
36 [BPF_LD
| BPF_W
] = "ld",
38 [BPF_LDX
| BPF_B
] = "ldxb",
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",
56 [BPF_MISC
| BPF_TAX
] = "tax",
57 [BPF_MISC
| BPF_TXA
] = "txa",
60 void bpf_dump_op_table(void)
63 for (i
= 0; i
< array_size(op_table
); ++i
) {
65 printf("%s\n", op_table
[i
]);
69 static const char *bpf_dump_linux_k(uint32_t k
)
74 /* Linux specific arguments */
75 case SKF_AD_OFF
+ SKF_AD_PROTOCOL
:
77 case SKF_AD_OFF
+ SKF_AD_PKTTYPE
:
79 case SKF_AD_OFF
+ SKF_AD_IFINDEX
:
81 case SKF_AD_OFF
+ SKF_AD_NLATTR
:
83 case SKF_AD_OFF
+ SKF_AD_NLATTR_NEST
:
85 case SKF_AD_OFF
+ SKF_AD_MARK
:
87 case SKF_AD_OFF
+ SKF_AD_QUEUE
:
89 case SKF_AD_OFF
+ SKF_AD_HATYPE
:
91 case SKF_AD_OFF
+ SKF_AD_RXHASH
:
93 case SKF_AD_OFF
+ SKF_AD_CPU
:
98 static char *bpf_dump(const struct sock_filter bpf
, int n
)
101 const char *fmt
, *op
;
102 static char image
[256];
112 case BPF_RET
| BPF_K
:
113 op
= op_table
[BPF_RET
];
116 case BPF_RET
| BPF_A
:
117 op
= op_table
[BPF_RET
];
120 case BPF_LD
| BPF_W
| BPF_ABS
:
121 op
= op_table
[BPF_LD
| BPF_W
];
122 fmt
= bpf_dump_linux_k(bpf
.k
);
124 case BPF_LD
| BPF_H
| BPF_ABS
:
125 op
= op_table
[BPF_LD
| BPF_H
];
126 fmt
= bpf_dump_linux_k(bpf
.k
);
128 case BPF_LD
| BPF_B
| BPF_ABS
:
129 op
= op_table
[BPF_LD
| BPF_B
];
130 fmt
= bpf_dump_linux_k(bpf
.k
);
132 case BPF_LD
| BPF_W
| BPF_LEN
:
133 op
= op_table
[BPF_LD
| BPF_W
];
136 case BPF_LD
| BPF_W
| BPF_IND
:
137 op
= op_table
[BPF_LD
| BPF_W
];
140 case BPF_LD
| BPF_H
| BPF_IND
:
141 op
= op_table
[BPF_LD
| BPF_H
];
144 case BPF_LD
| BPF_B
| BPF_IND
:
145 op
= op_table
[BPF_LD
| BPF_B
];
148 case BPF_LD
| BPF_IMM
:
149 op
= op_table
[BPF_LD
| BPF_W
];
152 case BPF_LDX
| BPF_IMM
:
153 op
= op_table
[BPF_LDX
];
156 case BPF_LDX
| BPF_B
| BPF_MSH
:
157 op
= op_table
[BPF_LDX
| BPF_B
];
158 fmt
= "4*([%d]&0xf)";
160 case BPF_LD
| BPF_MEM
:
161 op
= op_table
[BPF_LD
| BPF_W
];
164 case BPF_LDX
| BPF_MEM
:
165 op
= op_table
[BPF_LDX
];
169 op
= op_table
[BPF_ST
];
173 op
= op_table
[BPF_STX
];
176 case BPF_JMP
| BPF_JA
:
177 op
= op_table
[BPF_JMP
| BPF_JA
];
181 case BPF_JMP
| BPF_JGT
| BPF_K
:
182 op
= op_table
[BPF_JMP
| BPF_JGT
];
185 case BPF_JMP
| BPF_JGE
| BPF_K
:
186 op
= op_table
[BPF_JMP
| BPF_JGE
];
189 case BPF_JMP
| BPF_JEQ
| BPF_K
:
190 op
= op_table
[BPF_JMP
| BPF_JEQ
];
193 case BPF_JMP
| BPF_JSET
| BPF_K
:
194 op
= op_table
[BPF_JMP
| BPF_JSET
];
197 case BPF_JMP
| BPF_JGT
| BPF_X
:
198 op
= op_table
[BPF_JMP
| BPF_JGT
];
201 case BPF_JMP
| BPF_JGE
| BPF_X
:
202 op
= op_table
[BPF_JMP
| BPF_JGE
];
205 case BPF_JMP
| BPF_JEQ
| BPF_X
:
206 op
= op_table
[BPF_JMP
| BPF_JEQ
];
209 case BPF_JMP
| BPF_JSET
| BPF_X
:
210 op
= op_table
[BPF_JMP
| BPF_JSET
];
213 case BPF_ALU
| BPF_ADD
| BPF_X
:
214 op
= op_table
[BPF_ALU
| BPF_ADD
];
217 case BPF_ALU
| BPF_SUB
| BPF_X
:
218 op
= op_table
[BPF_ALU
| BPF_SUB
];
221 case BPF_ALU
| BPF_MUL
| BPF_X
:
222 op
= op_table
[BPF_ALU
| BPF_MUL
];
225 case BPF_ALU
| BPF_DIV
| BPF_X
:
226 op
= op_table
[BPF_ALU
| BPF_DIV
];
229 case BPF_ALU
| BPF_MOD
| BPF_X
:
230 op
= op_table
[BPF_ALU
| BPF_MOD
];
233 case BPF_ALU
| BPF_AND
| BPF_X
:
234 op
= op_table
[BPF_ALU
| BPF_AND
];
237 case BPF_ALU
| BPF_OR
| BPF_X
:
238 op
= op_table
[BPF_ALU
| BPF_OR
];
241 case BPF_ALU
| BPF_LSH
| BPF_X
:
242 op
= op_table
[BPF_ALU
| BPF_LSH
];
245 case BPF_ALU
| BPF_RSH
| BPF_X
:
246 op
= op_table
[BPF_ALU
| BPF_RSH
];
249 case BPF_ALU
| BPF_ADD
| BPF_K
:
250 op
= op_table
[BPF_ALU
| BPF_ADD
];
253 case BPF_ALU
| BPF_SUB
| BPF_K
:
254 op
= op_table
[BPF_ALU
| BPF_SUB
];
257 case BPF_ALU
| BPF_MUL
| BPF_K
:
258 op
= op_table
[BPF_ALU
| BPF_MUL
];
261 case BPF_ALU
| BPF_DIV
| BPF_K
:
262 op
= op_table
[BPF_ALU
| BPF_DIV
];
265 case BPF_ALU
| BPF_MOD
| BPF_K
:
266 op
= op_table
[BPF_ALU
| BPF_MOD
];
269 case BPF_ALU
| BPF_AND
| BPF_K
:
270 op
= op_table
[BPF_ALU
| BPF_AND
];
273 case BPF_ALU
| BPF_OR
| BPF_K
:
274 op
= op_table
[BPF_ALU
| BPF_OR
];
277 case BPF_ALU
| BPF_LSH
| BPF_K
:
278 op
= op_table
[BPF_ALU
| BPF_LSH
];
281 case BPF_ALU
| BPF_RSH
| BPF_K
:
282 op
= op_table
[BPF_ALU
| BPF_RSH
];
285 case BPF_ALU
| BPF_NEG
:
286 op
= op_table
[BPF_ALU
| BPF_NEG
];
289 case BPF_MISC
| BPF_TAX
:
290 op
= op_table
[BPF_MISC
| BPF_TAX
];
293 case BPF_MISC
| BPF_TXA
:
294 op
= op_table
[BPF_MISC
| BPF_TXA
];
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
);
309 void bpf_dump_all(struct sock_fprog
*bpf
)
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
)
321 if (bpf
->filter
[0].code
== BPF_RET
&&
322 bpf
->filter
[0].k
== 0xFFFFFFFF)
325 ret
= setsockopt(sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, bpf
, sizeof(*bpf
));
327 panic("Cannot attach filter to socket!\n");
330 void bpf_detach_from_sock(int sock
)
334 ret
= setsockopt(sock
, SOL_SOCKET
, SO_DETACH_FILTER
, &empty
,
337 panic("Cannot detach filter from socket!\n");
340 void enable_kernel_bpf_jit_compiler(void)
344 char *file
= "/proc/sys/net/core/bpf_jit_enable";
346 fd
= open(file
, O_WRONLY
);
350 ret
= write(fd
, "1", strlen("1"));
357 int bpf_validate(const struct sock_fprog
*bpf
)
360 const struct sock_filter
*p
;
367 for (i
= 0; i
< bpf
->len
; ++i
) {
369 switch (BPF_CLASS(p
->code
)) {
371 * Check that memory operations use valid addresses.
375 switch (BPF_MODE(p
->code
)) {
382 * There's no maximum packet data size
383 * in userland. The runtime packet length
388 if (p
->k
>= BPF_MEMWORDS
)
399 if (p
->k
>= BPF_MEMWORDS
)
403 switch (BPF_OP(p
->code
)) {
415 /* Check for constant division by 0 (undefined
418 if (BPF_RVAL(p
->code
) == BPF_K
&& p
->k
== 0)
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
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.
453 switch (BPF_OP(p
->code
)) {
455 if (from
+ p
->k
>= bpf
->len
)
462 if (from
+ p
->jt
>= bpf
->len
||
463 from
+ p
->jf
>= bpf
->len
)
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
,
485 /* XXX: caplen == len */
488 struct sock_filter
*bpf
;
489 int32_t mem
[BPF_MEMWORDS
];
491 if (fcode
== NULL
|| fcode
->filter
== NULL
|| fcode
->len
== 0)
506 case BPF_RET
| BPF_K
:
507 return (uint32_t) bpf
->k
;
508 case BPF_RET
| BPF_A
:
510 case BPF_LD
| BPF_W
| BPF_ABS
:
512 if (k
+ sizeof(int32_t) > plen
)
514 A
= EXTRACT_LONG(&packet
[k
]);
516 case BPF_LD
| BPF_H
| BPF_ABS
:
518 if (k
+ sizeof(short) > plen
)
520 A
= EXTRACT_SHORT(&packet
[k
]);
522 case BPF_LD
| BPF_B
| BPF_ABS
:
528 case BPF_LD
| BPF_W
| BPF_LEN
:
531 case BPF_LDX
| BPF_W
| BPF_LEN
:
534 case BPF_LD
| BPF_W
| BPF_IND
:
536 if (k
+ sizeof(int32_t) > plen
)
538 A
= EXTRACT_LONG(&packet
[k
]);
540 case BPF_LD
| BPF_H
| BPF_IND
:
542 if (k
+ sizeof(short) > plen
)
544 A
= EXTRACT_SHORT(&packet
[k
]);
546 case BPF_LD
| BPF_B
| BPF_IND
:
552 case BPF_LDX
| BPF_MSH
| BPF_B
:
556 X
= (packet
[bpf
->k
] & 0xf) << 2;
558 case BPF_LD
| BPF_IMM
:
561 case BPF_LDX
| BPF_IMM
:
564 case BPF_LD
| BPF_MEM
:
567 case BPF_LDX
| BPF_MEM
:
576 case BPF_JMP
| BPF_JA
:
579 case BPF_JMP
| BPF_JGT
| BPF_K
:
580 bpf
+= (A
> bpf
->k
) ? bpf
->jt
: bpf
->jf
;
582 case BPF_JMP
| BPF_JGE
| BPF_K
:
583 bpf
+= (A
>= bpf
->k
) ? bpf
->jt
: bpf
->jf
;
585 case BPF_JMP
| BPF_JEQ
| BPF_K
:
586 bpf
+= (A
== bpf
->k
) ? bpf
->jt
: bpf
->jf
;
588 case BPF_JMP
| BPF_JSET
| BPF_K
:
589 bpf
+= (A
& bpf
->k
) ? bpf
->jt
: bpf
->jf
;
591 case BPF_JMP
| BPF_JGT
| BPF_X
:
592 bpf
+= (A
> X
) ? bpf
->jt
: bpf
->jf
;
594 case BPF_JMP
| BPF_JGE
| BPF_X
:
595 bpf
+= (A
>= X
) ? bpf
->jt
: bpf
->jf
;
597 case BPF_JMP
| BPF_JEQ
| BPF_X
:
598 bpf
+= (A
== X
) ? bpf
->jt
: bpf
->jf
;
600 case BPF_JMP
| BPF_JSET
| BPF_X
:
601 bpf
+= (A
& X
) ? bpf
->jt
: bpf
->jf
;
603 case BPF_ALU
| BPF_ADD
| BPF_X
:
606 case BPF_ALU
| BPF_SUB
| BPF_X
:
609 case BPF_ALU
| BPF_MUL
| BPF_X
:
612 case BPF_ALU
| BPF_DIV
| BPF_X
:
617 case BPF_ALU
| BPF_MOD
| BPF_X
:
622 case BPF_ALU
| BPF_AND
| BPF_X
:
625 case BPF_ALU
| BPF_OR
| BPF_X
:
628 case BPF_ALU
| BPF_LSH
| BPF_X
:
631 case BPF_ALU
| BPF_RSH
| BPF_X
:
634 case BPF_ALU
| BPF_ADD
| BPF_K
:
637 case BPF_ALU
| BPF_SUB
| BPF_K
:
640 case BPF_ALU
| BPF_MUL
| BPF_K
:
643 case BPF_ALU
| BPF_DIV
| BPF_K
:
646 case BPF_ALU
| BPF_MOD
| BPF_K
:
649 case BPF_ALU
| BPF_AND
| BPF_K
:
652 case BPF_ALU
| BPF_OR
| BPF_K
:
655 case BPF_ALU
| BPF_LSH
| BPF_K
:
658 case BPF_ALU
| BPF_RSH
| BPF_K
:
661 case BPF_ALU
| BPF_NEG
:
664 case BPF_MISC
| BPF_TAX
:
667 case BPF_MISC
| BPF_TXA
:
674 void bpf_parse_rules(char *rulefile
, struct sock_fprog
*bpf
)
678 struct sock_filter sf_single
= { 0x06, 0, 0, 0xFFFFFFFF };
681 if (rulefile
== NULL
) {
683 bpf
->filter
= xmalloc(sizeof(sf_single
));
684 fmemcpy(&bpf
->filter
[0], &sf_single
, sizeof(sf_single
));
688 fp
= fopen(rulefile
, "r");
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
));
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
);
707 panic("BPF syntax error!\n");
709 bpf
->filter
= xrealloc(bpf
->filter
, 1,
710 bpf
->len
* sizeof(sf_single
));
711 fmemcpy(&bpf
->filter
[bpf
->len
- 1], &sf_single
,
714 fmemset(buff
, 0, sizeof(buff
));
718 if (bpf_validate(bpf
) == 0)
719 panic("This is not a valid BPF program!\n");