diff options
| author | itojun <itojun@NetBSD.org> | 1999-07-02 10:05:22 +0000 |
|---|---|---|
| committer | itojun <itojun@NetBSD.org> | 1999-07-02 10:05:22 +0000 |
| commit | c6f88a42f468b45ffa052d50fe70acc86b98a5c4 (patch) | |
| tree | b02c54482a4b6d0989d999d980eb279c963419a8 /lib/libpcap/optimize.c | |
| parent | 22b07aaafdf84686043596c4264b6d011a67b19d (diff) | |
support IPv6 address and IPv6 protocols.
"tcp" will match both IPv4 TCP and IPv6 TCP.
"ip6" will match IPv6.
you can chase header chain by using "protochain" instead of "proto"
(but bpf code is not optimizable in this case)
commit to tcpdump will follow.
I've sent this fix to LBL guys to get no response. I wonder why it was.
Diffstat (limited to 'lib/libpcap/optimize.c')
| -rw-r--r-- | lib/libpcap/optimize.c | 93 |
1 files changed, 87 insertions, 6 deletions
diff --git a/lib/libpcap/optimize.c b/lib/libpcap/optimize.c index e1274a357d3..7dade84f93d 100644 --- a/lib/libpcap/optimize.c +++ b/lib/libpcap/optimize.c @@ -1,4 +1,4 @@ -/* $NetBSD: optimize.c,v 1.7 1997/10/03 15:53:11 christos Exp $ */ +/* $NetBSD: optimize.c,v 1.8 1999/07/02 10:05:22 itojun Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 @@ -28,7 +28,7 @@ static const char rcsid[] = "@(#) Header: optimize.c,v 1.60 96/09/26 23:28:14 leres Exp (LBL)"; #else -__RCSID("$NetBSD: optimize.c,v 1.7 1997/10/03 15:53:11 christos Exp $"); +__RCSID("$NetBSD: optimize.c,v 1.8 1999/07/02 10:05:22 itojun Exp $"); #endif #endif @@ -1111,6 +1111,14 @@ opt_blk(b, do_stmts) int i; bpf_int32 aval; +#if 0 + for (s = b->stmts; s && s->next; s = s->next) + if (BPF_CLASS(s->s.code) == BPF_JMP) { + do_stmts = 0; + break; + } +#endif + /* * Initialize the atom values. * If we have no predecessors, everything is undefined. @@ -1480,8 +1488,6 @@ opt_blks(root, do_stmts) init_val(); maxlevel = root->level; - - find_inedges(root); for (i = maxlevel; i >= 0; --i) for (p = levels[i]; p; p = p->link) opt_blk(p, do_stmts); @@ -1499,8 +1505,6 @@ opt_blks(root, do_stmts) opt_j(&p->ef); } } - - find_inedges(root); for (i = 1; i <= maxlevel; ++i) { for (p = levels[i]; p; p = p->link) { or_pullup(p); @@ -1580,6 +1584,7 @@ opt_loop(root, do_stmts) find_levels(root); find_dom(root); find_closure(root); + find_inedges(root); find_ud(root); find_edom(root); opt_blks(root, do_stmts); @@ -1896,6 +1901,7 @@ convert_code_r(p) int slen; u_int off; int extrajmps; /* number of extra jumps inserted */ + struct slist **offset; if (p == 0 || isMarked(p)) return (1); @@ -1912,13 +1918,88 @@ convert_code_r(p) p->offset = dst - fstart; + /* generate offset[] for convenience */ + offset = (struct slist **)calloc(sizeof(struct slist *), slen); + if (!offset) { + bpf_error("not enough core"); + /*NOTREACHED*/ + } + src = p->stmts; + for (off = 0; off < slen && src; off++) { +#if 0 + printf("off=%d src=%x\n", off, src); +#endif + offset[off] = src; + src = src->next; + } + + off = 0; for (src = p->stmts; src; src = src->next) { if (src->s.code == NOP) continue; dst->code = (u_short)src->s.code; dst->k = src->s.k; + + /* fill block-local relative jump */ + if (BPF_CLASS(src->s.code) != BPF_JMP + || src->s.code == (BPF_JMP|BPF_JA)) { +#if 0 + if (src->s.jt || src->s.jf) { + bpf_error("illegal jmp destination"); + /*NOTREACHED*/ + } +#endif + goto filled; + } + if (off == slen - 2) /*???*/ + goto filled; + + { + int i; + int jt, jf; + char *ljerr = "%s for block-local relative jump: off=%d"; + +#if 0 + printf("code=%x off=%d %x %x\n", src->s.code, + off, src->s.jt, src->s.jf); +#endif + + if (!src->s.jt || !src->s.jf) { + bpf_error(ljerr, "no jmp destination", off); + /*NOTREACHED*/ + } + + jt = jf = 0; + for (i = 0; i < slen; i++) { + if (offset[i] == src->s.jt) { + if (jt) { + bpf_error(ljerr, "multiple matches", off); + /*NOTREACHED*/ + } + + dst->jt = i - off - 1; + jt++; + } + if (offset[i] == src->s.jf) { + if (jf) { + bpf_error(ljerr, "multiple matches", off); + /*NOTREACHED*/ + } + dst->jf = i - off - 1; + jf++; + } + } + if (!jt || !jf) { + bpf_error(ljerr, "no destination found", off); + /*NOTREACHED*/ + } + } +filled: ++dst; + ++off; } + free(offset); + #ifdef BDEBUG bids[dst - fstart] = p->id + 1; #endif |
