// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2015-2020 Jason A. Donenfeld . All Rights Reserved. */ #include #include #include #include "containers.h" #include "ipc.h" struct string_list { char *buffer; size_t len; size_t cap; }; static int string_list_add(struct string_list *list, const char *str) { size_t len = strlen(str) + 1; if (len == 1) return 0; if (len >= list->cap - list->len) { char *new_buffer; size_t new_cap = list->cap * 2; if (new_cap < list->len + len + 1) new_cap = list->len + len + 1; new_buffer = realloc(list->buffer, new_cap); if (!new_buffer) return -errno; list->buffer = new_buffer; list->cap = new_cap; } memcpy(list->buffer + list->len, str, len); list->len += len; list->buffer[list->len] = '\0'; return 0; } #include "ipc-uapi.h" #if defined(__linux__) #include "ipc-linux.h" #elif defined(__OpenBSD__) #include "ipc-openbsd.h" #elif defined(__FreeBSD__) #include "ipc-freebsd.h" #elif defined(_WIN32) #include "ipc-windows.h" #endif /* first\0second\0third\0forth\0last\0\0 */ char *ipc_list_devices(void) { struct string_list list = { 0 }; int ret; #ifdef IPC_SUPPORTS_KERNEL_INTERFACE ret = kernel_get_wireguard_interfaces(&list); if (ret < 0) goto cleanup; #endif ret = userspace_get_wireguard_interfaces(&list); if (ret < 0) goto cleanup; cleanup: errno = -ret; if (errno) { free(list.buffer); return NULL; } return list.buffer ?: strdup("\0"); } int ipc_get_device(struct wgdevice **dev, const char *iface) { #ifdef IPC_SUPPORTS_KERNEL_INTERFACE if (userspace_has_wireguard_interface(iface)) return userspace_get_device(dev, iface); return kernel_get_device(dev, iface); #else return userspace_get_device(dev, iface); #endif } int ipc_set_device(struct wgdevice *dev) { #ifdef IPC_SUPPORTS_KERNEL_INTERFACE if (userspace_has_wireguard_interface(dev->name)) return userspace_set_device(dev); return kernel_set_device(dev); #else return userspace_set_device(dev); #endif }