From 64a0ba3b272dd9ee175e0c6256a6d0cb1733599b Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Wed, 21 Jul 2021 12:01:04 +0200 Subject: udp: Introduce recvmmsg()/sendmmsg(), zero-copy path from socket Packets are received directly onto pre-cooked, static buffers for IPv4 (with partial checksum pre-calculation) and IPv6 frames, with pre-filled Ethernet addresses and, partially, IP headers, and sent out from the same buffers with sendmmsg(), for both passt and pasta (non-local traffic only) modes. Signed-off-by: Stefano Brivio --- pcap.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) (limited to 'pcap.c') diff --git a/pcap.c b/pcap.c index c728b8a..90529ec 100644 --- a/pcap.c +++ b/pcap.c @@ -12,10 +12,12 @@ * Author: Stefano Brivio */ +#define _GNU_SOURCE #include #include #include #include +#include #include #include #include @@ -90,6 +92,65 @@ void pcap(char *pkt, size_t len) write(pcap_fd, pkt, len); } +/** + * pcapm() - Capture multiple frames from message header to pcap file + * @mh: Pointer to sendmsg() message header buffer + */ +void pcapm(struct msghdr *mh) +{ + struct pcap_pkthdr h; + struct timeval tv; + unsigned int i; + + if (pcap_fd == -1) + return; + + gettimeofday(&tv, NULL); + h.tv_sec = tv.tv_sec; + h.tv_usec = tv.tv_usec; + + for (i = 0; i < mh->msg_iovlen; i++) { + struct iovec *iov = &mh->msg_iov[i]; + + h.caplen = h.len = iov->iov_len - 4; + write(pcap_fd, &h, sizeof(h)); + + write(pcap_fd, (char *)iov->iov_base + 4, iov->iov_len - 4); + } +} + +/** + * pcapm() - Capture multiple frames from multiple message headers to pcap file + * @mmh: Pointer to first sendmmsg() header + */ +void pcapmm(struct mmsghdr *mmh, unsigned int vlen) +{ + struct pcap_pkthdr h; + struct timeval tv; + unsigned int i, j; + + if (pcap_fd == -1) + return; + + gettimeofday(&tv, NULL); + h.tv_sec = tv.tv_sec; + h.tv_usec = tv.tv_usec; + + for (i = 0; i < vlen; i++) { + struct msghdr *mh = &mmh[i].msg_hdr; + + for (j = 0; j < mh->msg_iovlen; j++) { + struct iovec *iov = &mh->msg_iov[j]; + + h.caplen = h.len = iov->iov_len - 4; + write(pcap_fd, &h, sizeof(h)); + + write(pcap_fd, (char *)iov->iov_base + 4, + iov->iov_len - 4); + } + } +} + /** * pcap_init() - Initialise pcap file * @c: Execution context @@ -129,10 +190,27 @@ void pcap_init(struct ctx *c, int index) } #else /* DEBUG */ -void pcap(char *pkt, size_t len) { +void pcap(char *pkt, size_t len) +{ (void)pkt; (void)len; } -void pcap_init(void) { } +void pcapm(struct msghdr *mh) +{ + (void)mh; +} + +void pcapmm(struct mmsghdr *mmh, unsigned int vlen) +{ + (void)mmh; + (void)vlen; +} + +void pcap_init(struct ctx *c, int sock_index) +{ + (void)c; + (void)sock_index; + +} #endif -- cgit v1.2.3