aboutgitcodebugslistschat
path: root/pcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcap.c')
-rw-r--r--pcap.c108
1 files changed, 108 insertions, 0 deletions
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 <sbrivio@redhat.com>
+ *
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <net/ethernet.h>
+#include <unistd.h>
+
+#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