[PATCH] wg show: Add json output

Jason A. Donenfeld Jason at zx2c4.com
Sun Feb 23 12:00:45 CET 2020


wg(8) is a unix text utility.

However, we have a script in contrib for accomplishing this same thing:

https://git.zx2c4.com/wireguard-tools/tree/contrib/json

On Sun, Feb 23, 2020, 11:36 Matthew Oliver <matt at oliver.net.au> wrote:

> 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
>>
>> _______________________________________________
> WireGuard mailing list
> WireGuard at lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/wireguard
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/wireguard/attachments/20200223/9be3d207/attachment.html>


More information about the WireGuard mailing list