}
#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- struct tpacket_auxdata *aux;
- unsigned int len;
- struct vlan_tag *tag;
-
- if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
- cmsg->cmsg_level != SOL_PACKET ||
- cmsg->cmsg_type != PACKET_AUXDATA)
- continue;
+ if (handle->md.add_vlan_tags) {
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ struct tpacket_auxdata *aux;
+ unsigned int len;
+ struct vlan_tag *tag;
- aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
- if (aux->tp_vlan_tci == 0)
- continue;
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
+ cmsg->cmsg_level != SOL_PACKET ||
+ cmsg->cmsg_type != PACKET_AUXDATA)
+ continue;
- len = packet_len > iov.iov_len ? iov.iov_len : packet_len;
- if (len < 2 * ETH_ALEN)
- break;
+ aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
+ if (aux->tp_vlan_tci == 0)
+ continue;
- bp -= VLAN_TAG_LEN;
- memmove(bp, bp + VLAN_TAG_LEN, 2 * ETH_ALEN);
+ len = packet_len > iov.iov_len ? iov.iov_len : packet_len;
+ if (len < 2 * ETH_ALEN)
+ break;
+
+ bp -= VLAN_TAG_LEN;
+ memmove(bp, bp + VLAN_TAG_LEN, 2 * ETH_ALEN);
- tag = (struct vlan_tag *)(bp + 2 * ETH_ALEN);
- tag->vlan_tpid = htons(ETH_P_8021Q);
- tag->vlan_tci = htons(aux->tp_vlan_tci);
+ tag = (struct vlan_tag *)(bp + 2 * ETH_ALEN);
+ tag->vlan_tpid = htons(ETH_P_8021Q);
+ tag->vlan_tci = htons(aux->tp_vlan_tci);
- packet_len += VLAN_TAG_LEN;
+ packet_len += VLAN_TAG_LEN;
+ }
}
#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */
#endif /* HAVE_PF_PACKET_SOCKETS */
}
handle->bufsize = handle->snapshot;
+ /*
+ * Only enable the insertion of VLAN tags if the link-layer
+ * header type is Ethernet. If it should be supported on
+ * any other link-layer type, the code that inserts them
+ * must be modified to insert them in the proper place, which
+ * differs from link-layer header type to link-layer header
+ * type.
+ */
+ if (handle->linktype == DLT_EN10MB)
+ handle->md.add_vlan_tags = 1;
+ else
+ handle->md.add_vlan_tags = 0;
+
/* Save the socket FD in the pcap structure */
handle->fd = sock_fd;
handle->getnonblock_op = pcap_getnonblock_mmap;
handle->oneshot_callback = pcap_oneshot_mmap;
handle->selectable_fd = handle->fd;
+
+ /*
+ * We only support inserting VLAN tags for tpacket V2;
+ * if we're using v1, disable it.
+ */
+ if (handle->md.tp_version == TPACKET_V1)
+ handle->md.add_vlan_tags = 0;
+
return 1;
}
#else /* HAVE_PACKET_RING */
}
#ifdef HAVE_TPACKET2
- if (handle->md.tp_version == TPACKET_V2 && h.h2->tp_vlan_tci &&
+ if (handle->md.add_vlan_tags && h.h2->tp_vlan_tci &&
tp_snaplen >= 2 * ETH_ALEN) {
struct vlan_tag *tag;
*/
handle->offset = 0;
+ /*
+ * No support for getting VLAN tags to insert.
+ */
+ handle->md.add_vlan_tags = 0;
+
return 1;
}