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