<div dir="ltr">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 :)<div><br></div><div>Matt</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Feb 17, 2020 at 2:57 PM Matthew Oliver <<a href="mailto:matt@oliver.net.au">matt@oliver.net.au</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This patch adds a new option to `wg show` called json. When<br>
specified it'll output the WG interface in json output.<br>
<br>
It works with both given an interface or all.<br>
<br>
  # wg show wg1 json<br>
  [<br>
    {<br>
      "interface": "wg1",<br>
      "public_key": "Yh0kKjoqnJsxbCsTkQ/3uncEhdqa+EtJXCYcVzMdugs=",<br>
      "private_key": "MKVTz8NCXL0uaE77MJfgIWSSy1AfqSmLFRx16oxmrmk=",<br>
      "port": "51831",<br>
      "fwmark": null,<br>
      "peers": [<br>
         {<br>
           "peer": "GzY59HlXkCkfXl9uSkEFTHzOtBsxQFKu3KWGFH5P9Qc=",<br>
           "preshared_key": null,<br>
           "endpoint": "<a href="http://172.16.3.104:51834" rel="noreferrer" target="_blank">172.16.3.104:51834</a>",<br>
           "allowed_ips": [<br>
             "<a href="http://10.0.3.0/24" rel="noreferrer" target="_blank">10.0.3.0/24</a>", "<a href="http://224.0.0.0/8" rel="noreferrer" target="_blank">224.0.0.0/8</a>", "<a href="http://172.16.0.0/16" rel="noreferrer" target="_blank">172.16.0.0/16</a>"<br>
           ],<br>
           "latest_handshake": 1581909869,<br>
           "transfer": {<br>
            "received": 3949216,<br>
            "sent": 4531428<br>
           },<br>
           "persistent_keepalive": 30<br>
         }<br>
      ]<br>
    }<br>
  ]<br>
<br>
Note however, that this will print out the private key.<br>
<br>
Signed-off-by: Matthew Oliver <<a href="mailto:matt@oliver.net.au" target="_blank">matt@oliver.net.au</a>><br>
---<br>
 src/show.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++---<br>
 1 file changed, 72 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/src/show.c b/src/show.c<br>
index e772339..f8c7543 100644<br>
--- a/src/show.c<br>
+++ b/src/show.c<br>
@@ -202,7 +202,62 @@ static char *bytes(uint64_t b)<br>
 static const char *COMMAND_NAME;<br>
 static void show_usage(void)<br>
 {<br>
-       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);<br>
+       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);<br>
+}<br>
+<br>
+static void json_print(struct wgdevice *device)<br>
+{<br>
+       struct wgpeer *peer;<br>
+       struct wgallowedip *allowedip;<br>
+       terminal_printf(TERMINAL_RESET);<br>
+       terminal_printf("  {\n");<br>
+       terminal_printf("    \"interface\": \"%s\",\n", device->name);<br>
+       terminal_printf("    \"public_key\": \"%s\",\n", key(device->public_key));<br>
+       terminal_printf("    \"private_key\": \"%s\",\n", key(device->private_key));<br>
+       terminal_printf("    \"port\": \"%d\",\n", device->listen_port);<br>
+       if (device->fwmark)<br>
+               terminal_printf("    \"fwmark\": \"0x%x\",\n", device->fwmark);<br>
+       else<br>
+               terminal_printf("    \"fwmark\": null,\n");<br>
+       terminal_printf("    \"peers\": [\n");<br>
+       sort_peers(device);<br>
+       for_each_wgpeer(device, peer) {<br>
+               terminal_printf("       {\n");<br>
+               terminal_printf("         \"peer\": \"%s\",\n", key(peer->public_key));<br>
+               if (peer->flags & WGPEER_HAS_PRESHARED_KEY)<br>
+                       terminal_printf("         \"preshared_key\": \"%s\",\n", key(peer->preshared_key));<br>
+               else<br>
+                       terminal_printf("         \"preshared_key\": null,\n");<br>
+               if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)<br>
+                       terminal_printf("         \"endpoint\": \"%s\",\n", endpoint(&peer->endpoint.addr));<br>
+               else<br>
+                       terminal_printf("         \"endpoint\": null,\n");<br>
+               terminal_printf("         \"allowed_ips\": [\n");<br>
+               if (peer->first_allowedip) {<br>
+                       terminal_printf("           ");<br>
+                       for_each_wgallowedip(peer, allowedip)<br>
+                               terminal_printf("\"%s/%u\"%s", ip(allowedip), allowedip->cidr, allowedip->next_allowedip ? ", " : "\n");<br>
+               }<br>
+               terminal_printf("         ],\n");<br>
+               if (peer->last_handshake_time.tv_sec)<br>
+                       terminal_printf("         \"latest_handshake\": %ld,\n", peer->last_handshake_time.tv_sec);<br>
+               else<br>
+                       terminal_printf("         \"latest_handshake\": null,\n");<br>
+               terminal_printf("         \"transfer\": {\n");<br>
+               terminal_printf("          \"received\": %ld,\n", peer->rx_bytes);<br>
+               terminal_printf("          \"sent\": %ld\n", peer->tx_bytes);<br>
+               terminal_printf("         },\n");<br>
+               if (peer->persistent_keepalive_interval)<br>
+                       terminal_printf("         \"persistent_keepalive\": %d\n", peer->persistent_keepalive_interval);<br>
+               else<br>
+                       terminal_printf("         \"persistent_keepalive\": null\n");<br>
+               if (peer->next_peer)<br>
+                       terminal_printf("       },\n");<br>
+               else<br>
+                       terminal_printf("       }\n");<br>
+       }<br>
+       terminal_printf("    ]\n");<br>
+       terminal_printf("  }");<br>
 }<br>
