1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /*
3 * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4 */
5
6 #include <arpa/inet.h>
7 #include <netinet/in.h>
8 #include <sys/socket.h>
9 #include <net/if.h>
10 #include <stddef.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <netdb.h>
15
16 #include "containers.h"
17 #include "encoding.h"
18 #include "ipc.h"
19 #include "subcommands.h"
20
showconf_main(int argc,const char * argv[])21 int showconf_main(int argc, const char *argv[])
22 {
23 char base64[WG_KEY_LEN_BASE64];
24 char ip[INET6_ADDRSTRLEN];
25 struct wgdevice *device = NULL;
26 struct wgpeer *peer;
27 struct wgallowedip *allowedip;
28 int ret = 1;
29
30 if (argc != 2) {
31 fprintf(stderr, "Usage: %s %s <interface>\n", PROG_NAME, argv[0]);
32 return 1;
33 }
34
35 if (ipc_get_device(&device, argv[1])) {
36 perror("Unable to access interface");
37 goto cleanup;
38 }
39
40 printf("[Interface]\n");
41 if (device->listen_port)
42 printf("ListenPort = %u\n", device->listen_port);
43 if (device->fwmark)
44 printf("FwMark = 0x%x\n", device->fwmark);
45 if (device->flags & WGDEVICE_HAS_PRIVATE_KEY) {
46 key_to_base64(base64, device->private_key);
47 printf("PrivateKey = %s\n", base64);
48 }
49 printf("\n");
50 for_each_wgpeer(device, peer) {
51 key_to_base64(base64, peer->public_key);
52 printf("[Peer]\nPublicKey = %s\n", base64);
53 if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
54 key_to_base64(base64, peer->preshared_key);
55 printf("PresharedKey = %s\n", base64);
56 }
57 if (peer->first_allowedip)
58 printf("AllowedIPs = ");
59 for_each_wgallowedip(peer, allowedip) {
60 if (allowedip->family == AF_INET) {
61 if (!inet_ntop(AF_INET, &allowedip->ip4, ip, INET6_ADDRSTRLEN))
62 continue;
63 } else if (allowedip->family == AF_INET6) {
64 if (!inet_ntop(AF_INET6, &allowedip->ip6, ip, INET6_ADDRSTRLEN))
65 continue;
66 } else
67 continue;
68 printf("%s/%d", ip, allowedip->cidr);
69 if (allowedip->next_allowedip)
70 printf(", ");
71 }
72 if (peer->first_allowedip)
73 printf("\n");
74
75 if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6) {
76 char host[4096 + 1];
77 char service[512 + 1];
78 socklen_t addr_len = 0;
79
80 if (peer->endpoint.addr.sa_family == AF_INET)
81 addr_len = sizeof(struct sockaddr_in);
82 else if (peer->endpoint.addr.sa_family == AF_INET6)
83 addr_len = sizeof(struct sockaddr_in6);
84 if (!getnameinfo(&peer->endpoint.addr, addr_len, host, sizeof(host), service, sizeof(service), NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST)) {
85 if (peer->endpoint.addr.sa_family == AF_INET6 && strchr(host, ':'))
86 printf("Endpoint = [%s]:%s\n", host, service);
87 else
88 printf("Endpoint = %s:%s\n", host, service);
89 }
90 }
91
92 if (peer->persistent_keepalive_interval)
93 printf("PersistentKeepalive = %u\n", peer->persistent_keepalive_interval);
94
95 if (peer->next_peer)
96 printf("\n");
97 }
98 ret = 0;
99
100 cleanup:
101 free_wgdevice(device);
102 return ret;
103 }
104