pcap_frame() explicitly takes a single frame, and only allows a single buffer (iovec) to be passed. pcap_multiple() takes multiple buffers, but explicitly expects exactly one frame per buffer. Future changes are going to want to split single frames across multiple buffers in some circumstances, so extend the pcap functions to allow for that. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- pcap.c | 26 +++++++++++++++----------- pcap.h | 3 ++- tap.c | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/pcap.c b/pcap.c index 317fc844..dcf1a741 100644 --- a/pcap.c +++ b/pcap.c @@ -31,6 +31,7 @@ #include "util.h" #include "passt.h" #include "log.h" +#include "pcap.h" #define PCAP_VERSION_MINOR 4 @@ -67,14 +68,15 @@ struct pcap_pkthdr { /** * pcap_frame() - Capture a single frame to pcap file with given timestamp - * @iov: IO vector referencing buffer containing frame (with L2 headers) - * @offset: Offset of the frame from @iov->iov_base + * @iov: IO vector containing frame (with L2 headers and tap headers) + * @iovcnt: Number of buffers (@iov entries) in frame + * @offset: Byte offset of the L2 headers within @iov * @tv: Timestamp * * Returns: 0 on success, -errno on error writing to the file */ -static void pcap_frame(const struct iovec *iov, size_t offset, - const struct timeval *tv) +static void pcap_frame(const struct iovec *iov, size_t iovcnt, + size_t offset, const struct timeval *tv) { size_t len = iov->iov_len - offset; struct pcap_pkthdr h = { @@ -86,7 +88,7 @@ static void pcap_frame(const struct iovec *iov, size_t offset, struct iovec hiov = { &h, sizeof(h) }; if (write_remainder(pcap_fd, &hiov, 1, 0) < 0 || - write_remainder(pcap_fd, iov, 1, offset) < 0) + write_remainder(pcap_fd, iov, iovcnt, offset) < 0) debug("Cannot log packet, length %zu: %s", len, strerror(errno)); } @@ -105,16 +107,18 @@ void pcap(const char *pkt, size_t len) return; gettimeofday(&tv, NULL); - pcap_frame(&iov, 0, &tv); + pcap_frame(&iov, 1, 0, &tv); } /** * pcap_multiple() - Capture multiple frames - * @iov: Array of iovecs, one entry per frame - * @n: Number of frames to capture - * @offset: Offset of the frame within each iovec buffer + * @iov: IO vector with @frame_parts * @n entries + * @frame_parts: Number of IO vector items for each frame + * @n: Number of frames to capture + * @offset: Offset of the L2 frame within each iovec buffer */ -void pcap_multiple(const struct iovec *iov, unsigned int n, size_t offset) +void pcap_multiple(const struct iovec *iov, size_t frame_parts, unsigned int n, + size_t offset) { struct timeval tv; unsigned int i; @@ -125,7 +129,7 @@ void pcap_multiple(const struct iovec *iov, unsigned int n, size_t offset) gettimeofday(&tv, NULL); for (i = 0; i < n; i++) - pcap_frame(iov + i, offset, &tv); + pcap_frame(iov + i * frame_parts, frame_parts, offset, &tv); } /** diff --git a/pcap.h b/pcap.h index da5a7e84..85fc58e5 100644 --- a/pcap.h +++ b/pcap.h @@ -7,7 +7,8 @@ #define PCAP_H void pcap(const char *pkt, size_t len); -void pcap_multiple(const struct iovec *iov, unsigned int n, size_t offset); +void pcap_multiple(const struct iovec *iov, size_t frame_parts, unsigned int n, + size_t offset); void pcap_init(struct ctx *c); #endif /* PCAP_H */ diff --git a/tap.c b/tap.c index dd11d1d4..87d176b7 100644 --- a/tap.c +++ b/tap.c @@ -433,7 +433,7 @@ size_t tap_send_frames(const struct ctx *c, const struct iovec *iov, size_t n) if (m < n) debug("tap: failed to send %zu frames of %zu", n - m, n); - pcap_multiple(iov, m, c->mode == MODE_PASST ? sizeof(uint32_t) : 0); + pcap_multiple(iov, 1, n, c->mode == MODE_PASST ? sizeof(uint32_t) : 0); return m; } -- 2.43.2