mirror of
https://github.com/amnezia-vpn/amneziawg-tools.git
synced 2025-08-02 01:22:51 +02:00
fix: formatting
This commit is contained in:
parent
5d3c2a6096
commit
66de01f211
10 changed files with 3170 additions and 3696 deletions
220
src/containers.h
220
src/containers.h
|
@ -6,13 +6,13 @@
|
||||||
#ifndef CONTAINERS_H
|
#ifndef CONTAINERS_H
|
||||||
#define CONTAINERS_H
|
#define CONTAINERS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <time.h>
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#include <linux/wireguard.h>
|
#include <linux/wireguard.h>
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__)
|
||||||
|
@ -28,143 +28,127 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Cross platform __kernel_timespec */
|
/* Cross platform __kernel_timespec */
|
||||||
struct timespec64
|
struct timespec64 {
|
||||||
{
|
int64_t tv_sec;
|
||||||
int64_t tv_sec;
|
int64_t tv_nsec;
|
||||||
int64_t tv_nsec;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wgallowedip
|
struct wgallowedip {
|
||||||
{
|
uint16_t family;
|
||||||
uint16_t family;
|
union {
|
||||||
union
|
struct in_addr ip4;
|
||||||
{
|
struct in6_addr ip6;
|
||||||
struct in_addr ip4;
|
};
|
||||||
struct in6_addr ip6;
|
uint8_t cidr;
|
||||||
};
|
struct wgallowedip *next_allowedip;
|
||||||
uint8_t cidr;
|
|
||||||
struct wgallowedip* next_allowedip;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
WGPEER_REMOVE_ME = 1U << 0,
|
||||||
WGPEER_REMOVE_ME = 1U << 0,
|
WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
|
||||||
WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
|
WGPEER_HAS_PUBLIC_KEY = 1U << 2,
|
||||||
WGPEER_HAS_PUBLIC_KEY = 1U << 2,
|
WGPEER_HAS_PRESHARED_KEY = 1U << 3,
|
||||||
WGPEER_HAS_PRESHARED_KEY = 1U << 3,
|
WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4,
|
||||||
WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4,
|
WGPEER_HAS_ADVANCED_SECURITY = 1U << 5,
|
||||||
WGPEER_HAS_ADVANCED_SECURITY = 1U << 5,
|
WGPEER_HAS_SPECIAL_HANDSHAKE = 1U << 6
|
||||||
WGPEER_HAS_SPECIAL_HANDSHAKE = 1U << 6
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wgpeer
|
struct wgpeer {
|
||||||
{
|
uint32_t flags;
|
||||||
uint32_t flags;
|
|
||||||
|
|
||||||
uint8_t public_key[WG_KEY_LEN];
|
uint8_t public_key[WG_KEY_LEN];
|
||||||
uint8_t preshared_key[WG_KEY_LEN];
|
uint8_t preshared_key[WG_KEY_LEN];
|
||||||
|
|
||||||
union
|
union {
|
||||||
{
|
struct sockaddr addr;
|
||||||
struct sockaddr addr;
|
struct sockaddr_in addr4;
|
||||||
struct sockaddr_in addr4;
|
struct sockaddr_in6 addr6;
|
||||||
struct sockaddr_in6 addr6;
|
} endpoint;
|
||||||
} endpoint;
|
|
||||||
|
|
||||||
struct timespec64 last_handshake_time;
|
struct timespec64 last_handshake_time;
|
||||||
uint64_t rx_bytes, tx_bytes;
|
uint64_t rx_bytes, tx_bytes;
|
||||||
uint16_t persistent_keepalive_interval;
|
uint16_t persistent_keepalive_interval;
|
||||||
|
|
||||||
bool advanced_security;
|
bool advanced_security;
|
||||||
bool special_handshake;
|
bool special_handshake;
|
||||||
|
|
||||||
struct wgallowedip *first_allowedip, *last_allowedip;
|
struct wgallowedip *first_allowedip, *last_allowedip;
|
||||||
struct wgpeer* next_peer;
|
struct wgpeer *next_peer;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
WGDEVICE_REPLACE_PEERS = 1U << 0,
|
||||||
WGDEVICE_REPLACE_PEERS = 1U << 0,
|
WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
|
||||||
WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
|
WGDEVICE_HAS_PUBLIC_KEY = 1U << 2,
|
||||||
WGDEVICE_HAS_PUBLIC_KEY = 1U << 2,
|
WGDEVICE_HAS_LISTEN_PORT = 1U << 3,
|
||||||
WGDEVICE_HAS_LISTEN_PORT = 1U << 3,
|
WGDEVICE_HAS_FWMARK = 1U << 4,
|
||||||
WGDEVICE_HAS_FWMARK = 1U << 4,
|
WGDEVICE_HAS_JC = 1U << 5,
|
||||||
WGDEVICE_HAS_JC = 1U << 5,
|
WGDEVICE_HAS_JMIN = 1U << 6,
|
||||||
WGDEVICE_HAS_JMIN = 1U << 6,
|
WGDEVICE_HAS_JMAX = 1U << 7,
|
||||||
WGDEVICE_HAS_JMAX = 1U << 7,
|
WGDEVICE_HAS_S1 = 1U << 8,
|
||||||
WGDEVICE_HAS_S1 = 1U << 8,
|
WGDEVICE_HAS_S2 = 1U << 9,
|
||||||
WGDEVICE_HAS_S2 = 1U << 9,
|
WGDEVICE_HAS_H1 = 1U << 10,
|
||||||
WGDEVICE_HAS_H1 = 1U << 10,
|
WGDEVICE_HAS_H2 = 1U << 11,
|
||||||
WGDEVICE_HAS_H2 = 1U << 11,
|
WGDEVICE_HAS_H3 = 1U << 12,
|
||||||
WGDEVICE_HAS_H3 = 1U << 12,
|
WGDEVICE_HAS_H4 = 1U << 13,
|
||||||
WGDEVICE_HAS_H4 = 1U << 13,
|
WGDEVICE_HAS_I1 = 1U << 14,
|
||||||
WGDEVICE_HAS_I1 = 1U << 14,
|
WGDEVICE_HAS_I2 = 1U << 15,
|
||||||
WGDEVICE_HAS_I2 = 1U << 15,
|
WGDEVICE_HAS_I3 = 1U << 16,
|
||||||
WGDEVICE_HAS_I3 = 1U << 16,
|
WGDEVICE_HAS_I4 = 1U << 17,
|
||||||
WGDEVICE_HAS_I4 = 1U << 17,
|
WGDEVICE_HAS_I5 = 1U << 18,
|
||||||
WGDEVICE_HAS_I5 = 1U << 18,
|
WGDEVICE_HAS_J1 = 1U << 19,
|
||||||
WGDEVICE_HAS_J1 = 1U << 19,
|
WGDEVICE_HAS_J2 = 1U << 20,
|
||||||
WGDEVICE_HAS_J2 = 1U << 20,
|
WGDEVICE_HAS_J3 = 1U << 21,
|
||||||
WGDEVICE_HAS_J3 = 1U << 21,
|
WGDEVICE_HAS_ITIME = 1U << 22
|
||||||
WGDEVICE_HAS_ITIME = 1U << 22
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wgdevice
|
struct wgdevice {
|
||||||
{
|
char name[IFNAMSIZ];
|
||||||
char name[IFNAMSIZ];
|
uint32_t ifindex;
|
||||||
uint32_t ifindex;
|
|
||||||
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
uint8_t public_key[WG_KEY_LEN];
|
uint8_t public_key[WG_KEY_LEN];
|
||||||
uint8_t private_key[WG_KEY_LEN];
|
uint8_t private_key[WG_KEY_LEN];
|
||||||
|
|
||||||
uint32_t fwmark;
|
uint32_t fwmark;
|
||||||
uint16_t listen_port;
|
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_count;
|
||||||
uint16_t junk_packet_min_size;
|
uint16_t junk_packet_min_size;
|
||||||
uint16_t junk_packet_max_size;
|
uint16_t junk_packet_max_size;
|
||||||
uint16_t init_packet_junk_size;
|
uint16_t init_packet_junk_size;
|
||||||
uint16_t response_packet_junk_size;
|
uint16_t response_packet_junk_size;
|
||||||
uint32_t init_packet_magic_header;
|
uint32_t init_packet_magic_header;
|
||||||
uint32_t response_packet_magic_header;
|
uint32_t response_packet_magic_header;
|
||||||
uint32_t underload_packet_magic_header;
|
uint32_t underload_packet_magic_header;
|
||||||
uint32_t transport_packet_magic_header;
|
uint32_t transport_packet_magic_header;
|
||||||
char* i1;
|
char* i1;
|
||||||
char* i2;
|
char* i2;
|
||||||
char* i3;
|
char* i3;
|
||||||
char* i4;
|
char* i4;
|
||||||
char* i5;
|
char* i5;
|
||||||
char* j1;
|
char* j1;
|
||||||
char* j2;
|
char* j2;
|
||||||
char* j3;
|
char* j3;
|
||||||
uint32_t itime;
|
uint32_t itime;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define for_each_wgpeer(__dev, __peer) \
|
#define for_each_wgpeer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_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_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)
|
if (!dev)
|
||||||
return;
|
return;
|
||||||
for (struct wgpeer *peer = dev->first_peer, *np = peer ? peer->next_peer : NULL; peer;
|
for (struct wgpeer *peer = dev->first_peer, *np = peer ? peer->next_peer : NULL; peer; peer = np, np = peer ? peer->next_peer : NULL) {
|
||||||
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);
|
||||||
for (struct wgallowedip *allowedip = peer->first_allowedip,
|
free(peer);
|
||||||
*na = allowedip ? allowedip->next_allowedip : NULL;
|
}
|
||||||
allowedip;
|
free(dev);
|
||||||
allowedip = na, na = allowedip ? allowedip->next_allowedip : NULL)
|
|
||||||
free(allowedip);
|
|
||||||
free(peer);
|
|
||||||
}
|
|
||||||
free(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1007
src/ipc-freebsd.h
1007
src/ipc-freebsd.h
File diff suppressed because it is too large
Load diff
1368
src/ipc-linux.h
1368
src/ipc-linux.h
File diff suppressed because it is too large
Load diff
|
@ -3,521 +3,478 @@
|
||||||
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "containers.h"
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_wg.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <time.h>
|
#include <net/if.h>
|
||||||
|
#include <net/if_wg.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include "containers.h"
|
||||||
|
|
||||||
#define IPC_SUPPORTS_KERNEL_INTERFACE
|
#define IPC_SUPPORTS_KERNEL_INTERFACE
|
||||||
|
|
||||||
static int get_dgram_socket(void)
|
static int get_dgram_socket(void)
|
||||||
{
|
{
|
||||||
static int sock = -1;
|
static int sock = -1;
|
||||||
if (sock < 0)
|
if (sock < 0)
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
return sock;
|
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 ifgroupreq ifgr = { .ifgr_name = "wg" };
|
||||||
struct ifg_req* ifg;
|
struct ifg_req *ifg;
|
||||||
int s = get_dgram_socket(), ret = 0;
|
int s = get_dgram_socket(), ret = 0;
|
||||||
|
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
|
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
|
||||||
return errno == ENOENT ? 0 : -errno;
|
return errno == ENOENT ? 0 : -errno;
|
||||||
|
|
||||||
ifgr.ifgr_groups = calloc(1, ifgr.ifgr_len);
|
ifgr.ifgr_groups = calloc(1, ifgr.ifgr_len);
|
||||||
if (!ifgr.ifgr_groups)
|
if (!ifgr.ifgr_groups)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0)
|
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) < 0) {
|
||||||
{
|
ret = -errno;
|
||||||
ret = -errno;
|
goto out;
|
||||||
goto out;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (ifg = ifgr.ifgr_groups; ifg && ifgr.ifgr_len > 0; ++ifg)
|
for (ifg = ifgr.ifgr_groups; ifg && ifgr.ifgr_len > 0; ++ifg) {
|
||||||
{
|
if ((ret = string_list_add(list, ifg->ifgrq_member)) < 0)
|
||||||
if ((ret = string_list_add(list, ifg->ifgrq_member)) < 0)
|
goto out;
|
||||||
goto out;
|
ifgr.ifgr_len -= sizeof(struct ifg_req);
|
||||||
ifgr.ifgr_len -= sizeof(struct ifg_req);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(ifgr.ifgr_groups);
|
free(ifgr.ifgr_groups);
|
||||||
return ret;
|
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_data_io wgdata = { .wgd_size = 0 };
|
||||||
struct wg_interface_io* wg_iface;
|
struct wg_interface_io *wg_iface;
|
||||||
struct wg_peer_io* wg_peer;
|
struct wg_peer_io *wg_peer;
|
||||||
struct wg_aip_io* wg_aip;
|
struct wg_aip_io *wg_aip;
|
||||||
struct wgdevice* dev;
|
struct wgdevice *dev;
|
||||||
struct wgpeer* peer;
|
struct wgpeer *peer;
|
||||||
struct wgallowedip* aip;
|
struct wgallowedip *aip;
|
||||||
int s = get_dgram_socket(), ret;
|
int s = get_dgram_socket(), ret;
|
||||||
|
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
*device = NULL;
|
*device = NULL;
|
||||||
strlcpy(wgdata.wgd_name, iface, sizeof(wgdata.wgd_name));
|
strlcpy(wgdata.wgd_name, iface, sizeof(wgdata.wgd_name));
|
||||||
for (size_t last_size = wgdata.wgd_size;; last_size = wgdata.wgd_size)
|
for (size_t last_size = wgdata.wgd_size;; last_size = wgdata.wgd_size) {
|
||||||
{
|
if (ioctl(s, SIOCGWG, (caddr_t)&wgdata) < 0)
|
||||||
if (ioctl(s, SIOCGWG, (caddr_t)&wgdata) < 0)
|
goto out;
|
||||||
goto out;
|
if (last_size >= wgdata.wgd_size)
|
||||||
if (last_size >= wgdata.wgd_size)
|
break;
|
||||||
break;
|
wgdata.wgd_interface = realloc(wgdata.wgd_interface, wgdata.wgd_size);
|
||||||
wgdata.wgd_interface = realloc(wgdata.wgd_interface, wgdata.wgd_size);
|
if (!wgdata.wgd_interface)
|
||||||
if (!wgdata.wgd_interface)
|
goto out;
|
||||||
goto out;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
wg_iface = wgdata.wgd_interface;
|
wg_iface = wgdata.wgd_interface;
|
||||||
dev = calloc(1, sizeof(*dev));
|
dev = calloc(1, sizeof(*dev));
|
||||||
if (!dev)
|
if (!dev)
|
||||||
goto out;
|
goto out;
|
||||||
strlcpy(dev->name, iface, sizeof(dev->name));
|
strlcpy(dev->name, iface, sizeof(dev->name));
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_HAS_RTABLE)
|
if (wg_iface->i_flags & WG_INTERFACE_HAS_RTABLE) {
|
||||||
{
|
dev->fwmark = wg_iface->i_rtable;
|
||||||
dev->fwmark = wg_iface->i_rtable;
|
dev->flags |= WGDEVICE_HAS_FWMARK;
|
||||||
dev->flags |= WGDEVICE_HAS_FWMARK;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_HAS_PORT)
|
if (wg_iface->i_flags & WG_INTERFACE_HAS_PORT) {
|
||||||
{
|
dev->listen_port = wg_iface->i_port;
|
||||||
dev->listen_port = wg_iface->i_port;
|
dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
|
||||||
dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_HAS_PUBLIC)
|
if (wg_iface->i_flags & WG_INTERFACE_HAS_PUBLIC) {
|
||||||
{
|
memcpy(dev->public_key, wg_iface->i_public, sizeof(dev->public_key));
|
||||||
memcpy(dev->public_key, wg_iface->i_public, sizeof(dev->public_key));
|
dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
|
||||||
dev->flags |= WGDEVICE_HAS_PUBLIC_KEY;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_HAS_PRIVATE)
|
if (wg_iface->i_flags & WG_INTERFACE_HAS_PRIVATE) {
|
||||||
{
|
memcpy(dev->private_key, wg_iface->i_private, sizeof(dev->private_key));
|
||||||
memcpy(dev->private_key, wg_iface->i_private, sizeof(dev->private_key));
|
dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
|
||||||
dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_JC)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_JC) {
|
||||||
{
|
dev->junk_packet_count = wg_iface->i_junk_packet_count;
|
||||||
dev->junk_packet_count = wg_iface->i_junk_packet_count;
|
dev->flags |= WGDEVICE_HAS_JC;
|
||||||
dev->flags |= WGDEVICE_HAS_JC;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_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->junk_packet_min_size = wg_iface->i_junk_packet_min_size;
|
dev->flags |= WGDEVICE_HAS_JMIN;
|
||||||
dev->flags |= WGDEVICE_HAS_JMIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_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->junk_packet_max_size = wg_iface->i_junk_packet_max_size;
|
dev->flags |= WGDEVICE_HAS_JMAX;
|
||||||
dev->flags |= WGDEVICE_HAS_JMAX;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_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->init_packet_junk_size = wg_iface->i_init_packet_junk_size;
|
dev->flags |= WGDEVICE_HAS_S1;
|
||||||
dev->flags |= WGDEVICE_HAS_S1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_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->response_packet_junk_size = wg_iface->i_response_packet_junk_size;
|
dev->flags |= WGDEVICE_HAS_S2;
|
||||||
dev->flags |= WGDEVICE_HAS_S2;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_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->init_packet_magic_header = wg_iface->i_init_packet_magic_header;
|
dev->flags |= WGDEVICE_HAS_H1;
|
||||||
dev->flags |= WGDEVICE_HAS_H1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_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->response_packet_magic_header = wg_iface->i_response_packet_magic_header;
|
dev->flags |= WGDEVICE_HAS_H2;
|
||||||
dev->flags |= WGDEVICE_HAS_H2;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_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->underload_packet_magic_header = wg_iface->i_underload_packet_magic_header;
|
dev->flags |= WGDEVICE_HAS_H3;
|
||||||
dev->flags |= WGDEVICE_HAS_H3;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_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->transport_packet_magic_header = wg_iface->i_transport_packet_magic_header;
|
dev->flags |= WGDEVICE_HAS_H4;
|
||||||
dev->flags |= WGDEVICE_HAS_H4;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I1)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I1)
|
||||||
{
|
{
|
||||||
wg_iface->i_i1 = strdup(dev->i1);
|
wg_iface->i_i1 = strdup(dev->i1);
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_I1;
|
wg_iface->i_flags |= WGDEVICE_HAS_I1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I2)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I2)
|
||||||
{
|
{
|
||||||
wg_iface->i_i2 = strdup(dev->i2);
|
wg_iface->i_i2 = strdup(dev->i2);
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_I2;
|
wg_iface->i_flags |= WGDEVICE_HAS_I2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I3)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I3)
|
||||||
{
|
{
|
||||||
wg_iface->i_i3 = strdup(dev->i3);
|
wg_iface->i_i3 = strdup(dev->i3);
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_I3;
|
wg_iface->i_flags |= WGDEVICE_HAS_I3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I4)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I4)
|
||||||
{
|
{
|
||||||
wg_iface->i_i4 = strdup(dev->i4);
|
wg_iface->i_i4 = strdup(dev->i4);
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_I4;
|
wg_iface->i_flags |= WGDEVICE_HAS_I4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I5)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I5)
|
||||||
{
|
{
|
||||||
wg_iface->i_i5 = strdup(dev->i5);
|
wg_iface->i_i5 = strdup(dev->i5);
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_I5;
|
wg_iface->i_flags |= WGDEVICE_HAS_I5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J1)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J1)
|
||||||
{
|
{
|
||||||
wg_iface->i_j1 = strdup(dev->j1);
|
wg_iface->i_j1 = strdup(dev->j1);
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_J1;
|
wg_iface->i_flags |= WGDEVICE_HAS_J1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J2)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J2)
|
||||||
{
|
{
|
||||||
wg_iface->i_j2 = strdup(dev->j2);
|
wg_iface->i_j2 = strdup(dev->j2);
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_J2;
|
wg_iface->i_flags |= WGDEVICE_HAS_J2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J3)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J3)
|
||||||
{
|
{
|
||||||
wg_iface->i_j3 = strdup(dev->j3);
|
wg_iface->i_j3 = strdup(dev->j3);
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_J3;
|
wg_iface->i_flags |= WGDEVICE_HAS_J3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_ITIME)
|
if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_ITIME)
|
||||||
{
|
{
|
||||||
wg_iface->i_itime = dev->itime;
|
wg_iface->i_itime = dev->itime;
|
||||||
wg_iface->i_flags |= WGDEVICE_HAS_ITIME;
|
wg_iface->i_flags |= WGDEVICE_HAS_ITIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
wg_peer = &wg_iface->i_peers[0];
|
wg_peer = &wg_iface->i_peers[0];
|
||||||
for (size_t i = 0; i < wg_iface->i_peers_count; ++i)
|
for (size_t i = 0; i < wg_iface->i_peers_count; ++i) {
|
||||||
{
|
peer = calloc(1, sizeof(*peer));
|
||||||
peer = calloc(1, sizeof(*peer));
|
if (!peer)
|
||||||
if (!peer)
|
goto out;
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (dev->first_peer == NULL)
|
if (dev->first_peer == NULL)
|
||||||
dev->first_peer = peer;
|
dev->first_peer = peer;
|
||||||
else
|
else
|
||||||
dev->last_peer->next_peer = peer;
|
dev->last_peer->next_peer = peer;
|
||||||
dev->last_peer = peer;
|
dev->last_peer = peer;
|
||||||
|
|
||||||
if (wg_peer->p_flags & WG_PEER_HAS_PUBLIC)
|
if (wg_peer->p_flags & WG_PEER_HAS_PUBLIC) {
|
||||||
{
|
memcpy(peer->public_key, wg_peer->p_public, sizeof(peer->public_key));
|
||||||
memcpy(peer->public_key, wg_peer->p_public, sizeof(peer->public_key));
|
peer->flags |= WGPEER_HAS_PUBLIC_KEY;
|
||||||
peer->flags |= WGPEER_HAS_PUBLIC_KEY;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_peer->p_flags & WG_PEER_HAS_PSK)
|
if (wg_peer->p_flags & WG_PEER_HAS_PSK) {
|
||||||
{
|
memcpy(peer->preshared_key, wg_peer->p_psk, sizeof(peer->preshared_key));
|
||||||
memcpy(peer->preshared_key, wg_peer->p_psk, sizeof(peer->preshared_key));
|
if (!key_is_zero(peer->preshared_key))
|
||||||
if (!key_is_zero(peer->preshared_key))
|
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
||||||
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_peer->p_flags & WG_PEER_HAS_PKA)
|
if (wg_peer->p_flags & WG_PEER_HAS_PKA) {
|
||||||
{
|
peer->persistent_keepalive_interval = wg_peer->p_pka;
|
||||||
peer->persistent_keepalive_interval = wg_peer->p_pka;
|
peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
|
||||||
peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (wg_peer->p_flags & WG_PEER_HAS_ENDPOINT &&
|
if (wg_peer->p_flags & WG_PEER_HAS_ENDPOINT && wg_peer->p_sa.sa_len <= sizeof(peer->endpoint.addr))
|
||||||
wg_peer->p_sa.sa_len <= sizeof(peer->endpoint.addr))
|
memcpy(&peer->endpoint.addr, &wg_peer->p_sa, wg_peer->p_sa.sa_len);
|
||||||
memcpy(&peer->endpoint.addr, &wg_peer->p_sa, wg_peer->p_sa.sa_len);
|
|
||||||
|
|
||||||
peer->rx_bytes = wg_peer->p_rxbytes;
|
peer->rx_bytes = wg_peer->p_rxbytes;
|
||||||
peer->tx_bytes = wg_peer->p_txbytes;
|
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_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_nsec = wg_peer->p_last_handshake.tv_nsec;
|
||||||
|
|
||||||
wg_aip = &wg_peer->p_aips[0];
|
wg_aip = &wg_peer->p_aips[0];
|
||||||
for (size_t j = 0; j < wg_peer->p_aips_count; ++j)
|
for (size_t j = 0; j < wg_peer->p_aips_count; ++j) {
|
||||||
{
|
aip = calloc(1, sizeof(*aip));
|
||||||
aip = calloc(1, sizeof(*aip));
|
if (!aip)
|
||||||
if (!aip)
|
goto out;
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (peer->first_allowedip == NULL)
|
if (peer->first_allowedip == NULL)
|
||||||
peer->first_allowedip = aip;
|
peer->first_allowedip = aip;
|
||||||
else
|
else
|
||||||
peer->last_allowedip->next_allowedip = aip;
|
peer->last_allowedip->next_allowedip = aip;
|
||||||
peer->last_allowedip = aip;
|
peer->last_allowedip = aip;
|
||||||
|
|
||||||
aip->family = wg_aip->a_af;
|
aip->family = wg_aip->a_af;
|
||||||
if (wg_aip->a_af == AF_INET)
|
if (wg_aip->a_af == AF_INET) {
|
||||||
{
|
memcpy(&aip->ip4, &wg_aip->a_ipv4, sizeof(aip->ip4));
|
||||||
memcpy(&aip->ip4, &wg_aip->a_ipv4, sizeof(aip->ip4));
|
aip->cidr = wg_aip->a_cidr;
|
||||||
aip->cidr = wg_aip->a_cidr;
|
} else if (wg_aip->a_af == AF_INET6) {
|
||||||
}
|
memcpy(&aip->ip6, &wg_aip->a_ipv6, sizeof(aip->ip6));
|
||||||
else if (wg_aip->a_af == AF_INET6)
|
aip->cidr = wg_aip->a_cidr;
|
||||||
{
|
}
|
||||||
memcpy(&aip->ip6, &wg_aip->a_ipv6, sizeof(aip->ip6));
|
++wg_aip;
|
||||||
aip->cidr = wg_aip->a_cidr;
|
}
|
||||||
}
|
wg_peer = (struct wg_peer_io *)wg_aip;
|
||||||
++wg_aip;
|
}
|
||||||
}
|
*device = dev;
|
||||||
wg_peer = (struct wg_peer_io*)wg_aip;
|
errno = 0;
|
||||||
}
|
|
||||||
*device = dev;
|
|
||||||
errno = 0;
|
|
||||||
out:
|
out:
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
free(wgdata.wgd_interface);
|
free(wgdata.wgd_interface);
|
||||||
return ret;
|
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_data_io wgdata = { .wgd_size = sizeof(struct wg_interface_io) };
|
||||||
struct wg_interface_io* wg_iface;
|
struct wg_interface_io *wg_iface;
|
||||||
struct wg_peer_io* wg_peer;
|
struct wg_peer_io *wg_peer;
|
||||||
struct wg_aip_io* wg_aip;
|
struct wg_aip_io *wg_aip;
|
||||||
struct wgpeer* peer;
|
struct wgpeer *peer;
|
||||||
struct wgallowedip* aip;
|
struct wgallowedip *aip;
|
||||||
int s = get_dgram_socket(), ret;
|
int s = get_dgram_socket(), ret;
|
||||||
size_t peer_count, aip_count;
|
size_t peer_count, aip_count;
|
||||||
|
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
for_each_wgpeer(dev, peer)
|
for_each_wgpeer(dev, peer) {
|
||||||
{
|
wgdata.wgd_size += sizeof(struct wg_peer_io);
|
||||||
wgdata.wgd_size += sizeof(struct wg_peer_io);
|
for_each_wgallowedip(peer, aip)
|
||||||
for_each_wgallowedip(peer, aip) wgdata.wgd_size += sizeof(struct wg_aip_io);
|
wgdata.wgd_size += sizeof(struct wg_aip_io);
|
||||||
}
|
}
|
||||||
wg_iface = wgdata.wgd_interface = calloc(1, wgdata.wgd_size);
|
wg_iface = wgdata.wgd_interface = calloc(1, wgdata.wgd_size);
|
||||||
if (!wgdata.wgd_interface)
|
if (!wgdata.wgd_interface)
|
||||||
return -errno;
|
return -errno;
|
||||||
strlcpy(wgdata.wgd_name, dev->name, sizeof(wgdata.wgd_name));
|
strlcpy(wgdata.wgd_name, dev->name, sizeof(wgdata.wgd_name));
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
|
if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
|
||||||
{
|
memcpy(wg_iface->i_private, dev->private_key, sizeof(wg_iface->i_private));
|
||||||
memcpy(wg_iface->i_private, dev->private_key, sizeof(wg_iface->i_private));
|
wg_iface->i_flags |= WG_INTERFACE_HAS_PRIVATE;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_HAS_PRIVATE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
|
if (dev->flags & WGDEVICE_HAS_LISTEN_PORT) {
|
||||||
{
|
wg_iface->i_port = dev->listen_port;
|
||||||
wg_iface->i_port = dev->listen_port;
|
wg_iface->i_flags |= WG_INTERFACE_HAS_PORT;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_HAS_PORT;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_FWMARK)
|
if (dev->flags & WGDEVICE_HAS_FWMARK) {
|
||||||
{
|
wg_iface->i_rtable = dev->fwmark;
|
||||||
wg_iface->i_rtable = dev->fwmark;
|
wg_iface->i_flags |= WG_INTERFACE_HAS_RTABLE;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_HAS_RTABLE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_REPLACE_PEERS)
|
if (dev->flags & WGDEVICE_REPLACE_PEERS)
|
||||||
wg_iface->i_flags |= WG_INTERFACE_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)
|
if (dev->flags & WGDEVICE_HAS_JC) {
|
||||||
{
|
wg_iface->i_junk_packet_count = dev->junk_packet_count;
|
||||||
wg_iface->i_junk_packet_min_size = dev->junk_packet_min_size;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JC;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JMIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_JMAX)
|
if (dev->flags & WGDEVICE_HAS_JMIN) {
|
||||||
{
|
wg_iface->i_junk_packet_min_size = dev->junk_packet_min_size;
|
||||||
wg_iface->i_junk_packet_max_size = dev->junk_packet_max_size;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JMIN;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JMAX;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_S1)
|
if (dev->flags & WGDEVICE_HAS_JMAX) {
|
||||||
{
|
wg_iface->i_junk_packet_max_size = dev->junk_packet_max_size;
|
||||||
wg_iface->i_init_packet_junk_size = dev->init_packet_junk_size;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_JMAX;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_S2)
|
if (dev->flags & WGDEVICE_HAS_S1) {
|
||||||
{
|
wg_iface->i_init_packet_junk_size = dev->init_packet_junk_size;
|
||||||
wg_iface->i_response_packet_junk_size = dev->response_packet_junk_size;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S1;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S2;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_H1)
|
if (dev->flags & WGDEVICE_HAS_S2) {
|
||||||
{
|
wg_iface->i_response_packet_junk_size = dev->response_packet_junk_size;
|
||||||
wg_iface->i_init_packet_magic_header = dev->init_packet_magic_header;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S2;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_H2)
|
if (dev->flags & WGDEVICE_HAS_H1) {
|
||||||
{
|
wg_iface->i_init_packet_magic_header = dev->init_packet_magic_header;
|
||||||
wg_iface->i_response_packet_magic_header = dev->response_packet_magic_header;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H1;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H2;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_H3)
|
if (dev->flags & WGDEVICE_HAS_H2) {
|
||||||
{
|
wg_iface->i_response_packet_magic_header = dev->response_packet_magic_header;
|
||||||
wg_iface->i_underload_packet_magic_header = dev->underload_packet_magic_header;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H2;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H3;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_H4)
|
if (dev->flags & WGDEVICE_HAS_H3) {
|
||||||
{
|
wg_iface->i_underload_packet_magic_header = dev->underload_packet_magic_header;
|
||||||
wg_iface->i_transport_packet_magic_header = dev->transport_packet_magic_header;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H3;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H4;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_I1)
|
if (dev->flags & WGDEVICE_HAS_H4) {
|
||||||
{
|
wg_iface->i_transport_packet_magic_header = dev->transport_packet_magic_header;
|
||||||
wg_iface->i_i1 = strdup(dev->i1);
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H4;
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_I2)
|
if (dev->flags & WGDEVICE_HAS_I1)
|
||||||
{
|
{
|
||||||
wg_iface->i_i2 = strdup(dev->i2);
|
wg_iface->i_i1 = strdup(dev->i1);
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I2;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_I3)
|
if (dev->flags & WGDEVICE_HAS_I2)
|
||||||
{
|
{
|
||||||
wg_iface->i_i3 = strdup(dev->i3);
|
wg_iface->i_i2 = strdup(dev->i2);
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I3;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_I4)
|
if (dev->flags & WGDEVICE_HAS_I3)
|
||||||
{
|
{
|
||||||
wg_iface->i_i4 = strdup(dev->i4);
|
wg_iface->i_i3 = strdup(dev->i3);
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I4;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_I5)
|
if (dev->flags & WGDEVICE_HAS_I4)
|
||||||
{
|
{
|
||||||
wg_iface->i_i5 = strdup(dev->i5);
|
wg_iface->i_i4 = strdup(dev->i4);
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I5;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_J1)
|
if (dev->flags & WGDEVICE_HAS_I5)
|
||||||
{
|
{
|
||||||
wg_iface->i_j1 = strdup(dev->j1);
|
wg_iface->i_i5 = strdup(dev->i5);
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J1;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_J2)
|
if (dev->flags & WGDEVICE_HAS_J1)
|
||||||
{
|
{
|
||||||
wg_iface->i_j2 = strdup(dev->j2);
|
wg_iface->i_j1 = strdup(dev->j1);
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J2;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_J3)
|
if (dev->flags & WGDEVICE_HAS_J2)
|
||||||
{
|
{
|
||||||
wg_iface->i_j3 = strdup(dev->j3);
|
wg_iface->i_j2 = strdup(dev->j2);
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J3;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_ITIME)
|
if (dev->flags & WGDEVICE_HAS_J3)
|
||||||
{
|
{
|
||||||
wg_iface->i_itime = dev->itime;
|
wg_iface->i_j3 = strdup(dev->j3);
|
||||||
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_ITIME;
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J3;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_count = 0;
|
if (dev->flags & WGDEVICE_HAS_ITIME)
|
||||||
wg_peer = &wg_iface->i_peers[0];
|
{
|
||||||
for_each_wgpeer(dev, peer)
|
wg_iface->i_itime = dev->itime;
|
||||||
{
|
wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_ITIME;
|
||||||
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_PRESHARED_KEY)
|
peer_count = 0;
|
||||||
{
|
wg_peer = &wg_iface->i_peers[0];
|
||||||
memcpy(wg_peer->p_psk, peer->preshared_key, sizeof(wg_peer->p_psk));
|
for_each_wgpeer(dev, peer) {
|
||||||
wg_peer->p_flags |= WG_PEER_HAS_PSK;
|
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)
|
if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
|
||||||
{
|
memcpy(wg_peer->p_psk, peer->preshared_key, sizeof(wg_peer->p_psk));
|
||||||
wg_peer->p_pka = peer->persistent_keepalive_interval;
|
wg_peer->p_flags |= WG_PEER_HAS_PSK;
|
||||||
wg_peer->p_flags |= WG_PEER_HAS_PKA;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((peer->endpoint.addr.sa_family == AF_INET ||
|
if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL) {
|
||||||
peer->endpoint.addr.sa_family == AF_INET6) &&
|
wg_peer->p_pka = peer->persistent_keepalive_interval;
|
||||||
peer->endpoint.addr.sa_len <= sizeof(wg_peer->p_endpoint))
|
wg_peer->p_flags |= WG_PEER_HAS_PKA;
|
||||||
{
|
}
|
||||||
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_REPLACE_ALLOWEDIPS)
|
if ((peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6) &&
|
||||||
wg_peer->p_flags |= WG_PEER_REPLACE_AIPS;
|
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)
|
if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
|
||||||
wg_peer->p_flags |= WG_PEER_REMOVE;
|
wg_peer->p_flags |= WG_PEER_REPLACE_AIPS;
|
||||||
|
|
||||||
aip_count = 0;
|
if (peer->flags & WGPEER_REMOVE_ME)
|
||||||
wg_aip = &wg_peer->p_aips[0];
|
wg_peer->p_flags |= WG_PEER_REMOVE;
|
||||||
for_each_wgallowedip(peer, aip)
|
|
||||||
{
|
|
||||||
wg_aip->a_af = aip->family;
|
|
||||||
wg_aip->a_cidr = aip->cidr;
|
|
||||||
|
|
||||||
if (aip->family == AF_INET)
|
aip_count = 0;
|
||||||
memcpy(&wg_aip->a_ipv4, &aip->ip4, sizeof(wg_aip->a_ipv4));
|
wg_aip = &wg_peer->p_aips[0];
|
||||||
else if (aip->family == AF_INET6)
|
for_each_wgallowedip(peer, aip) {
|
||||||
memcpy(&wg_aip->a_ipv6, &aip->ip6, sizeof(wg_aip->a_ipv6));
|
wg_aip->a_af = aip->family;
|
||||||
else
|
wg_aip->a_cidr = aip->cidr;
|
||||||
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)
|
if (aip->family == AF_INET)
|
||||||
goto out;
|
memcpy(&wg_aip->a_ipv4, &aip->ip4, sizeof(wg_aip->a_ipv4));
|
||||||
errno = 0;
|
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:
|
out:
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
free(wgdata.wgd_interface);
|
free(wgdata.wgd_interface);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
804
src/ipc-uapi.h
804
src/ipc-uapi.h
|
@ -3,10 +3,6 @@
|
||||||
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "containers.h"
|
|
||||||
#include "ctype.h"
|
|
||||||
#include "curve25519.h"
|
|
||||||
#include "encoding.h"
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
@ -18,6 +14,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include "containers.h"
|
||||||
|
#include "curve25519.h"
|
||||||
|
#include "encoding.h"
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "ipc-uapi-windows.h"
|
#include "ipc-uapi-windows.h"
|
||||||
|
@ -25,467 +25,381 @@
|
||||||
#include "ipc-uapi-unix.h"
|
#include "ipc-uapi-unix.h"
|
||||||
#endif
|
#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];
|
char hex[WG_KEY_LEN_HEX], ip[INET6_ADDRSTRLEN], host[4096 + 1], service[512 + 1];
|
||||||
struct wgpeer* peer;
|
struct wgpeer *peer;
|
||||||
struct wgallowedip* allowedip;
|
struct wgallowedip *allowedip;
|
||||||
FILE* f;
|
FILE *f;
|
||||||
int ret, set_errno = -EPROTO;
|
int ret, set_errno = -EPROTO;
|
||||||
socklen_t addr_len;
|
socklen_t addr_len;
|
||||||
size_t line_buffer_len = 0, line_len;
|
size_t line_buffer_len = 0, line_len;
|
||||||
char * key = NULL, *value;
|
char *key = NULL, *value;
|
||||||
|
|
||||||
f = userspace_interface_file(dev->name);
|
f = userspace_interface_file(dev->name);
|
||||||
if (!f)
|
if (!f)
|
||||||
return -errno;
|
return -errno;
|
||||||
fprintf(f, "set=1\n");
|
fprintf(f, "set=1\n");
|
||||||
|
|
||||||
if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
|
if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY) {
|
||||||
{
|
key_to_hex(hex, dev->private_key);
|
||||||
key_to_hex(hex, dev->private_key);
|
fprintf(f, "private_key=%s\n", hex);
|
||||||
fprintf(f, "private_key=%s\n", hex);
|
}
|
||||||
}
|
if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
|
||||||
if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
|
fprintf(f, "listen_port=%u\n", dev->listen_port);
|
||||||
fprintf(f, "listen_port=%u\n", dev->listen_port);
|
if (dev->flags & WGDEVICE_HAS_FWMARK)
|
||||||
if (dev->flags & WGDEVICE_HAS_FWMARK)
|
fprintf(f, "fwmark=%u\n", dev->fwmark);
|
||||||
fprintf(f, "fwmark=%u\n", dev->fwmark);
|
if (dev->flags & WGDEVICE_REPLACE_PEERS)
|
||||||
if (dev->flags & WGDEVICE_REPLACE_PEERS)
|
fprintf(f, "replace_peers=true\n");
|
||||||
fprintf(f, "replace_peers=true\n");
|
if (dev->flags & WGDEVICE_HAS_JC)
|
||||||
if (dev->flags & WGDEVICE_HAS_JC)
|
fprintf(f, "jc=%u\n", dev->junk_packet_count);
|
||||||
fprintf(f, "jc=%u\n", dev->junk_packet_count);
|
if (dev->flags & WGDEVICE_HAS_JMIN)
|
||||||
if (dev->flags & WGDEVICE_HAS_JMIN)
|
fprintf(f, "jmin=%u\n", dev->junk_packet_min_size);
|
||||||
fprintf(f, "jmin=%u\n", dev->junk_packet_min_size);
|
if (dev->flags & WGDEVICE_HAS_JMAX)
|
||||||
if (dev->flags & WGDEVICE_HAS_JMAX)
|
fprintf(f, "jmax=%u\n", dev->junk_packet_max_size);
|
||||||
fprintf(f, "jmax=%u\n", dev->junk_packet_max_size);
|
if (dev->flags & WGDEVICE_HAS_S1)
|
||||||
if (dev->flags & WGDEVICE_HAS_S1)
|
fprintf(f, "s1=%u\n", dev->init_packet_junk_size);
|
||||||
fprintf(f, "s1=%u\n", dev->init_packet_junk_size);
|
if (dev->flags & WGDEVICE_HAS_S2)
|
||||||
if (dev->flags & WGDEVICE_HAS_S2)
|
fprintf(f, "s2=%u\n", dev->response_packet_junk_size);
|
||||||
fprintf(f, "s2=%u\n", dev->response_packet_junk_size);
|
if (dev->flags & WGDEVICE_HAS_H1)
|
||||||
if (dev->flags & WGDEVICE_HAS_H1)
|
fprintf(f, "h1=%u\n", dev->init_packet_magic_header);
|
||||||
fprintf(f, "h1=%u\n", dev->init_packet_magic_header);
|
if (dev->flags & WGDEVICE_HAS_H2)
|
||||||
if (dev->flags & WGDEVICE_HAS_H2)
|
fprintf(f, "h2=%u\n", dev->response_packet_magic_header);
|
||||||
fprintf(f, "h2=%u\n", dev->response_packet_magic_header);
|
if (dev->flags & WGDEVICE_HAS_H3)
|
||||||
if (dev->flags & WGDEVICE_HAS_H3)
|
fprintf(f, "h3=%u\n", dev->underload_packet_magic_header);
|
||||||
fprintf(f, "h3=%u\n", dev->underload_packet_magic_header);
|
if (dev->flags & WGDEVICE_HAS_H4)
|
||||||
if (dev->flags & WGDEVICE_HAS_H4)
|
fprintf(f, "h4=%u\n", dev->transport_packet_magic_header);
|
||||||
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);
|
|
||||||
|
|
||||||
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)
|
for_each_wgpeer(dev, peer) {
|
||||||
{
|
key_to_hex(hex, peer->public_key);
|
||||||
key_to_hex(hex, peer->public_key);
|
fprintf(f, "public_key=%s\n", hex);
|
||||||
fprintf(f, "public_key=%s\n", hex);
|
if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) {
|
||||||
if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY)
|
ret = -EINVAL;
|
||||||
{
|
goto out;
|
||||||
ret = -EINVAL;
|
}
|
||||||
goto out;
|
if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)
|
||||||
}
|
{
|
||||||
if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)
|
ret = -EINVAL;
|
||||||
{
|
goto out;
|
||||||
ret = -EINVAL;
|
}
|
||||||
goto out;
|
if (peer->flags & WGPEER_REMOVE_ME) {
|
||||||
}
|
fprintf(f, "remove=true\n");
|
||||||
if (peer->flags & WGPEER_REMOVE_ME)
|
continue;
|
||||||
{
|
}
|
||||||
fprintf(f, "remove=true\n");
|
if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
|
||||||
continue;
|
key_to_hex(hex, peer->preshared_key);
|
||||||
}
|
fprintf(f, "preshared_key=%s\n", hex);
|
||||||
if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
|
}
|
||||||
{
|
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6) {
|
||||||
key_to_hex(hex, peer->preshared_key);
|
addr_len = 0;
|
||||||
fprintf(f, "preshared_key=%s\n", hex);
|
if (peer->endpoint.addr.sa_family == AF_INET)
|
||||||
}
|
addr_len = sizeof(struct sockaddr_in);
|
||||||
if (peer->endpoint.addr.sa_family == AF_INET ||
|
else if (peer->endpoint.addr.sa_family == AF_INET6)
|
||||||
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)) {
|
||||||
addr_len = 0;
|
if (peer->endpoint.addr.sa_family == AF_INET6 && strchr(host, ':'))
|
||||||
if (peer->endpoint.addr.sa_family == AF_INET)
|
fprintf(f, "endpoint=[%s]:%s\n", host, service);
|
||||||
addr_len = sizeof(struct sockaddr_in);
|
else
|
||||||
else if (peer->endpoint.addr.sa_family == AF_INET6)
|
fprintf(f, "endpoint=%s:%s\n", host, service);
|
||||||
addr_len = sizeof(struct sockaddr_in6);
|
}
|
||||||
if (!getnameinfo(
|
}
|
||||||
&peer->endpoint.addr,
|
if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
|
||||||
addr_len,
|
fprintf(f, "persistent_keepalive_interval=%u\n", peer->persistent_keepalive_interval);
|
||||||
host,
|
if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
|
||||||
sizeof(host),
|
fprintf(f, "replace_allowed_ips=true\n");
|
||||||
service,
|
for_each_wgallowedip(peer, allowedip) {
|
||||||
sizeof(service),
|
if (allowedip->family == AF_INET) {
|
||||||
NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST))
|
if (!inet_ntop(AF_INET, &allowedip->ip4, ip, INET6_ADDRSTRLEN))
|
||||||
{
|
continue;
|
||||||
if (peer->endpoint.addr.sa_family == AF_INET6 && strchr(host, ':'))
|
} else if (allowedip->family == AF_INET6) {
|
||||||
fprintf(f, "endpoint=[%s]:%s\n", host, service);
|
if (!inet_ntop(AF_INET6, &allowedip->ip6, ip, INET6_ADDRSTRLEN))
|
||||||
else
|
continue;
|
||||||
fprintf(f, "endpoint=%s:%s\n", host, service);
|
} else
|
||||||
}
|
continue;
|
||||||
}
|
fprintf(f, "allowed_ip=%s/%d\n", ip, allowedip->cidr);
|
||||||
if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL)
|
}
|
||||||
fprintf(
|
}
|
||||||
f,
|
fprintf(f, "\n");
|
||||||
"persistent_keepalive_interval=%u\n",
|
fflush(f);
|
||||||
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)
|
while (getline(&key, &line_buffer_len, f) > 0) {
|
||||||
{
|
line_len = strlen(key);
|
||||||
line_len = strlen(key);
|
ret = set_errno;
|
||||||
ret = set_errno;
|
if (line_len == 1 && key[0] == '\n')
|
||||||
if (line_len == 1 && key[0] == '\n')
|
goto out;
|
||||||
goto out;
|
value = strchr(key, '=');
|
||||||
value = strchr(key, '=');
|
if (!value || line_len == 0 || key[line_len - 1] != '\n')
|
||||||
if (!value || line_len == 0 || key[line_len - 1] != '\n')
|
break;
|
||||||
break;
|
*value++ = key[--line_len] = '\0';
|
||||||
*value++ = key[--line_len] = '\0';
|
|
||||||
|
|
||||||
if (!strcmp(key, "errno"))
|
if (!strcmp(key, "errno")) {
|
||||||
{
|
long long num;
|
||||||
long long num;
|
char *end;
|
||||||
char* end;
|
if (value[0] != '-' && !char_is_digit(value[0]))
|
||||||
if (value[0] != '-' && !char_is_digit(value[0]))
|
break;
|
||||||
break;
|
num = strtoll(value, &end, 10);
|
||||||
num = strtoll(value, &end, 10);
|
if (*end || num > INT_MAX || num < INT_MIN)
|
||||||
if (*end || num > INT_MAX || num < INT_MIN)
|
break;
|
||||||
break;
|
set_errno = num;
|
||||||
set_errno = num;
|
}
|
||||||
}
|
}
|
||||||
}
|
ret = errno ? -errno : -EPROTO;
|
||||||
ret = errno ? -errno : -EPROTO;
|
|
||||||
out:
|
out:
|
||||||
free(key);
|
free(key);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUM(max) \
|
#define NUM(max) ({ \
|
||||||
({ \
|
unsigned long long num; \
|
||||||
unsigned long long num; \
|
char *end; \
|
||||||
char* end; \
|
if (!char_is_digit(value[0])) \
|
||||||
if (!char_is_digit(value[0])) \
|
break; \
|
||||||
break; \
|
num = strtoull(value, &end, 10); \
|
||||||
num = strtoull(value, &end, 10); \
|
if (*end || num > max) \
|
||||||
if (*end || num > max) \
|
break; \
|
||||||
break; \
|
num; \
|
||||||
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 wgdevice *dev;
|
||||||
struct wgpeer* peer = NULL;
|
struct wgpeer *peer = NULL;
|
||||||
struct wgallowedip* allowedip = NULL;
|
struct wgallowedip *allowedip = NULL;
|
||||||
size_t line_buffer_len = 0, line_len;
|
size_t line_buffer_len = 0, line_len;
|
||||||
char * key = NULL, *value;
|
char *key = NULL, *value;
|
||||||
FILE* f;
|
FILE *f;
|
||||||
int ret = -EPROTO;
|
int ret = -EPROTO;
|
||||||
|
|
||||||
*out = dev = calloc(1, sizeof(*dev));
|
*out = dev = calloc(1, sizeof(*dev));
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
f = userspace_interface_file(iface);
|
f = userspace_interface_file(iface);
|
||||||
if (!f)
|
if (!f) {
|
||||||
{
|
ret = -errno;
|
||||||
ret = -errno;
|
free(dev);
|
||||||
free(dev);
|
*out = NULL;
|
||||||
*out = NULL;
|
return ret;
|
||||||
return ret;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "get=1\n\n");
|
fprintf(f, "get=1\n\n");
|
||||||
fflush(f);
|
fflush(f);
|
||||||
|
|
||||||
strncpy(dev->name, iface, IFNAMSIZ - 1);
|
strncpy(dev->name, iface, IFNAMSIZ - 1);
|
||||||
dev->name[IFNAMSIZ - 1] = '\0';
|
dev->name[IFNAMSIZ - 1] = '\0';
|
||||||
|
|
||||||
while (getline(&key, &line_buffer_len, f) > 0)
|
while (getline(&key, &line_buffer_len, f) > 0) {
|
||||||
{
|
line_len = strlen(key);
|
||||||
line_len = strlen(key);
|
if (line_len == 1 && key[0] == '\n')
|
||||||
if (line_len == 1 && key[0] == '\n')
|
goto err;
|
||||||
goto err;
|
value = strchr(key, '=');
|
||||||
value = strchr(key, '=');
|
if (!value || line_len == 0 || key[line_len - 1] != '\n')
|
||||||
if (!value || line_len == 0 || key[line_len - 1] != '\n')
|
break;
|
||||||
break;
|
*value++ = key[--line_len] = '\0';
|
||||||
*value++ = key[--line_len] = '\0';
|
|
||||||
|
|
||||||
if (!peer && !strcmp(key, "private_key"))
|
if (!peer && !strcmp(key, "private_key")) {
|
||||||
{
|
if (!key_from_hex(dev->private_key, value))
|
||||||
if (!key_from_hex(dev->private_key, value))
|
break;
|
||||||
break;
|
curve25519_generate_public(dev->public_key, dev->private_key);
|
||||||
curve25519_generate_public(dev->public_key, dev->private_key);
|
dev->flags |= WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_PUBLIC_KEY;
|
||||||
dev->flags |= WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_PUBLIC_KEY;
|
} else if (!peer && !strcmp(key, "listen_port")) {
|
||||||
}
|
dev->listen_port = NUM(0xffffU);
|
||||||
else if (!peer && !strcmp(key, "listen_port"))
|
dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
|
||||||
{
|
} else if (!peer && !strcmp(key, "fwmark")) {
|
||||||
dev->listen_port = NUM(0xffffU);
|
dev->fwmark = NUM(0xffffffffU);
|
||||||
dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
|
dev->flags |= WGDEVICE_HAS_FWMARK;
|
||||||
}
|
} else if(!peer && !strcmp(key, "jc")) {
|
||||||
else if (!peer && !strcmp(key, "fwmark"))
|
dev->junk_packet_count = NUM(0xffffU);
|
||||||
{
|
dev->flags |= WGDEVICE_HAS_JC;
|
||||||
dev->fwmark = NUM(0xffffffffU);
|
} else if(!peer && !strcmp(key, "jmin")) {
|
||||||
dev->flags |= WGDEVICE_HAS_FWMARK;
|
dev->junk_packet_min_size = NUM(0xffffU);
|
||||||
}
|
dev->flags |= WGDEVICE_HAS_JMIN;
|
||||||
else if (!peer && !strcmp(key, "jc"))
|
} else if(!peer && !strcmp(key, "jmax")) {
|
||||||
{
|
dev->junk_packet_max_size = NUM(0xffffU);
|
||||||
dev->junk_packet_count = NUM(0xffffU);
|
dev->flags |= WGDEVICE_HAS_JMAX;
|
||||||
dev->flags |= WGDEVICE_HAS_JC;
|
} else if(!peer && !strcmp(key, "s1")) {
|
||||||
}
|
dev->init_packet_junk_size = NUM(0xffffU);
|
||||||
else if (!peer && !strcmp(key, "jmin"))
|
dev->flags |= WGDEVICE_HAS_S1;
|
||||||
{
|
} else if(!peer && !strcmp(key, "s2")) {
|
||||||
dev->junk_packet_min_size = NUM(0xffffU);
|
dev->response_packet_junk_size = NUM(0xffffU);
|
||||||
dev->flags |= WGDEVICE_HAS_JMIN;
|
dev->flags |= WGDEVICE_HAS_S2;
|
||||||
}
|
} else if(!peer && !strcmp(key, "h1")) {
|
||||||
else if (!peer && !strcmp(key, "jmax"))
|
dev->init_packet_magic_header = NUM(0xffffffffU);
|
||||||
{
|
dev->flags |= WGDEVICE_HAS_H1;
|
||||||
dev->junk_packet_max_size = NUM(0xffffU);
|
} else if(!peer && !strcmp(key, "h2")) {
|
||||||
dev->flags |= WGDEVICE_HAS_JMAX;
|
dev->response_packet_magic_header = NUM(0xffffffffU);
|
||||||
}
|
dev->flags |= WGDEVICE_HAS_H2;
|
||||||
else if (!peer && !strcmp(key, "s1"))
|
} else if(!peer && !strcmp(key, "h3")) {
|
||||||
{
|
dev->underload_packet_magic_header = NUM(0xffffffffU);
|
||||||
dev->init_packet_junk_size = NUM(0xffffU);
|
dev->flags |= WGDEVICE_HAS_H3;
|
||||||
dev->flags |= WGDEVICE_HAS_S1;
|
} else if(!peer && !strcmp(key, "h4")) {
|
||||||
}
|
dev->transport_packet_magic_header = NUM(0xffffffffU);
|
||||||
else if (!peer && !strcmp(key, "s2"))
|
dev->flags |= WGDEVICE_HAS_H4;
|
||||||
{
|
} else if (!peer && !strcmp(key, "i1")) {
|
||||||
dev->response_packet_junk_size = NUM(0xffffU);
|
dev->i1 = strdup(value);
|
||||||
dev->flags |= WGDEVICE_HAS_S2;
|
dev->flags |= WGDEVICE_HAS_I1;
|
||||||
}
|
}
|
||||||
else if (!peer && !strcmp(key, "h1"))
|
else if (!peer && !strcmp(key, "i2")) {
|
||||||
{
|
dev->i2 = strdup(value);
|
||||||
dev->init_packet_magic_header = NUM(0xffffffffU);
|
dev->flags |= WGDEVICE_HAS_I2;
|
||||||
dev->flags |= WGDEVICE_HAS_H1;
|
}
|
||||||
}
|
else if (!peer && !strcmp(key, "i3")) {
|
||||||
else if (!peer && !strcmp(key, "h2"))
|
dev->i3 = strdup(value);
|
||||||
{
|
dev->flags |= WGDEVICE_HAS_I3;
|
||||||
dev->response_packet_magic_header = NUM(0xffffffffU);
|
}
|
||||||
dev->flags |= WGDEVICE_HAS_H2;
|
else if (!peer && !strcmp(key, "i4")) {
|
||||||
}
|
dev->i4 = strdup(value);
|
||||||
else if (!peer && !strcmp(key, "h3"))
|
dev->flags |= WGDEVICE_HAS_I4;
|
||||||
{
|
}
|
||||||
dev->underload_packet_magic_header = NUM(0xffffffffU);
|
else if (!peer && !strcmp(key, "i5")) {
|
||||||
dev->flags |= WGDEVICE_HAS_H3;
|
dev->i5 = strdup(value);
|
||||||
}
|
dev->flags |= WGDEVICE_HAS_I5;
|
||||||
else if (!peer && !strcmp(key, "h4"))
|
}
|
||||||
{
|
else if (!peer && !strcmp(key, "j1")) {
|
||||||
dev->transport_packet_magic_header = NUM(0xffffffffU);
|
dev->j1 = strdup(value);
|
||||||
dev->flags |= WGDEVICE_HAS_H4;
|
dev->flags |= WGDEVICE_HAS_J1;
|
||||||
}
|
}
|
||||||
else if (!peer && !strcmp(key, "i1"))
|
else if (!peer && !strcmp(key, "j2")) {
|
||||||
{
|
dev->j2 = strdup(value);
|
||||||
dev->i1 = strdup(value);
|
dev->flags |= WGDEVICE_HAS_J2;
|
||||||
dev->flags |= WGDEVICE_HAS_I1;
|
}
|
||||||
}
|
else if (!peer && !strcmp(key, "j3")) {
|
||||||
else if (!peer && !strcmp(key, "i2"))
|
dev->j3 = strdup(value);
|
||||||
{
|
dev->flags |= WGDEVICE_HAS_J3;
|
||||||
dev->i2 = strdup(value);
|
}
|
||||||
dev->flags |= WGDEVICE_HAS_I2;
|
else if (!peer && !strcmp(key, "itime")) {
|
||||||
}
|
dev->itime = NUM(0xffffffffU);
|
||||||
else if (!peer && !strcmp(key, "i3"))
|
dev->flags |= WGDEVICE_HAS_ITIME;
|
||||||
{
|
} else if (!strcmp(key, "public_key")) {
|
||||||
dev->i3 = strdup(value);
|
struct wgpeer *new_peer = calloc(1, sizeof(*new_peer));
|
||||||
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)
|
if (!new_peer) {
|
||||||
{
|
ret = -ENOMEM;
|
||||||
ret = -ENOMEM;
|
goto err;
|
||||||
goto err;
|
}
|
||||||
}
|
allowedip = NULL;
|
||||||
allowedip = NULL;
|
if (peer)
|
||||||
if (peer)
|
peer->next_peer = new_peer;
|
||||||
peer->next_peer = new_peer;
|
else
|
||||||
else
|
dev->first_peer = new_peer;
|
||||||
dev->first_peer = new_peer;
|
peer = new_peer;
|
||||||
peer = new_peer;
|
if (!key_from_hex(peer->public_key, value))
|
||||||
if (!key_from_hex(peer->public_key, value))
|
break;
|
||||||
break;
|
peer->flags |= WGPEER_HAS_PUBLIC_KEY;
|
||||||
peer->flags |= WGPEER_HAS_PUBLIC_KEY;
|
} else if (peer && !strcmp(key, "preshared_key")) {
|
||||||
}
|
if (!key_from_hex(peer->preshared_key, value))
|
||||||
else if (peer && !strcmp(key, "preshared_key"))
|
break;
|
||||||
{
|
if (!key_is_zero(peer->preshared_key))
|
||||||
if (!key_from_hex(peer->preshared_key, value))
|
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
||||||
break;
|
} else if (peer && !strcmp(key, "endpoint")) {
|
||||||
if (!key_is_zero(peer->preshared_key))
|
char *begin, *end;
|
||||||
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
struct addrinfo *resolved;
|
||||||
}
|
struct addrinfo hints = {
|
||||||
else if (peer && !strcmp(key, "endpoint"))
|
.ai_family = AF_UNSPEC,
|
||||||
{
|
.ai_socktype = SOCK_DGRAM,
|
||||||
char * begin, *end;
|
.ai_protocol = IPPROTO_UDP
|
||||||
struct addrinfo* resolved;
|
};
|
||||||
struct addrinfo hints = {
|
if (!strlen(value))
|
||||||
.ai_family = AF_UNSPEC,
|
break;
|
||||||
.ai_socktype = SOCK_DGRAM,
|
if (value[0] == '[') {
|
||||||
.ai_protocol = IPPROTO_UDP};
|
begin = &value[1];
|
||||||
if (!strlen(value))
|
end = strchr(value, ']');
|
||||||
break;
|
if (!end)
|
||||||
if (value[0] == '[')
|
break;
|
||||||
{
|
*end++ = '\0';
|
||||||
begin = &value[1];
|
if (*end++ != ':' || !*end)
|
||||||
end = strchr(value, ']');
|
break;
|
||||||
if (!end)
|
} else {
|
||||||
break;
|
begin = value;
|
||||||
*end++ = '\0';
|
end = strrchr(value, ':');
|
||||||
if (*end++ != ':' || !*end)
|
if (!end || !*(end + 1))
|
||||||
break;
|
break;
|
||||||
}
|
*end++ = '\0';
|
||||||
else
|
}
|
||||||
{
|
if (getaddrinfo(begin, end, &hints, &resolved) != 0) {
|
||||||
begin = value;
|
ret = ENETUNREACH;
|
||||||
end = strrchr(value, ':');
|
goto err;
|
||||||
if (!end || !*(end + 1))
|
}
|
||||||
break;
|
if ((resolved->ai_family == AF_INET && resolved->ai_addrlen == sizeof(struct sockaddr_in)) ||
|
||||||
*end++ = '\0';
|
(resolved->ai_family == AF_INET6 && resolved->ai_addrlen == sizeof(struct sockaddr_in6)))
|
||||||
}
|
memcpy(&peer->endpoint.addr, resolved->ai_addr, resolved->ai_addrlen);
|
||||||
if (getaddrinfo(begin, end, &hints, &resolved) != 0)
|
else {
|
||||||
{
|
freeaddrinfo(resolved);
|
||||||
ret = ENETUNREACH;
|
break;
|
||||||
goto err;
|
}
|
||||||
}
|
freeaddrinfo(resolved);
|
||||||
if ((resolved->ai_family == AF_INET &&
|
} else if (peer && !strcmp(key, "persistent_keepalive_interval")) {
|
||||||
resolved->ai_addrlen == sizeof(struct sockaddr_in)) ||
|
peer->persistent_keepalive_interval = NUM(0xffffU);
|
||||||
(resolved->ai_family == AF_INET6 &&
|
peer->flags |= WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL;
|
||||||
resolved->ai_addrlen == sizeof(struct sockaddr_in6)))
|
} else if (peer && !strcmp(key, "allowed_ip")) {
|
||||||
memcpy(&peer->endpoint.addr, resolved->ai_addr, resolved->ai_addrlen);
|
struct wgallowedip *new_allowedip;
|
||||||
else
|
char *end, *mask = value, *ip = strsep(&mask, "/");
|
||||||
{
|
|
||||||
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]))
|
if (!mask || !char_is_digit(mask[0]))
|
||||||
break;
|
break;
|
||||||
new_allowedip = calloc(1, sizeof(*new_allowedip));
|
new_allowedip = calloc(1, sizeof(*new_allowedip));
|
||||||
if (!new_allowedip)
|
if (!new_allowedip) {
|
||||||
{
|
ret = -ENOMEM;
|
||||||
ret = -ENOMEM;
|
goto err;
|
||||||
goto err;
|
}
|
||||||
}
|
if (allowedip)
|
||||||
if (allowedip)
|
allowedip->next_allowedip = new_allowedip;
|
||||||
allowedip->next_allowedip = new_allowedip;
|
else
|
||||||
else
|
peer->first_allowedip = new_allowedip;
|
||||||
peer->first_allowedip = new_allowedip;
|
allowedip = new_allowedip;
|
||||||
allowedip = new_allowedip;
|
allowedip->family = AF_UNSPEC;
|
||||||
allowedip->family = AF_UNSPEC;
|
if (strchr(ip, ':')) {
|
||||||
if (strchr(ip, ':'))
|
if (inet_pton(AF_INET6, ip, &allowedip->ip6) == 1)
|
||||||
{
|
allowedip->family = AF_INET6;
|
||||||
if (inet_pton(AF_INET6, ip, &allowedip->ip6) == 1)
|
} else {
|
||||||
allowedip->family = AF_INET6;
|
if (inet_pton(AF_INET, ip, &allowedip->ip4) == 1)
|
||||||
}
|
allowedip->family = AF_INET;
|
||||||
else
|
}
|
||||||
{
|
allowedip->cidr = strtoul(mask, &end, 10);
|
||||||
if (inet_pton(AF_INET, ip, &allowedip->ip4) == 1)
|
if (*end || allowedip->family == AF_UNSPEC || (allowedip->family == AF_INET6 && allowedip->cidr > 128) || (allowedip->family == AF_INET && allowedip->cidr > 32))
|
||||||
allowedip->family = AF_INET;
|
break;
|
||||||
}
|
} else if (peer && !strcmp(key, "last_handshake_time_sec"))
|
||||||
allowedip->cidr = strtoul(mask, &end, 10);
|
peer->last_handshake_time.tv_sec = NUM(0x7fffffffffffffffULL);
|
||||||
if (*end || allowedip->family == AF_UNSPEC ||
|
else if (peer && !strcmp(key, "last_handshake_time_nsec"))
|
||||||
(allowedip->family == AF_INET6 && allowedip->cidr > 128) ||
|
peer->last_handshake_time.tv_nsec = NUM(0x7fffffffffffffffULL);
|
||||||
(allowedip->family == AF_INET && allowedip->cidr > 32))
|
else if (peer && !strcmp(key, "rx_bytes"))
|
||||||
break;
|
peer->rx_bytes = NUM(0xffffffffffffffffULL);
|
||||||
}
|
else if (peer && !strcmp(key, "tx_bytes"))
|
||||||
else if (peer && !strcmp(key, "last_handshake_time_sec"))
|
peer->tx_bytes = NUM(0xffffffffffffffffULL);
|
||||||
peer->last_handshake_time.tv_sec = NUM(0x7fffffffffffffffULL);
|
else if (!strcmp(key, "errno"))
|
||||||
else if (peer && !strcmp(key, "last_handshake_time_nsec"))
|
ret = -NUM(0x7fffffffU);
|
||||||
peer->last_handshake_time.tv_nsec = NUM(0x7fffffffffffffffULL);
|
}
|
||||||
else if (peer && !strcmp(key, "rx_bytes"))
|
ret = -EPROTO;
|
||||||
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:
|
err:
|
||||||
free(key);
|
free(key);
|
||||||
if (ret)
|
if (ret) {
|
||||||
{
|
free_wgdevice(dev);
|
||||||
free_wgdevice(dev);
|
*out = NULL;
|
||||||
*out = NULL;
|
}
|
||||||
}
|
fclose(f);
|
||||||
fclose(f);
|
errno = -ret;
|
||||||
errno = -ret;
|
return ret;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#undef NUM
|
#undef NUM
|
||||||
|
|
1264
src/ipc-windows.h
1264
src/ipc-windows.h
File diff suppressed because it is too large
Load diff
1119
src/netlink.h
1119
src/netlink.h
File diff suppressed because it is too large
Load diff
|
@ -7,12 +7,13 @@
|
||||||
#ifndef __IF_WG_H__
|
#ifndef __IF_WG_H__
|
||||||
#define __IF_WG_H__
|
#define __IF_WG_H__
|
||||||
|
|
||||||
#include <sys/errno.h>
|
|
||||||
#include <sys/limits.h>
|
#include <sys/limits.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the public interface to the WireGuard network interface.
|
* This is the public interface to the WireGuard network interface.
|
||||||
*
|
*
|
||||||
|
@ -24,56 +25,52 @@
|
||||||
#define SIOCSWG _IOWR('i', 210, struct wg_data_io)
|
#define SIOCSWG _IOWR('i', 210, struct wg_data_io)
|
||||||
#define SIOCGWG _IOWR('i', 211, struct wg_data_io)
|
#define SIOCGWG _IOWR('i', 211, struct wg_data_io)
|
||||||
|
|
||||||
#define a_ipv4 a_addr.addr_ipv4
|
#define a_ipv4 a_addr.addr_ipv4
|
||||||
#define a_ipv6 a_addr.addr_ipv6
|
#define a_ipv6 a_addr.addr_ipv6
|
||||||
|
|
||||||
struct wg_aip_io
|
struct wg_aip_io {
|
||||||
{
|
sa_family_t a_af;
|
||||||
sa_family_t a_af;
|
int a_cidr;
|
||||||
int a_cidr;
|
union wg_aip_addr {
|
||||||
union wg_aip_addr
|
struct in_addr addr_ipv4;
|
||||||
{
|
struct in6_addr addr_ipv6;
|
||||||
struct in_addr addr_ipv4;
|
} a_addr;
|
||||||
struct in6_addr addr_ipv6;
|
|
||||||
} a_addr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WG_PEER_HAS_PUBLIC (1 << 0)
|
#define WG_PEER_HAS_PUBLIC (1 << 0)
|
||||||
#define WG_PEER_HAS_PSK (1 << 1)
|
#define WG_PEER_HAS_PSK (1 << 1)
|
||||||
#define WG_PEER_HAS_PKA (1 << 2)
|
#define WG_PEER_HAS_PKA (1 << 2)
|
||||||
#define WG_PEER_HAS_ENDPOINT (1 << 3)
|
#define WG_PEER_HAS_ENDPOINT (1 << 3)
|
||||||
#define WG_PEER_REPLACE_AIPS (1 << 4)
|
#define WG_PEER_REPLACE_AIPS (1 << 4)
|
||||||
#define WG_PEER_REMOVE (1 << 5)
|
#define WG_PEER_REMOVE (1 << 5)
|
||||||
#define WG_PEER_UPDATE (1 << 6)
|
#define WG_PEER_UPDATE (1 << 6)
|
||||||
|
|
||||||
#define p_sa p_endpoint.sa_sa
|
#define p_sa p_endpoint.sa_sa
|
||||||
#define p_sin p_endpoint.sa_sin
|
#define p_sin p_endpoint.sa_sin
|
||||||
#define p_sin6 p_endpoint.sa_sin6
|
#define p_sin6 p_endpoint.sa_sin6
|
||||||
|
|
||||||
struct wg_peer_io
|
struct wg_peer_io {
|
||||||
{
|
int p_flags;
|
||||||
int p_flags;
|
int p_protocol_version;
|
||||||
int p_protocol_version;
|
uint8_t p_public[WG_KEY_LEN];
|
||||||
uint8_t p_public[WG_KEY_LEN];
|
uint8_t p_psk[WG_KEY_LEN];
|
||||||
uint8_t p_psk[WG_KEY_LEN];
|
uint16_t p_pka;
|
||||||
uint16_t p_pka;
|
union wg_peer_endpoint {
|
||||||
union wg_peer_endpoint
|
struct sockaddr sa_sa;
|
||||||
{
|
struct sockaddr_in sa_sin;
|
||||||
struct sockaddr sa_sa;
|
struct sockaddr_in6 sa_sin6;
|
||||||
struct sockaddr_in sa_sin;
|
} p_endpoint;
|
||||||
struct sockaddr_in6 sa_sin6;
|
uint64_t p_txbytes;
|
||||||
} p_endpoint;
|
uint64_t p_rxbytes;
|
||||||
uint64_t p_txbytes;
|
struct timespec p_last_handshake; /* nanotime */
|
||||||
uint64_t p_rxbytes;
|
size_t p_aips_count;
|
||||||
struct timespec p_last_handshake; /* nanotime */
|
struct wg_aip_io p_aips[];
|
||||||
size_t p_aips_count;
|
|
||||||
struct wg_aip_io p_aips[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WG_INTERFACE_HAS_PUBLIC (1 << 0)
|
#define WG_INTERFACE_HAS_PUBLIC (1 << 0)
|
||||||
#define WG_INTERFACE_HAS_PRIVATE (1 << 1)
|
#define WG_INTERFACE_HAS_PRIVATE (1 << 1)
|
||||||
#define WG_INTERFACE_HAS_PORT (1 << 2)
|
#define WG_INTERFACE_HAS_PORT (1 << 2)
|
||||||
#define WG_INTERFACE_HAS_RTABLE (1 << 3)
|
#define WG_INTERFACE_HAS_RTABLE (1 << 3)
|
||||||
#define WG_INTERFACE_REPLACE_PEERS (1 << 4)
|
#define WG_INTERFACE_REPLACE_PEERS (1 << 4)
|
||||||
#define WG_INTERFACE_DEVICE_HAS_JC (1 << 5)
|
#define WG_INTERFACE_DEVICE_HAS_JC (1 << 5)
|
||||||
#define WG_INTERFACE_DEVICE_HAS_JMIN (1 << 6)
|
#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_J3 (1 << 21)
|
||||||
#define WG_INTERFACE_DEVICE_HAS_ITIME (1 << 22)
|
#define WG_INTERFACE_DEVICE_HAS_ITIME (1 << 22)
|
||||||
|
|
||||||
struct wg_interface_io
|
struct wg_interface_io {
|
||||||
{
|
uint16_t i_flags;
|
||||||
uint16_t i_flags;
|
in_port_t i_port;
|
||||||
in_port_t i_port;
|
int i_rtable;
|
||||||
int i_rtable;
|
uint8_t i_public[WG_KEY_LEN];
|
||||||
uint8_t i_public[WG_KEY_LEN];
|
uint8_t i_private[WG_KEY_LEN];
|
||||||
uint8_t i_private[WG_KEY_LEN];
|
size_t i_peers_count;
|
||||||
size_t i_peers_count;
|
struct wg_peer_io i_peers[];
|
||||||
struct wg_peer_io i_peers[];
|
|
||||||
|
|
||||||
uint16_t i_junk_packet_count;
|
uint16_t i_junk_packet_count;
|
||||||
uint16_t i_junk_packet_min_size;
|
uint16_t i_junk_packet_min_size;
|
||||||
uint16_t i_junk_packet_max_size;
|
uint16_t i_junk_packet_max_size;
|
||||||
uint16_t i_init_packet_junk_size;
|
uint16_t i_init_packet_junk_size;
|
||||||
uint16_t i_response_packet_junk_size;
|
uint16_t i_response_packet_junk_size;
|
||||||
uint32_t i_init_packet_magic_header;
|
uint32_t i_init_packet_magic_header;
|
||||||
uint32_t i_response_packet_magic_header;
|
uint32_t i_response_packet_magic_header;
|
||||||
uint32_t i_underload_packet_magic_header;
|
uint32_t i_underload_packet_magic_header;
|
||||||
uint32_t i_transport_packet_magic_header;
|
uint32_t i_transport_packet_magic_header;
|
||||||
|
|
||||||
uint8_t* i_i1;
|
uint8_t* i_i1;
|
||||||
uint8_t* i_i2;
|
uint8_t* i_i2;
|
||||||
|
@ -125,11 +121,10 @@ struct wg_interface_io
|
||||||
uint32_t i_itime;
|
uint32_t i_itime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wg_data_io
|
struct wg_data_io {
|
||||||
{
|
char wgd_name[IFNAMSIZ];
|
||||||
char wgd_name[IFNAMSIZ];
|
size_t wgd_size; /* total size of the memory pointed to by wgd_interface */
|
||||||
size_t wgd_size; /* total size of the memory pointed to by wgd_interface */
|
struct wg_interface_io *wgd_interface;
|
||||||
struct wg_interface_io* wgd_interface;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __IF_WG_H__ */
|
#endif /* __IF_WG_H__ */
|
||||||
|
|
|
@ -6,113 +6,113 @@
|
||||||
#ifndef _WIREGUARD_NT_H
|
#ifndef _WIREGUARD_NT_H
|
||||||
#define _WIREGUARD_NT_H
|
#define _WIREGUARD_NT_H
|
||||||
|
|
||||||
#include <in6addr.h>
|
|
||||||
#include <inaddr.h>
|
|
||||||
#include <ntdef.h>
|
#include <ntdef.h>
|
||||||
#include <ws2def.h>
|
#include <ws2def.h>
|
||||||
#include <ws2ipdef.h>
|
#include <ws2ipdef.h>
|
||||||
|
#include <inaddr.h>
|
||||||
|
#include <in6addr.h>
|
||||||
|
|
||||||
#define WG_KEY_LEN 32
|
#define WG_KEY_LEN 32
|
||||||
|
|
||||||
typedef struct _WG_IOCTL_ALLOWED_IP
|
typedef struct _WG_IOCTL_ALLOWED_IP
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
IN_ADDR V4;
|
IN_ADDR V4;
|
||||||
IN6_ADDR V6;
|
IN6_ADDR V6;
|
||||||
} Address;
|
} Address;
|
||||||
ADDRESS_FAMILY AddressFamily;
|
ADDRESS_FAMILY AddressFamily;
|
||||||
UCHAR Cidr;
|
UCHAR Cidr;
|
||||||
} __attribute__((aligned(8))) WG_IOCTL_ALLOWED_IP;
|
} __attribute__((aligned(8))) WG_IOCTL_ALLOWED_IP;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
WG_IOCTL_PEER_HAS_PUBLIC_KEY = 1 << 0,
|
WG_IOCTL_PEER_HAS_PUBLIC_KEY = 1 << 0,
|
||||||
WG_IOCTL_PEER_HAS_PRESHARED_KEY = 1 << 1,
|
WG_IOCTL_PEER_HAS_PRESHARED_KEY = 1 << 1,
|
||||||
WG_IOCTL_PEER_HAS_PERSISTENT_KEEPALIVE = 1 << 2,
|
WG_IOCTL_PEER_HAS_PERSISTENT_KEEPALIVE = 1 << 2,
|
||||||
WG_IOCTL_PEER_HAS_ENDPOINT = 1 << 3,
|
WG_IOCTL_PEER_HAS_ENDPOINT = 1 << 3,
|
||||||
WG_IOCTL_PEER_HAS_PROTOCOL_VERSION = 1 << 4,
|
WG_IOCTL_PEER_HAS_PROTOCOL_VERSION = 1 << 4,
|
||||||
WG_IOCTL_PEER_REPLACE_ALLOWED_IPS = 1 << 5,
|
WG_IOCTL_PEER_REPLACE_ALLOWED_IPS = 1 << 5,
|
||||||
WG_IOCTL_PEER_REMOVE = 1 << 6,
|
WG_IOCTL_PEER_REMOVE = 1 << 6,
|
||||||
WG_IOCTL_PEER_UPDATE = 1 << 7
|
WG_IOCTL_PEER_UPDATE = 1 << 7
|
||||||
} WG_IOCTL_PEER_FLAG;
|
} WG_IOCTL_PEER_FLAG;
|
||||||
|
|
||||||
typedef struct _WG_IOCTL_PEER
|
typedef struct _WG_IOCTL_PEER
|
||||||
{
|
{
|
||||||
WG_IOCTL_PEER_FLAG Flags;
|
WG_IOCTL_PEER_FLAG Flags;
|
||||||
ULONG ProtocolVersion; /* 0 = latest protocol, 1 = this protocol. */
|
ULONG ProtocolVersion; /* 0 = latest protocol, 1 = this protocol. */
|
||||||
UCHAR PublicKey[WG_KEY_LEN];
|
UCHAR PublicKey[WG_KEY_LEN];
|
||||||
UCHAR PresharedKey[WG_KEY_LEN];
|
UCHAR PresharedKey[WG_KEY_LEN];
|
||||||
USHORT PersistentKeepalive;
|
USHORT PersistentKeepalive;
|
||||||
SOCKADDR_INET Endpoint;
|
SOCKADDR_INET Endpoint;
|
||||||
ULONG64 TxBytes;
|
ULONG64 TxBytes;
|
||||||
ULONG64 RxBytes;
|
ULONG64 RxBytes;
|
||||||
ULONG64 LastHandshake;
|
ULONG64 LastHandshake;
|
||||||
ULONG AllowedIPsCount;
|
ULONG AllowedIPsCount;
|
||||||
} __attribute__((aligned(8))) WG_IOCTL_PEER;
|
} __attribute__((aligned(8))) WG_IOCTL_PEER;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
WG_IOCTL_INTERFACE_HAS_PUBLIC_KEY = 1 << 0,
|
WG_IOCTL_INTERFACE_HAS_PUBLIC_KEY = 1 << 0,
|
||||||
WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY = 1 << 1,
|
WG_IOCTL_INTERFACE_HAS_PRIVATE_KEY = 1 << 1,
|
||||||
WG_IOCTL_INTERFACE_HAS_LISTEN_PORT = 1 << 2,
|
WG_IOCTL_INTERFACE_HAS_LISTEN_PORT = 1 << 2,
|
||||||
WG_IOCTL_INTERFACE_REPLACE_PEERS = 1 << 3,
|
WG_IOCTL_INTERFACE_REPLACE_PEERS = 1 << 3,
|
||||||
WG_IOCTL_INTERFACE_PEERS = 1 << 4,
|
WG_IOCTL_INTERFACE_PEERS = 1 << 4,
|
||||||
WG_IOCTL_INTERFACE_JC = 1 << 5,
|
WG_IOCTL_INTERFACE_JC = 1 << 5,
|
||||||
WG_IOCTL_INTERFACE_JMIN = 1 << 6,
|
WG_IOCTL_INTERFACE_JMIN = 1 << 6,
|
||||||
WG_IOCTL_INTERFACE_JMAX = 1 << 7,
|
WG_IOCTL_INTERFACE_JMAX = 1 << 7,
|
||||||
WG_IOCTL_INTERFACE_S1 = 1 << 8,
|
WG_IOCTL_INTERFACE_S1 = 1 << 8,
|
||||||
WG_IOCTL_INTERFACE_S2 = 1 << 9,
|
WG_IOCTL_INTERFACE_S2 = 1 << 9,
|
||||||
WG_IOCTL_INTERFACE_H1 = 1 << 10,
|
WG_IOCTL_INTERFACE_H1 = 1 << 10,
|
||||||
WG_IOCTL_INTERFACE_H2 = 1 << 11,
|
WG_IOCTL_INTERFACE_H2 = 1 << 11,
|
||||||
WG_IOCTL_INTERFACE_H3 = 1 << 12,
|
WG_IOCTL_INTERFACE_H3 = 1 << 12,
|
||||||
WG_IOCTL_INTERFACE_H4 = 1 << 13,
|
WG_IOCTL_INTERFACE_H4 = 1 << 13,
|
||||||
WG_IOCTL_INTERFACE_I1 = 1U << 14,
|
WG_IOCTL_INTERFACE_I1 = 1U << 14,
|
||||||
WG_IOCTL_INTERFACE_I2 = 1U << 15,
|
WG_IOCTL_INTERFACE_I2 = 1U << 15,
|
||||||
WG_IOCTL_INTERFACE_I3 = 1U << 16,
|
WG_IOCTL_INTERFACE_I3 = 1U << 16,
|
||||||
WG_IOCTL_INTERFACE_I4 = 1U << 17,
|
WG_IOCTL_INTERFACE_I4 = 1U << 17,
|
||||||
WG_IOCTL_INTERFACE_I5 = 1U << 18,
|
WG_IOCTL_INTERFACE_I5 = 1U << 18,
|
||||||
WG_IOCTL_INTERFACE_J1 = 1U << 19,
|
WG_IOCTL_INTERFACE_J1 = 1U << 19,
|
||||||
WG_IOCTL_INTERFACE_J2 = 1U << 20,
|
WG_IOCTL_INTERFACE_J2 = 1U << 20,
|
||||||
WG_IOCTL_INTERFACE_J3 = 1U << 21,
|
WG_IOCTL_INTERFACE_J3 = 1U << 21,
|
||||||
WG_IOCTL_INTERFACE_ITIME = 1U << 22
|
WG_IOCTL_INTERFACE_ITIME = 1U << 22
|
||||||
} WG_IOCTL_INTERFACE_FLAG;
|
} WG_IOCTL_INTERFACE_FLAG;
|
||||||
|
|
||||||
typedef struct _WG_IOCTL_INTERFACE
|
typedef struct _WG_IOCTL_INTERFACE
|
||||||
{
|
{
|
||||||
WG_IOCTL_INTERFACE_FLAG Flags;
|
WG_IOCTL_INTERFACE_FLAG Flags;
|
||||||
USHORT ListenPort;
|
USHORT ListenPort;
|
||||||
UCHAR PrivateKey[WG_KEY_LEN];
|
UCHAR PrivateKey[WG_KEY_LEN];
|
||||||
UCHAR PublicKey[WG_KEY_LEN];
|
UCHAR PublicKey[WG_KEY_LEN];
|
||||||
ULONG PeersCount;
|
ULONG PeersCount;
|
||||||
USHORT JunkPacketCount;
|
USHORT JunkPacketCount;
|
||||||
USHORT JunkPacketMinSize;
|
USHORT JunkPacketMinSize;
|
||||||
USHORT JunkPacketMaxSize;
|
USHORT JunkPacketMaxSize;
|
||||||
USHORT InitPacketJunkSize;
|
USHORT InitPacketJunkSize;
|
||||||
USHORT ResponsePacketJunkSize;
|
USHORT ResponsePacketJunkSize;
|
||||||
ULONG InitPacketMagicHeader;
|
ULONG InitPacketMagicHeader;
|
||||||
ULONG ResponsePacketMagicHeader;
|
ULONG ResponsePacketMagicHeader;
|
||||||
ULONG UnderloadPacketMagicHeader;
|
ULONG UnderloadPacketMagicHeader;
|
||||||
ULONG TransportPacketMagicHeader;
|
ULONG TransportPacketMagicHeader;
|
||||||
UCHAR* I1;
|
|
||||||
UCHAR* I2;
|
UCHAR* I1;
|
||||||
UCHAR* I3;
|
UCHAR* I2;
|
||||||
UCHAR* I4;
|
UCHAR* I3;
|
||||||
UCHAR* I5;
|
UCHAR* I4;
|
||||||
UCHAR* J1;
|
UCHAR* I5;
|
||||||
UCHAR* J2;
|
UCHAR* J1;
|
||||||
UCHAR* J3;
|
UCHAR* J2;
|
||||||
ULONG Itime;
|
UCHAR* J3;
|
||||||
|
ULONG Itime;
|
||||||
} __attribute__((aligned(8))) WG_IOCTL_INTERFACE;
|
} __attribute__((aligned(8))) WG_IOCTL_INTERFACE;
|
||||||
|
|
||||||
#define WG_IOCTL_GET \
|
#define WG_IOCTL_GET CTL_CODE(45208U, 321, METHOD_OUT_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||||
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_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
|
#endif
|
||||||
|
|
2
src/wg.c
2
src/wg.c
|
@ -42,7 +42,7 @@ int main(int argc, const char *argv[])
|
||||||
PROG_NAME = argv[0];
|
PROG_NAME = argv[0];
|
||||||
|
|
||||||
if (argc == 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version") || !strcmp(argv[1], "version"))) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "help"))) {
|
if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "help"))) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue