From ad4a85c86056dbab773ba3e2823b51cf1d128245 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Fri, 21 May 2021 11:14:52 +0200 Subject: qrap: Connect to the first available instance of passt, probe via ARP request Signed-off-by: Stefano Brivio --- arp.c | 15 +-------------- arp.h | 14 ++++++++++++++ qrap.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/arp.c b/arp.c index d1052ec..20f08b2 100644 --- a/arp.c +++ b/arp.c @@ -26,20 +26,7 @@ #include "dhcp.h" #include "util.h" #include "tap.h" - -/** - * struct arpmsg - 802.2 ARP IPv4 payload - * @sha: Sender hardware address - * @sip: Sender IP address - * @tha: Target hardware address - * @tip: Target IP address - */ -struct arpmsg { - unsigned char sha[ETH_ALEN]; - unsigned char sip[4]; - unsigned char tha[ETH_ALEN]; - unsigned char tip[4]; -} __attribute__((__packed__)); +#include "arp.h" /** * arp() - Check if this is an ARP message, reply as needed diff --git a/arp.h b/arp.h index 70188b3..e9b5adf 100644 --- a/arp.h +++ b/arp.h @@ -1 +1,15 @@ +/** + * struct arpmsg - 802.2 ARP IPv4 payload + * @sha: Sender hardware address + * @sip: Sender IP address + * @tha: Target hardware address + * @tip: Target IP address + */ +struct arpmsg { + unsigned char sha[ETH_ALEN]; + unsigned char sip[4]; + unsigned char tha[ETH_ALEN]; + unsigned char tip[4]; +} __attribute__((__packed__)); + int arp(struct ctx *c, struct ethhdr *eh, size_t len); diff --git a/qrap.c b/qrap.c index fc7b397..5c535ff 100644 --- a/qrap.c +++ b/qrap.c @@ -14,21 +14,22 @@ #include #include #include +#include #include #include #include -#include #include #include #include #include +#include #include -#include +#include +#include #include "passt.h" - -#define STRINGIFY(x) #x -#define STR(x) STRINGIFY(x) +#include "util.h" +#include "arp.h" static char *qemu_names[] = { "kvm", @@ -101,10 +102,32 @@ int main(int argc, char **argv) int i, s, qemu_argc = 0, addr_map = 0, has_dev = 0; struct sockaddr_un addr = { .sun_family = AF_UNIX, - .sun_path = UNIX_SOCK_PATH, }; const struct pci_dev *dev = NULL; long fd; + struct { + uint32_t vnet_len; + struct ethhdr eh; + struct arphdr ah; + struct arpmsg am; + } probe = { + htonl(42), + { + .h_dest = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + .h_source = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + .h_proto = htons(ETH_P_ARP), + }, + { .ar_hrd = htons(ARPHRD_ETHER), + .ar_pro = htons(ETH_P_IP), + .ar_hln = ETH_ALEN, + .ar_pln = 4, + .ar_op = htons(ARPOP_REQUEST), + }, + { + .sha = { 0 }, .sip = { 0 }, .tha = { 0 }, .tip = { 0 }, + }, + }; + char probe_r; if (argc >= 3) { fd = strtol(argv[1], NULL, 0); @@ -193,13 +216,32 @@ int main(int argc, char **argv) qemu_argv[qemu_argc] = NULL; valid_args: - s = socket(AF_UNIX, SOCK_STREAM, 0); - if (s < 0) { - perror("socket"); - exit(EXIT_FAILURE); + for (i = 1; i < UNIX_SOCK_MAX; i++) { + struct timeval tv = { .tv_sec = 0, .tv_usec = 100 * 1000 }; + + s = socket(AF_UNIX, SOCK_STREAM, 0); + setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + + if (s < 0) { + perror("socket"); + exit(EXIT_FAILURE); + } + + snprintf(addr.sun_path, UNIX_PATH_MAX, UNIX_SOCK_PATH, i); + if (!connect(s, (const struct sockaddr *)&addr, sizeof(addr)) && + send(s, &probe, sizeof(probe), 0) == sizeof(probe) && + recv(s, &probe_r, 1, MSG_PEEK) > 0) { + tv.tv_usec = 0; + setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + break; + } + + perror("send"); + + close(s); } - if (connect(s, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (i == UNIX_SOCK_MAX) { perror("connect"); exit(EXIT_FAILURE); } -- cgit v1.2.3