Merge branch 'vendor/LIBPCAP'
authorPeter Avalos <pavalos@dragonflybsd.org>
Mon, 23 Jan 2012 00:08:22 +0000 (16:08 -0800)
committerPeter Avalos <pavalos@dragonflybsd.org>
Mon, 23 Jan 2012 00:08:22 +0000 (16:08 -0800)
1  2 
contrib/libpcap/bpf/net/bpf_filter.c
contrib/libpcap/gencode.c
contrib/libpcap/grammar.y
contrib/libpcap/pcap/pcap.h
contrib/libpcap/scanner.l

@@@ -40,7 -40,7 +40,7 @@@
  
  #if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
  static const char rcsid[] _U_ =
-     "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.45.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)";
+     "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.46 2008-01-02 04:16:46 guy Exp $ (LBL)";
  #endif
  
  #ifdef HAVE_CONFIG_H
  
  #else /* WIN32 */
  
+ #if HAVE_INTTYPES_H
+ #include <inttypes.h>
+ #elif HAVE_STDINT_H
+ #include <stdint.h>
+ #endif
+ #ifdef HAVE_SYS_BITYPES_H
+ #include <sys/bitypes.h>
+ #endif
  #include <sys/param.h>
  #include <sys/types.h>
  #include <sys/time.h>
  # define      m_next  b_cont
  # define      MLEN(m) ((m)->b_wptr - (m)->b_rptr)
  # define      mtod(m,t)       ((t)(m)->b_rptr)
- #else
+ #else /* defined(__hpux) || SOLARIS */
  # define      MLEN(m) ((m)->m_len)
- #endif
+ #endif /* defined(__hpux) || SOLARIS */
  
  #endif /* WIN32 */
  
 -#include <pcap/bpf.h>
 +#include <net/bpf.h>
  
  #if !defined(KERNEL) && !defined(_KERNEL)
  #include <stdlib.h>
