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