Import libpcap-1.4.0.
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 3 May 2014 15:46:52 +0000 (08:46 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 3 May 2014 15:46:52 +0000 (08:46 -0700)
See CHANGES for the details.

20 files changed:
contrib/libpcap/CHANGES
contrib/libpcap/README
contrib/libpcap/VERSION
contrib/libpcap/bpf_image.c
contrib/libpcap/fad-getad.c
contrib/libpcap/gencode.c
contrib/libpcap/grammar.y
contrib/libpcap/nametoaddr.c
contrib/libpcap/optimize.c
contrib/libpcap/pcap-bpf.c
contrib/libpcap/pcap-common.c
contrib/libpcap/pcap-filter.manmisc.in
contrib/libpcap/pcap-int.h
contrib/libpcap/pcap.c
contrib/libpcap/pcap/bpf.h
contrib/libpcap/pcap/pcap.h
contrib/libpcap/pcap_breakloop.3pcap
contrib/libpcap/pcap_loop.3pcap
contrib/libpcap/pcap_offline_filter.3pcap
contrib/libpcap/scanner.l

index 4f7fa35..0dcf957 100644 (file)
@@ -1,3 +1,35 @@
+Monday March 18, 2013 guy@alum.mit.edu
+Summary for 1.4.0 libpcap release
+       Add netfilter/nfqueue interface.
+       If we don't have support for IPv6 address resolution, support,
+           in filter expressions, what IPv6 stuff we can.
+       Checks added for malloc()/realloc()/etc. failures.
+       Fix pcap-config to include -lpthread if canusb support is
+           present
+       Try to fix "pcap_parse not defined" problems when --without-flex
+           and --without-bison are used when you have Flex and Bison
+       Fix some issues with the pcap_loop man page.
+       Fix pcap_getnonblock() and pcap_setnonblock() to fill in the
+           supplied error message buffer
+       Fix typo that, it appeared, would cause pcap-libdlpi.c not to
+           compile (perhaps systems with libdlpi also have BPF and use
+           that instead)
+       Catch attempts to call pcap_compile() on a non-activated pcap_t
+       Fix crash on Linux with CAN-USB support without usbfs
+       Fix addition of VLAN tags for Linux cooked captures
+       Check for both EOPNOTSUPP and EINVAL after SIOCETHTOOL ioctl, so
+           that the driver can report either one if it doesn't support
+           SIOCETHTOOL
+       Add DLT_INFINIBAND and DLT_SCTP
+       Describe "proto XXX" and "protochain XXX" in the pcap-filter man
+           page
+       Handle either directories, or symlinks to directories, that
+           correspond to interfaces in /sys/class/net
+       Fix handling of VLAN tag insertion to check, on Linux 3.x
+           kernels, for VLAN tag valid flag
+       Clean up some man pages
+       Support libnl3 as well as libnl1 and libnl2 on Linux
+
 Friday  March 30, 2012.  mcr@sandelman.ca
 Summary for 1.3.0 libpcap release
         Handle DLT_PFSYNC in {FreeBSD, other *BSD+Mac OS X, other}.
index a206474..8cac0af 100644 (file)
@@ -13,8 +13,11 @@ Anonymous Git is available via:
 Version 1.x.y of LIBPCAP can be retrieved with the CVS tag "libpcap_1_{x}rel{y}":
        cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_1_{x}rel{y} libpcap
 
-Please submit patches against the master copy to the libpcap project on
-sourceforge.net.
+Please submit patches by forking the branch on GitHub at
+
+       http://github.com/mcr/libpcap/tree/master
+
+and issuing a pull request.
 
 formerly from  Lawrence Berkeley National Laboratory
                Network Research Group <libpcap@ee.lbl.gov>
@@ -91,15 +94,18 @@ a particular release of libpcap.
 
 Problems, bugs, questions, desirable enhancements, etc. should be sent
 to the address "tcpdump-workers@lists.tcpdump.org".  Bugs, support
-requests, and feature requests may also be submitted on the SourceForge
-site for libpcap at
+requests, and feature requests may also be submitted on the GitHub issue
+tracker for libpcap at
 
-       http://sourceforge.net/projects/libpcap/
+       https://github.com/mcr/libpcap/issues
 
 Source code contributions, etc. should be sent to the email address
-submitted as patches on the SourceForge site for libpcap.
+above or submitted by forking the branch on GitHub at
+
+       http://github.com/mcr/libpcap/tree/master
+
+and issuing a pull request.
 
-Current versions can be found at www.tcpdump.org, or the SourceForge
-site for libpcap.
+Current versions can be found at www.tcpdump.org.
 
  - The TCPdump team
index e2f1a77..e6c0f62 100644 (file)
@@ -292,11 +292,14 @@ bpf_image(p, n)
                break;
        }
        (void)snprintf(operand, sizeof operand, fmt, v);
-       (void)snprintf(image, sizeof image,
-                     (BPF_CLASS(p->code) == BPF_JMP &&
-                      BPF_OP(p->code) != BPF_JA) ?
-                     "(%03d) %-8s %-16s jt %d\tjf %d"
-                     : "(%03d) %-8s %s",
-                     n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
+       if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
+               (void)snprintf(image, sizeof image,
+                             "(%03d) %-8s %-16s jt %d\tjf %d",
+                             n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
+       } else {
+               (void)snprintf(image, sizeof image,
+                             "(%03d) %-8s %s",
+                             n, op, operand);
+       }
        return image;
 }
index 742ae1f..f4d5869 100644 (file)
@@ -141,11 +141,9 @@ get_sa_len(struct sockaddr *addr)
  * Returns -1 on error, 0 otherwise.
  * The list, as returned through "alldevsp", may be null if no interfaces
  * were up and could be opened.
- *
- * This is the implementation used on platforms that have "getifaddrs()".
  */
 int
-pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
 {
        pcap_if_t *devlist = NULL;
        struct ifaddrs *ifap, *ifa;
@@ -273,15 +271,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
 
        freeifaddrs(ifap);
 
-       if (ret != -1) {
-               /*
-                * We haven't had any errors yet; do any platform-specific
-                * operations to add devices.
-                */
-               if (pcap_platform_finddevs(&devlist, errbuf) < 0)
-                       ret = -1;
-       }
-
        if (ret == -1) {
                /*
                 * We had an error; free the list we've been constructing.
index 532229a..cdb0d34 100644 (file)
@@ -107,6 +107,18 @@ static const char rcsid[] _U_ =
 
 #define ETHERMTU       1500
 
+#ifndef IPPROTO_HOPOPTS
+#define IPPROTO_HOPOPTS 0
+#endif
+#ifndef IPPROTO_ROUTING
+#define IPPROTO_ROUTING 43
+#endif
+#ifndef IPPROTO_FRAGMENT
+#define IPPROTO_FRAGMENT 44
+#endif
+#ifndef IPPROTO_DSTOPTS
+#define IPPROTO_DSTOPTS 60
+#endif
 #ifndef IPPROTO_SCTP
 #define IPPROTO_SCTP 132
 #endif
@@ -261,20 +273,16 @@ 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);
 static struct block *gen_portrangeatom(int, bpf_int32, bpf_int32);
-#ifdef INET6
 static struct block *gen_portatom6(int, bpf_int32);
 static struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32);
-#endif
 struct block *gen_portop(int, int, int);
 static struct block *gen_port(int, int, int);
 struct block *gen_portrangeop(int, int, int, int);
 static struct block *gen_portrange(int, int, int, int);
-#ifdef INET6
 struct block *gen_portop6(int, int, int);
 static struct block *gen_port6(int, int, int);
 struct block *gen_portrangeop6(int, int, int, int);
 static struct block *gen_portrange6(int, int, int, int);
-#endif
 static int lookup_proto(const char *, int);
 static struct block *gen_protochain(int, int, int);
 static struct block *gen_proto(int, int, int);
@@ -425,6 +433,15 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
        const char * volatile xbuf = buf;
        u_int len;
 
+       /*
+        * If this pcap_t hasn't been activated, it doesn't have a
+        * link-layer type, so we can't use it.
+        */
+       if (!p->activated) {
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+                   "not-yet-activated pcap_t passed to pcap_compile");
+               return (-1);
+       }
        no_optimize = 0;
        n_errors = 0;
        root = NULL;
@@ -2832,11 +2849,9 @@ ethertype_to_ppptype(proto)
                proto = PPP_IP;
                break;
 
-#ifdef INET6
        case ETHERTYPE_IPV6:
                proto = PPP_IPV6;
                break;
-#endif
 
        case ETHERTYPE_DN:
                proto = PPP_DECNET;
@@ -3044,11 +3059,10 @@ gen_linktype(proto)
                case ETHERTYPE_IP:
                        /* Check for a version number of 4. */
                        return gen_mcmp(OR_LINK, 0, BPF_B, 0x40, 0xF0);
-#ifdef INET6
+
                case ETHERTYPE_IPV6:
                        /* Check for a version number of 6. */
                        return gen_mcmp(OR_LINK, 0, BPF_B, 0x60, 0xF0);
-#endif
 
                default:
                        return gen_false();             /* always false */
@@ -3072,10 +3086,8 @@ gen_linktype(proto)
                /*
                 * Raw IPv6, so no type field.
                 */
-#ifdef INET6
                if (proto == ETHERTYPE_IPV6)
                        return gen_true();              /* always true */
-#endif
 
                /* Checking for something other than IPv6; always false */
                return gen_false();
@@ -3197,11 +3209,9 @@ gen_linktype(proto)
                if (proto == ETHERTYPE_IP)
                        return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
                            BPF_B, (bpf_int32)AF_INET));
-#ifdef INET6
                else if (proto == ETHERTYPE_IPV6)
                        return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
                            BPF_B, (bpf_int32)AF_INET6));
-#endif /* INET6 */
                else
                        return gen_false();
                /*NOTREACHED*/
@@ -3219,11 +3229,9 @@ gen_linktype(proto)
                default:
                        return gen_false();
 
-#ifdef INET6
                case ETHERTYPE_IPV6:
                        return (gen_cmp(OR_LINK, off_linktype, BPF_B,
                                (bpf_int32)ARCTYPE_INET6));
-#endif /* INET6 */
 
                case ETHERTYPE_IP:
                        b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
@@ -3275,13 +3283,11 @@ gen_linktype(proto)
                         */
                        return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0xcc);
 
-#ifdef INET6
                case ETHERTYPE_IPV6:
                        /*
                         * Check for the special NLPID for IPv6.
                         */
                        return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0x8e);
-#endif
 
                case LLCSAP_ISONS:
                        /*
@@ -3628,7 +3634,7 @@ gen_hostop6(addr, mask, dir, proto, src_off, dst_off)
        gen_and(b0, b1);
        return b1;
 }
-#endif /*INET6*/
+#endif
 
 static struct block *
 gen_ehostop(eaddr, dir)
@@ -4506,13 +4512,11 @@ gen_host(addr, mask, proto, dir, type)
        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 %s", typestr);
-#endif /* INET6 */
 
        case Q_AH:
                bpf_error("'ah' modifier applied to %s", typestr);
@@ -4669,7 +4673,7 @@ gen_host6(addr, mask, proto, dir, type)
        }
        /* NOTREACHED */
 }
-#endif /*INET6*/
+#endif
 
 #ifndef INET6
 static struct block *
@@ -4761,26 +4765,20 @@ gen_proto_abbrev(proto)
 
        case Q_SCTP:
                b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT);
-#ifdef INET6
                b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT);
                gen_or(b0, b1);
-#endif
                break;
 
        case Q_TCP:
                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
                break;
 
        case Q_UDP:
                b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT);
-#ifdef INET6
                b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
                gen_or(b0, b1);
-#endif
                break;
 
        case Q_ICMP:
@@ -4808,10 +4806,8 @@ gen_proto_abbrev(proto)
 
        case Q_PIM:
                b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT);
-#ifdef INET6
                b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
                gen_or(b0, b1);
-#endif
                break;
 
 #ifndef IPPROTO_VRRP
@@ -4873,7 +4869,6 @@ gen_proto_abbrev(proto)
                b1 =  gen_linktype(ETHERTYPE_MOPRC);
                break;
 
-#ifdef INET6
        case Q_IPV6:
                b1 = gen_linktype(ETHERTYPE_IPV6);
                break;
@@ -4884,17 +4879,14 @@ gen_proto_abbrev(proto)
        case Q_ICMPV6:
                b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT);
                break;
-#endif /* INET6 */
 
 #ifndef IPPROTO_AH
 #define IPPROTO_AH     51
 #endif
        case Q_AH:
                b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT);
-#ifdef INET6
                b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT);
                gen_or(b0, b1);
-#endif
                break;
 
 #ifndef IPPROTO_ESP
@@ -4902,10 +4894,8 @@ gen_proto_abbrev(proto)
 #endif
        case Q_ESP:
                b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT);
-#ifdef INET6
                b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
                gen_or(b0, b1);
-#endif
                break;
 
        case Q_ISO:
@@ -5038,7 +5028,6 @@ gen_portatom(off, v)
        return gen_cmp(OR_TRAN_IPV4, off, BPF_H, v);
 }
 
-#ifdef INET6
 static struct block *
 gen_portatom6(off, v)
        int off;
@@ -5046,7 +5035,6 @@ gen_portatom6(off, v)
 {
        return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v);
 }
-#endif/*INET6*/
 
 struct block *
 gen_portop(port, proto, dir)
@@ -5138,7 +5126,6 @@ gen_port(port, ip_proto, dir)
        return b1;
 }
 
-#ifdef INET6
 struct block *
 gen_portop6(port, proto, dir)
        int port, proto, dir;
@@ -5211,7 +5198,6 @@ gen_port6(port, ip_proto, dir)
        gen_and(b0, b1);
        return b1;
 }
-#endif /* INET6 */
 
 /* gen_portrange code */
 static struct block *
@@ -5316,7 +5302,6 @@ gen_portrange(port1, port2, ip_proto, dir)
        return b1;
 }
 
-#ifdef INET6
 static struct block *
 gen_portrangeatom6(off, v1, v2)
        int off;
@@ -5417,7 +5402,6 @@ gen_portrange6(port1, port2, ip_proto, dir)
        gen_and(b0, b1);
        return b1;
 }
-#endif /* INET6 */
 
 static int
 lookup_proto(name, proto)
@@ -5552,7 +5536,7 @@ gen_protochain(v, proto, dir)
                s[i]->s.k = off_macpl + off_nl;
                i++;
                break;
-#ifdef INET6
+
        case Q_IPV6:
                b0 = gen_linktype(ETHERTYPE_IPV6);
 
@@ -5565,7 +5549,7 @@ gen_protochain(v, proto, dir)
                s[i]->s.k = 40;
                i++;
                break;
-#endif
+
        default:
                bpf_error("unsupported proto to gen_protochain");
                /*NOTREACHED*/
@@ -5592,7 +5576,6 @@ gen_protochain(v, proto, dir)
        fix2 = i;
        i++;
 
