Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libpcap support IPv6 address and IPv6 protocols.



details:   https://anonhg.NetBSD.org/src/rev/b850890a04c0
branches:  trunk
changeset: 474257:b850890a04c0
user:      itojun <itojun%NetBSD.org@localhost>
date:      Fri Jul 02 10:05:22 1999 +0000

description:
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.

diffstat:

 lib/libpcap/Makefile      |    3 +-
 lib/libpcap/gencode.c     |  825 ++++++++++++++++++++++++++++++++++++++++++++-
 lib/libpcap/gencode.h     |   22 +-
 lib/libpcap/grammar.y     |   37 +-
 lib/libpcap/nametoaddr.c  |   32 +-
 lib/libpcap/optimize.c    |   93 ++++-
 lib/libpcap/pcap-bpf.c    |   13 +-
 lib/libpcap/pcap-namedb.h |    5 +-
 lib/libpcap/scanner.l     |   33 +-
 9 files changed, 1019 insertions(+), 44 deletions(-)

diffs (truncated from 1635 to 300 lines):

diff -r ed1e7d125e49 -r b850890a04c0 lib/libpcap/Makefile
--- a/lib/libpcap/Makefile      Fri Jul 02 10:00:59 1999 +0000
+++ b/lib/libpcap/Makefile      Fri Jul 02 10:05:22 1999 +0000
@@ -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 @@
 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
diff -r ed1e7d125e49 -r b850890a04c0 lib/libpcap/gencode.c
--- a/lib/libpcap/gencode.c     Fri Jul 02 10:00:59 1999 +0000
+++ b/lib/libpcap/gencode.c     Fri Jul 02 10:05:22 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gencode.c,v 1.12 1999/05/15 17:39:07 thorpej Exp $     */
+/*     $NetBSD: gencode.c,v 1.13 1999/07/02 10:05:22 itojun Exp $      */
 
 /*
  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -26,7 +26,7 @@
 static const char rcsid[] =
     "@(#) Header: gencode.c,v 1.93 97/06/12 14:22:47 leres Exp  (LBL)";
 #else
-__RCSID("$NetBSD: gencode.c,v 1.12 1999/05/15 17:39:07 thorpej Exp $");
+__RCSID("$NetBSD: gencode.c,v 1.13 1999/07/02 10:05:22 itojun Exp $");
 #endif
 #endif
 
@@ -63,6 +63,10 @@
 #include "gencode.h"
 #include "ppp.h"
 #include <pcap-namedb.h>
+#ifdef INET6
+#include <netdb.h>
+#include <sys/socket.h>
+#endif /*INET6*/
 
 #include "gnuc.h"
 #ifdef HAVE_OS_PROTO_H
@@ -147,15 +151,28 @@
 static inline struct block *gen_false(void);
 static struct block *gen_linktype(int);
 static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
+#ifdef INET6
+static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
+#endif
 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);
+#ifdef INET6
+static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int);
+#endif
 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, bpf_int32);
+#ifdef INET6
+static struct block *gen_portatom6(int, bpf_int32);
+#endif
 struct block *gen_portop(int, int, int);
 static struct block *gen_port(int, int, int);
+#ifdef INET6
+struct block *gen_portop6(int, int, int);
+static struct block *gen_port6(int, int, int);
+#endif
 static int lookup_proto(const char *, int);
 static struct block *gen_proto(int, int, int);
 static struct slist *xfer_to_x(struct arth *);
@@ -258,6 +275,7 @@
 
 static bpf_u_int32 netmask;
 static int snaplen;
+int no_optimize;
 
 int
 pcap_compile(pcap_t *p, struct bpf_program *program,
@@ -266,6 +284,7 @@
        extern int n_errors;
        int len;
 
+       no_optimize = 0;
        n_errors = 0;
        root = NULL;
        bpf_pcap = p;
@@ -287,7 +306,7 @@
        if (root == NULL)
                root = gen_retblk(snaplen);
 
-       if (optimize) {
+       if (optimize && !no_optimize) {
                bpf_optimize(&root);
                if (root == NULL ||
                    (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
@@ -643,6 +662,10 @@
                /* XXX */
                if (proto == ETHERTYPE_IP)
                        return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET)));
+#ifdef INET6
+               if (proto == ETHERTYPE_IPV6)
+                       return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET6)));
+#endif /* INET6 */
                else
                        return gen_false();
        }
@@ -691,6 +714,61 @@
        return b1;
 }
 
