From a8ca46755f4dbaae07a12281e711a32eaa37ac91 Mon Sep 17 00:00:00 2001
From: Mark Puha
Date: Sun, 10 Aug 2025 11:51:19 +0200
Subject: [PATCH] fix: support linux kernel
---
src/containers.h | 9 ++++++
src/ipc-linux.h | 78 +++++++++++++++++++++++-------------------------
src/ipc-uapi.h | 19 +++++++++---
3 files changed, 62 insertions(+), 44 deletions(-)
diff --git a/src/containers.h b/src/containers.h
index ec5c2e2..129e378 100644
--- a/src/containers.h
+++ b/src/containers.h
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -167,4 +168,12 @@ static inline void free_wgdevice(struct wgdevice *dev)
free(dev);
}
+static inline int contains_hyphen(const char *str)
+{
+ if (strchr(str, '-') != NULL)
+ return 1;
+
+ return 0;
+}
+
#endif
diff --git a/src/ipc-linux.h b/src/ipc-linux.h
index be2855b..9b57057 100644
--- a/src/ipc-linux.h
+++ b/src/ipc-linux.h
@@ -8,6 +8,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -25,6 +26,35 @@
#define IPC_SUPPORTS_KERNEL_INTERFACE
+void put_magic_header_attr(struct nlmsghdr *nlh, int attr_name, char *header_field)
+{
+ if (contains_hyphen(header_field)) {
+ mnl_attr_put_strz(nlh, attr_name, header_field);
+ } else {
+ uint32_t magic_header = strtoul(header_field, NULL, 10);
+ mnl_attr_put_u32(nlh, attr_name, magic_header);
+ }
+}
+
+#define GET_MAGIC_HEADER(attr, magic_header, attr_name)\
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {\
+ magic_header = strdup(mnl_attr_get_str(attr));\
+ if (!magic_header) {\
+ perror("strdup");\
+ return MNL_CB_ERROR;\
+ }\
+ device->flags |= attr_name;\
+ } else if (!mnl_attr_validate(attr, MNL_TYPE_U32)) {\
+ uint32_t numeric_value = mnl_attr_get_u32(attr);\
+ magic_header = malloc(12);\
+ if (!magic_header) {\
+ perror("malloc");\
+ return MNL_CB_ERROR;\
+ }\
+ snprintf(magic_header, 12, "%u", numeric_value);\
+ device->flags |= attr_name;\
+ }
+
#define SOCKET_BUFFER_SIZE (mnl_ideal_socket_buffer_size())
struct interface {
@@ -178,13 +208,13 @@ again:
if (dev->flags & WGDEVICE_HAS_S4)
mnl_attr_put_u16(nlh, WGDEVICE_A_S4, dev->transport_packet_junk_size);
if (dev->flags & WGDEVICE_HAS_H1)
- mnl_attr_put_strz(nlh, WGDEVICE_A_H1, dev->init_packet_magic_header);
+ put_magic_header_attr(nlh, WGDEVICE_A_H1, dev->init_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H2)
- mnl_attr_put_strz(nlh, WGDEVICE_A_H2, dev->response_packet_magic_header);
+ put_magic_header_attr(nlh, WGDEVICE_A_H2, dev->response_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H3)
- mnl_attr_put_strz(nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header);
+ put_magic_header_attr(nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H4)
- mnl_attr_put_strz(nlh, WGDEVICE_A_H4, dev->transport_packet_magic_header);
+ put_magic_header_attr(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)
@@ -548,48 +578,16 @@ static int parse_device(const struct nlattr *attr, void *data)
}
break;
case WGDEVICE_A_H1:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
- device->init_packet_magic_header = strdup(mnl_attr_get_str(attr));
- if (!device->init_packet_magic_header) {
- perror("strdup");
- return MNL_CB_ERROR;
- }
-
- device->flags |= WGDEVICE_HAS_H1;
- }
+ GET_MAGIC_HEADER(attr, device->init_packet_magic_header, WGDEVICE_HAS_H1);
break;
case WGDEVICE_A_H2:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
- device->response_packet_magic_header = strdup(mnl_attr_get_str(attr));
- if (!device->response_packet_magic_header) {
- perror("strdup");
- return MNL_CB_ERROR;
- }
-
- device->flags |= WGDEVICE_HAS_H2;
- }
+ GET_MAGIC_HEADER(attr, device->response_packet_magic_header, WGDEVICE_HAS_H2);
break;
case WGDEVICE_A_H3:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
- device->underload_packet_magic_header = strdup(mnl_attr_get_str(attr));
- if (!device->underload_packet_magic_header) {
- perror("strdup");
- return MNL_CB_ERROR;
- }
-
- device->flags |= WGDEVICE_HAS_H3;
- }
+ GET_MAGIC_HEADER(attr, device->underload_packet_magic_header, WGDEVICE_HAS_H3);
break;
case WGDEVICE_A_H4:
- if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
- device->transport_packet_magic_header = strdup(mnl_attr_get_str(attr));
- if (!device->transport_packet_magic_header) {
- perror("strdup");
- return MNL_CB_ERROR;
- }
-
- device->flags |= WGDEVICE_HAS_H4;
- }
+ GET_MAGIC_HEADER(attr, device->transport_packet_magic_header, WGDEVICE_HAS_H4);
break;
case WGDEVICE_A_I1:
if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
diff --git a/src/ipc-uapi.h b/src/ipc-uapi.h
index fb44f10..45ca24a 100644
--- a/src/ipc-uapi.h
+++ b/src/ipc-uapi.h
@@ -25,6 +25,17 @@
#include "ipc-uapi-unix.h"
#endif
+
+static void set_magic_header(FILE *f, const char* prefix, const char *header_field)
+{
+ if (contains_hyphen(header_field))
+ fprintf(f, "%s=%s\n", prefix, header_field);
+ else {
+ uint32_t magic_header = strtoul(header_field, NULL, 10);
+ fprintf(f, "%s=%u\n", prefix, magic_header);
+ }
+}
+
static int userspace_set_device(struct wgdevice *dev)
{
char hex[WG_KEY_LEN_HEX], ip[INET6_ADDRSTRLEN], host[4096 + 1], service[512 + 1];
@@ -66,13 +77,13 @@ static int userspace_set_device(struct wgdevice *dev)
if (dev->flags & WGDEVICE_HAS_S4)
fprintf(f, "s4=%u\n", dev->transport_packet_junk_size);
if (dev->flags & WGDEVICE_HAS_H1)
- fprintf(f, "h1=%s\n", dev->init_packet_magic_header);
+ set_magic_header(f, "h1", dev->init_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H2)
- fprintf(f, "h2=%s\n", dev->response_packet_magic_header);
+ set_magic_header(f, "h2", dev->response_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H3)
- fprintf(f, "h3=%s\n", dev->underload_packet_magic_header);
+ set_magic_header(f, "h3", dev->underload_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H4)
- fprintf(f, "h4=%s\n", dev->transport_packet_magic_header);
+ set_magic_header(f, "h4", dev->transport_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_I1)
fprintf(f, "i1=%s\n", dev->i1);