diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f53f13 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libpcap-1.5.3.tar.gz diff --git a/.libpcap.metadata b/.libpcap.metadata new file mode 100644 index 0000000..fa998b7 --- /dev/null +++ b/.libpcap.metadata @@ -0,0 +1 @@ +0d1502d1e46f088f5432d9d16e7fc2619cc33380 SOURCES/libpcap-1.5.3.tar.gz diff --git a/SOURCES/0001-Add-names-for-DLT_NETLINK.patch b/SOURCES/0001-Add-names-for-DLT_NETLINK.patch new file mode 100644 index 0000000..56d29e4 --- /dev/null +++ b/SOURCES/0001-Add-names-for-DLT_NETLINK.patch @@ -0,0 +1,29 @@ +From 2048727a901ef7d9d3803c9206730d11b2fd6ebf Mon Sep 17 00:00:00 2001 +From: Jakub Zawadzki +Date: Sat, 7 Dec 2013 23:37:23 +0100 +Subject: [PATCH] Add names for DLT_NETLINK + +Before patch: + tcpdump: listening on nlmon0, link-type 253, capture size 65535 bytes + +After patch: + tcpdump: listening on nlmon0, link-type NETLINK (Linux netlink), capture size 65535 bytes +--- + pcap.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/pcap.c b/pcap.c +index 626938c..faa9762 100644 +--- a/pcap.c ++++ b/pcap.c +@@ -1203,6 +1203,7 @@ static struct dlt_choice dlt_choices[] = { + DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"), + DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"), + DLT_CHOICE(DLT_DBUS, "D-Bus"), ++ DLT_CHOICE(DLT_NETLINK, "Linux netlink"), + DLT_CHOICE_SENTINEL + }; + +-- +2.4.3 + diff --git a/SOURCES/0001-Fix-link-type-for-nlmon.patch b/SOURCES/0001-Fix-link-type-for-nlmon.patch new file mode 100644 index 0000000..98e1b85 --- /dev/null +++ b/SOURCES/0001-Fix-link-type-for-nlmon.patch @@ -0,0 +1,31 @@ +From 674f2e8bd990be129932c5778d951ffee6eaefbd Mon Sep 17 00:00:00 2001 +From: Jakub Zawadzki +Date: Sat, 7 Dec 2013 23:36:47 +0100 +Subject: [PATCH] Fix link-type for nlmon. + +Before patch: + tcpdump: listening on nlmon0, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes + +After patch: + tcpdump: listening on nlmon0, link-type 253, capture size 65535 bytes +--- + pcap-linux.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/pcap-linux.c b/pcap-linux.c +index 8800c96..7c07793 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -3195,7 +3195,8 @@ activate_new(pcap_t *handle) + * same applies to LAPD capture. + */ + if (handle->linktype != DLT_LINUX_IRDA && +- handle->linktype != DLT_LINUX_LAPD) ++ handle->linktype != DLT_LINUX_LAPD && ++ handle->linktype != DLT_NETLINK) + handle->linktype = DLT_LINUX_SLL; + } + +-- +2.4.3 + diff --git a/SOURCES/0001-Handle-using-cooked-mode-for-DLT_NETLINK-in-activate.patch b/SOURCES/0001-Handle-using-cooked-mode-for-DLT_NETLINK-in-activate.patch new file mode 100644 index 0000000..575e30f --- /dev/null +++ b/SOURCES/0001-Handle-using-cooked-mode-for-DLT_NETLINK-in-activate.patch @@ -0,0 +1,58 @@ +From b5d27a8197012ac2b1b52621be2cfe0b5fc2b47e Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Tue, 19 Nov 2013 10:45:42 -0800 +Subject: [PATCH] Handle using cooked mode for DLT_NETLINK in activate_new(). + +That's how we handle it elsewhere; if that can be cleaned up, especially +if we can avoid opening a raw socket in the cooked-mode case, that would +be nice. + +Note this in comments. + +(cherry picked from eeb0348fe8d74800af37759618270fb8bed17443) + +Conflicts: + pcap-linux.c +--- + pcap-linux.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/pcap-linux.c b/pcap-linux.c +index e6343b0..a0e543c 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -2941,7 +2941,9 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) + /* Don't expect IP packet out of this interfaces... */ + handle->linktype = DLT_LINUX_IRDA; + /* We need to save packet direction for IrDA decoding, +- * so let's use "Linux-cooked" mode. Jean II */ ++ * so let's use "Linux-cooked" mode. Jean II ++ * ++ * XXX - this is handled in activate_new(). */ + //handlep->cooked = 1; + break; + +@@ -2982,8 +2984,11 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) + * We need to use cooked mode, so that in sll_protocol we + * pick up the netlink protocol type such as NETLINK_ROUTE, + * NETLINK_GENERIC, NETLINK_FIB_LOOKUP, etc. ++ * ++ * XXX - this is now handled in activate_new() + */ +- handle->cooked = 1; ++ ++ /* handlep->cooked = 1; */ + break; + + default: +@@ -3122,6 +3127,7 @@ activate_new(pcap_t *handle) + handle->linktype == DLT_LINUX_SLL || + handle->linktype == DLT_LINUX_IRDA || + handle->linktype == DLT_LINUX_LAPD || ++ handle->linktype == DLT_NETLINK || + (handle->linktype == DLT_EN10MB && + (strncmp("isdn", device, 4) == 0 || + strncmp("isdY", device, 4) == 0))) { +-- +2.4.3 + diff --git a/SOURCES/0001-Introduce-bpf_filter1-function.patch b/SOURCES/0001-Introduce-bpf_filter1-function.patch new file mode 100644 index 0000000..19783df --- /dev/null +++ b/SOURCES/0001-Introduce-bpf_filter1-function.patch @@ -0,0 +1,180 @@ +From d4306feb76ee9a6d9ecee63b152404bd0db0f97c Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 5 Aug 2014 16:46:19 +0200 +Subject: [PATCH] Introduce bpf_filter1 function + +Function takes additional argument which is a pointer to bpf_aux_data +structure. This newly introduced struct holds auxiliary data provided by caller +to specify additional data needed to implement some BPF extensions while +executing filter in userspace. + +bpf_filter1 currently implements support for two BPF extesions, namely +vlan_tci and vlan_pr. + +(cherry picked from 02e420f820750e970c93068c01ea10d4c16f2b9a) + +Conflicts: + bpf/net/bpf_filter.c +--- + bpf/net/bpf_filter.c | 77 +++++++++++++++++++++++++++++++++++++++++++--------- + pcap/bpf.h | 10 +++++++ + 2 files changed, 74 insertions(+), 13 deletions(-) + +diff --git a/bpf/net/bpf_filter.c b/bpf/net/bpf_filter.c +index 0c4fb00..3409a9b 100644 +--- a/bpf/net/bpf_filter.c ++++ b/bpf/net/bpf_filter.c +@@ -200,6 +200,17 @@ m_xhalf(m, k, err) + } + #endif + ++#ifdef __linux__ ++#include ++#include ++#endif ++ ++enum { ++ BPF_S_ANC_NONE, ++ BPF_S_ANC_VLAN_TAG, ++ BPF_S_ANC_VLAN_TAG_PRESENT, ++}; ++ + /* + * Execute the filter program starting at pc on the packet p + * wirelen is the length of the original packet +@@ -208,11 +219,12 @@ m_xhalf(m, k, err) + * in all other cases, p is a pointer to a buffer and buflen is its size. + */ + u_int +-bpf_filter(pc, p, wirelen, buflen) ++bpf_filter1(pc, p, wirelen, buflen, aux_data) + register const struct bpf_insn *pc; + register const u_char *p; + u_int wirelen; + register u_int buflen; ++ register const struct bpf_aux_data *aux_data; + { + register u_int32 A, X; + register int k; +@@ -288,22 +300,50 @@ bpf_filter(pc, p, wirelen, buflen) + continue; + + case BPF_LD|BPF_B|BPF_ABS: +- k = pc->k; +- if (k >= buflen) { ++ { ++#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT) ++ int code = BPF_S_ANC_NONE; ++#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \ ++ code = BPF_S_ANC_##CODE; \ ++ if (!aux_data) \ ++ return 0; \ ++ break; ++ ++ switch (pc->k) { ++ ANCILLARY(VLAN_TAG); ++ ANCILLARY(VLAN_TAG_PRESENT); ++ default : ++#endif ++ k = pc->k; ++ if (k >= buflen) { + #if defined(KERNEL) || defined(_KERNEL) +- if (m == NULL) +- return 0; +- n = m; +- MINDEX(len, n, k); +- A = mtod(n, u_char *)[k]; +- continue; ++ if (m == NULL) ++ return 0; ++ n = m; ++ MINDEX(len, n, k); ++ A = mtod(n, u_char *)[k]; ++ continue; + #else +- return 0; ++ return 0; ++#endif ++ } ++ A = p[k]; ++#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT) ++ } ++ switch (code) { ++ case BPF_S_ANC_VLAN_TAG: ++ if (aux_data) ++ A = aux_data->vlan_tag; ++ break; ++ ++ case BPF_S_ANC_VLAN_TAG_PRESENT: ++ if (aux_data) ++ A = aux_data->vlan_tag_present; ++ break; ++ } + #endif ++ continue; + } +- A = p[k]; +- continue; +- + case BPF_LD|BPF_W|BPF_LEN: + A = wirelen; + continue; +@@ -532,6 +572,17 @@ bpf_filter(pc, p, wirelen, buflen) + } + } + ++u_int ++bpf_filter(pc, p, wirelen, buflen) ++ register const struct bpf_insn *pc; ++ register const u_char *p; ++ u_int wirelen; ++ register u_int buflen; ++{ ++ return bpf_filter1(pc, p, wirelen, buflen, NULL); ++} ++ ++ + /* + * Return true if the 'fcode' is a valid filter program. + * The constraints are that each jump be forward and to a valid +diff --git a/pcap/bpf.h b/pcap/bpf.h +index 8286ed5..495f326 100644 +--- a/pcap/bpf.h ++++ b/pcap/bpf.h +@@ -70,6 +70,9 @@ + * + * This also provides our own multiple-include protection. + */ ++ ++#include ++ + #if !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) + #define lib_pcap_bpf_h + +@@ -1317,6 +1320,11 @@ struct bpf_insn { + bpf_u_int32 k; + }; + ++struct bpf_aux_data { ++ uint16_t vlan_tag_present; ++ uint16_t vlan_tag; ++}; ++ + /* + * Macros for insn array initializers. + */ +@@ -1326,9 +1334,11 @@ struct bpf_insn { + #if __STDC__ || defined(__cplusplus) + extern int bpf_validate(const struct bpf_insn *, int); + extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); ++extern u_int bpf_filter1(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *); + #else + extern int bpf_validate(); + extern u_int bpf_filter(); ++extern u_int bpf_filter(); + #endif + + /* +-- +2.4.3 + diff --git a/SOURCES/0001-Make-sure-the-userland-filtering-happens-correctly-o.patch b/SOURCES/0001-Make-sure-the-userland-filtering-happens-correctly-o.patch new file mode 100644 index 0000000..4ddb3db --- /dev/null +++ b/SOURCES/0001-Make-sure-the-userland-filtering-happens-correctly-o.patch @@ -0,0 +1,73 @@ +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 + diff --git a/SOURCES/0001-NFLOG-don-t-crash-trying-to-filter-at-link-layer.patch b/SOURCES/0001-NFLOG-don-t-crash-trying-to-filter-at-link-layer.patch new file mode 100644 index 0000000..28ac26f --- /dev/null +++ b/SOURCES/0001-NFLOG-don-t-crash-trying-to-filter-at-link-layer.patch @@ -0,0 +1,41 @@ +From 676cf8a61ed240d0a86d471ef419f45ba35dba80 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko +Date: Thu, 5 Dec 2013 14:54:14 +0400 +Subject: [PATCH] NFLOG: don't crash trying to filter at link layer + +Before: + +@ tcpdump -i nflog icmp +tcpdump: WARNING: SIOCGIFADDR: nflog: No such device +Aborted (core dumped) + +After: + +@ tcpdump -i nflog icmp +tcpdump: WARNING: SIOCGIFADDR: nflog: No such device +tcpdump: NFLOG link-layer type filtering not implemented +--- + gencode.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/gencode.c b/gencode.c +index 7bb07fb..d58ea30 100644 +--- a/gencode.c ++++ b/gencode.c +@@ -3410,6 +3410,13 @@ gen_linktype(proto) + + case DLT_AX25_KISS: + bpf_error("AX.25 link-layer type filtering not implemented"); ++ ++ case DLT_NFLOG: ++ /* Using the fixed-size NFLOG header it is possible to tell only ++ * the address family of the packet, other meaningful data is ++ * either missing or behind TLVs. ++ */ ++ bpf_error("NFLOG link-layer type filtering not implemented"); + } + + /* +-- +1.8.4.2 + diff --git a/SOURCES/0001-bpf-increase-snaplen-if-doing-cooked-mode-userspace-.patch b/SOURCES/0001-bpf-increase-snaplen-if-doing-cooked-mode-userspace-.patch new file mode 100644 index 0000000..bf8365c --- /dev/null +++ b/SOURCES/0001-bpf-increase-snaplen-if-doing-cooked-mode-userspace-.patch @@ -0,0 +1,44 @@ +From 8ce2c17fd359a758b08bd15a33a0deae872c8231 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Mon, 20 Apr 2015 13:47:28 +0200 +Subject: [PATCH] bpf: increase snaplen if doing cooked mode userspace + filtering + +This commit should address the issue when bpf_filter_with_auxdata returned 0 for valid +packets because offset in filter exceeded tp_snaplen as returned by kernel. If +we filter in cooked mode filter offsets are adjusted because sll_header, we +should do the same for snaplen. +--- + pcap-linux.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/pcap-linux.c b/pcap-linux.c +index 95c94df..034bcd3 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -4186,6 +4186,7 @@ static int pcap_handle_packet_mmap( + unsigned char *bp; + struct sockaddr_ll *sll; + struct pcap_pkthdr pcaphdr; ++ unsigned int snaplen = tp_snaplen; + + /* perform sanity check on internal offset. */ + if (tp_mac + tp_snaplen > handle->bufsize) { +@@ -4246,11 +4247,13 @@ 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; ++ ++ snaplen += sizeof(struct sll_header); + } + + if (handlep->filter_in_userland && handle->fcode.bf_insns && + (bpf_filter(handle->fcode.bf_insns, bp, +- tp_len, tp_snaplen) == 0)) ++ tp_len, snaplen) == 0)) + return 0; + + if (!linux_check_direction(handle, sll)) +-- +2.3.4 + diff --git a/SOURCES/0001-bpf-make-sure-sll-header-size-if-accounted-for.patch b/SOURCES/0001-bpf-make-sure-sll-header-size-if-accounted-for.patch new file mode 100644 index 0000000..25a8562 --- /dev/null +++ b/SOURCES/0001-bpf-make-sure-sll-header-size-if-accounted-for.patch @@ -0,0 +1,46 @@ +From 98e98bf9cc6ee76d7861db966708b1e51cc6e014 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 15 Sep 2015 13:30:37 +0200 +Subject: [PATCH] bpf: make sure sll header size if accounted for + +This got reverted when backporting bpf_filter_with_auxdata. + +Related: #1176612 +--- + pcap-linux.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/pcap-linux.c b/pcap-linux.c +index a5b8953..f7f2aae 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -4306,7 +4306,7 @@ static int pcap_handle_packet_mmap( + 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) ++ if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp, tp_len, snaplen, &aux_data) == 0) + return 0; + } + +@@ -4316,7 +4316,7 @@ static int pcap_handle_packet_mmap( + /* get required packet info from ring header */ + pcaphdr.ts.tv_sec = tp_sec; + pcaphdr.ts.tv_usec = tp_usec; +- pcaphdr.caplen = tp_snaplen; ++ pcaphdr.caplen = snaplen; + pcaphdr.len = tp_len; + + /* if required build in place the sll header*/ +@@ -4329,7 +4329,7 @@ static int pcap_handle_packet_mmap( + #if defined(HAVE_TPACKET2) || defined(HAVE_TPACKET3) + if (tp_vlan_tci_valid && + handlep->vlan_offset != -1 && +- tp_snaplen >= (unsigned int) handlep->vlan_offset) ++ snaplen >= (unsigned int) handlep->vlan_offset) + { + struct vlan_tag *tag; + +-- +2.4.3 + diff --git a/SOURCES/0001-linktype-add-netlink-link-dlt-type.patch b/SOURCES/0001-linktype-add-netlink-link-dlt-type.patch new file mode 100644 index 0000000..609cd21 --- /dev/null +++ b/SOURCES/0001-linktype-add-netlink-link-dlt-type.patch @@ -0,0 +1,92 @@ +From 23d2673796e60c7fea6ba218eb084cbd59e7271b Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Mon, 18 Nov 2013 15:39:37 -0800 +Subject: [PATCH] linktype: add netlink link/dlt type + +With Linux 3.11, we have the possibility to debug local netlink traffic +[1] i.e. the workflow looks like this: + +Setup: + modprobe nlmon + ip link add type nlmon + ip link set nlmon0 up + +Capture: + tcpdump -i nlmon0 ... + +Teardown: + ip link set nlmon0 down + ip link del dev nlmon0 + rmmod nlmon + +For pcap interoperability, introduce a common link type for netlink +captures. +--- + pcap-common.c | 7 ++++++- + pcap-linux.c | 13 +++++++++++++ + pcap/bpf.h | 7 ++++++- + 3 files changed, 25 insertions(+), 2 deletions(-) + +diff --git a/pcap-common.c b/pcap-common.c +index 6175a5a..f26d22e 100644 +--- a/pcap-common.c ++++ b/pcap-common.c +@@ -932,7 +932,12 @@ + */ + #define LINKTYPE_WIRESHARK_UPPER_PDU 252 + +-#define LINKTYPE_MATCHING_MAX 252 /* highest value in the "matching" range */ ++/* ++ * Link-layer header type for the netlink protocol (nlmon devices). ++ */ ++#define LINKTYPE_NETLINK 253 ++ ++#define LINKTYPE_MATCHING_MAX 253 /* highest value in the "matching" range */ + + static struct linktype_map { + int dlt; +diff --git a/pcap-linux.c b/pcap-linux.c +index e817382..0651522 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -2972,6 +2972,19 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) + handle->linktype = DLT_IEEE802_15_4_NOFCS; + break; + ++#ifndef ARPHRD_NETLINK ++#define ARPHRD_NETLINK 824 ++#endif ++ case ARPHRD_NETLINK: ++ handle->linktype = DLT_NETLINK; ++ /* ++ * We need to use cooked mode, so that in sll_protocol we ++ * pick up the netlink protocol type such as NETLINK_ROUTE, ++ * NETLINK_GENERIC, NETLINK_FIB_LOOKUP, etc. ++ */ ++ handle->cooked = 1; ++ break; ++ + default: + handle->linktype = -1; + break; +diff --git a/pcap/bpf.h b/pcap/bpf.h +index ad36eb6..8286ed5 100644 +--- a/pcap/bpf.h ++++ b/pcap/bpf.h +@@ -1224,7 +1224,12 @@ struct bpf_program { + */ + #define DLT_WIRESHARK_UPPER_PDU 252 + +-#define DLT_MATCHING_MAX 252 /* highest value in the "matching" range */ ++/* ++ * DLT type for the netlink protocol (nlmon devices). ++ */ ++#define DLT_NETLINK 253 ++ ++#define DLT_MATCHING_MAX 253 /* highest value in the "matching" range */ + + /* + * DLT and savefile link type values are split into a class and +-- +2.4.3 + diff --git a/SOURCES/0002-Use-BPF-extensions-in-compiled-filters.patch b/SOURCES/0002-Use-BPF-extensions-in-compiled-filters.patch new file mode 100644 index 0000000..e419caa --- /dev/null +++ b/SOURCES/0002-Use-BPF-extensions-in-compiled-filters.patch @@ -0,0 +1,236 @@ +From e80ed31b6e3ab778a7e0dd53348f488a91456cfc Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Fri, 31 Oct 2014 15:19:54 +0100 +Subject: [PATCH 2/2] Use BPF extensions in compiled filters + +libpcap will generate BPF filter code which uses BPF extensions if target +platform supports them. Currently supported BPF extensions are vlan_tci and +vlan_pr. + +Also to properly handle such filters when filtering in userspace libpcap now +employs bpf_filter1. + +(cherry picked from 04660eb1e56102e2369473cae2538e4d3d263607) + +Conflicts: + pcap-linux.c +--- + gencode.c | 110 +++++++++++++++++++++++++++++++++++++++++++++-------------- + pcap-linux.c | 23 +++++++++---- + 2 files changed, 102 insertions(+), 31 deletions(-) + +diff --git a/gencode.c b/gencode.c +index d58ea30..2ff725e 100644 +--- a/gencode.c ++++ b/gencode.c +@@ -58,6 +58,7 @@ static const char rcsid[] _U_ = + + #include + #include ++#include + + #endif /* WIN32 */ + +@@ -135,9 +136,9 @@ static pcap_t *bpf_pcap; + + /* Hack for updating VLAN, MPLS, and PPPoE offsets. */ + #ifdef WIN32 +-static u_int orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1; ++static u_int orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1, vlan_stack_depth = (u_int)-1; + #else +-static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U; ++static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U, vlan_stack_depth = -1U; + #endif + + /* XXX */ +@@ -962,6 +963,7 @@ init_linktype(p) + orig_linktype = -1; + orig_nl = -1; + label_stack_depth = 0; ++ vlan_stack_depth = 0; + + reg_off_ll = -1; + reg_off_macpl = -1; +@@ -7861,6 +7863,76 @@ gen_ahostop(eaddr, dir) + /* NOTREACHED */ + } + ++#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) { ++ 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 */ ++ s = new_stmt(BPF_LD|BPF_B|BPF_ABS); ++ s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT; ++ ++ b0 = new_block(JMP(BPF_JEQ)); ++ b0->stmts = s; ++ b0->s.k = 1; ++ ++ if (vlan_num >= 0) { ++ s = new_stmt(BPF_LD|BPF_B|BPF_ABS); ++ s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG; ++ ++ b1 = new_block(JMP(BPF_JEQ)); ++ b1->stmts = s; ++ b1->s.k = (bpf_int32) vlan_num; ++ ++ gen_and(b0,b1); ++ b0 = b1; ++ } ++ ++ return b0; ++} ++#endif ++ ++static struct block * ++gen_vlan_no_bpf_extensions(int vlan_num) { ++ struct block *b0, *b1; ++ ++ /* check for VLAN, including QinQ */ ++ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, ++ (bpf_int32)ETHERTYPE_8021Q); ++ b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, ++ (bpf_int32)ETHERTYPE_8021QINQ); ++ gen_or(b0,b1); ++ b0 = b1; ++ ++ /* If a specific VLAN is requested, check VLAN id */ ++ if (vlan_num >= 0) { ++ b1 = gen_mcmp(OR_MACPL, 0, BPF_H, ++ (bpf_int32)vlan_num, 0x0fff); ++ gen_and(b0, b1); ++ b0 = b1; ++ } ++ ++ off_macpl += 4; ++ off_linktype += 4; ++ ++ return b0; ++} ++ + /* + * support IEEE 802.1Q VLAN trunk over ethernet + */ +@@ -7912,36 +7984,24 @@ gen_vlan(vlan_num) + case DLT_EN10MB: + case DLT_NETANALYZER: + case DLT_NETANALYZER_TRANSPARENT: +- /* check for VLAN, including QinQ */ +- b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, +- (bpf_int32)ETHERTYPE_8021Q); +- b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, +- (bpf_int32)ETHERTYPE_8021QINQ); +- gen_or(b0,b1); +- b0 = b1; +- +- /* If a specific VLAN is requested, check VLAN id */ +- if (vlan_num >= 0) { +- b1 = gen_mcmp(OR_MACPL, 0, BPF_H, +- (bpf_int32)vlan_num, 0x0fff); +- gen_and(b0, b1); +- b0 = b1; +- } +- +- off_macpl += 4; +- off_linktype += 4; +-#if 0 +- off_nl_nosnap += 4; +- off_nl += 4; ++#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 + #endif +- break; +- ++ b0 = gen_vlan_no_bpf_extensions(vlan_num); ++ break; + default: + bpf_error("no VLAN support for data link type %d", + linktype); + /*NOTREACHED*/ + } + ++ vlan_stack_depth++; ++ + return (b0); + } + +diff --git a/pcap-linux.c b/pcap-linux.c +index a0e543c..68e6d05 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -1475,6 +1475,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) + int packet_len, caplen; + struct pcap_pkthdr pcap_header; + ++ struct bpf_aux_data aux_data; + #ifdef HAVE_PF_PACKET_SOCKETS + /* + * If this is a cooked device, leave extra room for a +@@ -1658,6 +1659,11 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) + tag->vlan_tpid = htons(ETH_P_8021Q); + tag->vlan_tci = htons(aux->tp_vlan_tci); + ++ /* store vlan tci to bpf_aux_data struct for userland bpf filter */ ++#if defined(TP_STATUS_VLAN_VALID) ++ aux_data.vlan_tag = htons(aux->tp_vlan_tci) & 0x0fff; ++ aux_data.vlan_tag_present = (aux->tp_status & TP_STATUS_VLAN_VALID); ++#endif + packet_len += VLAN_TAG_LEN; + } + } +@@ -1702,8 +1708,8 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) + + /* Run the packet filter if not using kernel filter */ + if (handlep->filter_in_userland && handle->fcode.bf_insns) { +- if (bpf_filter(handle->fcode.bf_insns, bp, +- packet_len, caplen) == 0) ++ if (bpf_filter1(handle->fcode.bf_insns, bp, ++ packet_len, caplen, &aux_data) == 0) + { + /* rejected by filter */ + return 0; +@@ -4270,10 +4276,15 @@ static int pcap_handle_packet_mmap( + snaplen += sizeof(struct sll_header); + } + +- if (handlep->filter_in_userland && handle->fcode.bf_insns && +- (bpf_filter(handle->fcode.bf_insns, bp, +- tp_len, snaplen) == 0)) +- return 0; ++ 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_filter1(handle->fcode.bf_insns, bp, tp_len, tp_snaplen, &aux_data) == 0) ++ return 0; ++ } + + if (!linux_check_direction(handle, sll)) + return 0; +-- +2.4.3 + diff --git a/SOURCES/0003-More-descriptive-name-for-bpf_filter1.patch b/SOURCES/0003-More-descriptive-name-for-bpf_filter1.patch new file mode 100644 index 0000000..13e264a --- /dev/null +++ b/SOURCES/0003-More-descriptive-name-for-bpf_filter1.patch @@ -0,0 +1,101 @@ +From e58e6b25c82cc2f76f08b291e14f4e81f4ae1364 Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Wed, 5 Nov 2014 11:18:51 -0800 +Subject: [PATCH 3/3] More descriptive name for bpf_filter1(). + +Call it bpf_filter_with_aux_data(), to better indicate what it does. + +Also expand some comments and clean up white space a bit. + +(cherry picked from 20119d41be224cf9ea821155ad0b267f7e40f234) + +Conflicts: + pcap-linux.c +--- + bpf/net/bpf_filter.c | 7 +++++-- + pcap-linux.c | 7 +++---- + pcap/bpf.h | 7 ++++++- + 3 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/bpf/net/bpf_filter.c b/bpf/net/bpf_filter.c +index 3409a9b..307f980 100644 +--- a/bpf/net/bpf_filter.c ++++ b/bpf/net/bpf_filter.c +@@ -215,11 +215,14 @@ enum { + * Execute the filter program starting at pc on the packet p + * wirelen is the length of the original packet + * buflen is the amount of data present ++ * aux_data is auxiliary data, currently used only when interpreting ++ * filters intended for the Linux kernel in cases where the kernel ++ * rejects the filter; it contains VLAN tag information + * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0, + * in all other cases, p is a pointer to a buffer and buflen is its size. + */ + u_int +-bpf_filter1(pc, p, wirelen, buflen, aux_data) ++bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data) + register const struct bpf_insn *pc; + register const u_char *p; + u_int wirelen; +@@ -579,7 +582,7 @@ bpf_filter(pc, p, wirelen, buflen) + u_int wirelen; + register u_int buflen; + { +- return bpf_filter1(pc, p, wirelen, buflen, NULL); ++ return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL); + } + + +diff --git a/pcap-linux.c b/pcap-linux.c +index 68e6d05..a370858 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -1708,9 +1708,8 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) + + /* Run the packet filter if not using kernel filter */ + if (handlep->filter_in_userland && handle->fcode.bf_insns) { +- if (bpf_filter1(handle->fcode.bf_insns, bp, +- packet_len, caplen, &aux_data) == 0) +- { ++ if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp, ++ packet_len, caplen, &aux_data) == 0) { + /* rejected by filter */ + return 0; + } +@@ -4282,7 +4281,7 @@ static int pcap_handle_packet_mmap( + aux_data.vlan_tag = tp_vlan_tci & 0x0fff; + aux_data.vlan_tag_present = tp_vlan_tci_valid; + +- if (bpf_filter1(handle->fcode.bf_insns, bp, tp_len, tp_snaplen, &aux_data) == 0) ++ if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp, tp_len, tp_snaplen, &aux_data) == 0) + return 0; + } + +diff --git a/pcap/bpf.h b/pcap/bpf.h +index 495f326..29efd7e 100644 +--- a/pcap/bpf.h ++++ b/pcap/bpf.h +@@ -1320,6 +1320,11 @@ struct bpf_insn { + bpf_u_int32 k; + }; + ++/* ++ * Auxiliary data, for use when interpreting a filter intended for the ++ * Linux kernel when the kernel rejects the filter (requiring us to ++ * run it in userland). It contains VLAN tag information. ++ */ + struct bpf_aux_data { + uint16_t vlan_tag_present; + uint16_t vlan_tag; +@@ -1334,7 +1339,7 @@ struct bpf_aux_data { + #if __STDC__ || defined(__cplusplus) + extern int bpf_validate(const struct bpf_insn *, int); + extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); +-extern u_int bpf_filter1(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *); ++extern u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *); + #else + extern int bpf_validate(); + extern u_int bpf_filter(); +-- +2.4.3 + diff --git a/SOURCES/0004-Get-rid-of-unused-variable.patch b/SOURCES/0004-Get-rid-of-unused-variable.patch new file mode 100644 index 0000000..3112a40 --- /dev/null +++ b/SOURCES/0004-Get-rid-of-unused-variable.patch @@ -0,0 +1,37 @@ +From 98ab67580f4cdcede021f6f5a2d9d50bb86bff55 Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Wed, 5 Nov 2014 11:19:39 -0800 +Subject: [PATCH 4/4] Get rid of unused variable. + +Also clean up white space a bit. + +(cherry picked from 86db77ce320dd9e81e5cc7b93ac9adf26643b140) +--- + gencode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gencode.c b/gencode.c +index 2ff725e..9c1d17b 100644 +--- a/gencode.c ++++ b/gencode.c +@@ -7940,7 +7940,7 @@ struct block * + gen_vlan(vlan_num) + int vlan_num; + { +- struct block *b0, *b1; ++ struct block *b0; + + /* can't check for VLAN-encapsulated packets inside MPLS */ + if (label_stack_depth > 0) +@@ -8012,7 +8012,7 @@ struct block * + gen_mpls(label_num) + int label_num; + { +- struct block *b0,*b1; ++ struct block *b0, *b1; + + /* + * Change the offsets to point to the type and data fields within +-- +2.4.3 + diff --git a/SOURCES/0005-Move-the-socket-ops-out-of-gencode.c.patch b/SOURCES/0005-Move-the-socket-ops-out-of-gencode.c.patch new file mode 100644 index 0000000..685904e --- /dev/null +++ b/SOURCES/0005-Move-the-socket-ops-out-of-gencode.c.patch @@ -0,0 +1,213 @@ +From 06553e55d6ff2b203c4ab1dda2d6fb15c45e2896 Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Wed, 5 Nov 2014 14:33:14 -0800 +Subject: [PATCH 5/5] Move the socket ops out of gencode.c. + +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. + +(cherry picked from 612503bb0801a49a1c6ebe9c82591289b1d2e5c9) + +Conflicts: + pcap-linux.c +--- + gencode.c | 37 ++++++++++++++----------------------- + pcap-int.h | 10 ++++++++++ + pcap-linux.c | 24 ++++++++++++++++++++++++ + pcap.c | 12 ++++++++++++ + savefile.c | 5 +++++ + 5 files changed, 65 insertions(+), 23 deletions(-) + +diff --git a/gencode.c b/gencode.c +index 9c1d17b..6b3772f 100644 +--- a/gencode.c ++++ b/gencode.c +@@ -58,7 +58,6 @@ static const char rcsid[] _U_ = + + #include + #include +-#include + + #endif /* WIN32 */ + +@@ -7864,23 +7863,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 */ +@@ -7908,7 +7895,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 */ +@@ -7985,14 +7973,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 (bpf_pcap->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", +diff --git a/pcap-int.h b/pcap-int.h +index 0c27ec7..c9dbb5f 100644 +--- a/pcap-int.h ++++ b/pcap-int.h +@@ -182,6 +182,11 @@ struct pcap { + pcap_direction_t direction; + + /* ++ * Flags to affect BPF code generation. ++ */ ++ int bpf_codegen_flags; ++ ++ /* + * Placeholder for filter code if bpf not in kernel. + */ + struct bpf_program fcode; +@@ -228,6 +233,11 @@ struct pcap { + }; + + /* ++ * 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 + * `struct timeval'; `struct timeval' has 32-bit tv_sec values on some +diff --git a/pcap-linux.c b/pcap-linux.c +index a370858..a82f4eb 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -3024,6 +3024,10 @@ activate_new(pcap_t *handle) + #endif + int err = 0; + struct packet_mreq mr; ++#ifdef SO_BPF_EXTENSIONS ++ int bpf_extensions; ++ socklen_t len; ++#endif + + /* + * Open a socket with protocol family packet. If the +@@ -3342,6 +3346,26 @@ activate_new(pcap_t *handle) + /* Save the socket FD in the pcap structure */ + 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?) ++ */ ++ len = sizeof(bpf_extensions); ++ ++ 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 */ ++ ++ ++ + #if defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS) + if (handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) { + int nsec_tstamps = 1; +diff --git a/pcap.c b/pcap.c +index 6b16cea..74dc708 100644 +--- a/pcap.c ++++ b/pcap.c +@@ -558,6 +558,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); + } + +@@ -1810,6 +1816,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); + } +diff --git a/savefile.c b/savefile.c +index 73e3ea9..98f9c82 100644 +--- a/savefile.c ++++ b/savefile.c +@@ -349,6 +349,11 @@ found: + */ + p->oneshot_callback = pcap_oneshot; + ++ /* ++ * Savefiles never require special BPF code generation. ++ */ ++ p->bpf_codegen_flags = 0; ++ + p->activated = 1; + + return (p); +-- +2.4.3 + diff --git a/SOURCES/0006-Bound-tpacketv2-to-64k.patch b/SOURCES/0006-Bound-tpacketv2-to-64k.patch new file mode 100644 index 0000000..10f7614 --- /dev/null +++ b/SOURCES/0006-Bound-tpacketv2-to-64k.patch @@ -0,0 +1,67 @@ +From d8aade59b5787f5d3517fededcd684fe85367afa Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Mon, 29 May 2017 11:54:43 +0200 +Subject: [PATCH] Backport patch to bound tpacketv2 to 64k + +--- + pcap-linux.c | 29 ++++++++++++++++++----------- + 1 file changed, 18 insertions(+), 11 deletions(-) + +diff --git a/pcap-linux.c b/pcap-linux.c +index f7f2aae..d7149d5 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -3600,6 +3600,8 @@ prepare_tpacket_socket(pcap_t *handle) + return 1; + } + ++#define MAX(a,b) ((a)>(b)?(a):(b)) ++ + /* + * Attempt to set up memory-mapped access. + * +@@ -3674,25 +3676,30 @@ create_ring(pcap_t *handle, int *status) + * "packets" bigger than the MTU. */ + frame_size = handle->snapshot; + if (handle->linktype == DLT_EN10MB) { ++ unsigned int max_frame_len; + int mtu; + int offload; + ++ mtu = iface_get_mtu(handle->fd, handle->opt.source, ++ handle->errbuf); ++ if (mtu == -1) { ++ *status = PCAP_ERROR; ++ return -1; ++ } + offload = iface_get_offload(handle); + if (offload == -1) { + *status = PCAP_ERROR; + return -1; + } +- if (!offload) { +- mtu = iface_get_mtu(handle->fd, handle->opt.source, +- handle->errbuf); +- if (mtu == -1) { +- *status = PCAP_ERROR; +- return -1; +- } +- if (frame_size > mtu + 18) +- frame_size = mtu + 18; +- } +- } ++ if (offload) ++ max_frame_len = MAX(mtu, 65535); ++ else ++ max_frame_len = mtu; ++ max_frame_len += 18; ++ ++ if (frame_size > max_frame_len) ++ frame_size = max_frame_len; ++ } + + /* NOTE: calculus matching those in tpacket_rcv() + * in linux-2.6/net/packet/af_packet.c +-- +2.13.0 + diff --git a/SOURCES/0007-Add-support-for-AF_VSOCK.patch b/SOURCES/0007-Add-support-for-AF_VSOCK.patch new file mode 100644 index 0000000..a742f10 --- /dev/null +++ b/SOURCES/0007-Add-support-for-AF_VSOCK.patch @@ -0,0 +1,67 @@ +From 59a65c3d24289661dc444e3c303fbd880de5b6e0 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 15 Aug 2017 09:59:02 +0200 +Subject: [PATCH] Add support for AF_VSOCK + +Backported from here: +https://github.com/the-tcpdump-group/libpcap/commit/8fe43bb140f1b5dd193a76b89e379a27847a9391 +and extended with DLT_VSOCK definition from upstream pcap/dlt.h file. +--- + pcap-linux.c | 6 ++++++ + pcap.c | 1 + + pcap/bpf.h | 10 +++++++++- + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/pcap-linux.c b/pcap-linux.c +index d7149d5..0bfc77a 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -2995,6 +2995,12 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) + + /* handlep->cooked = 1; */ + break; ++#ifndef ARPHRD_VSOCKMON ++#define ARPHRD_VSOCKMON 826 ++#endif ++ case ARPHRD_VSOCKMON: ++ handle->linktype = DLT_VSOCK; ++ break; + + default: + handle->linktype = -1; +diff --git a/pcap.c b/pcap.c +index 7b834af..ce5ade8 100644 +--- a/pcap.c ++++ b/pcap.c +@@ -1210,6 +1210,7 @@ static struct dlt_choice dlt_choices[] = { + DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"), + DLT_CHOICE(DLT_DBUS, "D-Bus"), + DLT_CHOICE(DLT_NETLINK, "Linux netlink"), ++ DLT_CHOICE(DLT_VSOCK, "Linux vsock"), + DLT_CHOICE_SENTINEL + }; + +diff --git a/pcap/bpf.h b/pcap/bpf.h +index 29efd7e..22bff1e 100644 +--- a/pcap/bpf.h ++++ b/pcap/bpf.h +@@ -1232,7 +1232,15 @@ struct bpf_program { + */ + #define DLT_NETLINK 253 + +-#define DLT_MATCHING_MAX 253 /* highest value in the "matching" range */ ++#define DLT_MATCHING_MAX 271 /* highest value in the "matching" range */ ++ ++/* ++ * per: Stefanha at gmail.com for ++ * http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html ++ * and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h ++ * for: http://qemu-project.org/Features/VirtioVsock ++ */ ++#define DLT_VSOCK 271 + + /* + * DLT and savefile link type values are split into a class and +-- +2.13.5 + diff --git a/SOURCES/0008-Vlan-tpid-handling.patch b/SOURCES/0008-Vlan-tpid-handling.patch new file mode 100644 index 0000000..e06877a --- /dev/null +++ b/SOURCES/0008-Vlan-tpid-handling.patch @@ -0,0 +1,73 @@ +diff --git a/pcap-linux.c b/pcap-linux.c +index 0bfc77a..8cf531b 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -368,6 +368,12 @@ static void pcap_oneshot_mmap(u_char *user, const struct pcap_pkthdr *h, + const u_char *bytes); + #endif + ++#ifdef TP_STATUS_VLAN_TPID_VALID ++#define VLAN_TPID(hdr, hv) (((hv)->tp_vlan_tpid || ((hdr)->tp_status & TP_STATUS_VLAN_TPID_VALID)) ? (hv)->tp_vlan_tpid : ETH_P_8021Q) ++#else ++#define VLAN_TPID(hdr, hv) ETH_P_8021Q ++#endif ++ + /* + * Wrap some ioctl calls + */ +@@ -1656,7 +1662,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) + memmove(bp, bp + VLAN_TAG_LEN, handlep->vlan_offset); + + tag = (struct vlan_tag *)(bp + handlep->vlan_offset); +- tag->vlan_tpid = htons(ETH_P_8021Q); ++ tag->vlan_tpid = htons(VLAN_TPID(aux, aux)); + tag->vlan_tci = htons(aux->tp_vlan_tci); + + /* store vlan tci to bpf_aux_data struct for userland bpf filter */ +@@ -4242,7 +4248,8 @@ static int pcap_handle_packet_mmap( + unsigned int tp_sec, + unsigned int tp_usec, + int tp_vlan_tci_valid, +- __u16 tp_vlan_tci) ++ __u16 tp_vlan_tci, ++ __u16 tp_vlan_tpid) + { + struct pcap_linux *handlep = handle->priv; + unsigned char *bp; +@@ -4350,7 +4357,7 @@ static int pcap_handle_packet_mmap( + memmove(bp, bp + VLAN_TAG_LEN, handlep->vlan_offset); + + tag = (struct vlan_tag *)(bp + handlep->vlan_offset); +- tag->vlan_tpid = htons(ETH_P_8021Q); ++ tag->vlan_tpid = htons(tp_vlan_tpid); + tag->vlan_tci = htons(tp_vlan_tci); + + pcaphdr.caplen += VLAN_TAG_LEN; +@@ -4410,6 +4417,7 @@ pcap_read_linux_mmap_v1(pcap_t *handle, int max_packets, pcap_handler callback, + h.h1->tp_sec, + h.h1->tp_usec, + 0, ++ 0, + 0); + if (ret == 1) { + pkts++; +@@ -4488,7 +4496,8 @@ pcap_read_linux_mmap_v2(pcap_t *handle, int max_packets, pcap_handler callback, + #else + h.h2->tp_vlan_tci != 0, + #endif +- h.h2->tp_vlan_tci); ++ h.h2->tp_vlan_tci, ++ VLAN_TPID(h.h2, h.h2)); + if (ret == 1) { + pkts++; + handlep->packets_read++; +@@ -4583,7 +4592,8 @@ pcap_read_linux_mmap_v3(pcap_t *handle, int max_packets, pcap_handler callback, + #else + tp3_hdr->hv1.tp_vlan_tci != 0, + #endif +- tp3_hdr->hv1.tp_vlan_tci); ++ tp3_hdr->hv1.tp_vlan_tci, ++ VLAN_TPID(tp3_hdr, &tp3_hdr->hv1)); + if (ret == 1) { + pkts++; + handlep->packets_read++; diff --git a/SOURCES/libpcap-man.patch b/SOURCES/libpcap-man.patch new file mode 100644 index 0000000..e37afbc --- /dev/null +++ b/SOURCES/libpcap-man.patch @@ -0,0 +1,12 @@ +diff -up libpcap/pcap.3pcap.in.man libpcap/pcap.3pcap.in +--- libpcap/pcap.3pcap.in.man 2009-07-03 06:01:12.000000000 +0200 ++++ libpcap/pcap.3pcap.in 2009-07-03 15:00:12.000000000 +0200 +@@ -363,7 +363,7 @@ use an + script or some other configuration script to check whether the libpcap + 1.0 APIs are available and use them only if they are. + .SH SEE ALSO +-autoconf(1), tcpdump(1), tcpslice(1), pcap-filter(@MAN_MISC_INFO@), pfconfig(8), ++autoconf(1), tcpdump(8), tcpslice(8), pcap-filter(@MAN_MISC_INFO@), pfconfig(8), + usermod(1M) + .SH AUTHORS + The original authors of libpcap are: diff --git a/SOURCES/libpcap-multilib.patch b/SOURCES/libpcap-multilib.patch new file mode 100644 index 0000000..e359736 --- /dev/null +++ b/SOURCES/libpcap-multilib.patch @@ -0,0 +1,69 @@ +diff -up libpcap-1.3.0/pcap-config.in.multilib libpcap-1.3.0/pcap-config.in +--- libpcap-1.3.0/pcap-config.in.multilib 2012-03-29 14:57:32.000000000 +0200 ++++ libpcap-1.3.0/pcap-config.in 2013-03-26 09:56:16.293324264 +0100 +@@ -7,7 +7,6 @@ + prefix="@prefix@" + exec_prefix="@exec_prefix@" + includedir="@includedir@" +-libdir="@libdir@" + V_RPATH_OPT="@V_RPATH_OPT@" + LIBS="@LIBS@" + +@@ -36,16 +35,6 @@ do + esac + shift + done +-if [ "$V_RPATH_OPT" != "" ] +-then +- # +- # If libdir isn't /usr/lib, add it to the run-time linker path. +- # +- if [ "$libdir" != "/usr/lib" ] +- then +- RPATH=$V_RPATH_OPT$libdir +- fi +-fi + if [ "$static" = 1 ] + then + # +@@ -54,16 +43,16 @@ then + # + if [ "$show_cflags" = 1 -a "$show_libs" = 1 ] + then +- echo "-I$includedir -L$libdir -lpcap $LIBS" ++ echo "-lpcap @LIBS@" + elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ] + then +- echo "-I$includedir -L$libdir $LIBS" ++ echo "@LIBS@" + elif [ "$show_cflags" = 1 ] + then +- echo "-I$includedir" ++ echo "" + elif [ "$show_libs" = 1 ] + then +- echo "-L$libdir -lpcap $LIBS" ++ echo "-lpcap @LIBS@" + elif [ "$show_additional_libs" = 1 ] + then + echo "$LIBS" +@@ -75,15 +64,15 @@ else + # + if [ "$show_cflags" = 1 -a "$show_libs" = 1 ] + then +- echo "-I$includedir -L$libdir $RPATH -lpcap" ++ echo "-lpcap" + elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ] + then +- echo "-I$includedir" ++ echo "" + elif [ "$show_cflags" = 1 ] + then +- echo "-I$includedir" ++ echo "" + elif [ "$show_libs" = 1 ] + then +- echo "-L$libdir $RPATH -lpcap" ++ echo "-lpcap" + fi + fi diff --git a/SOURCES/libpcap-s390.patch b/SOURCES/libpcap-s390.patch new file mode 100644 index 0000000..ee7c003 --- /dev/null +++ b/SOURCES/libpcap-s390.patch @@ -0,0 +1,14 @@ +diff -up libpcap-1.5.0/pcap-linux.c.s390 libpcap-1.5.0/pcap-linux.c +--- libpcap-1.5.0/pcap-linux.c.s390 2013-11-08 08:05:02.608387300 +0100 ++++ libpcap-1.5.0/pcap-linux.c 2013-11-08 08:08:49.597405024 +0100 +@@ -3181,6 +3181,10 @@ activate_new(pcap_t *handle) + handle->linktype = DLT_LINUX_SLL; + } + ++ /* Hack to make things work on s390 ctc interfaces */ ++ if (strncmp("ctc", device, 3) == 0) ++ handle->linktype = DLT_EN10MB; ++ + handlep->ifindex = iface_get_id(sock_fd, device, + handle->errbuf); + if (handlep->ifindex == -1) { diff --git a/SPECS/libpcap.spec b/SPECS/libpcap.spec new file mode 100644 index 0000000..7867da5 --- /dev/null +++ b/SPECS/libpcap.spec @@ -0,0 +1,229 @@ +Name: libpcap +Epoch: 14 +Version: 1.5.3 +Release: 12%{?dist} +Summary: A system-independent interface for user-level packet capture +Group: Development/Libraries +License: BSD with advertising +URL: http://www.tcpdump.org +BuildRequires: glibc-kernheaders >= 2.2.0 bison flex bluez-libs-devel git + +Source: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz +Patch1: libpcap-man.patch +Patch2: libpcap-multilib.patch +Patch3: libpcap-s390.patch +Patch4: 0001-NFLOG-don-t-crash-trying-to-filter-at-link-layer.patch +Patch6: 0001-Make-sure-the-userland-filtering-happens-correctly-o.patch +Patch7: 0001-bpf-increase-snaplen-if-doing-cooked-mode-userspace-.patch +Patch8: 0001-linktype-add-netlink-link-dlt-type.patch +Patch9: 0001-Handle-using-cooked-mode-for-DLT_NETLINK-in-activate.patch +Patch10: 0001-Introduce-bpf_filter1-function.patch +Patch11: 0002-Use-BPF-extensions-in-compiled-filters.patch +Patch12: 0003-More-descriptive-name-for-bpf_filter1.patch +Patch13: 0004-Get-rid-of-unused-variable.patch +Patch14: 0005-Move-the-socket-ops-out-of-gencode.c.patch +Patch15: 0001-Add-names-for-DLT_NETLINK.patch +Patch16: 0001-Fix-link-type-for-nlmon.patch +Patch17: 0001-bpf-make-sure-sll-header-size-if-accounted-for.patch +Patch18: 0006-Bound-tpacketv2-to-64k.patch +Patch19: 0007-Add-support-for-AF_VSOCK.patch +Patch20: 0008-Vlan-tpid-handling.patch + + +%description +Libpcap provides a portable framework for low-level network +monitoring. Libpcap can provide network statistics collection, +security monitoring and network debugging. Since almost every system +vendor provides a different interface for packet capture, the libpcap +authors created this system-independent API to ease in porting and to +alleviate the need for several system-dependent packet capture modules +in each application. + +Install libpcap if you need to do low-level network traffic monitoring +on your network. + +%package devel +Summary: Libraries and header files for the libpcap library +Group: Development/Libraries +Requires: %{name} = %{epoch}:%{version}-%{release} + +%description devel +Libpcap provides a portable framework for low-level network +monitoring. Libpcap can provide network statistics collection, +security monitoring and network debugging. Since almost every system +vendor provides a different interface for packet capture, the libpcap +authors created this system-independent API to ease in porting and to +alleviate the need for several system-dependent packet capture modules +in each application. + +This package provides the libraries, include files, and other +resources needed for developing libpcap applications. + +%prep +%autosetup -S git + +#sparc needs -fPIC +%ifarch %{sparc} +sed -i -e 's|-fpic|-fPIC|g' configure +%endif + +%build +export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" +%configure +make %{?_smp_mflags} + +%install +make DESTDIR=$RPM_BUILD_ROOT install +rm -f $RPM_BUILD_ROOT%{_libdir}/libpcap.a + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%doc LICENSE README CHANGES CREDITS +%{_libdir}/libpcap.so.* +%{_mandir}/man7/pcap*.7* + +%files devel +%defattr(-,root,root) +%{_bindir}/pcap-config +%{_includedir}/pcap*.h +%{_includedir}/pcap +%{_libdir}/libpcap.so +%{_mandir}/man1/pcap-config.1* +%{_mandir}/man3/pcap*.3* +%{_mandir}/man5/pcap*.5* + +%changelog +* Wed Jul 24 2019 Michal Ruprich - 14:1.5.3-12 +- Resolves: #1596834 - Re-enable TPACKET_V3 to fix silent packet drops + +* Tue Oct 17 2017 Michal Ruprich - 14:1.5.3-11 +- Resolves: #1427251 - tcpdump incorrectly shows 0x8100 tag for 802.1ad frames + +* Tue Aug 15 2017 Martin Sehnoutka - 14:1.5.3-10 +- Add support for AF_VSOCK + +* Mon May 29 2017 Martin Sehnoutka - 14:1.5.3-9 +- Bound packet size to 64k + +* Tue Sep 15 2015 Michal Sekletar - 14:1.5.3-8 +- make sure that sll header size is accounted for (#1176612) + +* Wed Jul 08 2015 Michal Sekletar - 14:1.5.3-7 +- make sure that netlink monitor interfaces are also properly recognized by tcpdump (#1031974) + +* Tue Jun 16 2015 Michal Sekletar - 14:1.5.3-6 +- libpcap now correctly recognizes Netlink datalink type (#1031974) +- fix vlan tagged packet filtering (#1079525) + +* Tue Mar 31 2015 Michal Sekletar - 14:1.5.3-5 +- display also first packet when capturing in cooked mode (#1176612) +- make sure that userland bpf filter interpreter is given snaplen such that size of + cooked header is account for + +* Tue Dec 2 2014 Michal Sekletar - 14:1.5.3-4 +- disable TPACKET_V3 memory mapped packet capture on AF_PACKET socket, use TPACKET_V2 instead (#1085096) + +* Thu Feb 13 2014 Michal Sekletar - 14:1.5.3-3 +- don't crash when trying to filter on interface with NFLOG link layer type (#1062511) + +* Fri Jan 24 2014 Daniel Mach - 14:1.5.3-2 +- Mass rebuild 2014-01-24 + +* Wed Jan 15 2014 Michal Sekletar - 14:1.5.3-1 +- update to 1.5.3 + +* Fri Dec 27 2013 Daniel Mach - 14:1.5.0-2.20131108git459712e +- Mass rebuild 2013-12-27 + +* Fri Nov 08 2013 Michal Sekletar - 14:1.5.0-1.20131108git459712e +- update to snapshot 20131108git459712e (#1026856) + +* Thu Jun 06 2013 Michal Sekletar - 14:1.4.0-1 +- update to 1.4.0 + +* Tue Mar 26 2013 Michal Sekletar - 14:1.3.0-4 +- remove unused variable from pcap-config to prevent multilib conflicts +- specfile cleanup + +* Thu Feb 14 2013 Fedora Release Engineering - 14:1.3.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Jul 19 2012 Fedora Release Engineering - 14:1.3.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed Jun 13 2012 Michal Sekletar 14:1.3.0-1 +- Update to 1.3.0 + +* Thu Jan 05 2012 Jan Synáček 14:1.2.1-2 +- Rebuilt for GCC 4.7 + +* Tue Jan 03 2012 Jan Synáček 14:1.2.1-1 +- Update to 1.2.1 +- Drop unnecessary -fragment patch + +* Fri Dec 02 2011 Michal Sekletar 14:1.2.0-1 +- update to 1.2.0 + +* Tue Sep 06 2011 Michal Sekletar 14:1.1.1-4 +- fix capture of fragmented ipv6 packets + +* Fri Apr 22 2011 Miroslav Lichvar 14:1.1.1-3 +- ignore /sys/net/dev files on ENODEV (#693943) +- drop ppp patch +- compile with -fno-strict-aliasing + +* Tue Feb 08 2011 Fedora Release Engineering - 14:1.1.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Apr 06 2010 Miroslav Lichvar 14:1.1.1-1 +- update to 1.1.1 + +* Wed Dec 16 2009 Miroslav Lichvar 14:1.0.0-5.20091201git117cb5 +- update to snapshot 20091201git117cb5 + +* Sat Oct 17 2009 Dennis Gilmore 14:1.0.0-4.20090922gite154e2 +- use -fPIC on sparc arches + +* Wed Sep 23 2009 Miroslav Lichvar 14:1.0.0-3.20090922gite154e2 +- update to snapshot 20090922gite154e2 +- drop old soname + +* Fri Jul 24 2009 Fedora Release Engineering - 14:1.0.0-2.20090716git6de2de +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jul 22 2009 Miroslav Lichvar 14:1.0.0-1.20090716git6de2de +- update to 1.0.0, git snapshot 20090716git6de2de + +* Wed Feb 25 2009 Fedora Release Engineering - 14:0.9.8-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Jun 27 2008 Miroslav Lichvar 14:0.9.8-3 +- use CFLAGS when linking (#445682) + +* Tue Feb 19 2008 Fedora Release Engineering - 14:0.9.8-2 +- Autorebuild for GCC 4.3 + +* Wed Oct 24 2007 Miroslav Lichvar 14:0.9.8-1 +- update to 0.9.8 + +* Wed Aug 22 2007 Miroslav Lichvar 14:0.9.7-3 +- update license tag + +* Wed Jul 25 2007 Jesse Keating - 14:0.9.7-2 +- Rebuild for RH #249435 + +* Tue Jul 24 2007 Miroslav Lichvar 14:0.9.7-1 +- update to 0.9.7 + +* Tue Jun 19 2007 Miroslav Lichvar 14:0.9.6-1 +- update to 0.9.6 + +* Tue Nov 28 2006 Miroslav Lichvar 14:0.9.5-1 +- split from tcpdump package (#193657) +- update to 0.9.5 +- don't package static library +- maintain soname