summaryrefslogtreecommitdiff
path: root/lib/libpcap/optimize.c
diff options
context:
space:
mode:
authorJakob Schlyter <jakob@cvs.openbsd.org>2000-04-26 21:25:54 +0000
committerJakob Schlyter <jakob@cvs.openbsd.org>2000-04-26 21:25:54 +0000
commit1b61474ff3af74b82ca97acff0c048e5e082201d (patch)
tree011fd1106acce11a3aae1d0c6ba403781a45171f /lib/libpcap/optimize.c
parentd22e957192c23ed5f75ecce51e53b9ff201c5ceb (diff)
sync with libpcap v0.5
add support for INET6 (kame)
Diffstat (limited to 'lib/libpcap/optimize.c')
-rw-r--r--lib/libpcap/optimize.c90
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