]> The Tcpdump Group git mirrors - libpcap/commitdiff
Move the socket ops out of gencode.c.
authorGuy Harris <[email protected]>
Wed, 5 Nov 2014 22:33:14 +0000 (14:33 -0800)
committerGuy Harris <[email protected]>
Wed, 5 Nov 2014 22:33:14 +0000 (14:33 -0800)
Instead, do it in pcap-linux.c, and have it set a flag in the pcap_t
structure to indicate to the code in gencode.c that it needs to generate
special VLAN-handling code.

gencode.c
pcap-int.h
pcap-linux.c
pcap.c
savefile.c

index 30b2e50a7eb06d27b32bf357e7f90c96698229d9..c59abe6ad1ac6d40b5710914ec8f9123f02ea965 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -54,7 +54,6 @@
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <errno.h>
 
 #endif /* WIN32 */
 
@@ -8048,23 +8047,11 @@ gen_ahostop(eaddr, dir)
 }
 
 #if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
-static int skf_ad_vlan_tag_present_supported(int bpf_extensions) {
-        return bpf_extensions >= SKF_AD_VLAN_TAG_PRESENT;
-}
-
 static struct block *
-gen_vlan_bpf_extensions(int vlan_num) {
+gen_vlan_bpf_extensions(int vlan_num)
+{
         struct block *b0, *b1;
         struct slist *s;
-        int val = 0, len, r;
-
-        len = sizeof(val);
-        r = getsockopt(bpf_pcap->fd, SOL_SOCKET, SO_BPF_EXTENSIONS, &val, &len);
-        if (r < 0)
-                return NULL;
-
-        if (!skf_ad_vlan_tag_present_supported(val))
-                return NULL;
 
         /* generate new filter code based on extracting packet
          * metadata */
@@ -8092,7 +8079,8 @@ gen_vlan_bpf_extensions(int vlan_num) {
 #endif
 
 static struct block *
-gen_vlan_no_bpf_extensions(int vlan_num) {
+gen_vlan_no_bpf_extensions(int vlan_num)
+{
         struct block *b0, *b1;
 
         /* check for VLAN, including QinQ */
@@ -8169,14 +8157,17 @@ gen_vlan(vlan_num)
        case DLT_NETANALYZER:
        case DLT_NETANALYZER_TRANSPARENT:
 #if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
-                if (!vlan_stack_depth) {
-                        b0 = gen_vlan_bpf_extensions(vlan_num);
-                        if (!b0)
-                                b0 = gen_vlan_no_bpf_extensions(vlan_num);
-                }
-                else
+               if (vlan_stack_depth == 0) {
+                       /*
+                        * Do we need special VLAN handling?
+                        */
+                       if (p->bpf_codegen_flags & BPF_SPECIAL_VLAN_HANDLING)
+                               b0 = gen_vlan_bpf_extensions(vlan_num);
+                       else
+                               b0 = gen_vlan_no_bpf_extensions(vlan_num);
+               } else
 #endif
-                        b0 = gen_vlan_no_bpf_extensions(vlan_num);
+                       b0 = gen_vlan_no_bpf_extensions(vlan_num);
                 break;
        default:
                bpf_error("no VLAN support for data link type %d",
index 5a20444617a9d8d061ddf9d1ff7ae06815145b26..2f71e1152676aa8c949b3aff06dea27a2ad6697e 100644 (file)
@@ -202,6 +202,11 @@ struct pcap {
        /* We're accepting only packets in this direction/these directions. */
        pcap_direction_t direction;
 
+       /*
+        * Flags to affect BPF code generation.
+        */
+       int bpf_codegen_flags;
+
        /*
         * Placeholder for filter code if bpf not in kernel.
         */
@@ -248,6 +253,11 @@ struct pcap {
        cleanup_op_t cleanup_op;
 };
 
+/*
+ * BPF code generation flags.
+ */
+#define BPF_SPECIAL_VLAN_HANDLING      0x00000001      /* special VLAN handling for Linux */
+
 /*
  * This is a timeval as stored in a savefile.
  * It has to use the same types everywhere, independent of the actual
index 2f092b7f85bc8bb66aff005b9855bc47694ed58f..5d63e849192383aab966b16d89bb2408894feae6 100644 (file)
@@ -3015,6 +3015,9 @@ activate_new(pcap_t *handle)
 #endif
        int                     err = 0;
        struct packet_mreq      mr;
+#ifdef SO_BPF_EXTENSIONS
+       int                     bpf_extensions, len;
+#endif
 
        /*
         * Open a socket with protocol family packet. If the
@@ -3345,6 +3348,23 @@ activate_new(pcap_t *handle)
         */
        handle->fd = sock_fd;
 
+#ifdef SO_BPF_EXTENSIONS
+       /*
+        * Can we generate special code for VLAN checks?
+        * (XXX - what if we need the special code but it's not supported
+        * by the OS?  Is that possible?)
+        */
+       if (getsockopt(sock_fd, SOL_SOCKET, SO_BPF_EXTENSIONS,
+           &bpf_extensions, &len == 0) {
+               if (bpf_extensions >= SKF_AD_VLAN_TAG_PRESENT) {
+                       /*
+                        * Yes, we can.  Request that we do so.
+                        */
+                       handle->bpf_codegen_flags |= BPF_SPECIAL_VLAN_HANDLING;
+               }
+       }
+#endif /* SO_BPF_EXTENSIONS */
+
        return 1;
 #else /* HAVE_PF_PACKET_SOCKETS */
        strlcpy(ebuf,
diff --git a/pcap.c b/pcap.c
index badc312b804ad8a63b02cabe3fad0a6b4480c5d6..ff0219556c244115594d3fe84f66c2de9f6903ed 100644 (file)
--- a/pcap.c
+++ b/pcap.c
@@ -561,6 +561,12 @@ pcap_create_common(const char *source, char *ebuf, size_t size)
        p->opt.immediate = 0;
        p->opt.tstamp_type = -1;        /* default to not setting time stamp type */
        p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
+
+       /*
+        * Start out with no BPF code generation flags set.
+        */
+       p->bpf_codegen_flags = 0;
+
        return (p);
 }
 
@@ -1831,6 +1837,12 @@ pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision)
        p->setmintocopy_op = pcap_setmintocopy_dead;
 #endif
        p->cleanup_op = pcap_cleanup_dead;
+
+       /*
+        * A "dead" pcap_t never requires special BPF code generation.
+        */
+       p->bpf_codegen_flags = 0;
+
        p->activated = 1;
        return (p);
 }
index 0ab2fdefb201ee91be5a342b5e0cc13c14e6e658..abe1d2dd63b50de5d3b1f5c071a7324902f419cd 100644 (file)
@@ -344,6 +344,11 @@ found:
         */
        p->oneshot_callback = pcap_oneshot;
 
+       /*
+        * Savefiles never require special BPF code generation.
+        */
+       p->bpf_codegen_flags = 0;
+
        p->activated = 1;
 
        return (p);