+#ifdef INET6
+static struct block *
+gen_hostop6(addr, mask, dir, proto, src_off, dst_off)
+       struct in6_addr *addr;
+       struct in6_addr *mask;
+       int dir, proto;
+       u_int src_off, dst_off;
+{
+       struct block *b0, *b1;
+       u_int offset;
+
+       switch (dir) {
+
+       case Q_SRC:
+               offset = src_off;
+               break;
+
+       case Q_DST:
+               offset = dst_off;
+               break;
+
+       case Q_AND:
+               b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
+               b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
+               gen_and(b0, b1);
+               return b1;
+
+       case Q_OR:
+       case Q_DEFAULT:
+               b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
+               b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
+               gen_or(b0, b1);
+               return b1;
+
+       default:
+               abort();
+       }
+       /* this order is important */
+       b1 = gen_mcmp(offset + 12, BPF_W, ntohl(addr->s6_addr32[3]),
+               ntohl(mask->s6_addr32[3]));
+       b0 = gen_mcmp(offset + 8, BPF_W, ntohl(addr->s6_addr32[2]),
+               ntohl(mask->s6_addr32[2]));
+       gen_and(b0, b1);
+       b0 = gen_mcmp(offset + 4, BPF_W, ntohl(addr->s6_addr32[1]),
+               ntohl(mask->s6_addr32[1]));
+       gen_and(b0, b1);
+       b0 = gen_mcmp(offset + 0, BPF_W, ntohl(addr->s6_addr32[0]),
+               ntohl(mask->s6_addr32[0]));
+       gen_and(b0, b1);
+       b0 = gen_linktype(proto);
+       gen_and(b0, b1);
+       return b1;
+}
+#endif /*INET6*/
+
 static struct block *
 gen_ehostop(eaddr, dir)
        register const u_char *eaddr;
@@ -898,6 +976,9 @@
        case Q_IGRP:
                bpf_error("'igrp' modifier applied to host");
 
+       case Q_PIM:
+               bpf_error("'pim' modifier applied to host");
+
        case Q_ATALK:
                bpf_error("ATALK host filtering not implemented");
 
@@ -916,12 +997,104 @@
        case Q_MOPRC:
                bpf_error("MOPRC host filtering not implemented");
 
+#ifdef INET6
+       case Q_IPV6:
+               bpf_error("'ip6' modifier applied to ip host");
+
+       case Q_ICMPV6:
+               bpf_error("'icmp6' modifier applied to host");
+#endif /* INET6 */
+
+       case Q_AH:
+               bpf_error("'ah' modifier applied to host");
+
+       case Q_ESP:
+               bpf_error("'esp' modifier applied to host");
+
        default:
                abort();
        }
        /* NOTREACHED */
 }
 
+#ifdef INET6
+static struct block *
+gen_host6(addr, mask, proto, dir)
+       struct in6_addr *addr;
+       struct in6_addr *mask;
+       int proto;
+       int dir;
+{
+       switch (proto) {
+
+       case Q_DEFAULT:
+               return gen_host6(addr, mask, Q_IPV6, dir);
+
+       case Q_IP:
+               bpf_error("'ip' modifier applied to ip6 host");
+
+       case Q_RARP:
+               bpf_error("'rarp' modifier applied to ip6 host");
+
+       case Q_ARP:
+               bpf_error("'arp' modifier applied to ip6 host");
+
+       case Q_TCP:
+               bpf_error("'tcp' modifier applied to host");
+
+       case Q_UDP:
+               bpf_error("'udp' modifier applied to host");
+
+       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_PIM:
+               bpf_error("'pim' modifier applied to host");
+
+       case Q_ATALK:
+               bpf_error("ATALK host filtering not implemented");
+
+       case Q_DECNET:
+               bpf_error("'decnet' modifier applied to ip6 host");
+
+       case Q_SCA:
+               bpf_error("SCA host filtering not implemented");
+
+       case Q_LAT:
+               bpf_error("LAT host filtering not implemented");
+
+       case Q_MOPDL:
+               bpf_error("MOPDL host filtering not implemented");
+
+       case Q_MOPRC:
+               bpf_error("MOPRC host filtering not implemented");
+
+       case Q_IPV6:
+               return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6,
+                                 off_nl + 8, off_nl + 24);
+
+       case Q_ICMPV6:
+               bpf_error("'icmp6' modifier applied to host");
+
+       case Q_AH:
+               bpf_error("'ah' modifier applied to host");
+
+       case Q_ESP:
+               bpf_error("'esp' modifier applied to host");
+
+       default:
+               abort();
+       }
+       /* NOTREACHED */
+}
+#endif /*INET6*/
+
 static struct block *
 gen_gateway(eaddr, alist, proto, dir)
        const u_char *eaddr;
@@ -970,38 +1143,45 @@
        switch (proto) {
 
        case Q_TCP:
-               b0 = gen_linktype(ETHERTYPE_IP);
-               b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_TCP);
-               gen_and(b0, b1);
+               b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT);
+#ifdef INET6
+               b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
+               gen_or(b0, b1);
+#endif



Home | Main Index | Thread Index | Old Index