Fix manpage warnings
[netsniff-ng-new.git] / bpf.c
blob868742b351626e01eac667bb45823c61cd8ad7fd
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009 - 2012 Daniel Borkmann.
4 * Copyright 2009, 2010 Emmanuel Roullit.
5 * Copyright 1990-1996 The Regents of the University of
6 * California. All rights reserved. (3-clause BSD license)
7 * Subject to the GPL, version 2.
8 */
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <string.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 "die.h"
21 #include "str.h"
22 #include "sysctl.h"
24 #define EXTRACT_SHORT(packet) \
25 ((unsigned short) ntohs(*(unsigned short *) packet))
26 #define EXTRACT_LONG(packet) \
27 (ntohl(*(unsigned long *) packet))
29 #ifndef BPF_MEMWORDS
30 # define BPF_MEMWORDS 16
31 #endif
33 #define BPF_LD_B (BPF_LD | BPF_B)
34 #define BPF_LD_H (BPF_LD | BPF_H)
35 #define BPF_LD_W (BPF_LD | BPF_W)
36 #define BPF_LDX_B (BPF_LDX | BPF_B)
37 #define BPF_LDX_W (BPF_LDX | BPF_W)
38 #define BPF_JMP_JA (BPF_JMP | BPF_JA)
39 #define BPF_JMP_JEQ (BPF_JMP | BPF_JEQ)
40 #define BPF_JMP_JGT (BPF_JMP | BPF_JGT)
41 #define BPF_JMP_JGE (BPF_JMP | BPF_JGE)
42 #define BPF_JMP_JSET (BPF_JMP | BPF_JSET)
43 #define BPF_ALU_ADD (BPF_ALU | BPF_ADD)
44 #define BPF_ALU_SUB (BPF_ALU | BPF_SUB)
45 #define BPF_ALU_MUL (BPF_ALU | BPF_MUL)
46 #define BPF_ALU_DIV (BPF_ALU | BPF_DIV)
47 #define BPF_ALU_MOD (BPF_ALU | BPF_MOD)
48 #define BPF_ALU_NEG (BPF_ALU | BPF_NEG)
49 #define BPF_ALU_AND (BPF_ALU | BPF_AND)
50 #define BPF_ALU_OR (BPF_ALU | BPF_OR)
51 #define BPF_ALU_XOR (BPF_ALU | BPF_XOR)
52 #define BPF_ALU_LSH (BPF_ALU | BPF_LSH)
53 #define BPF_ALU_RSH (BPF_ALU | BPF_RSH)
54 #define BPF_MISC_TAX (BPF_MISC | BPF_TAX)
55 #define BPF_MISC_TXA (BPF_MISC | BPF_TXA)
57 static const char *op_table[] = {
58 [BPF_LD_B] = "ldb",
59 [BPF_LD_H] = "ldh",
60 [BPF_LD_W] = "ld",
61 [BPF_LDX] = "ldx",
62 [BPF_LDX_B] = "ldxb",
63 [BPF_ST] = "st",
64 [BPF_STX] = "stx",
65 [BPF_JMP_JA] = "ja",
66 [BPF_JMP_JEQ] = "jeq",
67 [BPF_JMP_JGT] = "jgt",
68 [BPF_JMP_JGE] = "jge",
69 [BPF_JMP_JSET] = "jset",
70 [BPF_ALU_ADD] = "add",
71 [BPF_ALU_SUB] = "sub",
72 [BPF_ALU_MUL] = "mul",
73 [BPF_ALU_DIV] = "div",
74 [BPF_ALU_MOD] = "mod",
75 [BPF_ALU_NEG] = "neg",
76 [BPF_ALU_AND] = "and",
77 [BPF_ALU_OR] = "or",
78 [BPF_ALU_XOR] = "xor",
79 [BPF_ALU_LSH] = "lsh",
80 [BPF_ALU_RSH] = "rsh",
81 [BPF_RET] = "ret",
82 [BPF_MISC_TAX] = "tax",
83 [BPF_MISC_TXA] = "txa",
86 void bpf_dump_op_table(void)
88 size_t i;
89 for (i = 0; i < array_size(op_table); ++i) {
90 if (op_table[i])
91 printf("%s\n", op_table[i]);
95 static const char *bpf_dump_linux_k(uint32_t k)
97 switch (k) {
98 default:
99 return "[%d]";
100 case SKF_AD_OFF + SKF_AD_PROTOCOL:
101 return "proto";
102 case SKF_AD_OFF + SKF_AD_PKTTYPE:
103 return "type";
104 case SKF_AD_OFF + SKF_AD_IFINDEX:
105 return "ifidx";
106 case SKF_AD_OFF + SKF_AD_NLATTR:
107 return "nla";
108 case SKF_AD_OFF + SKF_AD_NLATTR_NEST:
109 return "nlan";
110 case SKF_AD_OFF + SKF_AD_MARK:
111 return "mark";
112 case SKF_AD_OFF + SKF_AD_QUEUE:
113 return "queue";
114 case SKF_AD_OFF + SKF_AD_HATYPE:
115 return "hatype";
116 case SKF_AD_OFF + SKF_AD_RXHASH:
117 return "rxhash";
118 case SKF_AD_OFF + SKF_AD_CPU:
119 return "cpu";
120 case SKF_AD_OFF + SKF_AD_VLAN_TAG:
121 return "vlant";
122 case SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT:
123 return "vlanp";
124 case SKF_AD_OFF + SKF_AD_PAY_OFFSET:
125 return "poff";
129 static char *__bpf_dump(const struct sock_filter bpf, int n)
131 int v;
132 const char *fmt, *op;
133 static char image[256];
134 char operand[64];
136 v = bpf.k;
137 switch (bpf.code) {
138 default:
139 op = "unimp";
140 fmt = "0x%x";
141 v = bpf.code;
142 break;
143 case BPF_RET | BPF_K:
144 op = op_table[BPF_RET];
145 fmt = "#0x%x";
146 break;
147 case BPF_RET | BPF_A:
148 op = op_table[BPF_RET];
149 fmt = "a";
150 break;
151 case BPF_RET | BPF_X:
152 op = op_table[BPF_RET];
153 fmt = "x";
154 break;
155 case BPF_LD_W | BPF_ABS:
156 op = op_table[BPF_LD_W];
157 fmt = bpf_dump_linux_k(bpf.k);
158 break;
159 case BPF_LD_H | BPF_ABS:
160 op = op_table[BPF_LD_H];
161 fmt = bpf_dump_linux_k(bpf.k);
162 break;
163 case BPF_LD_B | BPF_ABS:
164 op = op_table[BPF_LD_B];
165 fmt = bpf_dump_linux_k(bpf.k);
166 break;
167 case BPF_LD_W | BPF_LEN:
168 op = op_table[BPF_LD_W];
169 fmt = "#len";
170 break;
171 case BPF_LD_W | BPF_IND:
172 op = op_table[BPF_LD_W];
173 fmt = "[x + %d]";
174 break;
175 case BPF_LD_H | BPF_IND:
176 op = op_table[BPF_LD_H];
177 fmt = "[x + %d]";
178 break;
179 case BPF_LD_B | BPF_IND:
180 op = op_table[BPF_LD_B];
181 fmt = "[x + %d]";
182 break;
183 case BPF_LD | BPF_IMM:
184 op = op_table[BPF_LD_W];
185 fmt = "#0x%x";
186 break;
187 case BPF_LDX | BPF_IMM:
188 op = op_table[BPF_LDX];
189 fmt = "#0x%x";
190 break;
191 case BPF_LDX_B | BPF_MSH:
192 op = op_table[BPF_LDX_B];
193 fmt = "4*([%d]&0xf)";
194 break;
195 case BPF_LD | BPF_MEM:
196 op = op_table[BPF_LD_W];
197 fmt = "M[%d]";
198 break;
199 case BPF_LDX | BPF_MEM:
200 op = op_table[BPF_LDX];
201 fmt = "M[%d]";
202 break;
203 case BPF_ST:
204 op = op_table[BPF_ST];
205 fmt = "M[%d]";
206 break;
207 case BPF_STX:
208 op = op_table[BPF_STX];
209 fmt = "M[%d]";
210 break;
211 case BPF_JMP_JA:
212 op = op_table[BPF_JMP_JA];
213 fmt = "%d";
214 v = n + 1 + bpf.k;
215 break;
216 case BPF_JMP_JGT | BPF_K:
217 op = op_table[BPF_JMP_JGT];
218 fmt = "#0x%x";
219 break;
220 case BPF_JMP_JGE | BPF_K:
221 op = op_table[BPF_JMP_JGE];
222 fmt = "#0x%x";
223 break;
224 case BPF_JMP_JEQ | BPF_K:
225 op = op_table[BPF_JMP_JEQ];
226 fmt = "#0x%x";
227 break;
228 case BPF_JMP_JSET | BPF_K:
229 op = op_table[BPF_JMP_JSET];
230 fmt = "#0x%x";
231 break;
232 case BPF_JMP_JGT | BPF_X:
233 op = op_table[BPF_JMP_JGT];
234 fmt = "x";
235 break;
236 case BPF_JMP_JGE | BPF_X:
237 op = op_table[BPF_JMP_JGE];
238 fmt = "x";
239 break;
240 case BPF_JMP_JEQ | BPF_X:
241 op = op_table[BPF_JMP_JEQ];
242 fmt = "x";
243 break;
244 case BPF_JMP_JSET | BPF_X:
245 op = op_table[BPF_JMP_JSET];
246 fmt = "x";
247 break;
248 case BPF_ALU_ADD | BPF_X:
249 op = op_table[BPF_ALU_ADD];
250 fmt = "x";
251 break;
252 case BPF_ALU_SUB | BPF_X:
253 op = op_table[BPF_ALU_SUB];
254 fmt = "x";
255 break;
256 case BPF_ALU_MUL | BPF_X:
257 op = op_table[BPF_ALU_MUL];
258 fmt = "x";
259 break;
260 case BPF_ALU_DIV | BPF_X:
261 op = op_table[BPF_ALU_DIV];
262 fmt = "x";
263 break;
264 case BPF_ALU_MOD | BPF_X:
265 op = op_table[BPF_ALU_MOD];
266 fmt = "x";
267 break;
268 case BPF_ALU_AND | BPF_X:
269 op = op_table[BPF_ALU_AND];
270 fmt = "x";
271 break;
272 case BPF_ALU_OR | BPF_X:
273 op = op_table[BPF_ALU_OR];
274 fmt = "x";
275 break;
276 case BPF_ALU_XOR | BPF_X:
277 op = op_table[BPF_ALU_XOR];
278 fmt = "x";
279 break;
280 case BPF_ALU_LSH | BPF_X:
281 op = op_table[BPF_ALU_LSH];
282 fmt = "x";
283 break;
284 case BPF_ALU_RSH | BPF_X:
285 op = op_table[BPF_ALU_RSH];
286 fmt = "x";
287 break;
288 case BPF_ALU_ADD | BPF_K:
289 op = op_table[BPF_ALU_ADD];
290 fmt = "#%d";
291 break;
292 case BPF_ALU_SUB | BPF_K:
293 op = op_table[BPF_ALU_SUB];
294 fmt = "#%d";
295 break;
296 case BPF_ALU_MUL | BPF_K:
297 op = op_table[BPF_ALU_MUL];
298 fmt = "#%d";
299 break;
300 case BPF_ALU_DIV | BPF_K:
301 op = op_table[BPF_ALU_DIV];
302 fmt = "#%d";
303 break;
304 case BPF_ALU_MOD | BPF_K:
305 op = op_table[BPF_ALU_MOD];
306 fmt = "#%d";
307 break;
308 case BPF_ALU_AND | BPF_K:
309 op = op_table[BPF_ALU_AND];
310 fmt = "#0x%x";
311 break;
312 case BPF_ALU_OR | BPF_K:
313 op = op_table[BPF_ALU_OR];
314 fmt = "#0x%x";
315 break;
316 case BPF_ALU_XOR | BPF_K:
317 op = op_table[BPF_ALU_XOR];
318 fmt = "#0x%x";
319 break;
320 case BPF_ALU_LSH | BPF_K:
321 op = op_table[BPF_ALU_LSH];
322 fmt = "#%d";
323 break;
324 case BPF_ALU_RSH | BPF_K:
325 op = op_table[BPF_ALU_RSH];
326 fmt = "#%d";
327 break;
328 case BPF_ALU_NEG:
329 op = op_table[BPF_ALU_NEG];
330 fmt = "";
331 break;
332 case BPF_MISC_TAX:
333 op = op_table[BPF_MISC_TAX];
334 fmt = "";
335 break;
336 case BPF_MISC_TXA:
337 op = op_table[BPF_MISC_TXA];
338 fmt = "";
339 break;
342 slprintf_nocheck(operand, sizeof(operand), fmt, v);
343 slprintf_nocheck(image, sizeof(image),
344 (BPF_CLASS(bpf.code) == BPF_JMP &&
345 BPF_OP(bpf.code) != BPF_JA) ?
346 " L%d: %s %s, L%d, L%d" : " L%d: %s %s",
347 n, op, operand, n + 1 + bpf.jt, n + 1 + bpf.jf);
348 return image;
351 void bpf_dump_all(struct sock_fprog *bpf)
353 int i;
355 for (i = 0; i < bpf->len; ++i)
356 printf("%s\n", __bpf_dump(bpf->filter[i], i));
359 void bpf_attach_to_sock(int sock, struct sock_fprog *bpf)
361 int ret;
363 if (bpf->filter[0].code == BPF_RET &&
364 bpf->filter[0].k == 0xFFFFFFFF)
365 return;
367 ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER,
368 bpf, sizeof(*bpf));
369 if (unlikely(ret < 0))
370 panic("Cannot attach filter to socket!\n");
373 void bpf_detach_from_sock(int sock)
375 int ret, empty = 0;
377 ret = setsockopt(sock, SOL_SOCKET, SO_DETACH_FILTER,
378 &empty, sizeof(empty));
379 if (unlikely(ret < 0))
380 panic("Cannot detach filter from socket!\n");
383 int enable_kernel_bpf_jit_compiler(void)
385 return sysctl_set_int("net/core/bpf_jit_enable", 1);
388 int __bpf_validate(const struct sock_fprog *bpf)
390 uint32_t i, from;
391 const struct sock_filter *p;
393 if (!bpf)
394 return 0;
395 if (bpf->len < 1)
396 return 0;
398 for (i = 0; i < bpf->len; ++i) {
399 p = &bpf->filter[i];
400 switch (BPF_CLASS(p->code)) {
401 /* Check that memory operations use valid addresses. */
402 case BPF_LD:
403 case BPF_LDX:
404 switch (BPF_MODE(p->code)) {
405 case BPF_IMM:
406 break;
407 case BPF_ABS:
408 case BPF_IND:
409 case BPF_MSH:
410 /* There's no maximum packet data size
411 * in userland. The runtime packet length
412 * check suffices.
414 break;
415 case BPF_MEM:
416 if (p->k >= BPF_MEMWORDS)
417 return 0;
418 break;
419 case BPF_LEN:
420 break;
421 default:
422 return 0;
424 break;
425 case BPF_ST:
426 case BPF_STX:
427 if (p->k >= BPF_MEMWORDS)
428 return 0;
429 break;
430 case BPF_ALU:
431 switch (BPF_OP(p->code)) {
432 case BPF_ADD:
433 case BPF_SUB:
434 case BPF_MUL:
435 case BPF_OR:
436 case BPF_XOR:
437 case BPF_AND:
438 case BPF_LSH:
439 case BPF_RSH:
440 case BPF_NEG:
441 break;
442 case BPF_DIV:
443 case BPF_MOD:
444 /* Check for constant division by 0 (undefined
445 * for div and mod).
447 if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
448 return 0;
449 break;
450 default:
451 return 0;
453 break;
454 case BPF_JMP:
455 /* Check that jumps are within the code block,
456 * and that unconditional branches don't go
457 * backwards as a result of an overflow.
458 * Unconditional branches have a 32-bit offset,
459 * so they could overflow; we check to make
460 * sure they don't. Conditional branches have
461 * an 8-bit offset, and the from address is <=
462 * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
463 * is sufficiently small that adding 255 to it
464 * won't overflow.
466 * We know that len is <= BPF_MAXINSNS, and we
467 * assume that BPF_MAXINSNS is < the maximum size
468 * of a u_int, so that i + 1 doesn't overflow.
470 * For userland, we don't know that the from
471 * or len are <= BPF_MAXINSNS, but we know that
472 * from <= len, and, except on a 64-bit system,
473 * it's unlikely that len, if it truly reflects
474 * the size of the program we've been handed,
475 * will be anywhere near the maximum size of
476 * a u_int. We also don't check for backward
477 * branches, as we currently support them in
478 * userland for the protochain operation.
480 from = i + 1;
481 switch (BPF_OP(p->code)) {
482 case BPF_JA:
483 if (from + p->k >= bpf->len)
484 return 0;
485 break;
486 case BPF_JEQ:
487 case BPF_JGT:
488 case BPF_JGE:
489 case BPF_JSET:
490 if (from + p->jt >= bpf->len ||
491 from + p->jf >= bpf->len)
492 return 0;
493 break;
494 default:
495 return 0;
497 break;
498 case BPF_RET:
499 break;
500 case BPF_MISC:
501 break;
505 return BPF_CLASS(bpf->filter[bpf->len - 1].code) == BPF_RET;
508 uint32_t bpf_run_filter(const struct sock_fprog * fcode, uint8_t * packet,
509 size_t plen)
511 /* XXX: caplen == len */
512 uint32_t A, X;
513 uint32_t k;
514 struct sock_filter *bpf;
515 int32_t mem[BPF_MEMWORDS] = { 0, };
517 if (fcode == NULL || fcode->filter == NULL || fcode->len == 0)
518 return 0xFFFFFFFF;
520 A = 0;
521 X = 0;
523 bpf = fcode->filter;
524 --bpf;
525 while (1) {
526 ++bpf;
527 switch (bpf->code) {
528 default:
529 return 0;
530 case BPF_RET | BPF_K:
531 return (uint32_t) bpf->k;
532 case BPF_RET | BPF_A:
533 return (uint32_t) A;
534 case BPF_LD_W | BPF_ABS:
535 /* No Linux extensions supported here! */
536 k = bpf->k;
537 if (k + sizeof(int32_t) > plen)
538 return 0;
539 A = EXTRACT_LONG(&packet[k]);
540 continue;
541 case BPF_LD_H | BPF_ABS:
542 /* No Linux extensions supported here! */
543 k = bpf->k;
544 if (k + sizeof(short) > plen)
545 return 0;
546 A = EXTRACT_SHORT(&packet[k]);
547 continue;
548 case BPF_LD_B | BPF_ABS:
549 /* No Linux extensions supported here! */
550 k = bpf->k;
551 if (k >= plen)
552 return 0;
553 A = packet[k];
554 continue;
555 case BPF_LD_W | BPF_LEN:
556 A = plen;
557 continue;
558 case BPF_LDX_W | BPF_LEN:
559 X = plen;
560 continue;
561 case BPF_LD_W | BPF_IND:
562 k = X + bpf->k;
563 if (k + sizeof(int32_t) > plen)
564 return 0;
565 A = EXTRACT_LONG(&packet[k]);
566 continue;
567 case BPF_LD_H | BPF_IND:
568 k = X + bpf->k;
569 if (k + sizeof(short) > plen)
570 return 0;
571 A = EXTRACT_SHORT(&packet[k]);
572 continue;
573 case BPF_LD_B | BPF_IND:
574 k = X + bpf->k;
575 if (k >= plen)
576 return 0;
577 A = packet[k];
578 continue;
579 case BPF_LDX_B | BPF_MSH:
580 k = bpf->k;
581 if (k >= plen)
582 return 0;
583 X = (packet[bpf->k] & 0xf) << 2;
584 continue;
585 case BPF_LD | BPF_IMM:
586 A = bpf->k;
587 continue;
588 case BPF_LDX | BPF_IMM:
589 X = bpf->k;
590 continue;
591 case BPF_LD | BPF_MEM:
592 A = mem[bpf->k];
593 continue;
594 case BPF_LDX | BPF_MEM:
595 X = mem[bpf->k];
596 continue;
597 case BPF_ST:
598 mem[bpf->k] = A;
599 continue;
600 case BPF_STX:
601 mem[bpf->k] = X;
602 continue;
603 case BPF_JMP_JA:
604 bpf += bpf->k;
605 continue;
606 case BPF_JMP_JGT | BPF_K:
607 bpf += (A > bpf->k) ? bpf->jt : bpf->jf;
608 continue;
609 case BPF_JMP_JGE | BPF_K:
610 bpf += (A >= bpf->k) ? bpf->jt : bpf->jf;
611 continue;
612 case BPF_JMP_JEQ | BPF_K:
613 bpf += (A == bpf->k) ? bpf->jt : bpf->jf;
614 continue;
615 case BPF_JMP_JSET | BPF_K:
616 bpf += (A & bpf->k) ? bpf->jt : bpf->jf;
617 continue;
618 case BPF_JMP_JGT | BPF_X:
619 bpf += (A > X) ? bpf->jt : bpf->jf;
620 continue;
621 case BPF_JMP_JGE | BPF_X:
622 bpf += (A >= X) ? bpf->jt : bpf->jf;
623 continue;
624 case BPF_JMP_JEQ | BPF_X:
625 bpf += (A == X) ? bpf->jt : bpf->jf;
626 continue;
627 case BPF_JMP_JSET | BPF_X:
628 bpf += (A & X) ? bpf->jt : bpf->jf;
629 continue;
630 case BPF_ALU_ADD | BPF_X:
631 A += X;
632 continue;
633 case BPF_ALU_SUB | BPF_X:
634 A -= X;
635 continue;
636 case BPF_ALU_MUL | BPF_X:
637 A *= X;
638 continue;
639 case BPF_ALU_DIV | BPF_X:
640 if (X == 0)
641 return 0;
642 A /= X;
643 continue;
644 case BPF_ALU_MOD | BPF_X:
645 if (X == 0)
646 return 0;
647 A %= X;
648 continue;
649 case BPF_ALU_AND | BPF_X:
650 A &= X;
651 continue;
652 case BPF_ALU_OR | BPF_X:
653 A |= X;
654 continue;
655 case BPF_ALU_XOR | BPF_X:
656 A ^= X;
657 continue;
658 case BPF_ALU_LSH | BPF_X:
659 A <<= X;
660 continue;
661 case BPF_ALU_RSH | BPF_X:
662 A >>= X;
663 continue;
664 case BPF_ALU_ADD | BPF_K:
665 A += bpf->k;
666 continue;
667 case BPF_ALU_SUB | BPF_K:
668 A -= bpf->k;
669 continue;
670 case BPF_ALU_MUL | BPF_K:
671 A *= bpf->k;
672 continue;
673 case BPF_ALU_DIV | BPF_K:
674 A /= bpf->k;
675 continue;
676 case BPF_ALU_MOD | BPF_K:
677 A %= bpf->k;
678 continue;
679 case BPF_ALU_AND | BPF_K:
680 A &= bpf->k;
681 continue;
682 case BPF_ALU_OR | BPF_K:
683 A |= bpf->k;
684 continue;
685 case BPF_ALU_XOR | BPF_K:
686 A ^= bpf->k;
687 continue;
688 case BPF_ALU_LSH | BPF_K:
689 A <<= bpf->k;
690 continue;
691 case BPF_ALU_RSH | BPF_K:
692 A >>= bpf->k;
693 continue;
694 case BPF_ALU_NEG:
695 A = -A;
696 continue;
697 case BPF_MISC_TAX:
698 X = A;
699 continue;
700 case BPF_MISC_TXA:
701 A = X;
702 continue;
707 void bpf_parse_rules(char *rulefile, struct sock_fprog *bpf, uint32_t link_type)
709 int ret;
710 char buff[256];
711 struct sock_filter sf_single = { 0x06, 0, 0, 0xFFFFFFFF };
712 FILE *fp;
714 memset(bpf, 0, sizeof(*bpf));
716 if (rulefile == NULL) {
717 bpf->len = 1;
718 bpf->filter = xmalloc(sizeof(sf_single));
720 memcpy(&bpf->filter[0], &sf_single, sizeof(sf_single));
721 return;
724 if (!strcmp(rulefile, "-"))
725 fp = stdin;
726 else
727 fp = fopen(rulefile, "r");
729 if (!fp) {
730 bpf_try_compile(rulefile, bpf, link_type);
731 return;
734 memset(buff, 0, sizeof(buff));
735 while (fgets(buff, sizeof(buff), fp) != NULL) {
736 buff[sizeof(buff) - 1] = 0;
738 if (buff[0] != '{') {
739 memset(buff, 0, sizeof(buff));
740 continue;
743 memset(&sf_single, 0, sizeof(sf_single));
744 ret = sscanf(buff, "{ 0x%x, %u, %u, 0x%08x },",
745 (unsigned int *) &sf_single.code,
746 (unsigned int *) &sf_single.jt,
747 (unsigned int *) &sf_single.jf,
748 (unsigned int *) &sf_single.k);
749 if (unlikely(ret != 4))
750 panic("BPF syntax error!\n");
752 bpf->len++;
753 bpf->filter = xrealloc(bpf->filter,
754 bpf->len * sizeof(sf_single));
756 memcpy(&bpf->filter[bpf->len - 1], &sf_single,
757 sizeof(sf_single));
758 memset(buff, 0, sizeof(buff));
761 if (fp != stdin)
762 fclose(fp);
764 if (unlikely(__bpf_validate(bpf) == 0))
765 panic("This is not a valid BPF program!\n");