aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-05-21 11:14:48 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-05-21 11:14:48 +0200
commit17337a736ff0e7ebd7d5272eba7466a627795215 (patch)
treec1ebb233dbec7a926315f354eb9f9feb709da07b
parent59182924f01e4d2e8f6d8af27c355c191f332eba (diff)
downloadpasst-17337a736ff0e7ebd7d5272eba7466a627795215.tar
passt-17337a736ff0e7ebd7d5272eba7466a627795215.tar.gz
passt-17337a736ff0e7ebd7d5272eba7466a627795215.tar.bz2
passt-17337a736ff0e7ebd7d5272eba7466a627795215.tar.lz
passt-17337a736ff0e7ebd7d5272eba7466a627795215.tar.xz
passt-17337a736ff0e7ebd7d5272eba7466a627795215.tar.zst
passt-17337a736ff0e7ebd7d5272eba7466a627795215.zip
passt: Introduce packet capture implementation
With -DDEBUG, passt now saves guest-side traffic captures in pcap format at /tmp/passt_<ISO8601 timestamp>.pcap. The timestamp refers to time and date of start-up. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--Makefile4
-rw-r--r--passt.c5
-rw-r--r--pcap.c108
-rw-r--r--pcap.h2
-rw-r--r--tap.c3
5 files changed, 120 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 213020b..fb4494a 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@ CFLAGS += -Wall -Wextra -pedantic
all: passt qrap
-passt: passt.c passt.h arp.c arp.h dhcp.c dhcp.h dhcpv6.c dhcpv6.h ndp.c ndp.h siphash.c siphash.h tap.c tap.h icmp.c icmp.h tcp.c tcp.h udp.c udp.h util.c util.h
- $(CC) $(CFLAGS) passt.c arp.c dhcp.c dhcpv6.c ndp.c siphash.c tap.c icmp.c tcp.c udp.c util.c -o passt
+passt: passt.c passt.h arp.c arp.h dhcp.c dhcp.h dhcpv6.c dhcpv6.h pcap.c pcap.h ndp.c ndp.h siphash.c siphash.h tap.c tap.h icmp.c icmp.h tcp.c tcp.h udp.c udp.h util.c util.h
+ $(CC) $(CFLAGS) passt.c arp.c dhcp.c dhcpv6.c pcap.c ndp.c siphash.c tap.c icmp.c tcp.c udp.c util.c -o passt
qrap: qrap.c passt.h
$(CC) $(CFLAGS) -DARCH=\"$(shell uname -m)\" qrap.c -o qrap
diff --git a/passt.c b/passt.c
index d0dcb26..6b6a317 100644
--- a/passt.c
+++ b/passt.c
@@ -53,6 +53,7 @@
#include "icmp.h"
#include "tcp.h"
#include "udp.h"
+#include "pcap.h"
#define EPOLL_EVENTS 10
@@ -601,6 +602,8 @@ static int tap_handler(struct ctx *c, struct timespec *now)
return 0;
}
+ pcap(p, len);
+
msg[msg_count].start = p;
msg[msg_count++].len = len;
@@ -792,6 +795,8 @@ int main(int argc, char **argv)
memset(&c.mac_guest, 0xff, sizeof(c.mac_guest));
+ pcap_init();
+
if (c.v4) {
info("ARP:");
info(" address: %02x:%02x:%02x:%02x:%02x:%02x from %s",
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
diff --git a/pcap.h b/pcap.h
new file mode 100644
index 0000000..00bafee
--- /dev/null
+++ b/pcap.h
@@ -0,0 +1,2 @@
+void pcap(char *pkt, size_t len);
+void pcap_init(void);
diff --git a/tap.c b/tap.c
index 5d2201a..70e4774 100644
--- a/tap.c
+++ b/tap.c
@@ -25,6 +25,7 @@
#include "passt.h"
#include "util.h"
+#include "pcap.h"
/**
* tap_send() - Send frame and qemu socket header with indication of length
@@ -39,6 +40,8 @@ int tap_send(int fd, void *data, size_t len, int flags)
uint32_t vnet_len = htonl(len);
send(fd, &vnet_len, 4, MSG_DONTWAIT | MSG_NOSIGNAL);
+ pcap(data, len);
+
return send(fd, data, len, flags | MSG_DONTWAIT | MSG_NOSIGNAL);
}