aboutsummaryrefslogtreecommitdiff
path: root/pcap-linux.c
diff options
context:
space:
mode:
authorTommy Beadle <tbeadle@arbor.net>2015-02-10 13:49:45 -0500
committerTommy Beadle <tbeadle@arbor.net>2015-02-10 13:49:45 -0500
commit84ef791fc980939c795b0b9e33ddfb5ecba9dcf2 (patch)
treee9a20e7505b4641f698d2a32412457f41ba0af5e /pcap-linux.c
parent8f7159ef6a54021d7decf0f5c437f628d7d68327 (diff)
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.
Diffstat (limited to 'pcap-linux.c')
-rw-r--r--pcap-linux.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/pcap-linux.c b/pcap-linux.c
index 99d76218..379e3338 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -4257,28 +4257,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) {
- struct bpf_aux_data aux_data;
-
- aux_data.vlan_tag = tp_vlan_tci & 0x0fff;
- aux_data.vlan_tag_present = tp_vlan_tci_valid;
-
- if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp,
- tp_len, tp_snaplen, &aux_data) == 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;
@@ -4291,7 +4272,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
@@ -4316,7 +4297,30 @@ 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) {
+ struct bpf_aux_data aux_data;
+
+ aux_data.vlan_tag = tp_vlan_tci & 0x0fff;
+ aux_data.vlan_tag_present = tp_vlan_tci_valid;
+
+ if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp,
+ tp_len, tp_snaplen, &aux_data) == 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;