<br>
 static void pretty_print(struct wgdevice *device)<br>
@@ -396,6 +451,8 @@ int show_main(int argc, char *argv[])<br>
                }<br>
                ret = !!*interfaces;<br>
                interface = interfaces;<br>
+               if (argc == 3 && !strcmp(argv[2], "json"))<br>
+                       terminal_printf("[\n");<br>
                for (size_t len = 0; (len = strlen(interface)); interface += len + 1) {<br>
                        struct wgdevice *device = NULL;<br>
<br>
@@ -404,7 +461,13 @@ int show_main(int argc, char *argv[])<br>
                                continue;<br>
                        }<br>
                        if (argc == 3) {<br>
-                               if (!ugly_print(device, argv[2], true)) {<br>
+                               if (!strcmp(argv[2], "json")) {<br>
+                                       json_print(device);<br>
+                                       if (strlen(interface + len + 1))<br>
+                                               terminal_printf(",\n");<br>
+                                       else<br>
+                                               terminal_printf("\n");<br>
+                               } else if (!ugly_print(device, argv[2], true)) {<br>
                                        ret = 1;<br>
                                        free_wgdevice(device);<br>
                                        break;<br>
@@ -417,6 +480,8 @@ int show_main(int argc, char *argv[])<br>
                        free_wgdevice(device);<br>
                        ret = 0;<br>
                }<br>
+               if (argc == 3 && !strcmp(argv[2], "json"))<br>
+                       terminal_printf("]\n");<br>
                free(interfaces);<br>
        } else if (!strcmp(argv[1], "interfaces")) {<br>
                char *interfaces, *interface;<br>
@@ -444,7 +509,11 @@ int show_main(int argc, char *argv[])<br>
                        return 1;<br>
                }<br>
                if (argc == 3) {<br>
-                       if (!ugly_print(device, argv[2], false))<br>
+                       if (!strcmp(argv[2], "json")) {<br>
+                               terminal_printf("[\n");<br>
+                               json_print(device);<br>
+                               terminal_printf("\n]\n");<br>
+                       } else if (!ugly_print(device, argv[2], false))<br>
                                ret = 1;<br>
                } else<br>
                        pretty_print(device);<br>
-- <br>
2.22.0<br>
<br>
</blockquote></div>