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 <string.h> 7 #include <stdlib.h> 8 #include <errno.h> 9 #include "containers.h" 10 #include "ipc.h" 11 12 struct string_list { 13 char *buffer; 14 size_t len; 15 size_t cap; 16 }; 17 18 static int string_list_add(struct string_list *list, const char *str) 19 { 20 size_t len = strlen(str) + 1; 21 22 if (len == 1) 23 return 0; 24 25 if (len >= list->cap - list->len) { 26 char *new_buffer; 27 size_t new_cap = list->cap * 2; 28 29 if (new_cap < list->len + len + 1) 30 new_cap = list->len + len + 1; 31 new_buffer = realloc(list->buffer, new_cap); 32 if (!new_buffer) 33 return -errno; 34 list->buffer = new_buffer; 35 list->cap = new_cap; 36 } 37 memcpy(list->buffer + list->len, str, len); 38 list->len += len; 39 list->buffer[list->len] = '\0'; 40 return 0; 41 } 42 43 #include "ipc-uapi.h" 44 #if defined(__linux__) 45 #include "ipc-linux.h" 46 #elif defined(__OpenBSD__) 47 #include "ipc-openbsd.h" 48 #elif defined(__FreeBSD__) 49 #include "ipc-freebsd.h" 50 #elif defined(_WIN32) 51 #include "ipc-windows.h" 52 #endif 53 54 /* first\0second\0third\0forth\0last\0\0 */ 55 char *ipc_list_devices(void) 56 { 57 struct string_list list = { 0 }; 58 int ret; 59 60 #ifdef IPC_SUPPORTS_KERNEL_INTERFACE 61 ret = kernel_get_wireguard_interfaces(&list); 62 if (ret < 0) 63 goto cleanup; 64 #endif 65 ret = userspace_get_wireguard_interfaces(&list); 66 if (ret < 0) 67 goto cleanup; 68 69 cleanup: 70 errno = -ret; 71 if (errno) { 72 free(list.buffer); 73 return NULL; 74 } 75 return list.buffer ?: strdup("\0"); 76 } 77 78 int ipc_get_device(struct wgdevice **dev, const char *iface) 79 { 80 #ifdef IPC_SUPPORTS_KERNEL_INTERFACE 81 if (userspace_has_wireguard_interface(iface)) 82 return userspace_get_device(dev, iface); 83 return kernel_get_device(dev, iface); 84 #else 85 return userspace_get_device(dev, iface); 86 #endif 87 } 88 89 int ipc_set_device(struct wgdevice *dev) 90 { 91 #ifdef IPC_SUPPORTS_KERNEL_INTERFACE 92 if (userspace_has_wireguard_interface(dev->name)) 93 return userspace_set_device(dev); 94 return kernel_set_device(dev); 95 #else 96 return userspace_set_device(dev); 97 #endif 98 } 99