[PATCH] wg show: Add json output
Matthew Oliver
matt at oliver.net.au
Mon Feb 17 05:47:56 CET 2020
Someone asked about this in the IRC channel, so quickly wrote up a patch to
add it. No pressure if you do/don't want to merge it :)
Matt
On Mon, Feb 17, 2020 at 2:57 PM Matthew Oliver <matt at oliver.net.au> wrote:
> This patch adds a new option to `wg show` called json. When
> specified it'll output the WG interface in json output.
>
> It works with both given an interface or all.
>
> # wg show wg1 json
> [
> {
> "interface": "wg1",
> "public_key": "Yh0kKjoqnJsxbCsTkQ/3uncEhdqa+EtJXCYcVzMdugs=",
> "private_key": "MKVTz8NCXL0uaE77MJfgIWSSy1AfqSmLFRx16oxmrmk=",
> "port": "51831",
> "fwmark": null,
> "peers": [
> {
> "peer": "GzY59HlXkCkfXl9uSkEFTHzOtBsxQFKu3KWGFH5P9Qc=",
> "preshared_key": null,
> "endpoint": "172.16.3.104:51834",
> "allowed_ips": [
> "10.0.3.0/24", "224.0.0.0/8", "172.16.0.0/16"
> ],
> "latest_handshake": 1581909869,
> "transfer": {
> "received": 3949216,
> "sent": 4531428
> },
> "persistent_keepalive": 30
> }
> ]
> }
> ]
>
> Note however, that this will print out the private key.
>
> Signed-off-by: Matthew Oliver <matt at oliver.net.au>
> ---
> src/show.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 72 insertions(+), 3 deletions(-)
>
> diff --git a/src/show.c b/src/show.c
> index e772339..f8c7543 100644
> --- a/src/show.c
> +++ b/src/show.c
> @@ -202,7 +202,62 @@ static char *bytes(uint64_t b)
> static const char *COMMAND_NAME;
> static void show_usage(void)
> {
> - fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces }
> [public-key | private-key | listen-port | fwmark | peers | preshared-keys |
> endpoints | allowed-ips | latest-handshakes | transfer |
> persistent-keepalive | dump]\n", PROG_NAME, COMMAND_NAME);
> + fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces }
> [public-key | private-key | listen-port | fwmark | peers | preshared-keys |
> endpoints | allowed-ips | latest-handshakes | transfer |
> persistent-keepalive | dump | json]\n", PROG_NAME, COMMAND_NAME);
> +}
> +
> +static void json_print(struct wgdevice *device)
> +{
> + struct wgpeer *peer;
> + struct wgallowedip *allowedip;
> + terminal_printf(TERMINAL_RESET);
> + terminal_printf(" {\n");
> + terminal_printf(" \"interface\": \"%s\",\n", device->name);
> + terminal_printf(" \"public_key\": \"%s\",\n",
> key(device->public_key));
> + terminal_printf(" \"private_key\": \"%s\",\n",
> key(device->private_key));
> + terminal_printf(" \"port\": \"%d\",\n", device->listen_port);
> + if (device->fwmark)
> + terminal_printf(" \"fwmark\": \"0x%x\",\n",
> device->fwmark);
> + else
> + terminal_printf(" \"fwmark\": null,\n");
> + terminal_printf(" \"peers\": [\n");
> + sort_peers(device);
> + for_each_wgpeer(device, peer) {
> + terminal_printf(" {\n");
> + terminal_printf(" \"peer\": \"%s\",\n",
> key(peer->public_key));
> + if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
> + terminal_printf(" \"preshared_key\":
> \"%s\",\n", key(peer->preshared_key));
> + else
> + terminal_printf(" \"preshared_key\":
> null,\n");
> + if (peer->endpoint.addr.sa_family == AF_INET ||
> peer->endpoint.addr.sa_family == AF_INET6)
> + terminal_printf(" \"endpoint\":
> \"%s\",\n", endpoint(&peer->endpoint.addr));
> + else
> + terminal_printf(" \"endpoint\": null,\n");
> + terminal_printf(" \"allowed_ips\": [\n");
> + if (peer->first_allowedip) {
> + terminal_printf(" ");
> + for_each_wgallowedip(peer, allowedip)
> + terminal_printf("\"%s/%u\"%s",
> ip(allowedip), allowedip->cidr, allowedip->next_allowedip ? ", " : "\n");
> + }
> + terminal_printf(" ],\n");
> + if (peer->last_handshake_time.tv_sec)
> + terminal_printf(" \"latest_handshake\":
> %ld,\n", peer->last_handshake_time.tv_sec);
> + else
> + terminal_printf(" \"latest_handshake\":
> null,\n");
> + terminal_printf(" \"transfer\": {\n");
> + terminal_printf(" \"received\": %ld,\n",
> peer->rx_bytes);
> + terminal_printf(" \"sent\": %ld\n",
> peer->tx_bytes);
> + terminal_printf(" },\n");
> + if (peer->persistent_keepalive_interval)
> + terminal_printf("
> \"persistent_keepalive\": %d\n", peer->persistent_keepalive_interval);
> + else
> + terminal_printf("
> \"persistent_keepalive\": null\n");
> + if (peer->next_peer)
> + terminal_printf(" },\n");
> + else
> + terminal_printf(" }\n");
> + }
> + terminal_printf(" ]\n");
> + terminal_printf(" }");
> }
>
> static void pretty_print(struct wgdevice *device)
> @@ -396,6 +451,8 @@ int show_main(int argc, char *argv[])
> }
> ret = !!*interfaces;
> interface = interfaces;
> + if (argc == 3 && !strcmp(argv[2], "json"))
> + terminal_printf("[\n");
> for (size_t len = 0; (len = strlen(interface)); interface
> += len + 1) {
> struct wgdevice *device = NULL;
>
> @@ -404,7 +461,13 @@ int show_main(int argc, char *argv[])
> continue;
> }
> if (argc == 3) {
> - if (!ugly_print(device, argv[2], true)) {
> + if (!strcmp(argv[2], "json")) {
> + json_print(device);
> + if (strlen(interface + len + 1))
> + terminal_printf(",\n");
> + else
> + terminal_printf("\n");
> + } else if (!ugly_print(device, argv[2],
> true)) {
> ret = 1;
> free_wgdevice(device);
> break;
> @@ -417,6 +480,8 @@ int show_main(int argc, char *argv[])
> free_wgdevice(device);
> ret = 0;
> }
> + if (argc == 3 && !strcmp(argv[2], "json"))
> + terminal_printf("]\n");
> free(interfaces);
> } else if (!strcmp(argv[1], "interfaces")) {
> char *interfaces, *interface;
> @@ -444,7 +509,11 @@ int show_main(int argc, char *argv[])
> return 1;
> }
> if (argc == 3) {
> - if (!ugly_print(device, argv[2], false))
> + if (!strcmp(argv[2], "json")) {
> + terminal_printf("[\n");
> + json_print(device);
> + terminal_printf("\n]\n");
> + } else if (!ugly_print(device, argv[2], false))
> ret = 1;
> } else
> pretty_print(device);
> --
> 2.22.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/wireguard/attachments/20200217/3a5e396a/attachment.html>
More information about the WireGuard
mailing list