From 66de01f21196befe6676cdd09c637224ff7f8851 Mon Sep 17 00:00:00 2001
From: Mark Puha
Date: Sat, 14 Jun 2025 15:02:32 +0200
Subject: [PATCH] fix: formatting
---
src/containers.h | 220 +++---
src/ipc-freebsd.h | 1007 ++++++++++++-------------
src/ipc-linux.h | 1368 ++++++++++++++++------------------
src/ipc-openbsd.h | 791 ++++++++++----------
src/ipc-uapi.h | 804 +++++++++-----------
src/ipc-windows.h | 1264 ++++++++++++++-----------------
src/netlink.h | 1119 +++++++++++++--------------
src/uapi/openbsd/net/if_wg.h | 129 ++--
src/uapi/windows/wireguard.h | 162 ++--
src/wg.c | 2 +-
10 files changed, 3170 insertions(+), 3696 deletions(-)
diff --git a/src/containers.h b/src/containers.h
index 376230e..9035c1a 100644
--- a/src/containers.h
+++ b/src/containers.h
@@ -6,13 +6,13 @@
#ifndef CONTAINERS_H
#define CONTAINERS_H
+#include
+#include
+#include
+#include
+#include
#include
#include
-#include
-#include
-#include
-#include
-#include
#if defined(__linux__)
#include
#elif defined(__OpenBSD__)
@@ -28,143 +28,127 @@
#endif
/* Cross platform __kernel_timespec */
-struct timespec64
-{
- int64_t tv_sec;
- int64_t tv_nsec;
+struct timespec64 {
+ int64_t tv_sec;
+ int64_t tv_nsec;
};
-struct wgallowedip
-{
- uint16_t family;
- union
- {
- struct in_addr ip4;
- struct in6_addr ip6;
- };
- uint8_t cidr;
- struct wgallowedip* next_allowedip;
+struct wgallowedip {
+ uint16_t family;
+ union {
+ struct in_addr ip4;
+ struct in6_addr ip6;
+ };
+ uint8_t cidr;
+ struct wgallowedip *next_allowedip;
};
-enum
-{
- WGPEER_REMOVE_ME = 1U << 0,
- WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
- WGPEER_HAS_PUBLIC_KEY = 1U << 2,
- WGPEER_HAS_PRESHARED_KEY = 1U << 3,
- WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4,
- WGPEER_HAS_ADVANCED_SECURITY = 1U << 5,
- WGPEER_HAS_SPECIAL_HANDSHAKE = 1U << 6
+enum {
+ WGPEER_REMOVE_ME = 1U << 0,
+ WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
+ WGPEER_HAS_PUBLIC_KEY = 1U << 2,
+ WGPEER_HAS_PRESHARED_KEY = 1U << 3,
+ WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4,
+ WGPEER_HAS_ADVANCED_SECURITY = 1U << 5,
+ WGPEER_HAS_SPECIAL_HANDSHAKE = 1U << 6
};
-struct wgpeer
-{
- uint32_t flags;
+struct wgpeer {
+ uint32_t flags;
- uint8_t public_key[WG_KEY_LEN];
- uint8_t preshared_key[WG_KEY_LEN];
+ uint8_t public_key[WG_KEY_LEN];
+ uint8_t preshared_key[WG_KEY_LEN];
- union
- {
- struct sockaddr addr;
- struct sockaddr_in addr4;
- struct sockaddr_in6 addr6;
- } endpoint;
+ union {
+ struct sockaddr addr;
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+ } endpoint;
- struct timespec64 last_handshake_time;
- uint64_t rx_bytes, tx_bytes;
- uint16_t persistent_keepalive_interval;
+ struct timespec64 last_handshake_time;
+ uint64_t rx_bytes, tx_bytes;
+ uint16_t persistent_keepalive_interval;
- bool advanced_security;
- bool special_handshake;
+ bool advanced_security;
+ bool special_handshake;
- struct wgallowedip *first_allowedip, *last_allowedip;
- struct wgpeer* next_peer;
+ struct wgallowedip *first_allowedip, *last_allowedip;
+ struct wgpeer *next_peer;
};
-enum
-{
- WGDEVICE_REPLACE_PEERS = 1U << 0,
- WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
- WGDEVICE_HAS_PUBLIC_KEY = 1U << 2,
- WGDEVICE_HAS_LISTEN_PORT = 1U << 3,
- WGDEVICE_HAS_FWMARK = 1U << 4,
- WGDEVICE_HAS_JC = 1U << 5,
- WGDEVICE_HAS_JMIN = 1U << 6,
- WGDEVICE_HAS_JMAX = 1U << 7,
- WGDEVICE_HAS_S1 = 1U << 8,
- WGDEVICE_HAS_S2 = 1U << 9,
- WGDEVICE_HAS_H1 = 1U << 10,
- WGDEVICE_HAS_H2 = 1U << 11,
- WGDEVICE_HAS_H3 = 1U << 12,
- WGDEVICE_HAS_H4 = 1U << 13,
- WGDEVICE_HAS_I1 = 1U << 14,
- WGDEVICE_HAS_I2 = 1U << 15,
- WGDEVICE_HAS_I3 = 1U << 16,
- WGDEVICE_HAS_I4 = 1U << 17,
- WGDEVICE_HAS_I5 = 1U << 18,
- WGDEVICE_HAS_J1 = 1U << 19,
- WGDEVICE_HAS_J2 = 1U << 20,
- WGDEVICE_HAS_J3 = 1U << 21,
- WGDEVICE_HAS_ITIME = 1U << 22
+enum {
+ WGDEVICE_REPLACE_PEERS = 1U << 0,
+ WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
+ WGDEVICE_HAS_PUBLIC_KEY = 1U << 2,
+ WGDEVICE_HAS_LISTEN_PORT = 1U << 3,
+ WGDEVICE_HAS_FWMARK = 1U << 4,
+ WGDEVICE_HAS_JC = 1U << 5,
+ WGDEVICE_HAS_JMIN = 1U << 6,
+ WGDEVICE_HAS_JMAX = 1U << 7,
+ WGDEVICE_HAS_S1 = 1U << 8,
+ WGDEVICE_HAS_S2 = 1U << 9,
+ WGDEVICE_HAS_H1 = 1U << 10,
+ WGDEVICE_HAS_H2 = 1U << 11,
+ WGDEVICE_HAS_H3 = 1U << 12,
+ WGDEVICE_HAS_H4 = 1U << 13,
+ WGDEVICE_HAS_I1 = 1U << 14,
+ WGDEVICE_HAS_I2 = 1U << 15,
+ WGDEVICE_HAS_I3 = 1U << 16,
+ WGDEVICE_HAS_I4 = 1U << 17,
+ WGDEVICE_HAS_I5 = 1U << 18,
+ WGDEVICE_HAS_J1 = 1U << 19,
+ WGDEVICE_HAS_J2 = 1U << 20,
+ WGDEVICE_HAS_J3 = 1U << 21,
+ WGDEVICE_HAS_ITIME = 1U << 22
};
-struct wgdevice
-{
- char name[IFNAMSIZ];
- uint32_t ifindex;
+struct wgdevice {
+ char name[IFNAMSIZ];
+ uint32_t ifindex;
- uint32_t flags;
+ uint32_t flags;
- uint8_t public_key[WG_KEY_LEN];
- uint8_t private_key[WG_KEY_LEN];
+ uint8_t public_key[WG_KEY_LEN];
+ uint8_t private_key[WG_KEY_LEN];
- uint32_t fwmark;
- uint16_t listen_port;
+ uint32_t fwmark;
+ uint16_t listen_port;
- struct wgpeer *first_peer, *last_peer;
+ struct wgpeer *first_peer, *last_peer;
- uint16_t junk_packet_count;
- uint16_t junk_packet_min_size;
- uint16_t junk_packet_max_size;
- uint16_t init_packet_junk_size;
- uint16_t response_packet_junk_size;
- uint32_t init_packet_magic_header;
- uint32_t response_packet_magic_header;
- uint32_t underload_packet_magic_header;
- uint32_t transport_packet_magic_header;
- char* i1;
- char* i2;
- char* i3;
- char* i4;
- char* i5;
- char* j1;
- char* j2;
- char* j3;
- uint32_t itime;
+ uint16_t junk_packet_count;
+ uint16_t junk_packet_min_size;
+ uint16_t junk_packet_max_size;
+ uint16_t init_packet_junk_size;
+ uint16_t response_packet_junk_size;
+ uint32_t init_packet_magic_header;
+ uint32_t response_packet_magic_header;
+ uint32_t underload_packet_magic_header;
+ uint32_t transport_packet_magic_header;
+ char* i1;
+ char* i2;
+ char* i3;
+ char* i4;
+ char* i5;
+ char* j1;
+ char* j2;
+ char* j3;
+ uint32_t itime;
};
-#define for_each_wgpeer(__dev, __peer) \
- for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer)
-#define for_each_wgallowedip(__peer, __allowedip) \
- for ((__allowedip) = (__peer)->first_allowedip; (__allowedip); \
- (__allowedip) = (__allowedip)->next_allowedip)
+#define for_each_wgpeer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer)
+#define for_each_wgallowedip(__peer, __allowedip) for ((__allowedip) = (__peer)->first_allowedip; (__allowedip); (__allowedip) = (__allowedip)->next_allowedip)
-static inline void free_wgdevice(struct wgdevice* dev)
+static inline void free_wgdevice(struct wgdevice *dev)
{
- if (!dev)
- return;
- for (struct wgpeer *peer = dev->first_peer, *np = peer ? peer->next_peer : NULL; peer;
- peer = np, np = peer ? peer->next_peer : NULL)
- {
- for (struct wgallowedip *allowedip = peer->first_allowedip,
- *na = allowedip ? allowedip->next_allowedip : NULL;
- allowedip;
- allowedip = na, na = allowedip ? allowedip->next_allowedip : NULL)
- free(allowedip);
- free(peer);
- }
- free(dev);
+ if (!dev)
+ return;
+ for (struct wgpeer *peer = dev->first_peer, *np = peer ? peer->next_peer : NULL; peer; peer = np, np = peer ? peer->next_peer : NULL) {
+ for (struct wgallowedip *allowedip = peer->first_allowedip, *na = allowedip ? allowedip->next_allowedip : NULL; allowedip; allowedip = na, na = allowedip ? allowedip->next_allowedip : NULL)
+ free(allowedip);
+ free(peer);
+ }
+ free(dev);
}
#endif
diff --git a/src/ipc-freebsd.h b/src/ipc-freebsd.h
index 7fe3b12..f07b5dd 100644
--- a/src/ipc-freebsd.h
+++ b/src/ipc-freebsd.h
@@ -5,485 +5,436 @@
*/
#include
-#include
#include
#include
+#include
#define IPC_SUPPORTS_KERNEL_INTERFACE
static int get_dgram_socket(void)
{
- static int sock = -1;
- if (sock < 0)
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- return sock;
+ static int sock = -1;
+ if (sock < 0)
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ return sock;
}
-static int kernel_get_wireguard_interfaces(struct string_list* list)
+static int kernel_get_wireguard_interfaces(struct string_list *list)
{
- struct ifgroupreq ifgr = {.ifgr_name = "wg"};
- struct ifg_req* ifg;
- int s = get_dgram_socket(), ret = 0;
+ struct ifgroupreq ifgr = { .ifgr_name = "wg" };
+ struct ifg_req *ifg;
+ int s = get_dgram_socket(), ret = 0;
- if (s < 0)
- return -errno;
+ if (s < 0)
+ return -errno;
- if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
- return errno == ENOENT ? 0 : -errno;
+ if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
+ return errno == ENOENT ? 0 : -errno;
- ifgr.ifgr_groups = calloc(1, ifgr.ifgr_len);
- if (!ifgr.ifgr_groups)
- return -errno;
- if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
- {
- ret = -errno;
- goto out;
- }
+ ifgr.ifgr_groups = calloc(1, ifgr.ifgr_len);
+ if (!ifgr.ifgr_groups)
+ return -errno;
+ if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0) {
+ ret = -errno;
+ goto out;
+ }
- for (ifg = ifgr.ifgr_groups; ifg && ifgr.ifgr_len > 0; ++ifg)
- {
- if ((ret = string_list_add(list, ifg->ifgrq_member)) < 0)
- goto out;
- ifgr.ifgr_len -= sizeof(struct ifg_req);
- }
+ for (ifg = ifgr.ifgr_groups; ifg && ifgr.ifgr_len > 0; ++ifg) {
+ if ((ret = string_list_add(list, ifg->ifgrq_member)) < 0)
+ goto out;
+ ifgr.ifgr_len -= sizeof(struct ifg_req);
+ }
out:
- free(ifgr.ifgr_groups);
- return ret;
+ free(ifgr.ifgr_groups);
+ return ret;
}
-static int kernel_get_device(struct wgdevice** device, const char* ifname)
+static int kernel_get_device(struct wgdevice **device, const char *ifname)
{
- struct wg_data_io wgd = {0};
- nvlist_t* nvl_device = NULL;
- const nvlist_t* const* nvl_peers;
- struct wgdevice* dev = NULL;
- size_t size, peer_count, i;
- uint64_t number;
- const void* binary;
- int ret = 0, s;
+ struct wg_data_io wgd = { 0 };
+ nvlist_t *nvl_device = NULL;
+ const nvlist_t *const *nvl_peers;
+ struct wgdevice *dev = NULL;
+ size_t size, peer_count, i;
+ uint64_t number;
+ const void *binary;
+ int ret = 0, s;
- *device = NULL;
- s = get_dgram_socket();
- if (s < 0)
- goto err;
+ *device = NULL;
+ s = get_dgram_socket();
+ if (s < 0)
+ goto err;
- strlcpy(wgd.wgd_name, ifname, sizeof(wgd.wgd_name));
- if (ioctl(s, SIOCGWG, &wgd) < 0)
- goto err;
+ strlcpy(wgd.wgd_name, ifname, sizeof(wgd.wgd_name));
+ if (ioctl(s, SIOCGWG, &wgd) < 0)
+ goto err;
- wgd.wgd_data = malloc(wgd.wgd_size);
- if (!wgd.wgd_data)
- goto err;
- if (ioctl(s, SIOCGWG, &wgd) < 0)
- goto err;
+ wgd.wgd_data = malloc(wgd.wgd_size);
+ if (!wgd.wgd_data)
+ goto err;
+ if (ioctl(s, SIOCGWG, &wgd) < 0)
+ goto err;
- dev = calloc(1, sizeof(*dev));
- if (!dev)
- goto err;
- strlcpy(dev->name, ifname, sizeof(dev->name));
- nvl_device = nvlist_unpack(wgd.wgd_data, wgd.wgd_size, 0);
- if (!nvl_device)
- goto err;
+ dev = calloc(1, sizeof(*dev));
+ if (!dev)
+ goto err;
+ strlcpy(dev->name, ifname, sizeof(dev->name));
+ nvl_device = nvlist_unpack(wgd.wgd_data, wgd.wgd_size, 0);
+ if (!nvl_device)
+ goto err;
- if (nvlist_exists_number(nvl_device, "listen-port"))
- {
- number = nvlist_get_number(nvl_device, "listen-port");
- if (number <= UINT16_MAX)
- {
- dev->listen_port = number;
- dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
- }
- }
- if (nvlist_exists_number(nvl_device, "jc"))
- {
- number = nvlist_get_number(nvl_device, "jc");
- if (number <= UINT16_MAX)
- {
- dev->junk_packet_count = number;
- dev->flags |= WGDEVICE_HAS_JC;
- }
- }
- if (nvlist_exists_number(nvl_device, "jmin"))
- {
- number = nvlist_get_number(nvl_device, "jmin");
- if (number <= UINT16_MAX)
- {
- dev->junk_packet_min_size = number;
- dev->flags |= WGDEVICE_HAS_JMIN;
- }
- }
- if (nvlist_exists_number(nvl_device, "jmax"))
- {
- number = nvlist_get_number(nvl_device, "jmax");
- if (number <= UINT16_MAX)
- {
- dev->junk_packet_max_size = number;
- dev->flags |= WGDEVICE_HAS_JMAX;
- }
- }
- if (nvlist_exists_number(nvl_device, "s1"))
- {
- number = nvlist_get_number(nvl_device, "s1");
- if (number <= UINT16_MAX)
- {
- dev->init_packet_junk_size = number;
- dev->flags |= WGDEVICE_HAS_S1;
- }
- }
- if (nvlist_exists_number(nvl_device, "s2"))
- {
- number = nvlist_get_number(nvl_device, "s2");
- if (number <= UINT16_MAX)
- {
- dev->response_packet_junk_size = number;
- dev->flags |= WGDEVICE_HAS_S2;
- }
- }
- if (nvlist_exists_number(nvl_device, "h1"))
- {
- number = nvlist_get_number(nvl_device, "h1");
- if (number <= UINT32_MAX)
- {
- dev->init_packet_magic_header = number;
- dev->flags |= WGDEVICE_HAS_H1;
- }
- }
- if (nvlist_exists_number(nvl_device, "h2"))
- {
- number = nvlist_get_number(nvl_device, "h2");
- if (number <= UINT32_MAX)
- {
- dev->response_packet_magic_header = number;
- dev->flags |= WGDEVICE_HAS_H2;
- }
- }
- if (nvlist_exists_number(nvl_device, "h3"))
- {
- number = nvlist_get_number(nvl_device, "h3");
- if (number <= UINT32_MAX)
- {
- dev->underload_packet_magic_header = number;
- dev->flags |= WGDEVICE_HAS_H3;
- }
- }
- if (nvlist_exists_number(nvl_device, "h4"))
- {
- number = nvlist_get_number(nvl_device, "h4");
- if (number <= UINT32_MAX)
- {
- dev->transport_packet_magic_header = number;
- dev->flags |= WGDEVICE_HAS_H4;
- }
- }
- if (nvlist_exists_binary(nvl_device, "i1"))
- {
- binary = nvlist_get_binary(nvl_device, "i1", &size);
- if (binary && size < MAX_AWG_JUNK_LEN)
- {
- dev->i1 = strdup((const char*)binary);
- dev->flags |= WGDEVICE_HAS_I1;
- }
- }
- if (nvlist_exists_binary(nvl_device, "i2"))
- {
- binary = nvlist_get_binary(nvl_device, "i2", &size);
- if (binary && size < MAX_AWG_JUNK_LEN)
- {
- dev->i2 = strdup((const char*)binary);
- dev->flags |= WGDEVICE_HAS_I2;
- }
- }
- if (nvlist_exists_binary(nvl_device, "i3"))
- {
- binary = nvlist_get_binary(nvl_device, "i3", &size);
- if (binary && size < MAX_AWG_JUNK_LEN)
- {
- dev->i3 = strdup((const char*)binary);
- dev->flags |= WGDEVICE_HAS_I3;
- }
- }
- if (nvlist_exists_binary(nvl_device, "i4"))
- {
- binary = nvlist_get_binary(nvl_device, "i4", &size);
- if (binary && size < MAX_AWG_JUNK_LEN)
- {
- dev->i4 = strdup((const char*)binary);
- dev->flags |= WGDEVICE_HAS_I4;
- }
- }
- if (nvlist_exists_binary(nvl_device, "i5"))
- {
- binary = nvlist_get_binary(nvl_device, "i5", &size);
- if (binary && size < MAX_AWG_JUNK_LEN)
- {
- dev->i5 = strdup((const char*)binary);
- dev->flags |= WGDEVICE_HAS_I5;
- }
- }
- if (nvlist_exists_binary(nvl_device, "j1"))
- {
- binary = nvlist_get_binary(nvl_device, "j1", &size);
- if (binary && size < MAX_AWG_JUNK_LEN)
- {
- dev->j1 = strdup((const char*)binary);
- dev->flags |= WGDEVICE_HAS_J1;
- }
- }
- if (nvlist_exists_binary(nvl_device, "j2"))
- {
- binary = nvlist_get_binary(nvl_device, "j2", &size);
- if (binary && size < MAX_AWG_JUNK_LEN)
- {
- dev->j2 = strdup((const char*)binary);
- dev->flags |= WGDEVICE_HAS_J2;
- }
- }
- if (nvlist_exists_binary(nvl_device, "j3"))
- {
- binary = nvlist_get_binary(nvl_device, "j3", &size);
- if (binary && size < MAX_AWG_JUNK_LEN)
- {
- dev->j3 = strdup((const char*)binary);
- dev->flags |= WGDEVICE_HAS_J3;
- }
- }
- if (nvlist_exists_binary(nvl_device, "itime"))
- {
- number = nvlist_get_number(nvl_device, "itime");
- if (number <= UINT32_MAX)
- {
- dev->itime = number;
- dev->flags |= WGDEVICE_HAS_ITIME;
- }
- }
+ if (nvlist_exists_number(nvl_device, "listen-port")) {
+ number = nvlist_get_number(nvl_device, "listen-port");
+ if (number <= UINT16_MAX) {
+ dev->listen_port = number;
+ dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "jc")) {
+ number = nvlist_get_number(nvl_device, "jc");
+ if (number <= UINT16_MAX){
+ dev->junk_packet_count = number;
+ dev->flags |= WGDEVICE_HAS_JC;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "jmin")) {
+ number = nvlist_get_number(nvl_device, "jmin");
+ if (number <= UINT16_MAX){
+ dev->junk_packet_min_size = number;
+ dev->flags |= WGDEVICE_HAS_JMIN;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "jmax")) {
+ number = nvlist_get_number(nvl_device, "jmax");
+ if (number <= UINT16_MAX){
+ dev->junk_packet_max_size = number;
+ dev->flags |= WGDEVICE_HAS_JMAX;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "s1")) {
+ number = nvlist_get_number(nvl_device, "s1");
+ if (number <= UINT16_MAX){
+ dev->init_packet_junk_size = number;
+ dev->flags |= WGDEVICE_HAS_S1;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "s2")) {
+ number = nvlist_get_number(nvl_device, "s2");
+ if (number <= UINT16_MAX){
+ dev->response_packet_junk_size = number;
+ dev->flags |= WGDEVICE_HAS_S2;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "h1")) {
+ number = nvlist_get_number(nvl_device, "h1");
+ if (number <= UINT32_MAX){
+ dev->init_packet_magic_header = number;
+ dev->flags |= WGDEVICE_HAS_H1;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "h2")) {
+ number = nvlist_get_number(nvl_device, "h2");
+ if (number <= UINT32_MAX){
+ dev->response_packet_magic_header = number;
+ dev->flags |= WGDEVICE_HAS_H2;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "h3")) {
+ number = nvlist_get_number(nvl_device, "h3");
+ if (number <= UINT32_MAX){
+ dev->underload_packet_magic_header = number;
+ dev->flags |= WGDEVICE_HAS_H3;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "h4")) {
+ number = nvlist_get_number(nvl_device, "h4");
+ if (number <= UINT32_MAX){
+ dev->transport_packet_magic_header = number;
+ dev->flags |= WGDEVICE_HAS_H4;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "i1"))
+ {
+ binary = nvlist_get_binary(nvl_device, "i1", &size);
+ if (binary && size < MAX_AWG_JUNK_LEN)
+ {
+ dev->i1 = strdup((const char*)binary);
+ dev->flags |= WGDEVICE_HAS_I1;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "i2"))
+ {
+ binary = nvlist_get_binary(nvl_device, "i2", &size);
+ if (binary && size < MAX_AWG_JUNK_LEN)
+ {
+ dev->i2 = strdup((const char*)binary);
+ dev->flags |= WGDEVICE_HAS_I2;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "i3"))
+ {
+ binary = nvlist_get_binary(nvl_device, "i3", &size);
+ if (binary && size < MAX_AWG_JUNK_LEN)
+ {
+ dev->i3 = strdup((const char*)binary);
+ dev->flags |= WGDEVICE_HAS_I3;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "i4"))
+ {
+ binary = nvlist_get_binary(nvl_device, "i4", &size);
+ if (binary && size < MAX_AWG_JUNK_LEN)
+ {
+ dev->i4 = strdup((const char*)binary);
+ dev->flags |= WGDEVICE_HAS_I4;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "i5"))
+ {
+ binary = nvlist_get_binary(nvl_device, "i5", &size);
+ if (binary && size < MAX_AWG_JUNK_LEN)
+ {
+ dev->i5 = strdup((const char*)binary);
+ dev->flags |= WGDEVICE_HAS_I5;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "j1"))
+ {
+ binary = nvlist_get_binary(nvl_device, "j1", &size);
+ if (binary && size < MAX_AWG_JUNK_LEN)
+ {
+ dev->j1 = strdup((const char*)binary);
+ dev->flags |= WGDEVICE_HAS_J1;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "j2"))
+ {
+ binary = nvlist_get_binary(nvl_device, "j2", &size);
+ if (binary && size < MAX_AWG_JUNK_LEN)
+ {
+ dev->j2 = strdup((const char*)binary);
+ dev->flags |= WGDEVICE_HAS_J2;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "j3"))
+ {
+ binary = nvlist_get_binary(nvl_device, "j3", &size);
+ if (binary && size < MAX_AWG_JUNK_LEN)
+ {
+ dev->j3 = strdup((const char*)binary);
+ dev->flags |= WGDEVICE_HAS_J3;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "itime"))
+ {
+ number = nvlist_get_number(nvl_device, "itime");
+ if (number <= UINT32_MAX)
+ {
+ dev->itime = number;
+ dev->flags |= WGDEVICE_HAS_ITIME;
+ }
+ }
- if (nvlist_exists_number(nvl_device, "user-cookie"))
- {
- number = nvlist_get_number(nvl_device, "user-cookie");
- if (number <= UINT32_MAX)
- {
- dev->fwmark = number;
- dev->flags |= WGDEVICE_HAS_FWMARK;
- }
- }
- if (nvlist_exists_binary(nvl_device, "public-key"))
- {
- binary = nvlist_get_binary(nvl_device, "public-key", &size);
- if (binary && size == sizeof(dev->public_key))
- {
- memcpy(dev->public_key, binary, sizeof(dev->public_key));
- dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
- }
- }
- if (nvlist_exists_binary(nvl_device, "private-key"))
- {
- binary = nvlist_get_binary(nvl_device, "private-key", &size);
- if (binary && size == sizeof(dev->private_key))
- {
- memcpy(dev->private_key, binary, sizeof(dev->private_key));
- dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
- }
- }
- if (!nvlist_exists_nvlist_array(nvl_device, "peers"))
- goto skip_peers;
- nvl_peers = nvlist_get_nvlist_array(nvl_device, "peers", &peer_count);
- if (!nvl_peers)
- goto skip_peers;
- for (i = 0; i < peer_count; ++i)
- {
- struct wgpeer* peer;
- struct wgallowedip* aip = NULL;
- const nvlist_t* const* nvl_aips;
- size_t aip_count, j;
+ if (nvlist_exists_number(nvl_device, "user-cookie")) {
+ number = nvlist_get_number(nvl_device, "user-cookie");
+ if (number <= UINT32_MAX) {
+ dev->fwmark = number;
+ dev->flags |= WGDEVICE_HAS_FWMARK;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "public-key")) {
+ binary = nvlist_get_binary(nvl_device, "public-key", &size);
+ if (binary && size == sizeof(dev->public_key)) {
+ memcpy(dev->public_key, binary, sizeof(dev->public_key));
+ dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
+ }
+ }
+ if (nvlist_exists_binary(nvl_device, "private-key")) {
+ binary = nvlist_get_binary(nvl_device, "private-key", &size);
+ if (binary && size == sizeof(dev->private_key)) {
+ memcpy(dev->private_key, binary, sizeof(dev->private_key));
+ dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
+ }
+ }
+ if (!nvlist_exists_nvlist_array(nvl_device, "peers"))
+ goto skip_peers;
+ nvl_peers = nvlist_get_nvlist_array(nvl_device, "peers", &peer_count);
+ if (!nvl_peers)
+ goto skip_peers;
+ for (i = 0; i < peer_count; ++i) {
+ struct wgpeer *peer;
+ struct wgallowedip *aip = NULL;
+ const nvlist_t *const *nvl_aips;
+ size_t aip_count, j;
- peer = calloc(1, sizeof(*peer));
- if (!peer)
- goto err_peer;
- if (nvlist_exists_binary(nvl_peers[i], "public-key"))
- {
- binary = nvlist_get_binary(nvl_peers[i], "public-key", &size);
- if (binary && size == sizeof(peer->public_key))
- {
- memcpy(peer->public_key, binary, sizeof(peer->public_key));
- peer->flags |= WGPEER_HAS_PUBLIC_KEY;
- }
- }
- if (nvlist_exists_binary(nvl_peers[i], "preshared-key"))
- {
- binary = nvlist_get_binary(nvl_peers[i], "preshared-key", &size);
- if (binary && size == sizeof(peer->preshared_key))
- {
- memcpy(peer->preshared_key, binary, sizeof(peer->preshared_key));
- if (!key_is_zero(peer->preshared_key))
- peer->flags |= WGPEER_HAS_PRESHARED_KEY;
- }
- }
- if (nvlist_exists_number(nvl_peers[i], "persistent-keepalive-interval"))
- {
- number = nvlist_get_number(nvl_peers[i], "persistent-keepalive-interval");
- if (number <= UINT16_MAX)
- {
- peer->persistent_keepalive_interval = number;
- peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
- }
- }
- if (nvlist_exists_binary(nvl_peers[i], "endpoint"))
- {
- const struct sockaddr* endpoint =
- nvlist_get_binary(nvl_peers[i], "endpoint", &size);
- if (endpoint && size <= sizeof(peer->endpoint) &&
- size >= sizeof(peer->endpoint.addr) &&
- (endpoint->sa_family == AF_INET || endpoint->sa_family == AF_INET6))
- memcpy(&peer->endpoint.addr, endpoint, size);
- }
- if (nvlist_exists_number(nvl_peers[i], "rx-bytes"))
- peer->rx_bytes = nvlist_get_number(nvl_peers[i], "rx-bytes");
- if (nvlist_exists_number(nvl_peers[i], "tx-bytes"))
- peer->tx_bytes = nvlist_get_number(nvl_peers[i], "tx-bytes");
- if (nvlist_exists_binary(nvl_peers[i], "last-handshake-time"))
- {
- binary = nvlist_get_binary(nvl_peers[i], "last-handshake-time", &size);
- if (binary && size == sizeof(peer->last_handshake_time))
- memcpy(
- &peer->last_handshake_time,
- binary,
- sizeof(peer->last_handshake_time));
- }
+ peer = calloc(1, sizeof(*peer));
+ if (!peer)
+ goto err_peer;
+ if (nvlist_exists_binary(nvl_peers[i], "public-key")) {
+ binary = nvlist_get_binary(nvl_peers[i], "public-key", &size);
+ if (binary && size == sizeof(peer->public_key)) {
+ memcpy(peer->public_key, binary, sizeof(peer->public_key));
+ peer->flags |= WGPEER_HAS_PUBLIC_KEY;
+ }
+ }
+ if (nvlist_exists_binary(nvl_peers[i], "preshared-key")) {
+ binary = nvlist_get_binary(nvl_peers[i], "preshared-key", &size);
+ if (binary && size == sizeof(peer->preshared_key)) {
+ memcpy(peer->preshared_key, binary, sizeof(peer->preshared_key));
+ if (!key_is_zero(peer->preshared_key))
+ peer->flags |= WGPEER_HAS_PRESHARED_KEY;
+ }
+ }
+ if (nvlist_exists_number(nvl_peers[i], "persistent-keepalive-interval")) {
+ number = nvlist_get_number(nvl_peers[i], "persistent-keepalive-interval");
+ if (number <= UINT16_MAX) {
+ peer->persistent_keepalive_interval = number;
+ peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
+ }
+ }
+ if (nvlist_exists_binary(nvl_peers[i], "endpoint")) {
+ const struct sockaddr *endpoint = nvlist_get_binary(nvl_peers[i], "endpoint", &size);
+ if (endpoint && size <= sizeof(peer->endpoint) && size >= sizeof(peer->endpoint.addr) &&
+ (endpoint->sa_family == AF_INET || endpoint->sa_family == AF_INET6))
+ memcpy(&peer->endpoint.addr, endpoint, size);
+ }
+ if (nvlist_exists_number(nvl_peers[i], "rx-bytes"))
+ peer->rx_bytes = nvlist_get_number(nvl_peers[i], "rx-bytes");
+ if (nvlist_exists_number(nvl_peers[i], "tx-bytes"))
+ peer->tx_bytes = nvlist_get_number(nvl_peers[i], "tx-bytes");
+ if (nvlist_exists_binary(nvl_peers[i], "last-handshake-time")) {
+ binary = nvlist_get_binary(nvl_peers[i], "last-handshake-time", &size);
+ if (binary && size == sizeof(peer->last_handshake_time))
+ memcpy(&peer->last_handshake_time, binary, sizeof(peer->last_handshake_time));
+ }
- if (!nvlist_exists_nvlist_array(nvl_peers[i], "allowed-ips"))
- goto skip_allowed_ips;
- nvl_aips = nvlist_get_nvlist_array(nvl_peers[i], "allowed-ips", &aip_count);
- if (!aip_count || !nvl_aips)
- goto skip_allowed_ips;
- for (j = 0; j < aip_count; ++j)
- {
- if (!nvlist_exists_number(nvl_aips[j], "cidr"))
- continue;
- if (!nvlist_exists_binary(nvl_aips[j], "ipv4") &&
- !nvlist_exists_binary(nvl_aips[j], "ipv6"))
- continue;
- aip = calloc(1, sizeof(*aip));
- if (!aip)
- goto err_allowed_ips;
- number = nvlist_get_number(nvl_aips[j], "cidr");
- if (nvlist_exists_binary(nvl_aips[j], "ipv4"))
- {
- binary = nvlist_get_binary(nvl_aips[j], "ipv4", &size);
- if (!binary || number > 32)
- {
- ret = EINVAL;
- goto err_allowed_ips;
- }
- aip->family = AF_INET;
- aip->cidr = number;
- memcpy(&aip->ip4, binary, sizeof(aip->ip4));
- }
- else
- {
- assert(nvlist_exists_binary(nvl_aips[j], "ipv6"));
- binary = nvlist_get_binary(nvl_aips[j], "ipv6", &size);
- if (!binary || number > 128)
- {
- ret = EINVAL;
- goto err_allowed_ips;
- }
- aip->family = AF_INET6;
- aip->cidr = number;
- memcpy(&aip->ip6, binary, sizeof(aip->ip6));
- }
+ if (!nvlist_exists_nvlist_array(nvl_peers[i], "allowed-ips"))
+ goto skip_allowed_ips;
+ nvl_aips = nvlist_get_nvlist_array(nvl_peers[i], "allowed-ips", &aip_count);
+ if (!aip_count || !nvl_aips)
+ goto skip_allowed_ips;
+ for (j = 0; j < aip_count; ++j) {
+ if (!nvlist_exists_number(nvl_aips[j], "cidr"))
+ continue;
+ if (!nvlist_exists_binary(nvl_aips[j], "ipv4") && !nvlist_exists_binary(nvl_aips[j], "ipv6"))
+ continue;
+ aip = calloc(1, sizeof(*aip));
+ if (!aip)
+ goto err_allowed_ips;
+ number = nvlist_get_number(nvl_aips[j], "cidr");
+ if (nvlist_exists_binary(nvl_aips[j], "ipv4")) {
+ binary = nvlist_get_binary(nvl_aips[j], "ipv4", &size);
+ if (!binary || number > 32) {
+ ret = EINVAL;
+ goto err_allowed_ips;
+ }
+ aip->family = AF_INET;
+ aip->cidr = number;
+ memcpy(&aip->ip4, binary, sizeof(aip->ip4));
+ } else {
+ assert(nvlist_exists_binary(nvl_aips[j], "ipv6"));
+ binary = nvlist_get_binary(nvl_aips[j], "ipv6", &size);
+ if (!binary || number > 128) {
+ ret = EINVAL;
+ goto err_allowed_ips;
+ }
+ aip->family = AF_INET6;
+ aip->cidr = number;
+ memcpy(&aip->ip6, binary, sizeof(aip->ip6));
+ }
- if (!peer->first_allowedip)
- peer->first_allowedip = aip;
- else
- peer->last_allowedip->next_allowedip = aip;
- peer->last_allowedip = aip;
- aip = NULL;
- continue;
+ if (!peer->first_allowedip)
+ peer->first_allowedip = aip;
+ else
+ peer->last_allowedip->next_allowedip = aip;
+ peer->last_allowedip = aip;
+ aip = NULL;
+ continue;
- err_allowed_ips:
- if (!ret)
- ret = -errno;
- free(aip);
- goto err_peer;
- }
+ err_allowed_ips:
+ if (!ret)
+ ret = -errno;
+ free(aip);
+ goto err_peer;
+ }
- /* Nothing leaked, hopefully -- ownership transferred or aip freed. */
- assert(aip == NULL);
- skip_allowed_ips:
- if (!dev->first_peer)
- dev->first_peer = peer;
- else
- dev->last_peer->next_peer = peer;
- dev->last_peer = peer;
- continue;
+ /* Nothing leaked, hopefully -- ownership transferred or aip freed. */
+ assert(aip == NULL);
+ skip_allowed_ips:
+ if (!dev->first_peer)
+ dev->first_peer = peer;
+ else
+ dev->last_peer->next_peer = peer;
+ dev->last_peer = peer;
+ continue;
- err_peer:
- if (!ret)
- ret = -errno;
- free(peer);
- goto err;
- }
+ err_peer:
+ if (!ret)
+ ret = -errno;
+ free(peer);
+ goto err;
+ }
skip_peers:
- free(wgd.wgd_data);
- nvlist_destroy(nvl_device);
- *device = dev;
- return 0;
+ free(wgd.wgd_data);
+ nvlist_destroy(nvl_device);
+ *device = dev;
+ return 0;
err:
- if (!ret)
- ret = -errno;
- free(wgd.wgd_data);
- nvlist_destroy(nvl_device);
- free(dev);
- return ret;
+ if (!ret)
+ ret = -errno;
+ free(wgd.wgd_data);
+ nvlist_destroy(nvl_device);
+ free(dev);
+ return ret;
}
-static int kernel_set_device(struct wgdevice* dev)
+
+static int kernel_set_device(struct wgdevice *dev)
{
- struct wg_data_io wgd = {0};
- nvlist_t * nvl_device = NULL, **nvl_peers = NULL;
- size_t peer_count = 0, i = 0;
- struct wgpeer* peer;
- int ret = 0, s;
+ struct wg_data_io wgd = { 0 };
+ nvlist_t *nvl_device = NULL, **nvl_peers = NULL;
+ size_t peer_count = 0, i = 0;
+ struct wgpeer *peer;
+ int ret = 0, s;
- strlcpy(wgd.wgd_name, dev->name, sizeof(wgd.wgd_name));
+ strlcpy(wgd.wgd_name, dev->name, sizeof(wgd.wgd_name));
- nvl_device = nvlist_create(0);
- if (!nvl_device)
- goto err;
+ nvl_device = nvlist_create(0);
+ if (!nvl_device)
+ goto err;
- for_each_wgpeer(dev, peer)++ peer_count;
- if (peer_count)
- {
- nvl_peers = calloc(peer_count, sizeof(*nvl_peers));
- if (!nvl_peers)
- goto err;
- }
- if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
- nvlist_add_binary(
- nvl_device, "private-key", dev->private_key, sizeof(dev->private_key));
- if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
- nvlist_add_number(nvl_device, "listen-port", dev->listen_port);
- if (dev->flags & WGDEVICE_HAS_JC)
- nvlist_add_number(nvl_device, "jc", dev->junk_packet_count);
- if (dev->flags & WGDEVICE_HAS_JMIN)
- nvlist_add_number(nvl_device, "jmin", dev->junk_packet_min_size);
- if (dev->flags & WGDEVICE_HAS_JMAX)
- nvlist_add_number(nvl_device, "jmax", dev->junk_packet_max_size);
- if (dev->flags & WGDEVICE_HAS_S1)
- nvlist_add_number(nvl_device, "s1", dev->init_packet_junk_size);
- if (dev->flags & WGDEVICE_HAS_S2)
- nvlist_add_number(nvl_device, "s2", dev->response_packet_junk_size);
- if (dev->flags & WGDEVICE_HAS_H1)
- nvlist_add_number(nvl_device, "h1", dev->init_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H2)
- nvlist_add_number(nvl_device, "h2", dev->response_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H3)
- nvlist_add_number(nvl_device, "h3", dev->underload_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H4)
- nvlist_add_number(nvl_device, "h4", dev->transport_packet_magic_header);
+ for_each_wgpeer(dev, peer)
+ ++peer_count;
+ if (peer_count) {
+ nvl_peers = calloc(peer_count, sizeof(*nvl_peers));
+ if (!nvl_peers)
+ goto err;
+ }
+ if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
+ nvlist_add_binary(nvl_device, "private-key", dev->private_key, sizeof(dev->private_key));
+ if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
+ nvlist_add_number(nvl_device, "listen-port", dev->listen_port);
+ if (dev->flags & WGDEVICE_HAS_JC)
+ nvlist_add_number(nvl_device, "jc", dev->junk_packet_count);
+ if (dev->flags & WGDEVICE_HAS_JMIN)
+ nvlist_add_number(nvl_device, "jmin", dev->junk_packet_min_size);
+ if (dev->flags & WGDEVICE_HAS_JMAX)
+ nvlist_add_number(nvl_device, "jmax", dev->junk_packet_max_size);
+ if (dev->flags & WGDEVICE_HAS_S1)
+ nvlist_add_number(nvl_device, "s1", dev->init_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_S2)
+ nvlist_add_number(nvl_device, "s2", dev->response_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_H1)
+ nvlist_add_number(nvl_device, "h1", dev->init_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H2)
+ nvlist_add_number(nvl_device, "h2", dev->response_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H3)
+ nvlist_add_number(nvl_device, "h3", dev->underload_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H4)
+ nvlist_add_number(nvl_device, "h4", dev->transport_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_I1)
nvlist_add_binary(nvl_device, "i1", dev->i1, strlen(dev->i1) + 1);
if (dev->flags & WGDEVICE_HAS_I2)
@@ -502,109 +453,89 @@ static int kernel_set_device(struct wgdevice* dev)
nvlist_add_binary(nvl_device, "j3", dev->j3, strlen(dev->j3) + 1);
if (dev->flags & WGDEVICE_HAS_ITIME)
nvlist_add_number(nvl_device, "itime", dev->itime);
+ if (dev->flags & WGDEVICE_HAS_FWMARK)
+ nvlist_add_number(nvl_device, "user-cookie", dev->fwmark);
+ if (dev->flags & WGDEVICE_REPLACE_PEERS)
+ nvlist_add_bool(nvl_device, "replace-peers", true);
- if (dev->flags & WGDEVICE_HAS_FWMARK)
- nvlist_add_number(nvl_device, "user-cookie", dev->fwmark);
- if (dev->flags & WGDEVICE_REPLACE_PEERS)
- nvlist_add_bool(nvl_device, "replace-peers", true);
+ for_each_wgpeer(dev, peer) {
+ size_t aip_count = 0, j = 0;
+ nvlist_t **nvl_aips = NULL;
+ struct wgallowedip *aip;
- for_each_wgpeer(dev, peer)
- {
- size_t aip_count = 0, j = 0;
- nvlist_t** nvl_aips = NULL;
- struct wgallowedip* aip;
+ nvl_peers[i] = nvlist_create(0);
+ if (!nvl_peers[i])
+ goto err_peer;
+ for_each_wgallowedip(peer, aip)
+ ++aip_count;
+ if (aip_count) {
+ nvl_aips = calloc(aip_count, sizeof(*nvl_aips));
+ if (!nvl_aips)
+ goto err_peer;
+ }
+ nvlist_add_binary(nvl_peers[i], "public-key", peer->public_key, sizeof(peer->public_key));
+ if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
+ nvlist_add_binary(nvl_peers[i], "preshared-key", peer->preshared_key, sizeof(peer->preshared_key));
+ if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
+ nvlist_add_number(nvl_peers[i], "persistent-keepalive-interval", peer->persistent_keepalive_interval);
+ if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
+ nvlist_add_binary(nvl_peers[i], "endpoint", &peer->endpoint.addr, peer->endpoint.addr.sa_len);
+ if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
+ nvlist_add_bool(nvl_peers[i], "replace-allowedips", true);
+ if (peer->flags & WGPEER_REMOVE_ME)
+ nvlist_add_bool(nvl_peers[i], "remove", true);
+ for_each_wgallowedip(peer, aip) {
+ nvl_aips[j] = nvlist_create(0);
+ if (!nvl_aips[j])
+ goto err_peer;
+ nvlist_add_number(nvl_aips[j], "cidr", aip->cidr);
+ if (aip->family == AF_INET)
+ nvlist_add_binary(nvl_aips[j], "ipv4", &aip->ip4, sizeof(aip->ip4));
+ else if (aip->family == AF_INET6)
+ nvlist_add_binary(nvl_aips[j], "ipv6", &aip->ip6, sizeof(aip->ip6));
+ ++j;
+ }
+ if (j) {
+ nvlist_add_nvlist_array(nvl_peers[i], "allowed-ips", (const nvlist_t *const *)nvl_aips, j);
+ for (j = 0; j < aip_count; ++j)
+ nvlist_destroy(nvl_aips[j]);
+ free(nvl_aips);
+ }
+ ++i;
+ continue;
- nvl_peers[i] = nvlist_create(0);
- if (!nvl_peers[i])
- goto err_peer;
- for_each_wgallowedip(peer, aip)++ aip_count;
- if (aip_count)
- {
- nvl_aips = calloc(aip_count, sizeof(*nvl_aips));
- if (!nvl_aips)
- goto err_peer;
- }
- nvlist_add_binary(
- nvl_peers[i], "public-key", peer->public_key, sizeof(peer->public_key));
- if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
- nvlist_add_binary(
- nvl_peers[i],
- "preshared-key",
- peer->preshared_key,
- sizeof(peer->preshared_key));
- if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
- nvlist_add_number(
- nvl_peers[i],
- "persistent-keepalive-interval",
- peer->persistent_keepalive_interval);
- if (peer->endpoint.addr.sa_family == AF_INET ||
- peer->endpoint.addr.sa_family == AF_INET6)
- nvlist_add_binary(
- nvl_peers[i],
- "endpoint",
- &peer->endpoint.addr,
- peer->endpoint.addr.sa_len);
- if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
- nvlist_add_bool(nvl_peers[i], "replace-allowedips", true);
- if (peer->flags & WGPEER_REMOVE_ME)
- nvlist_add_bool(nvl_peers[i], "remove", true);
- for_each_wgallowedip(peer, aip)
- {
- nvl_aips[j] = nvlist_create(0);
- if (!nvl_aips[j])
- goto err_peer;
- nvlist_add_number(nvl_aips[j], "cidr", aip->cidr);
- if (aip->family == AF_INET)
- nvlist_add_binary(nvl_aips[j], "ipv4", &aip->ip4, sizeof(aip->ip4));
- else if (aip->family == AF_INET6)
- nvlist_add_binary(nvl_aips[j], "ipv6", &aip->ip6, sizeof(aip->ip6));
- ++j;
- }
- if (j)
- {
- nvlist_add_nvlist_array(
- nvl_peers[i], "allowed-ips", (const nvlist_t* const*)nvl_aips, j);
- for (j = 0; j < aip_count; ++j)
- nvlist_destroy(nvl_aips[j]);
- free(nvl_aips);
- }
- ++i;
- continue;
-
- err_peer:
- ret = -errno;
- for (j = 0; j < aip_count && nvl_aips; ++j)
- nvlist_destroy(nvl_aips[j]);
- free(nvl_aips);
- nvlist_destroy(nvl_peers[i]);
- nvl_peers[i] = NULL;
- goto err;
- }
- if (i)
- {
- nvlist_add_nvlist_array(
- nvl_device, "peers", (const nvlist_t* const*)nvl_peers, i);
- for (i = 0; i < peer_count; ++i)
- nvlist_destroy(nvl_peers[i]);
- free(nvl_peers);
- nvl_peers = NULL;
- }
- wgd.wgd_data = nvlist_pack(nvl_device, &wgd.wgd_size);
- nvlist_destroy(nvl_device);
- nvl_device = NULL;
- if (!wgd.wgd_data)
- goto err;
- s = get_dgram_socket();
- if (s < 0)
- return -errno;
- return ioctl(s, SIOCSWG, &wgd);
+ err_peer:
+ ret = -errno;
+ for (j = 0; j < aip_count && nvl_aips; ++j)
+ nvlist_destroy(nvl_aips[j]);
+ free(nvl_aips);
+ nvlist_destroy(nvl_peers[i]);
+ nvl_peers[i] = NULL;
+ goto err;
+ }
+ if (i) {
+ nvlist_add_nvlist_array(nvl_device, "peers", (const nvlist_t *const *)nvl_peers, i);
+ for (i = 0; i < peer_count; ++i)
+ nvlist_destroy(nvl_peers[i]);
+ free(nvl_peers);
+ nvl_peers = NULL;
+ }
+ wgd.wgd_data = nvlist_pack(nvl_device, &wgd.wgd_size);
+ nvlist_destroy(nvl_device);
+ nvl_device = NULL;
+ if (!wgd.wgd_data)
+ goto err;
+ s = get_dgram_socket();
+ if (s < 0)
+ return -errno;
+ return ioctl(s, SIOCSWG, &wgd);
err:
- if (!ret)
- ret = -errno;
- for (i = 0; i < peer_count && nvl_peers; ++i)
- nvlist_destroy(nvl_peers[i]);
- free(nvl_peers);
- nvlist_destroy(nvl_device);
- return ret;
+ if (!ret)
+ ret = -errno;
+ for (i = 0; i < peer_count && nvl_peers; ++i)
+ nvlist_destroy(nvl_peers[i]);
+ free(nvl_peers);
+ nvlist_destroy(nvl_device);
+ return ret;
}
diff --git a/src/ipc-linux.h b/src/ipc-linux.h
index d228c67..ffc95ca 100644
--- a/src/ipc-linux.h
+++ b/src/ipc-linux.h
@@ -3,849 +3,725 @@
* Copyright (C) 2015-2020 Jason A. Donenfeld . All Rights Reserved.
*/
-#include "containers.h"
-#include "encoding.h"
-#include "netlink.h"
-#include "uapi/linux/linux/wireguard.h"
+#include
+#include
+#include
+#include
+#include
#include
+#include
+#include
+#include
+#include
#include
#include
#include
#include
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
+#include "containers.h"
+#include "encoding.h"
+#include "netlink.h"
#define IPC_SUPPORTS_KERNEL_INTERFACE
#define SOCKET_BUFFER_SIZE (mnl_ideal_socket_buffer_size())
-struct interface
-{
- const char* name;
- bool is_wireguard;
+struct interface {
+ const char *name;
+ bool is_wireguard;
};
-static int parse_linkinfo(const struct nlattr* attr, void* data)
+static int parse_linkinfo(const struct nlattr *attr, void *data)
{
- struct interface* interface = data;
+ struct interface *interface = data;
- if (mnl_attr_get_type(attr) == IFLA_INFO_KIND &&
- !strcmp(WG_GENL_NAME, mnl_attr_get_str(attr)))
- interface->is_wireguard = true;
- return MNL_CB_OK;
+ if (mnl_attr_get_type(attr) == IFLA_INFO_KIND && !strcmp(WG_GENL_NAME, mnl_attr_get_str(attr)))
+ interface->is_wireguard = true;
+ return MNL_CB_OK;
}
-static int parse_infomsg(const struct nlattr* attr, void* data)
+static int parse_infomsg(const struct nlattr *attr, void *data)
{
- struct interface* interface = data;
+ struct interface *interface = data;
- if (mnl_attr_get_type(attr) == IFLA_LINKINFO)
- return mnl_attr_parse_nested(attr, parse_linkinfo, data);
- else if (mnl_attr_get_type(attr) == IFLA_IFNAME)
- interface->name = mnl_attr_get_str(attr);
- return MNL_CB_OK;
+ if (mnl_attr_get_type(attr) == IFLA_LINKINFO)
+ return mnl_attr_parse_nested(attr, parse_linkinfo, data);
+ else if (mnl_attr_get_type(attr) == IFLA_IFNAME)
+ interface->name = mnl_attr_get_str(attr);
+ return MNL_CB_OK;
}
-static int read_devices_cb(const struct nlmsghdr* nlh, void* data)
+static int read_devices_cb(const struct nlmsghdr *nlh, void *data)
{
- struct string_list* list = data;
- struct interface interface = {0};
- int ret;
+ struct string_list *list = data;
+ struct interface interface = { 0 };
+ int ret;
- ret = mnl_attr_parse(nlh, sizeof(struct ifinfomsg), parse_infomsg, &interface);
- if (ret != MNL_CB_OK)
- return ret;
- if (interface.name && interface.is_wireguard)
- ret = string_list_add(list, interface.name);
- if (ret < 0)
- return ret;
- if (nlh->nlmsg_type != NLMSG_DONE)
- return MNL_CB_OK + 1;
- return MNL_CB_OK;
+ ret = mnl_attr_parse(nlh, sizeof(struct ifinfomsg), parse_infomsg, &interface);
+ if (ret != MNL_CB_OK)
+ return ret;
+ if (interface.name && interface.is_wireguard)
+ ret = string_list_add(list, interface.name);
+ if (ret < 0)
+ return ret;
+ if (nlh->nlmsg_type != NLMSG_DONE)
+ return MNL_CB_OK + 1;
+ return MNL_CB_OK;
}
-static int kernel_get_wireguard_interfaces(struct string_list* list)
+static int kernel_get_wireguard_interfaces(struct string_list *list)
{
- struct mnl_socket* nl = NULL;
- char* rtnl_buffer = NULL;
- size_t message_len;
- unsigned int portid, seq;
- ssize_t len;
- int ret = 0;
- struct nlmsghdr* nlh;
- struct ifinfomsg* ifm;
+ struct mnl_socket *nl = NULL;
+ char *rtnl_buffer = NULL;
+ size_t message_len;
+ unsigned int portid, seq;
+ ssize_t len;
+ int ret = 0;
+ struct nlmsghdr *nlh;
+ struct ifinfomsg *ifm;
- ret = -ENOMEM;
- rtnl_buffer = calloc(SOCKET_BUFFER_SIZE, 1);
- if (!rtnl_buffer)
- goto cleanup;
+ ret = -ENOMEM;
+ rtnl_buffer = calloc(SOCKET_BUFFER_SIZE, 1);
+ if (!rtnl_buffer)
+ goto cleanup;
- nl = mnl_socket_open(NETLINK_ROUTE);
- if (!nl)
- {
- ret = -errno;
- goto cleanup;
- }
+ nl = mnl_socket_open(NETLINK_ROUTE);
+ if (!nl) {
+ ret = -errno;
+ goto cleanup;
+ }
- if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0)
- {
- ret = -errno;
- goto cleanup;
- }
+ if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
- seq = time(NULL);
- portid = mnl_socket_get_portid(nl);
- nlh = mnl_nlmsg_put_header(rtnl_buffer);
- nlh->nlmsg_type = RTM_GETLINK;
- nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP;
- nlh->nlmsg_seq = seq;
- ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
- ifm->ifi_family = AF_UNSPEC;
- message_len = nlh->nlmsg_len;
+ seq = time(NULL);
+ portid = mnl_socket_get_portid(nl);
+ nlh = mnl_nlmsg_put_header(rtnl_buffer);
+ nlh->nlmsg_type = RTM_GETLINK;
+ nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP;
+ nlh->nlmsg_seq = seq;
+ ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
+ ifm->ifi_family = AF_UNSPEC;
+ message_len = nlh->nlmsg_len;
- if (mnl_socket_sendto(nl, rtnl_buffer, message_len) < 0)
- {
- ret = -errno;
- goto cleanup;
- }
+ if (mnl_socket_sendto(nl, rtnl_buffer, message_len) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
another:
- if ((len = mnl_socket_recvfrom(nl, rtnl_buffer, SOCKET_BUFFER_SIZE)) < 0)
- {
- ret = -errno;
- goto cleanup;
- }
- if ((len = mnl_cb_run(rtnl_buffer, len, seq, portid, read_devices_cb, list)) < 0)
- {
- /* Netlink returns NLM_F_DUMP_INTR if the set of all tunnels changed
+ if ((len = mnl_socket_recvfrom(nl, rtnl_buffer, SOCKET_BUFFER_SIZE)) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+ if ((len = mnl_cb_run(rtnl_buffer, len, seq, portid, read_devices_cb, list)) < 0) {
+ /* Netlink returns NLM_F_DUMP_INTR if the set of all tunnels changed
* during the dump. That's unfortunate, but is pretty common on busy
* systems that are adding and removing tunnels all the time. Rather
* than retrying, potentially indefinitely, we just work with the
* partial results. */
- if (errno != EINTR)
- {
- ret = -errno;
- goto cleanup;
- }
- }
- if (len == MNL_CB_OK + 1)
- goto another;
- ret = 0;
+ if (errno != EINTR) {
+ ret = -errno;
+ goto cleanup;
+ }
+ }
+ if (len == MNL_CB_OK + 1)
+ goto another;
+ ret = 0;
cleanup:
- free(rtnl_buffer);
- if (nl)
- mnl_socket_close(nl);
- return ret;
+ free(rtnl_buffer);
+ if (nl)
+ mnl_socket_close(nl);
+ return ret;
}
-static int kernel_set_device(struct wgdevice* dev)
+static int kernel_set_device(struct wgdevice *dev)
{
- int ret = 0;
- struct wgpeer* peer = NULL;
- struct wgallowedip* allowedip = NULL;
- struct nlattr * peers_nest, *peer_nest, *allowedips_nest, *allowedip_nest;
- struct nlmsghdr* nlh;
- struct mnlg_socket* nlg;
+ int ret = 0;
+ struct wgpeer *peer = NULL;
+ struct wgallowedip *allowedip = NULL;
+ struct nlattr *peers_nest, *peer_nest, *allowedips_nest, *allowedip_nest;
+ struct nlmsghdr *nlh;
+ struct mnlg_socket *nlg;
- nlg = mnlg_socket_open(WG_GENL_NAME, WG_GENL_VERSION);
- if (!nlg)
- return -errno;
+ nlg = mnlg_socket_open(WG_GENL_NAME, WG_GENL_VERSION);
+ if (!nlg)
+ return -errno;
again:
- nlh = mnlg_msg_prepare(nlg, WG_CMD_SET_DEVICE, NLM_F_REQUEST | NLM_F_ACK);
- mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, dev->name);
+ nlh = mnlg_msg_prepare(nlg, WG_CMD_SET_DEVICE, NLM_F_REQUEST | NLM_F_ACK);
+ mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, dev->name);
- if (!peer)
- {
- uint32_t flags = 0;
+ if (!peer) {
+ uint32_t flags = 0;
- if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
- mnl_attr_put(
- nlh, WGDEVICE_A_PRIVATE_KEY, sizeof(dev->private_key), dev->private_key);
- if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
- mnl_attr_put_u16(nlh, WGDEVICE_A_LISTEN_PORT, dev->listen_port);
- if (dev->flags & WGDEVICE_HAS_JC)
- mnl_attr_put_u16(nlh, WGDEVICE_A_JC, dev->junk_packet_count);
- if (dev->flags & WGDEVICE_HAS_JMIN)
- mnl_attr_put_u16(nlh, WGDEVICE_A_JMIN, dev->junk_packet_min_size);
- if (dev->flags & WGDEVICE_HAS_JMAX)
- mnl_attr_put_u16(nlh, WGDEVICE_A_JMAX, dev->junk_packet_max_size);
- if (dev->flags & WGDEVICE_HAS_S1)
- mnl_attr_put_u16(nlh, WGDEVICE_A_S1, dev->init_packet_junk_size);
- if (dev->flags & WGDEVICE_HAS_S2)
- mnl_attr_put_u16(nlh, WGDEVICE_A_S2, dev->response_packet_junk_size);
- if (dev->flags & WGDEVICE_HAS_H1)
- mnl_attr_put_u32(nlh, WGDEVICE_A_H1, dev->init_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H2)
- mnl_attr_put_u32(nlh, WGDEVICE_A_H2, dev->response_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H3)
- mnl_attr_put_u32(nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H4)
- mnl_attr_put_u32(nlh, WGDEVICE_A_H4, dev->transport_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_I1)
- mnl_attr_put_strz(nlh, WGDEVICE_A_I1, dev->i1);
- if (dev->flags & WGDEVICE_HAS_I2)
- mnl_attr_put_strz(nlh, WGDEVICE_A_I2, dev->i2);
- if (dev->flags & WGDEVICE_HAS_I3)
- mnl_attr_put_strz(nlh, WGDEVICE_A_I3, dev->i3);
- if (dev->flags & WGDEVICE_HAS_I4)
- mnl_attr_put_strz(nlh, WGDEVICE_A_I4, dev->i4);
- if (dev->flags & WGDEVICE_HAS_I5)
- mnl_attr_put_strz(nlh, WGDEVICE_A_I5, dev->i5);
- if (dev->flags & WGDEVICE_HAS_J1)
- mnl_attr_put_strz(nlh, WGDEVICE_A_J1, dev->j1);
- if (dev->flags & WGDEVICE_HAS_J2)
- mnl_attr_put_strz(nlh, WGDEVICE_A_J2, dev->j2);
- if (dev->flags & WGDEVICE_HAS_J3)
- mnl_attr_put_strz(nlh, WGDEVICE_A_J3, dev->j3);
- if (dev->flags & WGDEVICE_HAS_ITIME)
- mnl_attr_put_u32(nlh, WGDEVICE_A_ITIME, dev->itime);
+ if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
+ mnl_attr_put(nlh, WGDEVICE_A_PRIVATE_KEY, sizeof(dev->private_key), dev->private_key);
+ if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
+ mnl_attr_put_u16(nlh, WGDEVICE_A_LISTEN_PORT, dev->listen_port);
+ if (dev->flags & WGDEVICE_HAS_JC)
+ mnl_attr_put_u16(nlh, WGDEVICE_A_JC, dev->junk_packet_count);
+ if (dev->flags & WGDEVICE_HAS_JMIN)
+ mnl_attr_put_u16(nlh, WGDEVICE_A_JMIN, dev->junk_packet_min_size);
+ if (dev->flags & WGDEVICE_HAS_JMAX)
+ mnl_attr_put_u16(nlh, WGDEVICE_A_JMAX, dev->junk_packet_max_size);
+ if (dev->flags & WGDEVICE_HAS_S1)
+ mnl_attr_put_u16(nlh, WGDEVICE_A_S1, dev->init_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_S2)
+ mnl_attr_put_u16(nlh, WGDEVICE_A_S2, dev->response_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_H1)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_H1, dev->init_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H2)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_H2, dev->response_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H3)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H4)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_H4, dev->transport_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_I1)
+ mnl_attr_put_strz(nlh, WGDEVICE_A_I1, dev->i1);
+ if (dev->flags & WGDEVICE_HAS_I2)
+ mnl_attr_put_strz(nlh, WGDEVICE_A_I2, dev->i2);
+ if (dev->flags & WGDEVICE_HAS_I3)
+ mnl_attr_put_strz(nlh, WGDEVICE_A_I3, dev->i3);
+ if (dev->flags & WGDEVICE_HAS_I4)
+ mnl_attr_put_strz(nlh, WGDEVICE_A_I4, dev->i4);
+ if (dev->flags & WGDEVICE_HAS_I5)
+ mnl_attr_put_strz(nlh, WGDEVICE_A_I5, dev->i5);
+ if (dev->flags & WGDEVICE_HAS_J1)
+ mnl_attr_put_strz(nlh, WGDEVICE_A_J1, dev->j1);
+ if (dev->flags & WGDEVICE_HAS_J2)
+ mnl_attr_put_strz(nlh, WGDEVICE_A_J2, dev->j2);
+ if (dev->flags & WGDEVICE_HAS_J3)
+ mnl_attr_put_strz(nlh, WGDEVICE_A_J3, dev->j3);
+ if (dev->flags & WGDEVICE_HAS_ITIME)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_ITIME, dev->itime);
+ if (dev->flags & WGDEVICE_HAS_FWMARK)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark);
+ if (dev->flags & WGDEVICE_REPLACE_PEERS)
+ flags |= WGDEVICE_F_REPLACE_PEERS;
+ if (flags)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_FLAGS, flags);
+ }
+ if (!dev->first_peer)
+ goto send;
+ peers_nest = peer_nest = allowedips_nest = allowedip_nest = NULL;
+ peers_nest = mnl_attr_nest_start(nlh, WGDEVICE_A_PEERS);
+ for (peer = peer ? peer : dev->first_peer; peer; peer = peer->next_peer) {
+ uint32_t flags = 0;
- if (dev->flags & WGDEVICE_HAS_FWMARK)
- mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark);
- if (dev->flags & WGDEVICE_REPLACE_PEERS)
- flags |= WGDEVICE_F_REPLACE_PEERS;
- if (flags)
- mnl_attr_put_u32(nlh, WGDEVICE_A_FLAGS, flags);
- }
- if (!dev->first_peer)
- goto send;
- peers_nest = peer_nest = allowedips_nest = allowedip_nest = NULL;
- peers_nest = mnl_attr_nest_start(nlh, WGDEVICE_A_PEERS);
- for (peer = peer ? peer : dev->first_peer; peer; peer = peer->next_peer)
- {
- uint32_t flags = 0;
+ peer_nest = mnl_attr_nest_start_check(nlh, SOCKET_BUFFER_SIZE, 0);
+ if (!peer_nest)
+ goto toobig_peers;
+ if (!mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_PUBLIC_KEY, sizeof(peer->public_key), peer->public_key))
+ goto toobig_peers;
+ if (peer->flags & WGPEER_REMOVE_ME)
+ flags |= WGPEER_F_REMOVE_ME;
+ if (!allowedip) {
+ if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
+ flags |= WGPEER_F_REPLACE_ALLOWEDIPS;
+ if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
+ if (!mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_PRESHARED_KEY, sizeof(peer->preshared_key), peer->preshared_key))
+ goto toobig_peers;
+ }
+ if (peer->endpoint.addr.sa_family == AF_INET) {
+ if (!mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_ENDPOINT, sizeof(peer->endpoint.addr4), &peer->endpoint.addr4))
+ goto toobig_peers;
+ } else if (peer->endpoint.addr.sa_family == AF_INET6) {
+ if (!mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_ENDPOINT, sizeof(peer->endpoint.addr6), &peer->endpoint.addr6))
+ goto toobig_peers;
+ }
+ if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL) {
+ if (!mnl_attr_put_u16_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, peer->persistent_keepalive_interval))
+ goto toobig_peers;
+ }
+ }
+ if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) {
+ if (peer->advanced_security)
+ mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_ADVANCED_SECURITY, 0, NULL);
+ flags |= WGPEER_F_HAS_ADVANCED_SECURITY;
+ }
+ if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)
+ {
+ if (peer->special_handshake)
+ mnl_attr_put_check(
+ nlh, SOCKET_BUFFER_SIZE, WGPEER_A_SPECIAL_HANDSHAKE, 0, NULL);
+ flags |= WGPEER_F_HAS_SPECIAL_HANDSHAKE;
+ }
+ if (flags) {
+ if (!mnl_attr_put_u32_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_FLAGS, flags))
+ goto toobig_peers;
+ }
+ if (peer->first_allowedip) {
+ if (!allowedip)
+ allowedip = peer->first_allowedip;
+ allowedips_nest = mnl_attr_nest_start_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_ALLOWEDIPS);
+ if (!allowedips_nest)
+ goto toobig_allowedips;
+ for (; allowedip; allowedip = allowedip->next_allowedip) {
+ allowedip_nest = mnl_attr_nest_start_check(nlh, SOCKET_BUFFER_SIZE, 0);
+ if (!allowedip_nest)
+ goto toobig_allowedips;
+ if (!mnl_attr_put_u16_check(nlh, SOCKET_BUFFER_SIZE, WGALLOWEDIP_A_FAMILY, allowedip->family))
+ goto toobig_allowedips;
+ if (allowedip->family == AF_INET) {
+ if (!mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGALLOWEDIP_A_IPADDR, sizeof(allowedip->ip4), &allowedip->ip4))
+ goto toobig_allowedips;
+ } else if (allowedip->family == AF_INET6) {
+ if (!mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGALLOWEDIP_A_IPADDR, sizeof(allowedip->ip6), &allowedip->ip6))
+ goto toobig_allowedips;
+ }
+ if (!mnl_attr_put_u8_check(nlh, SOCKET_BUFFER_SIZE, WGALLOWEDIP_A_CIDR_MASK, allowedip->cidr))
+ goto toobig_allowedips;
+ mnl_attr_nest_end(nlh, allowedip_nest);
+ allowedip_nest = NULL;
+ }
+ mnl_attr_nest_end(nlh, allowedips_nest);
+ allowedips_nest = NULL;
+ }
- peer_nest = mnl_attr_nest_start_check(nlh, SOCKET_BUFFER_SIZE, 0);
- if (!peer_nest)
- goto toobig_peers;
- if (!mnl_attr_put_check(
- nlh,
- SOCKET_BUFFER_SIZE,
- WGPEER_A_PUBLIC_KEY,
- sizeof(peer->public_key),
- peer->public_key))
- goto toobig_peers;
- if (peer->flags & WGPEER_REMOVE_ME)
- flags |= WGPEER_F_REMOVE_ME;
- if (!allowedip)
- {
- if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
- flags |= WGPEER_F_REPLACE_ALLOWEDIPS;
- if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
- {
- if (!mnl_attr_put_check(
- nlh,
- SOCKET_BUFFER_SIZE,
- WGPEER_A_PRESHARED_KEY,
- sizeof(peer->preshared_key),
- peer->preshared_key))
- goto toobig_peers;
- }
- if (peer->endpoint.addr.sa_family == AF_INET)
- {
- if (!mnl_attr_put_check(
- nlh,
- SOCKET_BUFFER_SIZE,
- WGPEER_A_ENDPOINT,
- sizeof(peer->endpoint.addr4),
- &peer->endpoint.addr4))
- goto toobig_peers;
- }
- else if (peer->endpoint.addr.sa_family == AF_INET6)
- {
- if (!mnl_attr_put_check(
- nlh,
- SOCKET_BUFFER_SIZE,
- WGPEER_A_ENDPOINT,
- sizeof(peer->endpoint.addr6),
- &peer->endpoint.addr6))
- goto toobig_peers;
- }
- if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
- {
- if (!mnl_attr_put_u16_check(
- nlh,
- SOCKET_BUFFER_SIZE,
- WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
- peer->persistent_keepalive_interval))
- goto toobig_peers;
- }
- }
- if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY)
- {
- if (peer->advanced_security)
- mnl_attr_put_check(
- nlh, SOCKET_BUFFER_SIZE, WGPEER_A_ADVANCED_SECURITY, 0, NULL);
- flags |= WGPEER_F_HAS_ADVANCED_SECURITY;
- }
- if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)
- {
- if (peer->special_handshake)
- mnl_attr_put_check(
- nlh, SOCKET_BUFFER_SIZE, WGPEER_A_SPECIAL_HANDSHAKE, 0, NULL);
- flags |= WGPEER_F_HAS_SPECIAL_HANDSHAKE;
- }
- if (flags)
- {
- if (!mnl_attr_put_u32_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_FLAGS, flags))
- goto toobig_peers;
- }
- if (peer->first_allowedip)
- {
- if (!allowedip)
- allowedip = peer->first_allowedip;
- allowedips_nest =
- mnl_attr_nest_start_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_ALLOWEDIPS);
- if (!allowedips_nest)
- goto toobig_allowedips;
- for (; allowedip; allowedip = allowedip->next_allowedip)
- {
- allowedip_nest = mnl_attr_nest_start_check(nlh, SOCKET_BUFFER_SIZE, 0);
- if (!allowedip_nest)
- goto toobig_allowedips;
- if (!mnl_attr_put_u16_check(
- nlh, SOCKET_BUFFER_SIZE, WGALLOWEDIP_A_FAMILY, allowedip->family))
- goto toobig_allowedips;
- if (allowedip->family == AF_INET)
- {
- if (!mnl_attr_put_check(
- nlh,
- SOCKET_BUFFER_SIZE,
- WGALLOWEDIP_A_IPADDR,
- sizeof(allowedip->ip4),
- &allowedip->ip4))
- goto toobig_allowedips;
- }
- else if (allowedip->family == AF_INET6)
- {
- if (!mnl_attr_put_check(
- nlh,
- SOCKET_BUFFER_SIZE,
- WGALLOWEDIP_A_IPADDR,
- sizeof(allowedip->ip6),
- &allowedip->ip6))
- goto toobig_allowedips;
- }
- if (!mnl_attr_put_u8_check(
- nlh,
- SOCKET_BUFFER_SIZE,
- WGALLOWEDIP_A_CIDR_MASK,
- allowedip->cidr))
- goto toobig_allowedips;
- mnl_attr_nest_end(nlh, allowedip_nest);
- allowedip_nest = NULL;
- }
- mnl_attr_nest_end(nlh, allowedips_nest);
- allowedips_nest = NULL;
- }
-
- mnl_attr_nest_end(nlh, peer_nest);
- peer_nest = NULL;
- }
- mnl_attr_nest_end(nlh, peers_nest);
- peers_nest = NULL;
- goto send;
+ mnl_attr_nest_end(nlh, peer_nest);
+ peer_nest = NULL;
+ }
+ mnl_attr_nest_end(nlh, peers_nest);
+ peers_nest = NULL;
+ goto send;
toobig_allowedips:
- if (allowedip_nest)
- mnl_attr_nest_cancel(nlh, allowedip_nest);
- if (allowedips_nest)
- mnl_attr_nest_end(nlh, allowedips_nest);
- mnl_attr_nest_end(nlh, peer_nest);
- mnl_attr_nest_end(nlh, peers_nest);
- goto send;
+ if (allowedip_nest)
+ mnl_attr_nest_cancel(nlh, allowedip_nest);
+ if (allowedips_nest)
+ mnl_attr_nest_end(nlh, allowedips_nest);
+ mnl_attr_nest_end(nlh, peer_nest);
+ mnl_attr_nest_end(nlh, peers_nest);
+ goto send;
toobig_peers:
- if (peer_nest)
- mnl_attr_nest_cancel(nlh, peer_nest);
- mnl_attr_nest_end(nlh, peers_nest);
- goto send;
+ if (peer_nest)
+ mnl_attr_nest_cancel(nlh, peer_nest);
+ mnl_attr_nest_end(nlh, peers_nest);
+ goto send;
send:
- if (mnlg_socket_send(nlg, nlh) < 0)
- {
- ret = -errno;
- goto out;
- }
- errno = 0;
- if (mnlg_socket_recv_run(nlg, NULL, NULL) < 0)
- {
- ret = errno ? -errno : -EINVAL;
- goto out;
- }
- if (peer)
- goto again;
+ if (mnlg_socket_send(nlg, nlh) < 0) {
+ ret = -errno;
+ goto out;
+ }
+ errno = 0;
+ if (mnlg_socket_recv_run(nlg, NULL, NULL) < 0) {
+ ret = errno ? -errno : -EINVAL;
+ goto out;
+ }
+ if (peer)
+ goto again;
out:
- mnlg_socket_close(nlg);
- errno = -ret;
- return ret;
+ mnlg_socket_close(nlg);
+ errno = -ret;
+ return ret;
}
-static int parse_allowedip(const struct nlattr* attr, void* data)
+static int parse_allowedip(const struct nlattr *attr, void *data)
{
- struct wgallowedip* allowedip = data;
+ struct wgallowedip *allowedip = data;
- switch (mnl_attr_get_type(attr))
- {
- case WGALLOWEDIP_A_UNSPEC:
- break;
- case WGALLOWEDIP_A_FAMILY:
- if (!mnl_attr_validate(attr, MNL_TYPE_U16))
- allowedip->family = mnl_attr_get_u16(attr);
- break;
- case WGALLOWEDIP_A_IPADDR:
- if (mnl_attr_get_payload_len(attr) == sizeof(allowedip->ip4))
- memcpy(&allowedip->ip4, mnl_attr_get_payload(attr), sizeof(allowedip->ip4));
- else if (mnl_attr_get_payload_len(attr) == sizeof(allowedip->ip6))
- memcpy(&allowedip->ip6, mnl_attr_get_payload(attr), sizeof(allowedip->ip6));
- break;
- case WGALLOWEDIP_A_CIDR_MASK:
- if (!mnl_attr_validate(attr, MNL_TYPE_U8))
- allowedip->cidr = mnl_attr_get_u8(attr);
- break;
- }
+ switch (mnl_attr_get_type(attr)) {
+ case WGALLOWEDIP_A_UNSPEC:
+ break;
+ case WGALLOWEDIP_A_FAMILY:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16))
+ allowedip->family = mnl_attr_get_u16(attr);
+ break;
+ case WGALLOWEDIP_A_IPADDR:
+ if (mnl_attr_get_payload_len(attr) == sizeof(allowedip->ip4))
+ memcpy(&allowedip->ip4, mnl_attr_get_payload(attr), sizeof(allowedip->ip4));
+ else if (mnl_attr_get_payload_len(attr) == sizeof(allowedip->ip6))
+ memcpy(&allowedip->ip6, mnl_attr_get_payload(attr), sizeof(allowedip->ip6));
+ break;
+ case WGALLOWEDIP_A_CIDR_MASK:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U8))
+ allowedip->cidr = mnl_attr_get_u8(attr);
+ break;
+ }
- return MNL_CB_OK;
+ return MNL_CB_OK;
}
-static int parse_allowedips(const struct nlattr* attr, void* data)
+static int parse_allowedips(const struct nlattr *attr, void *data)
{
- struct wgpeer* peer = data;
- struct wgallowedip* new_allowedip = calloc(1, sizeof(*new_allowedip));
- int ret;
+ struct wgpeer *peer = data;
+ struct wgallowedip *new_allowedip = calloc(1, sizeof(*new_allowedip));
+ int ret;
- if (!new_allowedip)
- {
- perror("calloc");
- return MNL_CB_ERROR;
- }
- if (!peer->first_allowedip)
- peer->first_allowedip = peer->last_allowedip = new_allowedip;
- else
- {
- peer->last_allowedip->next_allowedip = new_allowedip;
- peer->last_allowedip = new_allowedip;
- }
- ret = mnl_attr_parse_nested(attr, parse_allowedip, new_allowedip);
- if (!ret)
- return ret;
- if (!((new_allowedip->family == AF_INET && new_allowedip->cidr <= 32) ||
- (new_allowedip->family == AF_INET6 && new_allowedip->cidr <= 128)))
- return MNL_CB_ERROR;
- return MNL_CB_OK;
+ if (!new_allowedip) {
+ perror("calloc");
+ return MNL_CB_ERROR;
+ }
+ if (!peer->first_allowedip)
+ peer->first_allowedip = peer->last_allowedip = new_allowedip;
+ else {
+ peer->last_allowedip->next_allowedip = new_allowedip;
+ peer->last_allowedip = new_allowedip;
+ }
+ ret = mnl_attr_parse_nested(attr, parse_allowedip, new_allowedip);
+ if (!ret)
+ return ret;
+ if (!((new_allowedip->family == AF_INET && new_allowedip->cidr <= 32) || (new_allowedip->family == AF_INET6 && new_allowedip->cidr <= 128)))
+ return MNL_CB_ERROR;
+ return MNL_CB_OK;
}
-static int parse_peer(const struct nlattr* attr, void* data)
+static int parse_peer(const struct nlattr *attr, void *data)
{
- struct wgpeer* peer = data;
+ struct wgpeer *peer = data;
- switch (mnl_attr_get_type(attr))
- {
- case WGPEER_A_UNSPEC:
- break;
- case WGPEER_A_PUBLIC_KEY:
- if (mnl_attr_get_payload_len(attr) == sizeof(peer->public_key))
- {
- memcpy(
- peer->public_key, mnl_attr_get_payload(attr), sizeof(peer->public_key));
- peer->flags |= WGPEER_HAS_PUBLIC_KEY;
- }
- break;
- case WGPEER_A_PRESHARED_KEY:
- if (mnl_attr_get_payload_len(attr) == sizeof(peer->preshared_key))
- {
- memcpy(
- peer->preshared_key,
- mnl_attr_get_payload(attr),
- sizeof(peer->preshared_key));
- if (!key_is_zero(peer->preshared_key))
- peer->flags |= WGPEER_HAS_PRESHARED_KEY;
- }
- break;
- case WGPEER_A_ENDPOINT: {
- struct sockaddr* addr;
+ switch (mnl_attr_get_type(attr)) {
+ case WGPEER_A_UNSPEC:
+ break;
+ case WGPEER_A_PUBLIC_KEY:
+ if (mnl_attr_get_payload_len(attr) == sizeof(peer->public_key)) {
+ memcpy(peer->public_key, mnl_attr_get_payload(attr), sizeof(peer->public_key));
+ peer->flags |= WGPEER_HAS_PUBLIC_KEY;
+ }
+ break;
+ case WGPEER_A_PRESHARED_KEY:
+ if (mnl_attr_get_payload_len(attr) == sizeof(peer->preshared_key)) {
+ memcpy(peer->preshared_key, mnl_attr_get_payload(attr), sizeof(peer->preshared_key));
+ if (!key_is_zero(peer->preshared_key))
+ peer->flags |= WGPEER_HAS_PRESHARED_KEY;
+ }
+ break;
+ case WGPEER_A_ENDPOINT: {
+ struct sockaddr *addr;
- if (mnl_attr_get_payload_len(attr) < sizeof(*addr))
- break;
- addr = mnl_attr_get_payload(attr);
- if (addr->sa_family == AF_INET &&
- mnl_attr_get_payload_len(attr) == sizeof(peer->endpoint.addr4))
- memcpy(&peer->endpoint.addr4, addr, sizeof(peer->endpoint.addr4));
- else if (
- addr->sa_family == AF_INET6 &&
- mnl_attr_get_payload_len(attr) == sizeof(peer->endpoint.addr6))
- memcpy(&peer->endpoint.addr6, addr, sizeof(peer->endpoint.addr6));
- break;
- }
- case WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL:
- if (!mnl_attr_validate(attr, MNL_TYPE_U16))
- peer->persistent_keepalive_interval = mnl_attr_get_u16(attr);
- break;
- case WGPEER_A_LAST_HANDSHAKE_TIME:
- if (mnl_attr_get_payload_len(attr) == sizeof(peer->last_handshake_time))
- memcpy(
- &peer->last_handshake_time,
- mnl_attr_get_payload(attr),
- sizeof(peer->last_handshake_time));
- break;
- case WGPEER_A_RX_BYTES:
- if (!mnl_attr_validate(attr, MNL_TYPE_U64))
- peer->rx_bytes = mnl_attr_get_u64(attr);
- break;
- case WGPEER_A_TX_BYTES:
- if (!mnl_attr_validate(attr, MNL_TYPE_U64))
- peer->tx_bytes = mnl_attr_get_u64(attr);
- break;
- case WGPEER_A_FLAGS:
- if (!mnl_attr_validate(attr, MNL_TYPE_U32))
- {
- uint32_t flags = mnl_attr_get_u32(attr);
+ if (mnl_attr_get_payload_len(attr) < sizeof(*addr))
+ break;
+ addr = mnl_attr_get_payload(attr);
+ if (addr->sa_family == AF_INET && mnl_attr_get_payload_len(attr) == sizeof(peer->endpoint.addr4))
+ memcpy(&peer->endpoint.addr4, addr, sizeof(peer->endpoint.addr4));
+ else if (addr->sa_family == AF_INET6 && mnl_attr_get_payload_len(attr) == sizeof(peer->endpoint.addr6))
+ memcpy(&peer->endpoint.addr6, addr, sizeof(peer->endpoint.addr6));
+ break;
+ }
+ case WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16))
+ peer->persistent_keepalive_interval = mnl_attr_get_u16(attr);
+ break;
+ case WGPEER_A_LAST_HANDSHAKE_TIME:
+ if (mnl_attr_get_payload_len(attr) == sizeof(peer->last_handshake_time))
+ memcpy(&peer->last_handshake_time, mnl_attr_get_payload(attr), sizeof(peer->last_handshake_time));
+ break;
+ case WGPEER_A_RX_BYTES:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U64))
+ peer->rx_bytes = mnl_attr_get_u64(attr);
+ break;
+ case WGPEER_A_TX_BYTES:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U64))
+ peer->tx_bytes = mnl_attr_get_u64(attr);
+ break;
+ case WGPEER_A_FLAGS:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32)) {
+ uint32_t flags = mnl_attr_get_u32(attr);
- if (flags & WGPEER_F_HAS_ADVANCED_SECURITY &&
- !(peer->flags & WGPEER_HAS_ADVANCED_SECURITY))
- {
- peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
- peer->advanced_security = false;
- }
- else if (
- flags & WGPEER_F_HAS_SPECIAL_HANDSHAKE &&
- !(peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE))
- {
- peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE;
- peer->special_handshake = false;
- }
- }
- break;
- case WGPEER_A_ADVANCED_SECURITY:
- if (!mnl_attr_validate(attr, MNL_TYPE_FLAG))
- {
- peer->advanced_security = true;
+ if (flags & WGPEER_F_HAS_ADVANCED_SECURITY && !(peer->flags & WGPEER_HAS_ADVANCED_SECURITY)) {
+ peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
+ peer->advanced_security = false;
+ }
+ if (
+ flags & WGPEER_F_HAS_SPECIAL_HANDSHAKE &&
+ !(peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE))
+ {
+ peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE;
+ peer->special_handshake = false;
+ }
+ }
+ break;
+ case WGPEER_A_ADVANCED_SECURITY:
+ if (!mnl_attr_validate(attr, MNL_TYPE_FLAG)) {
+ peer->advanced_security = true;
- if (!(peer->flags & WGPEER_HAS_ADVANCED_SECURITY))
- {
- peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
- }
- }
- break;
- case WGPEER_A_SPECIAL_HANDSHAKE:
- if (!mnl_attr_validate(attr, MNL_TYPE_FLAG))
- {
- peer->special_handshake = true;
+ if (!(peer->flags & WGPEER_HAS_ADVANCED_SECURITY)) {
+ peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
+ }
+ }
+ break;
+ case WGPEER_A_SPECIAL_HANDSHAKE:
+ if (!mnl_attr_validate(attr, MNL_TYPE_FLAG))
+ {
+ peer->special_handshake = true;
- if (!(peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE))
- {
- peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE;
- }
- }
- break;
- case WGPEER_A_ALLOWEDIPS:
- return mnl_attr_parse_nested(attr, parse_allowedips, peer);
- }
+ if (!(peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE))
+ {
+ peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE;
+ }
+ }
+ break;
+ case WGPEER_A_ALLOWEDIPS:
+ return mnl_attr_parse_nested(attr, parse_allowedips, peer);
+ }
- return MNL_CB_OK;
+ return MNL_CB_OK;
}
-static int parse_peers(const struct nlattr* attr, void* data)
+static int parse_peers(const struct nlattr *attr, void *data)
{
- struct wgdevice* device = data;
- struct wgpeer* new_peer = calloc(1, sizeof(*new_peer));
- int ret;
+ struct wgdevice *device = data;
+ struct wgpeer *new_peer = calloc(1, sizeof(*new_peer));
+ int ret;
- if (!new_peer)
- {
- perror("calloc");
- return MNL_CB_ERROR;
- }
- if (!device->first_peer)
- device->first_peer = device->last_peer = new_peer;
- else
- {
- device->last_peer->next_peer = new_peer;
- device->last_peer = new_peer;
- }
- ret = mnl_attr_parse_nested(attr, parse_peer, new_peer);
- if (!ret)
- return ret;
- if (!(new_peer->flags & WGPEER_HAS_PUBLIC_KEY))
- return MNL_CB_ERROR;
- return MNL_CB_OK;
+ if (!new_peer) {
+ perror("calloc");
+ return MNL_CB_ERROR;
+ }
+ if (!device->first_peer)
+ device->first_peer = device->last_peer = new_peer;
+ else {
+ device->last_peer->next_peer = new_peer;
+ device->last_peer = new_peer;
+ }
+ ret = mnl_attr_parse_nested(attr, parse_peer, new_peer);
+ if (!ret)
+ return ret;
+ if (!(new_peer->flags & WGPEER_HAS_PUBLIC_KEY))
+ return MNL_CB_ERROR;
+ return MNL_CB_OK;
}
-static int parse_device(const struct nlattr* attr, void* data)
+static int parse_device(const struct nlattr *attr, void *data)
{
- struct wgdevice* device = data;
+ struct wgdevice *device = data;
- switch (mnl_attr_get_type(attr))
- {
- case WGDEVICE_A_UNSPEC:
- break;
- case WGDEVICE_A_IFINDEX:
- if (!mnl_attr_validate(attr, MNL_TYPE_U32))
- device->ifindex = mnl_attr_get_u32(attr);
- break;
- case WGDEVICE_A_IFNAME:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- strncpy(device->name, mnl_attr_get_str(attr), sizeof(device->name) - 1);
- device->name[sizeof(device->name) - 1] = '\0';
- }
- break;
- case WGDEVICE_A_PRIVATE_KEY:
- if (mnl_attr_get_payload_len(attr) == sizeof(device->private_key))
- {
- memcpy(
- device->private_key,
- mnl_attr_get_payload(attr),
- sizeof(device->private_key));
- device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
- }
- break;
- case WGDEVICE_A_PUBLIC_KEY:
- if (mnl_attr_get_payload_len(attr) == sizeof(device->public_key))
- {
- memcpy(
- device->public_key,
- mnl_attr_get_payload(attr),
- sizeof(device->public_key));
- device->flags |= WGDEVICE_HAS_PUBLIC_KEY;
- }
- break;
- case WGDEVICE_A_LISTEN_PORT:
- if (!mnl_attr_validate(attr, MNL_TYPE_U16))
- device->listen_port = mnl_attr_get_u16(attr);
- break;
- case WGDEVICE_A_FWMARK:
- if (!mnl_attr_validate(attr, MNL_TYPE_U32))
- device->fwmark = mnl_attr_get_u32(attr);
- break;
- case WGDEVICE_A_PEERS:
- return mnl_attr_parse_nested(attr, parse_peers, device);
- case WGDEVICE_A_JC:
- if (!mnl_attr_validate(attr, MNL_TYPE_U16))
- {
- device->junk_packet_count = mnl_attr_get_u16(attr);
- device->flags |= WGDEVICE_HAS_JC;
- }
- break;
- case WGDEVICE_A_JMIN:
- if (!mnl_attr_validate(attr, MNL_TYPE_U16))
- {
- device->junk_packet_min_size = mnl_attr_get_u16(attr);
- device->flags |= WGDEVICE_HAS_JMIN;
- }
- break;
- case WGDEVICE_A_JMAX:
- if (!mnl_attr_validate(attr, MNL_TYPE_U16))
- {
- device->junk_packet_max_size = mnl_attr_get_u16(attr);
- device->flags |= WGDEVICE_HAS_JMAX;
- }
- break;
- case WGDEVICE_A_S1:
- if (!mnl_attr_validate(attr, MNL_TYPE_U16))
- {
- device->init_packet_junk_size = mnl_attr_get_u16(attr);
- device->flags |= WGDEVICE_HAS_S1;
- }
- break;
- case WGDEVICE_A_S2:
- if (!mnl_attr_validate(attr, MNL_TYPE_U16))
- {
- device->response_packet_junk_size = mnl_attr_get_u16(attr);
- device->flags |= WGDEVICE_HAS_S2;
- }
- break;
- case WGDEVICE_A_H1:
- if (!mnl_attr_validate(attr, MNL_TYPE_U32))
- {
- device->init_packet_magic_header = mnl_attr_get_u32(attr);
- device->flags |= WGDEVICE_HAS_H1;
- }
- break;
- case WGDEVICE_A_H2:
- if (!mnl_attr_validate(attr, MNL_TYPE_U32))
- {
- device->response_packet_magic_header = mnl_attr_get_u32(attr);
- device->flags |= WGDEVICE_HAS_H2;
- }
- break;
- case WGDEVICE_A_H3:
- if (!mnl_attr_validate(attr, MNL_TYPE_U32))
- {
- device->underload_packet_magic_header = mnl_attr_get_u32(attr);
- device->flags |= WGDEVICE_HAS_H3;
- }
- break;
- case WGDEVICE_A_H4:
- if (!mnl_attr_validate(attr, MNL_TYPE_U32))
- {
- device->transport_packet_magic_header = mnl_attr_get_u32(attr);
- device->flags |= WGDEVICE_HAS_H4;
- }
- break;
- case WGDEVICE_A_I1:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->i1 = strdup(mnl_attr_get_str(attr));
- device->flags |= WGDEVICE_HAS_I1;
- }
- break;
- case WGDEVICE_A_I2:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->i2 = strdup(mnl_attr_get_str(attr));
- device->flags |= WGDEVICE_HAS_I2;
- }
- break;
- case WGDEVICE_A_I3:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->i3 = strdup(mnl_attr_get_str(attr));
- device->flags |= WGDEVICE_HAS_I3;
- }
- break;
- case WGDEVICE_A_I4:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->i4 = strdup(mnl_attr_get_str(attr));
- device->flags |= WGDEVICE_HAS_I4;
- }
- break;
- case WGDEVICE_A_I5:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->i5 = strdup(mnl_attr_get_str(attr));
- device->flags |= WGDEVICE_HAS_I5;
- }
- break;
- case WGDEVICE_A_J1:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->j1 = strdup(mnl_attr_get_str(attr));
- device->flags |= WGDEVICE_HAS_J1;
- }
- break;
- case WGDEVICE_A_J2:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->j2 = strdup(mnl_attr_get_str(attr));
- device->flags |= WGDEVICE_HAS_J2;
- }
- break;
- case WGDEVICE_A_J3:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->j3 = strdup(mnl_attr_get_str(attr));
- device->flags |= WGDEVICE_HAS_J3;
- }
- break;
- case WGDEVICE_A_ITIME:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
- {
- device->itime = mnl_attr_get_u32(attr);
- device->flags |= WGDEVICE_HAS_ITIME;
- }
- break;
- }
+ switch (mnl_attr_get_type(attr)) {
+ case WGDEVICE_A_UNSPEC:
+ break;
+ case WGDEVICE_A_IFINDEX:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32))
+ device->ifindex = mnl_attr_get_u32(attr);
+ break;
+ case WGDEVICE_A_IFNAME:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
+ strncpy(device->name, mnl_attr_get_str(attr), sizeof(device->name) - 1);
+ device->name[sizeof(device->name) - 1] = '\0';
+ }
+ break;
+ case WGDEVICE_A_PRIVATE_KEY:
+ if (mnl_attr_get_payload_len(attr) == sizeof(device->private_key)) {
+ memcpy(device->private_key, mnl_attr_get_payload(attr), sizeof(device->private_key));
+ device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
+ }
+ break;
+ case WGDEVICE_A_PUBLIC_KEY:
+ if (mnl_attr_get_payload_len(attr) == sizeof(device->public_key)) {
+ memcpy(device->public_key, mnl_attr_get_payload(attr), sizeof(device->public_key));
+ device->flags |= WGDEVICE_HAS_PUBLIC_KEY;
+ }
+ break;
+ case WGDEVICE_A_LISTEN_PORT:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16))
+ device->listen_port = mnl_attr_get_u16(attr);
+ break;
+ case WGDEVICE_A_FWMARK:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32))
+ device->fwmark = mnl_attr_get_u32(attr);
+ break;
+ case WGDEVICE_A_PEERS:
+ return mnl_attr_parse_nested(attr, parse_peers, device);
+ case WGDEVICE_A_JC:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16)) {
+ device->junk_packet_count = mnl_attr_get_u16(attr);
+ device->flags |= WGDEVICE_HAS_JC;
+ }
+ break;
+ case WGDEVICE_A_JMIN:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16)) {
+ device->junk_packet_min_size = mnl_attr_get_u16(attr);
+ device->flags |= WGDEVICE_HAS_JMIN;
+ }
+ break;
+ case WGDEVICE_A_JMAX:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16)) {
+ device->junk_packet_max_size = mnl_attr_get_u16(attr);
+ device->flags |= WGDEVICE_HAS_JMAX;
+ }
+ break;
+ case WGDEVICE_A_S1:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16)) {
+ device->init_packet_junk_size = mnl_attr_get_u16(attr);
+ device->flags |= WGDEVICE_HAS_S1;
+ }
+ break;
+ case WGDEVICE_A_S2:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16)) {
+ device->response_packet_junk_size = mnl_attr_get_u16(attr);
+ device->flags |= WGDEVICE_HAS_S2;
+ }
+ break;
+ case WGDEVICE_A_H1:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32)) {
+ device->init_packet_magic_header = mnl_attr_get_u32(attr);
+ device->flags |= WGDEVICE_HAS_H1;
+ }
+ break;
+ case WGDEVICE_A_H2:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32)) {
+ device->response_packet_magic_header = mnl_attr_get_u32(attr);
+ device->flags |= WGDEVICE_HAS_H2;
+ }
+ break;
+ case WGDEVICE_A_H3:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32)) {
+ device->underload_packet_magic_header = mnl_attr_get_u32(attr);
+ device->flags |= WGDEVICE_HAS_H3;
+ }
+ break;
+ case WGDEVICE_A_H4:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32)) {
+ device->transport_packet_magic_header = mnl_attr_get_u32(attr);
+ device->flags |= WGDEVICE_HAS_H4;
+ }
+ break;
+ case WGDEVICE_A_I1:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->i1 = strdup(mnl_attr_get_str(attr));
+ device->flags |= WGDEVICE_HAS_I1;
+ }
+ break;
+ case WGDEVICE_A_I2:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->i2 = strdup(mnl_attr_get_str(attr));
+ device->flags |= WGDEVICE_HAS_I2;
+ }
+ break;
+ case WGDEVICE_A_I3:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->i3 = strdup(mnl_attr_get_str(attr));
+ device->flags |= WGDEVICE_HAS_I3;
+ }
+ break;
+ case WGDEVICE_A_I4:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->i4 = strdup(mnl_attr_get_str(attr));
+ device->flags |= WGDEVICE_HAS_I4;
+ }
+ break;
+ case WGDEVICE_A_I5:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->i5 = strdup(mnl_attr_get_str(attr));
+ device->flags |= WGDEVICE_HAS_I5;
+ }
+ break;
+ case WGDEVICE_A_J1:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->j1 = strdup(mnl_attr_get_str(attr));
+ device->flags |= WGDEVICE_HAS_J1;
+ }
+ break;
+ case WGDEVICE_A_J2:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->j2 = strdup(mnl_attr_get_str(attr));
+ device->flags |= WGDEVICE_HAS_J2;
+ }
+ break;
+ case WGDEVICE_A_J3:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->j3 = strdup(mnl_attr_get_str(attr));
+ device->flags |= WGDEVICE_HAS_J3;
+ }
+ break;
+ case WGDEVICE_A_ITIME:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING))
+ {
+ device->itime = mnl_attr_get_u32(attr);
+ device->flags |= WGDEVICE_HAS_ITIME;
+ }
+ break;
+ }
- return MNL_CB_OK;
+ return MNL_CB_OK;
}
-static int read_device_cb(const struct nlmsghdr* nlh, void* data)
+static int read_device_cb(const struct nlmsghdr *nlh, void *data)
{
- return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_device, data);
+ return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_device, data);
}
-static void coalesce_peers(struct wgdevice* device)
+static void coalesce_peers(struct wgdevice *device)
{
- struct wgpeer *old_next_peer, *peer = device->first_peer;
+ struct wgpeer *old_next_peer, *peer = device->first_peer;
- while (peer && peer->next_peer)
- {
- if (memcmp(
- peer->public_key, peer->next_peer->public_key, sizeof(peer->public_key)))
- {
- peer = peer->next_peer;
- continue;
- }
- if (!peer->first_allowedip)
- {
- peer->first_allowedip = peer->next_peer->first_allowedip;
- peer->last_allowedip = peer->next_peer->last_allowedip;
- }
- else
- {
- peer->last_allowedip->next_allowedip = peer->next_peer->first_allowedip;
- peer->last_allowedip = peer->next_peer->last_allowedip;
- }
- old_next_peer = peer->next_peer;
- peer->next_peer = old_next_peer->next_peer;
- free(old_next_peer);
- }
+ while (peer && peer->next_peer) {
+ if (memcmp(peer->public_key, peer->next_peer->public_key, sizeof(peer->public_key))) {
+ peer = peer->next_peer;
+ continue;
+ }
+ if (!peer->first_allowedip) {
+ peer->first_allowedip = peer->next_peer->first_allowedip;
+ peer->last_allowedip = peer->next_peer->last_allowedip;
+ } else {
+ peer->last_allowedip->next_allowedip = peer->next_peer->first_allowedip;
+ peer->last_allowedip = peer->next_peer->last_allowedip;
+ }
+ old_next_peer = peer->next_peer;
+ peer->next_peer = old_next_peer->next_peer;
+ free(old_next_peer);
+ }
}
-static int kernel_get_device(struct wgdevice** device, const char* iface)
+static int kernel_get_device(struct wgdevice **device, const char *iface)
{
- int ret;
- struct nlmsghdr* nlh;
- struct mnlg_socket* nlg;
+ int ret;
+ struct nlmsghdr *nlh;
+ struct mnlg_socket *nlg;
- /* libmnl doesn't check the buffer size, so enforce that before using. */
- if (strlen(iface) >= IFNAMSIZ)
- {
- errno = ENAMETOOLONG;
- return -ENAMETOOLONG;
- }
+ /* libmnl doesn't check the buffer size, so enforce that before using. */
+ if (strlen(iface) >= IFNAMSIZ) {
+ errno = ENAMETOOLONG;
+ return -ENAMETOOLONG;
+ }
try_again:
- ret = 0;
- *device = calloc(1, sizeof(**device));
- if (!*device)
- return -errno;
+ ret = 0;
+ *device = calloc(1, sizeof(**device));
+ if (!*device)
+ return -errno;
- nlg = mnlg_socket_open(WG_GENL_NAME, WG_GENL_VERSION);
- if (!nlg)
- {
- free_wgdevice(*device);
- *device = NULL;
- return -errno;
- }
+ nlg = mnlg_socket_open(WG_GENL_NAME, WG_GENL_VERSION);
+ if (!nlg) {
+ free_wgdevice(*device);
+ *device = NULL;
+ return -errno;
+ }
- nlh =
- mnlg_msg_prepare(nlg, WG_CMD_GET_DEVICE, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
- mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, iface);
- if (mnlg_socket_send(nlg, nlh) < 0)
- {
- ret = -errno;
- goto out;
- }
- errno = 0;
- if (mnlg_socket_recv_run(nlg, read_device_cb, *device) < 0)
- {
- ret = errno ? -errno : -EINVAL;
- goto out;
- }
- coalesce_peers(*device);
+ nlh = mnlg_msg_prepare(nlg, WG_CMD_GET_DEVICE, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
+ mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, iface);
+ if (mnlg_socket_send(nlg, nlh) < 0) {
+ ret = -errno;
+ goto out;
+ }
+ errno = 0;
+ if (mnlg_socket_recv_run(nlg, read_device_cb, *device) < 0) {
+ ret = errno ? -errno : -EINVAL;
+ goto out;
+ }
+ coalesce_peers(*device);
out:
- if (nlg)
- mnlg_socket_close(nlg);
- if (ret)
- {
- free_wgdevice(*device);
- if (ret == -EINTR)
- goto try_again;
- *device = NULL;
- }
- errno = -ret;
- return ret;
+ if (nlg)
+ mnlg_socket_close(nlg);
+ if (ret) {
+ free_wgdevice(*device);
+ if (ret == -EINTR)
+ goto try_again;
+ *device = NULL;
+ }
+ errno = -ret;
+ return ret;
}
diff --git a/src/ipc-openbsd.h b/src/ipc-openbsd.h
index 6a8e80a..c0f1e7b 100644
--- a/src/ipc-openbsd.h
+++ b/src/ipc-openbsd.h
@@ -3,521 +3,478 @@
* Copyright (C) 2015-2020 Jason A. Donenfeld . All Rights Reserved.
*/
-#include "containers.h"
#include
-#include
-#include
-#include
#include
#include
#include
+#include
#include
#include
#include
#include
-#include
+#include
+#include
+#include
+#include "containers.h"
#define IPC_SUPPORTS_KERNEL_INTERFACE
static int get_dgram_socket(void)
{
- static int sock = -1;
- if (sock < 0)
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- return sock;
+ static int sock = -1;
+ if (sock < 0)
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ return sock;
}
-static int kernel_get_wireguard_interfaces(struct string_list* list)
+static int kernel_get_wireguard_interfaces(struct string_list *list)
{
- struct ifgroupreq ifgr = {.ifgr_name = "wg"};
- struct ifg_req* ifg;
- int s = get_dgram_socket(), ret = 0;
+ struct ifgroupreq ifgr = { .ifgr_name = "wg" };
+ struct ifg_req *ifg;
+ int s = get_dgram_socket(), ret = 0;
- if (s < 0)
- return -errno;
+ if (s < 0)
+ return -errno;
- if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
- return errno == ENOENT ? 0 : -errno;
+ if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
+ return errno == ENOENT ? 0 : -errno;
- ifgr.ifgr_groups = calloc(1, ifgr.ifgr_len);
- if (!ifgr.ifgr_groups)
- return -errno;
- if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
- {
- ret = -errno;
- goto out;
- }
+ ifgr.ifgr_groups = calloc(1, ifgr.ifgr_len);
+ if (!ifgr.ifgr_groups)
+ return -errno;
+ if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0) {
+ ret = -errno;
+ goto out;
+ }
- for (ifg = ifgr.ifgr_groups; ifg && ifgr.ifgr_len > 0; ++ifg)
- {
- if ((ret = string_list_add(list, ifg->ifgrq_member)) < 0)
- goto out;
- ifgr.ifgr_len -= sizeof(struct ifg_req);
- }
+ for (ifg = ifgr.ifgr_groups; ifg && ifgr.ifgr_len > 0; ++ifg) {
+ if ((ret = string_list_add(list, ifg->ifgrq_member)) < 0)
+ goto out;
+ ifgr.ifgr_len -= sizeof(struct ifg_req);
+ }
out:
- free(ifgr.ifgr_groups);
- return ret;
+ free(ifgr.ifgr_groups);
+ return ret;
}
-static int kernel_get_device(struct wgdevice** device, const char* iface)
+static int kernel_get_device(struct wgdevice **device, const char *iface)
{
- struct wg_data_io wgdata = {.wgd_size = 0};
- struct wg_interface_io* wg_iface;
- struct wg_peer_io* wg_peer;
- struct wg_aip_io* wg_aip;
- struct wgdevice* dev;
- struct wgpeer* peer;
- struct wgallowedip* aip;
- int s = get_dgram_socket(), ret;
+ struct wg_data_io wgdata = { .wgd_size = 0 };
+ struct wg_interface_io *wg_iface;
+ struct wg_peer_io *wg_peer;
+ struct wg_aip_io *wg_aip;
+ struct wgdevice *dev;
+ struct wgpeer *peer;
+ struct wgallowedip *aip;
+ int s = get_dgram_socket(), ret;
- if (s < 0)
- return -errno;
+ if (s < 0)
+ return -errno;
- *device = NULL;
- strlcpy(wgdata.wgd_name, iface, sizeof(wgdata.wgd_name));
- for (size_t last_size = wgdata.wgd_size;; last_size = wgdata.wgd_size)
- {
- if (ioctl(s, SIOCGWG, (caddr_t)&wgdata) < 0)
- goto out;
- if (last_size >= wgdata.wgd_size)
- break;
- wgdata.wgd_interface = realloc(wgdata.wgd_interface, wgdata.wgd_size);
- if (!wgdata.wgd_interface)
- goto out;
- }
+ *device = NULL;
+ strlcpy(wgdata.wgd_name, iface, sizeof(wgdata.wgd_name));
+ for (size_t last_size = wgdata.wgd_size;; last_size = wgdata.wgd_size) {
+ if (ioctl(s, SIOCGWG, (caddr_t)&wgdata) < 0)
+ goto out;
+ if (last_size >= wgdata.wgd_size)
+ break;
+ wgdata.wgd_interface = realloc(wgdata.wgd_interface, wgdata.wgd_size);
+ if (!wgdata.wgd_interface)
+ goto out;
+ }
- wg_iface = wgdata.wgd_interface;
- dev = calloc(1, sizeof(*dev));
- if (!dev)
- goto out;
- strlcpy(dev->name, iface, sizeof(dev->name));
+ wg_iface = wgdata.wgd_interface;
+ dev = calloc(1, sizeof(*dev));
+ if (!dev)
+ goto out;
+ strlcpy(dev->name, iface, sizeof(dev->name));
- if (wg_iface->i_flags & WG_INTERFACE_HAS_RTABLE)
- {
- dev->fwmark = wg_iface->i_rtable;
- dev->flags |= WGDEVICE_HAS_FWMARK;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_HAS_RTABLE) {
+ dev->fwmark = wg_iface->i_rtable;
+ dev->flags |= WGDEVICE_HAS_FWMARK;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_HAS_PORT)
- {
- dev->listen_port = wg_iface->i_port;
- dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_HAS_PORT) {
+ dev->listen_port = wg_iface->i_port;
+ dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_HAS_PUBLIC)
- {
- memcpy(dev->public_key, wg_iface->i_public, sizeof(dev->public_key));
- dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_HAS_PUBLIC) {
+ memcpy(dev->public_key, wg_iface->i_public, sizeof(dev->public_key));
+ dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_HAS_PRIVATE)
- {
- memcpy(dev->private_key, wg_iface->i_private, sizeof(dev->private_key));
- dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_HAS_PRIVATE) {
+ memcpy(dev->private_key, wg_iface->i_private, sizeof(dev->private_key));
+ dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_JC)
- {
- dev->junk_packet_count = wg_iface->i_junk_packet_count;
- dev->flags |= WGDEVICE_HAS_JC;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_JC) {
+ dev->junk_packet_count = wg_iface->i_junk_packet_count;
+ dev->flags |= WGDEVICE_HAS_JC;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_JMIN)
- {
- dev->junk_packet_min_size = wg_iface->i_junk_packet_min_size;
- dev->flags |= WGDEVICE_HAS_JMIN;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_JMIN) {
+ dev->junk_packet_min_size = wg_iface->i_junk_packet_min_size;
+ dev->flags |= WGDEVICE_HAS_JMIN;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_JMAX)
- {
- dev->junk_packet_max_size = wg_iface->i_junk_packet_max_size;
- dev->flags |= WGDEVICE_HAS_JMAX;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_JMAX) {
+ dev->junk_packet_max_size = wg_iface->i_junk_packet_max_size;
+ dev->flags |= WGDEVICE_HAS_JMAX;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_S1)
- {
- dev->init_packet_junk_size = wg_iface->i_init_packet_junk_size;
- dev->flags |= WGDEVICE_HAS_S1;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_S1) {
+ dev->init_packet_junk_size = wg_iface->i_init_packet_junk_size;
+ dev->flags |= WGDEVICE_HAS_S1;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_S2)
- {
- dev->response_packet_junk_size = wg_iface->i_response_packet_junk_size;
- dev->flags |= WGDEVICE_HAS_S2;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_S2) {
+ dev->response_packet_junk_size = wg_iface->i_response_packet_junk_size;
+ dev->flags |= WGDEVICE_HAS_S2;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H1)
- {
- dev->init_packet_magic_header = wg_iface->i_init_packet_magic_header;
- dev->flags |= WGDEVICE_HAS_H1;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H1) {
+ dev->init_packet_magic_header = wg_iface->i_init_packet_magic_header;
+ dev->flags |= WGDEVICE_HAS_H1;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H2)
- {
- dev->response_packet_magic_header = wg_iface->i_response_packet_magic_header;
- dev->flags |= WGDEVICE_HAS_H2;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H2) {
+ dev->response_packet_magic_header = wg_iface->i_response_packet_magic_header;
+ dev->flags |= WGDEVICE_HAS_H2;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H3)
- {
- dev->underload_packet_magic_header = wg_iface->i_underload_packet_magic_header;
- dev->flags |= WGDEVICE_HAS_H3;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H3) {
+ dev->underload_packet_magic_header = wg_iface->i_underload_packet_magic_header;
+ dev->flags |= WGDEVICE_HAS_H3;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H4)
- {
- dev->transport_packet_magic_header = wg_iface->i_transport_packet_magic_header;
- dev->flags |= WGDEVICE_HAS_H4;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H4) {
+ dev->transport_packet_magic_header = wg_iface->i_transport_packet_magic_header;
+ dev->flags |= WGDEVICE_HAS_H4;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I1)
- {
- wg_iface->i_i1 = strdup(dev->i1);
- wg_iface->i_flags |= WGDEVICE_HAS_I1;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I1)
+ {
+ wg_iface->i_i1 = strdup(dev->i1);
+ wg_iface->i_flags |= WGDEVICE_HAS_I1;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I2)
- {
- wg_iface->i_i2 = strdup(dev->i2);
- wg_iface->i_flags |= WGDEVICE_HAS_I2;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I2)
+ {
+ wg_iface->i_i2 = strdup(dev->i2);
+ wg_iface->i_flags |= WGDEVICE_HAS_I2;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I3)
- {
- wg_iface->i_i3 = strdup(dev->i3);
- wg_iface->i_flags |= WGDEVICE_HAS_I3;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I3)
+ {
+ wg_iface->i_i3 = strdup(dev->i3);
+ wg_iface->i_flags |= WGDEVICE_HAS_I3;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I4)
- {
- wg_iface->i_i4 = strdup(dev->i4);
- wg_iface->i_flags |= WGDEVICE_HAS_I4;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I4)
+ {
+ wg_iface->i_i4 = strdup(dev->i4);
+ wg_iface->i_flags |= WGDEVICE_HAS_I4;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I5)
- {
- wg_iface->i_i5 = strdup(dev->i5);
- wg_iface->i_flags |= WGDEVICE_HAS_I5;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I5)
+ {
+ wg_iface->i_i5 = strdup(dev->i5);
+ wg_iface->i_flags |= WGDEVICE_HAS_I5;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J1)
- {
- wg_iface->i_j1 = strdup(dev->j1);
- wg_iface->i_flags |= WGDEVICE_HAS_J1;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J1)
+ {
+ wg_iface->i_j1 = strdup(dev->j1);
+ wg_iface->i_flags |= WGDEVICE_HAS_J1;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J2)
- {
- wg_iface->i_j2 = strdup(dev->j2);
- wg_iface->i_flags |= WGDEVICE_HAS_J2;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J2)
+ {
+ wg_iface->i_j2 = strdup(dev->j2);
+ wg_iface->i_flags |= WGDEVICE_HAS_J2;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J3)
- {
- wg_iface->i_j3 = strdup(dev->j3);
- wg_iface->i_flags |= WGDEVICE_HAS_J3;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J3)
+ {
+ wg_iface->i_j3 = strdup(dev->j3);
+ wg_iface->i_flags |= WGDEVICE_HAS_J3;
+ }
- if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_ITIME)
- {
- wg_iface->i_itime = dev->itime;
- wg_iface->i_flags |= WGDEVICE_HAS_ITIME;
- }
+ if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_ITIME)
+ {
+ wg_iface->i_itime = dev->itime;
+ wg_iface->i_flags |= WGDEVICE_HAS_ITIME;
+ }
- wg_peer = &wg_iface->i_peers[0];
- for (size_t i = 0; i < wg_iface->i_peers_count; ++i)
- {
- peer = calloc(1, sizeof(*peer));
- if (!peer)
- goto out;
+ wg_peer = &wg_iface->i_peers[0];
+ for (size_t i = 0; i < wg_iface->i_peers_count; ++i) {
+ peer = calloc(1, sizeof(*peer));
+ if (!peer)
+ goto out;
- if (dev->first_peer == NULL)
- dev->first_peer = peer;
- else
- dev->last_peer->next_peer = peer;
- dev->last_peer = peer;
+ if (dev->first_peer == NULL)
+ dev->first_peer = peer;
+ else
+ dev->last_peer->next_peer = peer;
+ dev->last_peer = peer;
- if (wg_peer->p_flags & WG_PEER_HAS_PUBLIC)
- {
- memcpy(peer->public_key, wg_peer->p_public, sizeof(peer->public_key));
- peer->flags |= WGPEER_HAS_PUBLIC_KEY;
- }
+ if (wg_peer->p_flags & WG_PEER_HAS_PUBLIC) {
+ memcpy(peer->public_key, wg_peer->p_public, sizeof(peer->public_key));
+ peer->flags |= WGPEER_HAS_PUBLIC_KEY;
+ }
- if (wg_peer->p_flags & WG_PEER_HAS_PSK)
- {
- memcpy(peer->preshared_key, wg_peer->p_psk, sizeof(peer->preshared_key));
- if (!key_is_zero(peer->preshared_key))
- peer->flags |= WGPEER_HAS_PRESHARED_KEY;
- }
+ if (wg_peer->p_flags & WG_PEER_HAS_PSK) {
+ memcpy(peer->preshared_key, wg_peer->p_psk, sizeof(peer->preshared_key));
+ if (!key_is_zero(peer->preshared_key))
+ peer->flags |= WGPEER_HAS_PRESHARED_KEY;
+ }
- if (wg_peer->p_flags & WG_PEER_HAS_PKA)
- {
- peer->persistent_keepalive_interval = wg_peer->p_pka;
- peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
- }
+ if (wg_peer->p_flags & WG_PEER_HAS_PKA) {
+ peer->persistent_keepalive_interval = wg_peer->p_pka;
+ peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
+ }
- if (wg_peer->p_flags & WG_PEER_HAS_ENDPOINT &&
- wg_peer->p_sa.sa_len <= sizeof(peer->endpoint.addr))
- memcpy(&peer->endpoint.addr, &wg_peer->p_sa, wg_peer->p_sa.sa_len);
+ if (wg_peer->p_flags & WG_PEER_HAS_ENDPOINT && wg_peer->p_sa.sa_len <= sizeof(peer->endpoint.addr))
+ memcpy(&peer->endpoint.addr, &wg_peer->p_sa, wg_peer->p_sa.sa_len);
- peer->rx_bytes = wg_peer->p_rxbytes;
- peer->tx_bytes = wg_peer->p_txbytes;
+ peer->rx_bytes = wg_peer->p_rxbytes;
+ peer->tx_bytes = wg_peer->p_txbytes;
- peer->last_handshake_time.tv_sec = wg_peer->p_last_handshake.tv_sec;
- peer->last_handshake_time.tv_nsec = wg_peer->p_last_handshake.tv_nsec;
+ peer->last_handshake_time.tv_sec = wg_peer->p_last_handshake.tv_sec;
+ peer->last_handshake_time.tv_nsec = wg_peer->p_last_handshake.tv_nsec;
- wg_aip = &wg_peer->p_aips[0];
- for (size_t j = 0; j < wg_peer->p_aips_count; ++j)
- {
- aip = calloc(1, sizeof(*aip));
- if (!aip)
- goto out;
+ wg_aip = &wg_peer->p_aips[0];
+ for (size_t j = 0; j < wg_peer->p_aips_count; ++j) {
+ aip = calloc(1, sizeof(*aip));
+ if (!aip)
+ goto out;
- if (peer->first_allowedip == NULL)
- peer->first_allowedip = aip;
- else
- peer->last_allowedip->next_allowedip = aip;
- peer->last_allowedip = aip;
+ if (peer->first_allowedip == NULL)
+ peer->first_allowedip = aip;
+ else
+ peer->last_allowedip->next_allowedip = aip;
+ peer->last_allowedip = aip;
- aip->family = wg_aip->a_af;
- if (wg_aip->a_af == AF_INET)
- {
- memcpy(&aip->ip4, &wg_aip->a_ipv4, sizeof(aip->ip4));
- aip->cidr = wg_aip->a_cidr;
- }
- else if (wg_aip->a_af == AF_INET6)
- {
- memcpy(&aip->ip6, &wg_aip->a_ipv6, sizeof(aip->ip6));
- aip->cidr = wg_aip->a_cidr;
- }
- ++wg_aip;
- }
- wg_peer = (struct wg_peer_io*)wg_aip;
- }
- *device = dev;
- errno = 0;
+ aip->family = wg_aip->a_af;
+ if (wg_aip->a_af == AF_INET) {
+ memcpy(&aip->ip4, &wg_aip->a_ipv4, sizeof(aip->ip4));
+ aip->cidr = wg_aip->a_cidr;
+ } else if (wg_aip->a_af == AF_INET6) {
+ memcpy(&aip->ip6, &wg_aip->a_ipv6, sizeof(aip->ip6));
+ aip->cidr = wg_aip->a_cidr;
+ }
+ ++wg_aip;
+ }
+ wg_peer = (struct wg_peer_io *)wg_aip;
+ }
+ *device = dev;
+ errno = 0;
out:
- ret = -errno;
- free(wgdata.wgd_interface);
- return ret;
+ ret = -errno;
+ free(wgdata.wgd_interface);
+ return ret;
}
-static int kernel_set_device(struct wgdevice* dev)
+static int kernel_set_device(struct wgdevice *dev)
{
- struct wg_data_io wgdata = {.wgd_size = sizeof(struct wg_interface_io)};
- struct wg_interface_io* wg_iface;
- struct wg_peer_io* wg_peer;
- struct wg_aip_io* wg_aip;
- struct wgpeer* peer;
- struct wgallowedip* aip;
- int s = get_dgram_socket(), ret;
- size_t peer_count, aip_count;
+ struct wg_data_io wgdata = { .wgd_size = sizeof(struct wg_interface_io) };
+ struct wg_interface_io *wg_iface;
+ struct wg_peer_io *wg_peer;
+ struct wg_aip_io *wg_aip;
+ struct wgpeer *peer;
+ struct wgallowedip *aip;
+ int s = get_dgram_socket(), ret;
+ size_t peer_count, aip_count;
- if (s < 0)
- return -errno;
+ if (s < 0)
+ return -errno;
- for_each_wgpeer(dev, peer)
- {
- wgdata.wgd_size += sizeof(struct wg_peer_io);
- for_each_wgallowedip(peer, aip) wgdata.wgd_size += sizeof(struct wg_aip_io);
- }
- wg_iface = wgdata.wgd_interface = calloc(1, wgdata.wgd_size);
- if (!wgdata.wgd_interface)
- return -errno;
- strlcpy(wgdata.wgd_name, dev->name, sizeof(wgdata.wgd_name));
+ for_each_wgpeer(dev, peer) {
+ wgdata.wgd_size += sizeof(struct wg_peer_io);
+ for_each_wgallowedip(peer, aip)
+ wgdata.wgd_size += sizeof(struct wg_aip_io);
+ }
+ wg_iface = wgdata.wgd_interface = calloc(1, wgdata.wgd_size);
+ if (!wgdata.wgd_interface)
+ return -errno;
+ strlcpy(wgdata.wgd_name, dev->name, sizeof(wgdata.wgd_name));
- if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
- {
- memcpy(wg_iface->i_private, dev->private_key, sizeof(wg_iface->i_private));
- wg_iface->i_flags |= WG_INTERFACE_HAS_PRIVATE;
- }
+ if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
+ memcpy(wg_iface->i_private, dev->private_key, sizeof(wg_iface->i_private));
+ wg_iface->i_flags |= WG_INTERFACE_HAS_PRIVATE;
+ }
- if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
- {
- wg_iface->i_port = dev->listen_port;
- wg_iface->i_flags |= WG_INTERFACE_HAS_PORT;
- }
+ if (dev->flags & WGDEVICE_HAS_LISTEN_PORT) {
+ wg_iface->i_port = dev->listen_port;
+ wg_iface->i_flags |= WG_INTERFACE_HAS_PORT;
+ }
- if (dev->flags & WGDEVICE_HAS_FWMARK)
- {
- wg_iface->i_rtable = dev->fwmark;
- wg_iface->i_flags |= WG_INTERFACE_HAS_RTABLE;
- }
+ if (dev->flags & WGDEVICE_HAS_FWMARK) {
+ wg_iface->i_rtable = dev->fwmark;
+ wg_iface->i_flags |= WG_INTERFACE_HAS_RTABLE;
+ }
- if (dev->flags & WGDEVICE_REPLACE_PEERS)
- wg_iface->i_flags |= WG_INTERFACE_REPLACE_PEERS;
+ if (dev->flags & WGDEVICE_REPLACE_PEERS)
+ wg_iface->i_flags |= WG_INTERFACE_REPLACE_PEERS;
- if (dev->flags & WGDEVICE_HAS_JC)
- {
- wg_iface->i_junk_packet_count = dev->junk_packet_count;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JC;
- }
- if (dev->flags & WGDEVICE_HAS_JMIN)
- {
- wg_iface->i_junk_packet_min_size = dev->junk_packet_min_size;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JMIN;
- }
+ if (dev->flags & WGDEVICE_HAS_JC) {
+ wg_iface->i_junk_packet_count = dev->junk_packet_count;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JC;
+ }
- if (dev->flags & WGDEVICE_HAS_JMAX)
- {
- wg_iface->i_junk_packet_max_size = dev->junk_packet_max_size;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JMAX;
- }
+ if (dev->flags & WGDEVICE_HAS_JMIN) {
+ wg_iface->i_junk_packet_min_size = dev->junk_packet_min_size;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JMIN;
+ }
- if (dev->flags & WGDEVICE_HAS_S1)
- {
- wg_iface->i_init_packet_junk_size = dev->init_packet_junk_size;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S1;
- }
+ if (dev->flags & WGDEVICE_HAS_JMAX) {
+ wg_iface->i_junk_packet_max_size = dev->junk_packet_max_size;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JMAX;
+ }
- if (dev->flags & WGDEVICE_HAS_S2)
- {
- wg_iface->i_response_packet_junk_size = dev->response_packet_junk_size;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S2;
- }
+ if (dev->flags & WGDEVICE_HAS_S1) {
+ wg_iface->i_init_packet_junk_size = dev->init_packet_junk_size;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S1;
+ }
- if (dev->flags & WGDEVICE_HAS_H1)
- {
- wg_iface->i_init_packet_magic_header = dev->init_packet_magic_header;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H1;
- }
+ if (dev->flags & WGDEVICE_HAS_S2) {
+ wg_iface->i_response_packet_junk_size = dev->response_packet_junk_size;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S2;
+ }
- if (dev->flags & WGDEVICE_HAS_H2)
- {
- wg_iface->i_response_packet_magic_header = dev->response_packet_magic_header;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H2;
- }
+ if (dev->flags & WGDEVICE_HAS_H1) {
+ wg_iface->i_init_packet_magic_header = dev->init_packet_magic_header;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H1;
+ }
- if (dev->flags & WGDEVICE_HAS_H3)
- {
- wg_iface->i_underload_packet_magic_header = dev->underload_packet_magic_header;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H3;
- }
+ if (dev->flags & WGDEVICE_HAS_H2) {
+ wg_iface->i_response_packet_magic_header = dev->response_packet_magic_header;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H2;
+ }
- if (dev->flags & WGDEVICE_HAS_H4)
- {
- wg_iface->i_transport_packet_magic_header = dev->transport_packet_magic_header;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H4;
- }
+ if (dev->flags & WGDEVICE_HAS_H3) {
+ wg_iface->i_underload_packet_magic_header = dev->underload_packet_magic_header;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H3;
+ }
- if (dev->flags & WGDEVICE_HAS_I1)
- {
- wg_iface->i_i1 = strdup(dev->i1);
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I1;
- }
+ if (dev->flags & WGDEVICE_HAS_H4) {
+ wg_iface->i_transport_packet_magic_header = dev->transport_packet_magic_header;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H4;
+ }
- if (dev->flags & WGDEVICE_HAS_I2)
- {
- wg_iface->i_i2 = strdup(dev->i2);
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I2;
- }
+ if (dev->flags & WGDEVICE_HAS_I1)
+ {
+ wg_iface->i_i1 = strdup(dev->i1);
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I1;
+ }
- if (dev->flags & WGDEVICE_HAS_I3)
- {
- wg_iface->i_i3 = strdup(dev->i3);
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I3;
- }
+ if (dev->flags & WGDEVICE_HAS_I2)
+ {
+ wg_iface->i_i2 = strdup(dev->i2);
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I2;
+ }
- if (dev->flags & WGDEVICE_HAS_I4)
- {
- wg_iface->i_i4 = strdup(dev->i4);
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I4;
- }
+ if (dev->flags & WGDEVICE_HAS_I3)
+ {
+ wg_iface->i_i3 = strdup(dev->i3);
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I3;
+ }
- if (dev->flags & WGDEVICE_HAS_I5)
- {
- wg_iface->i_i5 = strdup(dev->i5);
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I5;
- }
+ if (dev->flags & WGDEVICE_HAS_I4)
+ {
+ wg_iface->i_i4 = strdup(dev->i4);
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I4;
+ }
- if (dev->flags & WGDEVICE_HAS_J1)
- {
- wg_iface->i_j1 = strdup(dev->j1);
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J1;
- }
+ if (dev->flags & WGDEVICE_HAS_I5)
+ {
+ wg_iface->i_i5 = strdup(dev->i5);
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I5;
+ }
- if (dev->flags & WGDEVICE_HAS_J2)
- {
- wg_iface->i_j2 = strdup(dev->j2);
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J2;
- }
+ if (dev->flags & WGDEVICE_HAS_J1)
+ {
+ wg_iface->i_j1 = strdup(dev->j1);
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J1;
+ }
- if (dev->flags & WGDEVICE_HAS_J3)
- {
- wg_iface->i_j3 = strdup(dev->j3);
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J3;
- }
+ if (dev->flags & WGDEVICE_HAS_J2)
+ {
+ wg_iface->i_j2 = strdup(dev->j2);
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J2;
+ }
- if (dev->flags & WGDEVICE_HAS_ITIME)
- {
- wg_iface->i_itime = dev->itime;
- wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_ITIME;
- }
+ if (dev->flags & WGDEVICE_HAS_J3)
+ {
+ wg_iface->i_j3 = strdup(dev->j3);
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J3;
+ }
- peer_count = 0;
- wg_peer = &wg_iface->i_peers[0];
- for_each_wgpeer(dev, peer)
- {
- wg_peer->p_flags = WG_PEER_HAS_PUBLIC;
- memcpy(wg_peer->p_public, peer->public_key, sizeof(wg_peer->p_public));
+ if (dev->flags & WGDEVICE_HAS_ITIME)
+ {
+ wg_iface->i_itime = dev->itime;
+ wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_ITIME;
+ }
- if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
- {
- memcpy(wg_peer->p_psk, peer->preshared_key, sizeof(wg_peer->p_psk));
- wg_peer->p_flags |= WG_PEER_HAS_PSK;
- }
+ peer_count = 0;
+ wg_peer = &wg_iface->i_peers[0];
+ for_each_wgpeer(dev, peer) {
+ wg_peer->p_flags = WG_PEER_HAS_PUBLIC;
+ memcpy(wg_peer->p_public, peer->public_key, sizeof(wg_peer->p_public));
- if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
- {
- wg_peer->p_pka = peer->persistent_keepalive_interval;
- wg_peer->p_flags |= WG_PEER_HAS_PKA;
- }
+ if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
+ memcpy(wg_peer->p_psk, peer->preshared_key, sizeof(wg_peer->p_psk));
+ wg_peer->p_flags |= WG_PEER_HAS_PSK;
+ }
- if ((peer->endpoint.addr.sa_family == AF_INET ||
- peer->endpoint.addr.sa_family == AF_INET6) &&
- peer->endpoint.addr.sa_len <= sizeof(wg_peer->p_endpoint))
- {
- memcpy(
- &wg_peer->p_endpoint, &peer->endpoint.addr, peer->endpoint.addr.sa_len);
- wg_peer->p_flags |= WG_PEER_HAS_ENDPOINT;
- }
+ if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL) {
+ wg_peer->p_pka = peer->persistent_keepalive_interval;
+ wg_peer->p_flags |= WG_PEER_HAS_PKA;
+ }
- if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
- wg_peer->p_flags |= WG_PEER_REPLACE_AIPS;
+ if ((peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6) &&
+ peer->endpoint.addr.sa_len <= sizeof(wg_peer->p_endpoint)) {
+ memcpy(&wg_peer->p_endpoint, &peer->endpoint.addr, peer->endpoint.addr.sa_len);
+ wg_peer->p_flags |= WG_PEER_HAS_ENDPOINT;
+ }
- if (peer->flags & WGPEER_REMOVE_ME)
- wg_peer->p_flags |= WG_PEER_REMOVE;
+ if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
+ wg_peer->p_flags |= WG_PEER_REPLACE_AIPS;
- aip_count = 0;
- wg_aip = &wg_peer->p_aips[0];
- for_each_wgallowedip(peer, aip)
- {
- wg_aip->a_af = aip->family;
- wg_aip->a_cidr = aip->cidr;
+ if (peer->flags & WGPEER_REMOVE_ME)
+ wg_peer->p_flags |= WG_PEER_REMOVE;
- if (aip->family == AF_INET)
- memcpy(&wg_aip->a_ipv4, &aip->ip4, sizeof(wg_aip->a_ipv4));
- else if (aip->family == AF_INET6)
- memcpy(&wg_aip->a_ipv6, &aip->ip6, sizeof(wg_aip->a_ipv6));
- else
- continue;
- ++aip_count;
- ++wg_aip;
- }
- wg_peer->p_aips_count = aip_count;
- ++peer_count;
- wg_peer = (struct wg_peer_io*)wg_aip;
- }
- wg_iface->i_peers_count = peer_count;
+ aip_count = 0;
+ wg_aip = &wg_peer->p_aips[0];
+ for_each_wgallowedip(peer, aip) {
+ wg_aip->a_af = aip->family;
+ wg_aip->a_cidr = aip->cidr;
- if (ioctl(s, SIOCSWG, (caddr_t)&wgdata) < 0)
- goto out;
- errno = 0;
+ if (aip->family == AF_INET)
+ memcpy(&wg_aip->a_ipv4, &aip->ip4, sizeof(wg_aip->a_ipv4));
+ else if (aip->family == AF_INET6)
+ memcpy(&wg_aip->a_ipv6, &aip->ip6, sizeof(wg_aip->a_ipv6));
+ else
+ continue;
+ ++aip_count;
+ ++wg_aip;
+ }
+ wg_peer->p_aips_count = aip_count;
+ ++peer_count;
+ wg_peer = (struct wg_peer_io *)wg_aip;
+ }
+ wg_iface->i_peers_count = peer_count;
+
+ if (ioctl(s, SIOCSWG, (caddr_t)&wgdata) < 0)
+ goto out;
+ errno = 0;
out:
- ret = -errno;
- free(wgdata.wgd_interface);
- return ret;
+ ret = -errno;
+ free(wgdata.wgd_interface);
+ return ret;
}
diff --git a/src/ipc-uapi.h b/src/ipc-uapi.h
index 563243f..2060c51 100644
--- a/src/ipc-uapi.h
+++ b/src/ipc-uapi.h
@@ -3,10 +3,6 @@
* Copyright (C) 2015-2020 Jason A. Donenfeld . All Rights Reserved.
*/
-#include "containers.h"
-#include "ctype.h"
-#include "curve25519.h"
-#include "encoding.h"
#include
#include
#include
@@ -18,6 +14,10 @@
#include
#include
#include
+#include "containers.h"
+#include "curve25519.h"
+#include "encoding.h"
+#include "ctype.h"
#ifdef _WIN32
#include "ipc-uapi-windows.h"
@@ -25,467 +25,381 @@
#include "ipc-uapi-unix.h"
#endif
-static int userspace_set_device(struct wgdevice* dev)
+static int userspace_set_device(struct wgdevice *dev)
{
- char hex[WG_KEY_LEN_HEX], ip[INET6_ADDRSTRLEN], host[4096 + 1], service[512 + 1];
- struct wgpeer* peer;
- struct wgallowedip* allowedip;
- FILE* f;
- int ret, set_errno = -EPROTO;
- socklen_t addr_len;
- size_t line_buffer_len = 0, line_len;
- char * key = NULL, *value;
+ char hex[WG_KEY_LEN_HEX], ip[INET6_ADDRSTRLEN], host[4096 + 1], service[512 + 1];
+ struct wgpeer *peer;
+ struct wgallowedip *allowedip;
+ FILE *f;
+ int ret, set_errno = -EPROTO;
+ socklen_t addr_len;
+ size_t line_buffer_len = 0, line_len;
+ char *key = NULL, *value;
- f = userspace_interface_file(dev->name);
- if (!f)
- return -errno;
- fprintf(f, "set=1\n");
+ f = userspace_interface_file(dev->name);
+ if (!f)
+ return -errno;
+ fprintf(f, "set=1\n");
- if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
- {
- key_to_hex(hex, dev->private_key);
- fprintf(f, "private_key=%s\n", hex);
- }
- if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
- fprintf(f, "listen_port=%u\n", dev->listen_port);
- if (dev->flags & WGDEVICE_HAS_FWMARK)
- fprintf(f, "fwmark=%u\n", dev->fwmark);
- if (dev->flags & WGDEVICE_REPLACE_PEERS)
- fprintf(f, "replace_peers=true\n");
- if (dev->flags & WGDEVICE_HAS_JC)
- fprintf(f, "jc=%u\n", dev->junk_packet_count);
- if (dev->flags & WGDEVICE_HAS_JMIN)
- fprintf(f, "jmin=%u\n", dev->junk_packet_min_size);
- if (dev->flags & WGDEVICE_HAS_JMAX)
- fprintf(f, "jmax=%u\n", dev->junk_packet_max_size);
- if (dev->flags & WGDEVICE_HAS_S1)
- fprintf(f, "s1=%u\n", dev->init_packet_junk_size);
- if (dev->flags & WGDEVICE_HAS_S2)
- fprintf(f, "s2=%u\n", dev->response_packet_junk_size);
- if (dev->flags & WGDEVICE_HAS_H1)
- fprintf(f, "h1=%u\n", dev->init_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H2)
- fprintf(f, "h2=%u\n", dev->response_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H3)
- fprintf(f, "h3=%u\n", dev->underload_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_H4)
- fprintf(f, "h4=%u\n", dev->transport_packet_magic_header);
- if (dev->flags & WGDEVICE_HAS_I1)
- fprintf(f, "i1=%s\n", dev->i1);
- if (dev->flags & WGDEVICE_HAS_I2)
- fprintf(f, "i2=%s\n", dev->i2);
- if (dev->flags & WGDEVICE_HAS_I3)
- fprintf(f, "i3=%s\n", dev->i3);
- if (dev->flags & WGDEVICE_HAS_I4)
- fprintf(f, "i4=%s\n", dev->i4);
- if (dev->flags & WGDEVICE_HAS_I5)
- fprintf(f, "i5=%s\n", dev->i5);
- if (dev->flags & WGDEVICE_HAS_J1)
- fprintf(f, "j1=%s\n", dev->j1);
- if (dev->flags & WGDEVICE_HAS_J2)
- fprintf(f, "j2=%s\n", dev->j2);
- if (dev->flags & WGDEVICE_HAS_J3)
- fprintf(f, "j3=%s\n", dev->j3);
- if (dev->flags & WGDEVICE_HAS_ITIME)
- fprintf(f, "itime=%u\n", dev->itime);
+ if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
+ key_to_hex(hex, dev->private_key);
+ fprintf(f, "private_key=%s\n", hex);
+ }
+ if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
+ fprintf(f, "listen_port=%u\n", dev->listen_port);
+ if (dev->flags & WGDEVICE_HAS_FWMARK)
+ fprintf(f, "fwmark=%u\n", dev->fwmark);
+ if (dev->flags & WGDEVICE_REPLACE_PEERS)
+ fprintf(f, "replace_peers=true\n");
+ if (dev->flags & WGDEVICE_HAS_JC)
+ fprintf(f, "jc=%u\n", dev->junk_packet_count);
+ if (dev->flags & WGDEVICE_HAS_JMIN)
+ fprintf(f, "jmin=%u\n", dev->junk_packet_min_size);
+ if (dev->flags & WGDEVICE_HAS_JMAX)
+ fprintf(f, "jmax=%u\n", dev->junk_packet_max_size);
+ if (dev->flags & WGDEVICE_HAS_S1)
+ fprintf(f, "s1=%u\n", dev->init_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_S2)
+ fprintf(f, "s2=%u\n", dev->response_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_H1)
+ fprintf(f, "h1=%u\n", dev->init_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H2)
+ fprintf(f, "h2=%u\n", dev->response_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H3)
+ fprintf(f, "h3=%u\n", dev->underload_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H4)
+ fprintf(f, "h4=%u\n", dev->transport_packet_magic_header);
- printf("i1: %s\n", dev->i1);
+ if (dev->flags & WGDEVICE_HAS_I1)
+ fprintf(f, "i1=%s\n", dev->i1);
+ if (dev->flags & WGDEVICE_HAS_I2)
+ fprintf(f, "i2=%s\n", dev->i2);
+ if (dev->flags & WGDEVICE_HAS_I3)
+ fprintf(f, "i3=%s\n", dev->i3);
+ if (dev->flags & WGDEVICE_HAS_I4)
+ fprintf(f, "i4=%s\n", dev->i4);
+ if (dev->flags & WGDEVICE_HAS_I5)
+ fprintf(f, "i5=%s\n", dev->i5);
+ if (dev->flags & WGDEVICE_HAS_J1)
+ fprintf(f, "j1=%s\n", dev->j1);
+ if (dev->flags & WGDEVICE_HAS_J2)
+ fprintf(f, "j2=%s\n", dev->j2);
+ if (dev->flags & WGDEVICE_HAS_J3)
+ fprintf(f, "j3=%s\n", dev->j3);
+ if (dev->flags & WGDEVICE_HAS_ITIME)
+ fprintf(f, "itime=%u\n", dev->itime);
- for_each_wgpeer(dev, peer)
- {
- key_to_hex(hex, peer->public_key);
- fprintf(f, "public_key=%s\n", hex);
- if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY)
- {
- ret = -EINVAL;
- goto out;
- }
- if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)
- {
- ret = -EINVAL;
- goto out;
- }
- if (peer->flags & WGPEER_REMOVE_ME)
- {
- fprintf(f, "remove=true\n");
- continue;
- }
- if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
- {
- key_to_hex(hex, peer->preshared_key);
- fprintf(f, "preshared_key=%s\n", hex);
- }
- if (peer->endpoint.addr.sa_family == AF_INET ||
- peer->endpoint.addr.sa_family == AF_INET6)
- {
- addr_len = 0;
- if (peer->endpoint.addr.sa_family == AF_INET)
- addr_len = sizeof(struct sockaddr_in);
- else if (peer->endpoint.addr.sa_family == AF_INET6)
- addr_len = sizeof(struct sockaddr_in6);
- if (!getnameinfo(
- &peer->endpoint.addr,
- addr_len,
- host,
- sizeof(host),
- service,
- sizeof(service),
- NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST))
- {
- if (peer->endpoint.addr.sa_family == AF_INET6 && strchr(host, ':'))
- fprintf(f, "endpoint=[%s]:%s\n", host, service);
- else
- fprintf(f, "endpoint=%s:%s\n", host, service);
- }
- }
- if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
- fprintf(
- f,
- "persistent_keepalive_interval=%u\n",
- peer->persistent_keepalive_interval);
- if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
- fprintf(f, "replace_allowed_ips=true\n");
- for_each_wgallowedip(peer, allowedip)
- {
- if (allowedip->family == AF_INET)
- {
- if (!inet_ntop(AF_INET, &allowedip->ip4, ip, INET6_ADDRSTRLEN))
- continue;
- }
- else if (allowedip->family == AF_INET6)
- {
- if (!inet_ntop(AF_INET6, &allowedip->ip6, ip, INET6_ADDRSTRLEN))
- continue;
- }
- else
- continue;
- fprintf(f, "allowed_ip=%s/%d\n", ip, allowedip->cidr);
- }
- }
- fprintf(f, "\n");
- fflush(f);
+ for_each_wgpeer(dev, peer) {
+ key_to_hex(hex, peer->public_key);
+ fprintf(f, "public_key=%s\n", hex);
+ if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)
+ {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (peer->flags & WGPEER_REMOVE_ME) {
+ fprintf(f, "remove=true\n");
+ continue;
+ }
+ if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
+ key_to_hex(hex, peer->preshared_key);
+ fprintf(f, "preshared_key=%s\n", hex);
+ }
+ if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6) {
+ addr_len = 0;
+ if (peer->endpoint.addr.sa_family == AF_INET)
+ addr_len = sizeof(struct sockaddr_in);
+ else if (peer->endpoint.addr.sa_family == AF_INET6)
+ addr_len = sizeof(struct sockaddr_in6);
+ if (!getnameinfo(&peer->endpoint.addr, addr_len, host, sizeof(host), service, sizeof(service), NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST)) {
+ if (peer->endpoint.addr.sa_family == AF_INET6 && strchr(host, ':'))
+ fprintf(f, "endpoint=[%s]:%s\n", host, service);
+ else
+ fprintf(f, "endpoint=%s:%s\n", host, service);
+ }
+ }
+ if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
+ fprintf(f, "persistent_keepalive_interval=%u\n", peer->persistent_keepalive_interval);
+ if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
+ fprintf(f, "replace_allowed_ips=true\n");
+ for_each_wgallowedip(peer, allowedip) {
+ if (allowedip->family == AF_INET) {
+ if (!inet_ntop(AF_INET, &allowedip->ip4, ip, INET6_ADDRSTRLEN))
+ continue;
+ } else if (allowedip->family == AF_INET6) {
+ if (!inet_ntop(AF_INET6, &allowedip->ip6, ip, INET6_ADDRSTRLEN))
+ continue;
+ } else
+ continue;
+ fprintf(f, "allowed_ip=%s/%d\n", ip, allowedip->cidr);
+ }
+ }
+ fprintf(f, "\n");
+ fflush(f);
- while (getline(&key, &line_buffer_len, f) > 0)
- {
- line_len = strlen(key);
- ret = set_errno;
- if (line_len == 1 && key[0] == '\n')
- goto out;
- value = strchr(key, '=');
- if (!value || line_len == 0 || key[line_len - 1] != '\n')
- break;
- *value++ = key[--line_len] = '\0';
+ while (getline(&key, &line_buffer_len, f) > 0) {
+ line_len = strlen(key);
+ ret = set_errno;
+ if (line_len == 1 && key[0] == '\n')
+ goto out;
+ value = strchr(key, '=');
+ if (!value || line_len == 0 || key[line_len - 1] != '\n')
+ break;
+ *value++ = key[--line_len] = '\0';
- if (!strcmp(key, "errno"))
- {
- long long num;
- char* end;
- if (value[0] != '-' && !char_is_digit(value[0]))
- break;
- num = strtoll(value, &end, 10);
- if (*end || num > INT_MAX || num < INT_MIN)
- break;
- set_errno = num;
- }
- }
- ret = errno ? -errno : -EPROTO;
+ if (!strcmp(key, "errno")) {
+ long long num;
+ char *end;
+ if (value[0] != '-' && !char_is_digit(value[0]))
+ break;
+ num = strtoll(value, &end, 10);
+ if (*end || num > INT_MAX || num < INT_MIN)
+ break;
+ set_errno = num;
+ }
+ }
+ ret = errno ? -errno : -EPROTO;
out:
- free(key);
- fclose(f);
- errno = -ret;
- return ret;
+ free(key);
+ fclose(f);
+ errno = -ret;
+ return ret;
}
-#define NUM(max) \
- ({ \
- unsigned long long num; \
- char* end; \
- if (!char_is_digit(value[0])) \
- break; \
- num = strtoull(value, &end, 10); \
- if (*end || num > max) \
- break; \
- num; \
- })
+#define NUM(max) ({ \
+ unsigned long long num; \
+ char *end; \
+ if (!char_is_digit(value[0])) \
+ break; \
+ num = strtoull(value, &end, 10); \
+ if (*end || num > max) \
+ break; \
+ num; \
+})
-static int userspace_get_device(struct wgdevice** out, const char* iface)
+static int userspace_get_device(struct wgdevice **out, const char *iface)
{
- struct wgdevice* dev;
- struct wgpeer* peer = NULL;
- struct wgallowedip* allowedip = NULL;
- size_t line_buffer_len = 0, line_len;
- char * key = NULL, *value;
- FILE* f;
- int ret = -EPROTO;
+ struct wgdevice *dev;
+ struct wgpeer *peer = NULL;
+ struct wgallowedip *allowedip = NULL;
+ size_t line_buffer_len = 0, line_len;
+ char *key = NULL, *value;
+ FILE *f;
+ int ret = -EPROTO;
- *out = dev = calloc(1, sizeof(*dev));
- if (!dev)
- return -errno;
+ *out = dev = calloc(1, sizeof(*dev));
+ if (!dev)
+ return -errno;
- f = userspace_interface_file(iface);
- if (!f)
- {
- ret = -errno;
- free(dev);
- *out = NULL;
- return ret;
- }
+ f = userspace_interface_file(iface);
+ if (!f) {
+ ret = -errno;
+ free(dev);
+ *out = NULL;
+ return ret;
+ }
- fprintf(f, "get=1\n\n");
- fflush(f);
+ fprintf(f, "get=1\n\n");
+ fflush(f);
- strncpy(dev->name, iface, IFNAMSIZ - 1);
- dev->name[IFNAMSIZ - 1] = '\0';
+ strncpy(dev->name, iface, IFNAMSIZ - 1);
+ dev->name[IFNAMSIZ - 1] = '\0';
- while (getline(&key, &line_buffer_len, f) > 0)
- {
- line_len = strlen(key);
- if (line_len == 1 && key[0] == '\n')
- goto err;
- value = strchr(key, '=');
- if (!value || line_len == 0 || key[line_len - 1] != '\n')
- break;
- *value++ = key[--line_len] = '\0';
+ while (getline(&key, &line_buffer_len, f) > 0) {
+ line_len = strlen(key);
+ if (line_len == 1 && key[0] == '\n')
+ goto err;
+ value = strchr(key, '=');
+ if (!value || line_len == 0 || key[line_len - 1] != '\n')
+ break;
+ *value++ = key[--line_len] = '\0';
- if (!peer && !strcmp(key, "private_key"))
- {
- if (!key_from_hex(dev->private_key, value))
- break;
- curve25519_generate_public(dev->public_key, dev->private_key);
- dev->flags |= WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_PUBLIC_KEY;
- }
- else if (!peer && !strcmp(key, "listen_port"))
- {
- dev->listen_port = NUM(0xffffU);
- dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
- }
- else if (!peer && !strcmp(key, "fwmark"))
- {
- dev->fwmark = NUM(0xffffffffU);
- dev->flags |= WGDEVICE_HAS_FWMARK;
- }
- else if (!peer && !strcmp(key, "jc"))
- {
- dev->junk_packet_count = NUM(0xffffU);
- dev->flags |= WGDEVICE_HAS_JC;
- }
- else if (!peer && !strcmp(key, "jmin"))
- {
- dev->junk_packet_min_size = NUM(0xffffU);
- dev->flags |= WGDEVICE_HAS_JMIN;
- }
- else if (!peer && !strcmp(key, "jmax"))
- {
- dev->junk_packet_max_size = NUM(0xffffU);
- dev->flags |= WGDEVICE_HAS_JMAX;
- }
- else if (!peer && !strcmp(key, "s1"))
- {
- dev->init_packet_junk_size = NUM(0xffffU);
- dev->flags |= WGDEVICE_HAS_S1;
- }
- else if (!peer && !strcmp(key, "s2"))
- {
- dev->response_packet_junk_size = NUM(0xffffU);
- dev->flags |= WGDEVICE_HAS_S2;
- }
- else if (!peer && !strcmp(key, "h1"))
- {
- dev->init_packet_magic_header = NUM(0xffffffffU);
- dev->flags |= WGDEVICE_HAS_H1;
- }
- else if (!peer && !strcmp(key, "h2"))
- {
- dev->response_packet_magic_header = NUM(0xffffffffU);
- dev->flags |= WGDEVICE_HAS_H2;
- }
- else if (!peer && !strcmp(key, "h3"))
- {
- dev->underload_packet_magic_header = NUM(0xffffffffU);
- dev->flags |= WGDEVICE_HAS_H3;
- }
- else if (!peer && !strcmp(key, "h4"))
- {
- dev->transport_packet_magic_header = NUM(0xffffffffU);
- dev->flags |= WGDEVICE_HAS_H4;
- }
- else if (!peer && !strcmp(key, "i1"))
- {
- dev->i1 = strdup(value);
- dev->flags |= WGDEVICE_HAS_I1;
- }
- else if (!peer && !strcmp(key, "i2"))
- {
- dev->i2 = strdup(value);
- dev->flags |= WGDEVICE_HAS_I2;
- }
- else if (!peer && !strcmp(key, "i3"))
- {
- dev->i3 = strdup(value);
- dev->flags |= WGDEVICE_HAS_I3;
- }
- else if (!peer && !strcmp(key, "i4"))
- {
- dev->i4 = strdup(value);
- dev->flags |= WGDEVICE_HAS_I4;
- }
- else if (!peer && !strcmp(key, "i5"))
- {
- dev->i5 = strdup(value);
- dev->flags |= WGDEVICE_HAS_I5;
- }
- else if (!peer && !strcmp(key, "j1"))
- {
- dev->j1 = strdup(value);
- dev->flags |= WGDEVICE_HAS_J1;
- }
- else if (!peer && !strcmp(key, "j2"))
- {
- dev->j2 = strdup(value);
- dev->flags |= WGDEVICE_HAS_J2;
- }
- else if (!peer && !strcmp(key, "j3"))
- {
- dev->j3 = strdup(value);
- dev->flags |= WGDEVICE_HAS_J3;
- }
- else if (!peer && !strcmp(key, "itime"))
- {
- dev->itime = NUM(0xffffffffU);
- dev->flags |= WGDEVICE_HAS_ITIME;
- }
- else if (!strcmp(key, "public_key"))
- {
- struct wgpeer* new_peer = calloc(1, sizeof(*new_peer));
+ if (!peer && !strcmp(key, "private_key")) {
+ if (!key_from_hex(dev->private_key, value))
+ break;
+ curve25519_generate_public(dev->public_key, dev->private_key);
+ dev->flags |= WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_PUBLIC_KEY;
+ } else if (!peer && !strcmp(key, "listen_port")) {
+ dev->listen_port = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
+ } else if (!peer && !strcmp(key, "fwmark")) {
+ dev->fwmark = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_FWMARK;
+ } else if(!peer && !strcmp(key, "jc")) {
+ dev->junk_packet_count = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_JC;
+ } else if(!peer && !strcmp(key, "jmin")) {
+ dev->junk_packet_min_size = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_JMIN;
+ } else if(!peer && !strcmp(key, "jmax")) {
+ dev->junk_packet_max_size = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_JMAX;
+ } else if(!peer && !strcmp(key, "s1")) {
+ dev->init_packet_junk_size = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_S1;
+ } else if(!peer && !strcmp(key, "s2")) {
+ dev->response_packet_junk_size = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_S2;
+ } else if(!peer && !strcmp(key, "h1")) {
+ dev->init_packet_magic_header = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_H1;
+ } else if(!peer && !strcmp(key, "h2")) {
+ dev->response_packet_magic_header = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_H2;
+ } else if(!peer && !strcmp(key, "h3")) {
+ dev->underload_packet_magic_header = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_H3;
+ } else if(!peer && !strcmp(key, "h4")) {
+ dev->transport_packet_magic_header = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_H4;
+ } else if (!peer && !strcmp(key, "i1")) {
+ dev->i1 = strdup(value);
+ dev->flags |= WGDEVICE_HAS_I1;
+ }
+ else if (!peer && !strcmp(key, "i2")) {
+ dev->i2 = strdup(value);
+ dev->flags |= WGDEVICE_HAS_I2;
+ }
+ else if (!peer && !strcmp(key, "i3")) {
+ dev->i3 = strdup(value);
+ dev->flags |= WGDEVICE_HAS_I3;
+ }
+ else if (!peer && !strcmp(key, "i4")) {
+ dev->i4 = strdup(value);
+ dev->flags |= WGDEVICE_HAS_I4;
+ }
+ else if (!peer && !strcmp(key, "i5")) {
+ dev->i5 = strdup(value);
+ dev->flags |= WGDEVICE_HAS_I5;
+ }
+ else if (!peer && !strcmp(key, "j1")) {
+ dev->j1 = strdup(value);
+ dev->flags |= WGDEVICE_HAS_J1;
+ }
+ else if (!peer && !strcmp(key, "j2")) {
+ dev->j2 = strdup(value);
+ dev->flags |= WGDEVICE_HAS_J2;
+ }
+ else if (!peer && !strcmp(key, "j3")) {
+ dev->j3 = strdup(value);
+ dev->flags |= WGDEVICE_HAS_J3;
+ }
+ else if (!peer && !strcmp(key, "itime")) {
+ dev->itime = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_ITIME;
+ } else if (!strcmp(key, "public_key")) {
+ struct wgpeer *new_peer = calloc(1, sizeof(*new_peer));
- if (!new_peer)
- {
- ret = -ENOMEM;
- goto err;
- }
- allowedip = NULL;
- if (peer)
- peer->next_peer = new_peer;
- else
- dev->first_peer = new_peer;
- peer = new_peer;
- if (!key_from_hex(peer->public_key, value))
- break;
- peer->flags |= WGPEER_HAS_PUBLIC_KEY;
- }
- else if (peer && !strcmp(key, "preshared_key"))
- {
- if (!key_from_hex(peer->preshared_key, value))
- break;
- if (!key_is_zero(peer->preshared_key))
- peer->flags |= WGPEER_HAS_PRESHARED_KEY;
- }
- else if (peer && !strcmp(key, "endpoint"))
- {
- char * begin, *end;
- struct addrinfo* resolved;
- struct addrinfo hints = {
- .ai_family = AF_UNSPEC,
- .ai_socktype = SOCK_DGRAM,
- .ai_protocol = IPPROTO_UDP};
- if (!strlen(value))
- break;
- if (value[0] == '[')
- {
- begin = &value[1];
- end = strchr(value, ']');
- if (!end)
- break;
- *end++ = '\0';
- if (*end++ != ':' || !*end)
- break;
- }
- else
- {
- begin = value;
- end = strrchr(value, ':');
- if (!end || !*(end + 1))
- break;
- *end++ = '\0';
- }
- if (getaddrinfo(begin, end, &hints, &resolved) != 0)
- {
- ret = ENETUNREACH;
- goto err;
- }
- if ((resolved->ai_family == AF_INET &&
- resolved->ai_addrlen == sizeof(struct sockaddr_in)) ||
- (resolved->ai_family == AF_INET6 &&
- resolved->ai_addrlen == sizeof(struct sockaddr_in6)))
- memcpy(&peer->endpoint.addr, resolved->ai_addr, resolved->ai_addrlen);
- else
- {
- freeaddrinfo(resolved);
- break;
- }
- freeaddrinfo(resolved);
- }
- else if (peer && !strcmp(key, "persistent_keepalive_interval"))
- {
- peer->persistent_keepalive_interval = NUM(0xffffU);
- peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
- }
- else if (peer && !strcmp(key, "allowed_ip"))
- {
- struct wgallowedip* new_allowedip;
- char * end, *mask = value, *ip = strsep(&mask, "/");
+ if (!new_peer) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ allowedip = NULL;
+ if (peer)
+ peer->next_peer = new_peer;
+ else
+ dev->first_peer = new_peer;
+ peer = new_peer;
+ if (!key_from_hex(peer->public_key, value))
+ break;
+ peer->flags |= WGPEER_HAS_PUBLIC_KEY;
+ } else if (peer && !strcmp(key, "preshared_key")) {
+ if (!key_from_hex(peer->preshared_key, value))
+ break;
+ if (!key_is_zero(peer->preshared_key))
+ peer->flags |= WGPEER_HAS_PRESHARED_KEY;
+ } else if (peer && !strcmp(key, "endpoint")) {
+ char *begin, *end;
+ struct addrinfo *resolved;
+ struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_DGRAM,
+ .ai_protocol = IPPROTO_UDP
+ };
+ if (!strlen(value))
+ break;
+ if (value[0] == '[') {
+ begin = &value[1];
+ end = strchr(value, ']');
+ if (!end)
+ break;
+ *end++ = '\0';
+ if (*end++ != ':' || !*end)
+ break;
+ } else {
+ begin = value;
+ end = strrchr(value, ':');
+ if (!end || !*(end + 1))
+ break;
+ *end++ = '\0';
+ }
+ if (getaddrinfo(begin, end, &hints, &resolved) != 0) {
+ ret = ENETUNREACH;
+ goto err;
+ }
+ if ((resolved->ai_family == AF_INET && resolved->ai_addrlen == sizeof(struct sockaddr_in)) ||
+ (resolved->ai_family == AF_INET6 && resolved->ai_addrlen == sizeof(struct sockaddr_in6)))
+ memcpy(&peer->endpoint.addr, resolved->ai_addr, resolved->ai_addrlen);
+ else {
+ freeaddrinfo(resolved);
+ break;
+ }
+ freeaddrinfo(resolved);
+ } else if (peer && !strcmp(key, "persistent_keepalive_interval")) {
+ peer->persistent_keepalive_interval = NUM(0xffffU);
+ peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
+ } else if (peer && !strcmp(key, "allowed_ip")) {
+ struct wgallowedip *new_allowedip;
+ char *end, *mask = value, *ip = strsep(&mask, "/");
- if (!mask || !char_is_digit(mask[0]))
- break;
- new_allowedip = calloc(1, sizeof(*new_allowedip));
- if (!new_allowedip)
- {
- ret = -ENOMEM;
- goto err;
- }
- if (allowedip)
- allowedip->next_allowedip = new_allowedip;
- else
- peer->first_allowedip = new_allowedip;
- allowedip = new_allowedip;
- allowedip->family = AF_UNSPEC;
- if (strchr(ip, ':'))
- {
- if (inet_pton(AF_INET6, ip, &allowedip->ip6) == 1)
- allowedip->family = AF_INET6;
- }
- else
- {
- if (inet_pton(AF_INET, ip, &allowedip->ip4) == 1)
- allowedip->family = AF_INET;
- }
- allowedip->cidr = strtoul(mask, &end, 10);
- if (*end || allowedip->family == AF_UNSPEC ||
- (allowedip->family == AF_INET6 && allowedip->cidr > 128) ||
- (allowedip->family == AF_INET && allowedip->cidr > 32))
- break;
- }
- else if (peer && !strcmp(key, "last_handshake_time_sec"))
- peer->last_handshake_time.tv_sec = NUM(0x7fffffffffffffffULL);
- else if (peer && !strcmp(key, "last_handshake_time_nsec"))
- peer->last_handshake_time.tv_nsec = NUM(0x7fffffffffffffffULL);
- else if (peer && !strcmp(key, "rx_bytes"))
- peer->rx_bytes = NUM(0xffffffffffffffffULL);
- else if (peer && !strcmp(key, "tx_bytes"))
- peer->tx_bytes = NUM(0xffffffffffffffffULL);
- else if (!strcmp(key, "errno"))
- ret = -NUM(0x7fffffffU);
- }
- ret = -EPROTO;
+ if (!mask || !char_is_digit(mask[0]))
+ break;
+ new_allowedip = calloc(1, sizeof(*new_allowedip));
+ if (!new_allowedip) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ if (allowedip)
+ allowedip->next_allowedip = new_allowedip;
+ else
+ peer->first_allowedip = new_allowedip;
+ allowedip = new_allowedip;
+ allowedip->family = AF_UNSPEC;
+ if (strchr(ip, ':')) {
+ if (inet_pton(AF_INET6, ip, &allowedip->ip6) == 1)
+ allowedip->family = AF_INET6;
+ } else {
+ if (inet_pton(AF_INET, ip, &allowedip->ip4) == 1)
+ allowedip->family = AF_INET;
+ }
+ allowedip->cidr = strtoul(mask, &end, 10);
+ if (*end || allowedip->family == AF_UNSPEC || (allowedip->family == AF_INET6 && allowedip->cidr > 128) || (allowedip->family == AF_INET && allowedip->cidr > 32))
+ break;
+ } else if (peer && !strcmp(key, "last_handshake_time_sec"))
+ peer->last_handshake_time.tv_sec = NUM(0x7fffffffffffffffULL);
+ else if (peer && !strcmp(key, "last_handshake_time_nsec"))
+ peer->last_handshake_time.tv_nsec = NUM(0x7fffffffffffffffULL);
+ else if (peer && !strcmp(key, "rx_bytes"))
+ peer->rx_bytes = NUM(0xffffffffffffffffULL);
+ else if (peer && !strcmp(key, "tx_bytes"))
+ peer->tx_bytes = NUM(0xffffffffffffffffULL);
+ else if (!strcmp(key, "errno"))
+ ret = -NUM(0x7fffffffU);
+ }
+ ret = -EPROTO;
err:
- free(key);
- if (ret)
- {
- free_wgdevice(dev);
- *out = NULL;
- }
- fclose(f);
- errno = -ret;
- return ret;
+ free(key);
+ if (ret) {
+ free_wgdevice(dev);
+ *out = NULL;
+ }
+ fclose(f);
+ errno = -ret;
+ return ret;
+
}
#undef NUM
diff --git a/src/ipc-windows.h b/src/ipc-windows.h
index b269f1b..99d9a48 100644
--- a/src/ipc-windows.h
+++ b/src/ipc-windows.h
@@ -4,774 +4,652 @@
*/
#include "containers.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
+#include
#define IPC_SUPPORTS_KERNEL_INTERFACE
-static bool have_cached_kernel_interfaces;
+static bool have_cached_kernel_interfaces;
static struct hashtable cached_kernel_interfaces;
static const DEVPROPKEY devpkey_name = DEVPKEY_WG_NAME;
-extern bool is_win7;
+extern bool is_win7;
-static int kernel_get_wireguard_interfaces(struct string_list* list)
+static int kernel_get_wireguard_interfaces(struct string_list *list)
{
- HDEVINFO dev_info = SetupDiGetClassDevsExW(
- &GUID_DEVCLASS_NET,
- is_win7 ? L"ROOT\\WIREGUARD" : L"SWD\\WireGuard",
- NULL,
- DIGCF_PRESENT,
- NULL,
- NULL,
- NULL);
- bool will_have_cached_kernel_interfaces = true;
+ HDEVINFO dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, is_win7 ? L"ROOT\\WIREGUARD" : L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL);
+ bool will_have_cached_kernel_interfaces = true;
- if (dev_info == INVALID_HANDLE_VALUE)
- {
- errno = EACCES;
- return -errno;
- }
+ if (dev_info == INVALID_HANDLE_VALUE) {
+ errno = EACCES;
+ return -errno;
+ }
- for (DWORD i = 0;; ++i)
- {
- DWORD buf_len;
- WCHAR adapter_name[MAX_ADAPTER_NAME];
- SP_DEVINFO_DATA dev_info_data = {.cbSize = sizeof(SP_DEVINFO_DATA)};
- DEVPROPTYPE prop_type;
- ULONG status, problem_code;
- char* interface_name;
- struct hashtable_entry* entry;
+ for (DWORD i = 0;; ++i) {
+ DWORD buf_len;
+ WCHAR adapter_name[MAX_ADAPTER_NAME];
+ SP_DEVINFO_DATA dev_info_data = { .cbSize = sizeof(SP_DEVINFO_DATA) };
+ DEVPROPTYPE prop_type;
+ ULONG status, problem_code;
+ char *interface_name;
+ struct hashtable_entry *entry;
- if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data))
- {
- if (GetLastError() == ERROR_NO_MORE_ITEMS)
- break;
- continue;
- }
+ if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data)) {
+ if (GetLastError() == ERROR_NO_MORE_ITEMS)
+ break;
+ continue;
+ }
- if (!SetupDiGetDevicePropertyW(
- dev_info,
- &dev_info_data,
- &devpkey_name,
- &prop_type,
- (PBYTE)adapter_name,
- sizeof(adapter_name),
- NULL,
- 0) ||
- prop_type != DEVPROP_TYPE_STRING)
- continue;
- adapter_name[_countof(adapter_name) - 1] = L'0';
- if (!adapter_name[0])
- continue;
- buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, NULL, 0, NULL, NULL);
- if (!buf_len)
- continue;
- interface_name = malloc(buf_len);
- if (!interface_name)
- continue;
- buf_len = WideCharToMultiByte(
- CP_UTF8, 0, adapter_name, -1, interface_name, buf_len, NULL, NULL);
- if (!buf_len)
- {
- free(interface_name);
- continue;
- }
+ if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name,
+ &prop_type, (PBYTE)adapter_name,
+ sizeof(adapter_name), NULL, 0) ||
+ prop_type != DEVPROP_TYPE_STRING)
+ continue;
+ adapter_name[_countof(adapter_name) - 1] = L'0';
+ if (!adapter_name[0])
+ continue;
+ buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, NULL, 0, NULL, NULL);
+ if (!buf_len)
+ continue;
+ interface_name = malloc(buf_len);
+ if (!interface_name)
+ continue;
+ buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, interface_name, buf_len, NULL, NULL);
+ if (!buf_len) {
+ free(interface_name);
+ continue;
+ }
- if (CM_Get_DevNode_Status(&status, &problem_code, dev_info_data.DevInst, 0) ==
- CR_SUCCESS &&
- (status & (DN_DRIVER_LOADED | DN_STARTED)) == (DN_DRIVER_LOADED | DN_STARTED))
- string_list_add(list, interface_name);
+ if (CM_Get_DevNode_Status(&status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS &&
+ (status & (DN_DRIVER_LOADED | DN_STARTED)) == (DN_DRIVER_LOADED | DN_STARTED))
+ string_list_add(list, interface_name);
- entry = hashtable_find_or_insert_entry(&cached_kernel_interfaces, interface_name);
- free(interface_name);
- if (!entry)
- continue;
+ entry = hashtable_find_or_insert_entry(&cached_kernel_interfaces, interface_name);
+ free(interface_name);
+ if (!entry)
+ continue;
- if (SetupDiGetDeviceInstanceIdW(dev_info, &dev_info_data, NULL, 0, &buf_len) ||
- GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- continue;
- entry->value = calloc(sizeof(WCHAR), buf_len);
- if (!entry->value)
- continue;
- if (!SetupDiGetDeviceInstanceIdW(
- dev_info, &dev_info_data, entry->value, buf_len, &buf_len))
- {
- free(entry->value);
- entry->value = NULL;
- continue;
- }
+ if (SetupDiGetDeviceInstanceIdW(dev_info, &dev_info_data, NULL, 0, &buf_len) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ continue;
+ entry->value = calloc(sizeof(WCHAR), buf_len);
+ if (!entry->value)
+ continue;
+ if (!SetupDiGetDeviceInstanceIdW(dev_info, &dev_info_data, entry->value, buf_len, &buf_len)) {
+ free(entry->value);
+ entry->value = NULL;
+ continue;
+ }
- will_have_cached_kernel_interfaces = true;
- }
- SetupDiDestroyDeviceInfoList(dev_info);
- have_cached_kernel_interfaces = will_have_cached_kernel_interfaces;
- return 0;
+ will_have_cached_kernel_interfaces = true;
+ }
+ SetupDiDestroyDeviceInfoList(dev_info);
+ have_cached_kernel_interfaces = will_have_cached_kernel_interfaces;
+ return 0;
}
-static HANDLE kernel_interface_handle(const char* iface)
+static HANDLE kernel_interface_handle(const char *iface)
{
- HDEVINFO dev_info;
- WCHAR* interfaces = NULL;
- HANDLE handle;
+ HDEVINFO dev_info;
+ WCHAR *interfaces = NULL;
+ HANDLE handle;
- if (have_cached_kernel_interfaces)
- {
- struct hashtable_entry* entry =
- hashtable_find_entry(&cached_kernel_interfaces, iface);
- if (entry)
- {
- DWORD buf_len;
- if (CM_Get_Device_Interface_List_SizeW(
- &buf_len,
- (GUID*)&GUID_DEVINTERFACE_NET,
- (DEVINSTID_W)entry->value,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS)
- goto err_hash;
- interfaces = calloc(buf_len, sizeof(*interfaces));
- if (!interfaces)
- goto err_hash;
- if (CM_Get_Device_Interface_ListW(
- (GUID*)&GUID_DEVINTERFACE_NET,
- (DEVINSTID_W)entry->value,
- interfaces,
- buf_len,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS ||
- !interfaces[0])
- {
- free(interfaces);
- interfaces = NULL;
- goto err_hash;
- }
- handle = CreateFileW(
- interfaces,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- free(interfaces);
- if (handle == INVALID_HANDLE_VALUE)
- goto err_hash;
- return handle;
- err_hash:
- errno = EACCES;
- return NULL;
- }
- }
+ if (have_cached_kernel_interfaces) {
+ struct hashtable_entry *entry = hashtable_find_entry(&cached_kernel_interfaces, iface);
+ if (entry) {
+ DWORD buf_len;
+ if (CM_Get_Device_Interface_List_SizeW(
+ &buf_len, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)entry->value,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS)
+ goto err_hash;
+ interfaces = calloc(buf_len, sizeof(*interfaces));
+ if (!interfaces)
+ goto err_hash;
+ if (CM_Get_Device_Interface_ListW(
+ (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)entry->value, interfaces, buf_len,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS || !interfaces[0]) {
+ free(interfaces);
+ interfaces = NULL;
+ goto err_hash;
+ }
+ handle = CreateFileW(interfaces, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, 0, NULL);
+ free(interfaces);
+ if (handle == INVALID_HANDLE_VALUE)
+ goto err_hash;
+ return handle;
+err_hash:
+ errno = EACCES;
+ return NULL;
+ }
+ }
- dev_info = SetupDiGetClassDevsExW(
- &GUID_DEVCLASS_NET,
- is_win7 ? L"ROOT\\WIREGUARD" : L"SWD\\WireGuard",
- NULL,
- DIGCF_PRESENT,
- NULL,
- NULL,
- NULL);
- if (dev_info == INVALID_HANDLE_VALUE)
- return NULL;
+ dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, is_win7 ? L"ROOT\\WIREGUARD" : L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL);
+ if (dev_info == INVALID_HANDLE_VALUE)
+ return NULL;
- for (DWORD i = 0; !interfaces; ++i)
- {
- bool found;
- DWORD buf_len;
- WCHAR * buf, adapter_name[MAX_ADAPTER_NAME];
- SP_DEVINFO_DATA dev_info_data = {.cbSize = sizeof(SP_DEVINFO_DATA)};
- DEVPROPTYPE prop_type;
- char* interface_name;
+ for (DWORD i = 0; !interfaces; ++i) {
+ bool found;
+ DWORD buf_len;
+ WCHAR *buf, adapter_name[MAX_ADAPTER_NAME];
+ SP_DEVINFO_DATA dev_info_data = { .cbSize = sizeof(SP_DEVINFO_DATA) };
+ DEVPROPTYPE prop_type;
+ char *interface_name;
- if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data))
- {
- if (GetLastError() == ERROR_NO_MORE_ITEMS)
- break;
- continue;
- }
+ if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data)) {
+ if (GetLastError() == ERROR_NO_MORE_ITEMS)
+ break;
+ continue;
+ }
- if (!SetupDiGetDevicePropertyW(
- dev_info,
- &dev_info_data,
- &devpkey_name,
- &prop_type,
- (PBYTE)adapter_name,
- sizeof(adapter_name),
- NULL,
- 0) ||
- prop_type != DEVPROP_TYPE_STRING)
- continue;
- adapter_name[_countof(adapter_name) - 1] = L'0';
- if (!adapter_name[0])
- continue;
- buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, NULL, 0, NULL, NULL);
- if (!buf_len)
- continue;
- interface_name = malloc(buf_len);
- if (!interface_name)
- continue;
- buf_len = WideCharToMultiByte(
- CP_UTF8, 0, adapter_name, -1, interface_name, buf_len, NULL, NULL);
- if (!buf_len)
- {
- free(interface_name);
- continue;
- }
- found = !strcmp(interface_name, iface);
- free(interface_name);
- if (!found)
- continue;
+ if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name,
+ &prop_type, (PBYTE)adapter_name,
+ sizeof(adapter_name), NULL, 0) ||
+ prop_type != DEVPROP_TYPE_STRING)
+ continue;
+ adapter_name[_countof(adapter_name) - 1] = L'0';
+ if (!adapter_name[0])
+ continue;
+ buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, NULL, 0, NULL, NULL);
+ if (!buf_len)
+ continue;
+ interface_name = malloc(buf_len);
+ if (!interface_name)
+ continue;
+ buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, interface_name, buf_len, NULL, NULL);
+ if (!buf_len) {
+ free(interface_name);
+ continue;
+ }
+ found = !strcmp(interface_name, iface);
+ free(interface_name);
+ if (!found)
+ continue;
- if (SetupDiGetDeviceInstanceIdW(dev_info, &dev_info_data, NULL, 0, &buf_len) ||
- GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- continue;
- buf = calloc(sizeof(*buf), buf_len);
- if (!buf)
- continue;
- if (!SetupDiGetDeviceInstanceIdW(
- dev_info, &dev_info_data, buf, buf_len, &buf_len))
- goto cleanup_instance_id;
- if (CM_Get_Device_Interface_List_SizeW(
- &buf_len,
- (GUID*)&GUID_DEVINTERFACE_NET,
- (DEVINSTID_W)buf,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS)
- goto cleanup_instance_id;
- interfaces = calloc(buf_len, sizeof(*interfaces));
- if (!interfaces)
- goto cleanup_instance_id;
- if (CM_Get_Device_Interface_ListW(
- (GUID*)&GUID_DEVINTERFACE_NET,
- (DEVINSTID_W)buf,
- interfaces,
- buf_len,
- CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS ||
- !interfaces[0])
- {
- free(interfaces);
- interfaces = NULL;
- goto cleanup_instance_id;
- }
- cleanup_instance_id:
- free(buf);
- }
- SetupDiDestroyDeviceInfoList(dev_info);
- if (!interfaces)
- {
- errno = ENOENT;
- return NULL;
- }
- handle = CreateFileW(
- interfaces,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- free(interfaces);
- if (handle == INVALID_HANDLE_VALUE)
- {
- errno = EACCES;
- return NULL;
- }
- return handle;
+ if (SetupDiGetDeviceInstanceIdW(dev_info, &dev_info_data, NULL, 0, &buf_len) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ continue;
+ buf = calloc(sizeof(*buf), buf_len);
+ if (!buf)
+ continue;
+ if (!SetupDiGetDeviceInstanceIdW(dev_info, &dev_info_data, buf, buf_len, &buf_len))
+ goto cleanup_instance_id;
+ if (CM_Get_Device_Interface_List_SizeW(
+ &buf_len, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)buf,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS)
+ goto cleanup_instance_id;
+ interfaces = calloc(buf_len, sizeof(*interfaces));
+ if (!interfaces)
+ goto cleanup_instance_id;
+ if (CM_Get_Device_Interface_ListW(
+ (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)buf, interfaces, buf_len,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS || !interfaces[0]) {
+ free(interfaces);
+ interfaces = NULL;
+ goto cleanup_instance_id;
+ }
+cleanup_instance_id:
+ free(buf);
+ }
+ SetupDiDestroyDeviceInfoList(dev_info);
+ if (!interfaces) {
+ errno = ENOENT;
+ return NULL;
+ }
+ handle = CreateFileW(interfaces, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, 0, NULL);
+ free(interfaces);
+ if (handle == INVALID_HANDLE_VALUE) {
+ errno = EACCES;
+ return NULL;
+ }
+ return handle;
}
-static int kernel_get_device(struct wgdevice** device, const char* iface)
+static int kernel_get_device(struct wgdevice **device, const char *iface)
{
- WG_IOCTL_INTERFACE* wg_iface;
- WG_IOCTL_PEER* wg_peer;
- WG_IOCTL_ALLOWED_IP* wg_aip;
- void* buf = NULL;
- DWORD buf_len = 0;
- HANDLE handle = kernel_interface_handle(iface);
- struct wgdevice* dev;
- struct wgpeer* peer;
- struct wgallowedip* aip;
- int ret;
+ WG_IOCTL_INTERFACE *wg_iface;
+ WG_IOCTL_PEER *wg_peer;
+ WG_IOCTL_ALLOWED_IP *wg_aip;
+ void *buf = NULL;
+ DWORD buf_len = 0;
+ HANDLE handle = kernel_interface_handle(iface);
+ struct wgdevice *dev;
+ struct wgpeer *peer;
+ struct wgallowedip *aip;
+ int ret;
- *device = NULL;
+ *device = NULL;
- if (!handle)
- return -errno;
+ if (!handle)
+ return -errno;
- while (!DeviceIoControl(handle, WG_IOCTL_GET, NULL, 0, buf, buf_len, &buf_len, NULL))
- {
- free(buf);
- if (GetLastError() != ERROR_MORE_DATA)
- {
- errno = EACCES;
- return -errno;
- }
- buf = malloc(buf_len);
- if (!buf)
- return -errno;
- }
+ while (!DeviceIoControl(handle, WG_IOCTL_GET, NULL, 0, buf, buf_len, &buf_len, NULL)) {
+ free(buf);
+ if (GetLastError() != ERROR_MORE_DATA) {
+ errno = EACCES;
+ return -errno;
+ }
+ buf = malloc(buf_len);
+ if (!buf)
+ return -errno;
+ }
- wg_iface = (WG_IOCTL_INTERFACE*)buf;
- dev = calloc(1, sizeof(*dev));
- if (!dev)
- goto out;
- strncpy(dev->name, iface, sizeof(dev->name));
- dev->name[sizeof(dev->name) - 1] = '\0';
+ wg_iface = (WG_IOCTL_INTERFACE *)buf;
+ dev = calloc(1, sizeof(*dev));
+ if (!dev)
+ goto out;
+ strncpy(dev->name, iface, sizeof(dev->name));
+ dev->name[sizeof(dev->name) - 1] = '\0';
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_HAS_LISTEN_PORT)
- {
- dev->listen_port = wg_iface->ListenPort;
- dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
- }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_HAS_LISTEN_PORT) {
+ dev->listen_port = wg_iface->ListenPort;
+ dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
+ }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_HAS_PUBLIC_KEY)
- {
- memcpy(dev->public_key, wg_iface->PublicKey, sizeof(dev->public_key));
- dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
- }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_HAS_PUBLIC_KEY) {
+ memcpy(dev->public_key, wg_iface->PublicKey, sizeof(dev->public_key));
+ dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
+ }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY)
- {
- memcpy(dev->private_key, wg_iface->PrivateKey, sizeof(dev->private_key));
- dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
- }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY) {
+ memcpy(dev->private_key, wg_iface->PrivateKey, sizeof(dev->private_key));
+ dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
+ }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_JC)
- {
- dev->junk_packet_count = wg_iface->JunkPacketCount;
- dev->flags |= WGDEVICE_HAS_JC;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_JMIN)
- {
- dev->junk_packet_min_size = wg_iface->JunkPacketMinSize;
- dev->flags |= WGDEVICE_HAS_JMIN;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_JMAX)
- {
- dev->junk_packet_max_size = wg_iface->JunkPacketMaxSize;
- dev->flags |= WGDEVICE_HAS_JMAX;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_S1)
- {
- dev->init_packet_junk_size = wg_iface->InitPacketJunkSize;
- dev->flags |= WGDEVICE_HAS_S1;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_S2)
- {
- dev->response_packet_junk_size = wg_iface->ResponsePacketJunkSize;
- dev->flags |= WGDEVICE_HAS_S2;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_H1)
- {
- dev->init_packet_magic_header = wg_iface->InitPacketMagicHeader;
- dev->flags |= WGDEVICE_HAS_H1;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_H2)
- {
- dev->response_packet_magic_header = wg_iface->ResponsePacketMagicHeader;
- dev->flags |= WGDEVICE_HAS_H2;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_H3)
- {
- dev->underload_packet_magic_header = wg_iface->UnderloadPacketMagicHeader;
- dev->flags |= WGDEVICE_HAS_H3;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_H4)
- {
- dev->transport_packet_magic_header = wg_iface->TransportPacketMagicHeader;
- dev->flags |= WGDEVICE_HAS_H4;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_I1)
- {
- const size_t i1_size = strlen((char*)wg_iface->I1) + 1;
- dev->i1 = (char*)malloc(i1_size);
- memcpy(dev->i1, wg_iface->I1, i1_size);
- dev->flags |= WGDEVICE_HAS_I1;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_I2)
- {
- const size_t i2_size = strlen((char*)wg_iface->I2) + 1;
- dev->i2 = (char*)malloc(i2_size);
- memcpy(dev->i2, wg_iface->I2, i2_size);
- dev->flags |= WGDEVICE_HAS_I2;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_I3)
- {
- const size_t i3_size = strlen((char*)wg_iface->I3) + 1;
- dev->i3 = (char*)malloc(i3_size);
- memcpy(dev->i3, wg_iface->I3, i3_size);
- dev->flags |= WGDEVICE_HAS_I3;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_I4)
- {
- const size_t i4_size = strlen((char*)wg_iface->I4) + 1;
- dev->i4 = (char*)malloc(i4_size);
- memcpy(dev->i4, wg_iface->I4, i4_size);
- dev->flags |= WGDEVICE_HAS_I4;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_I5)
- {
- const size_t i5_size = strlen((char*)wg_iface->I5) + 1;
- dev->i5 = (char*)malloc(i5_size);
- memcpy(dev->i5, wg_iface->I5, i5_size);
- dev->flags |= WGDEVICE_HAS_I5;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_J1)
- {
- const size_t j1_size = strlen((char*)wg_iface->J1) + 1;
- dev->j1 = (char*)malloc(j1_size);
- memcpy(dev->j1, wg_iface->J1, j1_size);
- dev->flags |= WGDEVICE_HAS_J1;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_J2)
- {
- const size_t j2_size = strlen((char*)wg_iface->J2) + 1;
- dev->j2 = (char*)malloc(j2_size);
- memcpy(dev->j2, wg_iface->J2, j2_size);
- dev->flags |= WGDEVICE_HAS_J2;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_J3)
- {
- const size_t j3_size = strlen((char*)wg_iface->J3) + 1;
- dev->j3 = (char*)malloc(j3_size);
- memcpy(dev->j3, wg_iface->J3, j3_size);
- dev->flags |= WGDEVICE_HAS_J3;
- }
- if (wg_iface->Flags & WG_IOCTL_INTERFACE_ITIME)
- {
- dev->itime = wg_iface->Itime;
- dev->flags |= WGDEVICE_HAS_ITIME;
- }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_JC) {
+ dev->junk_packet_count = wg_iface->JunkPacketCount;
+ dev->flags |= WGDEVICE_HAS_JC;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_JMIN) {
+ dev->junk_packet_min_size = wg_iface->JunkPacketMinSize;
+ dev->flags |= WGDEVICE_HAS_JMIN;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_JMAX) {
+ dev->junk_packet_max_size = wg_iface->JunkPacketMaxSize;
+ dev->flags |= WGDEVICE_HAS_JMAX;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_S1) {
+ dev->init_packet_junk_size = wg_iface->InitPacketJunkSize;
+ dev->flags |= WGDEVICE_HAS_S1;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_S2) {
+ dev->response_packet_junk_size = wg_iface->ResponsePacketJunkSize;
+ dev->flags |= WGDEVICE_HAS_S2;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_H1) {
+ dev->init_packet_magic_header = wg_iface->InitPacketMagicHeader;
+ dev->flags |= WGDEVICE_HAS_H1;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_H2) {
+ dev->response_packet_magic_header = wg_iface->ResponsePacketMagicHeader;
+ dev->flags |= WGDEVICE_HAS_H2;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_H3) {
+ dev->underload_packet_magic_header = wg_iface->UnderloadPacketMagicHeader;
+ dev->flags |= WGDEVICE_HAS_H3;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_H4) {
+ dev->transport_packet_magic_header = wg_iface->TransportPacketMagicHeader;
+ dev->flags |= WGDEVICE_HAS_H4;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_I1)
+ {
+ const size_t i1_size = strlen((char*)wg_iface->I1) + 1;
+ dev->i1 = (char*)malloc(i1_size);
+ memcpy(dev->i1, wg_iface->I1, i1_size);
+ dev->flags |= WGDEVICE_HAS_I1;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_I2)
+ {
+ const size_t i2_size = strlen((char*)wg_iface->I2) + 1;
+ dev->i2 = (char*)malloc(i2_size);
+ memcpy(dev->i2, wg_iface->I2, i2_size);
+ dev->flags |= WGDEVICE_HAS_I2;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_I3)
+ {
+ const size_t i3_size = strlen((char*)wg_iface->I3) + 1;
+ dev->i3 = (char*)malloc(i3_size);
+ memcpy(dev->i3, wg_iface->I3, i3_size);
+ dev->flags |= WGDEVICE_HAS_I3;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_I4)
+ {
+ const size_t i4_size = strlen((char*)wg_iface->I4) + 1;
+ dev->i4 = (char*)malloc(i4_size);
+ memcpy(dev->i4, wg_iface->I4, i4_size);
+ dev->flags |= WGDEVICE_HAS_I4;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_I5)
+ {
+ const size_t i5_size = strlen((char*)wg_iface->I5) + 1;
+ dev->i5 = (char*)malloc(i5_size);
+ memcpy(dev->i5, wg_iface->I5, i5_size);
+ dev->flags |= WGDEVICE_HAS_I5;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_J1)
+ {
+ const size_t j1_size = strlen((char*)wg_iface->J1) + 1;
+ dev->j1 = (char*)malloc(j1_size);
+ memcpy(dev->j1, wg_iface->J1, j1_size);
+ dev->flags |= WGDEVICE_HAS_J1;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_J2)
+ {
+ const size_t j2_size = strlen((char*)wg_iface->J2) + 1;
+ dev->j2 = (char*)malloc(j2_size);
+ memcpy(dev->j2, wg_iface->J2, j2_size);
+ dev->flags |= WGDEVICE_HAS_J2;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_J3)
+ {
+ const size_t j3_size = strlen((char*)wg_iface->J3) + 1;
+ dev->j3 = (char*)malloc(j3_size);
+ memcpy(dev->j3, wg_iface->J3, j3_size);
+ dev->flags |= WGDEVICE_HAS_J3;
+ }
+ if (wg_iface->Flags & WG_IOCTL_INTERFACE_ITIME)
+ {
+ dev->itime = wg_iface->Itime;
+ dev->flags |= WGDEVICE_HAS_ITIME;
+ }
- wg_peer = buf + sizeof(WG_IOCTL_INTERFACE);
- for (ULONG i = 0; i < wg_iface->PeersCount; ++i)
- {
- peer = calloc(1, sizeof(*peer));
- if (!peer)
- goto out;
+ wg_peer = buf + sizeof(WG_IOCTL_INTERFACE);
+ for (ULONG i = 0; i < wg_iface->PeersCount; ++i) {
+ peer = calloc(1, sizeof(*peer));
+ if (!peer)
+ goto out;
- if (dev->first_peer == NULL)
- dev->first_peer = peer;
- else
- dev->last_peer->next_peer = peer;
- dev->last_peer = peer;
+ if (dev->first_peer == NULL)
+ dev->first_peer = peer;
+ else
+ dev->last_peer->next_peer = peer;
+ dev->last_peer = peer;
- if (wg_peer->Flags & WG_IOCTL_PEER_HAS_PUBLIC_KEY)
- {
- memcpy(peer->public_key, wg_peer->PublicKey, sizeof(peer->public_key));
- peer->flags |= WGPEER_HAS_PUBLIC_KEY;
- }
+ if (wg_peer->Flags & WG_IOCTL_PEER_HAS_PUBLIC_KEY) {
+ memcpy(peer->public_key, wg_peer->PublicKey, sizeof(peer->public_key));
+ peer->flags |= WGPEER_HAS_PUBLIC_KEY;
+ }
- if (wg_peer->Flags & WG_IOCTL_PEER_HAS_PRESHARED_KEY)
- {
- memcpy(
- peer->preshared_key, wg_peer->PresharedKey, sizeof(peer->preshared_key));
- if (!key_is_zero(peer->preshared_key))
- peer->flags |= WGPEER_HAS_PRESHARED_KEY;
- }
+ if (wg_peer->Flags & WG_IOCTL_PEER_HAS_PRESHARED_KEY) {
+ memcpy(peer->preshared_key, wg_peer->PresharedKey, sizeof(peer->preshared_key));
+ if (!key_is_zero(peer->preshared_key))
+ peer->flags |= WGPEER_HAS_PRESHARED_KEY;
+ }
- if (wg_peer->Flags & WG_IOCTL_PEER_HAS_PERSISTENT_KEEPALIVE)
- {
- peer->persistent_keepalive_interval = wg_peer->PersistentKeepalive;
- peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
- }
+ if (wg_peer->Flags & WG_IOCTL_PEER_HAS_PERSISTENT_KEEPALIVE) {
+ peer->persistent_keepalive_interval = wg_peer->PersistentKeepalive;
+ peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
+ }
- if (wg_peer->Flags & WG_IOCTL_PEER_HAS_ENDPOINT)
- {
- if (wg_peer->Endpoint.si_family == AF_INET)
- peer->endpoint.addr4 = wg_peer->Endpoint.Ipv4;
- else if (wg_peer->Endpoint.si_family == AF_INET6)
- peer->endpoint.addr6 = wg_peer->Endpoint.Ipv6;
- }
+ if (wg_peer->Flags & WG_IOCTL_PEER_HAS_ENDPOINT) {
+ if (wg_peer->Endpoint.si_family == AF_INET)
+ peer->endpoint.addr4 = wg_peer->Endpoint.Ipv4;
+ else if (wg_peer->Endpoint.si_family == AF_INET6)
+ peer->endpoint.addr6 = wg_peer->Endpoint.Ipv6;
+ }
- peer->rx_bytes = wg_peer->RxBytes;
- peer->tx_bytes = wg_peer->TxBytes;
+ peer->rx_bytes = wg_peer->RxBytes;
+ peer->tx_bytes = wg_peer->TxBytes;
- if (wg_peer->LastHandshake)
- {
- peer->last_handshake_time.tv_sec =
- wg_peer->LastHandshake / 10000000 - 11644473600LL;
- peer->last_handshake_time.tv_nsec = wg_peer->LastHandshake % 10000000 * 100;
- }
+ if (wg_peer->LastHandshake) {
+ peer->last_handshake_time.tv_sec = wg_peer->LastHandshake / 10000000 - 11644473600LL;
+ peer->last_handshake_time.tv_nsec = wg_peer->LastHandshake % 10000000 * 100;
+ }
- wg_aip = (void*)wg_peer + sizeof(WG_IOCTL_PEER);
- for (ULONG j = 0; j < wg_peer->AllowedIPsCount; ++j)
- {
- aip = calloc(1, sizeof(*aip));
- if (!aip)
- goto out;
+ wg_aip = (void *)wg_peer + sizeof(WG_IOCTL_PEER);
+ for (ULONG j = 0; j < wg_peer->AllowedIPsCount; ++j) {
+ aip = calloc(1, sizeof(*aip));
+ if (!aip)
+ goto out;
- if (peer->first_allowedip == NULL)
- peer->first_allowedip = aip;
- else
- peer->last_allowedip->next_allowedip = aip;
- peer->last_allowedip = aip;
+ if (peer->first_allowedip == NULL)
+ peer->first_allowedip = aip;
+ else
+ peer->last_allowedip->next_allowedip = aip;
+ peer->last_allowedip = aip;
- aip->family = wg_aip->AddressFamily;
- if (wg_aip->AddressFamily == AF_INET)
- {
- memcpy(&aip->ip4, &wg_aip->Address.V4, sizeof(aip->ip4));
- aip->cidr = wg_aip->Cidr;
- }
- else if (wg_aip->AddressFamily == AF_INET6)
- {
- memcpy(&aip->ip6, &wg_aip->Address.V6, sizeof(aip->ip6));
- aip->cidr = wg_aip->Cidr;
- }
- ++wg_aip;
- }
- wg_peer = (WG_IOCTL_PEER*)wg_aip;
- }
- *device = dev;
- errno = 0;
+ aip->family = wg_aip->AddressFamily;
+ if (wg_aip->AddressFamily == AF_INET) {
+ memcpy(&aip->ip4, &wg_aip->Address.V4, sizeof(aip->ip4));
+ aip->cidr = wg_aip->Cidr;
+ } else if (wg_aip->AddressFamily == AF_INET6) {
+ memcpy(&aip->ip6, &wg_aip->Address.V6, sizeof(aip->ip6));
+ aip->cidr = wg_aip->Cidr;
+ }
+ ++wg_aip;
+ }
+ wg_peer = (WG_IOCTL_PEER *)wg_aip;
+ }
+ *device = dev;
+ errno = 0;
out:
- ret = -errno;
- free(buf);
- CloseHandle(handle);
- return ret;
+ ret = -errno;
+ free(buf);
+ CloseHandle(handle);
+ return ret;
}
-static int kernel_set_device(struct wgdevice* dev)
+static int kernel_set_device(struct wgdevice *dev)
{
- WG_IOCTL_INTERFACE* wg_iface = NULL;
- WG_IOCTL_PEER* wg_peer;
- WG_IOCTL_ALLOWED_IP* wg_aip;
- DWORD buf_len = sizeof(WG_IOCTL_INTERFACE);
- HANDLE handle = kernel_interface_handle(dev->name);
- struct wgpeer* peer;
- struct wgallowedip* aip;
- size_t peer_count, aip_count;
- int ret = 0;
+ WG_IOCTL_INTERFACE *wg_iface = NULL;
+ WG_IOCTL_PEER *wg_peer;
+ WG_IOCTL_ALLOWED_IP *wg_aip;
+ DWORD buf_len = sizeof(WG_IOCTL_INTERFACE);
+ HANDLE handle = kernel_interface_handle(dev->name);
+ struct wgpeer *peer;
+ struct wgallowedip *aip;
+ size_t peer_count, aip_count;
+ int ret = 0;
- if (!handle)
- return -errno;
+ if (!handle)
+ return -errno;
- for_each_wgpeer(dev, peer)
- {
- if (DWORD_MAX - buf_len < sizeof(WG_IOCTL_PEER))
- {
- errno = EOVERFLOW;
- goto out;
- }
- buf_len += sizeof(WG_IOCTL_PEER);
- for_each_wgallowedip(peer, aip)
- {
- if (DWORD_MAX - buf_len < sizeof(WG_IOCTL_ALLOWED_IP))
- {
- errno = EOVERFLOW;
- goto out;
- }
- buf_len += sizeof(WG_IOCTL_ALLOWED_IP);
- }
- }
- wg_iface = calloc(1, buf_len);
- if (!wg_iface)
- goto out;
+ for_each_wgpeer(dev, peer) {
+ if (DWORD_MAX - buf_len < sizeof(WG_IOCTL_PEER)) {
+ errno = EOVERFLOW;
+ goto out;
+ }
+ buf_len += sizeof(WG_IOCTL_PEER);
+ for_each_wgallowedip(peer, aip) {
+ if (DWORD_MAX - buf_len < sizeof(WG_IOCTL_ALLOWED_IP)) {
+ errno = EOVERFLOW;
+ goto out;
+ }
+ buf_len += sizeof(WG_IOCTL_ALLOWED_IP);
+ }
+ }
+ wg_iface = calloc(1, buf_len);
+ if (!wg_iface)
+ goto out;
- if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
- {
- memcpy(wg_iface->PrivateKey, dev->private_key, sizeof(wg_iface->PrivateKey));
- wg_iface->Flags |= WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY;
- }
+ if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
+ memcpy(wg_iface->PrivateKey, dev->private_key, sizeof(wg_iface->PrivateKey));
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY;
+ }
- if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
- {
- wg_iface->ListenPort = dev->listen_port;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_HAS_LISTEN_PORT;
- }
+ if (dev->flags & WGDEVICE_HAS_LISTEN_PORT) {
+ wg_iface->ListenPort = dev->listen_port;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_HAS_LISTEN_PORT;
+ }
- if (dev->flags & WGDEVICE_REPLACE_PEERS)
- wg_iface->Flags |= WG_IOCTL_INTERFACE_REPLACE_PEERS;
+ if (dev->flags & WGDEVICE_REPLACE_PEERS)
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_REPLACE_PEERS;
- if (dev->flags & WGDEVICE_HAS_JC)
- {
- wg_iface->JunkPacketCount = dev->junk_packet_count;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_JC;
- }
+ if (dev->flags & WGDEVICE_HAS_JC) {
+ wg_iface->JunkPacketCount = dev->junk_packet_count;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_JC;
+ }
- if (dev->flags & WGDEVICE_HAS_JMIN)
- {
- wg_iface->JunkPacketMinSize = dev->junk_packet_min_size;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_JMIN;
- }
+ if (dev->flags & WGDEVICE_HAS_JMIN) {
+ wg_iface->JunkPacketMinSize = dev->junk_packet_min_size;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_JMIN;
+ }
- if (dev->flags & WGDEVICE_HAS_JMAX)
- {
- wg_iface->JunkPacketMaxSize = dev->junk_packet_max_size;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_JMAX;
- }
+ if (dev->flags & WGDEVICE_HAS_JMAX) {
+ wg_iface->JunkPacketMaxSize = dev->junk_packet_max_size;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_JMAX;
+ }
- if (dev->flags & WGDEVICE_HAS_S1)
- {
- wg_iface->InitPacketJunkSize = dev->init_packet_junk_size;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_S1;
- }
+ if (dev->flags & WGDEVICE_HAS_S1) {
+ wg_iface->InitPacketJunkSize = dev->init_packet_junk_size;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_S1;
+ }
- if (dev->flags & WGDEVICE_HAS_S2)
- {
- wg_iface->ResponsePacketJunkSize = dev->response_packet_junk_size;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_S2;
- }
+ if (dev->flags & WGDEVICE_HAS_S2) {
+ wg_iface->ResponsePacketJunkSize = dev->response_packet_junk_size;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_S2;
+ }
- if (dev->flags & WGDEVICE_HAS_H1)
- {
- wg_iface->InitPacketMagicHeader = dev->init_packet_magic_header;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_H1;
- }
+ if (dev->flags & WGDEVICE_HAS_H1) {
+ wg_iface->InitPacketMagicHeader = dev->init_packet_magic_header;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_H1;
+ }
- if (dev->flags & WGDEVICE_HAS_H2)
- {
- wg_iface->ResponsePacketMagicHeader = dev->response_packet_magic_header;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_H2;
- }
+ if (dev->flags & WGDEVICE_HAS_H2) {
+ wg_iface->ResponsePacketMagicHeader = dev->response_packet_magic_header;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_H2;
+ }
- if (dev->flags & WGDEVICE_HAS_H3)
- {
- wg_iface->UnderloadPacketMagicHeader = dev->underload_packet_magic_header;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_H3;
- }
+ if (dev->flags & WGDEVICE_HAS_H3) {
+ wg_iface->UnderloadPacketMagicHeader = dev->underload_packet_magic_header;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_H3;
+ }
- if (dev->flags & WGDEVICE_HAS_H4)
- {
- wg_iface->TransportPacketMagicHeader = dev->transport_packet_magic_header;
- wg_iface->Flags |= WG_IOCTL_INTERFACE_H4;
- }
- if (dev->flags & WG_DEVICE_HAS_I1)
- {
- const size_t i1_size = strlen(dev->i1) + 1;
- wg_iface->I1 = (UCHAR*)malloc(i1_size);
- memcpy(wg_iface->I1, dev->i1, i1_size);
- dev->flags |= WG_IOCTL_INTERFACE_I1;
- }
- if (dev->flags & WG_DEVICE_HAS_I2)
- {
- const size_t i2_size = strlen(dev->i2) + 1;
- wg_iface->I2 = (UCHAR*)malloc(i2_size);
- memcpy(wg_iface->I2, dev->i2, i2_size);
- dev->flags |= WG_IOCTL_INTERFACE_I2;
- }
- if (dev->flags & WG_DEVICE_HAS_I3)
- {
- const size_t i3_size = strlen(dev->i3) + 1;
- wg_iface->I3 = (UCHAR*)malloc(i3_size);
- memcpy(wg_iface->I3, dev->i3, i3_size);
- dev->flags |= WG_IOCTL_INTERFACE_I3;
- }
- if (dev->flags & WG_DEVICE_HAS_I4)
- {
- const size_t i4_size = strlen(dev->i4) + 1;
- wg_iface->I4 = (UCHAR*)malloc(i4_size);
- memcpy(wg_iface->I4, dev->i4, i4_size);
- dev->flags |= WG_IOCTL_INTERFACE_I4;
- }
- if (dev->flags & WG_DEVICE_HAS_I5)
- {
- const size_t i5_size = strlen(dev->i5) + 1;
- wg_iface->I5 = (UCHAR*)malloc(i5_size);
- memcpy(wg_iface->I5, dev->i5, i5_size);
- dev->flags |= WG_IOCTL_INTERFACE_I5;
- }
- if (dev->flags & WG_DEVICE_HAS_J1)
- {
- const size_t j1_size = strlen(dev->j1) + 1;
- wg_iface->J1 = (UCHAR*)malloc(j1_size);
- memcpy(wg_iface->J1, dev->j1, j1_size);
- dev->flags |= WG_IOCTL_INTERFACE_J1;
- }
- if (dev->flags & WG_DEVICE_HAS_J2)
- {
- const size_t j2_size = strlen(dev->j2) + 1;
- wg_iface->J2 = (UCHAR*)malloc(j2_size);
- memcpy(wg_iface->J2, dev->j2, j2_size);
- dev->flags |= WG_IOCTL_INTERFACE_J2;
- }
- if (dev->flags & WG_DEVICE_HAS_J3)
- {
- const size_t j3_size = strlen(dev->j3) + 1;
- wg_iface->J3 = (UCHAR*)malloc(j3_size);
- memcpy(wg_iface->J3, dev->j3, j3_size);
- dev->flags |= WG_IOCTL_INTERFACE_J3;
- }
- if (dev->flags & WG_DEVICE_HAS_ITIME)
- {
- wg_iface->Itime = dev->Itime;
- wg_iface->flags |= WG_IOCTL_INTERFACE_HAS_ITIME;
- }
+ if (dev->flags & WGDEVICE_HAS_H4) {
+ wg_iface->TransportPacketMagicHeader = dev->transport_packet_magic_header;
+ wg_iface->Flags |= WG_IOCTL_INTERFACE_H4;
+ }
- peer_count = 0;
- wg_peer = (void*)wg_iface + sizeof(WG_IOCTL_INTERFACE);
- for_each_wgpeer(dev, peer)
- {
- wg_peer->Flags = WG_IOCTL_PEER_HAS_PUBLIC_KEY;
- memcpy(wg_peer->PublicKey, peer->public_key, sizeof(wg_peer->PublicKey));
+ if (dev->flags & WG_DEVICE_HAS_I1)
+ {
+ const size_t i1_size = strlen(dev->i1) + 1;
+ wg_iface->I1 = (UCHAR*)malloc(i1_size);
+ memcpy(wg_iface->I1, dev->i1, i1_size);
+ dev->flags |= WG_IOCTL_INTERFACE_I1;
+ }
+ if (dev->flags & WG_DEVICE_HAS_I2)
+ {
+ const size_t i2_size = strlen(dev->i2) + 1;
+ wg_iface->I2 = (UCHAR*)malloc(i2_size);
+ memcpy(wg_iface->I2, dev->i2, i2_size);
+ dev->flags |= WG_IOCTL_INTERFACE_I2;
+ }
+ if (dev->flags & WG_DEVICE_HAS_I3)
+ {
+ const size_t i3_size = strlen(dev->i3) + 1;
+ wg_iface->I3 = (UCHAR*)malloc(i3_size);
+ memcpy(wg_iface->I3, dev->i3, i3_size);
+ dev->flags |= WG_IOCTL_INTERFACE_I3;
+ }
+ if (dev->flags & WG_DEVICE_HAS_I4)
+ {
+ const size_t i4_size = strlen(dev->i4) + 1;
+ wg_iface->I4 = (UCHAR*)malloc(i4_size);
+ memcpy(wg_iface->I4, dev->i4, i4_size);
+ dev->flags |= WG_IOCTL_INTERFACE_I4;
+ }
+ if (dev->flags & WG_DEVICE_HAS_I5)
+ {
+ const size_t i5_size = strlen(dev->i5) + 1;
+ wg_iface->I5 = (UCHAR*)malloc(i5_size);
+ memcpy(wg_iface->I5, dev->i5, i5_size);
+ dev->flags |= WG_IOCTL_INTERFACE_I5;
+ }
+ if (dev->flags & WG_DEVICE_HAS_J1)
+ {
+ const size_t j1_size = strlen(dev->j1) + 1;
+ wg_iface->J1 = (UCHAR*)malloc(j1_size);
+ memcpy(wg_iface->J1, dev->j1, j1_size);
+ dev->flags |= WG_IOCTL_INTERFACE_J1;
+ }
+ if (dev->flags & WG_DEVICE_HAS_J2)
+ {
+ const size_t j2_size = strlen(dev->j2) + 1;
+ wg_iface->J2 = (UCHAR*)malloc(j2_size);
+ memcpy(wg_iface->J2, dev->j2, j2_size);
+ dev->flags |= WG_IOCTL_INTERFACE_J2;
+ }
+ if (dev->flags & WG_DEVICE_HAS_J3)
+ {
+ const size_t j3_size = strlen(dev->j3) + 1;
+ wg_iface->J3 = (UCHAR*)malloc(j3_size);
+ memcpy(wg_iface->J3, dev->j3, j3_size);
+ dev->flags |= WG_IOCTL_INTERFACE_J3;
+ }
+ if (dev->flags & WG_DEVICE_HAS_ITIME)
+ {
+ wg_iface->Itime = dev->Itime;
+ wg_iface->flags |= WG_IOCTL_INTERFACE_HAS_ITIME;
+ }
- if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
- {
- memcpy(
- wg_peer->PresharedKey,
- peer->preshared_key,
- sizeof(wg_peer->PresharedKey));
- wg_peer->Flags |= WG_IOCTL_PEER_HAS_PRESHARED_KEY;
- }
+ peer_count = 0;
+ wg_peer = (void *)wg_iface + sizeof(WG_IOCTL_INTERFACE);
+ for_each_wgpeer(dev, peer) {
+ wg_peer->Flags = WG_IOCTL_PEER_HAS_PUBLIC_KEY;
+ memcpy(wg_peer->PublicKey, peer->public_key, sizeof(wg_peer->PublicKey));
- if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
- {
- wg_peer->PersistentKeepalive = peer->persistent_keepalive_interval;
- wg_peer->Flags |= WG_IOCTL_PEER_HAS_PERSISTENT_KEEPALIVE;
- }
+ if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
+ memcpy(wg_peer->PresharedKey, peer->preshared_key, sizeof(wg_peer->PresharedKey));
+ wg_peer->Flags |= WG_IOCTL_PEER_HAS_PRESHARED_KEY;
+ }
- if (peer->endpoint.addr.sa_family == AF_INET)
- {
- wg_peer->Endpoint.Ipv4 = peer->endpoint.addr4;
- wg_peer->Flags |= WG_IOCTL_PEER_HAS_ENDPOINT;
- }
- else if (peer->endpoint.addr.sa_family == AF_INET6)
- {
- wg_peer->Endpoint.Ipv6 = peer->endpoint.addr6;
- wg_peer->Flags |= WG_IOCTL_PEER_HAS_ENDPOINT;
- }
+ if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL) {
+ wg_peer->PersistentKeepalive = peer->persistent_keepalive_interval;
+ wg_peer->Flags |= WG_IOCTL_PEER_HAS_PERSISTENT_KEEPALIVE;
+ }
- if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
- wg_peer->Flags |= WG_IOCTL_PEER_REPLACE_ALLOWED_IPS;
+ if (peer->endpoint.addr.sa_family == AF_INET) {
+ wg_peer->Endpoint.Ipv4 = peer->endpoint.addr4;
+ wg_peer->Flags |= WG_IOCTL_PEER_HAS_ENDPOINT;
+ } else if (peer->endpoint.addr.sa_family == AF_INET6) {
+ wg_peer->Endpoint.Ipv6 = peer->endpoint.addr6;
+ wg_peer->Flags |= WG_IOCTL_PEER_HAS_ENDPOINT;
+ }
- if (peer->flags & WGPEER_REMOVE_ME)
- wg_peer->Flags |= WG_IOCTL_PEER_REMOVE;
+ if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
+ wg_peer->Flags |= WG_IOCTL_PEER_REPLACE_ALLOWED_IPS;
- aip_count = 0;
- wg_aip = (void*)wg_peer + sizeof(WG_IOCTL_PEER);
- for_each_wgallowedip(peer, aip)
- {
- wg_aip->AddressFamily = aip->family;
- wg_aip->Cidr = aip->cidr;
+ if (peer->flags & WGPEER_REMOVE_ME)
+ wg_peer->Flags |= WG_IOCTL_PEER_REMOVE;
- if (aip->family == AF_INET)
- wg_aip->Address.V4 = aip->ip4;
- else if (aip->family == AF_INET6)
- wg_aip->Address.V6 = aip->ip6;
- else
- continue;
- ++aip_count;
- ++wg_aip;
- }
- wg_peer->AllowedIPsCount = aip_count;
- ++peer_count;
- wg_peer = (WG_IOCTL_PEER*)wg_aip;
- }
- wg_iface->PeersCount = peer_count;
+ aip_count = 0;
+ wg_aip = (void *)wg_peer + sizeof(WG_IOCTL_PEER);
+ for_each_wgallowedip(peer, aip) {
+ wg_aip->AddressFamily = aip->family;
+ wg_aip->Cidr = aip->cidr;
- if (!DeviceIoControl(
- handle, WG_IOCTL_SET, NULL, 0, wg_iface, buf_len, &buf_len, NULL))
- {
- errno = EACCES;
- goto out;
- }
- errno = 0;
+ if (aip->family == AF_INET)
+ wg_aip->Address.V4 = aip->ip4;
+ else if (aip->family == AF_INET6)
+ wg_aip->Address.V6 = aip->ip6;
+ else
+ continue;
+ ++aip_count;
+ ++wg_aip;
+ }
+ wg_peer->AllowedIPsCount = aip_count;
+ ++peer_count;
+ wg_peer = (WG_IOCTL_PEER *)wg_aip;
+ }
+ wg_iface->PeersCount = peer_count;
+
+ if (!DeviceIoControl(handle, WG_IOCTL_SET, NULL, 0, wg_iface, buf_len, &buf_len, NULL)) {
+ errno = EACCES;
+ goto out;
+ }
+ errno = 0;
out:
- ret = -errno;
- free(wg_iface);
- CloseHandle(handle);
- return ret;
+ ret = -errno;
+ free(wg_iface);
+ CloseHandle(handle);
+ return ret;
}
diff --git a/src/netlink.h b/src/netlink.h
index 08f1382..f9729ee 100644
--- a/src/netlink.h
+++ b/src/netlink.h
@@ -6,853 +6,792 @@
/* This is a minimized version of libmnl meant to be #include'd */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#define MNL_SOCKET_AUTOPID 0
#define MNL_ALIGNTO 4
-#define MNL_ALIGN(len) (((len) + MNL_ALIGNTO - 1) & ~(MNL_ALIGNTO - 1))
+#define MNL_ALIGN(len) (((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1))
#define MNL_NLMSG_HDRLEN MNL_ALIGN(sizeof(struct nlmsghdr))
#define MNL_ATTR_HDRLEN MNL_ALIGN(sizeof(struct nlattr))
-enum mnl_attr_data_type
-{
- MNL_TYPE_UNSPEC,
- MNL_TYPE_U8,
- MNL_TYPE_U16,
- MNL_TYPE_U32,
- MNL_TYPE_U64,
- MNL_TYPE_STRING,
- MNL_TYPE_FLAG,
- MNL_TYPE_MSECS,
- MNL_TYPE_NESTED,
- MNL_TYPE_NESTED_COMPAT,
- MNL_TYPE_NUL_STRING,
- MNL_TYPE_BINARY,
- MNL_TYPE_MAX,
+enum mnl_attr_data_type {
+ MNL_TYPE_UNSPEC,
+ MNL_TYPE_U8,
+ MNL_TYPE_U16,
+ MNL_TYPE_U32,
+ MNL_TYPE_U64,
+ MNL_TYPE_STRING,
+ MNL_TYPE_FLAG,
+ MNL_TYPE_MSECS,
+ MNL_TYPE_NESTED,
+ MNL_TYPE_NESTED_COMPAT,
+ MNL_TYPE_NUL_STRING,
+ MNL_TYPE_BINARY,
+ MNL_TYPE_MAX,
};
-#define mnl_attr_for_each(attr, nlh, offset) \
- for ((attr) = mnl_nlmsg_get_payload_offset((nlh), (offset)); \
- mnl_attr_ok((attr), (char*)mnl_nlmsg_get_payload_tail(nlh) - (char*)(attr)); \
- (attr) = mnl_attr_next(attr))
+#define mnl_attr_for_each(attr, nlh, offset) \
+ for ((attr) = mnl_nlmsg_get_payload_offset((nlh), (offset)); \
+ mnl_attr_ok((attr), (char *)mnl_nlmsg_get_payload_tail(nlh) - (char *)(attr)); \
+ (attr) = mnl_attr_next(attr))
-#define mnl_attr_for_each_nested(attr, nest) \
- for ((attr) = mnl_attr_get_payload(nest); mnl_attr_ok( \
- (attr), \
- (char*)mnl_attr_get_payload(nest) + mnl_attr_get_payload_len(nest) - \
- (char*)(attr)); \
- (attr) = mnl_attr_next(attr))
+#define mnl_attr_for_each_nested(attr, nest) \
+ for ((attr) = mnl_attr_get_payload(nest); \
+ mnl_attr_ok((attr), (char *)mnl_attr_get_payload(nest) + mnl_attr_get_payload_len(nest) - (char *)(attr)); \
+ (attr) = mnl_attr_next(attr))
-#define mnl_attr_for_each_payload(payload, payload_size) \
- for ((attr) = (payload); \
- mnl_attr_ok((attr), (char*)(payload) + payload_size - (char*)(attr)); \
- (attr) = mnl_attr_next(attr))
+#define mnl_attr_for_each_payload(payload, payload_size) \
+ for ((attr) = (payload); \
+ mnl_attr_ok((attr), (char *)(payload) + payload_size - (char *)(attr)); \
+ (attr) = mnl_attr_next(attr))
-#define MNL_CB_ERROR -1
-#define MNL_CB_STOP 0
-#define MNL_CB_OK 1
+#define MNL_CB_ERROR -1
+#define MNL_CB_STOP 0
+#define MNL_CB_OK 1
-typedef int (*mnl_attr_cb_t)(const struct nlattr* attr, void* data);
-typedef int (*mnl_cb_t)(const struct nlmsghdr* nlh, void* data);
+typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data);
+typedef int (*mnl_cb_t)(const struct nlmsghdr *nlh, void *data);
#ifndef MNL_ARRAY_SIZE
-#define MNL_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#define MNL_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#endif
static size_t mnl_ideal_socket_buffer_size(void)
{
- static size_t size = 0;
+ static size_t size = 0;
- if (size)
- return size;
- size = (size_t)sysconf(_SC_PAGESIZE);
- if (size > 8192)
- size = 8192;
- return size;
+ if (size)
+ return size;
+ size = (size_t)sysconf(_SC_PAGESIZE);
+ if (size > 8192)
+ size = 8192;
+ return size;
}
-static size_t mnl_nlmsg_size(size_t len) { return len + MNL_NLMSG_HDRLEN; }
-
-static struct nlmsghdr* mnl_nlmsg_put_header(void* buf)
+static size_t mnl_nlmsg_size(size_t len)
{
- int len = MNL_ALIGN(sizeof(struct nlmsghdr));
- struct nlmsghdr* nlh = buf;
-
- memset(buf, 0, len);
- nlh->nlmsg_len = len;
- return nlh;
+ return len + MNL_NLMSG_HDRLEN;
}
-static void* mnl_nlmsg_put_extra_header(struct nlmsghdr* nlh, size_t size)
+static struct nlmsghdr *mnl_nlmsg_put_header(void *buf)
{
- char* ptr = (char*)nlh + nlh->nlmsg_len;
- size_t len = MNL_ALIGN(size);
- nlh->nlmsg_len += len;
- memset(ptr, 0, len);
- return ptr;
+ int len = MNL_ALIGN(sizeof(struct nlmsghdr));
+ struct nlmsghdr *nlh = buf;
+
+ memset(buf, 0, len);
+ nlh->nlmsg_len = len;
+ return nlh;
}
-static void* mnl_nlmsg_get_payload(const struct nlmsghdr* nlh)
+static void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
{
- return (void*)nlh + MNL_NLMSG_HDRLEN;
+ char *ptr = (char *)nlh + nlh->nlmsg_len;
+ size_t len = MNL_ALIGN(size);
+ nlh->nlmsg_len += len;
+ memset(ptr, 0, len);
+ return ptr;
}
-static void* mnl_nlmsg_get_payload_offset(const struct nlmsghdr* nlh, size_t offset)
+static void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
{
- return (void*)nlh + MNL_NLMSG_HDRLEN + MNL_ALIGN(offset);
+ return (void *)nlh + MNL_NLMSG_HDRLEN;
}
-static bool mnl_nlmsg_ok(const struct nlmsghdr* nlh, int len)
+static void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset)
{
- return len >= (int)sizeof(struct nlmsghdr) &&
- nlh->nlmsg_len >= sizeof(struct nlmsghdr) && (int)nlh->nlmsg_len <= len;
+ return (void *)nlh + MNL_NLMSG_HDRLEN + MNL_ALIGN(offset);
}
-static struct nlmsghdr* mnl_nlmsg_next(const struct nlmsghdr* nlh, int* len)
+static bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len)
{
- *len -= MNL_ALIGN(nlh->nlmsg_len);
- return (struct nlmsghdr*)((void*)nlh + MNL_ALIGN(nlh->nlmsg_len));
+ return len >= (int)sizeof(struct nlmsghdr) &&
+ nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
+ (int)nlh->nlmsg_len <= len;
}
-static void* mnl_nlmsg_get_payload_tail(const struct nlmsghdr* nlh)
+static struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len)
{
- return (void*)nlh + MNL_ALIGN(nlh->nlmsg_len);
+ *len -= MNL_ALIGN(nlh->nlmsg_len);
+ return (struct nlmsghdr *)((void *)nlh + MNL_ALIGN(nlh->nlmsg_len));
}
-static bool mnl_nlmsg_seq_ok(const struct nlmsghdr* nlh, unsigned int seq)
+static void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh)
{
- return nlh->nlmsg_seq && seq ? nlh->nlmsg_seq == seq : true;
+ return (void *)nlh + MNL_ALIGN(nlh->nlmsg_len);
}
-static bool mnl_nlmsg_portid_ok(const struct nlmsghdr* nlh, unsigned int portid)
+static bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq)
{
- return nlh->nlmsg_pid && portid ? nlh->nlmsg_pid == portid : true;
+ return nlh->nlmsg_seq && seq ? nlh->nlmsg_seq == seq : true;
}
-static uint16_t mnl_attr_get_type(const struct nlattr* attr)
+static bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid)
{
- return attr->nla_type & NLA_TYPE_MASK;
+ return nlh->nlmsg_pid && portid ? nlh->nlmsg_pid == portid : true;
}
-static uint16_t mnl_attr_get_payload_len(const struct nlattr* attr)
+static uint16_t mnl_attr_get_type(const struct nlattr *attr)
{
- return attr->nla_len - MNL_ATTR_HDRLEN;
+ return attr->nla_type & NLA_TYPE_MASK;
}
-static void* mnl_attr_get_payload(const struct nlattr* attr)
+static uint16_t mnl_attr_get_payload_len(const struct nlattr *attr)
{
- return (void*)attr + MNL_ATTR_HDRLEN;
+ return attr->nla_len - MNL_ATTR_HDRLEN;
}
-static bool mnl_attr_ok(const struct nlattr* attr, int len)
+static void *mnl_attr_get_payload(const struct nlattr *attr)
{
- return len >= (int)sizeof(struct nlattr) && attr->nla_len >= sizeof(struct nlattr) &&
- (int)attr->nla_len <= len;
+ return (void *)attr + MNL_ATTR_HDRLEN;
}
-static struct nlattr* mnl_attr_next(const struct nlattr* attr)
+static bool mnl_attr_ok(const struct nlattr *attr, int len)
{
- return (struct nlattr*)((void*)attr + MNL_ALIGN(attr->nla_len));
+ return len >= (int)sizeof(struct nlattr) &&
+ attr->nla_len >= sizeof(struct nlattr) &&
+ (int)attr->nla_len <= len;
}
-static int mnl_attr_type_valid(const struct nlattr* attr, uint16_t max)
+static struct nlattr *mnl_attr_next(const struct nlattr *attr)
{
- if (mnl_attr_get_type(attr) > max)
- {
- errno = EOPNOTSUPP;
- return -1;
- }
- return 1;
+ return (struct nlattr *)((void *)attr + MNL_ALIGN(attr->nla_len));
}
-static int __mnl_attr_validate(
- const struct nlattr* attr,
- enum mnl_attr_data_type type,
- size_t exp_len)
+static int mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
{
- uint16_t attr_len = mnl_attr_get_payload_len(attr);
- const char* attr_data = mnl_attr_get_payload(attr);
+ if (mnl_attr_get_type(attr) > max) {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+ return 1;
+}
- if (attr_len < exp_len)
- {
- errno = ERANGE;
- return -1;
- }
- switch (type)
- {
- case MNL_TYPE_FLAG:
- if (attr_len > 0)
- {
- errno = ERANGE;
- return -1;
- }
- break;
- case MNL_TYPE_NUL_STRING:
- if (attr_len == 0)
- {
- errno = ERANGE;
- return -1;
- }
- if (attr_data[attr_len - 1] != '\0')
- {
- errno = EINVAL;
- return -1;
- }
- break;
- case MNL_TYPE_STRING:
- if (attr_len == 0)
- {
- errno = ERANGE;
- return -1;
- }
- break;
- case MNL_TYPE_NESTED:
+static int __mnl_attr_validate(const struct nlattr *attr,
+ enum mnl_attr_data_type type, size_t exp_len)
+{
+ uint16_t attr_len = mnl_attr_get_payload_len(attr);
+ const char *attr_data = mnl_attr_get_payload(attr);
- if (attr_len == 0)
- break;
+ if (attr_len < exp_len) {
+ errno = ERANGE;
+ return -1;
+ }
+ switch(type) {
+ case MNL_TYPE_FLAG:
+ if (attr_len > 0) {
+ errno = ERANGE;
+ return -1;
+ }
+ break;
+ case MNL_TYPE_NUL_STRING:
+ if (attr_len == 0) {
+ errno = ERANGE;
+ return -1;
+ }
+ if (attr_data[attr_len-1] != '\0') {
+ errno = EINVAL;
+ return -1;
+ }
+ break;
+ case MNL_TYPE_STRING:
+ if (attr_len == 0) {
+ errno = ERANGE;
+ return -1;
+ }
+ break;
+ case MNL_TYPE_NESTED:
- if (attr_len < MNL_ATTR_HDRLEN)
- {
- errno = ERANGE;
- return -1;
- }
- break;
- default:
+ if (attr_len == 0)
+ break;
- break;
- }
- if (exp_len && attr_len > exp_len)
- {
- errno = ERANGE;
- return -1;
- }
- return 0;
+ if (attr_len < MNL_ATTR_HDRLEN) {
+ errno = ERANGE;
+ return -1;
+ }
+ break;
+ default:
+
+ break;
+ }
+ if (exp_len && attr_len > exp_len) {
+ errno = ERANGE;
+ return -1;
+ }
+ return 0;
}
static const size_t mnl_attr_data_type_len[MNL_TYPE_MAX] = {
- [MNL_TYPE_U8] = sizeof(uint8_t),
- [MNL_TYPE_U16] = sizeof(uint16_t),
- [MNL_TYPE_U32] = sizeof(uint32_t),
- [MNL_TYPE_U64] = sizeof(uint64_t),
- [MNL_TYPE_MSECS] = sizeof(uint64_t),
+ [MNL_TYPE_U8] = sizeof(uint8_t),
+ [MNL_TYPE_U16] = sizeof(uint16_t),
+ [MNL_TYPE_U32] = sizeof(uint32_t),
+ [MNL_TYPE_U64] = sizeof(uint64_t),
+ [MNL_TYPE_MSECS] = sizeof(uint64_t),
};
-static int mnl_attr_validate(const struct nlattr* attr, enum mnl_attr_data_type type)
+static int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
{
- int exp_len;
+ int exp_len;
- if (type >= MNL_TYPE_MAX)
- {
- errno = EINVAL;
- return -1;
- }
- exp_len = mnl_attr_data_type_len[type];
- return __mnl_attr_validate(attr, type, exp_len);
+ if (type >= MNL_TYPE_MAX) {
+ errno = EINVAL;
+ return -1;
+ }
+ exp_len = mnl_attr_data_type_len[type];
+ return __mnl_attr_validate(attr, type, exp_len);
}
-static int mnl_attr_parse(
- const struct nlmsghdr* nlh,
- unsigned int offset,
- mnl_attr_cb_t cb,
- void* data)
+static int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset,
+ mnl_attr_cb_t cb, void *data)
{
- int ret = MNL_CB_OK;
- const struct nlattr* attr;
+ int ret = MNL_CB_OK;
+ const struct nlattr *attr;
- mnl_attr_for_each(
- attr, nlh, offset) if ((ret = cb(attr, data)) <= MNL_CB_STOP) return ret;
- return ret;
+ mnl_attr_for_each(attr, nlh, offset)
+ if ((ret = cb(attr, data)) <= MNL_CB_STOP)
+ return ret;
+ return ret;
}
-static int
-mnl_attr_parse_nested(const struct nlattr* nested, mnl_attr_cb_t cb, void* data)
+static int mnl_attr_parse_nested(const struct nlattr *nested, mnl_attr_cb_t cb,
+ void *data)
{
- int ret = MNL_CB_OK;
- const struct nlattr* attr;
+ int ret = MNL_CB_OK;
+ const struct nlattr *attr;
- mnl_attr_for_each_nested(
- attr, nested) if ((ret = cb(attr, data)) <= MNL_CB_STOP) return ret;
- return ret;
+ mnl_attr_for_each_nested(attr, nested)
+ if ((ret = cb(attr, data)) <= MNL_CB_STOP)
+ return ret;
+ return ret;
}
-static uint8_t mnl_attr_get_u8(const struct nlattr* attr)
+static uint8_t mnl_attr_get_u8(const struct nlattr *attr)
{
- return *((uint8_t*)mnl_attr_get_payload(attr));
+ return *((uint8_t *)mnl_attr_get_payload(attr));
}
-static uint16_t mnl_attr_get_u16(const struct nlattr* attr)
+static uint16_t mnl_attr_get_u16(const struct nlattr *attr)
{
- return *((uint16_t*)mnl_attr_get_payload(attr));
+ return *((uint16_t *)mnl_attr_get_payload(attr));
}
-static uint32_t mnl_attr_get_u32(const struct nlattr* attr)
+static uint32_t mnl_attr_get_u32(const struct nlattr *attr)
{
- return *((uint32_t*)mnl_attr_get_payload(attr));
+ return *((uint32_t *)mnl_attr_get_payload(attr));
}
-static uint64_t mnl_attr_get_u64(const struct nlattr* attr)
+static uint64_t mnl_attr_get_u64(const struct nlattr *attr)
{
- uint64_t tmp;
- memcpy(&tmp, mnl_attr_get_payload(attr), sizeof(tmp));
- return tmp;
+ uint64_t tmp;
+ memcpy(&tmp, mnl_attr_get_payload(attr), sizeof(tmp));
+ return tmp;
}
-static const char* mnl_attr_get_str(const struct nlattr* attr)
+static const char *mnl_attr_get_str(const struct nlattr *attr)
{
- return mnl_attr_get_payload(attr);
+ return mnl_attr_get_payload(attr);
}
-static void
-mnl_attr_put(struct nlmsghdr* nlh, uint16_t type, size_t len, const void* data)
+static void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len,
+ const void *data)
{
- struct nlattr* attr = mnl_nlmsg_get_payload_tail(nlh);
- uint16_t payload_len = MNL_ALIGN(sizeof(struct nlattr)) + len;
- int pad;
+ struct nlattr *attr = mnl_nlmsg_get_payload_tail(nlh);
+ uint16_t payload_len = MNL_ALIGN(sizeof(struct nlattr)) + len;
+ int pad;
- attr->nla_type = type;
- attr->nla_len = payload_len;
- memcpy(mnl_attr_get_payload(attr), data, len);
-
- nlh->nlmsg_len += MNL_ALIGN(payload_len);
- pad = MNL_ALIGN(len) - len;
- if (pad > 0)
- memset(mnl_attr_get_payload(attr) + len, 0, pad);
+ attr->nla_type = type;
+ attr->nla_len = payload_len;
+ memcpy(mnl_attr_get_payload(attr), data, len);
+ nlh->nlmsg_len += MNL_ALIGN(payload_len);
+ pad = MNL_ALIGN(len) - len;
+ if (pad > 0)
+ memset(mnl_attr_get_payload(attr) + len, 0, pad);
}
-static void mnl_attr_put_u16(struct nlmsghdr* nlh, uint16_t type, uint16_t data)
+static void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data)
{
- mnl_attr_put(nlh, type, sizeof(uint16_t), &data);
+ mnl_attr_put(nlh, type, sizeof(uint16_t), &data);
}
-static void mnl_attr_put_u32(struct nlmsghdr* nlh, uint16_t type, uint32_t data)
+static void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data)
{
- mnl_attr_put(nlh, type, sizeof(uint32_t), &data);
+ mnl_attr_put(nlh, type, sizeof(uint32_t), &data);
}
-static void mnl_attr_put_strz(struct nlmsghdr* nlh, uint16_t type, const char* data)
+static void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data)
{
- mnl_attr_put(nlh, type, strlen(data) + 1, data);
+ mnl_attr_put(nlh, type, strlen(data)+1, data);
}
-static struct nlattr* mnl_attr_nest_start(struct nlmsghdr* nlh, uint16_t type)
+static struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type)
{
- struct nlattr* start = mnl_nlmsg_get_payload_tail(nlh);
+ struct nlattr *start = mnl_nlmsg_get_payload_tail(nlh);
- start->nla_type = NLA_F_NESTED | type;
- nlh->nlmsg_len += MNL_ALIGN(sizeof(struct nlattr));
- return start;
+ start->nla_type = NLA_F_NESTED | type;
+ nlh->nlmsg_len += MNL_ALIGN(sizeof(struct nlattr));
+ return start;
}
-static bool mnl_attr_put_check(
- struct nlmsghdr* nlh,
- size_t buflen,
- uint16_t type,
- size_t len,
- const void* data)
+static bool mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type, size_t len, const void *data)
{
- if (nlh->nlmsg_len + MNL_ATTR_HDRLEN + MNL_ALIGN(len) > buflen)
- return false;
- mnl_attr_put(nlh, type, len, data);
- return true;
+ if (nlh->nlmsg_len + MNL_ATTR_HDRLEN + MNL_ALIGN(len) > buflen)
+ return false;
+ mnl_attr_put(nlh, type, len, data);
+ return true;
}
-static bool
-mnl_attr_put_u8_check(struct nlmsghdr* nlh, size_t buflen, uint16_t type, uint8_t data)
+static bool mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type, uint8_t data)
{
- return mnl_attr_put_check(nlh, buflen, type, sizeof(uint8_t), &data);
+ return mnl_attr_put_check(nlh, buflen, type, sizeof(uint8_t), &data);
}
-static bool
-mnl_attr_put_u16_check(struct nlmsghdr* nlh, size_t buflen, uint16_t type, uint16_t data)
+static bool mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type, uint16_t data)
{
- return mnl_attr_put_check(nlh, buflen, type, sizeof(uint16_t), &data);
+ return mnl_attr_put_check(nlh, buflen, type, sizeof(uint16_t), &data);
}
-static bool
-mnl_attr_put_u32_check(struct nlmsghdr* nlh, size_t buflen, uint16_t type, uint32_t data)
+static bool mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type, uint32_t data)
{
- return mnl_attr_put_check(nlh, buflen, type, sizeof(uint32_t), &data);
+ return mnl_attr_put_check(nlh, buflen, type, sizeof(uint32_t), &data);
}
-static struct nlattr*
-mnl_attr_nest_start_check(struct nlmsghdr* nlh, size_t buflen, uint16_t type)
+static struct nlattr *mnl_attr_nest_start_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type)
{
- if (nlh->nlmsg_len + MNL_ATTR_HDRLEN > buflen)
- return NULL;
- return mnl_attr_nest_start(nlh, type);
+ if (nlh->nlmsg_len + MNL_ATTR_HDRLEN > buflen)
+ return NULL;
+ return mnl_attr_nest_start(nlh, type);
}
-static void mnl_attr_nest_end(struct nlmsghdr* nlh, struct nlattr* start)
+static void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start)
{
- start->nla_len = mnl_nlmsg_get_payload_tail(nlh) - (void*)start;
+ start->nla_len = mnl_nlmsg_get_payload_tail(nlh) - (void *)start;
}
-static void mnl_attr_nest_cancel(struct nlmsghdr* nlh, struct nlattr* start)
+static void mnl_attr_nest_cancel(struct nlmsghdr *nlh, struct nlattr *start)
{
- nlh->nlmsg_len -= mnl_nlmsg_get_payload_tail(nlh) - (void*)start;
+ nlh->nlmsg_len -= mnl_nlmsg_get_payload_tail(nlh) - (void *)start;
}
-static int mnl_cb_noop(
- __attribute__((unused)) const struct nlmsghdr* nlh,
- __attribute__((unused)) void* data)
+static int mnl_cb_noop(__attribute__((unused)) const struct nlmsghdr *nlh, __attribute__((unused)) void *data)
{
- return MNL_CB_OK;
+ return MNL_CB_OK;
}
-static int mnl_cb_error(const struct nlmsghdr* nlh, __attribute__((unused)) void* data)
+static int mnl_cb_error(const struct nlmsghdr *nlh, __attribute__((unused)) void *data)
{
- const struct nlmsgerr* err = mnl_nlmsg_get_payload(nlh);
+ const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
- if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr)))
- {
- errno = EBADMSG;
- return MNL_CB_ERROR;
- }
+ if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr))) {
+ errno = EBADMSG;
+ return MNL_CB_ERROR;
+ }
- if (err->error < 0)
- errno = -err->error;
- else
- errno = err->error;
+ if (err->error < 0)
+ errno = -err->error;
+ else
+ errno = err->error;
- return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
+ return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
}
-static int mnl_cb_stop(
- __attribute__((unused)) const struct nlmsghdr* nlh,
- __attribute__((unused)) void* data)
+static int mnl_cb_stop(__attribute__((unused)) const struct nlmsghdr *nlh, __attribute__((unused)) void *data)
{
- return MNL_CB_STOP;
+ return MNL_CB_STOP;
}
static const mnl_cb_t default_cb_array[NLMSG_MIN_TYPE] = {
- [NLMSG_NOOP] = mnl_cb_noop,
- [NLMSG_ERROR] = mnl_cb_error,
- [NLMSG_DONE] = mnl_cb_stop,
- [NLMSG_OVERRUN] = mnl_cb_noop,
+ [NLMSG_NOOP] = mnl_cb_noop,
+ [NLMSG_ERROR] = mnl_cb_error,
+ [NLMSG_DONE] = mnl_cb_stop,
+ [NLMSG_OVERRUN] = mnl_cb_noop,
};
-static int __mnl_cb_run(
- const void* buf,
- size_t numbytes,
- unsigned int seq,
- unsigned int portid,
- mnl_cb_t cb_data,
- void* data,
- const mnl_cb_t* cb_ctl_array,
- unsigned int cb_ctl_array_len)
+static int __mnl_cb_run(const void *buf, size_t numbytes,
+ unsigned int seq, unsigned int portid,
+ mnl_cb_t cb_data, void *data,
+ const mnl_cb_t *cb_ctl_array,
+ unsigned int cb_ctl_array_len)
{
- int ret = MNL_CB_OK, len = numbytes;
- const struct nlmsghdr* nlh = buf;
+ int ret = MNL_CB_OK, len = numbytes;
+ const struct nlmsghdr *nlh = buf;
- while (mnl_nlmsg_ok(nlh, len))
- {
+ while (mnl_nlmsg_ok(nlh, len)) {
- if (!mnl_nlmsg_portid_ok(nlh, portid))
- {
- errno = ESRCH;
- return -1;
- }
+ if (!mnl_nlmsg_portid_ok(nlh, portid)) {
+ errno = ESRCH;
+ return -1;
+ }
- if (!mnl_nlmsg_seq_ok(nlh, seq))
- {
- errno = EPROTO;
- return -1;
- }
+ if (!mnl_nlmsg_seq_ok(nlh, seq)) {
+ errno = EPROTO;
+ return -1;
+ }
- if (nlh->nlmsg_flags & NLM_F_DUMP_INTR)
- {
- errno = EINTR;
- return -1;
- }
+ if (nlh->nlmsg_flags & NLM_F_DUMP_INTR) {
+ errno = EINTR;
+ return -1;
+ }
- if (nlh->nlmsg_type >= NLMSG_MIN_TYPE)
- {
- if (cb_data)
- {
- ret = cb_data(nlh, data);
- if (ret <= MNL_CB_STOP)
- goto out;
- }
- }
- else if (nlh->nlmsg_type < cb_ctl_array_len)
- {
- if (cb_ctl_array && cb_ctl_array[nlh->nlmsg_type])
- {
- ret = cb_ctl_array[nlh->nlmsg_type](nlh, data);
- if (ret <= MNL_CB_STOP)
- goto out;
- }
- }
- else if (default_cb_array[nlh->nlmsg_type])
- {
- ret = default_cb_array[nlh->nlmsg_type](nlh, data);
- if (ret <= MNL_CB_STOP)
- goto out;
- }
- nlh = mnl_nlmsg_next(nlh, &len);
- }
+ if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) {
+ if (cb_data){
+ ret = cb_data(nlh, data);
+ if (ret <= MNL_CB_STOP)
+ goto out;
+ }
+ } else if (nlh->nlmsg_type < cb_ctl_array_len) {
+ if (cb_ctl_array && cb_ctl_array[nlh->nlmsg_type]) {
+ ret = cb_ctl_array[nlh->nlmsg_type](nlh, data);
+ if (ret <= MNL_CB_STOP)
+ goto out;
+ }
+ } else if (default_cb_array[nlh->nlmsg_type]) {
+ ret = default_cb_array[nlh->nlmsg_type](nlh, data);
+ if (ret <= MNL_CB_STOP)
+ goto out;
+ }
+ nlh = mnl_nlmsg_next(nlh, &len);
+ }
out:
- return ret;
+ return ret;
}
-static int mnl_cb_run2(
- const void* buf,
- size_t numbytes,
- unsigned int seq,
- unsigned int portid,
- mnl_cb_t cb_data,
- void* data,
- const mnl_cb_t* cb_ctl_array,
- unsigned int cb_ctl_array_len)
+static int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq,
+ unsigned int portid, mnl_cb_t cb_data, void *data,
+ const mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len)
{
- return __mnl_cb_run(
- buf, numbytes, seq, portid, cb_data, data, cb_ctl_array, cb_ctl_array_len);
+ return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data,
+ cb_ctl_array, cb_ctl_array_len);
}
-static int mnl_cb_run(
- const void* buf,
- size_t numbytes,
- unsigned int seq,
- unsigned int portid,
- mnl_cb_t cb_data,
- void* data)
+static int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
+ unsigned int portid, mnl_cb_t cb_data, void *data)
{
- return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data, NULL, 0);
+ return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data, NULL, 0);
}
-struct mnl_socket
-{
- int fd;
- struct sockaddr_nl addr;
+struct mnl_socket {
+ int fd;
+ struct sockaddr_nl addr;
};
-static unsigned int mnl_socket_get_portid(const struct mnl_socket* nl)
+static unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
{
- return nl->addr.nl_pid;
+ return nl->addr.nl_pid;
}
-static struct mnl_socket* __mnl_socket_open(int bus, int flags)
+static struct mnl_socket *__mnl_socket_open(int bus, int flags)
{
- struct mnl_socket* nl;
+ struct mnl_socket *nl;
- nl = calloc(1, sizeof(struct mnl_socket));
- if (nl == NULL)
- return NULL;
+ nl = calloc(1, sizeof(struct mnl_socket));
+ if (nl == NULL)
+ return NULL;
- nl->fd = socket(AF_NETLINK, SOCK_RAW | flags, bus);
- if (nl->fd == -1)
- {
- free(nl);
- return NULL;
- }
+ nl->fd = socket(AF_NETLINK, SOCK_RAW | flags, bus);
+ if (nl->fd == -1) {
+ free(nl);
+ return NULL;
+ }
- return nl;
+ return nl;
}
-static struct mnl_socket* mnl_socket_open(int bus) { return __mnl_socket_open(bus, 0); }
-
-static int mnl_socket_bind(struct mnl_socket* nl, unsigned int groups, pid_t pid)
+static struct mnl_socket *mnl_socket_open(int bus)
{
- int ret;
- socklen_t addr_len;
-
- nl->addr.nl_family = AF_NETLINK;
- nl->addr.nl_groups = groups;
- nl->addr.nl_pid = pid;
-
- ret = bind(nl->fd, (struct sockaddr*)&nl->addr, sizeof(nl->addr));
- if (ret < 0)
- return ret;
-
- addr_len = sizeof(nl->addr);
- ret = getsockname(nl->fd, (struct sockaddr*)&nl->addr, &addr_len);
- if (ret < 0)
- return ret;
-
- if (addr_len != sizeof(nl->addr))
- {
- errno = EINVAL;
- return -1;
- }
- if (nl->addr.nl_family != AF_NETLINK)
- {
- errno = EINVAL;
- return -1;
- }
- return 0;
+ return __mnl_socket_open(bus, 0);
}
-static ssize_t mnl_socket_sendto(const struct mnl_socket* nl, const void* buf, size_t len)
+static int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
{
- static const struct sockaddr_nl snl = {.nl_family = AF_NETLINK};
- return sendto(nl->fd, buf, len, 0, (struct sockaddr*)&snl, sizeof(snl));
+ int ret;
+ socklen_t addr_len;
+
+ nl->addr.nl_family = AF_NETLINK;
+ nl->addr.nl_groups = groups;
+ nl->addr.nl_pid = pid;
+
+ ret = bind(nl->fd, (struct sockaddr *) &nl->addr, sizeof (nl->addr));
+ if (ret < 0)
+ return ret;
+
+ addr_len = sizeof(nl->addr);
+ ret = getsockname(nl->fd, (struct sockaddr *) &nl->addr, &addr_len);
+ if (ret < 0)
+ return ret;
+
+ if (addr_len != sizeof(nl->addr)) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (nl->addr.nl_family != AF_NETLINK) {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
}
-static ssize_t mnl_socket_recvfrom(const struct mnl_socket* nl, void* buf, size_t bufsiz)
+static ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *buf,
+ size_t len)
{
- ssize_t ret;
- struct sockaddr_nl addr;
- struct iovec iov = {
- .iov_base = buf,
- .iov_len = bufsiz,
- };
- struct msghdr msg = {
- .msg_name = &addr,
- .msg_namelen = sizeof(struct sockaddr_nl),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = NULL,
- .msg_controllen = 0,
- .msg_flags = 0,
- };
- ret = recvmsg(nl->fd, &msg, 0);
- if (ret == -1)
- return ret;
-
- if (msg.msg_flags & MSG_TRUNC)
- {
- errno = ENOSPC;
- return -1;
- }
- if (msg.msg_namelen != sizeof(struct sockaddr_nl))
- {
- errno = EINVAL;
- return -1;
- }
- return ret;
+ static const struct sockaddr_nl snl = {
+ .nl_family = AF_NETLINK
+ };
+ return sendto(nl->fd, buf, len, 0,
+ (struct sockaddr *) &snl, sizeof(snl));
}
-static int mnl_socket_close(struct mnl_socket* nl)
+static ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf,
+ size_t bufsiz)
{
- int ret = close(nl->fd);
- free(nl);
- return ret;
+ ssize_t ret;
+ struct sockaddr_nl addr;
+ struct iovec iov = {
+ .iov_base = buf,
+ .iov_len = bufsiz,
+ };
+ struct msghdr msg = {
+ .msg_name = &addr,
+ .msg_namelen = sizeof(struct sockaddr_nl),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = NULL,
+ .msg_controllen = 0,
+ .msg_flags = 0,
+ };
+ ret = recvmsg(nl->fd, &msg, 0);
+ if (ret == -1)
+ return ret;
+
+ if (msg.msg_flags & MSG_TRUNC) {
+ errno = ENOSPC;
+ return -1;
+ }
+ if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
+ errno = EINVAL;
+ return -1;
+ }
+ return ret;
+}
+
+static int mnl_socket_close(struct mnl_socket *nl)
+{
+ int ret = close(nl->fd);
+ free(nl);
+ return ret;
}
/* This is a wrapper for generic netlink, originally from Jiri Pirko : */
-struct mnlg_socket
-{
- struct mnl_socket* nl;
- char* buf;
- uint16_t id;
- uint8_t version;
- unsigned int seq;
- unsigned int portid;
+struct mnlg_socket {
+ struct mnl_socket *nl;
+ char *buf;
+ uint16_t id;
+ uint8_t version;
+ unsigned int seq;
+ unsigned int portid;
};
-static struct nlmsghdr* __mnlg_msg_prepare(
- struct mnlg_socket* nlg,
- uint8_t cmd,
- uint16_t flags,
- uint16_t id,
- uint8_t version)
+static struct nlmsghdr *__mnlg_msg_prepare(struct mnlg_socket *nlg, uint8_t cmd,
+ uint16_t flags, uint16_t id,
+ uint8_t version)
{
- struct nlmsghdr* nlh;
- struct genlmsghdr* genl;
+ struct nlmsghdr *nlh;
+ struct genlmsghdr *genl;
- nlh = mnl_nlmsg_put_header(nlg->buf);
- nlh->nlmsg_type = id;
- nlh->nlmsg_flags = flags;
- nlg->seq = time(NULL);
- nlh->nlmsg_seq = nlg->seq;
+ nlh = mnl_nlmsg_put_header(nlg->buf);
+ nlh->nlmsg_type = id;
+ nlh->nlmsg_flags = flags;
+ nlg->seq = time(NULL);
+ nlh->nlmsg_seq = nlg->seq;
- genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));
- genl->cmd = cmd;
- genl->version = version;
+ genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));
+ genl->cmd = cmd;
+ genl->version = version;
- return nlh;
+ return nlh;
}
-static struct nlmsghdr*
-mnlg_msg_prepare(struct mnlg_socket* nlg, uint8_t cmd, uint16_t flags)
+static struct nlmsghdr *mnlg_msg_prepare(struct mnlg_socket *nlg, uint8_t cmd,
+ uint16_t flags)
{
- return __mnlg_msg_prepare(nlg, cmd, flags, nlg->id, nlg->version);
+ return __mnlg_msg_prepare(nlg, cmd, flags, nlg->id, nlg->version);
}
-static int mnlg_socket_send(struct mnlg_socket* nlg, const struct nlmsghdr* nlh)
+static int mnlg_socket_send(struct mnlg_socket *nlg, const struct nlmsghdr *nlh)
{
- return mnl_socket_sendto(nlg->nl, nlh, nlh->nlmsg_len);
+ return mnl_socket_sendto(nlg->nl, nlh, nlh->nlmsg_len);
}
-static int mnlg_cb_noop(const struct nlmsghdr* nlh, void* data)
+static int mnlg_cb_noop(const struct nlmsghdr *nlh, void *data)
{
- (void)nlh;
- (void)data;
- return MNL_CB_OK;
+ (void)nlh;
+ (void)data;
+ return MNL_CB_OK;
}
-static int mnlg_cb_error(const struct nlmsghdr* nlh, void* data)
+static int mnlg_cb_error(const struct nlmsghdr *nlh, void *data)
{
- const struct nlmsgerr* err = mnl_nlmsg_get_payload(nlh);
- (void)data;
+ const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
+ (void)data;
- if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr)))
- {
- errno = EBADMSG;
- return MNL_CB_ERROR;
- }
- /* Netlink subsystems returns the errno value with different signess */
- if (err->error < 0)
- errno = -err->error;
- else
- errno = err->error;
+ if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr))) {
+ errno = EBADMSG;
+ return MNL_CB_ERROR;
+ }
+ /* Netlink subsystems returns the errno value with different signess */
+ if (err->error < 0)
+ errno = -err->error;
+ else
+ errno = err->error;
- return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
+ return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
}
-static int mnlg_cb_stop(const struct nlmsghdr* nlh, void* data)
+static int mnlg_cb_stop(const struct nlmsghdr *nlh, void *data)
{
- (void)data;
- if (nlh->nlmsg_flags & NLM_F_MULTI && nlh->nlmsg_len == mnl_nlmsg_size(sizeof(int)))
- {
- int error = *(int*)mnl_nlmsg_get_payload(nlh);
- /* Netlink subsystems returns the errno value with different signess */
- if (error < 0)
- errno = -error;
- else
- errno = error;
+ (void)data;
+ if (nlh->nlmsg_flags & NLM_F_MULTI && nlh->nlmsg_len == mnl_nlmsg_size(sizeof(int))) {
+ int error = *(int *)mnl_nlmsg_get_payload(nlh);
+ /* Netlink subsystems returns the errno value with different signess */
+ if (error < 0)
+ errno = -error;
+ else
+ errno = error;
- return error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
- }
- return MNL_CB_STOP;
+ return error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
+ }
+ return MNL_CB_STOP;
}
static const mnl_cb_t mnlg_cb_array[] = {
- [NLMSG_NOOP] = mnlg_cb_noop,
- [NLMSG_ERROR] = mnlg_cb_error,
- [NLMSG_DONE] = mnlg_cb_stop,
- [NLMSG_OVERRUN] = mnlg_cb_noop,
+ [NLMSG_NOOP] = mnlg_cb_noop,
+ [NLMSG_ERROR] = mnlg_cb_error,
+ [NLMSG_DONE] = mnlg_cb_stop,
+ [NLMSG_OVERRUN] = mnlg_cb_noop,
};
-static int mnlg_socket_recv_run(struct mnlg_socket* nlg, mnl_cb_t data_cb, void* data)
+static int mnlg_socket_recv_run(struct mnlg_socket *nlg, mnl_cb_t data_cb, void *data)
{
- int err;
+ int err;
- do
- {
- err = mnl_socket_recvfrom(nlg->nl, nlg->buf, mnl_ideal_socket_buffer_size());
- if (err <= 0)
- break;
- err = mnl_cb_run2(
- nlg->buf,
- err,
- nlg->seq,
- nlg->portid,
- data_cb,
- data,
- mnlg_cb_array,
- MNL_ARRAY_SIZE(mnlg_cb_array));
- } while (err > 0);
+ do {
+ err = mnl_socket_recvfrom(nlg->nl, nlg->buf,
+ mnl_ideal_socket_buffer_size());
+ if (err <= 0)
+ break;
+ err = mnl_cb_run2(nlg->buf, err, nlg->seq, nlg->portid,
+ data_cb, data, mnlg_cb_array, MNL_ARRAY_SIZE(mnlg_cb_array));
+ } while (err > 0);
- return err;
+ return err;
}
-static int get_family_id_attr_cb(const struct nlattr* attr, void* data)
+static int get_family_id_attr_cb(const struct nlattr *attr, void *data)
{
- const struct nlattr** tb = data;
- int type = mnl_attr_get_type(attr);
+ const struct nlattr **tb = data;
+ int type = mnl_attr_get_type(attr);
- if (mnl_attr_type_valid(attr, CTRL_ATTR_MAX) < 0)
- return MNL_CB_ERROR;
+ if (mnl_attr_type_valid(attr, CTRL_ATTR_MAX) < 0)
+ return MNL_CB_ERROR;
- if (type == CTRL_ATTR_FAMILY_ID && mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
- return MNL_CB_ERROR;
- tb[type] = attr;
- return MNL_CB_OK;
+ if (type == CTRL_ATTR_FAMILY_ID &&
+ mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
+ return MNL_CB_ERROR;
+ tb[type] = attr;
+ return MNL_CB_OK;
}
-static int get_family_id_cb(const struct nlmsghdr* nlh, void* data)
+static int get_family_id_cb(const struct nlmsghdr *nlh, void *data)
{
- uint16_t* p_id = data;
- struct nlattr* tb[CTRL_ATTR_MAX + 1] = {0};
+ uint16_t *p_id = data;
+ struct nlattr *tb[CTRL_ATTR_MAX + 1] = { 0 };
- mnl_attr_parse(nlh, sizeof(struct genlmsghdr), get_family_id_attr_cb, tb);
- if (!tb[CTRL_ATTR_FAMILY_ID])
- return MNL_CB_ERROR;
- *p_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
- return MNL_CB_OK;
+ mnl_attr_parse(nlh, sizeof(struct genlmsghdr), get_family_id_attr_cb, tb);
+ if (!tb[CTRL_ATTR_FAMILY_ID])
+ return MNL_CB_ERROR;
+ *p_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
+ return MNL_CB_OK;
}
-static struct mnlg_socket* mnlg_socket_open(const char* family_name, uint8_t version)
+static struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version)
{
- struct mnlg_socket* nlg;
- struct nlmsghdr* nlh;
- int err;
+ struct mnlg_socket *nlg;
+ struct nlmsghdr *nlh;
+ int err;
- nlg = malloc(sizeof(*nlg));
- if (!nlg)
- return NULL;
- nlg->id = 0;
+ nlg = malloc(sizeof(*nlg));
+ if (!nlg)
+ return NULL;
+ nlg->id = 0;
- err = -ENOMEM;
- nlg->buf = malloc(mnl_ideal_socket_buffer_size());
- if (!nlg->buf)
- goto err_buf_alloc;
+ err = -ENOMEM;
+ nlg->buf = malloc(mnl_ideal_socket_buffer_size());
+ if (!nlg->buf)
+ goto err_buf_alloc;
- nlg->nl = mnl_socket_open(NETLINK_GENERIC);
- if (!nlg->nl)
- {
- err = -errno;
- goto err_mnl_socket_open;
- }
+ nlg->nl = mnl_socket_open(NETLINK_GENERIC);
+ if (!nlg->nl) {
+ err = -errno;
+ goto err_mnl_socket_open;
+ }
- if (mnl_socket_bind(nlg->nl, 0, MNL_SOCKET_AUTOPID) < 0)
- {
- err = -errno;
- goto err_mnl_socket_bind;
- }
+ if (mnl_socket_bind(nlg->nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+ err = -errno;
+ goto err_mnl_socket_bind;
+ }
- nlg->portid = mnl_socket_get_portid(nlg->nl);
+ nlg->portid = mnl_socket_get_portid(nlg->nl);
- nlh = __mnlg_msg_prepare(
- nlg, CTRL_CMD_GETFAMILY, NLM_F_REQUEST | NLM_F_ACK, GENL_ID_CTRL, 1);
- mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, family_name);
+ nlh = __mnlg_msg_prepare(nlg, CTRL_CMD_GETFAMILY,
+ NLM_F_REQUEST | NLM_F_ACK, GENL_ID_CTRL, 1);
+ mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, family_name);
- if (mnlg_socket_send(nlg, nlh) < 0)
- {
- err = -errno;
- goto err_mnlg_socket_send;
- }
+ if (mnlg_socket_send(nlg, nlh) < 0) {
+ err = -errno;
+ goto err_mnlg_socket_send;
+ }
- errno = 0;
- if (mnlg_socket_recv_run(nlg, get_family_id_cb, &nlg->id) < 0)
- {
- errno = errno == ENOENT ? EPROTONOSUPPORT : errno;
- err = errno ? -errno : -ENOSYS;
- goto err_mnlg_socket_recv_run;
- }
+ errno = 0;
+ if (mnlg_socket_recv_run(nlg, get_family_id_cb, &nlg->id) < 0) {
+ errno = errno == ENOENT ? EPROTONOSUPPORT : errno;
+ err = errno ? -errno : -ENOSYS;
+ goto err_mnlg_socket_recv_run;
+ }
- nlg->version = version;
- errno = 0;
- return nlg;
+ nlg->version = version;
+ errno = 0;
+ return nlg;
err_mnlg_socket_recv_run:
err_mnlg_socket_send:
err_mnl_socket_bind:
- mnl_socket_close(nlg->nl);
+ mnl_socket_close(nlg->nl);
err_mnl_socket_open:
- free(nlg->buf);
+ free(nlg->buf);
err_buf_alloc:
- free(nlg);
- errno = -err;
- return NULL;
+ free(nlg);
+ errno = -err;
+ return NULL;
}
-static void mnlg_socket_close(struct mnlg_socket* nlg)
+static void mnlg_socket_close(struct mnlg_socket *nlg)
{
- mnl_socket_close(nlg->nl);
- free(nlg->buf);
- free(nlg);
+ mnl_socket_close(nlg->nl);
+ free(nlg->buf);
+ free(nlg);
}
diff --git a/src/uapi/openbsd/net/if_wg.h b/src/uapi/openbsd/net/if_wg.h
index 9bc3b91..8e29da5 100644
--- a/src/uapi/openbsd/net/if_wg.h
+++ b/src/uapi/openbsd/net/if_wg.h
@@ -7,12 +7,13 @@
#ifndef __IF_WG_H__
#define __IF_WG_H__
-#include
#include
+#include
#include
#include
+
/*
* This is the public interface to the WireGuard network interface.
*
@@ -24,56 +25,52 @@
#define SIOCSWG _IOWR('i', 210, struct wg_data_io)
#define SIOCGWG _IOWR('i', 211, struct wg_data_io)
-#define a_ipv4 a_addr.addr_ipv4
-#define a_ipv6 a_addr.addr_ipv6
+#define a_ipv4 a_addr.addr_ipv4
+#define a_ipv6 a_addr.addr_ipv6
-struct wg_aip_io
-{
- sa_family_t a_af;
- int a_cidr;
- union wg_aip_addr
- {
- struct in_addr addr_ipv4;
- struct in6_addr addr_ipv6;
- } a_addr;
+struct wg_aip_io {
+ sa_family_t a_af;
+ int a_cidr;
+ union wg_aip_addr {
+ struct in_addr addr_ipv4;
+ struct in6_addr addr_ipv6;
+ } a_addr;
};
-#define WG_PEER_HAS_PUBLIC (1 << 0)
-#define WG_PEER_HAS_PSK (1 << 1)
-#define WG_PEER_HAS_PKA (1 << 2)
-#define WG_PEER_HAS_ENDPOINT (1 << 3)
-#define WG_PEER_REPLACE_AIPS (1 << 4)
-#define WG_PEER_REMOVE (1 << 5)
-#define WG_PEER_UPDATE (1 << 6)
+#define WG_PEER_HAS_PUBLIC (1 << 0)
+#define WG_PEER_HAS_PSK (1 << 1)
+#define WG_PEER_HAS_PKA (1 << 2)
+#define WG_PEER_HAS_ENDPOINT (1 << 3)
+#define WG_PEER_REPLACE_AIPS (1 << 4)
+#define WG_PEER_REMOVE (1 << 5)
+#define WG_PEER_UPDATE (1 << 6)
-#define p_sa p_endpoint.sa_sa
-#define p_sin p_endpoint.sa_sin
-#define p_sin6 p_endpoint.sa_sin6
+#define p_sa p_endpoint.sa_sa
+#define p_sin p_endpoint.sa_sin
+#define p_sin6 p_endpoint.sa_sin6
-struct wg_peer_io
-{
- int p_flags;
- int p_protocol_version;
- uint8_t p_public[WG_KEY_LEN];
- uint8_t p_psk[WG_KEY_LEN];
- uint16_t p_pka;
- union wg_peer_endpoint
- {
- struct sockaddr sa_sa;
- struct sockaddr_in sa_sin;
- struct sockaddr_in6 sa_sin6;
- } p_endpoint;
- uint64_t p_txbytes;
- uint64_t p_rxbytes;
- struct timespec p_last_handshake; /* nanotime */
- size_t p_aips_count;
- struct wg_aip_io p_aips[];
+struct wg_peer_io {
+ int p_flags;
+ int p_protocol_version;
+ uint8_t p_public[WG_KEY_LEN];
+ uint8_t p_psk[WG_KEY_LEN];
+ uint16_t p_pka;
+ union wg_peer_endpoint {
+ struct sockaddr sa_sa;
+ struct sockaddr_in sa_sin;
+ struct sockaddr_in6 sa_sin6;
+ } p_endpoint;
+ uint64_t p_txbytes;
+ uint64_t p_rxbytes;
+ struct timespec p_last_handshake; /* nanotime */
+ size_t p_aips_count;
+ struct wg_aip_io p_aips[];
};
-#define WG_INTERFACE_HAS_PUBLIC (1 << 0)
-#define WG_INTERFACE_HAS_PRIVATE (1 << 1)
-#define WG_INTERFACE_HAS_PORT (1 << 2)
-#define WG_INTERFACE_HAS_RTABLE (1 << 3)
+#define WG_INTERFACE_HAS_PUBLIC (1 << 0)
+#define WG_INTERFACE_HAS_PRIVATE (1 << 1)
+#define WG_INTERFACE_HAS_PORT (1 << 2)
+#define WG_INTERFACE_HAS_RTABLE (1 << 3)
#define WG_INTERFACE_REPLACE_PEERS (1 << 4)
#define WG_INTERFACE_DEVICE_HAS_JC (1 << 5)
#define WG_INTERFACE_DEVICE_HAS_JMIN (1 << 6)
@@ -94,25 +91,24 @@ struct wg_peer_io
#define WG_INTERFACE_DEVICE_HAS_J3 (1 << 21)
#define WG_INTERFACE_DEVICE_HAS_ITIME (1 << 22)
-struct wg_interface_io
-{
- uint16_t i_flags;
- in_port_t i_port;
- int i_rtable;
- uint8_t i_public[WG_KEY_LEN];
- uint8_t i_private[WG_KEY_LEN];
- size_t i_peers_count;
- struct wg_peer_io i_peers[];
+struct wg_interface_io {
+ uint16_t i_flags;
+ in_port_t i_port;
+ int i_rtable;
+ uint8_t i_public[WG_KEY_LEN];
+ uint8_t i_private[WG_KEY_LEN];
+ size_t i_peers_count;
+ struct wg_peer_io i_peers[];
- uint16_t i_junk_packet_count;
- uint16_t i_junk_packet_min_size;
- uint16_t i_junk_packet_max_size;
- uint16_t i_init_packet_junk_size;
- uint16_t i_response_packet_junk_size;
- uint32_t i_init_packet_magic_header;
- uint32_t i_response_packet_magic_header;
- uint32_t i_underload_packet_magic_header;
- uint32_t i_transport_packet_magic_header;
+ uint16_t i_junk_packet_count;
+ uint16_t i_junk_packet_min_size;
+ uint16_t i_junk_packet_max_size;
+ uint16_t i_init_packet_junk_size;
+ uint16_t i_response_packet_junk_size;
+ uint32_t i_init_packet_magic_header;
+ uint32_t i_response_packet_magic_header;
+ uint32_t i_underload_packet_magic_header;
+ uint32_t i_transport_packet_magic_header;
uint8_t* i_i1;
uint8_t* i_i2;
@@ -125,11 +121,10 @@ struct wg_interface_io
uint32_t i_itime;
};
-struct wg_data_io
-{
- char wgd_name[IFNAMSIZ];
- size_t wgd_size; /* total size of the memory pointed to by wgd_interface */
- struct wg_interface_io* wgd_interface;
+struct wg_data_io {
+ char wgd_name[IFNAMSIZ];
+ size_t wgd_size; /* total size of the memory pointed to by wgd_interface */
+ struct wg_interface_io *wgd_interface;
};
#endif /* __IF_WG_H__ */
diff --git a/src/uapi/windows/wireguard.h b/src/uapi/windows/wireguard.h
index 1b99427..1b41517 100644
--- a/src/uapi/windows/wireguard.h
+++ b/src/uapi/windows/wireguard.h
@@ -6,113 +6,113 @@
#ifndef _WIREGUARD_NT_H
#define _WIREGUARD_NT_H
-#include
-#include
#include
#include
#include
+#include
+#include
#define WG_KEY_LEN 32
typedef struct _WG_IOCTL_ALLOWED_IP
{
- union
- {
- IN_ADDR V4;
- IN6_ADDR V6;
- } Address;
- ADDRESS_FAMILY AddressFamily;
- UCHAR Cidr;
+ union
+ {
+ IN_ADDR V4;
+ IN6_ADDR V6;
+ } Address;
+ ADDRESS_FAMILY AddressFamily;
+ UCHAR Cidr;
} __attribute__((aligned(8))) WG_IOCTL_ALLOWED_IP;
typedef enum
{
- WG_IOCTL_PEER_HAS_PUBLIC_KEY = 1 << 0,
- WG_IOCTL_PEER_HAS_PRESHARED_KEY = 1 << 1,
- WG_IOCTL_PEER_HAS_PERSISTENT_KEEPALIVE = 1 << 2,
- WG_IOCTL_PEER_HAS_ENDPOINT = 1 << 3,
- WG_IOCTL_PEER_HAS_PROTOCOL_VERSION = 1 << 4,
- WG_IOCTL_PEER_REPLACE_ALLOWED_IPS = 1 << 5,
- WG_IOCTL_PEER_REMOVE = 1 << 6,
- WG_IOCTL_PEER_UPDATE = 1 << 7
+ WG_IOCTL_PEER_HAS_PUBLIC_KEY = 1 << 0,
+ WG_IOCTL_PEER_HAS_PRESHARED_KEY = 1 << 1,
+ WG_IOCTL_PEER_HAS_PERSISTENT_KEEPALIVE = 1 << 2,
+ WG_IOCTL_PEER_HAS_ENDPOINT = 1 << 3,
+ WG_IOCTL_PEER_HAS_PROTOCOL_VERSION = 1 << 4,
+ WG_IOCTL_PEER_REPLACE_ALLOWED_IPS = 1 << 5,
+ WG_IOCTL_PEER_REMOVE = 1 << 6,
+ WG_IOCTL_PEER_UPDATE = 1 << 7
} WG_IOCTL_PEER_FLAG;
typedef struct _WG_IOCTL_PEER
{
- WG_IOCTL_PEER_FLAG Flags;
- ULONG ProtocolVersion; /* 0 = latest protocol, 1 = this protocol. */
- UCHAR PublicKey[WG_KEY_LEN];
- UCHAR PresharedKey[WG_KEY_LEN];
- USHORT PersistentKeepalive;
- SOCKADDR_INET Endpoint;
- ULONG64 TxBytes;
- ULONG64 RxBytes;
- ULONG64 LastHandshake;
- ULONG AllowedIPsCount;
+ WG_IOCTL_PEER_FLAG Flags;
+ ULONG ProtocolVersion; /* 0 = latest protocol, 1 = this protocol. */
+ UCHAR PublicKey[WG_KEY_LEN];
+ UCHAR PresharedKey[WG_KEY_LEN];
+ USHORT PersistentKeepalive;
+ SOCKADDR_INET Endpoint;
+ ULONG64 TxBytes;
+ ULONG64 RxBytes;
+ ULONG64 LastHandshake;
+ ULONG AllowedIPsCount;
} __attribute__((aligned(8))) WG_IOCTL_PEER;
typedef enum
{
- WG_IOCTL_INTERFACE_HAS_PUBLIC_KEY = 1 << 0,
- WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY = 1 << 1,
- WG_IOCTL_INTERFACE_HAS_LISTEN_PORT = 1 << 2,
- WG_IOCTL_INTERFACE_REPLACE_PEERS = 1 << 3,
- WG_IOCTL_INTERFACE_PEERS = 1 << 4,
- WG_IOCTL_INTERFACE_JC = 1 << 5,
- WG_IOCTL_INTERFACE_JMIN = 1 << 6,
- WG_IOCTL_INTERFACE_JMAX = 1 << 7,
- WG_IOCTL_INTERFACE_S1 = 1 << 8,
- WG_IOCTL_INTERFACE_S2 = 1 << 9,
- WG_IOCTL_INTERFACE_H1 = 1 << 10,
- WG_IOCTL_INTERFACE_H2 = 1 << 11,
- WG_IOCTL_INTERFACE_H3 = 1 << 12,
- WG_IOCTL_INTERFACE_H4 = 1 << 13,
- WG_IOCTL_INTERFACE_I1 = 1U << 14,
- WG_IOCTL_INTERFACE_I2 = 1U << 15,
- WG_IOCTL_INTERFACE_I3 = 1U << 16,
- WG_IOCTL_INTERFACE_I4 = 1U << 17,
- WG_IOCTL_INTERFACE_I5 = 1U << 18,
- WG_IOCTL_INTERFACE_J1 = 1U << 19,
- WG_IOCTL_INTERFACE_J2 = 1U << 20,
- WG_IOCTL_INTERFACE_J3 = 1U << 21,
- WG_IOCTL_INTERFACE_ITIME = 1U << 22
+ WG_IOCTL_INTERFACE_HAS_PUBLIC_KEY = 1 << 0,
+ WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY = 1 << 1,
+ WG_IOCTL_INTERFACE_HAS_LISTEN_PORT = 1 << 2,
+ WG_IOCTL_INTERFACE_REPLACE_PEERS = 1 << 3,
+ WG_IOCTL_INTERFACE_PEERS = 1 << 4,
+ WG_IOCTL_INTERFACE_JC = 1 << 5,
+ WG_IOCTL_INTERFACE_JMIN = 1 << 6,
+ WG_IOCTL_INTERFACE_JMAX = 1 << 7,
+ WG_IOCTL_INTERFACE_S1 = 1 << 8,
+ WG_IOCTL_INTERFACE_S2 = 1 << 9,
+ WG_IOCTL_INTERFACE_H1 = 1 << 10,
+ WG_IOCTL_INTERFACE_H2 = 1 << 11,
+ WG_IOCTL_INTERFACE_H3 = 1 << 12,
+ WG_IOCTL_INTERFACE_H4 = 1 << 13,
+ WG_IOCTL_INTERFACE_I1 = 1U << 14,
+ WG_IOCTL_INTERFACE_I2 = 1U << 15,
+ WG_IOCTL_INTERFACE_I3 = 1U << 16,
+ WG_IOCTL_INTERFACE_I4 = 1U << 17,
+ WG_IOCTL_INTERFACE_I5 = 1U << 18,
+ WG_IOCTL_INTERFACE_J1 = 1U << 19,
+ WG_IOCTL_INTERFACE_J2 = 1U << 20,
+ WG_IOCTL_INTERFACE_J3 = 1U << 21,
+ WG_IOCTL_INTERFACE_ITIME = 1U << 22
} WG_IOCTL_INTERFACE_FLAG;
typedef struct _WG_IOCTL_INTERFACE
{
- WG_IOCTL_INTERFACE_FLAG Flags;
- USHORT ListenPort;
- UCHAR PrivateKey[WG_KEY_LEN];
- UCHAR PublicKey[WG_KEY_LEN];
- ULONG PeersCount;
- USHORT JunkPacketCount;
- USHORT JunkPacketMinSize;
- USHORT JunkPacketMaxSize;
- USHORT InitPacketJunkSize;
- USHORT ResponsePacketJunkSize;
- ULONG InitPacketMagicHeader;
- ULONG ResponsePacketMagicHeader;
- ULONG UnderloadPacketMagicHeader;
- ULONG TransportPacketMagicHeader;
- UCHAR* I1;
- UCHAR* I2;
- UCHAR* I3;
- UCHAR* I4;
- UCHAR* I5;
- UCHAR* J1;
- UCHAR* J2;
- UCHAR* J3;
- ULONG Itime;
+ WG_IOCTL_INTERFACE_FLAG Flags;
+ USHORT ListenPort;
+ UCHAR PrivateKey[WG_KEY_LEN];
+ UCHAR PublicKey[WG_KEY_LEN];
+ ULONG PeersCount;
+ USHORT JunkPacketCount;
+ USHORT JunkPacketMinSize;
+ USHORT JunkPacketMaxSize;
+ USHORT InitPacketJunkSize;
+ USHORT ResponsePacketJunkSize;
+ ULONG InitPacketMagicHeader;
+ ULONG ResponsePacketMagicHeader;
+ ULONG UnderloadPacketMagicHeader;
+ ULONG TransportPacketMagicHeader;
+
+ UCHAR* I1;
+ UCHAR* I2;
+ UCHAR* I3;
+ UCHAR* I4;
+ UCHAR* I5;
+ UCHAR* J1;
+ UCHAR* J2;
+ UCHAR* J3;
+ ULONG Itime;
} __attribute__((aligned(8))) WG_IOCTL_INTERFACE;
-#define WG_IOCTL_GET \
- CTL_CODE(45208U, 321, METHOD_OUT_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
-#define WG_IOCTL_SET \
- CTL_CODE(45208U, 322, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
+#define WG_IOCTL_GET CTL_CODE(45208U, 321, METHOD_OUT_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
+#define WG_IOCTL_SET CTL_CODE(45208U, 322, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
+
+#define DEVPKEY_WG_NAME (DEVPROPKEY) { \
+ { 0x65726957, 0x7547, 0x7261, { 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x4b, 0x65, 0x79 } }, \
+ DEVPROPID_FIRST_USABLE + 1 \
+ }
-#define DEVPKEY_WG_NAME \
- (DEVPROPKEY){ \
- {0x65726957, 0x7547, 0x7261, {0x64, 0x4e, 0x61, 0x6d, 0x65, 0x4b, 0x65, 0x79}}, \
- DEVPROPID_FIRST_USABLE + 1}
#endif
diff --git a/src/wg.c b/src/wg.c
index 6480970..0431fce 100644
--- a/src/wg.c
+++ b/src/wg.c
@@ -42,7 +42,7 @@ int main(int argc, const char *argv[])
PROG_NAME = argv[0];
if (argc == 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version") || !strcmp(argv[1], "version"))) {
- printf("wireguard-tools v%s - https://git.zx2c4.com/wireguard-tools/\n", WIREGUARD_TOOLS_VERSION);
+ printf("amneziawg-tools v%s - https://amnezia.org\n", WIREGUARD_TOOLS_VERSION);
return 0;
}
if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "help"))) {