@@@ -396,7 -405,18 +405,18 @@@ bpf_filter(pc, p, wirelen, buflen
                        continue;
  
                case BPF_JMP|BPF_JA:
+ #if defined(KERNEL) || defined(_KERNEL)
+                       /*
+                        * No backward jumps allowed.
+                        */
                        pc += pc->k;
+ #else
+                       /*
+                        * XXX - we currently implement "ip6 protochain"
+                        * with backward jumps, so sign-extend pc->k.
+                        */
+                       pc += (bpf_int32)pc->k;
+ #endif
                        continue;
  
                case BPF_JMP|BPF_JGT|BPF_K:
@@@ -599,7 -619,7 +619,7 @@@ bpf_validate(f, len
                                /*
                                 * Check for constant division by 0.
                                 */
-                               if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
+                               if (BPF_SRC(p->code) == BPF_K && p->k == 0)
                                        return 0;
                                break;
                        default:
@@@ -21,7 -21,7 +21,7 @@@
   */
  #ifndef lint
  static const char rcsid[] _U_ =
-     "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.290.2.16 2008-09-22 20:16:01 guy Exp $ (LBL)";
+     "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.309 2008-12-23 20:13:29 guy Exp $ (LBL)";
  #endif
  
  #ifdef HAVE_CONFIG_H
  #ifdef WIN32
  #include <pcap-stdinc.h>
  #else /* WIN32 */
+ #if HAVE_INTTYPES_H
+ #include <inttypes.h>
+ #elif HAVE_STDINT_H
+ #include <stdint.h>
+ #endif
+ #ifdef HAVE_SYS_BITYPES_H
+ #include <sys/bitypes.h>
+ #endif
  #include <sys/types.h>
  #include <sys/socket.h>
  #endif /* WIN32 */
@@@ -39,7 -47,7 +47,7 @@@
   * XXX - why was this included even on UNIX?
   */
  #ifdef __MINGW32__
- #include "IP6_misc.h"
+ #include "ip6_misc.h"
  #endif
  
  #ifndef WIN32
@@@ -49,6 -57,7 +57,7 @@@
  #endif
  
  #include <netinet/in.h>
+ #include <arpa/inet.h>
  
  #endif /* WIN32 */
  
  #include "nlpid.h"
  #include "llc.h"
  #include "gencode.h"
 -#include "ieee80211.h"
 +#include <netproto/802_11/ieee80211.h>
  #include "atmuni31.h"
  #include "sunatmpos.h"
  #include "ppp.h"
  #include "pcap/sll.h"
+ #include "pcap/ipnet.h"
  #include "arcnet.h"
  #ifdef HAVE_NET_PFVAR_H
  #include <sys/socket.h>
  #include <net/if.h>
 -#include <net/pfvar.h>
 -#include <net/if_pflog.h>
 +#include <net/if_var.h>
 +#include <net/pf/pfvar.h>
 +#include <net/pf/if_pflog.h>
  #endif
  #ifndef offsetof
  #define offsetof(s, e) ((size_t)&((s *)0)->e)
  #endif /*INET6*/
  #include <pcap/namedb.h>
  
 +#include <netproto/802_11/ieee80211_radiotap.h>
 +
  #define ETHERMTU      1500
  
  #ifndef IPPROTO_SCTP
@@@ -158,6 -165,17 +168,17 @@@ enum e_offrel 
        OR_TRAN_IPV6    /* relative to the transport-layer header, with IPv6 network layer */
  };
  
+ #ifdef INET6
+ /*
+  * As errors are handled by a longjmp, anything allocated must be freed
+  * in the longjmp handler, so it must be reachable from that handler.
+  * One thing that's allocated is the result of pcap_nametoaddrinfo();
+  * it must be freed with freeaddrinfo().  This variable points to any
+  * addrinfo structure that would need to be freed.
+  */
+ static struct addrinfo *ai;
+ #endif
  /*
   * We divy out chunks of memory rather than call malloc each time so
   * we don't have to worry about leaking memory.  It's probably
@@@ -203,6 -221,7 +224,7 @@@ static struct block *gen_uncond(int)
  static inline struct block *gen_true(void);
  static inline struct block *gen_false(void);
  static struct block *gen_ether_linktype(int);
+ static struct block *gen_ipnet_linktype(int);
  static struct block *gen_linux_sll_linktype(int);
  static struct slist *gen_load_prism_llprefixlen(void);
  static struct slist *gen_load_avs_llprefixlen(void);
@@@ -368,11 -387,35 +390,35 @@@ syntax(
  static bpf_u_int32 netmask;
  static int snaplen;
  int no_optimize;
+ #ifdef WIN32
+ static int
+ pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
+            const char *buf, int optimize, bpf_u_int32 mask);
  
  int
  pcap_compile(pcap_t *p, struct bpf_program *program,
             const char *buf, int optimize, bpf_u_int32 mask)
  {
+       int result;
+       EnterCriticalSection(&g_PcapCompileCriticalSection);
+       result = pcap_compile_unsafe(p, program, buf, optimize, mask);
+       LeaveCriticalSection(&g_PcapCompileCriticalSection);
+       
+       return result;
+ }
+ static int
+ pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
+            const char *buf, int optimize, bpf_u_int32 mask)
+ #else /* WIN32 */
+ int
+ pcap_compile(pcap_t *p, struct bpf_program *program,
+            const char *buf, int optimize, bpf_u_int32 mask)
+ #endif /* WIN32 */
+ {
        extern int n_errors;
        const char * volatile xbuf = buf;
        int len;
        bpf_pcap = p;
        init_regs();
        if (setjmp(top_ctx)) {
+ #ifdef INET6
+               if (ai != NULL) {
+                       freeaddrinfo(ai);
+                       ai = NULL;
+               }
+ #endif
                lex_cleanup();
                freechunks();
                return (-1);
@@@ -723,7 -772,8 +775,8 @@@ static int reg_off_ll
   * This is the offset of the beginning of the MAC-layer header from
   * the beginning of the link-layer header.
   * It's usually 0, except for ATM LANE, where it's the offset, relative
-  * to the beginning of the raw packet data, of the Ethernet header.
+  * to the beginning of the raw packet data, of the Ethernet header, and
+  * for Ethernet with various additional information.
   */
  static u_int off_mac;
  
@@@ -1115,6 -1165,8 +1168,8 @@@ init_linktype(p
                return;
  
        case DLT_RAW:
+       case DLT_IPV4:
+       case DLT_IPV6:
                off_linktype = -1;
                off_macpl = 0;
                off_nl = 0;
                off_nl_nosnap = 0;      /* no 802.2 LLC */
                return;
  
-       case DLT_LINUX_IRDA:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_DOCSIS:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
        case DLT_SYMANTEC_FIREWALL:
                off_linktype = 6;
                off_macpl = 44;
                off_nl_nosnap = -1;
                return;
  
+       case DLT_JUNIPER_VS:
+       case DLT_JUNIPER_SRX_E2E:
+       case DLT_JUNIPER_FIBRECHANNEL:
+       case DLT_JUNIPER_ATM_CEMIC:
+               off_linktype = 8;
+               off_macpl = -1;
+               off_nl = -1;
+               off_nl_nosnap = -1;
+               return;
        case DLT_MTP2:
                off_li = 2;
                off_sio = 3;
                return;
  #endif
  
-       case DLT_LINUX_LAPD:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_USB:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_BLUETOOTH_HCI_H4:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_USB_LINUX:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_CAN20B:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_IEEE802_15_4_LINUX:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_IEEE802_16_MAC_CPS_RADIO:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_IEEE802_15_4:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
-       case DLT_SITA:
+       case DLT_AX25_KISS:
                /*
                 * Currently, only raw "link[N:M]" filtering is supported.
                 */
-               off_linktype = -1;
+               off_linktype = -1;      /* variable, min 15, max 71 steps of 7 */
                off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
+               off_nl = -1;            /* variable, min 16, max 71 steps of 7 */
+               off_nl_nosnap = -1;     /* no 802.2 LLC */
+               off_mac = 1;            /* step over the kiss length byte */
                return;
  
-       case DLT_RAIF1:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
+       case DLT_IPNET:
+               off_linktype = 1;
+               off_macpl = 24;         /* ipnet header length */
+               off_nl = 0;
                off_nl_nosnap = -1;
                return;
  
-       case DLT_IPMB:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
+       case DLT_NETANALYZER:
+               off_mac = 4;            /* MAC header is past 4-byte pseudo-header */
+               off_linktype = 16;      /* includes 4-byte pseudo-header */
+               off_macpl = 18;         /* pseudo-header+Ethernet header length */
+               off_nl = 0;             /* Ethernet II */
+               off_nl_nosnap = 3;      /* 802.3+802.2 */
                return;
  
-       case DLT_BLUETOOTH_HCI_H4_WITH_PHDR:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
+       case DLT_NETANALYZER_TRANSPARENT:
+               off_mac = 12;           /* MAC header is past 4-byte pseudo-header, preamble, and SFD */
+               off_linktype = 24;      /* includes 4-byte pseudo-header+preamble+SFD */
+               off_macpl = 26;         /* pseudo-header+preamble+SFD+Ethernet header length */
+               off_nl = 0;             /* Ethernet II */
+               off_nl_nosnap = 3;      /* 802.3+802.2 */
                return;
  
-       case DLT_AX25_KISS:
+       default:
                /*
-                * Currently, only raw "link[N:M]" filtering is supported.
+                * For values in the range in which we've assigned new
+                * DLT_ values, only raw "link[N:M]" filtering is supported.
                 */
-               off_linktype = -1;      /* variable, min 15, max 71 steps of 7 */
-               off_macpl = -1;
-               off_nl = -1;            /* variable, min 16, max 71 steps of 7 */
-               off_nl_nosnap = -1;     /* no 802.2 LLC */
-               off_mac = 1;            /* step over the kiss length byte */
-               return;
+               if (linktype >= DLT_MATCHING_MIN &&
+                   linktype <= DLT_MATCHING_MAX) {
+                       off_linktype = -1;
+                       off_macpl = -1;
+                       off_nl = -1;
+                       off_nl_nosnap = -1;
+                       return;
+               }
  
-       case DLT_IEEE802_15_4_NONASK_PHY:
-               /*
-                * Currently, only raw "link[N:M]" filtering is supported.
-                */
-               off_linktype = -1;
-               off_macpl = -1;
-               off_nl = -1;
-               off_nl_nosnap = -1;
-               return;
        }
        bpf_error("unknown data link type %d", linktype);
        /* NOTREACHED */
@@@ -1934,6 -1884,33 +1887,33 @@@ gen_ether_linktype(proto
  }
  
  /*
+  * "proto" is an Ethernet type value and for IPNET, if it is not IPv4
+  * or IPv6 then we have an error.
+  */
+ static struct block *
+ gen_ipnet_linktype(proto)
+       register int proto;
+ {
+       switch (proto) {
+       case ETHERTYPE_IP:
+               return gen_cmp(OR_LINK, off_linktype, BPF_B,
+                   (bpf_int32)IPH_AF_INET);
+               /* NOTREACHED */
+       case ETHERTYPE_IPV6:
+               return gen_cmp(OR_LINK, off_linktype, BPF_B,
+                   (bpf_int32)IPH_AF_INET6);
+               /* NOTREACHED */
+       default:
+               break;
+       }
+       return gen_false();
+ }
+ /*
   * Generate code to match a particular packet type.
   *
   * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
@@@ -2944,6 -2921,8 +2924,8 @@@ gen_linktype(proto
        switch (linktype) {
  
        case DLT_EN10MB:
+       case DLT_NETANALYZER:
+       case DLT_NETANALYZER_TRANSPARENT:
                return gen_ether_linktype(proto);
                /*NOTREACHED*/
                break;
                /*NOTREACHED*/
                break;
  
+       case DLT_IPV4:
+               /*
+                * Raw IPv4, so no type field.
+                */
+               if (proto == ETHERTYPE_IP)
+                       return gen_true();              /* always true */
+               /* Checking for something other than IPv4; always false */
+               return gen_false();
+               /*NOTREACHED*/
+               break;
+       case DLT_IPV6:
+               /*
+                * 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();
+               /*NOTREACHED*/
+               break;
        case DLT_PPP:
        case DLT_PPP_PPPD:
        case DLT_PPP_SERIAL:
          case DLT_JUNIPER_VP:
          case DLT_JUNIPER_ST:
          case DLT_JUNIPER_ISM:
+         case DLT_JUNIPER_VS:
+         case DLT_JUNIPER_SRX_E2E:
+         case DLT_JUNIPER_FIBRECHANNEL:
+       case DLT_JUNIPER_ATM_CEMIC:
                /* just lets verify the magic number for now -
                 * on ATM we may have up to 6 different encapsulations on the wire
                 * and need a lot of heuristics to figure out that the payload
                 */
                return gen_mcmp(OR_LINK, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */
  
+       case DLT_IPNET:
+               return gen_ipnet_linktype(proto);
        case DLT_LINUX_IRDA:
                bpf_error("IrDA link-layer type filtering not implemented");
  
  
        case DLT_USB:
        case DLT_USB_LINUX:
+       case DLT_USB_LINUX_MMAPPED:
                bpf_error("USB link-layer type filtering not implemented");
  
        case DLT_BLUETOOTH_HCI_H4:
                bpf_error("Bluetooth link-layer type filtering not implemented");
  
        case DLT_CAN20B:
-               bpf_error("CAN20B link-layer type filtering not implemented");
+       case DLT_CAN_SOCKETCAN:
+               bpf_error("CAN link-layer type filtering not implemented");
  
        case DLT_IEEE802_15_4:
        case DLT_IEEE802_15_4_LINUX:
        case DLT_IEEE802_15_4_NONASK_PHY:
+       case DLT_IEEE802_15_4_NOFCS:
                bpf_error("IEEE 802.15.4 link-layer type filtering not implemented");
  
        case DLT_IEEE802_16_MAC_CPS_RADIO:
@@@ -3639,6 -3655,30 +3658,30 @@@ gen_ehostop(eaddr, dir
                b1 = gen_ehostop(eaddr, Q_DST);
                gen_or(b0, b1);
                return b1;
+       case Q_ADDR1:
+               bpf_error("'addr1' is only supported on 802.11 with 802.11 headers");
+               break;
+       case Q_ADDR2:
+               bpf_error("'addr2' is only supported on 802.11 with 802.11 headers");
+               break;
+       case Q_ADDR3:
+               bpf_error("'addr3' is only supported on 802.11 with 802.11 headers");
+               break;
+       case Q_ADDR4:
+               bpf_error("'addr4' is only supported on 802.11 with 802.11 headers");
+               break;
+       case Q_RA:
+               bpf_error("'ra' is only supported on 802.11 with 802.11 headers");
+               break;
+       case Q_TA:
+               bpf_error("'ta' is only supported on 802.11 with 802.11 headers");
+               break;
        }
        abort();
        /* NOTREACHED */
@@@ -3681,6 -3721,30 +3724,30 @@@ gen_fhostop(eaddr, dir
                b1 = gen_fhostop(eaddr, Q_DST);
                gen_or(b0, b1);
                return b1;
+       case Q_ADDR1:
+               bpf_error("'addr1' is only supported on 802.11");
+               break;
+       case Q_ADDR2:
+               bpf_error("'addr2' is only supported on 802.11");
+               break;
+       case Q_ADDR3:
+               bpf_error("'addr3' is only supported on 802.11");
+               break;
+       case Q_ADDR4:
+               bpf_error("'addr4' is only supported on 802.11");
+               break;
+       case Q_RA:
+               bpf_error("'ra' is only supported on 802.11");
+               break;
+       case Q_TA:
+               bpf_error("'ta' is only supported on 802.11");
+               break;
        }
        abort();
        /* NOTREACHED */
@@@ -3715,6 -3779,30 +3782,30 @@@ gen_thostop(eaddr, dir
                b1 = gen_thostop(eaddr, Q_DST);
                gen_or(b0, b1);
                return b1;
+       case Q_ADDR1:
+               bpf_error("'addr1' is only supported on 802.11");
+               break;
+       case Q_ADDR2:
+               bpf_error("'addr2' is only supported on 802.11");
+               break;
+       case Q_ADDR3:
+               bpf_error("'addr3' is only supported on 802.11");
+               break;
+       case Q_ADDR4:
+               bpf_error("'addr4' is only supported on 802.11");
+               break;
+       case Q_RA:
+               bpf_error("'ra' is only supported on 802.11");
+               break;
+       case Q_TA:
+               bpf_error("'ta' is only supported on 802.11");
+               break;
        }
        abort();
        /* NOTREACHED */
@@@ -4008,8 -4096,79 +4099,79 @@@ gen_wlanhostop(eaddr, dir
                gen_and(b1, b0);
                return b0;
  
+       case Q_RA:
+               /*
+                * Not present in management frames; addr1 in other
+                * frames.
+                */
+               /*
+                * If the high-order bit of the type value is 0, this
+                * is a management frame.
+                * I.e, check "(link[0] & 0x08)".
+                */
+               s = gen_load_a(OR_LINK, 0, BPF_B);
+               b1 = new_block(JMP(BPF_JSET));
+               b1->s.k = 0x08;
+               b1->stmts = s;
+               /*
+                * Check addr1.
+                */
+               b0 = gen_bcmp(OR_LINK, 4, 6, eaddr);
+               /*
+                * AND that with the check of addr1.
+                */
+               gen_and(b1, b0);
+               return (b0);
+       case Q_TA:
+               /*
+                * Not present in management frames; addr2, if present,
+                * in other frames.
+                */
+               /*
+                * Not present in CTS or ACK control frames.
+                */
+               b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+                       IEEE80211_FC0_TYPE_MASK);
+               gen_not(b0);
+               b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+                       IEEE80211_FC0_SUBTYPE_MASK);
+               gen_not(b1);
+               b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
+                       IEEE80211_FC0_SUBTYPE_MASK);
+               gen_not(b2);
+               gen_and(b1, b2);
+               gen_or(b0, b2);
+               /*
+                * If the high-order bit of the type value is 0, this
+                * is a management frame.
+                * I.e, check "(link[0] & 0x08)".
+                */
+               s = gen_load_a(OR_LINK, 0, BPF_B);
+               b1 = new_block(JMP(BPF_JSET));
+               b1->s.k = 0x08;
+               b1->stmts = s;
+               /*
+                * AND that with the check for frames other than
+                * CTS and ACK frames.
+                */
+               gen_and(b1, b2);
+               /*
+                * Check addr2.
+                */
+               b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+               gen_and(b2, b1);
+               return b1;
        /*
-        * XXX - add RA, TA, and BSSID keywords?
+        * XXX - add BSSID keyword?
         */
        case Q_ADDR1:
                return (gen_bcmp(OR_LINK, 4, 6, eaddr));
@@@ -4105,6 -4264,30 +4267,30 @@@ gen_ipfchostop(eaddr, dir
                b1 = gen_ipfchostop(eaddr, Q_DST);
                gen_or(b0, b1);
                return b1;
+       case Q_ADDR1:
+               bpf_error("'addr1' is only supported on 802.11");
+               break;
+       case Q_ADDR2:
+               bpf_error("'addr2' is only supported on 802.11");
+               break;
+       case Q_ADDR3:
+               bpf_error("'addr3' is only supported on 802.11");
+               break;
+       case Q_ADDR4:
+               bpf_error("'addr4' is only supported on 802.11");
+               break;
+       case Q_RA:
+               bpf_error("'ra' is only supported on 802.11");
+               break;
+       case Q_TA:
+               bpf_error("'ta' is only supported on 802.11");
+               break;
        }
        abort();
        /* NOTREACHED */
@@@ -4298,6 -4481,9 +4484,9 @@@ gen_host(addr, mask, proto, dir, type
        case Q_VRRP:
                bpf_error("'vrrp' modifier applied to %s", typestr);
  
+       case Q_CARP:
+               bpf_error("'carp' modifier applied to %s", typestr);
        case Q_ATALK:
                bpf_error("ATALK host filtering not implemented");
  
@@@ -4417,6 -4603,9 +4606,9 @@@ gen_host6(addr, mask, proto, dir, type
        case Q_VRRP:
                bpf_error("'vrrp' modifier applied to %s", typestr);
  
+       case Q_CARP:
+               bpf_error("'carp' modifier applied to %s", typestr);
        case Q_ATALK:
                bpf_error("ATALK host filtering not implemented");
  
@@@ -4501,6 -4690,8 +4693,8 @@@ gen_gateway(eaddr, alist, proto, dir
        case Q_RARP:
                switch (linktype) {
                case DLT_EN10MB:
+               case DLT_NETANALYZER:
+               case DLT_NETANALYZER_TRANSPARENT:
                        b0 = gen_ehostop(eaddr, Q_OR);
                        break;
                case DLT_FDDI:
                        b0 = gen_wlanhostop(eaddr, Q_OR);
                        break;
                case DLT_SUNATM:
-                       if (is_lane) {
-                               /*
-                                * Check that the packet doesn't begin with an
-                                * LE Control marker.  (We've already generated
-                                * a test for LANE.)
-                                */
-                               b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
-                                   BPF_H, 0xFF00);
-                               gen_not(b1);
+                       if (!is_lane)
+                               bpf_error(
+                                   "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+                       /*
+                        * Check that the packet doesn't begin with an
+                        * LE Control marker.  (We've already generated
+                        * a test for LANE.)
+                        */
+                       b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+                           BPF_H, 0xFF00);
+                       gen_not(b1);
  
-                               /*
-                                * Now check the MAC address.
-                                */
-                               b0 = gen_ehostop(eaddr, Q_OR);
-                               gen_and(b1, b0);
-                       }
+                       /*
+                        * Now check the MAC address.
+                        */
+                       b0 = gen_ehostop(eaddr, Q_OR);
+                       gen_and(b1, b0);
                        break;
                case DLT_IP_OVER_FC:
                        b0 = gen_ipfchostop(eaddr, Q_OR);
                        break;
                default:
                        bpf_error(
-                           "'gateway' supported only on ethernet/FDDI/token ring/802.11/Fibre Channel");
+                           "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
                }
                b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST);
                while (*alist) {
@@@ -4629,6 -4821,14 +4824,14 @@@ gen_proto_abbrev(proto
                b1 = gen_proto(IPPROTO_VRRP, Q_IP, Q_DEFAULT);
                break;
  
+ #ifndef IPPROTO_CARP
+ #define IPPROTO_CARP  112
+ #endif
+       case Q_CARP:
+               b1 = gen_proto(IPPROTO_CARP, Q_IP, Q_DEFAULT);
+               break;
        case Q_IP:
                b1 =  gen_linktype(ETHERTYPE_IP);
                break;
@@@ -4810,7 -5010,7 +5013,7 @@@ gen_ipfrag(
        struct slist *s;
        struct block *b;
  
-       /* not ip frag */
+       /* not IPv4 frag other than the first frag */
        s = gen_load_a(OR_NET, 6, BPF_H);
        b = new_block(JMP(BPF_JSET));
        b->s.k = 0x1fff;
@@@ -4853,7 -5053,7 +5056,7 @@@ gen_portop(port, proto, dir
  {
        struct block *b0, *b1, *tmp;
  
-       /* ip proto 'proto' */
+       /* ip proto 'proto' and not a fragment other than the first fragment */
        tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
        b0 = gen_ipfrag();
        gen_and(tmp, b0);
@@@ -4945,6 -5145,7 +5148,7 @@@ gen_portop6(port, proto, dir
        struct block *b0, *b1, *tmp;
  
        /* ip6 proto 'proto' */
+       /* XXX - catch the first fragment of a fragmented packet? */
        b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
  
        switch (dir) {
@@@ -5046,7 -5247,7 +5250,7 @@@ gen_portrangeop(port1, port2, proto, di
  {
        struct block *b0, *b1, *tmp;
  
-       /* ip proto 'proto' */
+       /* ip proto 'proto' and not a fragment other than the first fragment */
        tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
        b0 = gen_ipfrag();
        gen_and(tmp, b0);
@@@ -5150,6 -5351,7 +5354,7 @@@ gen_portrangeop6(port1, port2, proto, d
        struct block *b0, *b1, *tmp;
  
        /* ip6 proto 'proto' */
+       /* XXX - catch the first fragment of a fragmented packet? */
        b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
  
        switch (dir) {
@@@ -5427,12 -5629,9 +5632,9 @@@ gen_protochain(v, proto, dir
  
                /*
                 * in short,
-                * A = P[X];
-                * X = X + (P[X + 1] + 1) * 8;
+                * A = P[X + packet head];
+                * X = X + (P[X + packet head + 1] + 1) * 8;
                 */
-               /* A = X */
-               s[i] = new_stmt(BPF_MISC|BPF_TXA);
-               i++;
                /* A = P[X + packet head] */
                s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
                s[i]->s.k = off_macpl + off_nl;
                s[i] = new_stmt(BPF_ST);
                s[i]->s.k = reg2;
                i++;
-               /* A = X */
-               s[i] = new_stmt(BPF_MISC|BPF_TXA);
-               i++;
-               /* A += 1 */
-               s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
-               s[i]->s.k = 1;
-               i++;
-               /* X = A */
-               s[i] = new_stmt(BPF_MISC|BPF_TAX);
-               i++;
-               /* A = P[X + packet head]; */
+               /* A = P[X + packet head + 1]; */
                s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
-               s[i]->s.k = off_macpl + off_nl;
+               s[i]->s.k = off_macpl + off_nl + 1;
                i++;
                /* A += 1 */
                s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
                s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
                s[i]->s.k = 8;
                i++;
+               /* A += X */
+               s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_X);
+               s[i]->s.k = 0;
+               i++;
                /* X = A; */
                s[i] = new_stmt(BPF_MISC|BPF_TAX);
                i++;
@@@ -5786,6 -5979,10 +5982,10 @@@ gen_proto(v, proto, dir
                bpf_error("'vrrp proto' is bogus");
                /* NOTREACHED */
  
+       case Q_CARP:
+               bpf_error("'carp proto' is bogus");
+               /* NOTREACHED */
  #ifdef INET6
        case Q_IPV6:
                b0 = gen_linktype(ETHERTYPE_IPV6);
@@@ -5869,6 -6066,8 +6069,8 @@@ gen_scode(name, q
                        switch (linktype) {
  
                        case DLT_EN10MB:
+                       case DLT_NETANALYZER:
+                       case DLT_NETANALYZER_TRANSPARENT:
                                eaddr = pcap_ether_hostton(name);
                                if (eaddr == NULL)
                                        bpf_error(
                        res0 = res = pcap_nametoaddrinfo(name);
                        if (res == NULL)
                                bpf_error("unknown host '%s'", name);
+                       ai = res;
                        b = tmp = NULL;
                        tproto = tproto6 = proto;
                        if (off_linktype == -1 && tproto == Q_DEFAULT) {
                                        gen_or(b, tmp);
                                b = tmp;
                        }
+                       ai = NULL;
                        freeaddrinfo(res0);
                        if (b == NULL) {
                                bpf_error("unknown host '%s'%s", name,
                                /* override PROTO_UNDEF */
                                real_proto = IPPROTO_SCTP;
                }
+               if (port < 0)
+                       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
                                /* override PROTO_UNDEF */
                                real_proto = IPPROTO_SCTP;      
                }
+               if (port1 < 0)
+                       bpf_error("illegal port number %d < 0", port1);
+               if (port1 > 65535)
+                       bpf_error("illegal port number %d > 65535", port1);
+               if (port2 < 0)
+                       bpf_error("illegal port number %d < 0", port2);
+               if (port2 > 65535)
+                       bpf_error("illegal port number %d > 65535", port2);
  #ifndef INET6
                return gen_portrange(port1, port2, real_proto, dir);
  #else
@@@ -6240,6 -6454,9 +6457,9 @@@ gen_ncode(s, v, q
                else
                        bpf_error("illegal qualifier of 'port'");
  
+               if (v > 65535)
+                       bpf_error("illegal port number %u > 65535", v);
  #ifndef INET6
                return gen_port((int)v, proto, dir);
  #else
                else
                        bpf_error("illegal qualifier of 'portrange'");
  
+               if (v > 65535)
+                       bpf_error("illegal port number %u > 65535", v);
  #ifndef INET6
                return gen_portrange((int)v, (int)v, proto, dir);
  #else
@@@ -6314,6 -6534,7 +6537,7 @@@ gen_mcode6(s1, s2, masklen, q
        res = pcap_nametoaddrinfo(s1);
        if (!res)
                bpf_error("invalid ip6 address %s", s1);
+       ai = res;
        if (res->ai_next)
                bpf_error("%s resolved to multiple address", s1);
        addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
  
        case Q_NET:
                b = gen_host6(addr, &mask, q.proto, q.dir, q.addr);
+               ai = NULL;
                freeaddrinfo(res);
                return b;
  
@@@ -6365,6 -6587,8 +6590,8 @@@ gen_ecode(eaddr, q
        if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
                switch (linktype) {
                case DLT_EN10MB:
+               case DLT_NETANALYZER:
+               case DLT_NETANALYZER_TRANSPARENT:
                        return gen_ehostop(eaddr, (int)q.dir);
                case DLT_FDDI:
                        return gen_fhostop(eaddr, (int)q.dir);
@@@ -6494,7 -6718,7 +6721,7 @@@ gen_load(proto, inst, size
  
                /*
                 * Load into the X register the offset computed into the
-                * register specifed by "index".
+                * register specified by "index".
                 */
                s = xfer_to_x(inst);
  
                 * the link-layer header.  Add to it the offset computed
                 * into the register specified by "index", and move that
                 * into the X register.  Otherwise, just load into the X
-                * register the offset computed into the register specifed
+                * register the offset computed into the register specified
                 * by "index".
                 */
                if (s != NULL) {
                 * payload.  Add to it the offset computed into the
                 * register specified by "index", and move that into
                 * the X register.  Otherwise, just load into the X
-                * register the offset computed into the register specifed
+                * register the offset computed into the register specified
                 * by "index".
                 */
                if (s != NULL) {
        case Q_IGRP:
        case Q_PIM:
        case Q_VRRP:
+       case Q_CARP:
                /*
                 * The offset is relative to the beginning of
                 * the transport-layer header.
@@@ -6968,6 -7193,8 +7196,8 @@@ gen_broadcast(proto
                case DLT_ARCNET_LINUX:
                        return gen_ahostop(abroadcast, Q_DST);
                case DLT_EN10MB:
+               case DLT_NETANALYZER:
+               case DLT_NETANALYZER_TRANSPARENT:
                        return gen_ehostop(ebroadcast, Q_DST);
                case DLT_FDDI:
                        return gen_fhostop(ebroadcast, Q_DST);
                break;
  
        case Q_IP:
+               /*
+                * We treat a netmask of PCAP_NETMASK_UNKNOWN (0xffffffff)
+                * as an indication that we don't know the netmask, and fail
+                * in that case.
+                */
+               if (netmask == PCAP_NETMASK_UNKNOWN)
+                       bpf_error("netmask not known, so 'ip broadcast' not supported");
                b0 = gen_linktype(ETHERTYPE_IP);
                hostmask = ~netmask;
                b1 = gen_mcmp(OR_NET, 16, BPF_W, (bpf_int32)0, hostmask);
@@@ -7056,6 -7290,8 +7293,8 @@@ gen_multicast(proto
                        /* all ARCnet multicasts use the same address */
                        return gen_ahostop(abroadcast, Q_DST);
                case DLT_EN10MB:
+               case DLT_NETANALYZER:
+               case DLT_NETANALYZER_TRANSPARENT:
                        /* ether[0] & 1 != 0 */
                        return gen_mac_multicast(0);
                case DLT_FDDI:
@@@ -7253,6 -7489,16 +7492,16 @@@ gen_inbound(dir
                          dir);
                break;
  
+       case DLT_IPNET:
+               if (dir) {
+                       /* match outgoing packets */
+                       b0 = gen_cmp(OR_LINK, 2, BPF_H, IPNET_OUTBOUND);
+               } else {
+                       /* match incoming packets */
+                       b0 = gen_cmp(OR_LINK, 2, BPF_H, IPNET_INBOUND);
+               }
+               break;
        case DLT_LINUX_SLL:
                if (dir) {
                        /*
          case DLT_JUNIPER_VP:
          case DLT_JUNIPER_ST:
          case DLT_JUNIPER_ISM:
+         case DLT_JUNIPER_VS:
+         case DLT_JUNIPER_SRX_E2E:
+         case DLT_JUNIPER_FIBRECHANNEL:
+       case DLT_JUNIPER_ATM_CEMIC:
                /* juniper flags (including direction) are stored
                 * the byte after the 3-byte magic number */
                if (dir) {
@@@ -7589,6 -7840,30 +7843,30 @@@ gen_ahostop(eaddr, dir
                b1 = gen_ahostop(eaddr, Q_DST);
                gen_or(b0, b1);
                return b1;
+       case Q_ADDR1:
+               bpf_error("'addr1' is only supported on 802.11");
+               break;
+       case Q_ADDR2:
+               bpf_error("'addr2' is only supported on 802.11");
+               break;
+       case Q_ADDR3:
+               bpf_error("'addr3' is only supported on 802.11");
+               break;
+       case Q_ADDR4:
+               bpf_error("'addr4' is only supported on 802.11");
+               break;
+       case Q_RA:
+               bpf_error("'ra' is only supported on 802.11");
+               break;
+       case Q_TA:
+               bpf_error("'ta' is only supported on 802.11");
+               break;
        }
        abort();
        /* NOTREACHED */
@@@ -7643,9 -7918,15 +7921,15 @@@ gen_vlan(vlan_num
        switch (linktype) {
  
        case DLT_EN10MB:
-               /* check for VLAN */
+       case DLT_NETANALYZER:
+       case DLT_NETANALYZER_TRANSPARENT:
+               /* check for VLAN, including QinQ */
                b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
                    (bpf_int32)ETHERTYPE_8021Q);
+               b1 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+                   (bpf_int32)ETHERTYPE_8021QINQ);
+               gen_or(b0,b1);
+               b0 = b1;
  
                /* If a specific VLAN is requested, check VLAN id */
                if (vlan_num >= 0) {
@@@ -7706,6 -7987,8 +7990,8 @@@ gen_mpls(label_num
                  
              case DLT_C_HDLC: /* fall through */
              case DLT_EN10MB:
+             case DLT_NETANALYZER:
+             case DLT_NETANALYZER_TRANSPARENT:
                      b0 = gen_linktype(ETHERTYPE_MPLS);
                      break;
                  
@@@ -22,7 -22,7 +22,7 @@@
   */
  #ifndef lint
  static const char rcsid[] _U_ =
-     "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.99.2.2 2007/11/18 02:04:55 guy Exp $ (LBL)";
+     "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
  #endif
  
  #ifdef HAVE_CONFIG_H
@@@ -45,6 -45,7 +45,7 @@@ struct rtentry
  #endif
  
  #include <netinet/in.h>
+ #include <arpa/inet.h>
  #endif /* WIN32 */
  
  #include <stdio.h>
  #include "gencode.h"
  #ifdef HAVE_NET_PFVAR_H
  #include <net/if.h>
 -#include <net/pfvar.h>
 -#include <net/if_pflog.h>
 +#include <net/if_var.h>
 +#include <net/pf/pfvar.h>
 +#include <net/pf/if_pflog.h>
  #endif
 -#include "ieee80211.h"
 +#include <netproto/802_11/ieee80211.h>
  #include <pcap/namedb.h>
  
  #ifdef HAVE_OS_PROTO_H
@@@ -120,16 -120,16 +121,16 @@@ static const struct tok ieee80211_data_
        { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
        { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
        { IEEE80211_FC0_SUBTYPE_NODATA, "null" },
 -      { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
 -      { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll"  },
 -      { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
 +      { IEEE80211_FC0_SUBTYPE_CFACK, "cf-ack" },
 +      { IEEE80211_FC0_SUBTYPE_CFPOLL, "cf-poll"  },
 +      { IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK, "cf-ack-poll" },
        { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
        { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
        { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
        { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
        { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
 -      { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
 -      { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
 +      { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CFPOLL, "qos-cf-poll" },
 +      { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK, "qos-cf-ack-poll" },
        { 0, NULL }
  };
  struct type2tok {
@@@ -272,12 -272,12 +273,12 @@@ pfaction_to_num(const char *action
  
  %token  DST SRC HOST GATEWAY
  %token  NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
- %token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
+ %token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
  %token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
  %token  TK_BROADCAST TK_MULTICAST
  %token  NUM INBOUND OUTBOUND
  %token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
- %token        TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4
+ %token        TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
  %token  LINK
  %token        GEQ LEQ NEQ
  %token        ID EID HID HID6 AID
@@@ -442,6 -442,8 +443,8 @@@ dqual:       SRC                   { $$ = Q_SRC; 
        | ADDR2                 { $$ = Q_ADDR2; }
        | ADDR3                 { $$ = Q_ADDR3; }
        | ADDR4                 { $$ = Q_ADDR4; }
+       | RA                    { $$ = Q_RA; }
+       | TA                    { $$ = Q_TA; }
        ;
  /* address type qualifiers */
  aqual:          HOST                  { $$ = Q_HOST; }
@@@ -464,6 -466,7 +467,7 @@@ pname:       LINK                  { $$ = Q_LINK; 
        | IGRP                  { $$ = Q_IGRP; }
        | PIM                   { $$ = Q_PIM; }
        | VRRP                  { $$ = Q_VRRP; }
+       | CARP                  { $$ = Q_CARP; }
        | ATALK                 { $$ = Q_ATALK; }
        | AARP                  { $$ = Q_AARP; }
        | DECNET                { $$ = Q_DECNET; }
@@@ -31,7 -31,7 +31,7 @@@
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
-  * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.11 2008-10-06 15:38:39 gianluca Exp $ (LBL)
+  * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.15 2008-10-06 15:27:32 gianluca Exp $ (LBL)
   */
  
  #ifndef lib_pcap_pcap_h
@@@ -48,7 -48,7 +48,7 @@@
  #endif /* WIN32/MSDOS/UN*X */
  
  #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
 -#include <pcap/bpf.h>
 +#include <net/bpf.h>
  #endif
  
  #include <stdio.h>
  extern "C" {
  #endif
  
+ /*
+  * Version number of the current version of the pcap file format.
+  *
+  * NOTE: this is *NOT* the version number of the libpcap library.
+  * To fetch the version information for the version of libpcap
+  * you're using, use pcap_lib_version().
+  */
  #define PCAP_VERSION_MAJOR 2
  #define PCAP_VERSION_MINOR 4
  
@@@ -163,7 -170,7 +170,7 @@@ struct pcap_pkthdr 
  struct pcap_stat {
        u_int ps_recv;          /* number of packets received */
        u_int ps_drop;          /* number of packets dropped */
-       u_int ps_ifdrop;        /* drops by interface XXX not yet supported */
+       u_int ps_ifdrop;        /* drops by interface -- only supported on some platforms */
  #ifdef WIN32
        u_int bs_capt;          /* number of packets that reach the application */
  #endif /* WIN32 */
@@@ -244,6 -251,8 +251,8 @@@ typedef void (*pcap_handler)(u_char *, 
  #define PCAP_ERROR_NOT_RFMON          -7      /* operation supported only in monitor mode */
  #define PCAP_ERROR_PERM_DENIED                -8      /* no permission to open the device */
  #define PCAP_ERROR_IFACE_NOT_UP               -9      /* interface isn't up */
+ #define PCAP_ERROR_CANTSET_TSTAMP_TYPE        -10     /* this device doesn't support setting the time stamp type */
+ #define PCAP_ERROR_PROMISC_PERM_DENIED        -11     /* you don't have permission to capture in promiscuous mode */
  
  /*
   * Warning codes for the pcap API.
   */
  #define PCAP_WARNING                  1       /* generic warning code */
  #define PCAP_WARNING_PROMISC_NOTSUP   2       /* this device doesn't support promiscuous mode */
+ #define PCAP_WARNING_TSTAMP_TYPE_NOTSUP       3       /* the requested time stamp type is not supported */
+ /*
+  * Value to pass to pcap_compile() as the netmask if you don't know what
+  * the netmask is.
+  */
+ #define PCAP_NETMASK_UNKNOWN  0xffffffff
  
  char  *pcap_lookupdev(char *);
  int   pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
@@@ -262,9 -278,60 +278,60 @@@ int      pcap_set_promisc(pcap_t *, int)
  int   pcap_can_set_rfmon(pcap_t *);
  int   pcap_set_rfmon(pcap_t *, int);
  int   pcap_set_timeout(pcap_t *, int);
+ int   pcap_set_tstamp_type(pcap_t *, int);
  int   pcap_set_buffer_size(pcap_t *, int);
  int   pcap_activate(pcap_t *);
  
+ int   pcap_list_tstamp_types(pcap_t *, int **);
+ void  pcap_free_tstamp_types(int *);
+ int   pcap_tstamp_type_name_to_val(const char *);
+ const char *pcap_tstamp_type_val_to_name(int);
+ const char *pcap_tstamp_type_val_to_description(int);
+ /*
+  * Time stamp types.
+  * Not all systems and interfaces will necessarily support all of these.
+  *
+  * A system that supports PCAP_TSTAMP_HOST is offering time stamps
+  * provided by the host machine, rather than by the capture device,
+  * but not committing to any characteristics of the time stamp;
+  * it will not offer any of the PCAP_TSTAMP_HOST_ subtypes.
+  *
+  * PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine,
+  * that's low-precision but relatively cheap to fetch; it's normally done
+  * using the system clock, so it's normally synchronized with times you'd
+  * fetch from system calls.
+  *
+  * PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine,
+  * that's high-precision; it might be more expensive to fetch.  It might
+  * or might not be synchronized with the system clock, and might have
+  * problems with time stamps for packets received on different CPUs,
+  * depending on the platform.
+  *
+  * PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the
+  * capture device; it's synchronized with the system clock.
+  *
+  * PCAP_TSTAMP_ADAPTER_UNSYNCED is a high-precision time stamp supplied by
+  * the capture device; it's not synchronized with the system clock.
+  *
+  * Note that time stamps synchronized with the system clock can go
+  * backwards, as the system clock can go backwards.  If a clock is
+  * not in sync with the system clock, that could be because the
+  * system clock isn't keeping accurate time, because the other
+  * clock isn't keeping accurate time, or both.
+  *
+  * Note that host-provided time stamps generally correspond to the
+  * time when the time-stamping code sees the packet; this could
+  * be some unknown amount of time after the first or last bit of
+  * the packet is received by the network adapter, due to batching
+  * of interrupts for packet arrival, queueing delays, etc..
+  */
+ #define PCAP_TSTAMP_HOST              0       /* host-provided, unknown characteristics */
+ #define PCAP_TSTAMP_HOST_LOWPREC      1       /* host-provided, low precision */
+ #define PCAP_TSTAMP_HOST_HIPREC               2       /* host-provided, high precision */
+ #define PCAP_TSTAMP_ADAPTER           3       /* device-provided, synced with the system clock */
+ #define PCAP_TSTAMP_ADAPTER_UNSYNCED  4       /* device-provided, not synced with the system clock */
  pcap_t        *pcap_open_live(const char *, int, int, int, char *);
  pcap_t        *pcap_open_dead(int, int);
  pcap_t        *pcap_open_offline(const char *, char *);
@@@ -335,8 -402,16 +402,16 @@@ void     pcap_freealldevs(pcap_if_t *)
  
  const char *pcap_lib_version(void);
  
- /* XXX this guy lives in the bpf tree */
+ /*
+  * On at least some versions of NetBSD, we don't want to declare
+  * bpf_filter() here, as it's also be declared in <net/bpf.h>, with a
+  * different signature, but, on other BSD-flavored UN*Xes, it's not
+  * declared in <net/bpf.h>, so we *do* want to declare it here, so it's
+  * declared when we build pcap-bpf.c.
+  */
+ #ifndef __NetBSD__
  u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
+ #endif
  int   bpf_validate(const struct bpf_insn *f, int len);
  char  *bpf_image(const struct bpf_insn *, int);
  void  bpf_dump(const struct bpf_program *, int);
@@@ -384,4 -459,4 +459,4 @@@ int        pcap_get_selectable_fd(pcap_t *)
  }
  #endif
  
- #endif
+ #endif /* lib_pcap_pcap_h */
  
  #ifndef lint
  static const char rcsid[] _U_ =
-     "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.110.2.2 2008/02/06 10:21:47 guy Exp $ (LBL)";
+     "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.112 2008-02-06 10:21:30 guy Exp $ (LBL)";
  #endif
  
  #ifdef HAVE_CONFIG_H
  #include "config.h"
  #endif
  
+ #ifdef WIN32
+ #include <pcap-stdinc.h>
+ #else /* WIN32 */
+ #if HAVE_INTTYPES_H
+ #include <inttypes.h>
+ #elif HAVE_STDINT_H
+ #include <stdint.h>
+ #endif
+ #ifdef HAVE_SYS_BITYPES_H
+ #include <sys/bitypes.h>
+ #endif
+ #include <sys/types.h>
+ #endif /* WIN32 */
  #include <ctype.h>
  #include <string.h>
  
@@@ -40,7 -54,7 +54,7 @@@
  #include <pcap-stdinc.h>
  
  #ifdef __MINGW32__
- #include "IP6_misc.h"
+ #include "ip6_misc.h"
  #endif
  #else /* WIN32 */
  #include <sys/socket.h>       /* for "struct sockaddr" in "struct addrinfo" */
@@@ -63,11 -77,11 +77,12 @@@ static int stoi(char *)
  static inline int xdtoi(int);
  
  #ifdef FLEX_SCANNER
+ #define YY_NO_INPUT
  #define YY_NO_UNPUT
 +#define YY_NO_INPUT
  static YY_BUFFER_STATE in_buffer;
  #else
- static char *in_buffer;
+ static const char *in_buffer;
  
  #undef getc
  #define getc(fp)  (*in_buffer == 0 ? EOF : *in_buffer++)
@@@ -189,6 -203,7 +204,7 @@@ igmp               return IGMP
  igrp          return IGRP;
  pim           return PIM;
  vrrp          return VRRP;
+ carp          return CARP;
  radio         return RADIO;
  
  ip6           {
@@@ -260,6 -275,8 +276,8 @@@ address1|addr1     return ADDR1
  address2|addr2        return ADDR2;
  address3|addr3        return ADDR3;
  address4|addr4        return ADDR4;
+ ra            return RA;
+ ta            return TA;
  
  less          return LESS;
  greater               return GREATER;
@@@ -335,6 -352,7 +353,7 @@@ ${B}                       { yylval.e = pcap_ether_aton(((c
                          if (getaddrinfo(yytext, NULL, &hints, &res))
                                bpf_error("bogus IPv6 address %s", yytext);
                          else {
+                               freeaddrinfo(res);
                                yylval.s = sdup((char *)yytext); return HID6;
                          }
  #else