diff options
author | Jakob Schlyter <jakob@cvs.openbsd.org> | 2000-04-26 21:25:54 +0000 |
---|---|---|
committer | Jakob Schlyter <jakob@cvs.openbsd.org> | 2000-04-26 21:25:54 +0000 |
commit | 1b61474ff3af74b82ca97acff0c048e5e082201d (patch) | |
tree | 011fd1106acce11a3aae1d0c6ba403781a45171f /lib/libpcap/optimize.c | |
parent | d22e957192c23ed5f75ecce51e53b9ff201c5ceb (diff) |
sync with libpcap v0.5
add support for INET6 (kame)
Diffstat (limited to 'lib/libpcap/optimize.c')
-rw-r--r-- | lib/libpcap/optimize.c | 90 |
1 files changed, 88 insertions, 2 deletions
diff --git a/lib/libpcap/optimize.c b/lib/libpcap/optimize.c index 9309f55a87d..eb00e08c2be 100644 --- a/lib/libpcap/optimize.c +++ b/lib/libpcap/optimize.c @@ -1,4 +1,4 @@ -/* $OpenBSD: optimize.c,v 1.6 1999/07/20 04:49:55 deraadt Exp $ */ +/* $OpenBSD: optimize.c,v 1.7 2000/04/26 21:25:53 jakob Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 @@ -24,7 +24,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /cvs/OpenBSD/src/lib/libpcap/optimize.c,v 1.6 1999/07/20 04:49:55 deraadt Exp $ (LBL)"; + "@(#) $Header: /cvs/OpenBSD/src/lib/libpcap/optimize.c,v 1.7 2000/04/26 21:25:53 jakob Exp $ (LBL)"; #endif #include <sys/types.h> @@ -1105,6 +1105,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. @@ -1887,6 +1895,7 @@ convert_code_r(p) int slen; u_int off; int extrajmps; /* number of extra jumps inserted */ + struct slist **offset = NULL; if (p == 0 || isMarked(p)) return (1); @@ -1903,13 +1912,90 @@ convert_code_r(p) p->offset = dst - fstart; + /* generate offset[] for convenience */ + if (slen) { + 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; } + if (offset) + free(offset); + #ifdef BDEBUG bids[dst - fstart] = p->id + 1; #endif |