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 <m...@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 _______________________________________________ WireGuard mailing list WireGuard@lists.zx2c4.com https://lists.zx2c4.com/mailman/listinfo/wireguard