-#ifdef INET6
        if (proto == Q_IPV6) {
                int v6start, v6end, v6advance, j;
 
@@ -5674,9 +5657,7 @@ gen_protochain(v, proto, dir)
                /* fixup */
                for (j = v6start; j <= v6end; j++)
                        s[j]->s.jt = s[v6advance];
-       } else
-#endif
-       {
+       } else {
                /* nop */
                s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
                s[i]->s.k = 0;
@@ -5820,10 +5801,8 @@ gen_proto(v, proto, dir)
        int dir;
 {
        struct block *b0, *b1;
-#ifdef INET6
 #ifndef CHASE_CHAIN
        struct block *b2;
-#endif
 #endif
 
        if (dir != Q_DEFAULT)
@@ -5831,14 +5810,11 @@ gen_proto(v, proto, dir)
 
        switch (proto) {
        case Q_DEFAULT:
-#ifdef INET6
                b0 = gen_proto(v, Q_IP, dir);
                b1 = gen_proto(v, Q_IPV6, dir);
                gen_or(b0, b1);
                return b1;
-#else
-               /*FALLTHROUGH*/
-#endif
+
        case Q_IP:
                /*
                 * For FDDI, RFC 1188 says that SNAP encapsulation is used,
@@ -5989,7 +5965,6 @@ gen_proto(v, proto, dir)
                bpf_error("'carp proto' is bogus");
                /* NOTREACHED */
 
-#ifdef INET6
        case Q_IPV6:
                b0 = gen_linktype(ETHERTYPE_IPV6);
 #ifndef CHASE_CHAIN
@@ -6010,7 +5985,6 @@ gen_proto(v, proto, dir)
 
        case Q_ICMPV6:
                bpf_error("'icmp6 proto' is bogus");
-#endif /* INET6 */
 
        case Q_AH:
                bpf_error("'ah proto' is bogus");
@@ -6267,13 +6241,9 @@ gen_scode(name, q)
                        bpf_error("illegal port number %d < 0", port);
                if (port > 65535)
                        bpf_error("illegal port number %d > 65535", port);
-#ifndef INET6
-               return gen_port(port, real_proto, dir);
-#else
                b = gen_port(port, real_proto, dir);
                gen_or(gen_port6(port, real_proto, dir), b);
                return b;
-#endif /* INET6 */
 
        case Q_PORTRANGE:
                if (proto != Q_DEFAULT &&
@@ -6317,13 +6287,9 @@ gen_scode(name, q)
                if (port2 > 65535)
                        bpf_error("illegal port number %d > 65535", port2);
 
-#ifndef INET6
-               return gen_portrange(port1, port2, real_proto, dir);
-#else
                b = gen_portrange(port1, port2, real_proto, dir);
                gen_or(gen_portrange6(port1, port2, real_proto, dir), b);
                return b;
-#endif /* INET6 */
 
        case Q_GATEWAY:
 #ifndef INET6
@@ -6471,16 +6437,12 @@ gen_ncode(s, v, q)
                if (v > 65535)
                        bpf_error("illegal port number %u > 65535", v);
 
-#ifndef INET6
-               return gen_port((int)v, proto, dir);
-#else
            {
                struct block *b;
                b = gen_port((int)v, proto, dir);
                gen_or(gen_port6((int)v, proto, dir), b);
                return b;
            }
-#endif /* INET6 */
 
        case Q_PORTRANGE:
                if (proto == Q_UDP)
@@ -6497,16 +6459,12 @@ gen_ncode(s, v, q)
                if (v > 65535)
                        bpf_error("illegal port number %u > 65535", v);
 
-#ifndef INET6
-               return gen_portrange((int)v, (int)v, proto, dir);
-#else
            {
                struct block *b;
                b = gen_portrange((int)v, (int)v, proto, dir);
                gen_or(gen_portrange6((int)v, (int)v, proto, dir), b);
                return b;
            }
-#endif /* INET6 */
 
        case Q_GATEWAY:
                bpf_error("'gateway' requires a name");
@@ -6796,9 +6754,7 @@ gen_load(proto, inst, size)
        case Q_LAT:
        case Q_MOPRC:
        case Q_MOPDL:
-#ifdef INET6
        case Q_IPV6:
-#endif
                /*
                 * The offset is relative to the beginning of
                 * the network-layer header.
@@ -6907,16 +6863,12 @@ gen_load(proto, inst, size)
                gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
                if (inst->b)
                        gen_and(inst->b, b);
-#ifdef INET6
                gen_and(gen_proto_abbrev(Q_IP), b);
-#endif
                inst->b = b;
                break;
-#ifdef INET6
        case Q_ICMPV6:
                bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
                /*NOTREACHED*/
-#endif
        }
        inst->regno = regno;
        s = new_stmt(BPF_ST);
@@ -7468,13 +7420,11 @@ gen_multicast(proto)
                gen_and(b0, b1);
                return b1;
 
-#ifdef INET6
        case Q_IPV6:
                b0 = gen_linktype(ETHERTYPE_IPV6);
                b1 = gen_cmp(OR_NET, 24, BPF_B, (bpf_int32)255);
                gen_and(b0, b1);
                return b1;
-#endif /* INET6 */
        }
        bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
        /* NOTREACHED */
index f2ba28b..f92e90d 100644 (file)
@@ -167,7 +167,7 @@ yyerror(const char *msg)
        /* NOTREACHED */
 }
 
-#ifndef YYBISON
+#ifdef NEED_YYPARSE_WRAPPER
 int yyparse(void);
 
 int
index 5835e4d..c0e86f4 100644 (file)
@@ -247,6 +247,7 @@ pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
                        free(cpy);
                        return 0;
                }
+               free(cpy);
 
                if (*proto != save_proto)
                        *proto = PROTO_UNDEF;
index 6bbda95..dcb104e 100644 (file)
@@ -112,51 +112,9 @@ static int cur_mark;
 static void opt_init(struct block *);
 static void opt_cleanup(void);
 
-static void make_marks(struct block *);
-static void mark_code(struct block *);
-
 static void intern_blocks(struct block *);
 
-static int eq_slist(struct slist *, struct slist *);
-
-static void find_levels_r(struct block *);
-
-static void find_levels(struct block *);
-static void find_dom(struct block *);
-static void propedom(struct edge *);
-static void find_edom(struct block *);
-static void find_closure(struct block *);
-static int atomuse(struct stmt *);
-static int atomdef(struct stmt *);
-static void compute_local_ud(struct block *);
-static void find_ud(struct block *);
-static void init_val(void);
-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 *);
-static void or_pullup(struct block *);
-static void and_pullup(struct block *);
-static void opt_blks(struct block *, int);
-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 *, 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 *, int[], int);
-static void deadstmt(struct stmt *, struct stmt *[]);
-static void opt_deadstores(struct block *);
-static struct block *fold_edge(struct block *, struct edge *);
-static inline int eq_blk(struct block *, struct block *);
-static u_int slength(struct slist *);
-static int count_blocks(struct block *);
-static void number_blks_r(struct block *);
-static u_int count_stmts(struct block *);
-static int convert_code_r(struct block *);
 #ifdef BDEBUG
 static void opt_dump(struct block *);
 #endif
@@ -232,8 +190,7 @@ static uset all_edge_sets;
 #endif
 
 static void
