diff options
| author | mikel <mikel@NetBSD.org> | 1996-12-13 08:25:54 +0000 |
|---|---|---|
| committer | mikel <mikel@NetBSD.org> | 1996-12-13 08:25:54 +0000 |
| commit | f17c8ad1a140f8d1637204ad49d4c9d8ac61bcd0 (patch) | |
| tree | a265ba5c9cf4a771e015faac361886517fb8a82e /lib/libpcap/gencode.c | |
| parent | 2b79ace362e44fedd8ab602f8071736c946d6c27 (diff) | |
Merge libpcap-0.2.1.
Includes numerous improvements (see CHANGES), fixes PR bin/2031.
Diffstat (limited to 'lib/libpcap/gencode.c')
| -rw-r--r-- | lib/libpcap/gencode.c | 451 |
1 files changed, 291 insertions, 160 deletions
diff --git a/lib/libpcap/gencode.c b/lib/libpcap/gencode.c index 2f4f24db028..c7e4a3d4034 100644 --- a/lib/libpcap/gencode.c +++ b/lib/libpcap/gencode.c @@ -1,7 +1,7 @@ -/* $NetBSD: gencode.c,v 1.4 1996/05/29 04:05:52 cgd Exp $ */ +/* $NetBSD: gencode.c,v 1.5 1996/12/13 08:26:03 mikel 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 @@ -22,64 +22,63 @@ */ #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.88 96/07/23 01:30:41 leres Exp (LBL)"; #endif #include <sys/param.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" +#include "pcap-int.h" -#ifndef __GNUC__ -#define inline -#endif +#include "ethertype.h" +#include "gencode.h" +#include <pcap-namedb.h> -#ifndef ETHERTYPE_REVARP -#define ETHERTYPE_REVARP 0x8035 -#endif -#ifndef ETHERTYPE_MOPDL -#define ETHERTYPE_MOPDL 0x6001 -#endif -#ifndef ETHERTYPE_MOPRC -#define ETHERTYPE_MOPRC 0x6002 -#endif -#ifndef ETHERTYPE_DN -#define ETHERTYPE_DN 0x6003 -#endif -#ifndef ETHERTYPE_LAT -#define ETHERTYPE_LAT 0x6004 +#include "gnuc.h" +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" #endif #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 { @@ -129,29 +128,25 @@ 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_bcmp(u_int, u_int, u_char *); +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, const 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_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_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); +static struct block *gen_ehostop(const u_char *, int); +static struct block *gen_fhostop(const u_char *, 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(const 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 int lookup_proto(const 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 struct slist *xfer_to_x(struct arth *); static struct slist *xfer_to_a(struct arth *); static struct block *gen_len(int, int); @@ -187,9 +182,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; + } } /* @@ -197,10 +195,11 @@ freechunks() */ char * sdup(s) - char *s; + register const char *s; { int n = strlen(s) + 1; char *cp = newchunk(n); + strcpy(cp, s); return (cp); } @@ -246,26 +245,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(); @@ -371,7 +374,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; @@ -389,8 +392,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; @@ -405,15 +408,16 @@ gen_mcmp(offset, size, v, mask) static struct block * gen_bcmp(offset, size, v) - u_int offset, size; - u_char *v; + register u_int offset, size; + register const u_char *v; { - struct block *b, *tmp; + register struct block *b, *tmp; 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]; + register const u_char *p = &v[size - 4]; + 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); @@ -421,8 +425,9 @@ gen_bcmp(offset, size, v) size -= 4; } while (size >= 2) { - u_char *p = &v[size - 2]; - int32_t w = (p[0] << 8) | p[1]; + register const u_char *p = &v[size - 2]; + bpf_int32 w = (p[0] << 8) | p[1]; + tmp = gen_cmp(offset + size - 2, BPF_H, w); if (b != NULL) gen_and(b, tmp); @@ -430,7 +435,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; @@ -446,9 +451,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) @@ -473,8 +475,8 @@ init_linktype(type) return; case DLT_NULL: - off_linktype = -1; - off_nl = 0; + off_linktype = 0; + off_nl = 4; return; case DLT_PPP: @@ -482,22 +484,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 */ @@ -545,14 +560,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; { @@ -586,17 +608,17 @@ 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; } static struct block * gen_ehostop(eaddr, dir) - u_char *eaddr; - int dir; + register const u_char *eaddr; + register int dir; { - struct block *b0, *b1; + register struct block *b0, *b1; switch (dir) { case Q_SRC: @@ -622,23 +644,30 @@ gen_ehostop(eaddr, dir) /* NOTREACHED */ } -#ifdef FDDI /* * Like gen_ehostop, but for DLT_FDDI */ static struct block * gen_fhostop(eaddr, dir) - u_char *eaddr; - int dir; + register const u_char *eaddr; + register int dir; { struct block *b0, *b1; 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); @@ -656,7 +685,6 @@ gen_fhostop(eaddr, dir) abort(); /* NOTREACHED */ } -#endif /* * This is quite tricky because there may be pad bytes in front of the @@ -678,7 +706,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; { @@ -719,23 +747,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); @@ -746,8 +776,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; { @@ -784,9 +814,21 @@ 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_IGRP: + bpf_error("'igrp' modifier applied to host"); + + case Q_ATALK: + bpf_error("ATALK host filtering not implemented"); + case Q_DECNET: return gen_dnhostop(addr, dir, off_nl); + case Q_SCA: + bpf_error("SCA host filtering not implemented"); + case Q_LAT: bpf_error("LAT host filtering not implemented"); @@ -804,8 +846,8 @@ gen_host(addr, mask, proto, dir) static struct block * gen_gateway(eaddr, alist, proto, dir) - u_char *eaddr; - u_int32_t **alist; + const u_char *eaddr; + bpf_u_int32 **alist; int proto; int dir; { @@ -821,16 +863,15 @@ 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); + b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); while (*alist) { - tmp = gen_host(**alist++, 0xffffffffL, proto, Q_OR); + tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR); gen_or(b1, tmp); b1 = tmp; } @@ -852,19 +893,34 @@ 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; + +#ifndef IPPROTO_IGRP +#define IPPROTO_IGRP 9 +#endif + case Q_IGRP: + b0 = gen_linktype(ETHERTYPE_IP); + b1 = gen_cmp(off_nl + 9, BPF_B, (long)IPPROTO_IGRP); gen_and(b0, b1); break; @@ -883,10 +939,18 @@ gen_proto_abbrev(proto) case Q_LINK: bpf_error("link layer applied in wrong context"); + case Q_ATALK: + b1 = gen_linktype(ETHERTYPE_ATALK); + break; + case Q_DECNET: b1 = gen_linktype(ETHERTYPE_DN); break; + case Q_SCA: + b1 = gen_linktype(ETHERTYPE_SCA); + break; + case Q_LAT: b1 = gen_linktype(ETHERTYPE_LAT); break; @@ -925,7 +989,7 @@ gen_ipfrag() static struct block * gen_portatom(off, v) int off; - int32_t v; + bpf_int32 v; { struct slist *s; struct block *b; @@ -950,29 +1014,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; @@ -1016,12 +1080,13 @@ gen_port(port, ip_proto, dir) static int lookup_proto(name, proto) - char *name; - int proto; + register const char *name; + register int proto; { - int v; + register int v; switch (proto) { + case Q_DEFAULT: case Q_IP: v = pcap_nametoproto(name); @@ -1058,7 +1123,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; @@ -1070,10 +1135,18 @@ gen_proto(v, proto, dir) bpf_error("rarp does not encapsulate another protocol"); /* NOTREACHED */ + case Q_ATALK: + bpf_error("atalk encapsulation is not specifiable"); + /* NOTREACHED */ + case Q_DECNET: bpf_error("decnet encapsulation is not specifiable"); /* NOTREACHED */ + case Q_SCA: + bpf_error("sca does not encapsulate another protocol"); + /* NOTREACHED */ + case Q_LAT: bpf_error("lat does not encapsulate another protocol"); /* NOTREACHED */ @@ -1101,6 +1174,14 @@ gen_proto(v, proto, dir) bpf_error("'icmp proto' is bogus"); /* NOTREACHED */ + case Q_IGMP: + bpf_error("'igmp proto' is bogus"); + /* NOTREACHED */ + + case Q_IGRP: + bpf_error("'igrp proto' is bogus"); + /* NOTREACHED */ + default: abort(); /* NOTREACHED */ @@ -1108,31 +1189,15 @@ gen_proto(v, proto, dir) /* NOTREACHED */ } -/* - * Left justify 'addr' and return its resulting network mask. - */ -static u_int32_t -net_mask(addr) - u_int32_t *addr; -{ - register u_int32_t m = 0xffffffff; - - if (*addr) - while ((*addr & 0xff000000) == 0) - *addr <<= 8, m <<= 8; - - return m; -} - struct block * gen_scode(name, q) - char *name; + register const char *name; struct qual 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; @@ -1142,28 +1207,36 @@ gen_scode(name, q) addr = pcap_nametonetaddr(name); if (addr == 0) bpf_error("unknown network '%s'", name); - mask = net_mask(&addr); + /* Left justify network addr and calculate its network mask */ + mask = 0xffffffff; + while (addr && (addr & 0xff000000) == 0) { + addr <<= 8; + mask <<= 8; + } return gen_host(addr, mask, proto, dir); case Q_DEFAULT: 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) { @@ -1177,9 +1250,9 @@ gen_scode(name, q) alist = pcap_nametoaddr(name); if (alist == NULL || *alist == NULL) bpf_error("unknown host '%s'", name); - b = gen_host(**alist++, 0xffffffffL, proto, dir); + b = gen_host(**alist++, 0xffffffff, proto, dir); while (*alist) { - tmp = gen_host(**alist++, 0xffffffffL, + tmp = gen_host(**alist++, 0xffffffff, proto, dir); gen_or(b, tmp); b = tmp; @@ -1234,13 +1307,57 @@ gen_scode(name, q) } struct block * -gen_ncode(v, q) - u_int32_t v; +gen_mcode(s1, s2, masklen, q) + register const char *s1, *s2; + register int masklen; + struct qual q; +{ + register int nlen, mlen; + bpf_u_int32 n, m; + + nlen = __pcap_atoin(s1, &n); + /* Promote short ipaddr */ + n <<= 32 - nlen; + + if (s2 != NULL) { + mlen = __pcap_atoin(s2, &m); + /* Promote short ipaddr */ + m <<= 32 - mlen; + } else { + /* Convert mask len to mask */ + if (masklen > 32) + bpf_error("mask length must be <= 32"); + m = 0xffffffff << (32 - masklen); + } + + switch (q.addr) { + + case Q_NET: + return gen_host(n, m, q.proto, q.dir); + + default: + bpf_error("Mask syntax for networks only"); + /* NOTREACHED */ + } +} + +struct block * +gen_ncode(s, v, q) + register const char *s; + bpf_u_int32 v; struct qual q; { - u_int32_t mask; + bpf_u_int32 mask; int proto = q.proto; int dir = q.dir; + register int vlen; + + if (s == NULL) + vlen = 32; + else if (q.proto == Q_DECNET) + vlen = __pcap_atodn(s, &v); + else + vlen = __pcap_atoin(s, &v); switch (q.addr) { @@ -1252,7 +1369,18 @@ gen_ncode(v, q) else if (proto == Q_LINK) { bpf_error("illegal link layer address"); } else { - mask = net_mask(&v); + mask = 0xffffffff; + if (s == NULL && q.addr == Q_NET) { + /* Promote short net number */ + while (v && (v & 0xff000000) == 0) { + v <<= 8; + mask <<= 8; + } + } else { + /* Promote short ipaddr */ + v <<= 32 - vlen; + mask <<= 32 - vlen; + } return gen_host(v, mask, proto, dir); } @@ -1288,16 +1416,14 @@ gen_ncode(v, q) struct block * gen_ecode(eaddr, q) - u_char *eaddr; + register const u_char *eaddr; struct qual 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 */ @@ -1380,7 +1506,9 @@ gen_load(proto, index, size) case Q_IP: case Q_ARP: case Q_RARP: + case Q_ATALK: case Q_DECNET: + case Q_SCA: case Q_LAT: case Q_MOPRC: case Q_MOPDL: @@ -1400,6 +1528,8 @@ gen_load(proto, index, size) case Q_TCP: case Q_UDP: case Q_ICMP: + case Q_IGMP: + case Q_IGRP: s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); s->s.k = off_nl; sappend(s, xfer_to_a(index)); @@ -1436,6 +1566,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); @@ -1592,10 +1726,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; } @@ -1631,16 +1764,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; @@ -1664,7 +1797,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 }; @@ -1674,19 +1807,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; @@ -1730,7 +1861,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; |
