support IPv6 address and IPv6 protocols.

"tcp" will match both IPv4 TCP and IPv6 TCP.
"ip6" will match IPv6.
you can chase header chain by using "protochain" instead of "proto"
(but bpf code is not optimizable in this case)

commit to tcpdump will follow.

I've sent this fix to LBL guys to get no response.  I wonder why it was.
This commit is contained in:
itojun 1999-07-02 10:05:22 +00:00
parent 22b07aaafd
commit c6f88a42f4
9 changed files with 1019 additions and 44 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.17 1998/11/01 03:48:35 lukem Exp $
# $NetBSD: Makefile,v 1.18 1999/07/02 10:05:22 itojun Exp $
LIB= pcap
MAN= pcap.3
@ -6,6 +6,7 @@ MAN= pcap.3
LEX= flex
CPPFLAGS+=-I. -I${.CURDIR} -DYYBISON
CPPFLAGS+=-DINET6
CPPFLAGS+=-DHAVE_MALLOC_H=1 -DHAVE_SYS_IOCCOM_H=1 -DHAVE_SYS_SOCKIO_H=1
CPPFLAGS+=-DHAVE_ETHER_HOSTTON=1 -DHAVE_STRERROR=1 -DHAVE_SOCKADDR_SA_LEN=1
CFPPLAGS+=-DLBL_ALIGN=1

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: gencode.h,v 1.5 1997/10/03 15:53:06 christos Exp $ */
/* $NetBSD: gencode.h,v 1.6 1999/07/02 10:05:22 itojun Exp $ */
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
@ -33,6 +33,7 @@
#define Q_PORT 3
#define Q_GATEWAY 4
#define Q_PROTO 5
#define Q_PROTOCHAIN 6
/* Protocol qualifiers. */
@ -54,6 +55,14 @@
#define Q_MOPRC 14
#define Q_MOPDL 15
#define Q_IPV6 16
#define Q_ICMPV6 17
#define Q_AH 18
#define Q_ESP 19
#define Q_PIM 20
/* Directional qualifiers. */
#define Q_SRC 1
@ -64,8 +73,12 @@
#define Q_DEFAULT 0
#define Q_UNDEF 255
struct slist;
struct stmt {
int code;
struct slist *jt; /*only for relative jump in block*/
struct slist *jf; /*only for relative jump in block*/
bpf_int32 k;
};
@ -149,9 +162,14 @@ void gen_and(struct block *, struct block *);
void gen_or(struct block *, struct block *);
void gen_not(struct block *);
struct stmt *gen_joinsp __P((struct stmt **, int));
struct block *gen_protochain __P((int, int, int));
struct block *gen_scode(const char *, struct qual);
struct block *gen_ecode(const u_char *, struct qual);
struct block *gen_mcode(const char *, const char *, int, struct qual);
#ifdef INET6
struct block *gen_mcode6(const char *, const char *, int, struct qual);
#endif
struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
struct block *gen_proto_abbrev(int);
struct block *gen_relation(int, struct arth *, struct arth *, int);
@ -179,3 +197,5 @@ void sappend(struct slist *, struct slist *);
/* XXX */
#define JT(b) ((b)->et.succ)
#define JF(b) ((b)->ef.succ)
extern int no_optimize;

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: grammar.y,v 1.5 1997/10/03 15:53:07 christos Exp $ */
/* $NetBSD: grammar.y,v 1.6 1999/07/02 10:05:22 itojun Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
@ -28,7 +28,7 @@
static const char rcsid[] =
"@(#) Header: grammar.y,v 1.56 96/11/02 21:54:55 leres Exp (LBL)";
#else
__RCSID("$NetBSD: grammar.y,v 1.5 1997/10/03 15:53:07 christos Exp $");
__RCSID("$NetBSD: grammar.y,v 1.6 1999/07/02 10:05:22 itojun Exp $");
#endif
#endif
@ -113,20 +113,21 @@ pcap_parse()
%type <rblk> other
%token DST SRC HOST GATEWAY
%token NET MASK PORT LESS GREATER PROTO BYTE
%token ARP RARP IP TCP UDP ICMP IGMP IGRP
%token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE
%token ARP RARP IP TCP UDP ICMP IGMP IGRP PIM
%token ATALK DECNET LAT SCA MOPRC MOPDL
%token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND
%token LINK
%token GEQ LEQ NEQ
%token ID EID HID
%token ID EID HID HID6
%token LSH RSH
%token LEN
%token IPV6 ICMPV6 AH ESP
%type <s> ID
%type <e> EID
%type <s> HID
%type <s> HID HID6
%type <i> NUM
%left OR AND
@ -178,6 +179,24 @@ nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
break;
}
}
| HID6 '/' NUM {
#ifdef INET6
$$.b = gen_mcode6($1, NULL, $3,
$$.q = $<blk>0.q);
#else
bpf_error("'ip6addr/prefixlen' not supported "
"in this configuration");
#endif /*INET6*/
}
| HID6 {
#ifdef INET6
$$.b = gen_mcode6($1, 0, 128,
$$.q = $<blk>0.q);
#else
bpf_error("'ip6addr' not supported "
"in this configuration");
#endif /*INET6*/
}
| EID { $$.b = gen_ecode($1, $$.q = $<blk>0.q); }
| not id { gen_not($2.b); $$ = $2; }
;
@ -200,6 +219,7 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
| pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
| pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
| pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
| pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
;
rterm: head id { $$ = $2; }
@ -240,12 +260,17 @@ pname: LINK { $$ = Q_LINK; }
| ICMP { $$ = Q_ICMP; }
| IGMP { $$ = Q_IGMP; }
| IGRP { $$ = Q_IGRP; }
| PIM { $$ = Q_PIM; }
| ATALK { $$ = Q_ATALK; }
| DECNET { $$ = Q_DECNET; }
| LAT { $$ = Q_LAT; }
| SCA { $$ = Q_SCA; }
| MOPDL { $$ = Q_MOPDL; }
| MOPRC { $$ = Q_MOPRC; }
| IPV6 { $$ = Q_IPV6; }
| ICMPV6 { $$ = Q_ICMPV6; }
| AH { $$ = Q_AH; }
| ESP { $$ = Q_ESP; }
;
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
| pqual TK_MULTICAST { $$ = gen_multicast($1); }

