Development discussion of WireGuard
 help / color / mirror / Atom feed
From: Matthew Oliver <matt@oliver.net.au>
To: wireguard@lists.zx2c4.com
Subject: Re: [PATCH] wg show: Add json output
Date: Mon, 17 Feb 2020 15:47:56 +1100	[thread overview]
Message-ID: <CAEQe3e=JMOwASvDGuC00uiYdTY_VaU0PnB285pU715i7g4uRaA@mail.gmail.com> (raw)
In-Reply-To: <20200217035701.28261-1-matt@oliver.net.au>


[-- Attachment #1.1: Type: text/plain, Size: 7819 bytes --]

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@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@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
>
>

[-- Attachment #1.2: Type: text/html, Size: 11166 bytes --]

[-- Attachment #2: Type: text/plain, Size: 148 bytes --]

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

  reply	other threads:[~2020-02-23 10:35 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-17  3:57 Matthew Oliver
2020-02-17  4:47 ` Matthew Oliver [this message]
2020-02-23 11:00   ` Jason A. Donenfeld
2020-02-25 15:49     ` Julian Orth
2020-02-23 12:45   ` Arti Zirk
2020-02-24 19:28     ` Barry Scott
2020-02-25 14:50       ` Kalin KOZHUHAROV

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAEQe3e=JMOwASvDGuC00uiYdTY_VaU0PnB285pU715i7g4uRaA@mail.gmail.com' \
    --to=matt@oliver.net.au \
    --cc=wireguard@lists.zx2c4.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).