Merge branch 'vendor/LIBPCAP'
authorPeter Avalos <pavalos@dragonflybsd.org>
Wed, 11 Jul 2012 01:36:31 +0000 (18:36 -0700)
committerPeter Avalos <pavalos@dragonflybsd.org>
Wed, 11 Jul 2012 01:36:31 +0000 (18:36 -0700)
1  2 
contrib/libpcap/gencode.c

@@@ -84,11 -84,16 +84,16 @@@ static const char rcsid[] _U_ 
  #include "pcap/sll.h"
  #include "pcap/ipnet.h"
  #include "arcnet.h"
+ #if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+ #include <linux/types.h>
+ #include <linux/if_packet.h>
+ #include <linux/filter.h>
+ #endif
  #ifdef HAVE_NET_PFVAR_H
  #include <sys/socket.h>
  #include <net/if.h>
 -#include <net/pfvar.h>
 -#include <net/if_pflog.h>
 +#include <net/pf/pfvar.h>
 +#include <net/pf/if_pflog.h>
  #endif
  #ifndef offsetof
  #define offsetof(s, e) ((size_t)&((s *)0)->e)
@@@ -418,7 -423,7 +423,7 @@@ pcap_compile(pcap_t *p, struct bpf_prog
  {
        extern int n_errors;
        const char * volatile xbuf = buf;
-       int len;
+       u_int len;
  
        no_optimize = 0;
        n_errors = 0;
@@@ -1393,14 -1398,12 +1398,12 @@@ init_linktype(p
                off_nl_nosnap = -1;
                return;
  
- #ifdef DLT_PFSYNC
        case DLT_PFSYNC:
                off_linktype = -1;
                off_macpl = 4;
                off_nl = 0;
                off_nl_nosnap = 0;
                return;
- #endif
  
        case DLT_AX25_KISS:
                /*
@@@ -3356,10 -3359,8 +3359,8 @@@ gen_linktype(proto
        case DLT_ERF:
                bpf_error("ERF link-layer type filtering not implemented");
  
- #ifdef DLT_PFSYNC
        case DLT_PFSYNC:
                bpf_error("PFSYNC link-layer type filtering not implemented");
- #endif
  
        case DLT_LINUX_LAPD:
                bpf_error("LAPD link-layer type filtering not implemented");
@@@ -5819,6 -5820,11 +5820,11 @@@ 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)
                bpf_error("direction applied to 'proto'");
        case Q_IPV6:
                b0 = gen_linktype(ETHERTYPE_IPV6);
  #ifndef CHASE_CHAIN
-               b1 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v);
+               /*
+                * Also check for a fragment header before the final
+                * header.
+                */
+               b2 = gen_cmp(OR_NET, 6, BPF_B, IPPROTO_FRAGMENT);
+               b1 = gen_cmp(OR_NET, 40, BPF_B, (bpf_int32)v);
+               gen_and(b2, b1);
+               b2 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v);
+               gen_or(b2, b1);
  #else
                b1 = gen_protochain(v, Q_IPV6);
  #endif
@@@ -7468,9 -7482,13 +7482,13 @@@ gen_multicast(proto
  }
  
  /*
-  * generate command for inbound/outbound.  It's here so we can
-  * make it link-type specific.  'dir' = 0 implies "inbound",
-  * = 1 implies "outbound".
+  * Filter on inbound (dir == 0) or outbound (dir == 1) traffic.
+  * Outbound traffic is sent by this machine, while inbound traffic is
+  * sent by a remote machine (and may include packets destined for a
+  * unicast or multicast link-layer address we are not subscribing to).
+  * These are the same definitions implemented by pcap_setdirection().
+  * Capturing only unicast traffic destined for this host is probably
+  * better accomplished using a higher-layer filter.
   */
  struct block *
  gen_inbound(dir)
                break;
  
        case DLT_LINUX_SLL:
-               if (dir) {
-                       /*
-                        * Match packets sent by this machine.
-                        */
-                       b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_OUTGOING);
-               } else {
-                       /*
-                        * Match packets sent to this machine.
-                        * (No broadcast or multicast packets, or
-                        * packets sent to some other machine and
-                        * received promiscuously.)
-                        *
-                        * XXX - packets sent to other machines probably
-                        * shouldn't be matched, but what about broadcast
-                        * or multicast packets we received?
-                        */
-                       b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_HOST);
+               /* match outgoing packets */
+               b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_OUTGOING);
+               if (!dir) {
+                       /* to filter on inbound traffic, invert the match */
+                       gen_not(b0);
                }
                break;
  
                break;
  
        default:
+               /*
+                * If we have packet meta-data indicating a direction,
+                * check it, otherwise give up as this link-layer type
+                * has nothing in the packet data.
+                */
+ #if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+               /*
+                * We infer that this is Linux with PF_PACKET support.
+                * If this is a *live* capture, we can look at
+                * special meta-data in the filter expression;
+                * if it's a savefile, we can't.
+                */
+               if (bpf_pcap->sf.rfile != NULL) {
+                       /* We have a FILE *, so this is a savefile */
+                       bpf_error("inbound/outbound not supported on linktype %d when reading savefiles",
+                           linktype);
+                       b0 = NULL;
+                       /* NOTREACHED */
+               }
+               /* match outgoing packets */
+               b0 = gen_cmp(OR_LINK, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H,
+                            PACKET_OUTGOING);
+               if (!dir) {
+                       /* to filter on inbound traffic, invert the match */
+                       gen_not(b0);
+               }
+ #else /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
                bpf_error("inbound/outbound not supported on linktype %d",
                    linktype);
                b0 = NULL;
                /* NOTREACHED */
+ #endif /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
        }
        return (b0);
  }