summaryrefslogtreecommitdiff
path: root/lib/libpcap/gencode.c
diff options
context:
space:
mode:
authormikel <mikel@NetBSD.org>1996-12-13 08:25:54 +0000
committermikel <mikel@NetBSD.org>1996-12-13 08:25:54 +0000
commitf17c8ad1a140f8d1637204ad49d4c9d8ac61bcd0 (patch)
treea265ba5c9cf4a771e015faac361886517fb8a82e /lib/libpcap/gencode.c
parent2b79ace362e44fedd8ab602f8071736c946d6c27 (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.c451
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;