View File

@ -1,4 +1,4 @@
/* $NetBSD: nametoaddr.c,v 1.9 1997/11/05 21:37:27 cgd Exp $ */
/* $NetBSD: nametoaddr.c,v 1.10 1999/07/02 10:05:22 itojun Exp $ */
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
@ -30,7 +30,7 @@
static const char rcsid[] =
"@(#) Header: nametoaddr.c,v 1.47 97/06/13 13:16:19 leres Exp (LBL)";
#else
__RCSID("$NetBSD: nametoaddr.c,v 1.9 1997/11/05 21:37:27 cgd Exp $");
__RCSID("$NetBSD: nametoaddr.c,v 1.10 1999/07/02 10:05:22 itojun Exp $");
#endif
#endif
@ -46,12 +46,12 @@ struct rtentry;
#include <net/if.h>
#include <netinet/in.h>
#ifdef __NetBSD__
#include <net/if_ether.h>
#else
#include <netinet/if_ether.h>
#endif
#include <arpa/inet.h>
#ifdef INET6
#include <netdb.h>
#include <sys/socket.h>
#endif /*INET6*/
#include <ctype.h>
#include <errno.h>
@ -105,6 +105,23 @@ pcap_nametoaddr(const char *name)
return 0;
}
#ifdef INET6
struct addrinfo *
pcap_nametoaddrinfo(const char *name)
{
struct addrinfo hints, *res;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
error = getaddrinfo(name, NULL, &hints, &res);
if (error)
return NULL;
else
return res;
}
#endif /*INET6*/
/*
* Convert net name to internet address.
* Return 0 upon failure.
@ -196,6 +213,9 @@ struct eproto eproto_db[] = {
{ "pup", ETHERTYPE_PUP },
{ "xns", ETHERTYPE_NS },
{ "ip", ETHERTYPE_IP },
#ifdef INET6
{ "ip6", ETHERTYPE_IPV6 },
#endif
{ "arp", ETHERTYPE_ARP },
{ "rarp", ETHERTYPE_REVARP },
{ "sprite", ETHERTYPE_SPRITE },

View File

@ -1,4 +1,4 @@
/* $NetBSD: optimize.c,v 1.7 1997/10/03 15:53:11 christos Exp $ */
/* $NetBSD: optimize.c,v 1.8 1999/07/02 10:05:22 itojun Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
@ -28,7 +28,7 @@
static const char rcsid[] =
"@(#) Header: optimize.c,v 1.60 96/09/26 23:28:14 leres Exp (LBL)";
#else
__RCSID("$NetBSD: optimize.c,v 1.7 1997/10/03 15:53:11 christos Exp $");
__RCSID("$NetBSD: optimize.c,v 1.8 1999/07/02 10:05:22 itojun Exp $");
#endif
#endif
@ -1111,6 +1111,14 @@ opt_blk(b, do_stmts)
int i;
bpf_int32 aval;
#if 0
for (s = b->stmts; s && s->next; s = s->next)
if (BPF_CLASS(s->s.code) == BPF_JMP) {
do_stmts = 0;
break;
}
#endif
/*
* Initialize the atom values.
* If we have no predecessors, everything is undefined.
@ -1480,8 +1488,6 @@ opt_blks(root, do_stmts)
init_val();
maxlevel = root->level;
find_inedges(root);
for (i = maxlevel; i >= 0; --i)
for (p = levels[i]; p; p = p->link)
opt_blk(p, do_stmts);
@ -1499,8 +1505,6 @@ opt_blks(root, do_stmts)
opt_j(&p->ef);
}
}
find_inedges(root);
for (i = 1; i <= maxlevel; ++i) {
for (p = levels[i]; p; p = p->link) {
or_pullup(p);
@ -1580,6 +1584,7 @@ opt_loop(root, do_stmts)
find_levels(root);
find_dom(root);
find_closure(root);
find_inedges(root);
find_ud(root);
find_edom(root);
opt_blks(root, do_stmts);
@ -1896,6 +1901,7 @@ convert_code_r(p)
int slen;
u_int off;
int extrajmps; /* number of extra jumps inserted */
struct slist **offset;
if (p == 0 || isMarked(p))
return (1);
@ -1912,13 +1918,88 @@ convert_code_r(p)
p->offset = dst - fstart;
/* generate offset[] for convenience */
offset = (struct slist **)calloc(sizeof(struct slist *), slen);
if (!offset) {
bpf_error("not enough core");
/*NOTREACHED*/
}
src = p->stmts;
for (off = 0; off < slen && src; off++) {
#if 0
printf("off=%d src=%x\n", off, src);
#endif
offset[off] = src;
src = src->next;
}
off = 0;
for (src = p->stmts; src; src = src->next) {
if (src->s.code == NOP)
continue;
dst->code = (u_short)src->s.code;
dst->k = src->s.k;
++dst;
/* fill block-local relative jump */
if (BPF_CLASS(src->s.code) != BPF_JMP
|| src->s.code == (BPF_JMP|BPF_JA)) {
#if 0
if (src->s.jt || src->s.jf) {
bpf_error("illegal jmp destination");
/*NOTREACHED*/
}
#endif
goto filled;
}
if (off == slen - 2) /*???*/
goto filled;
{
int i;
int jt, jf;
char *ljerr = "%s for block-local relative jump: off=%d";
#if 0
printf("code=%x off=%d %x %x\n", src->s.code,
off, src->s.jt, src->s.jf);
#endif
if (!src->s.jt || !src->s.jf) {
bpf_error(ljerr, "no jmp destination", off);
/*NOTREACHED*/
}
jt = jf = 0;
for (i = 0; i < slen; i++) {
if (offset[i] == src->s.jt) {
if (jt) {
bpf_error(ljerr, "multiple matches", off);
/*NOTREACHED*/
}
dst->jt = i - off - 1;
jt++;
}
if (offset[i] == src->s.jf) {
if (jf) {
bpf_error(ljerr, "multiple matches", off);
/*NOTREACHED*/
}
dst->jf = i - off - 1;
jf++;
}
}
if (!jt || !jf) {
bpf_error(ljerr, "no destination found", off);
/*NOTREACHED*/
}
}
filled:
++dst;
++off;
}
free(offset);
#ifdef BDEBUG
bids[dst - fstart] = p->id + 1;
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: pcap-bpf.c,v 1.6 1997/10/03 15:53:12 christos Exp $ */
/* $NetBSD: pcap-bpf.c,v 1.7 1999/07/02 10:05:22 itojun Exp $ */
/*
* Copyright (c) 1993, 1994, 1995, 1996
@ -26,7 +26,7 @@
static const char rcsid[] =
"@(#) Header: pcap-bpf.c,v 1.29 96/12/31 20:53:40 leres Exp (LBL)";
#else
__RCSID("$NetBSD: pcap-bpf.c,v 1.6 1997/10/03 15:53:12 christos Exp $");
__RCSID("$NetBSD: pcap-bpf.c,v 1.7 1999/07/02 10:05:22 itojun Exp $");
#endif
#endif
@ -54,6 +54,8 @@ __RCSID("$NetBSD: pcap-bpf.c,v 1.6 1997/10/03 15:53:12 christos Exp $");
#include "os-proto.h"
#endif
#include "gencode.h"
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
@ -262,6 +264,13 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
/*
* It looks that BPF code generated by gen_protochain() is not
* compatible with some of kernel BPF code (for example BSD/OS 3.1).
* Take a safer side for now.
*/
if (no_optimize)
p->fcode = *fp;
if (p->sf.rfile != NULL)
p->fcode = *fp;
else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: pcap-namedb.h,v 1.5 1997/10/03 15:53:14 christos Exp $ */
/* $NetBSD: pcap-namedb.h,v 1.6 1999/07/02 10:05:22 itojun Exp $ */
/*
* Copyright (c) 1994, 1996
@ -57,6 +57,9 @@ u_char *pcap_ether_hostton(const char*);
u_char *pcap_ether_aton(const char *);
bpf_u_int32 **pcap_nametoaddr(const char *);
#ifdef INET6
struct addrinfo *pcap_nametoaddrinfo(const char *);
#endif
bpf_u_int32 pcap_nametonetaddr(const char *);
int pcap_nametoport(const char *, int *, int *);

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: scanner.l,v 1.6 1999/03/22 09:15:10 ross Exp $ */
/* $NetBSD: scanner.l,v 1.7 1999/07/02 10:05:22 itojun Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@ -28,7 +28,7 @@
static const char rcsid[] =
"@(#) Header: scanner.l,v 1.56 97/07/21 13:31:50 leres Exp (LBL)";
#else
__RCSID("$NetBSD: scanner.l,v 1.6 1999/03/22 09:15:10 ross Exp $");
__RCSID("$NetBSD: scanner.l,v 1.7 1999/07/02 10:05:22 itojun Exp $");
#endif
#endif
@ -42,6 +42,10 @@ __RCSID("$NetBSD: scanner.l,v 1.6 1999/03/22 09:15:10 ross Exp $");
#include "gencode.h"
#include <pcap-namedb.h>
#ifdef INET6
#include <netdb.h>
#include <sys/socket.h>
#endif /*INET6*/
#include "grammar.h"
#include "gnuc.h"
@ -83,6 +87,7 @@ static char *in_buffer;
N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
B ([0-9A-Fa-f][0-9A-Fa-f]?)
W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?)
%a 3000
@ -100,6 +105,12 @@ udp return UDP;
icmp return ICMP;
igmp return IGMP;
igrp return IGRP;
pim return PIM;
ip6 return IPV6;
icmp6 return ICMPV6;
ah return AH;
esp return ESP;
atalk return ATALK;
decnet return DECNET;
@ -113,6 +124,7 @@ net return NET;
mask return MASK;
port return PORT;
proto return PROTO;
protochain return PROTOCHAIN;
gateway return GATEWAY;
@ -143,8 +155,23 @@ outbound return OUTBOUND;
yylval.s = sdup((char *)yytext); return HID; }
{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext);
return EID; }
[0-9a-zA-Z:]*:[0-9a-zA-Z:]*(:{N}\.{N}\.{N}\.{N})? {
#ifdef INET6
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(yytext, NULL, &hints, &res))
bpf_error("bogus IPv6 address %s", yytext);
else {
yylval.e = sdup((char *)yytext); return HID6;
}
#else
bpf_error("IPv6 address %s not supported", yytext);
#endif /*INET6*/
}
{B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); }
[A-Za-z0-9][-_.A-Za-z0-9]*[.A-Za-z0-9]|[A-Za-z] {
[A-Za-z0-9][-_.A-Za-z0-9]*[.A-Za-z0-9] {
yylval.s = sdup((char *)yytext); return ID; }
"\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; }
[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+i {