File libpcap-use-tpid.patch of Package libpcap
From: Atzm Watanabe <atzm@atzm.org>
Date: Tue, 25 Mar 2014 19:04:25 +0900
Subject: pcap-linux: Obtain VLAN TPID from the kernel when available
Patch-mainline: libpcap-1.7.2
Git-commit: 235734c4eb94a8dffd6fe7ca6c0c18e04fb390c1
References: bsc#874131
The VLAN TPID was hardcoded in pcap-linux.c but recent Linux kernel
supports 802.1ad Q-in-Q.
Since Linux 3.14, kernel gives the TPID value to the userspace when
available.
---
pcap-linux.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/pcap-linux.c b/pcap-linux.c
index 65513e929c97..434cda0eb992 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -1658,7 +1658,12 @@ 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);
+#if defined(TP_STATUS_VLAN_TPID_VALID)
+ if (aux->tp_vlan_tpid || (aux->tp_status & TP_STATUS_VLAN_TPID_VALID))
+ tag->vlan_tpid = htons(aux->tp_vlan_tpid);
+ else
+#endif
+ tag->vlan_tpid = htons(ETH_P_8021Q);
tag->vlan_tci = htons(aux->tp_vlan_tci);
packet_len += VLAN_TAG_LEN;
@@ -4179,7 +4184,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;
@@ -4279,7 +4285,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;
@@ -4339,6 +4345,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++;
@@ -4417,7 +4424,12 @@ 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,
+#if defined(TP_STATUS_VLAN_TPID_VALID)
+ (h.h2->tp_vlan_tpid || (h.h2->tp_status & TP_STATUS_VLAN_TPID_VALID)) ? h.h2->tp_vlan_tpid : ETH_P_8021Q);
+#else
+ ETH_P_8021Q);
+#endif
if (ret == 1) {
pkts++;
handlep->packets_read++;
@@ -4512,7 +4524,12 @@ 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,
+#if defined(TP_STATUS_VLAN_TPID_VALID)
+ (tp3_hdr->hv1.tp_vlan_tpid || (tp3_hdr->tp_status & TP_STATUS_VLAN_TPID_VALID)) ? tp3_hdr->hv1.tp_vlan_tpid : ETH_P_8021Q);
+#else
+ ETH_P_8021Q);
+#endif
if (ret == 1) {
pkts++;
handlep->packets_read++;
--
2.5.0