-find_levels_r(b)
-       struct block *b;
+find_levels_r(struct block *b)
 {
        int level;
 
@@ -261,8 +218,7 @@ find_levels_r(b)
  * with the 'link' field of the struct block.
  */
 static void
-find_levels(root)
-       struct block *root;
+find_levels(struct block *root)
 {
        memset((char *)levels, 0, n_blocks * sizeof(*levels));
        unMarkAll();
@@ -274,8 +230,7 @@ find_levels(root)
  * Assumes graph has been leveled.
  */
 static void
-find_dom(root)
-       struct block *root;
+find_dom(struct block *root)
 {
        int i;
        struct block *b;
@@ -305,8 +260,7 @@ find_dom(root)
 }
 
 static void
-propedom(ep)
-       struct edge *ep;
+propedom(struct edge *ep)
 {
        SET_INSERT(ep->edom, ep->id);
        if (ep->succ) {
@@ -320,8 +274,7 @@ propedom(ep)
  * Assumes graph has been leveled and predecessors established.
  */
 static void
-find_edom(root)
-       struct block *root;
+find_edom(struct block *root)
 {
        int i;
        uset x;
@@ -350,8 +303,7 @@ find_edom(root)
  * Assumes graph has been leveled.
  */
 static void
-find_closure(root)
-       struct block *root;
+find_closure(struct block *root)
 {
        int i;
        struct block *b;
@@ -381,8 +333,7 @@ find_closure(root)
  * The implementation should probably change to an array access.
  */
 static int
-atomuse(s)
-       struct stmt *s;
+atomuse(struct stmt *s)
 {
        register int c = s->code;
 
@@ -427,8 +378,7 @@ atomuse(s)
  * The implementation should probably change to an array access.
  */
 static int
-atomdef(s)
-       struct stmt *s;
+atomdef(struct stmt *s)
 {
        if (s->code == NOP)
                return -1;
@@ -464,8 +414,7 @@ atomdef(s)
  * register by a predecessor block of this block.
  */
 static void
-compute_local_ud(b)
-       struct block *b;
+compute_local_ud(struct block *b)
 {
        struct slist *s;
        atomset def = 0, use = 0, kill = 0;
@@ -526,8 +475,7 @@ compute_local_ud(b)
  * Assume graph is already leveled.
  */
 static void
-find_ud(root)
-       struct block *root;
+find_ud(struct block *root)
 {
        int i, maxlevel;
        struct block *p;
@@ -582,7 +530,7 @@ struct valnode *vnode_base;
 struct valnode *next_vnode;
 
 static void
-init_val()
+init_val(void)
 {
        curval = 0;
        next_vnode = vnode_base;
@@ -592,9 +540,7 @@ init_val()
 
 /* Because we really don't have an IR, this stuff is a little messy. */
 static int
-F(code, v0, v1)
-       int code;
-       int v0, v1;
+F(int code, int v0, int v1)
 {
        u_int hash;
        int val;
@@ -625,11 +571,7 @@ F(code, v0, v1)
 }
 
 static inline void
-vstore(s, valp, newval, alter)
-       struct stmt *s;
-       int *valp;
-       int newval;
-       int alter;
+vstore(struct stmt *s, int *valp, int newval, int alter)
 {
        if (alter && *valp == newval)
                s->code = NOP;
@@ -638,9 +580,7 @@ vstore(s, valp, newval, alter)
 }
 
 static void
-fold_op(s, v0, v1)
-       struct stmt *s;
-       int v0, v1;
+fold_op(struct stmt *s, int v0, int v1)
 {
        bpf_u_int32 a, b;
 
@@ -695,8 +635,7 @@ fold_op(s, v0, v1)
 }
 
 static inline struct slist *
-this_op(s)
-       struct slist *s;
+this_op(struct slist *s)
 {
        while (s != 0 && s->s.code == NOP)
                s = s->next;
@@ -704,8 +643,7 @@ this_op(s)
 }
 
 static void
-opt_not(b)
-       struct block *b;
+opt_not(struct block *b)
 {
        struct block *tmp = JT(b);
 
@@ -714,8 +652,7 @@ opt_not(b)
 }
 
 static void
-opt_peep(b)
-       struct block *b;
+opt_peep(struct block *b)
 {
        struct slist *s;
        struct slist *next, *last;
@@ -978,10 +915,7 @@ opt_peep(b)
  * evaluation and code transformations weren't folded together.
  */
 static void
-opt_stmt(s, val, alter)
-       struct stmt *s;
-       int val[];
-       int alter;
+opt_stmt(struct stmt *s, int val[], int alter)
 {
        int op;
        int v;
@@ -1166,9 +1100,7 @@ opt_stmt(s, val, alter)
 }
 
 static void
-deadstmt(s, last)
-       register struct stmt *s;
-       register struct stmt *last[];
+deadstmt(register struct stmt *s, register struct stmt *last[])
 {
        register int atom;
 
@@ -1192,8 +1124,7 @@ deadstmt(s, last)
 }
 
 static void
-opt_deadstores(b)
-       register struct block *b;
+opt_deadstores(register struct block *b)
 {
        register struct slist *s;
        register int atom;
@@ -1213,9 +1144,7 @@ opt_deadstores(b)
 }
 
 static void
-opt_blk(b, do_stmts)
-       struct block *b;
-       int do_stmts;
+opt_blk(struct block *b, int do_stmts)
 {
        struct slist *s;
        struct edge *p;
@@ -1319,8 +1248,7 @@ opt_blk(b, do_stmts)
  * from 'b'.
  */
 static int
-use_conflict(b, succ)
-       struct block *b, *succ;
+use_conflict(struct block *b, struct block *succ)
 {
        int atom;
        atomset use = succ->out_use;
@@ -1336,9 +1264,7 @@ use_conflict(b, succ)
 }
 
 static struct block *
-fold_edge(child, ep)
-       struct block *child;
-       struct edge *ep;
+fold_edge(struct block *child, struct edge *ep)
 {
        int sense;
        int aval0, aval1, oval0, oval1;
@@ -1390,8 +1316,7 @@ fold_edge(child, ep)
 }
 
 static void
-opt_j(ep)
-       struct edge *ep;
+opt_j(struct edge *ep)
 {
        register int i, k;
        register struct block *target;
@@ -1446,8 +1371,7 @@ opt_j(ep)
 
 
 static void
-or_pullup(b)
-       struct block *b;
+or_pullup(struct block *b)
 {
        int val, at_top;
        struct block *pull;
@@ -1539,8 +1463,7 @@ or_pullup(b)
 }
 
 static void
-and_pullup(b)
-       struct block *b;
+and_pullup(struct block *b)
 {
        int val, at_top;
        struct block *pull;
@@ -1631,9 +1554,7 @@ and_pullup(b)
 }
 
 static void
-opt_blks(root, do_stmts)
-       struct block *root;
-       int do_stmts;
+opt_blks(struct block *root, int do_stmts)
 {
        int i, maxlevel;
        struct block *p;
@@ -1670,17 +1591,14 @@ opt_blks(root, do_stmts)
 }
 
 static inline void
-link_inedge(parent, child)
-       struct edge *parent;
-       struct block *child;
+link_inedge(struct edge *parent, struct block *child)
 {
        parent->next = child->in_edges;
        child->in_edges = parent;
 }
 
 static void
-find_inedges(root)
-       struct block *root;
+find_inedges(struct block *root)
 {
        int i;
        struct block *b;
@@ -1701,8 +1619,7 @@ find_inedges(root)
 }
 
 static void
-opt_root(b)
-       struct block **b;
+opt_root(struct block **b)
 {
        struct slist *tmp, *s;
 
@@ -1726,9 +1643,7 @@ opt_root(b)
 }
 
 static void
-opt_loop(root, do_stmts)
-       struct block *root;
-       int do_stmts;
+opt_loop(struct block *root, int do_stmts)
 {
 
 #ifdef BDEBUG
@@ -1758,8 +1673,7 @@ opt_loop(root, do_stmts)
  * Optimize the filter code in its dag representation.
  */
 void
-bpf_optimize(rootp)
-       struct block **rootp;
+bpf_optimize(struct block **rootp)
 {
        struct block *root;
 
@@ -1786,8 +1700,7 @@ bpf_optimize(rootp)
 }
 
 static void
-make_marks(p)
-       struct block *p;
+make_marks(struct block *p)
 {
        if (!isMarked(p)) {
                Mark(p);
@@ -1803,8 +1716,7 @@ make_marks(p)
  * only for nodes that are alive.
  */
 static void
-mark_code(p)
-       struct block *p;
+mark_code(struct block *p)
 {
        cur_mark += 1;
        make_marks(p);
@@ -1815,8 +1727,7 @@ mark_code(p)
  * the accumulator.
  */
 static int
-eq_slist(x, y)
-       struct slist *x, *y;
+eq_slist(struct slist *x, struct slist *y)
 {
        while (1) {
                while (x && x->s.code == NOP)
@@ -1835,8 +1746,7 @@ eq_slist(x, y)
 }
 
 static inline int
-eq_blk(b0, b1)
-       struct block *b0, *b1;
+eq_blk(struct block *b0, struct block *b1)
 {
        if (b0->s.code == b1->s.code &&
            b0->s.k == b1->s.k &&
@@ -1847,8 +1757,7 @@ eq_blk(b0, b1)
 }
 
 static void
-intern_blocks(root)
-       struct block *root;
+intern_blocks(struct block *root)
 {
        struct block *p;
        int i, j;
@@ -1891,7 +1800,7 @@ intern_blocks(root)
 }
 
 static void
-opt_cleanup()
+opt_cleanup(void)
 {
        free((void *)vnode_base);
        free((void *)vmap);
@@ -1905,8 +1814,7 @@ opt_cleanup()
  * Return the number of stmts in 's'.
  */
 static u_int
-slength(s)
-       struct slist *s;
+slength(struct slist *s)
 {
        u_int n = 0;
 
@@ -1921,8 +1829,7 @@ slength(s)
  * All nodes should be initially unmarked.
  */
 static int
-count_blocks(p)
-       struct block *p;
+count_blocks(struct block *p)
 {
        if (p == 0 || isMarked(p))
                return 0;
@@ -1935,8 +1842,7 @@ count_blocks(p)
  * the basic blocks, and entering them into the 'blocks' array.`
  */
 static void
-number_blks_r(p)
-       struct block *p;
+number_blks_r(struct block *p)
 {
        int n;
 
@@ -1971,8 +1877,7 @@ number_blks_r(p)
  *     an extra long jump if the false branch requires it (p->longjf).
  */
 static u_int
-count_stmts(p)
-       struct block *p;
+count_stmts(struct block *p)
 {
        u_int n;
 
@@ -1989,8 +1894,7 @@ count_stmts(p)
  * from the total number of blocks and/or statements.
  */
 static void
-opt_init(root)
-       struct block *root;
+opt_init(struct block *root)
 {
        bpf_u_int32 *p;
        int i, n, max_stmts;
@@ -2088,8 +1992,7 @@ int bids[1000];
  * properly.
  */
 static int
-convert_code_r(p)
-       struct block *p;
+convert_code_r(struct block *p)
 {
        struct bpf_insn *dst;
        struct slist *src;
@@ -2261,9 +2164,7 @@ filled:
  * done with the filter program.  See the pcap man page.
  */
 struct bpf_insn *
-icode_to_fcode(root, lenp)
-       struct block *root;
-       u_int *lenp;
+icode_to_fcode(struct block *root, u_int *lenp)
 {
        u_int n;
        struct bpf_insn *fp;
@@ -2333,8 +2234,7 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp)
 
 #ifdef BDEBUG
 static void
-opt_dump(root)
-       struct block *root;
+opt_dump(struct block *root)
 {
        struct bpf_program f;
 
index 944445f..9e739dc 100644 (file)
@@ -122,14 +122,6 @@ static int bpf_load(char *errbuf);
 
 #include "pcap-int.h"
 
-#ifdef HAVE_DAG_API
-#include "pcap-dag.h"
-#endif /* HAVE_DAG_API */
-
-#ifdef HAVE_SNF_API
-#include "pcap-snf.h"
-#endif /* HAVE_SNF_API */
-
 #ifdef HAVE_OS_PROTO_H
 #include "os-proto.h"
 #endif
@@ -218,30 +210,21 @@ pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
 #ifdef HAVE_ZEROCOPY_BPF
        if (p->md.zerocopy) {
                /*
-                * Map each value to the corresponding 2's complement, to
+                * Map each value to their corresponding negation to
                 * preserve the timeout value provided with pcap_set_timeout.
                 * (from pcap-linux.c).
                 */
                if (nonblock) {
                        if (p->md.timeout >= 0) {
                                /*
-                                * Timeout is non-negative, so we're not
-                                * currently in non-blocking mode; set it
-                                * to the 2's complement, to make it
-                                * negative, as an indication that we're
-                                * in non-blocking mode.
+                                * Indicate that we're switching to
+                                * non-blocking mode.
                                 */
-                               p->md.timeout = p->md.timeout * -1 - 1;
+                               p->md.timeout = ~p->md.timeout;
                        }
                } else {
                        if (p->md.timeout < 0) {
-                               /*
-                                * Timeout is negative, so we're currently
-                                * in blocking mode; reverse the previous
-                                * operation, to make the timeout non-negative
-                                * again.
-                                */
-                               p->md.timeout = (p->md.timeout + 1) * -1;
+                               p->md.timeout = ~p->md.timeout;
                        }
                }
                return (0);
@@ -407,19 +390,10 @@ pcap_ack_zbuf(pcap_t *p)
 #endif /* HAVE_ZEROCOPY_BPF */
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
-#ifdef HAVE_DAG_API
-       if (strstr(device, "dag"))
-               return (dag_create(device, ebuf));
-#endif /* HAVE_DAG_API */
-#ifdef HAVE_SNF_API
-       if (strstr(device, "snf"))
-               return (snf_create(device, ebuf));
-#endif /* HAVE_SNF_API */
-
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return (NULL);
@@ -1701,7 +1675,7 @@ pcap_activate_bpf(pcap_t *p)
                            pcap_strerror(errno));
                        goto bad;
                }
-               bzero(&bz, sizeof(bz));
+               memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */
                bz.bz_bufa = p->md.zbuf1;
                bz.bz_bufb = p->md.zbuf2;
                bz.bz_buflen = p->md.zbufsize;
@@ -2283,15 +2257,6 @@ pcap_activate_bpf(pcap_t *p)
 int
 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
 {
-#ifdef HAVE_DAG_API
-       if (dag_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif /* HAVE_DAG_API */
-#ifdef HAVE_SNF_API
-       if (snf_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif /* HAVE_SNF_API */
-
        return (0);
 }
 
index 31cf84d..bd18c64 100644 (file)
 #define LINKTYPE_NETANALYZER_TRANSPARENT       241
 
 /*
- * IP-over-Infiniband, as specified by RFC 4391.
+ * IP-over-InfiniBand, as specified by RFC 4391.
  *
  * Requested by Petr Sumbera <petr.sumbera@oracle.com>.
  */
  */
 #define LINKTYPE_PFSYNC                246
 
-#define LINKTYPE_MATCHING_MAX  246             /* highest value in the "matching" range */
+/*
+ * Raw InfiniBand packets, starting with the Local Routing Header.
+ *
+ * Requested by Oren Kladnitsky <orenk@mellanox.com>.
+ */
+#define LINKTYPE_INFINIBAND    247
+
+/*
+ * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6).
+ *
+ * Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>.
+ */
+#define LINKTYPE_SCTP          248
+
+#define LINKTYPE_MATCHING_MAX  248             /* highest value in the "matching" range */
 
 static struct linktype_map {
        int     dlt;
index d7b4b0a..6019a80 100644 (file)
@@ -45,6 +45,7 @@ Primitives usually consist of an
 There are three
 different kinds of qualifier:
 .IP \fItype\fP
+.I type
 qualifiers say what kind of thing the id name or number refers to.
 Possible types are
 .BR host ,
@@ -58,6 +59,7 @@ qualifier,
 .B host
 is assumed.
 .IP \fIdir\fP
+.I dir
 qualifiers specify a particular transfer direction to and/or from
 .IR id .
 Possible directions are
@@ -93,6 +95,7 @@ and
 .B outbound
 qualifiers can be used to specify a desired direction.
 .IP \fIproto\fP
+.I proto
 qualifiers restrict the match to a particular protocol.
 Possible
 protos are:
@@ -159,7 +162,7 @@ True if the IPv4/v6 destination field of the packet is \fIhost\fP,
 which may be either an address or a name.
 .IP "\fBsrc host \fIhost\fR"
 True if the IPv4/v6 source field of the packet is \fIhost\fP.
-.IP "\fBhost \fIhost\fP
+.IP "\fBhost \fIhost\fP"
 True if either the IPv4/v6 source or destination of the packet is \fIhost\fP.
 .IP
 Any of the above host expressions can be prepended with the keywords,
@@ -177,17 +180,17 @@ which is equivalent to:
 .in -.5i
 If \fIhost\fR is a name with multiple IP addresses, each address will
 be checked for a match.
-.IP "\fBether dst \fIehost\fP
+.IP "\fBether dst \fIehost\fP"
 True if the Ethernet destination address is \fIehost\fP.
 \fIEhost\fP
 may be either a name from /etc/ethers or a number (see
 .IR ethers (3N)
 for numeric format).
-.IP "\fBether src \fIehost\fP
+.IP "\fBether src \fIehost\fP"
 True if the Ethernet source address is \fIehost\fP.
-.IP "\fBether host \fIehost\fP
+.IP "\fBether host \fIehost\fP"
 True if either the Ethernet source or destination address is \fIehost\fP.
-.IP "\fBgateway\fP \fIhost\fP
+.IP "\fBgateway\fP \fIhost\fP"
 True if the packet used \fIhost\fP as a gateway.
 I.e., the Ethernet
 source or destination address was \fIhost\fP but neither the IP source
@@ -302,6 +305,18 @@ Note that this primitive does not chase the protocol header chain.
 .IP "\fBip6 proto \fIprotocol\fR"
 True if the packet is an IPv6 packet of protocol type \fIprotocol\fP.
 Note that this primitive does not chase the protocol header chain.
+.IP "\fBproto \fIprotocol\fR"
+True if the packet is an IPv4 or IPv6 packet of protocol type
+\fIprotocol\fP.  Note that this primitive does not chase the protocol
+header chain.
+.IP  "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
+Abbreviations for:
+.in +.5i
+.nf
+\fBproto \fIp\fR\fB
+.fi
+.in -.5i
+where \fIp\fR is one of the above protocols.
 .IP "\fBip6 protochain \fIprotocol\fR"
 True if the packet is IPv6 packet,
 and contains protocol header with type \fIprotocol\fR
@@ -321,6 +336,10 @@ cannot be optimized by the BPF optimizer code, so this can be somewhat
 slow.
 .IP "\fBip protochain \fIprotocol\fR"
 Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4.
+.IP "\fBprotochain \fIprotocol\fR"
+True if the packet is an IPv4 or IPv6 packet of protocol type
+\fIprotocol\fP.  Note that this primitive chases the protocol
+header chain.
 .IP "\fBether broadcast\fR"
 True if the packet is an Ethernet broadcast packet.
 The \fIether\fP
@@ -402,6 +421,25 @@ the filter checks for the IPX etype in an Ethernet frame, the IPX
 DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of
 IPX, and the IPX etype in a SNAP frame.
 .RE
+.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP"
+Abbreviations for:
+.in +.5i
+.nf
+\fBether proto \fIp\fR
+.fi
+.in -.5i
+where \fIp\fR is one of the above protocols.
+.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
+Abbreviations for:
+.in +.5i
+.nf
+\fBether proto \fIp\fR
+.fi
+.in -.5i
+where \fIp\fR is one of the above protocols.
+Note that not all applications using
+.BR pcap (3PCAP)
+currently know how to parse these protocols.
 .IP "\fBdecnet src \fIhost\fR"
 True if the DECNET source address is
 .IR host ,
@@ -503,25 +541,6 @@ True if the fourth IEEE 802.11 address, if present, is
 .IR ehost .
 The fourth address field is only used for
 WDS (Wireless Distribution System) frames.
-.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP"
-Abbreviations for:
-.in +.5i
-.nf
-\fBether proto \fIp\fR
-.fi
-.in -.5i
-where \fIp\fR is one of the above protocols.
-.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
-Abbreviations for:
-.in +.5i
-.nf
-\fBether proto \fIp\fR
-.fi
-.in -.5i
-where \fIp\fR is one of the above protocols.
-Note that not all applications using
-.BR pcap (3)
-currently know how to parse these protocols.
 .IP "\fBtype \fIwlan_type\fR"
 True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR.
 Valid \fIwlan_type\fRs are:
@@ -652,14 +671,6 @@ For example:
 .fi
 .in -.5i
 filters IPv4 protocols encapsulated in PPPoE.
-.IP  "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
-Abbreviations for:
-.in +.5i
-.nf
-\fBip proto \fIp\fR\fB or ip6 proto \fIp\fR
-.fi
-.in -.5i
-where \fIp\fR is one of the above protocols.
 .IP "\fBiso proto \fIprotocol\fR"
 True if the packet is an OSI packet of protocol type \fIprotocol\fP.
 \fIProtocol\fP can be a number or one of the names
@@ -674,11 +685,11 @@ Abbreviations for:
 where \fIp\fR is one of the above protocols.
 .IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR"
 Abbreviations for IS-IS PDU types.
-.IP "\fBvpi\fP \fIn\fR
+.IP "\fBvpi\fP \fIn\fR"
 True if the packet is an ATM packet, for SunATM on Solaris, with a
 virtual path identifier of
 .IR n .
-.IP "\fBvci\fP \fIn\fR
+.IP "\fBvci\fP \fIn\fR"
 True if the packet is an ATM packet, for SunATM on Solaris, with a
 virtual channel identifier of
 .IR n .
@@ -918,27 +929,6 @@ icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
 .RE
 .SH "SEE ALSO"
 pcap(3PCAP)
-.SH AUTHORS
-The original authors are:
-.LP
-Van Jacobson,
-Craig Leres and
-Steven McCanne, all of the
-Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
-.LP
-It is currently being maintained by tcpdump.org.
-.LP
-The current version of libpcap is available via http:
-.LP
-.RS
-.I http://www.tcpdump.org/
-.RE
-.LP
-The original distribution is available via anonymous ftp:
-.LP
-.RS
-.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z
-.RE
 .SH BUGS
 Please send problems, bugs, questions, desirable enhancements, etc. to:
 .LP
index 8444e62..b3ce82d 100644 (file)
@@ -144,6 +144,7 @@ struct pcap_md {
        char    *mondevice;     /* mac80211 monitor device we created */
        u_char  *mmapbuf;       /* memory-mapped region pointer */
        size_t  mmapbuflen;     /* size of region */
+       int     vlan_offset;    /* offset at which to insert vlan tags; if -1, don't insert */
        u_int   tp_version;     /* version of tpacket_hdr for mmaped ring */
        u_int   tp_hdrlen;      /* hdrlen of tpacket_hdr for mmaped ring */
        u_char  *oneshot_buffer; /* buffer for copy of packet */
@@ -374,12 +375,13 @@ struct pcap_timeval {
  *     the old record header as well as files with the new record header
  *     (using the magic number to determine the header format).
  *
- * Then supply the changes as a patch at
+ * Then supply the changes by forking the branch at
  *
- *     http://sourceforge.net/projects/libpcap/
+ *     https://github.com/mcr/libpcap/issues
  *
- * so that future versions of libpcap and programs that use it (such as
- * tcpdump) will be able to read your new capture file format.
+ * and issuing a pull request, so that future versions of libpcap and
+ * programs that use it (such as tcpdump) will be able to read your new
+ * capture file format.
  */
 
 struct pcap_sf_pkthdr {
@@ -454,6 +456,18 @@ int        pcap_getnonblock_fd(pcap_t *, char *);
 int    pcap_setnonblock_fd(pcap_t *p, int, char *);
 #endif
 
+/*
+ * Internal interfaces for "pcap_create()".
+ *
+ * "pcap_create_interface()" is the routine to do a pcap_create on
+ * a regular network interface.  There are multiple implementations
+ * of this, one for each platform type (Linux, BPF, DLPI, etc.),
+ * with the one used chosen by the configure script.
+ *
+ * "pcap_create_common()" allocates and fills in a pcap_t, for use
+ * by pcap_create routines.
+ */
+pcap_t *pcap_create_interface(const char *, char *);
 pcap_t *pcap_create_common(const char *, char *);
 int    pcap_do_addexit(pcap_t *);
 void   pcap_add_to_pcaps_to_close(pcap_t *);
@@ -465,12 +479,16 @@ int       pcap_check_activated(pcap_t *);
 /*
  * Internal interfaces for "pcap_findalldevs()".
  *
+ * "pcap_findalldevs_interfaces()" finds interfaces using the
+ * "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
+ *
  * "pcap_platform_finddevs()" is a platform-dependent routine to
- * add devices not found by the "standard" mechanisms (SIOCGIFCONF,
- * "getifaddrs()", etc..
+ * add devices not found by the "standard" mechanisms.
  *
- * "pcap_add_if()" adds an interface to the list of interfaces.
+ * "pcap_add_if()" adds an interface to the list of interfaces, for
+ * use by various "find interfaces" routines.
  */
+int    pcap_findalldevs_interfaces(pcap_if_t **, char *);
 int    pcap_platform_finddevs(pcap_if_t **, char *);
 int    add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *,
            size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
index cfdd83f..9ce4318 100644 (file)
@@ -74,8 +74,35 @@ static const char rcsid[] _U_ =
 #include "pcap-int.h"
 
 #ifdef HAVE_DAG_API
-#include <dagnew.h>
-#include <dagapi.h>
+#include "pcap-dag.h"
+#endif /* HAVE_DAG_API */
+
+#ifdef HAVE_SEPTEL_API
+#include "pcap-septel.h"
+#endif /* HAVE_SEPTEL_API */
+
+#ifdef HAVE_SNF_API
+#include "pcap-snf.h"
+#endif /* HAVE_SNF_API */
+
+#ifdef PCAP_SUPPORT_USB
+#include "pcap-usb-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_BT
+#include "pcap-bt-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_CAN
+#include "pcap-can-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_CANUSB
+#include "pcap-canusb-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_NETFILTER
+#include "pcap-netfilter-linux.h"
 #endif
 
 int 
@@ -232,6 +259,173 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
        return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
 }
 
+#if defined(DAG_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+       return (dag_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+       return (dag_create(source, errbuf));
+}
+#elif defined(SEPTEL_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+       return (septel_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+       return (septel_create(source, errbuf));
+}
+#elif defined(SNF_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+       return (snf_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+       return (snf_create(source, errbuf));
+}
+#else /* regular pcap */
+struct capture_source_type {
+       int (*findalldevs_op)(pcap_if_t **, char *);
+       pcap_t *(*create_op)(const char *, char *, int *);
+} capture_source_types[] = {
+#ifdef HAVE_DAG_API
+       { dag_findalldevs, dag_create },
+#endif
+#ifdef HAVE_SEPTEL_API
+       { septel_findalldevs, septel_create },
+#endif
+#ifdef HAVE_SNF_API
+       { snf_findalldevs, snf_create },
+#endif
+#ifdef PCAP_SUPPORT_BT
+       { bt_findalldevs, bt_create },
+#endif
+#if PCAP_SUPPORT_CANUSB
+       { canusb_findalldevs, canusb_create },
+#endif
+#ifdef PCAP_SUPPORT_CAN
+       { can_findalldevs, can_create },
+#endif
+#ifdef PCAP_SUPPORT_USB
+       { usb_findalldevs, usb_create },
+#endif
+#ifdef PCAP_SUPPORT_NETFILTER
+       { netfilter_findalldevs, netfilter_create },
+#endif
+       { NULL, NULL }
+};
+
+/*
+ * Get a list of all capture sources that are up and that we can open.
+ * Returns -1 on error, 0 otherwise.
+ * The list, as returned through "alldevsp", may be null if no interfaces
+ * were up and could be opened.
+ */
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+       size_t i;
+
+       /*
+        * Get the list of regular interfaces first.
+        */ 
+       if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1)
+               return (-1);    /* failure */
+
+       /*
+        * Add any interfaces that need a platform-specific mechanism
+        * to find.
+        */
+       if (pcap_platform_finddevs(alldevsp, errbuf) == -1) {
+               /*
+                * We had an error; free the list we've been
+                * constructing.
+                */
+               if (*alldevsp != NULL) {
+                       pcap_freealldevs(*alldevsp);
+                       *alldevsp = NULL;
+               }
+               return (-1);
+       }
+
+       /*
+        * Ask each of the non-local-network-interface capture
+        * source types what interfaces they have.
+        */
+       for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) {
+               if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) {
+                       /*
+                        * We had an error; free the list we've been
+                        * constructing.
+                        */
+                       if (*alldevsp != NULL) {
+                               pcap_freealldevs(*alldevsp);
+                               *alldevsp = NULL;
+                       }
+                       return (-1);
+               }
+       }
+       return (0);
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+       size_t i;
+       int is_theirs;
+       pcap_t *p;
+
+       /*
+        * A null source name is equivalent to the "any" device -
+        * which might not be supported on this platform, but
+        * this means that you'll get a "not supported" error
+        * rather than, say, a crash when we try to dereference
+        * the null pointer.
+        */
+       if (source == NULL)
+               source = "any";
+
+       /*
+        * Try each of the non-local-network-interface capture
+        * source types until we find one that works for this
+        * device or run out of types.
+        */
+       for (i = 0; capture_source_types[i].create_op != NULL; i++) {
+               is_theirs = 0;
+               p = capture_source_types[i].create_op(source, errbuf, &is_theirs);
+               if (is_theirs) {
+                       /*
+                        * The device name refers to a device of the
+                        * type in question; either it succeeded,
+                        * in which case p refers to a pcap_t to
+                        * later activate for the device, or it
+                        * failed, in which case p is null and we
+                        * should return that to report the failure
+                        * to create.
+                        */
+                       return (p);
+               }
+       }
+
+       /*
+        * OK, try it as a regular network interface.
+        */
+       return (pcap_create_interface(source, errbuf));
+}
+#endif
+
 static void
 initialize_ops(pcap_t *p)
 {
@@ -1023,7 +1217,18 @@ pcap_geterr(pcap_t *p)
 int
 pcap_getnonblock(pcap_t *p, char *errbuf)
 {
-       return (p->getnonblock_op(p, errbuf));
+       int ret;
+
+       ret = p->getnonblock_op(p, errbuf);
+       if (ret == -1) {
+               /*
+                * In case somebody depended on the bug wherein
+                * the error message was put into p->errbuf
+                * by pcap_getnonblock_fd().
+                */
+               strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+       }
+       return (ret);
 }
 
 /*
@@ -1041,7 +1246,7 @@ pcap_getnonblock_fd(pcap_t *p, char *errbuf)
 
        fdflags = fcntl(p->fd, F_GETFL, 0);
        if (fdflags == -1) {
-               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+               snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
                    pcap_strerror(errno));
                return (-1);
        }
@@ -1055,7 +1260,18 @@ pcap_getnonblock_fd(pcap_t *p, char *errbuf)
 int
 pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
 {
-       return (p->setnonblock_op(p, nonblock, errbuf));
+       int ret;
+
+       ret = p->setnonblock_op(p, nonblock, errbuf);
+       if (ret == -1) {
+               /*
+                * In case somebody depended on the bug wherein
+                * the error message was put into p->errbuf
+                * by pcap_setnonblock_fd().
+                */
+               strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+       }
+       return (ret);
 }
 
 #if !defined(WIN32) && !defined(MSDOS)
@@ -1072,7 +1288,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
 
        fdflags = fcntl(p->fd, F_GETFL, 0);
        if (fdflags == -1) {
-               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+               snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
                    pcap_strerror(errno));
                return (-1);
        }
@@ -1081,7 +1297,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
        else
                fdflags &= ~O_NONBLOCK;
        if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
-               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
+               snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
                    pcap_strerror(errno));
                return (-1);
        }
@@ -1464,10 +1680,10 @@ pcap_close(pcap_t *p)
  * the packet doesn't pass and non-zero if the packet does pass.
  */
 int
-pcap_offline_filter(struct bpf_program *fp, const struct pcap_pkthdr *h,
+pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h,
     const u_char *pkt)
 {
-       struct bpf_insn *fcode = fp->bf_insns;
+       const struct bpf_insn *fcode = fp->bf_insns;
 
        if (fcode != NULL) 
                return (bpf_filter(fcode, pkt, h->len, h->caplen));
index 8bcde7f..8576bbd 100644 (file)
@@ -1133,7 +1133,7 @@ struct bpf_program {
 #define DLT_NETANALYZER_TRANSPARENT    241
 
 /*
- * IP-over-Infiniband, as specified by RFC 4391.
+ * IP-over-InfiniBand, as specified by RFC 4391.
  *
  * Requested by Petr Sumbera <petr.sumbera@oracle.com>.
  */
@@ -1175,7 +1175,21 @@ struct bpf_program {
 #define DLT_PFSYNC             246
 #endif
 
-#define DLT_MATCHING_MAX       246     /* highest value in the "matching" range */
+/*
+ * Raw InfiniBand packets, starting with the Local Routing Header.
+ *
+ * Requested by Oren Kladnitsky <orenk@mellanox.com>.
+ */
+#define DLT_INFINIBAND         247
+
+/*
+ * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6).
+ *
+ * Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>.
+ */
+#define DLT_SCTP               248
+
+#define DLT_MATCHING_MAX       248     /* highest value in the "matching" range */
 
 /*
  * DLT and savefile link type values are split into a class and
index a02b359..7be36b1 100644 (file)
@@ -113,12 +113,13 @@ typedef struct pcap_addr pcap_addr_t;
  *     the old file header as well as files with the new file header
  *     (using the magic number to determine the header format).
  *
- * Then supply the changes as a patch at
+ * Then supply the changes by forking the branch at
  *
- *     http://sourceforge.net/projects/libpcap/
+ *     https://github.com/mcr/libpcap/issues
  *
- * so that future versions of libpcap and programs that use it (such as
- * tcpdump) will be able to read your new capture file format.
+ * and issuing a pull request, so that future versions of libpcap and
+ * programs that use it (such as tcpdump) will be able to read your new
+ * capture file format.
  */
 struct pcap_file_header {
        bpf_u_int32 magic;
@@ -370,8 +371,8 @@ int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
 int    pcap_compile_nopcap(int, int, struct bpf_program *,
            const char *, int, bpf_u_int32);
 void   pcap_freecode(struct bpf_program *);
-int    pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *,
-           const u_char *);
+int    pcap_offline_filter(const struct bpf_program *,
+           const struct pcap_pkthdr *, const u_char *);
 int    pcap_datalink(pcap_t *);
 int    pcap_datalink_ext(pcap_t *);
 int    pcap_list_datalinks(pcap_t *, int **);
index 2372348..e437af8 100644 (file)
@@ -58,20 +58,15 @@ if the signal interrupted a call reading packets in a live capture,
 when your signal handler returns after calling pcap_breakloop(), the
 call will be restarted, and the loop will not terminate until more
 packets arrive and the call completes.
+.ft R
 .PP
+.ft B
 Note also that, in a multi-threaded application, if one thread is
-blocked in
-.BR pcap_dispatch() ,
-.BR pcap_loop() ,
-.BR pcap_next() ,
-or
-.BR pcap_next_ex() ,
-a call to
-.B pcap_breakloop()
-in a different thread will not unblock that thread; you will need to use
-whatever mechanism the OS provides for breaking a thread out of blocking
-calls in order to unblock the thread, such as thread cancellation in
-systems that support POSIX threads.
+blocked in pcap_dispatch(), pcap_loop(), pcap_next(), or pcap_next_ex(),
+a call to pcap_breakloop() in a different thread will not unblock that
+thread; you will need to use whatever mechanism the OS provides for
+breaking a thread out of blocking calls in order to unblock the thread,
+such as thread cancellation in systems that support POSIX threads.
 .ft R
 .PP
 Note that
index da30693..7e0b582 100644 (file)
@@ -84,7 +84,7 @@ processed when reading a ``savefile''.
 \fIcnt\fP
 was 0 was undefined; different platforms and devices behaved
 differently, so code that must work with older versions of libpcap
-should use \-1, nor 0, as the value of
+should use \-1, not 0, as the value of
 \fIcnt\fP.)
 .ft R
 .PP
@@ -119,8 +119,9 @@ them.
 .B pcap_loop()
 returns 0 if
 .I cnt
-is exhausted, \-1 if an error occurs, or \-2 if the loop terminated due
-to a call to
+is exhausted or if, when reading from a ``savefile'', no more packets
+are available.  It returns \-1 if an error occurs or \-2 if the loop
+terminated due to a call to
 .B pcap_breakloop()
 before any packets were processed.
 It does
index 596c5e4..3f11022 100644 (file)
@@ -29,7 +29,7 @@ pcap_offline_filter \- check whether a filter matches a packet
 .ft
 .LP
 .ft B
-int pcap_offline_filter(struct bpf_program *fp,
+int pcap_offline_filter(const struct bpf_program *fp,
 .ti +8
 const struct pcap_pkthdr *h, const u_char *pkt)
 .ft
index 064e9c8..10ffbcd 100644 (file)
@@ -206,20 +206,8 @@ vrrp               return VRRP;
 carp           return CARP;
 radio          return RADIO;
 
-ip6            {
-#ifdef INET6
-               return IPV6;
-#else
-               bpf_error("%s not supported", yytext);
-#endif
-               }
-icmp6          {
-#ifdef INET6
-               return ICMPV6;
-#else
-               bpf_error("%s not supported", yytext);
-#endif
-               }
+ip6            return IPV6;
+icmp6          return ICMPV6;
 ah             return AH;
 esp            return ESP;