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 --- qrap.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 11 deletions(-) (limited to 'qrap.c') 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