From fe0d58905f9934bfc04a1aaf9393997c2bdbfb6c Mon Sep 17 00:00:00 2001 From: rpm-build Date: Fri, 27 Mar 2015 12:21:56 +0100 Subject: [PATCH] Make sure the userland filtering happens correctly on cooked interfaces 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 | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/pcap-linux.c b/pcap-linux.c index 117405b..95c94df 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -4206,22 +4206,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; @@ -4259,7 +4246,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.3.4