1*121f4167SAsbjørn Sloth Tønnesen // SPDX-License-Identifier: GPL-2.0 2*121f4167SAsbjørn Sloth Tønnesen #include <arpa/inet.h> 3*121f4167SAsbjørn Sloth Tønnesen #include <string.h> 4*121f4167SAsbjørn Sloth Tønnesen #include <stdio.h> 5*121f4167SAsbjørn Sloth Tønnesen #include <errno.h> 6*121f4167SAsbjørn Sloth Tønnesen #include <ynl.h> 7*121f4167SAsbjørn Sloth Tønnesen 8*121f4167SAsbjørn Sloth Tønnesen #include "wireguard-user.h" 9*121f4167SAsbjørn Sloth Tønnesen 10*121f4167SAsbjørn Sloth Tønnesen static void print_allowed_ip(const struct wireguard_wgallowedip *aip) 11*121f4167SAsbjørn Sloth Tønnesen { 12*121f4167SAsbjørn Sloth Tønnesen char addr_out[INET6_ADDRSTRLEN]; 13*121f4167SAsbjørn Sloth Tønnesen 14*121f4167SAsbjørn Sloth Tønnesen if (!inet_ntop(aip->family, aip->ipaddr, addr_out, sizeof(addr_out))) { 15*121f4167SAsbjørn Sloth Tønnesen addr_out[0] = '?'; 16*121f4167SAsbjørn Sloth Tønnesen addr_out[1] = '\0'; 17*121f4167SAsbjørn Sloth Tønnesen } 18*121f4167SAsbjørn Sloth Tønnesen printf("\t\t\t%s/%u\n", addr_out, aip->cidr_mask); 19*121f4167SAsbjørn Sloth Tønnesen } 20*121f4167SAsbjørn Sloth Tønnesen 21*121f4167SAsbjørn Sloth Tønnesen /* Only printing public key in this demo. For better key formatting, 22*121f4167SAsbjørn Sloth Tønnesen * use the constant-time implementation as found in wireguard-tools. 23*121f4167SAsbjørn Sloth Tønnesen */ 24*121f4167SAsbjørn Sloth Tønnesen static void print_peer_header(const struct wireguard_wgpeer *peer) 25*121f4167SAsbjørn Sloth Tønnesen { 26*121f4167SAsbjørn Sloth Tønnesen unsigned int len = peer->_len.public_key; 27*121f4167SAsbjørn Sloth Tønnesen uint8_t *key = peer->public_key; 28*121f4167SAsbjørn Sloth Tønnesen unsigned int i; 29*121f4167SAsbjørn Sloth Tønnesen 30*121f4167SAsbjørn Sloth Tønnesen if (len != 32) 31*121f4167SAsbjørn Sloth Tønnesen return; 32*121f4167SAsbjørn Sloth Tønnesen printf("\tPeer "); 33*121f4167SAsbjørn Sloth Tønnesen for (i = 0; i < len; i++) 34*121f4167SAsbjørn Sloth Tønnesen printf("%02x", key[i]); 35*121f4167SAsbjørn Sloth Tønnesen printf(":\n"); 36*121f4167SAsbjørn Sloth Tønnesen } 37*121f4167SAsbjørn Sloth Tønnesen 38*121f4167SAsbjørn Sloth Tønnesen static void print_peer(const struct wireguard_wgpeer *peer) 39*121f4167SAsbjørn Sloth Tønnesen { 40*121f4167SAsbjørn Sloth Tønnesen unsigned int i; 41*121f4167SAsbjørn Sloth Tønnesen 42*121f4167SAsbjørn Sloth Tønnesen print_peer_header(peer); 43*121f4167SAsbjørn Sloth Tønnesen printf("\t\tData: rx: %llu / tx: %llu bytes\n", 44*121f4167SAsbjørn Sloth Tønnesen peer->rx_bytes, peer->tx_bytes); 45*121f4167SAsbjørn Sloth Tønnesen printf("\t\tAllowed IPs:\n"); 46*121f4167SAsbjørn Sloth Tønnesen for (i = 0; i < peer->_count.allowedips; i++) 47*121f4167SAsbjørn Sloth Tønnesen print_allowed_ip(&peer->allowedips[i]); 48*121f4167SAsbjørn Sloth Tønnesen } 49*121f4167SAsbjørn Sloth Tønnesen 50*121f4167SAsbjørn Sloth Tønnesen static void build_request(struct wireguard_get_device_req *req, char *arg) 51*121f4167SAsbjørn Sloth Tønnesen { 52*121f4167SAsbjørn Sloth Tønnesen char *endptr; 53*121f4167SAsbjørn Sloth Tønnesen int ifindex; 54*121f4167SAsbjørn Sloth Tønnesen 55*121f4167SAsbjørn Sloth Tønnesen ifindex = strtol(arg, &endptr, 0); 56*121f4167SAsbjørn Sloth Tønnesen if (endptr != arg + strlen(arg) || errno != 0) 57*121f4167SAsbjørn Sloth Tønnesen ifindex = 0; 58*121f4167SAsbjørn Sloth Tønnesen if (ifindex > 0) 59*121f4167SAsbjørn Sloth Tønnesen wireguard_get_device_req_set_ifindex(req, ifindex); 60*121f4167SAsbjørn Sloth Tønnesen else 61*121f4167SAsbjørn Sloth Tønnesen wireguard_get_device_req_set_ifname(req, arg); 62*121f4167SAsbjørn Sloth Tønnesen } 63*121f4167SAsbjørn Sloth Tønnesen 64*121f4167SAsbjørn Sloth Tønnesen int main(int argc, char **argv) 65*121f4167SAsbjørn Sloth Tønnesen { 66*121f4167SAsbjørn Sloth Tønnesen struct wireguard_get_device_list *devs; 67*121f4167SAsbjørn Sloth Tønnesen struct wireguard_get_device_req *req; 68*121f4167SAsbjørn Sloth Tønnesen struct ynl_error yerr; 69*121f4167SAsbjørn Sloth Tønnesen struct ynl_sock *ys; 70*121f4167SAsbjørn Sloth Tønnesen 71*121f4167SAsbjørn Sloth Tønnesen if (argc < 2) { 72*121f4167SAsbjørn Sloth Tønnesen fprintf(stderr, "usage: %s <ifindex|ifname>\n", argv[0]); 73*121f4167SAsbjørn Sloth Tønnesen return 1; 74*121f4167SAsbjørn Sloth Tønnesen } 75*121f4167SAsbjørn Sloth Tønnesen 76*121f4167SAsbjørn Sloth Tønnesen ys = ynl_sock_create(&ynl_wireguard_family, &yerr); 77*121f4167SAsbjørn Sloth Tønnesen if (!ys) { 78*121f4167SAsbjørn Sloth Tønnesen fprintf(stderr, "YNL: %s\n", yerr.msg); 79*121f4167SAsbjørn Sloth Tønnesen return 2; 80*121f4167SAsbjørn Sloth Tønnesen } 81*121f4167SAsbjørn Sloth Tønnesen 82*121f4167SAsbjørn Sloth Tønnesen req = wireguard_get_device_req_alloc(); 83*121f4167SAsbjørn Sloth Tønnesen build_request(req, argv[1]); 84*121f4167SAsbjørn Sloth Tønnesen 85*121f4167SAsbjørn Sloth Tønnesen devs = wireguard_get_device_dump(ys, req); 86*121f4167SAsbjørn Sloth Tønnesen if (!devs) { 87*121f4167SAsbjørn Sloth Tønnesen fprintf(stderr, "YNL (%d): %s\n", ys->err.code, ys->err.msg); 88*121f4167SAsbjørn Sloth Tønnesen wireguard_get_device_req_free(req); 89*121f4167SAsbjørn Sloth Tønnesen ynl_sock_destroy(ys); 90*121f4167SAsbjørn Sloth Tønnesen return 3; 91*121f4167SAsbjørn Sloth Tønnesen } 92*121f4167SAsbjørn Sloth Tønnesen 93*121f4167SAsbjørn Sloth Tønnesen ynl_dump_foreach(devs, d) { 94*121f4167SAsbjørn Sloth Tønnesen unsigned int i; 95*121f4167SAsbjørn Sloth Tønnesen 96*121f4167SAsbjørn Sloth Tønnesen printf("Interface %d: %s\n", d->ifindex, d->ifname); 97*121f4167SAsbjørn Sloth Tønnesen for (i = 0; i < d->_count.peers; i++) 98*121f4167SAsbjørn Sloth Tønnesen print_peer(&d->peers[i]); 99*121f4167SAsbjørn Sloth Tønnesen } 100*121f4167SAsbjørn Sloth Tønnesen 101*121f4167SAsbjørn Sloth Tønnesen wireguard_get_device_list_free(devs); 102*121f4167SAsbjørn Sloth Tønnesen wireguard_get_device_req_free(req); 103*121f4167SAsbjørn Sloth Tønnesen ynl_sock_destroy(ys); 104*121f4167SAsbjørn Sloth Tønnesen 105*121f4167SAsbjørn Sloth Tønnesen return 0; 106*121f4167SAsbjørn Sloth Tønnesen } 107