Blame SOURCES/0005-Move-the-socket-ops-out-of-gencode.c.patch

9b1536
From 06553e55d6ff2b203c4ab1dda2d6fb15c45e2896 Mon Sep 17 00:00:00 2001
9b1536
From: Guy Harris <guy@alum.mit.edu>
9b1536
Date: Wed, 5 Nov 2014 14:33:14 -0800
9b1536
Subject: [PATCH 5/5] Move the socket ops out of gencode.c.
9b1536
9b1536
Instead, do it in pcap-linux.c, and have it set a flag in the pcap_t
9b1536
structure to indicate to the code in gencode.c that it needs to generate
9b1536
special VLAN-handling code.
9b1536
9b1536
(cherry picked from 612503bb0801a49a1c6ebe9c82591289b1d2e5c9)
9b1536
9b1536
Conflicts:
9b1536
        pcap-linux.c
9b1536
---
9b1536
 gencode.c    | 37 ++++++++++++++-----------------------
9b1536
 pcap-int.h   | 10 ++++++++++
9b1536
 pcap-linux.c | 24 ++++++++++++++++++++++++
9b1536
 pcap.c       | 12 ++++++++++++
9b1536
 savefile.c   |  5 +++++
9b1536
 5 files changed, 65 insertions(+), 23 deletions(-)
9b1536
9b1536
diff --git a/gencode.c b/gencode.c
9b1536
index 9c1d17b..6b3772f 100644
9b1536
--- a/gencode.c
9b1536
+++ b/gencode.c
9b1536
@@ -58,7 +58,6 @@ static const char rcsid[] _U_ =
9b1536
 
9b1536
 #include <netinet/in.h>
9b1536
 #include <arpa/inet.h>
9b1536
-#include <errno.h>
9b1536
 
9b1536
 #endif /* WIN32 */
9b1536
 
9b1536
@@ -7864,23 +7863,11 @@ gen_ahostop(eaddr, dir)
9b1536
 }
9b1536
 
9b1536
 #if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
9b1536
-static int skf_ad_vlan_tag_present_supported(int bpf_extensions) {
9b1536
-        return bpf_extensions >= SKF_AD_VLAN_TAG_PRESENT;
9b1536
-}
9b1536
-
9b1536
 static struct block *
