From 17337a736ff0e7ebd7d5272eba7466a627795215 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Fri, 21 May 2021 11:14:48 +0200 Subject: passt: Introduce packet capture implementation With -DDEBUG, passt now saves guest-side traffic captures in pcap format at /tmp/passt_.pcap. The timestamp refers to time and date of start-up. Signed-off-by: Stefano Brivio --- pcap.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 pcap.c (limited to 'pcap.c') diff --git a/pcap.c b/pcap.c new file mode 100644 index 0000000..2767b53 --- /dev/null +++ b/pcap.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +/* PASST - Plug A Simple Socket Transport + * + * pcap.c - Packet capture for PASST + * + * Copyright (c) 2021 Red Hat GmbH + * Author: Stefano Brivio + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG + +#define PCAP_PREFIX "/tmp/passt_" +#define PCAP_ISO8601_FORMAT "%FT%H:%M:%SZ" +#define PCAP_ISO8601_STR "YYYY-MM-ddTHH:mm:ssZ" + +#define PCAP_VERSION_MINOR 4 + +static int pcap_fd = 1; + +/* See pcap.h from libpcap, or pcap-savefile(5) */ +static struct { + uint32_t magic; +#define PCAP_MAGIC 0xa1b2c3d4 + + uint16_t major; +#define PCAP_VERSION_MAJOR 2 + + uint16_t minor; +#define PCAP_VERSION_MINOR 4 + + int32_t thiszone; + uint32_t sigfigs; + uint32_t snaplen; + + uint32_t linktype; +#define PCAP_LINKTYPE_ETHERNET 1 +} pcap_hdr = { + PCAP_MAGIC, PCAP_VERSION_MAJOR, PCAP_VERSION_MINOR, 0, 0, ETH_MAX_MTU, + PCAP_LINKTYPE_ETHERNET +}; + +struct pcap_pkthdr { + uint32_t tv_sec; + uint32_t tv_usec; + uint32_t caplen; + uint32_t len; +}; + +void pcap(char *pkt, size_t len) +{ + struct pcap_pkthdr h; + struct timeval tv; + + if (pcap_fd == -1) + return; + + gettimeofday(&tv, NULL); + h.tv_sec = tv.tv_sec; + h.tv_usec = tv.tv_usec; + h.caplen = h.len = len; + + write(pcap_fd, &h, sizeof(h)); + write(pcap_fd, pkt, len); +} + +void pcap_init(void) +{ + char name[] = PCAP_PREFIX PCAP_ISO8601_STR ".pcap"; + struct timeval tv; + struct tm *tm; + + gettimeofday(&tv, NULL); + tm = localtime(&tv.tv_sec); + strftime(name + strlen(PCAP_PREFIX), sizeof(PCAP_ISO8601_STR) - 1, + PCAP_ISO8601_FORMAT, tm); + + pcap_fd = open(name, O_WRONLY | O_CREAT | O_APPEND | O_DSYNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (pcap_fd == -1) { + perror("open"); + return; + } + + write(pcap_fd, &pcap_hdr, sizeof(pcap_hdr)); +} + +#else /* DEBUG */ +void pcap(char *pkt, size_t len) { + (void)pkt; + (void)len; +} + +void pcap_init(void) { } +#endif -- cgit v1.2.3