// SPDX-License-Identifier: GPL-2.0-or-later /* PESTO - Programmable Extensible Socket Translation Orchestrator * front-end for passt(1) and pasta(1) forwarding configuration * * pesto.c - Main program (it's not actually extensible) * * Copyright (c) 2026 Red Hat GmbH * Author: Stefano Brivio */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "seccomp_pesto.h" #include "pesto_util.h" #include "pesto.h" #define die(...) \ do { \ FPRINTF(stderr, __VA_ARGS__); \ FPRINTF(stderr, "\n"); \ exit(EXIT_FAILURE); \ } while (0) /** * main() - Entry point and whole program with loop * @argc: Argument count * @argv: Arguments: socket path, operation, port specifiers * * Return: 0 on success, won't return on failure * * #syscalls:pesto connect write close exit_group fstat brk * #syscalls:pesto socket s390x:socketcall i686:socketcall * #syscalls:pesto recvfrom recvmsg arm:recv ppc64le:recv * #syscalls:pesto sendto sendmsg arm:send ppc64le:send */ int main(int argc, char **argv) { struct sockaddr_un a = { AF_UNIX, "" }; struct pesto_hello hello; struct sock_fprog prog; uint32_t s_version; int ret, s; prctl(PR_SET_DUMPABLE, 0); prog.len = (unsigned short)sizeof(filter_pesto) / sizeof(filter_pesto[0]); prog.filter = filter_pesto; if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) || prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) die("Failed to apply seccomp filter"); if (argc < 2) die("Usage: %s CONTROLPATH", argv[0]); if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) die("Failed to create AF_UNIX socket: %s", strerror(errno)); ret = snprintf(a.sun_path, sizeof(a.sun_path), "%s", argv[1]); if (ret <= 0 || ret >= (int)sizeof(a.sun_path)) die("Invalid socket path \"%s\"", argv[1]); ret = connect(s, (struct sockaddr *)&a, sizeof(a)); if (ret < 0) { die("Failed to connect to %s: %s", a.sun_path, strerror(errno)); } ret = read_all_buf(s, &hello, sizeof(hello)); if (ret < 0) die("Couldn't read server greeting: %s", strerror(errno)); if (memcmp(hello.magic, PESTO_SERVER_MAGIC, sizeof(hello.magic))) die("Bad magic number from server"); s_version = ntohl(hello.version); if (s_version > PESTO_PROTOCOL_VERSION) { die("Unknown server protocol version %"PRIu32" > %"PRIu32"\n", s_version, PESTO_PROTOCOL_VERSION); } if (!s_version) { if (PESTO_PROTOCOL_VERSION) die("Unsupported experimental server protocol"); fprintf(stderr, "Warning: Using experimental protocol version, client and server must match\n"); } return 0; }