diff options
-rw-r--r-- | lib/libpcap/CHANGES | 108 | ||||
-rw-r--r-- | lib/libpcap/README | 64 | ||||
-rw-r--r-- | lib/libpcap/bpf_image.c | 15 | ||||
-rw-r--r-- | lib/libpcap/etherent.c | 124 | ||||
-rw-r--r-- | lib/libpcap/gencode.c | 266 | ||||
-rw-r--r-- | lib/libpcap/gencode.h | 47 | ||||
-rw-r--r-- | lib/libpcap/grammar.y | 23 | ||||
-rw-r--r-- | lib/libpcap/inet.c | 30 | ||||
-rw-r--r-- | lib/libpcap/nametoaddr.c | 64 | ||||
-rw-r--r-- | lib/libpcap/optimize.c | 217 | ||||
-rw-r--r-- | lib/libpcap/pcap-bpf.c | 37 | ||||
-rw-r--r-- | lib/libpcap/pcap-int.h | 17 | ||||
-rw-r--r-- | lib/libpcap/pcap-namedb.h | 17 | ||||
-rw-r--r-- | lib/libpcap/pcap.3 | 2 | ||||
-rw-r--r-- | lib/libpcap/pcap.c | 40 | ||||
-rw-r--r-- | lib/libpcap/pcap.h | 21 | ||||
-rw-r--r-- | lib/libpcap/savefile.c | 93 | ||||
-rw-r--r-- | lib/libpcap/scanner.l | 19 | ||||
-rw-r--r-- | lib/libpcap/shlib_version | 2 |
19 files changed, 781 insertions, 425 deletions
diff --git a/lib/libpcap/CHANGES b/lib/libpcap/CHANGES index e6370e4994e..a820af9ae17 100644 --- a/lib/libpcap/CHANGES +++ b/lib/libpcap/CHANGES @@ -1,6 +1,110 @@ -$OpenBSD: CHANGES,v 1.3 1996/06/10 07:23:23 deraadt Exp $ +$OpenBSD: CHANGES,v 1.4 1996/07/12 13:19:06 mickey Exp $ $NetBSD: CHANGES,v 1.2 1995/03/06 11:37:58 mycroft Exp $ -@(#) Header: CHANGES,v 1.4 94/06/20 19:22:33 leres Exp (LBL) +@(#) $Header: /cvs/OpenBSD/src/lib/libpcap/CHANGES,v 1.4 1996/07/12 13:19:06 mickey Exp $ (LBL) + +v0.2 Sun Jun 23 02:28:42 PDT 1996 + +- Add support for HP-UX. Resulted from code contributed by Tom Murray + (tmurray@hpindck.cup.hp.com) and Philippe-Andri Prindeville + (philipp@res.enst.fr) + +- Update INSTALL with a reminder to install include files. Thanks to + Mark Andrews (mandrews@aw.sgi.com) + +- Fix bpf compiler alignment bug on the alpha. + +- Use autoconf to detect architectures that can't handle misaligned + accesses. + +- Added loopback support for snoop. Resulted from report Steve + Alexander (sca@engr.sgi.com) + +v0.1 Fri Apr 28 18:11:03 PDT 1995 + +- Fixed compiler and optimizer bugs. The BPF filter engine uses unsigned + comparison operators, while the code generator and optimizer assumed + signed semantics in several places. Thanks to Charlie Slater + (cslater@imatek.com) for pointing this out. + +- Removed FDDI ifdef's, they aren't really needed. Resulted from report + by Gary Veum (veum@boa.gsfc.nasa.gov). + +- Add pcap-null.c which allows offline use of libpcap on systems that + don't support live package capture. This feature resulting from a + request from Jan van Oorschot (j.p.m.voorschot@et.tudelft.nl). + +- Make bpf_compile() reentrant. Fix thanks to Pascal Hennequin + (Pascal.Hennequin@hugo.int-evry.fr). + +- Port to GNU autoconf. + +- Fix pcap-dlpi.c to work with isdn. Resulted from report by Flemming + Johansen (fsj@csd.cri.dk). + +- Handle multi-digit interface unit numbers (aka ppa's) under dlpi. + Resulted from report by Daniel Ehrlich (ehrlich@cse.psu.edu). + +- Fix pcap-dlpi.c to work in non-promiscuous mode. Resulted from report + by Jeff Murphy (jcmurphy@acsu.buffalo.edu). + +- Add support for "long jumps". Thanks to Jeffrey Mogul + (mogul@pa.dec.com). + +- Fix minor problems when compiling with BDEBUG as noticed by Scott + Bertilson (scott@unet.umn.edu). + +- Declare sys_errlist "const char *const" to avoid problems under + FreeBSD. Resulted from report by jher@eden.com. + +v0.0.6 Fri Apr 28 04:07:13 PDT 1995 + +- Add missing variable declaration missing from 0.0.6 + +v0.0.5 Fri Apr 28 00:22:21 PDT 1995 + +- Workaround for problems when pcap_read() returns 0 due to the timeout + expiring. + +v0.0.4 Thu Apr 20 20:41:48 PDT 1995 + +- Change configuration to not use gcc v2 flags with gcc v1. + +- Fixed a bug in pcap_next(); if pcap_dispatch() returns 0, pcap_next() + should also return 0. Thanks to Richard Stevens (rstevens@noao.edu). + +- Fixed configure to test for snoop before dlpi to avoid problems under + IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com). + +- Hack around deficiency in Ultrix's make. + +- Fix two bugs related to the Solaris pre-5.3.2 bufmod bug; handle + savefiles that have more than snapshot bytes of data in them (so we + can read old savefiles) and avoid writing such files. + +- Added checkioctl which is used with gcc to check that the + "fixincludes" script has been run. + +v0.0.3 Tue Oct 18 18:13:46 PDT 1994 + +- Fixed configure to test for snoop before dlpi to avoid problems under + IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com). + +v0.0.2 Wed Oct 12 20:56:37 PDT 1994 + +- Implement timeout in the dlpi pcap_open_live(). Thanks to Richard + Stevens. + +- Determine pcap link type from dlpi media type. Resulted from report + by Mahesh Jethanandani (mahesh@npix.com). + +v0.0.1 Fri Jun 24 14:50:57 PDT 1994 + +- Fixed bug in nit_setflags() in pcap-snit.c. The streams ioctl timeout + wasn't being initialized sometimes resulting in an "NIOCSFLAGS: + Invalid argument" error under OSF/1. Reported by Matt Day + (mday@artisoft.com) and Danny Mitzel (dmitzel@whitney.hitc.com). + +- Turn on FDDI support by default. v0.0 Mon Jun 20 19:20:16 PDT 1994 diff --git a/lib/libpcap/README b/lib/libpcap/README index 9e545b83898..53a6447ada8 100644 --- a/lib/libpcap/README +++ b/lib/libpcap/README @@ -1,9 +1,9 @@ -$OpenBSD: README,v 1.3 1996/06/10 07:23:24 deraadt Exp $ +$OpenBSD: README,v 1.4 1996/07/12 13:19:06 mickey Exp $ $NetBSD: README,v 1.2 1995/03/06 11:38:07 mycroft Exp $ -@(#) Header: README,v 1.7 94/06/20 18:56:55 leres Exp (LBL) +@(#) $Header: /cvs/OpenBSD/src/lib/libpcap/README,v 1.4 1996/07/12 13:19:06 mickey Exp $ (LBL) -LIBPCAP 0.0 -Lawrence Berkeley Laboratory +LIBPCAP 0.2 +Lawrence Berkeley National Laboratory Network Research Group libpcap@ee.lbl.gov ftp://ftp.ee.lbl.gov/libpcap-*.tar.Z @@ -13,28 +13,17 @@ interface for user-level packet capture. libpcap provides a portable framework for low-level network monitoring. Applications include network statistics collection, security monitoring, network debugging, etc. Since almost every system vendor provides a different interface -for packet capture, and since we've developed several tools that require -these interfaces, we've created this system-independent API to ease in -porting and to alleviate the need for several system-dependent packet -capture modules in each application. - -THIS IS AN ALPHA-QUALITY RELEASE. The interface is brand new and is -likely to change. If you code to this interface, and want to track -future versions, be prepared to update your code. We admit that this -release is premature, but we're releasing it anyway because the tcpdump-3.0 -distribution requires it. - -libpcap has been built and tested under SGI Irix 4.x & 5.2, SunOS 4.x, -Solaris 2.3, BSD/386 v1.1, DEC/OSF v1.3 v2.0, and Ultrix 4.x. SunOS 3.5 -4.3BSD Reno/Tahoe and 4.4BSD are supported as well, but we currently -do not have the resources to carry out testing in these environments -(we suspect you'll run into problems under these systems -- please -send us the patches if you fix any porting problems). +for packet capture, and since we've developed several tools that +require this functionality, we've created this system-independent API +to ease in porting and to alleviate the need for several +system-dependent packet capture modules in each application. + +Note well: this interface is new and is likely to change. The libpcap interface supports a filtering mechanism based on the -architecture in the BSD packet filter. BPF is described in the -1993 Winter Usenix paper ``The BSD Packet Filter: A New Architecture -for User-level Packet Capture''. A compressed postscript version is in +architecture in the BSD packet filter. BPF is described in the 1993 +Winter Usenix paper ``The BSD Packet Filter: A New Architecture for +User-level Packet Capture''. A compressed postscript version is in: ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z. @@ -42,22 +31,21 @@ Although most packet capture interfaces support in-kernel filtering, libpcap utilizes in-kernel filtering only for the BPF interface. On systems that don't have BPF, all packets are read into user-space and the BPF filters are evaluated in the libpcap library, incurring -added overhead (especially, for selective filters). We haven't tried -taking advantage of other packet filter models first because they -aren't general enough (i.e., only simple filters can be evaluated), -and second because we don't have the time to modify the code generator -(or write a filter translator) and BPF is more efficient anyway. +added overhead (especially, for selective filters). Ideally, libpcap +would translate BPF filters into a filter program that is compatible +with the underlying kernel subsystem, but this is not yet implemented. BPF is standard in 4.4BSD, BSD/386, NetBSD, and FreeBSD. DEC OSF/1 -uses the packetfilter interface but has been extended to accept -BPF filters (which libpcap utilizes). Also, you can add BPF filter -support to Ultrix using the kernel source and/or object patches -available in +uses the packetfilter interface but has been extended to accept BPF +filters (which libpcap utilizes). Also, you can add BPF filter support +to Ultrix using the kernel source and/or object patches available in: - ftp://gatekeeper.dec.com/pub/DEC/net/bpfext42.tar.Z. + ftp://gatekeeper.dec.com/pub/DEC/net/bpfext42.tar.Z. -Please send bugs and comments to libpcap@ee.lbl.gov. +Problems, bugs, questions, desirable enhancements, source code +contributions, etc., should be sent to the email address +"libpcap@ee.lbl.gov". - - Steve McCanne (mccanne@ee.lbl.gov) - Craig Leres (leres@ee.lbl.gov) - Van Jacobson (van@ee.lbl.gov) + - Steve McCanne + Craig Leres + Van Jacobson diff --git a/lib/libpcap/bpf_image.c b/lib/libpcap/bpf_image.c index 3a75dd44051..272859a57a4 100644 --- a/lib/libpcap/bpf_image.c +++ b/lib/libpcap/bpf_image.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: bpf_image.c,v 1.2 1995/03/06 11:38:11 mycroft Exp $ */ +/* $OpenBSD */ /* - * Copyright (c) 1990, 1991, 1992, 1994 + * Copyright (c) 1990, 1991, 1992, 1994, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +23,7 @@ #ifndef lint static char rcsid[] = - "@(#) Header: bpf_image.c,v 1.12 94/01/31 03:22:34 leres Exp (LBL)"; + "@(#) Header: bpf_image.c,v 1.19 95/11/26 14:02:36 leres Exp (LBL)"; #endif #include <sys/types.h> @@ -36,6 +35,12 @@ static char rcsid[] = #include <stdio.h> #include <string.h> +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "pcap-int.h" + char * bpf_image(p, n) struct bpf_insn *p; @@ -138,7 +143,7 @@ bpf_image(p, n) case BPF_JMP|BPF_JA: op = "ja"; fmt = "%d"; - v = n + p->k; + v = n + 1 + p->k; break; case BPF_JMP|BPF_JGT|BPF_K: diff --git a/lib/libpcap/etherent.c b/lib/libpcap/etherent.c index 53f9a07ef46..29af870e021 100644 --- a/lib/libpcap/etherent.c +++ b/lib/libpcap/etherent.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: etherent.c,v 1.2 1995/03/06 11:38:14 mycroft Exp $ */ +/* $OpenBSD: etherent.c,v 1.4 1996/07/12 13:19:07 mickey Exp $ */ /* - * Copyright (c) 1990, 1993, 1994 + * Copyright (c) 1990, 1993, 1994, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,20 +22,24 @@ */ #ifndef lint static char rcsid[] = - "@(#) Header: etherent.c,v 1.8 94/06/20 19:07:50 leres Exp (LBL)"; + "@(#) Header: etherent.c,v 1.18 95/10/07 03:08:12 leres Exp (LBL)"; #endif #include <sys/types.h> #include <ctype.h> +#include <memory.h> #include <pcap.h> #include <pcap-namedb.h> #include <stdio.h> +#include <string.h> -#ifndef __GNUC__ -#define inline +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" #endif +#include "pcap-int.h" + static inline int xdtoi(int); static inline int skip_space(FILE *); static inline int skip_line(FILE *); @@ -86,66 +89,71 @@ pcap_next_etherent(FILE *fp) register int c, d, i; char *bp; static struct pcap_etherent e; - static int nline = 1; - top: - while (nline) { + + memset((char *)&e, 0, sizeof(e)); + do { /* Find addr */ c = skip_space(fp); if (c == '\n') continue; + /* If this is a comment, or first thing on line - cannot be ethernet address, skip the line. */ - else if (!isxdigit(c)) + cannot be etehrnet address, skip the line. */ + if (!isxdigit(c)) { c = skip_line(fp); - else { - /* must be the start of an address */ - for (i = 0; i < 6; i += 1) { - d = xdtoi(c); - c = getc(fp); - if (c != ':') { - d <<= 4; - d |= xdtoi(c); - c = getc(fp); - } - e.addr[i] = d; - if (c != ':') - break; + continue; + } + + /* must be the start of an address */ + for (i = 0; i < 6; i += 1) { + d = xdtoi(c); + c = getc(fp); + if (isxdigit(c)) { + d <<= 4; + d |= xdtoi(c); c = getc(fp); } - nline = 0; + e.addr[i] = d; + if (c != ':') + break; + c = getc(fp); } if (c == EOF) - return 0; - } - - /* If we started a new line, 'c' holds the char past the ether addr, - which we assume is white space. If we are continuing a line, - 'c' is garbage. In either case, we can throw it away. */ - - c = skip_space(fp); - if (c == '\n') { - nline = 1; - goto top; - } - else if (c == '#') { - (void)skip_line(fp); - nline = 1; - goto top; - } - else if (c == EOF) - return 0; - - /* Must be a name. */ - bp = e.name; - /* Use 'd' to prevent buffer overflow. */ - d = sizeof(e.name) - 1; - do { - *bp++ = c; - c = getc(fp); - } while (!isspace(c) && c != EOF && --d > 0); - *bp = '\0'; - if (c == '\n') - nline = 1; - - return &e; + break; + + /* Must be whitespace */ + if (!isspace(c)) { + c = skip_line(fp); + continue; + } + c = skip_space(fp); + + /* hit end of line... */ + if (c == '\n') + continue; + + if (c == '#') { + c = skip_line(fp); + continue; + } + + /* pick up name */ + bp = e.name; + /* Use 'd' to prevent buffer overflow. */ + d = sizeof(e.name) - 1; + do { + *bp++ = c; + c = getc(fp); + } while (!isspace(c) && c != EOF && --d > 0); + *bp = '\0'; + + /* Eat trailing junk */ + if (c != '\n') + (void)skip_line(fp); + + return &e; + + } while (c != EOF); + + return (NULL); } diff --git a/lib/libpcap/gencode.c b/lib/libpcap/gencode.c index db37ff18932..9de3d47193c 100644 --- a/lib/libpcap/gencode.c +++ b/lib/libpcap/gencode.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: gencode.c,v 1.2.6.1 1996/06/05 18:04:23 cgd Exp $ */ +/* $OpenBSD: gencode.c,v 1.4 1996/07/12 13:19:08 mickey Exp $ */ /* - * Copyright (c) 1990, 1991, 1992, 1993, 1994 + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,36 +22,43 @@ */ #ifndef lint static char rcsid[] = - "@(#) Header: gencode.c,v 1.55 94/06/20 19:07:53 leres Exp (LBL)"; + "@(#) Header: gencode.c,v 1.81 96/06/19 23:09:09 leres Exp (LBL)"; #endif -#include <sys/param.h> +#include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> +#if __STDC__ +struct mbuf; +struct rtentry; +#endif + #include <net/if.h> #include <net/bpf.h> #include <netinet/in.h> #include <netinet/if_ether.h> +#include <stdlib.h> #include <memory.h> #include <pcap.h> #include <pcap-namedb.h> #include <setjmp.h> #if __STDC__ #include <stdarg.h> -#include <stdlib.h> #else #include <varargs.h> #endif -#include "gencode.h" - -#ifndef __GNUC__ -#define inline +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" #endif +#include "pcap-int.h" + +#include "gencode.h" + #ifndef ETHERTYPE_REVARP #define ETHERTYPE_REVARP 0x8035 #endif @@ -71,16 +77,24 @@ static char rcsid[] = #define JMP(c) ((c)|BPF_JMP|BPF_K) +/* Locals */ static jmp_buf top_ctx; static pcap_t *bpf_pcap; +/* XXX */ +#ifdef PCAP_FDDIPAD +int pcap_fddipad = PCAP_FDDIPAD; +#else +int pcap_fddipad; +#endif + /* VARARGS */ -volatile void -#if __STDC__ || defined(SOLARIS) -bpf_error(char *fmt, ...) +__dead void +#if __STDC__ +bpf_error(const char *fmt, ...) #else bpf_error(fmt, va_alist) - char *fmt; + const char *fmt; va_dcl #endif { @@ -130,29 +144,26 @@ static inline void syntax(void); static void backpatch(struct block *, struct block *); static void merge(struct block *, struct block *); -static struct block *gen_cmp(u_int, u_int, int32_t); -static struct block *gen_mcmp(u_int, u_int, int32_t, u_int32_t); +static struct block *gen_cmp(u_int, u_int, bpf_int32); +static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32); static struct block *gen_bcmp(u_int, u_int, u_char *); static struct block *gen_uncond(int); static inline struct block *gen_true(void); static inline struct block *gen_false(void); static struct block *gen_linktype(int); -static struct block *gen_hostop(u_int32_t, u_int32_t, int, int, u_int, u_int); +static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); static struct block *gen_ehostop(u_char *, int); -#ifdef FDDI static struct block *gen_fhostop(u_char *, int); -#endif -static struct block *gen_dnhostop(u_int32_t, int, u_int); -static struct block *gen_host(u_int32_t, u_int32_t, int, int); -static struct block *gen_gateway(u_char *, u_int32_t **, int, int); +static struct block *gen_dnhostop(bpf_u_int32, int, u_int); +static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int); +static struct block *gen_gateway(u_char *, bpf_u_int32 **, int, int); static struct block *gen_ipfrag(void); -static struct block *gen_portatom(int, int32_t); +static struct block *gen_portatom(int, bpf_int32); struct block *gen_portop(int, int, int); static struct block *gen_port(int, int, int); static int lookup_proto(char *, int); static struct block *gen_proto(int, int, int); -static u_int32_t net_mask(u_int32_t *); -static u_int32_t net_mask(u_int32_t *); +static bpf_u_int32 net_mask(bpf_u_int32 *); static struct slist *xfer_to_x(struct arth *); static struct slist *xfer_to_a(struct arth *); static struct block *gen_len(int, int); @@ -164,8 +175,8 @@ newchunk(n) struct chunk *cp; int k, size; - /* XXX Round to structure boundary. */ - n = ALIGN(n); + /* XXX Round up to nearest long. */ + n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1); cp = &chunks[cur_chunk]; if (n > cp->n_left) { @@ -188,9 +199,12 @@ freechunks() { int i; + cur_chunk = 0; for (i = 0; i < NCHUNKS; ++i) - if (chunks[i].m) + if (chunks[i].m != NULL) { free(chunks[i].m); + chunks[i].m = NULL; + } } /* @@ -247,26 +261,30 @@ syntax() bpf_error("syntax error in filter expression"); } -static u_int32_t netmask; +static bpf_u_int32 netmask; static int snaplen; int pcap_compile(pcap_t *p, struct bpf_program *program, - char *buf, int optimize, u_int32_t mask) + char *buf, int optimize, bpf_u_int32 mask) { extern int n_errors; int len; + n_errors = 0; + root = NULL; bpf_pcap = p; - if (setjmp(top_ctx)) + if (setjmp(top_ctx)) { + freechunks(); return (-1); + } netmask = mask; snaplen = pcap_snapshot(p); lex_init(buf ? buf : ""); init_linktype(pcap_datalink(p)); - pcap_parse(); + (void)pcap_parse(); if (n_errors) syntax(); @@ -372,7 +390,7 @@ gen_not(b) static struct block * gen_cmp(offset, size, v) u_int offset, size; - int32_t v; + bpf_int32 v; { struct slist *s; struct block *b; @@ -390,8 +408,8 @@ gen_cmp(offset, size, v) static struct block * gen_mcmp(offset, size, v, mask) u_int offset, size; - int32_t v; - u_int32_t mask; + bpf_int32 v; + bpf_u_int32 mask; { struct block *b = gen_cmp(offset, size, v); struct slist *s; @@ -414,7 +432,7 @@ gen_bcmp(offset, size, v) b = NULL; while (size >= 4) { u_char *p = &v[size - 4]; - int32_t w = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + bpf_int32 w = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; tmp = gen_cmp(offset + size - 4, BPF_W, w); if (b != NULL) gen_and(b, tmp); @@ -423,7 +441,7 @@ gen_bcmp(offset, size, v) } while (size >= 2) { u_char *p = &v[size - 2]; - int32_t w = (p[0] << 8) | p[1]; + bpf_int32 w = (p[0] << 8) | p[1]; tmp = gen_cmp(offset + size - 2, BPF_H, w); if (b != NULL) gen_and(b, tmp); @@ -431,7 +449,7 @@ gen_bcmp(offset, size, v) size -= 2; } if (size > 0) { - tmp = gen_cmp(offset, BPF_B, (int32_t)v[0]); + tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]); if (b != NULL) gen_and(b, tmp); b = tmp; @@ -447,9 +465,6 @@ gen_bcmp(offset, size, v) static u_int off_linktype; static u_int off_nl; static int linktype; -#ifdef FDDI -extern int fddipad; -#endif static void init_linktype(type) @@ -483,22 +498,35 @@ init_linktype(type) off_nl = 4; return; -#ifdef FDDI case DLT_FDDI: /* * FDDI doesn't really have a link-level type field. * We assume that SSAP = SNAP is being used and pick * out the encapsulated Ethernet type. */ - off_linktype = 19 + fddipad; - off_nl = 21 + fddipad; - return; + off_linktype = 19; +#ifdef PCAP_FDDIPAD + off_linktype += pcap_fddipad; #endif + off_nl = 21; +#ifdef PCAP_FDDIPAD + off_nl += pcap_fddipad; +#endif + return; case DLT_IEEE802: off_linktype = 20; off_nl = 22; return; + + case DLT_ATM_RFC1483: + /* + * assume routed, non-ISO PDUs + * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00) + */ + off_linktype = 6; + off_nl = 8; + return; } bpf_error("unknown data link type 0x%x", linktype); /* NOTREACHED */ @@ -546,14 +574,21 @@ gen_linktype(proto) if (proto == ETHERTYPE_IP) proto = 0x0021; /* XXX - need ppp.h defs */ break; + + case DLT_NULL: + /* XXX */ + if (proto == ETHERTYPE_IP) + return (gen_cmp(0, BPF_W, (bpf_int32)AF_INET)); + else + return gen_false(); } - return gen_cmp(off_linktype, BPF_H, (int32_t)proto); + return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); } static struct block * gen_hostop(addr, mask, dir, proto, src_off, dst_off) - u_int32_t addr; - u_int32_t mask; + bpf_u_int32 addr; + bpf_u_int32 mask; int dir, proto; u_int src_off, dst_off; { @@ -587,7 +622,7 @@ gen_hostop(addr, mask, dir, proto, src_off, dst_off) abort(); } b0 = gen_linktype(proto); - b1 = gen_mcmp(offset, BPF_W, (int32_t)addr, mask); + b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask); gen_and(b0, b1); return b1; } @@ -623,7 +658,6 @@ gen_ehostop(eaddr, dir) /* NOTREACHED */ } -#ifdef FDDI /* * Like gen_ehostop, but for DLT_FDDI */ @@ -636,10 +670,18 @@ gen_fhostop(eaddr, dir) switch (dir) { case Q_SRC: - return gen_bcmp(6 + 1 + fddipad, 6, eaddr); +#ifdef PCAP_FDDIPAD + return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr); +#else + return gen_bcmp(6 + 1, 6, eaddr); +#endif case Q_DST: - return gen_bcmp(0 + 1 + fddipad, 6, eaddr); +#ifdef PCAP_FDDIPAD + return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr); +#else + return gen_bcmp(0 + 1, 6, eaddr); +#endif case Q_AND: b0 = gen_fhostop(eaddr, Q_SRC); @@ -657,7 +699,6 @@ gen_fhostop(eaddr, dir) abort(); /* NOTREACHED */ } -#endif /* * This is quite tricky because there may be pad bytes in front of the @@ -679,7 +720,7 @@ gen_fhostop(eaddr, dir) */ static struct block * gen_dnhostop(addr, dir, base_off) - u_int32_t addr; + bpf_u_int32 addr; int dir; u_int base_off; { @@ -720,23 +761,25 @@ gen_dnhostop(addr, dir, base_off) b0 = gen_linktype(ETHERTYPE_DN); /* Check for pad = 1, long header case */ tmp = gen_mcmp(base_off + 2, BPF_H, - (int32_t)ntohs(0x0681), (int32_t)ntohs(0x07FF)); - b1 = gen_cmp(base_off + 2 + 1 + offset_lh, BPF_H, (int32_t)ntohs(addr)); + (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); + b1 = gen_cmp(base_off + 2 + 1 + offset_lh, + BPF_H, (bpf_int32)ntohs(addr)); gen_and(tmp, b1); /* Check for pad = 0, long header case */ - tmp = gen_mcmp(base_off + 2, BPF_B, (int32_t)0x06, (int32_t)0x7); - b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (int32_t)ntohs(addr)); + tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); + b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); gen_and(tmp, b2); gen_or(b2, b1); /* Check for pad = 1, short header case */ tmp = gen_mcmp(base_off + 2, BPF_H, - (int32_t)ntohs(0x0281), (int32_t)ntohs(0x07FF)); - b2 = gen_cmp(base_off + 2 + 1 + offset_sh, BPF_H, (int32_t)ntohs(addr)); + (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); + b2 = gen_cmp(base_off + 2 + 1 + offset_sh, + BPF_H, (bpf_int32)ntohs(addr)); gen_and(tmp, b2); gen_or(b2, b1); /* Check for pad = 0, short header case */ - tmp = gen_mcmp(base_off + 2, BPF_B, (int32_t)0x02, (int32_t)0x7); - b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (int32_t)ntohs(addr)); + tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); + b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); gen_and(tmp, b2); gen_or(b2, b1); @@ -747,8 +790,8 @@ gen_dnhostop(addr, dir, base_off) static struct block * gen_host(addr, mask, proto, dir) - u_int32_t addr; - u_int32_t mask; + bpf_u_int32 addr; + bpf_u_int32 mask; int proto; int dir; { @@ -785,6 +828,9 @@ gen_host(addr, mask, proto, dir) case Q_ICMP: bpf_error("'icmp' modifier applied to host"); + case Q_IGMP: + bpf_error("'igmp' modifier applied to host"); + case Q_DECNET: return gen_dnhostop(addr, dir, off_nl); @@ -806,7 +852,7 @@ gen_host(addr, mask, proto, dir) static struct block * gen_gateway(eaddr, alist, proto, dir) u_char *eaddr; - u_int32_t **alist; + bpf_u_int32 **alist; int proto; int dir; { @@ -822,12 +868,11 @@ gen_gateway(eaddr, alist, proto, dir) case Q_RARP: if (linktype == DLT_EN10MB) b0 = gen_ehostop(eaddr, Q_OR); -#ifdef FDDI else if (linktype == DLT_FDDI) b0 = gen_fhostop(eaddr, Q_OR); -#endif else - bpf_error("'gateway' supported only on ethernet or FDDI"); + bpf_error( + "'gateway' supported only on ethernet or FDDI"); b1 = gen_host(**alist++, 0xffffffffL, proto, Q_OR); while (*alist) { @@ -853,19 +898,25 @@ gen_proto_abbrev(proto) case Q_TCP: b0 = gen_linktype(ETHERTYPE_IP); - b1 = gen_cmp(off_nl + 9, BPF_B, (int32_t)IPPROTO_TCP); + b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_TCP); gen_and(b0, b1); break; case Q_UDP: b0 = gen_linktype(ETHERTYPE_IP); - b1 = gen_cmp(off_nl + 9, BPF_B, (int32_t)IPPROTO_UDP); + b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_UDP); gen_and(b0, b1); break; case Q_ICMP: b0 = gen_linktype(ETHERTYPE_IP); - b1 = gen_cmp(off_nl + 9, BPF_B, (int32_t)IPPROTO_ICMP); + b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_ICMP); + gen_and(b0, b1); + break; + + case Q_IGMP: + b0 = gen_linktype(ETHERTYPE_IP); + b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)2); gen_and(b0, b1); break; @@ -926,7 +977,7 @@ gen_ipfrag() static struct block * gen_portatom(off, v) int off; - int32_t v; + bpf_int32 v; { struct slist *s; struct block *b; @@ -951,29 +1002,29 @@ gen_portop(port, proto, dir) struct block *b0, *b1, *tmp; /* ip proto 'proto' */ - tmp = gen_cmp(off_nl + 9, BPF_B, (int32_t)proto); + tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto); b0 = gen_ipfrag(); gen_and(tmp, b0); switch (dir) { case Q_SRC: - b1 = gen_portatom(0, (int32_t)port); + b1 = gen_portatom(0, (bpf_int32)port); break; case Q_DST: - b1 = gen_portatom(2, (int32_t)port); + b1 = gen_portatom(2, (bpf_int32)port); break; case Q_OR: case Q_DEFAULT: - tmp = gen_portatom(0, (int32_t)port); - b1 = gen_portatom(2, (int32_t)port); + tmp = gen_portatom(0, (bpf_int32)port); + b1 = gen_portatom(2, (bpf_int32)port); gen_or(tmp, b1); break; case Q_AND: - tmp = gen_portatom(0, (int32_t)port); - b1 = gen_portatom(2, (int32_t)port); + tmp = gen_portatom(0, (bpf_int32)port); + b1 = gen_portatom(2, (bpf_int32)port); gen_and(tmp, b1); break; @@ -1059,7 +1110,7 @@ gen_proto(v, proto, dir) case Q_DEFAULT: case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); - b1 = gen_cmp(off_nl + 9, BPF_B, (int32_t)v); + b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v); gen_and(b0, b1); return b1; @@ -1102,6 +1153,10 @@ gen_proto(v, proto, dir) bpf_error("'icmp proto' is bogus"); /* NOTREACHED */ + case Q_IGMP: + bpf_error("'igmp proto' is bogus"); + /* NOTREACHED */ + default: abort(); /* NOTREACHED */ @@ -1112,11 +1167,11 @@ gen_proto(v, proto, dir) /* * Left justify 'addr' and return its resulting network mask. */ -static u_int32_t +static bpf_u_int32 net_mask(addr) - u_int32_t *addr; + bpf_u_int32 *addr; { - register u_int32_t m = 0xffffffff; + register bpf_u_int32 m = 0xffffffff; if (*addr) while ((*addr & 0xff000000) == 0) @@ -1133,7 +1188,7 @@ gen_scode(name, q) int proto = q.proto; int dir = q.dir; u_char *eaddr; - u_int32_t mask, addr, **alist; + bpf_u_int32 mask, addr, **alist; struct block *b, *tmp; int port, real_proto; @@ -1150,21 +1205,24 @@ gen_scode(name, q) case Q_HOST: if (proto == Q_LINK) { switch (linktype) { + case DLT_EN10MB: eaddr = pcap_ether_hostton(name); if (eaddr == NULL) - bpf_error("unknown ether host '%s'", name); + bpf_error( + "unknown ether host '%s'", name); return gen_ehostop(eaddr, dir); -#ifdef FDDI case DLT_FDDI: eaddr = pcap_ether_hostton(name); if (eaddr == NULL) - bpf_error("unknown FDDI host '%s'", name); + bpf_error( + "unknown FDDI host '%s'", name); return gen_fhostop(eaddr, dir); -#endif + default: - bpf_error("only ethernet/FDDI supports link-level host name"); + bpf_error( + "only ethernet/FDDI supports link-level host name"); break; } } else if (proto == Q_DECNET) { @@ -1236,10 +1294,10 @@ gen_scode(name, q) struct block * gen_ncode(v, q) - u_int32_t v; + bpf_u_int32 v; struct qual q; { - u_int32_t mask; + bpf_u_int32 mask; int proto = q.proto; int dir = q.dir; @@ -1295,10 +1353,8 @@ gen_ecode(eaddr, q) if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) { if (linktype == DLT_EN10MB) return gen_ehostop(eaddr, (int)q.dir); -#ifdef FDDI if (linktype == DLT_FDDI) return gen_fhostop(eaddr, (int)q.dir); -#endif } bpf_error("ethernet address used in non-ether expression"); /* NOTREACHED */ @@ -1401,6 +1457,7 @@ gen_load(proto, index, size) case Q_TCP: case Q_UDP: case Q_ICMP: + case Q_IGMP: s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); s->s.k = off_nl; sappend(s, xfer_to_a(index)); @@ -1437,6 +1494,10 @@ gen_relation(code, a0, a1, reversed) s1 = xfer_to_a(a0); s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); b = new_block(JMP(code)); + if (code == BPF_JGT || code == BPF_JGE) { + reversed = !reversed; + b->s.k = 0x80000000; + } if (reversed) gen_not(b); @@ -1593,10 +1654,9 @@ gen_len(jmp, n) struct block *b; s = new_stmt(BPF_LD|BPF_LEN); - s->next = new_stmt(BPF_ALU|BPF_SUB|BPF_K); - s->next->s.k = n; b = new_block(JMP(jmp)); b->stmts = s; + b->s.k = n; return b; } @@ -1632,16 +1692,16 @@ gen_byteop(op, idx, val) abort(); case '=': - return gen_cmp((u_int)idx, BPF_B, (int32_t)val); + return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); case '<': - b = gen_cmp((u_int)idx, BPF_B, (int32_t)val); + b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); b->s.code = JMP(BPF_JGE); gen_not(b); return b; case '>': - b = gen_cmp((u_int)idx, BPF_B, (int32_t)val); + b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); b->s.code = JMP(BPF_JGT); return b; @@ -1665,7 +1725,7 @@ struct block * gen_broadcast(proto) int proto; { - u_int32_t hostmask; + bpf_u_int32 hostmask; struct block *b0, *b1, *b2; static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -1675,19 +1735,17 @@ gen_broadcast(proto) case Q_LINK: if (linktype == DLT_EN10MB) return gen_ehostop(ebroadcast, Q_DST); -#ifdef FDDI if (linktype == DLT_FDDI) return gen_fhostop(ebroadcast, Q_DST); -#endif bpf_error("not a broadcast link"); break; case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); hostmask = ~netmask; - b1 = gen_mcmp(off_nl + 16, BPF_W, (int32_t)0, hostmask); + b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask); b2 = gen_mcmp(off_nl + 16, BPF_W, - (int32_t)(~0 & hostmask), hostmask); + (bpf_int32)(~0 & hostmask), hostmask); gen_or(b1, b2); gen_and(b0, b2); return b2; @@ -1731,7 +1789,7 @@ gen_multicast(proto) case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); - b1 = gen_cmp(off_nl + 16, BPF_B, (int32_t)224); + b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224); b1->s.code = JMP(BPF_JGE); gen_and(b0, b1); return b1; diff --git a/lib/libpcap/gencode.h b/lib/libpcap/gencode.h index 608ad0aef3b..b90d5bc70a2 100644 --- a/lib/libpcap/gencode.h +++ b/lib/libpcap/gencode.h @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: gencode.h,v 1.2.6.1 1996/06/05 18:04:30 cgd Exp $ */ +/* $OpenBSD: gencode.h,v 1.4 1996/07/12 13:19:08 mickey Exp $ */ /* - * Copyright (c) 1990, 1991, 1992, 1993, 1994 + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -21,14 +20,10 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) Header: gencode.h,v 1.20 94/06/12 14:29:30 leres Exp (LBL) + * @(#) Header: gencode.h,v 1.33 96/06/23 02:21:09 leres Exp (LBL) */ -/* - * filter.h must be included before this file. - */ - -/* Address qualifers. */ +/* Address qualifiers. */ #define Q_HOST 1 #define Q_NET 2 @@ -45,13 +40,14 @@ #define Q_TCP 5 #define Q_UDP 6 #define Q_ICMP 7 +#define Q_IGMP 8 -#define Q_DECNET 8 -#define Q_LAT 9 -#define Q_MOPRC 10 -#define Q_MOPDL 11 +#define Q_DECNET 9 +#define Q_LAT 10 +#define Q_MOPRC 11 +#define Q_MOPDL 12 -/* Directional qualifers. */ +/* Directional qualifiers. */ #define Q_SRC 1 #define Q_DST 2 @@ -63,7 +59,7 @@ struct stmt { int code; - int32_t k; + bpf_int32 k; }; struct slist { @@ -75,14 +71,14 @@ struct slist { * A bit vector to represent definition sets. We assume TOT_REGISTERS * is smaller than 8*sizeof(atomset). */ -typedef u_int32_t atomset; +typedef bpf_u_int32 atomset; #define ATOMMASK(n) (1 << (n)) #define ATOMELEM(d, n) (d & ATOMMASK(n)) /* * An unbounded set. */ -typedef u_int32_t *uset; +typedef bpf_u_int32 *uset; /* * Total number of atomic entities, including accumulator (A) and index (X). @@ -104,6 +100,8 @@ struct block { struct slist *stmts; /* side effect stmts */ struct stmt s; /* branch stmt */ int mark; + int longjt; /* jt branch requires long jump */ + int longjf; /* jf branch requires long jump */ int level; int offset; int sense; @@ -117,8 +115,8 @@ struct block { atomset def, kill; atomset in_use; atomset out_use; - int32_t oval; - int32_t val[N_ATOMS]; + int oval; + int val[N_ATOMS]; }; struct arth { @@ -134,10 +132,6 @@ struct qual { unsigned char pad; }; -#ifndef __GNUC__ -#define volatile -#endif - struct arth *gen_loadi(int); struct arth *gen_load(int, struct arth *, int); struct arth *gen_loadlen(void); @@ -150,7 +144,7 @@ void gen_not(struct block *); struct block *gen_scode(char *, struct qual); struct block *gen_ecode(u_char *, struct qual); -struct block *gen_ncode(u_int32_t, struct qual); +struct block *gen_ncode(bpf_u_int32, struct qual); struct block *gen_proto_abbrev(int); struct block *gen_relation(int, struct arth *, struct arth *, int); struct block *gen_less(int); @@ -161,7 +155,10 @@ struct block *gen_multicast(int); struct block *gen_inbound(int); void bpf_optimize(struct block **); -volatile void bpf_error(char *, ...); +#if __STDC__ +__dead void bpf_error(const char *, ...) + __attribute__((volatile, format (printf, 1, 2))); +#endif void finish_parse(struct block *); char *sdup(char *); diff --git a/lib/libpcap/grammar.y b/lib/libpcap/grammar.y index 7731a550e45..0bf080970a5 100644 --- a/lib/libpcap/grammar.y +++ b/lib/libpcap/grammar.y @@ -1,9 +1,8 @@ %{ -/* $OpenBSD */ -/* $NetBSD: grammar.y,v 1.2 1995/03/06 11:38:27 mycroft Exp $ */ +/* $OpenBSD: grammar.y,v 1.4 1996/07/12 13:19:09 mickey Exp $ */ /* - * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,13 +24,18 @@ */ #ifndef lint static char rcsid[] = - "@(#) Header: grammar.y,v 1.39 94/06/14 20:09:25 leres Exp (LBL)"; + "@(#) $Header: /cvs/OpenBSD/src/lib/libpcap/grammar.y,v 1.4 1996/07/12 13:19:09 mickey Exp $ (LBL)"; #endif #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> +#if __STDC__ +struct mbuf; +struct rtentry; +#endif + #include <net/if.h> #include <net/bpf.h> @@ -42,6 +46,11 @@ static char rcsid[] = #include <pcap.h> #include <pcap-namedb.h> +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "pcap-int.h" #include "gencode.h" #define QSET(q, p, d, a) (q).proto = (p),\ @@ -61,6 +70,9 @@ yyerror(char *msg) } #ifndef YYBISON +int yyparse(void); + +int pcap_parse() { return (yyparse()); @@ -93,7 +105,7 @@ pcap_parse() %token DST SRC HOST GATEWAY %token NET PORT LESS GREATER PROTO BYTE -%token ARP RARP IP TCP UDP ICMP +%token ARP RARP IP TCP UDP ICMP IGMP %token DECNET LAT MOPRC MOPDL %token TK_BROADCAST TK_MULTICAST %token NUM INBOUND OUTBOUND @@ -217,6 +229,7 @@ pname: LINK { $$ = Q_LINK; } | TCP { $$ = Q_TCP; } | UDP { $$ = Q_UDP; } | ICMP { $$ = Q_ICMP; } + | IGMP { $$ = Q_IGMP; } | DECNET { $$ = Q_DECNET; } | LAT { $$ = Q_LAT; } | MOPDL { $$ = Q_MOPDL; } diff --git a/lib/libpcap/inet.c b/lib/libpcap/inet.c index 9a29bea094a..fb0cb362d77 100644 --- a/lib/libpcap/inet.c +++ b/lib/libpcap/inet.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: inet.c,v 1.2.6.1 1996/06/05 18:04:32 cgd Exp $ */ +/* $OpenBSD: inet.c,v 1.4 1996/07/12 13:19:09 mickey Exp $ */ /* - * Copyright (c) 1994 + * Copyright (c) 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,28 +35,40 @@ #ifndef lint static char rcsid[] = - "@(#) Header: inet.c,v 1.4 94/06/07 01:16:50 leres Exp (LBL)"; + "@(#) Header: inet.c,v 1.16 96/06/23 14:28:22 leres Exp (LBL)"; #endif #include <sys/param.h> #include <sys/file.h> #include <sys/ioctl.h> #include <sys/socket.h> -#ifdef SOLARIS +#ifdef HAVE_SYS_SOCKIO_H #include <sys/sockio.h> #endif +#if __STDC__ +struct mbuf; +struct rtentry; +#endif + #include <net/if.h> #include <netinet/in.h> #include <ctype.h> #include <errno.h> +#include <memory.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pcap.h> +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "pcap-int.h" + /* Not all systems have IFF_LOOPBACK */ #ifdef IFF_LOOPBACK #define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK) @@ -101,7 +112,7 @@ pcap_lookupdev(errbuf) mp = NULL; minunit = 666; for (; ifrp < ifend; ifrp = ifnext) { -#if BSD - 0 >= 199006 +#ifdef HAVE_SOCKADDR_SA_LEN n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) ifnext = ifrp + 1; @@ -152,7 +163,7 @@ pcap_lookupdev(errbuf) int pcap_lookupnet(device, netp, maskp, errbuf) register char *device; - register u_int32_t *netp, *maskp; + register bpf_u_int32 *netp, *maskp; register char *errbuf; { register int fd; @@ -164,6 +175,11 @@ pcap_lookupnet(device, netp, maskp, errbuf) (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno)); return (-1); } + memset(&ifr, 0, sizeof(ifr)); +#ifdef linux + /* XXX Work around Linux kernel bug */ + ifr.ifr_addr.sa_family = AF_INET; +#endif (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { (void)sprintf(errbuf, "SIOCGIFADDR: %s: %s", diff --git a/lib/libpcap/nametoaddr.c b/lib/libpcap/nametoaddr.c index a8b75eee3f0..5da21a46875 100644 --- a/lib/libpcap/nametoaddr.c +++ b/lib/libpcap/nametoaddr.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: nametoaddr.c,v 1.3.6.1 1996/06/05 18:04:34 cgd Exp $ */ +/* $OpenBSD: nametoaddr.c,v 1.4 1996/07/12 13:19:09 mickey Exp $ */ /* - * Copyright (c) 1990, 1991, 1992, 1993, 1994 + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,11 +26,17 @@ #ifndef lint static char rcsid[] = - "@(#) Header: nametoaddr.c,v 1.21 94/06/20 19:07:54 leres Exp (LBL)"; + "@(#) Header: nametoaddr.c,v 1.38 96/06/17 02:42:50 leres Exp (LBL)"; #endif #include <sys/param.h> #include <sys/socket.h> + +#if __STDC__ +struct mbuf; +struct rtentry; +#endif + #include <net/if.h> #include <netinet/in.h> #include <netinet/if_ether.h> @@ -39,21 +44,20 @@ static char rcsid[] = #include <ctype.h> #include <errno.h> +#include <stdlib.h> +#include <memory.h> #include <netdb.h> #include <pcap.h> #include <pcap-namedb.h> #include <stdio.h> -#ifdef __NetBSD__ -#include <stdlib.h> -#include <string.h> + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" #endif +#include "pcap-int.h" #include "gencode.h" -#ifndef __GNUC__ -#define inline -#endif - #ifndef NTOHL #define NTOHL(x) (x) = ntohl(x) #define NTOHS(x) (x) = ntohs(x) @@ -65,24 +69,24 @@ static inline int xdtoi(int); * Convert host name to internet address. * Return 0 upon failure. */ -u_int32_t ** +bpf_u_int32 ** pcap_nametoaddr(const char *name) { #ifndef h_addr - static u_int32_t *hlist[2]; + static bpf_u_int32 *hlist[2]; #endif - u_int32_t **p; + bpf_u_int32 **p; struct hostent *hp; if ((hp = gethostbyname(name)) != NULL) { #ifndef h_addr - hlist[0] = (u_int32_t *)hp->h_addr; + hlist[0] = (bpf_u_int32 *)hp->h_addr; NTOHL(hp->h_addr); return hlist; #else - for (p = (u_int32_t **)hp->h_addr_list; *p; ++p) + for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p) NTOHL(**p); - return (u_int32_t **)hp->h_addr_list; + return (bpf_u_int32 **)hp->h_addr_list; #endif } else @@ -93,7 +97,7 @@ pcap_nametoaddr(const char *name) * Convert net name to internet address. * Return 0 upon failure. */ -u_long +bpf_u_int32 pcap_nametonetaddr(const char *name) { struct netent *np; @@ -134,14 +138,12 @@ pcap_nametoport(const char *name, int *port, int *proto) sp = getservbyname(name, other); if (sp != 0) { NTOHS(sp->s_port); +#ifdef notdef if (*port != sp->s_port) /* Can't handle ambiguous names that refer to different port numbers. */ -#ifdef notdef warning("ambiguous port %s in /etc/services", name); -#else - ; #endif *proto = PROTO_UNDEF; } @@ -226,10 +228,10 @@ xdtoi(c) return c - 'A' + 10; } -u_long +bpf_u_int32 __pcap_atoin(const char *s) { - u_long addr = 0; + bpf_u_int32 addr = 0; u_int n; while (1) { @@ -245,14 +247,14 @@ __pcap_atoin(const char *s) /* NOTREACHED */ } -u_long +bpf_u_int32 __pcap_atodn(const char *s) { #define AREASHIFT 10 #define AREAMASK 0176000 #define NODEMASK 01777 - u_long addr = 0; + bpf_u_int32 addr = 0; u_int node, area; if (sscanf((char *)s, "%d.%d", &area, &node) != 2) @@ -290,7 +292,7 @@ pcap_ether_aton(const char *s) return (e); } -#ifndef ETHER_SERVICE +#ifndef HAVE_ETHER_HOSTTON /* Roll our own */ u_char * pcap_ether_hostton(const char *name) @@ -323,18 +325,20 @@ pcap_ether_hostton(const char *name) return (NULL); } #else + +#ifndef sgi +extern int ether_hostton(char *, struct ether_addr *); +#endif + /* Use the os supplied routines */ u_char * pcap_ether_hostton(const char *name) { register u_char *ap; u_char a[6]; -#ifndef sgi - extern int ether_hostton(char *, struct ether_addr *); -#endif ap = NULL; - if (ether_hostton((char*)name, (struct ether_addr *)a) == 0) { + if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) { ap = (u_char *)malloc(6); if (ap != NULL) memcpy(ap, a, 6); diff --git a/lib/libpcap/optimize.c b/lib/libpcap/optimize.c index 8d631463909..70d105b4b7c 100644 --- a/lib/libpcap/optimize.c +++ b/lib/libpcap/optimize.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: optimize.c,v 1.3.6.1 1996/06/05 18:04:37 cgd Exp $ */ +/* $OpenBSD: optimize.c,v 1.4 1996/07/12 13:19:10 mickey Exp $ */ /* - * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994 + * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,7 +24,7 @@ */ #ifndef lint static char rcsid[] = - "@(#) Header: optimize.c,v 1.45 94/06/20 19:07:55 leres Exp (LBL)"; + "@(#) Header: optimize.c,v 1.58 96/06/16 22:36:59 leres Exp (LBL)"; #endif #include <sys/types.h> @@ -34,19 +33,18 @@ static char rcsid[] = #include <net/bpf.h> #include <stdio.h> -#ifdef __osf__ #include <stdlib.h> -#include <malloc.h> -#endif -#ifdef __NetBSD__ -#include <stdlib.h> -#endif #include <memory.h> +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "pcap-int.h" #include "gencode.h" -#ifndef __GNUC__ -#define inline +#ifdef BDEBUG +extern int dflag; #endif #define A_ATOM BPF_MEMWORDS @@ -100,8 +98,8 @@ static int atomdef(struct stmt *); static void compute_local_ud(struct block *); static void find_ud(struct block *); static void init_val(void); -static int32_t F(int, int32_t, int32_t); -static inline void vstore(struct stmt *, int32_t *, int32_t, int); +static int F(int, int, int); +static inline void vstore(struct stmt *, int *, int, int); static void opt_blk(struct block *, int); static int use_conflict(struct block *, struct block *); static void opt_j(struct edge *); @@ -112,11 +110,11 @@ static inline void link_inedge(struct edge *, struct block *); static void find_inedges(struct block *); static void opt_root(struct block **); static void opt_loop(struct block *, int); -static void fold_op(struct stmt *, int32_t, int32_t); +static void fold_op(struct stmt *, int, int); static inline struct slist *this_op(struct slist *); static void opt_not(struct block *); static void opt_peep(struct block *); -static void opt_stmt(struct stmt *, int32_t[], int); +static void opt_stmt(struct stmt *, int[], int); static void deadstmt(struct stmt *, struct stmt *[]); static void opt_deadstores(struct block *); static void opt_blk(struct block *, int); @@ -128,7 +126,10 @@ static int slength(struct slist *); static int count_blocks(struct block *); static void number_blks_r(struct block *); static int count_stmts(struct block *); -static void convert_code_r(struct block *); +static int convert_code_r(struct block *); +#ifdef BDEBUG +static void opt_dump(struct block *); +#endif static int n_blocks; struct block **blocks; @@ -142,8 +143,8 @@ struct edge **edges; static int nodewords; static int edgewords; struct block **levels; -u_int32_t *space; -#define BITS_PER_WORD (8*sizeof(u_int32_t)) +bpf_u_int32 *space; +#define BITS_PER_WORD (8*sizeof(bpf_u_int32)) /* * True if a is in uset {p} */ @@ -167,7 +168,7 @@ u_int32_t *space; */ #define SET_INTERSECT(a, b, n)\ {\ - register u_int32_t *_x = a, *_y = b;\ + register bpf_u_int32 *_x = a, *_y = b;\ register int _n = n;\ while (--_n >= 0) *_x++ &= *_y++;\ } @@ -177,7 +178,7 @@ u_int32_t *space; */ #define SET_SUBTRACT(a, b, n)\ {\ - register u_int32_t *_x = a, *_y = b;\ + register bpf_u_int32 *_x = a, *_y = b;\ register int _n = n;\ while (--_n >= 0) *_x++ &=~ *_y++;\ } @@ -187,7 +188,7 @@ u_int32_t *space; */ #define SET_UNION(a, b, n)\ {\ - register u_int32_t *_x = a, *_y = b;\ + register bpf_u_int32 *_x = a, *_y = b;\ register int _n = n;\ while (--_n >= 0) *_x++ |= *_y++;\ } @@ -248,7 +249,7 @@ find_dom(root) { int i; struct block *b; - u_int32_t *x; + bpf_u_int32 *x; /* * Initialize sets to contain all nodes. @@ -499,8 +500,8 @@ find_ud(root) */ struct valnode { int code; - int32_t v0, v1; - int32_t val; + int v0, v1; + int val; struct valnode *next; }; @@ -514,7 +515,7 @@ static int maxval; struct vmapinfo { int is_const; - int32_t const_val; + bpf_int32 const_val; }; struct vmapinfo *vmap; @@ -531,10 +532,10 @@ init_val() } /* Because we really don't have an IR, this stuff is a little messy. */ -static int32_t +static int F(code, v0, v1) int code; - int32_t v0, v1; + int v0, v1; { u_int hash; int val; @@ -567,8 +568,8 @@ F(code, v0, v1) static inline void vstore(s, valp, newval, alter) struct stmt *s; - int32_t *valp; - int32_t newval; + int *valp; + int newval; int alter; { if (alter && *valp == newval) @@ -580,9 +581,9 @@ vstore(s, valp, newval, alter) static void fold_op(s, v0, v1) struct stmt *s; - int32_t v0, v1; + int v0, v1; { - int32_t a, b; + bpf_int32 a, b; a = vmap[v0].const_val; b = vmap[v1].const_val; @@ -660,7 +661,6 @@ opt_peep(b) struct slist *s; struct slist *next, *last; int val; - int32_t v; s = b->stmts; if (s == 0) @@ -767,7 +767,16 @@ opt_peep(b) !ATOMELEM(b->out_use, A_ATOM)) { val = b->val[X_ATOM]; if (vmap[val].is_const) { + int op; + b->s.k += vmap[val].const_val; + op = BPF_OP(b->s.code); + if (op == BPF_JGT || op == BPF_JGE) { + struct block *t = JT(b); + JT(b) = JF(b); + JF(b) = t; + b->s.k += 0x80000000; + } last->s.code = NOP; done = 0; } else if (b->s.k == 0) { @@ -786,8 +795,17 @@ opt_peep(b) */ else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) && !ATOMELEM(b->out_use, A_ATOM)) { + int op; + b->s.k += last->s.k; last->s.code = NOP; + op = BPF_OP(b->s.code); + if (op == BPF_JGT || op == BPF_JGE) { + struct block *t = JT(b); + JT(b) = JF(b); + JF(b) = t; + b->s.k += 0x80000000; + } done = 0; } /* @@ -808,7 +826,7 @@ opt_peep(b) */ val = b->val[A_ATOM]; if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) { - v = vmap[val].const_val; + bpf_int32 v = vmap[val].const_val; switch (BPF_OP(b->s.code)) { case BPF_JEQ: @@ -816,11 +834,11 @@ opt_peep(b) break; case BPF_JGT: - v = v > b->s.k; + v = (unsigned)v > b->s.k; break; case BPF_JGE: - v = v >= b->s.k; + v = (unsigned)v >= b->s.k; break; case BPF_JSET: @@ -848,11 +866,11 @@ opt_peep(b) static void opt_stmt(s, val, alter) struct stmt *s; - int32_t val[]; + int val[]; int alter; { int op; - int32_t v; + int v; switch (s->code) { @@ -1086,7 +1104,7 @@ opt_blk(b, do_stmts) struct slist *s; struct edge *p; int i; - int32_t aval; + bpf_int32 aval; /* * Initialize the atom values. @@ -1113,12 +1131,17 @@ opt_blk(b, do_stmts) /* * This is a special case: if we don't use anything from this * block, and we load the accumulator with value that is - * already there, eliminate all the statements. + * already there, or if this block is a return, + * eliminate all the statements. */ - if (do_stmts && b->out_use == 0 && aval != 0 && - b->val[A_ATOM] == aval) - b->stmts = 0; - else { + if (do_stmts && + ((b->out_use == 0 && aval != 0 &&b->val[A_ATOM] == aval) || + BPF_CLASS(b->s.code) == BPF_RET)) { + if (b->stmts != 0) { + b->stmts = 0; + done = 0; + } + } else { opt_peep(b); opt_deadstores(b); } @@ -1230,7 +1253,7 @@ opt_j(ep) */ top: for (i = 0; i < edgewords; ++i) { - register u_int32_t x = ep->edom[i]; + register bpf_u_int32 x = ep->edom[i]; while (x != 0) { k = ffs(x) - 1; @@ -1523,6 +1546,14 @@ opt_root(b) if (tmp != 0) sappend(s, tmp); (*b)->stmts = s; + + /* + * If the root node is a return, then there is no + * point executing any statements (since the bpf machine + * has no side effects). + */ + if (BPF_CLASS((*b)->s.code) == BPF_RET) + (*b)->stmts = 0; } static void @@ -1763,7 +1794,7 @@ static void opt_init(root) struct block *root; { - u_int32_t *p; + bpf_u_int32 *p; int i, n, max_stmts; /* @@ -1785,11 +1816,11 @@ opt_init(root) */ levels = (struct block **)malloc(n_blocks * sizeof(*levels)); - edgewords = n_edges / (8 * sizeof(u_int32_t)) + 1; - nodewords = n_blocks / (8 * sizeof(u_int32_t)) + 1; + edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1; + nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1; /* XXX */ - space = (u_int32_t *)malloc(2 * n_blocks * nodewords * sizeof(*space) + space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space) + n_edges * edgewords * sizeof(*space)); p = space; all_dom_sets = p; @@ -1842,7 +1873,13 @@ static struct bpf_insn *ftail; int bids[1000]; #endif -static void +/* + * Returns true if successful. Returns false if a branch has + * an offset that is too large. If so, we have marked that + * branch so that on a subsequent iteration, it will be treated + * properly. + */ +static int convert_code_r(p) struct block *p; { @@ -1850,16 +1887,20 @@ convert_code_r(p) struct slist *src; int slen; u_int off; + int extrajmps; /* number of extra jumps inserted */ if (p == 0 || isMarked(p)) - return; + return (1); Mark(p); - convert_code_r(JF(p)); - convert_code_r(JT(p)); + if (convert_code_r(JF(p)) == 0) + return (0); + if (convert_code_r(JT(p)) == 0) + return (0); slen = slength(p->stmts); - dst = ftail -= slen + 1; + dst = ftail -= (slen + 1 + p->longjt + p->longjf); + /* inflate length by any extra jumps */ p->offset = dst - fstart; @@ -1876,15 +1917,42 @@ convert_code_r(p) dst->code = (u_short)p->s.code; dst->k = p->s.k; if (JT(p)) { + extrajmps = 0; off = JT(p)->offset - (p->offset + slen) - 1; - if (off >= 256) - bpf_error("long jumps not supported"); - dst->jt = off; + if (off >= 256) { + /* offset too large for branch, must add a jump */ + if (p->longjt == 0) { + /* mark this instruction and retry */ + p->longjt++; + return(0); + } + /* branch if T to following jump */ + dst->jt = extrajmps; + extrajmps++; + dst[extrajmps].code = BPF_JMP|BPF_JA; + dst[extrajmps].k = off - extrajmps; + } + else + dst->jt = off; off = JF(p)->offset - (p->offset + slen) - 1; - if (off >= 256) - bpf_error("long jumps not supported"); - dst->jf = off; + if (off >= 256) { + /* offset too large for branch, must add a jump */ + if (p->longjf == 0) { + /* mark this instruction and retry */ + p->longjf++; + return(0); + } + /* branch if F to following jump */ + /* if two jumps are inserted, F goes to second one */ + dst->jf = extrajmps; + extrajmps++; + dst[extrajmps].code = BPF_JMP|BPF_JA; + dst[extrajmps].k = off - extrajmps; + } + else + dst->jf = off; } + return (1); } @@ -1900,21 +1968,30 @@ icode_to_fcode(root, lenp) int n; struct bpf_insn *fp; - unMarkAll(); - n = *lenp = count_stmts(root); - - fp = (struct bpf_insn *)malloc(sizeof(*fp) * n); - memset((char *)fp, 0, sizeof(*fp) * n); - fstart = fp; - ftail = fp + n; - - unMarkAll(); - convert_code_r(root); + /* + * Loop doing convert_codr_r() until no branches remain + * with too-large offsets. + */ + while (1) { + unMarkAll(); + n = *lenp = count_stmts(root); + + fp = (struct bpf_insn *)malloc(sizeof(*fp) * n); + memset((char *)fp, 0, sizeof(*fp) * n); + fstart = fp; + ftail = fp + n; + + unMarkAll(); + if (convert_code_r(root)) + break; + free(fp); + } return fp; } #ifdef BDEBUG +static void opt_dump(root) struct block *root; { diff --git a/lib/libpcap/pcap-bpf.c b/lib/libpcap/pcap-bpf.c index 4fe4b6ddfa2..4251f8942f5 100644 --- a/lib/libpcap/pcap-bpf.c +++ b/lib/libpcap/pcap-bpf.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: pcap-bpf.c,v 1.3 1995/04/29 05:42:31 cgd Exp $ */ +/* $OpenBSD: pcap-bpf.c,v 1.6 1996/07/12 13:19:10 mickey Exp $ */ /* - * Copyright (c) 1993, 1994 + * Copyright (c) 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,25 +22,29 @@ */ #ifndef lint static char rcsid[] = - "@(#)Header: pcap-bpf.c,v 1.14 94/06/03 19:58:49 leres Exp (LBL)"; + "@(#)Header: pcap-bpf.c,v 1.25 96/06/24 02:50:11 leres Exp (LBL)"; #endif -#include <stdio.h> -#include <netdb.h> -#include <ctype.h> -#include <signal.h> -#include <errno.h> #include <sys/param.h> /* optionally get BSD define */ #include <sys/time.h> #include <sys/timeb.h> #include <sys/socket.h> #include <sys/file.h> #include <sys/ioctl.h> + #include <net/bpf.h> #include <net/if.h> -#include <string.h> -#ifdef __NetBSD__ + +#include <ctype.h> +#include <errno.h> #include <stdlib.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" #endif #include "pcap-int.h" @@ -51,7 +54,7 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps) { struct bpf_stat s; - if (ioctl(p->fd, BIOCGSTATS, &s) < 0) { + if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) { sprintf(p->errbuf, "BIOCGSTATS: %s", pcap_strerror(errno)); return (-1); } @@ -88,8 +91,9 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) * The lseek() to 0 will fix things. */ case EINVAL: - if ((long)(tell(p->fd) + p->bufsize) < 0) { - (void)lseek(p->fd, 0, 0); + if (lseek(p->fd, 0L, SEEK_CUR) + + p->bufsize < 0) { + (void)lseek(p->fd, 0L, SEEK_SET); goto again; } /* fall through */ @@ -133,7 +137,7 @@ pcap_inject(pcap_t *p, const void *buf, size_t len) return (write(p->fd, buf, len)); } -static __inline int +static inline int bpf_open(pcap_t *p, char *errbuf) { int fd; @@ -220,7 +224,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) goto bad; } p->bufsize = v; - p->buffer = (u_char*)malloc(p->bufsize); + p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { sprintf(ebuf, "malloc: %s", pcap_strerror(errno)); goto bad; @@ -228,6 +232,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) return (p); bad: + (void)close(fd); free(p); return (NULL); } diff --git a/lib/libpcap/pcap-int.h b/lib/libpcap/pcap-int.h index a6eb72b6d49..697c09f97d5 100644 --- a/lib/libpcap/pcap-int.h +++ b/lib/libpcap/pcap-int.h @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: pcap-int.h,v 1.2 1995/03/06 11:38:47 mycroft Exp $ */ +/* $OpenBSD: pcap-int.h,v 1.4 1996/07/12 13:19:11 mickey Exp $ */ /* - * Copyright (c) 1994 + * Copyright (c) 1994, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) Header: pcap-int.h,v 1.7 94/06/14 20:03:33 leres Exp (LBL) + * @(#) Header: pcap-int.h,v 1.14 95/10/21 22:04:49 leres Exp (LBL) */ #ifndef pcap_int_h @@ -54,14 +53,13 @@ struct pcap_sf { struct pcap_md { struct pcap_stat stat; -#ifdef PCAP_PF + /*XXX*/ int use_bpf; u_long TotPkts; /* can't oflow for 79 hrs on ether */ u_long TotAccepted; /* count accepted by filter */ u_long TotDrops; /* count of dropped packets */ long TotMissed; /* missed by i/f during this run */ long OrigMissed; /* missed by i/f before this run */ -#endif }; struct pcap { @@ -95,7 +93,14 @@ struct pcap { char errbuf[PCAP_ERRBUF_SIZE]; }; +int yylex(void); + /* XXX should these be in pcap.h? */ int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *); int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *); + +/* Ultrix pads to make everything line up on a nice boundary */ +#if defined(ultrix) || defined(__alpha) +#define PCAP_FDDIPAD 3 +#endif #endif diff --git a/lib/libpcap/pcap-namedb.h b/lib/libpcap/pcap-namedb.h index 8547c2e9769..1d0fd07d706 100644 --- a/lib/libpcap/pcap-namedb.h +++ b/lib/libpcap/pcap-namedb.h @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: pcap-namedb.h,v 1.2.6.1 1996/06/05 18:04:40 cgd Exp $ */ +/* $OpenBSD: pcap-namedb.h,v 1.4 1996/07/12 13:19:11 mickey Exp $ */ /* - * Copyright (c) 1994 + * Copyright (c) 1994, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) Header: pcap-namedb.h,v 1.2 94/06/14 20:03:34 leres Exp (LBL) + * @(#) Header: pcap-namedb.h,v 1.4 96/06/23 02:21:08 leres Exp (LBL) */ #ifndef lib_pcap_ethers_h @@ -41,7 +40,7 @@ /* * As returned by the pcap_next_etherent() - * XXX this stuff doesn't belong in this inteface, but this + * XXX this stuff doesn't belong in this interface, but this * library already must do name to address translation, so * on systems that don't have support for /etc/ethers, we * export these hooks since they'll @@ -57,8 +56,8 @@ struct pcap_etherent *pcap_next_etherent(FILE *); u_char *pcap_ether_hostton(const char*); u_char *pcap_ether_aton(const char *); -u_int32_t **pcap_nametoaddr(const char *); -u_long pcap_nametonetaddr(const char *); +bpf_u_int32 **pcap_nametoaddr(const char *); +bpf_u_int32 pcap_nametonetaddr(const char *); int pcap_nametoport(const char *, int *, int *); int pcap_nametoproto(const char *); @@ -72,8 +71,8 @@ int pcap_nametoeproto(const char *); #define PROTO_UNDEF -1 /* XXX move these to pcap-int.h? */ -u_long __pcap_atodn(const char *); -u_long __pcap_atoin(const char *); +bpf_u_int32 __pcap_atodn(const char *); +bpf_u_int32 __pcap_atoin(const char *); u_short __pcap_nametodnaddr(const char *); #endif diff --git a/lib/libpcap/pcap.3 b/lib/libpcap/pcap.3 index fecdb0e850f..eb9f003592d 100644 --- a/lib/libpcap/pcap.3 +++ b/lib/libpcap/pcap.3 @@ -20,7 +20,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP 3 "14 Jun 1994" +.TH PCAP 3 "12 Oct 1994" .SH NAME pcap \- Packet Capture library .SH SYNOPSIS diff --git a/lib/libpcap/pcap.c b/lib/libpcap/pcap.c index 889e4aabb21..ee14262af6d 100644 --- a/lib/libpcap/pcap.c +++ b/lib/libpcap/pcap.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: pcap.c,v 1.2 1995/03/06 11:39:05 mycroft Exp $ */ +/* $OpenBSD: pcap.c,v 1.4 1996/07/12 13:19:12 mickey Exp $ */ /* - * Copyright (c) 1993, 1994 + * Copyright (c) 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,23 +35,34 @@ #ifndef lint static char rcsid[] = - "@(#) Header: pcap.c,v 1.12 94/06/12 14:32:23 leres Exp (LBL)"; + "@(#) Header: pcap.c,v 1.25 96/06/05 21:45:26 leres Exp (LBL)"; #endif #include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + #include "pcap-int.h" int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { + register int cc; + if (p->sf.rfile != NULL) return (pcap_offline_read(p, cnt, callback, user)); - else - return (pcap_read(p, cnt, callback, user)); + /* XXX keep reading until we get something (or an error occurs) */ + do { + cc = pcap_read(p, cnt, callback, user); + } while (cc == 0); + return (cc); } int @@ -60,7 +70,7 @@ pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { for (;;) { int n = pcap_dispatch(p, cnt, callback, user); - if (n < 0) + if (n <= 0) return (n); if (cnt > 0) { cnt -= n; @@ -90,7 +100,7 @@ pcap_next(pcap_t *p, struct pcap_pkthdr *h) struct singleton s; s.hdr = h; - if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) < 0) + if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0) return (0); return (s.pkt); } @@ -155,8 +165,18 @@ pcap_geterr(pcap_t *p) char * pcap_strerror(int errnum) { - +#ifdef HAVE_STRERROR return (strerror(errnum)); +#else + extern int sys_nerr; + extern const char *const sys_errlist[]; + static char ebuf[20]; + + if ((unsigned int)errnum < sys_nerr) + return ((char *)sys_errlist[errnum]); + (void)sprintf(ebuf, "Unknown error: %d", errnum); + return(ebuf); +#endif } void @@ -166,7 +186,7 @@ pcap_close(pcap_t *p) if (p->fd >= 0) close(p->fd); if (p->sf.rfile != NULL) { - fclose(p->sf.rfile); + (void)fclose(p->sf.rfile); if (p->sf.base != NULL) free(p->sf.base); } else if (p->buffer != NULL) diff --git a/lib/libpcap/pcap.h b/lib/libpcap/pcap.h index 5efc16c8868..d95adc6fec4 100644 --- a/lib/libpcap/pcap.h +++ b/lib/libpcap/pcap.h @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: pcap.h,v 1.3.4.1 1996/06/05 18:04:46 cgd Exp $ */ +/* $OpenBSD: pcap.h,v 1.6 1996/07/12 13:19:12 mickey Exp $ */ /* - * Copyright (c) 1993, 1994 + * Copyright (c) 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) Header: pcap.h,v 1.15 94/06/14 20:03:34 leres Exp (LBL) + * @(#) Header: pcap.h,v 1.19 96/06/16 22:36:28 leres Exp (LBL) */ #ifndef lib_pcap_h @@ -56,8 +55,8 @@ * predates the bpf typedefs for 64-bit support. */ #if BPF_RELEASE - 0 < 199406 -typedef int32_t bpf_int32; -typedef u_int32_t bpf_u_int32; +typedef int bpf_int32; +typedef u_int bpf_u_int32; #endif typedef struct pcap pcap_t; @@ -66,7 +65,7 @@ typedef struct pcap_dumper pcap_dumper_t; /* * The first record in the file contains saved values for some * of the flags used in the printout phases of tcpdump. - * Many fields here are longs so compilers won't insert unwanted + * Many fields here are 32 bit ints so compilers won't insert unwanted * padding; these files need to be interchangeable across architectures. */ struct pcap_file_header { @@ -103,7 +102,7 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *); char *pcap_lookupdev(char *); -int pcap_lookupnet(char *, u_int32_t *, u_int32_t *, char *); +int pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *); pcap_t *pcap_open_live(char *, int, int, int, char *); pcap_t *pcap_open_offline(char *, char *); void pcap_close(pcap_t *); @@ -116,7 +115,8 @@ int pcap_setfilter(pcap_t *, struct bpf_program *); void pcap_perror(pcap_t *, char *); char *pcap_strerror(int); char *pcap_geterr(pcap_t *); -int pcap_compile(pcap_t *, struct bpf_program *, char *, int, u_int32_t); +int pcap_compile(pcap_t *, struct bpf_program *, char *, int, + bpf_u_int32); /* XXX */ int pcap_freecode(pcap_t *, struct bpf_program *); int pcap_datalink(pcap_t *); @@ -137,4 +137,7 @@ void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); char *bpf_image(struct bpf_insn *, int); +/* XXX */ +extern int pcap_fddipad; + #endif diff --git a/lib/libpcap/savefile.c b/lib/libpcap/savefile.c index 99a1adae3ca..7713291e0d1 100644 --- a/lib/libpcap/savefile.c +++ b/lib/libpcap/savefile.c @@ -1,8 +1,7 @@ -/* $OpenBSD */ -/* $NetBSD: savefile.c,v 1.2 1995/03/06 11:39:10 mycroft Exp $ */ +/* $OpenBSD: savefile.c,v 1.4 1996/07/12 13:19:13 mickey Exp $ */ /* - * Copyright (c) 1993, 1994 + * Copyright (c) 1993, 1994, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,7 +22,7 @@ */ #ifndef lint static char rcsid[] = - "@(#)Header: savefile.c,v 1.16 94/06/20 19:07:56 leres Exp (LBL)"; + "@(#)Header: savefile.c,v 1.28 95/10/07 03:09:06 leres Exp (LBL)"; #endif /* @@ -48,6 +47,10 @@ static char rcsid[] = #include <stdlib.h> #include <unistd.h> +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + #include "pcap-int.h" #define TCPDUMP_MAGIC 0xa1b2c3d4 @@ -117,11 +120,7 @@ pcap_open_offline(char *fname, char *errbuf) return (NULL); } -#ifdef notdef - bzero(p, sizeof(*p)); -#else - memset(p, 0, sizeof(*p)); -#endif + memset((char *)p, 0, sizeof(*p)); /* * Set this field so we don't close stdin in pcap_close! */ @@ -157,8 +156,25 @@ pcap_open_offline(char *fname, char *errbuf) p->linktype = hdr.linktype; p->sf.rfile = fp; p->bufsize = hdr.snaplen; + /* Align link header as required for proper data alignment */ - linklen = 14; /* XXX */ + /* XXX should handle all types */ + switch (p->linktype) { + + case DLT_EN10MB: + linklen = 14; + break; + + case DLT_FDDI: + linklen = 13 + 8; /* fddi_header + llc */ + break; + + case DLT_NULL: + default: + linklen = 0; + break; + } + p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); p->sf.version_major = hdr.version_major; @@ -207,15 +223,38 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) } if (hdr->caplen > buflen) { - sprintf(p->errbuf, "bad dump file format"); - return (-1); - } + /* + * This can happen due to Solaris 2.3 systems tripping + * over the BUFMOD problem and not setting the snapshot + * correctly in the savefile header. If the caplen isn't + * grossly wrong, try to salvage. + */ + static u_char *tp = NULL; + static int tsize = 0; + + if (tsize < hdr->caplen) { + tsize = ((hdr->caplen + 1023) / 1024) * 1024; + if (tp != NULL) + free((u_char *)tp); + tp = (u_char *)malloc(tsize); + if (tp == NULL) { + sprintf(p->errbuf, "BUFMOD hack malloc"); + return (-1); + } + } + if (fread((char *)tp, hdr->caplen, 1, fp) != 1) { + sprintf(p->errbuf, "truncated dump file"); + return (-1); + } + memcpy((char *)buf, (char *)tp, buflen); - /* read the packet itself */ + } else { + /* read the packet itself */ - if (fread((char *)buf, hdr->caplen, 1, fp) != 1) { - sprintf(p->errbuf, "truncated dump file"); - return (-1); + if (fread((char *)buf, hdr->caplen, 1, fp) != 1) { + sprintf(p->errbuf, "truncated dump file"); + return (-1); + } } return (0); } @@ -235,8 +274,11 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) struct pcap_pkthdr h; status = sf_next_packet(p, &h, p->buffer, p->bufsize); - if (status) - return (-1); + if (status) { + if (status == 1) + return (0); + return (status); + } if (fcode == NULL || bpf_filter(fcode, p->buffer, h.len, h.caplen)) { @@ -255,7 +297,10 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) void pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { - FILE * f = (FILE *)user; + register FILE *f; + + f = (FILE *)user; + /* XXX we should check the return status */ (void)fwrite((char *)h, sizeof(*h), 1, f); (void)fwrite((char *)sp, h->caplen, 1, f); } @@ -284,5 +329,11 @@ pcap_dump_open(pcap_t *p, char *fname) void pcap_dump_close(pcap_dumper_t *p) { - fclose((FILE *)p); + +#ifdef notyet + if (ferror((FILE *)p)) + return-an-error; + /* XXX should check return from fclose() too */ +#endif + (void)fclose((FILE *)p); } diff --git a/lib/libpcap/scanner.l b/lib/libpcap/scanner.l index 89c0b8c59e9..55828db9983 100644 --- a/lib/libpcap/scanner.l +++ b/lib/libpcap/scanner.l @@ -1,9 +1,8 @@ %{ -/* $OpenBSD */ -/* $NetBSD: scanner.l,v 1.2 1995/03/06 11:39:12 mycroft Exp $ */ +/* $OpenBSD: scanner.l,v 1.5 1996/07/12 13:19:13 mickey Exp $ */ /* - * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,23 +24,26 @@ #ifndef lint static char rcsid[] = - "@(#) Header: scanner.l,v 1.40 94/06/10 17:21:44 mccanne Exp (LBL)"; + "@(#) $Header: /cvs/OpenBSD/src/lib/libpcap/scanner.l,v 1.5 1996/07/12 13:19:13 mickey Exp $ (LBL)"; #endif #include <sys/types.h> #include <sys/time.h> #include <ctype.h> +#include <unistd.h> + #include <pcap.h> #include <pcap-namedb.h> +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "pcap-int.h" #include "gencode.h" #include "grammar.tab.h" -#ifndef __GNUC__ -#define inline -#endif - static int stoi(char *); static inline int xdtoi(int); @@ -89,6 +91,7 @@ ip return IP; tcp return TCP; udp return UDP; icmp return ICMP; +igmp return IGMP; decnet return DECNET; lat return LAT; diff --git a/lib/libpcap/shlib_version b/lib/libpcap/shlib_version index 97c9f92d6b8..dea2b62cafc 100644 --- a/lib/libpcap/shlib_version +++ b/lib/libpcap/shlib_version @@ -1,2 +1,2 @@ major=0 -minor=0 +minor=2 |