wg: add wg show [interface] dump

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2017-02-22 21:53:55 +01:00
parent d4edc7baa8
commit bda4b8c60b
3 changed files with 51 additions and 5 deletions

View file

@ -19,7 +19,7 @@ _wg_completion() {
fi fi
if [[ $COMP_CWORD -eq 3 && ${COMP_WORDS[1]} == show && ${COMP_WORDS[2]} != interfaces ]]; then if [[ $COMP_CWORD -eq 3 && ${COMP_WORDS[1]} == show && ${COMP_WORDS[2]} != interfaces ]]; then
COMPREPLY+=( $(compgen -W "public-key private-key preshared-key listen-port peers endpoints allowed-ips fwmark latest-handshakes persistent-keepalive transfer" -- "${COMP_WORDS[3]}") ) COMPREPLY+=( $(compgen -W "public-key private-key preshared-key listen-port peers endpoints allowed-ips fwmark latest-handshakes persistent-keepalive transfer dump" -- "${COMP_WORDS[3]}") )
return return
fi fi

View file

@ -203,7 +203,7 @@ static char *bytes(uint64_t b)
static const char *COMMAND_NAME = NULL; static const char *COMMAND_NAME = NULL;
static void show_usage(void) static void show_usage(void)
{ {
fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | preshared-key | listen-port | fwmark | peers | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive]\n", PROG_NAME, COMMAND_NAME); fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | preshared-key | listen-port | fwmark | peers | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump]\n", PROG_NAME, COMMAND_NAME);
} }
static void pretty_print(struct wgdevice *device) static void pretty_print(struct wgdevice *device)
@ -252,6 +252,44 @@ static void pretty_print(struct wgdevice *device)
} }
} }
static void dump_print(struct wgdevice *device, bool with_interface)
{
size_t i, j;
struct wgpeer *peer;
struct wgipmask *ipmask;
if (with_interface)
printf("%s\t", device->interface);
printf("%s\t", key(device->private_key));
printf("%s\t", key(device->public_key));
printf("%s\t", key(device->preshared_key));
printf("%u\t", device->port);
if (device->fwmark)
printf("0x%x\n", device->fwmark);
else
printf("off\n");
for_each_wgpeer(device, peer, i) {
if (with_interface)
printf("%s\t", device->interface);
printf("%s\t", key(peer->public_key));
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
printf("%s\t", endpoint(&peer->endpoint.addr));
else
printf("(none)\t");
if (peer->num_ipmasks) {
for_each_wgipmask(peer, ipmask, j)
printf("%s/%u%c", ip(ipmask), ipmask->cidr, j == (size_t)peer->num_ipmasks - 1 ? '\t' : ',');
} else
printf("(none)\t");
printf("%llu\t", (unsigned long long)peer->last_handshake_time.tv_sec);
printf("%" PRIu64 "\t%" PRIu64 "\t", (uint64_t)peer->rx_bytes, (uint64_t)peer->tx_bytes);
if (peer->persistent_keepalive_interval)
printf("%u\n", peer->persistent_keepalive_interval);
else
printf("off\n");
}
}
static bool ugly_print(struct wgdevice *device, const char *param, bool with_interface) static bool ugly_print(struct wgdevice *device, const char *param, bool with_interface)
{ {
size_t i, j; size_t i, j;
@ -328,7 +366,9 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
printf("%s\t", device->interface); printf("%s\t", device->interface);
printf("%s\n", key(peer->public_key)); printf("%s\n", key(peer->public_key));
} }
} else { } else if (!strcmp(param, "dump"))
dump_print(device, with_interface);
else {
fprintf(stderr, "Invalid parameter: `%s`\n", param); fprintf(stderr, "Invalid parameter: `%s`\n", param);
show_usage(); show_usage();
return false; return false;

View file

@ -36,14 +36,20 @@ Sub-commands that take an INTERFACE must be passed a WireGuard interface.
.SH COMMANDS .SH COMMANDS
.TP .TP
\fBshow\fP { \fI<interface>\fP | \fIall\fP | \fIinterfaces\fP } [\fIpublic-key\fP | \fIprivate-key\fP | \fIpreshared-key\fP | \fIlisten-port\fP | \fIfwmark\fP | \fIpeers\fP | \fIendpoints\fP | \fIallowed-ips\fP | \fIlatest-handshakes\fP | \fIpersistent-keepalive\fP | \fItransfer\fP] \fBshow\fP { \fI<interface>\fP | \fIall\fP | \fIinterfaces\fP } [\fIpublic-key\fP | \fIprivate-key\fP | \fIpreshared-key\fP | \fIlisten-port\fP | \fIfwmark\fP | \fIpeers\fP | \fIendpoints\fP | \fIallowed-ips\fP | \fIlatest-handshakes\fP | \fIpersistent-keepalive\fP | \fItransfer\fP | \fIdump\fP]
Shows current WireGuard configuration of specified \fI<interface>\fP. Shows current WireGuard configuration of specified \fI<interface>\fP.
If no \fI<interface>\fP is specified, \fI<interface>\fP defaults to \fIall\fP. If no \fI<interface>\fP is specified, \fI<interface>\fP defaults to \fIall\fP.
If \fIinterfaces\fP is specified, prints a list of all WireGuard interfaces, If \fIinterfaces\fP is specified, prints a list of all WireGuard interfaces,
one per line, and quit. If no options are given after the interface one per line, and quit. If no options are given after the interface
specification, then prints a list of all attributes in a visually pleasing way specification, then prints a list of all attributes in a visually pleasing way
meant for the terminal. Otherwise, prints specified information grouped by meant for the terminal. Otherwise, prints specified information grouped by
newlines and tabs, meant to be used in scripts. newlines and tabs, meant to be used in scripts. For this script-friendly display,
if \fIall\fP is specified, then the first field for all categories of information
is the interface name. If \fPdump\fP is specified, then several lines are printed;
the first contains in order separated by tab: private-key, public-key, preshared-key,
listen-port, fwmark. Subsequent lines are printed for each peer and contain in order
separated by tab: public-key, endpoint, allowed-ips, latest-handshake, transfer-rx,
transfer-tx, persistent-keepalive.
.TP .TP
\fBshowconf\fP \fI<interface>\fP \fBshowconf\fP \fI<interface>\fP
Shows the current configuration of \fI<interface>\fP in the format described Shows the current configuration of \fI<interface>\fP in the format described