diff options
| author | 2025-11-26 17:35:41 +0000 | |
|---|---|---|
| committer | 2025-11-26 18:56:21 +0100 | |
| commit | ec53ddf0d7b39aaad633391bb40bfcabbe2e1975 (patch) | |
| tree | 157043adacc412a3a35d9cddd26b04dde4e0fbb6 /tools/net/ynl/samples/wireguard.c | |
| parent | wireguard: uapi: generate header with ynl-gen (diff) | |
| download | wireguard-linux-ec53ddf0d7b39aaad633391bb40bfcabbe2e1975.tar.xz wireguard-linux-ec53ddf0d7b39aaad633391bb40bfcabbe2e1975.zip | |
tools: ynl: add sample for wireguard
Add a sample application for WireGuard, using the generated C library.
The main benefit of this is to exercise the generated library,
which might be useful for future selftests.
In order to support usage with a pre-YNL wireguard.h in /usr/include,
the former header guard is added to Makefile.deps as well.
Example:
$ make -C tools/net/ynl/lib
$ make -C tools/net/ynl/generated
$ make -C tools/net/ynl/samples wireguard
$ ./tools/net/ynl/samples/wireguard
usage: ./tools/net/ynl/samples/wireguard <ifindex|ifname>
$ sudo ./tools/net/ynl/samples/wireguard wg-test
Interface 3: wg-test
Peer 6adfb183a4a2c94a2f92dab5ade762a4788[...]:
Data: rx: 42 / tx: 42 bytes
Allowed IPs:
0.0.0.0/0
::/0
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to '')
| -rw-r--r-- | tools/net/ynl/samples/wireguard.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/tools/net/ynl/samples/wireguard.c b/tools/net/ynl/samples/wireguard.c new file mode 100644 index 000000000000..43f3551eb101 --- /dev/null +++ b/tools/net/ynl/samples/wireguard.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <arpa/inet.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <ynl.h> + +#include "wireguard-user.h" + +static void print_allowed_ip(const struct wireguard_wgallowedip *aip) +{ + char addr_out[INET6_ADDRSTRLEN]; + + if (!inet_ntop(aip->family, aip->ipaddr, addr_out, sizeof(addr_out))) { + addr_out[0] = '?'; + addr_out[1] = '\0'; + } + printf("\t\t\t%s/%u\n", addr_out, aip->cidr_mask); +} + +/* Only printing public key in this demo. For better key formatting, + * use the constant-time implementation as found in wireguard-tools. + */ +static void print_peer_header(const struct wireguard_wgpeer *peer) +{ + unsigned int i; + uint8_t *key = peer->public_key; + unsigned int len = peer->_len.public_key; + + if (len != 32) + return; + printf("\tPeer "); + for (i = 0; i < len; i++) + printf("%02x", key[i]); + printf(":\n"); +} + +static void print_peer(const struct wireguard_wgpeer *peer) +{ + unsigned int i; + + print_peer_header(peer); + printf("\t\tData: rx: %llu / tx: %llu bytes\n", + peer->rx_bytes, peer->tx_bytes); + printf("\t\tAllowed IPs:\n"); + for (i = 0; i < peer->_count.allowedips; i++) + print_allowed_ip(&peer->allowedips[i]); +} + +static void build_request(struct wireguard_get_device_req *req, char *arg) +{ + char *endptr; + int ifindex; + + ifindex = strtol(arg, &endptr, 0); + if (endptr != arg + strlen(arg) || errno != 0) + ifindex = 0; + if (ifindex > 0) + wireguard_get_device_req_set_ifindex(req, ifindex); + else + wireguard_get_device_req_set_ifname(req, arg); +} + +int main(int argc, char **argv) +{ + struct wireguard_get_device_list *devs; + struct wireguard_get_device_req *req; + struct ynl_sock *ys; + + if (argc < 2) { + fprintf(stderr, "usage: %s <ifindex|ifname>\n", argv[0]); + return 1; + } + + req = wireguard_get_device_req_alloc(); + build_request(req, argv[1]); + + ys = ynl_sock_create(&ynl_wireguard_family, NULL); + if (!ys) + return 2; + + devs = wireguard_get_device_dump(ys, req); + if (!devs) + goto err_close; + + ynl_dump_foreach(devs, d) { + unsigned int i; + + printf("Interface %d: %s\n", d->ifindex, d->ifname); + for (i = 0; i < d->_count.peers; i++) + print_peer(&d->peers[i]); + } + wireguard_get_device_list_free(devs); + wireguard_get_device_req_free(req); + ynl_sock_destroy(ys); + + return 0; + +err_close: + fprintf(stderr, "YNL (%d): %s\n", ys->err.code, ys->err.msg); + wireguard_get_device_req_free(req); + ynl_sock_destroy(ys); + return 3; +} |
