File libpcap-userspace-filter.patch of Package libpcap.2975

From: Tommy Beadle <tbeadle@arbor.net>
Date: Tue, 10 Feb 2015 13:49:45 -0500
Subject: Make sure the userland filtering happens correctly on cooked interfaces.
Patch-mainline: libpcap-1.7.2
Git-commit: 84ef791fc980939c795b0b9e33ddfb5ecba9dcf2
References: bsc#874131

If filtering in userland and capturing on a cooked interface, the packet buffer
being sent to bpf_filter_with_aux_data did not include the sll header, so the
filter was being applied improperly.  The buffer would start at the layer3
header.

This change moves the code to fill out the sll structure and update the bp
pointer to point to it to before the call to bpf_filter_with_aux_data.
---
 pcap-linux.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/pcap-linux.c b/pcap-linux.c
index 17bd0f566f43..65513e929c97 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -4205,22 +4205,9 @@ static int pcap_handle_packet_mmap(
 	 * the filter when the ring became empty, but it can possibly
 	 * happen a lot later... */
 	bp = frame + tp_mac;
-	if (handlep->filter_in_userland && handle->fcode.bf_insns &&
-			(bpf_filter(handle->fcode.bf_insns, bp,
-				tp_len, tp_snaplen) == 0))
-		return 0;
-
-	sll = (void *)frame + TPACKET_ALIGN(handlep->tp_hdrlen);
-	if (!linux_check_direction(handle, sll))
-		return 0;
-
-	/* get required packet info from ring header */
-	pcaphdr.ts.tv_sec = tp_sec;
-	pcaphdr.ts.tv_usec = tp_usec;
-	pcaphdr.caplen = tp_snaplen;
-	pcaphdr.len = tp_len;
 
 	/* if required build in place the sll header*/
+	sll = (void *)frame + TPACKET_ALIGN(handlep->tp_hdrlen);
 	if (handlep->cooked) {
 		struct sll_header *hdrp;
 
@@ -4233,7 +4220,7 @@ static int pcap_handle_packet_mmap(
 		 */
 		bp -= SLL_HDR_LEN;
 
-		/*/*
+		/*
 		 * Let's make sure that's past the end of
 		 * the tpacket header, i.e. >=
 		 * ((u_char *)thdr + TPACKET_HDRLEN), so we
@@ -4258,7 +4245,24 @@ static int pcap_handle_packet_mmap(
 		hdrp->sll_halen = htons(sll->sll_halen);
 		memcpy(hdrp->sll_addr, sll->sll_addr, SLL_ADDRLEN);
 		hdrp->sll_protocol = sll->sll_protocol;
+	}
 
+	if (handlep->filter_in_userland && handle->fcode.bf_insns &&
+			(bpf_filter(handle->fcode.bf_insns, bp,
+				tp_len, tp_snaplen) == 0))
+		return 0;
+
+	if (!linux_check_direction(handle, sll))
+		return 0;
+
+	/* get required packet info from ring header */
+	pcaphdr.ts.tv_sec = tp_sec;
+	pcaphdr.ts.tv_usec = tp_usec;
+	pcaphdr.caplen = tp_snaplen;
+	pcaphdr.len = tp_len;
+
+	/* if required build in place the sll header*/
+	if (handlep->cooked) {
 		/* update packet len */
 		pcaphdr.caplen += SLL_HDR_LEN;
 		pcaphdr.len += SLL_HDR_LEN;
-- 
2.5.0