9b1536
-gen_vlan_bpf_extensions(int vlan_num) {
9b1536
+gen_vlan_bpf_extensions(int vlan_num)
9b1536
+{
9b1536
         struct block *b0, *b1;
9b1536
         struct slist *s;
9b1536
-        int val = 0, len, r;
9b1536
-
9b1536
-        len = sizeof(val);
9b1536
-        r = getsockopt(bpf_pcap->fd, SOL_SOCKET, SO_BPF_EXTENSIONS, &val, &len;;
9b1536
-        if (r < 0)
9b1536
-                return NULL;
9b1536
-
9b1536
-        if (!skf_ad_vlan_tag_present_supported(val))
9b1536
-                return NULL;
9b1536
 
9b1536
         /* generate new filter code based on extracting packet
9b1536
          * metadata */
9b1536
@@ -7908,7 +7895,8 @@ gen_vlan_bpf_extensions(int vlan_num) {
9b1536
 #endif
9b1536
 
9b1536
 static struct block *
9b1536
-gen_vlan_no_bpf_extensions(int vlan_num) {
9b1536
+gen_vlan_no_bpf_extensions(int vlan_num)
9b1536
+{
9b1536
         struct block *b0, *b1;
9b1536
 
9b1536
         /* check for VLAN, including QinQ */
9b1536
@@ -7985,14 +7973,17 @@ gen_vlan(vlan_num)
9b1536
 	case DLT_NETANALYZER:
9b1536
 	case DLT_NETANALYZER_TRANSPARENT:
9b1536
 #if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
9b1536
-                if (!vlan_stack_depth) {
9b1536
-                        b0 = gen_vlan_bpf_extensions(vlan_num);
9b1536
-                        if (!b0)
9b1536
-                                b0 = gen_vlan_no_bpf_extensions(vlan_num);
9b1536
-                }
9b1536
-                else
9b1536
+		if (vlan_stack_depth == 0) {
9b1536
+			/*
9b1536
+			 * Do we need special VLAN handling?
9b1536
+			 */
9b1536
+			if (bpf_pcap->bpf_codegen_flags & BPF_SPECIAL_VLAN_HANDLING)
9b1536
+				b0 = gen_vlan_bpf_extensions(vlan_num);
9b1536
+			else
9b1536
+				b0 = gen_vlan_no_bpf_extensions(vlan_num);
9b1536
+		} else
9b1536
 #endif
9b1536
-                        b0 = gen_vlan_no_bpf_extensions(vlan_num);
9b1536
+			b0 = gen_vlan_no_bpf_extensions(vlan_num);
9b1536
                 break;
9b1536
 	default:
9b1536
 		bpf_error("no VLAN support for data link type %d",
9b1536
diff --git a/pcap-int.h b/pcap-int.h
9b1536
index 0c27ec7..c9dbb5f 100644
9b1536
--- a/pcap-int.h
9b1536
+++ b/pcap-int.h
9b1536
@@ -182,6 +182,11 @@ struct pcap {
9b1536
 	pcap_direction_t direction;
9b1536
 
9b1536
 	/*
9b1536
+	 * Flags to affect BPF code generation.
9b1536
+	 */
9b1536
+	int bpf_codegen_flags;
9b1536
+
9b1536
+	/*
9b1536
 	 * Placeholder for filter code if bpf not in kernel.
9b1536
 	 */
9b1536
 	struct bpf_program fcode;
9b1536
@@ -228,6 +233,11 @@ struct pcap {
9b1536
 };
9b1536
 
9b1536
 /*
9b1536
+ * BPF code generation flags.
9b1536
+ */
9b1536
+#define BPF_SPECIAL_VLAN_HANDLING	0x00000001	/* special VLAN handling for Linux */
9b1536
+
9b1536
+/*
9b1536
  * This is a timeval as stored in a savefile.
9b1536
  * It has to use the same types everywhere, independent of the actual
9b1536
  * `struct timeval'; `struct timeval' has 32-bit tv_sec values on some
9b1536
diff --git a/pcap-linux.c b/pcap-linux.c
9b1536
index a370858..a82f4eb 100644
9b1536
--- a/pcap-linux.c
9b1536
+++ b/pcap-linux.c
9b1536
@@ -3024,6 +3024,10 @@ activate_new(pcap_t *handle)
9b1536
 #endif
9b1536
 	int			err = 0;
9b1536
 	struct packet_mreq	mr;
9b1536
+#ifdef SO_BPF_EXTENSIONS
9b1536
+	int			bpf_extensions;
9b1536
+	socklen_t		len;
9b1536
+#endif
9b1536
 
9b1536
 	/*
9b1536
 	 * Open a socket with protocol family packet. If the
9b1536
@@ -3342,6 +3346,26 @@ activate_new(pcap_t *handle)
9b1536
 	/* Save the socket FD in the pcap structure */
9b1536
 	handle->fd = sock_fd;
9b1536
 
9b1536
+#ifdef SO_BPF_EXTENSIONS
9b1536
+	/*
9b1536
+	 * Can we generate special code for VLAN checks?
9b1536
+	 * (XXX - what if we need the special code but it's not supported
9b1536
+	 * by the OS?  Is that possible?)
9b1536
+	 */
9b1536
+	len = sizeof(bpf_extensions);
9b1536
+
9b1536
+	if (getsockopt(sock_fd, SOL_SOCKET, SO_BPF_EXTENSIONS, &bpf_extensions, &len) == 0) {
9b1536
+		if (bpf_extensions >= SKF_AD_VLAN_TAG_PRESENT) {
9b1536
+			/*
9b1536
+			 * Yes, we can.  Request that we do so.
9b1536
+			 */
9b1536
+			handle->bpf_codegen_flags |= BPF_SPECIAL_VLAN_HANDLING;
9b1536
+		}
9b1536
+	}
9b1536
+#endif /* SO_BPF_EXTENSIONS */
9b1536
+
9b1536
+
9b1536
+
9b1536
 #if defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS)
9b1536
 	if (handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
9b1536
 		int nsec_tstamps = 1;
9b1536
diff --git a/pcap.c b/pcap.c
9b1536
index 6b16cea..74dc708 100644
9b1536
--- a/pcap.c
9b1536
+++ b/pcap.c
9b1536
@@ -558,6 +558,12 @@ pcap_create_common(const char *source, char *ebuf, size_t size)
9b1536
 	p->opt.immediate = 0;
9b1536
 	p->opt.tstamp_type = -1;	/* default to not setting time stamp type */
9b1536
 	p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
9b1536
+
9b1536
+	/*
9b1536
+	 * Start out with no BPF code generation flags set.
9b1536
+	 */
9b1536
+	p->bpf_codegen_flags = 0;
9b1536
+
9b1536
 	return (p);
9b1536
 }
9b1536
 
9b1536
@@ -1810,6 +1816,12 @@ pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision)
9b1536
 	p->setmintocopy_op = pcap_setmintocopy_dead;
9b1536
 #endif
9b1536
 	p->cleanup_op = pcap_cleanup_dead;
9b1536
+
9b1536
+	/*
9b1536
+	 * A "dead" pcap_t never requires special BPF code generation.
9b1536
+	 */
9b1536
+	p->bpf_codegen_flags = 0;
9b1536
+
9b1536
 	p->activated = 1;
9b1536
 	return (p);
9b1536
 }
9b1536
diff --git a/savefile.c b/savefile.c
9b1536
index 73e3ea9..98f9c82 100644
9b1536
--- a/savefile.c
9b1536
+++ b/savefile.c
9b1536
@@ -349,6 +349,11 @@ found:
9b1536
 	 */
9b1536
 	p->oneshot_callback = pcap_oneshot;
9b1536
 
9b1536
+	/*
9b1536
+	 * Savefiles never require special BPF code generation.
9b1536
+	 */
9b1536
+	p->bpf_codegen_flags = 0;
9b1536
+
9b1536
 	p->activated = 1;
9b1536
 
9b1536
 	return (p);
9b1536
-- 
9b1536
2.4.3
9b1536