init
This commit is contained in:
commit
b8c995ab9a
16 changed files with 2318 additions and 0 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
perf.data
|
||||
build
|
||||
.cache
|
||||
subprojects/oatpp-1.3.1
|
||||
subprojects/packagecache
|
||||
|
7
Dockerfile
Normal file
7
Dockerfile
Normal file
|
@ -0,0 +1,7 @@
|
|||
FROM alpine:3.22
|
||||
|
||||
RUN apk update
|
||||
RUN apk add nftables wireguard-tools-wg
|
||||
RUN mkdir "/app"
|
||||
WORKDIR /app
|
||||
ENTRYPOINT ash
|
4
justfile
Normal file
4
justfile
Normal file
|
@ -0,0 +1,4 @@
|
|||
buildimage:
|
||||
podman build --dns 8.8.8.8 -t wgcldev .
|
||||
runapp:
|
||||
podman run --volume ./:/app -i -t wgcldev /bin/ash
|
23
meson.build
Normal file
23
meson.build
Normal file
|
@ -0,0 +1,23 @@
|
|||
project(
|
||||
'wgcl',
|
||||
['cpp','c'],
|
||||
version : '0.1',
|
||||
meson_version : '>= 1.3.0',
|
||||
default_options : ['warning_level=3', 'cpp_std=c++23'],
|
||||
)
|
||||
oatpp = subproject('oatpp').get_variable('oatpp_dep')
|
||||
dependencies = [
|
||||
oatpp
|
||||
]
|
||||
|
||||
exe = executable(
|
||||
'wgcl',
|
||||
['wgcl.cpp', './wireguard/wireguard.c', './server/server.cpp', './wireguard/wgcpp.cpp'],
|
||||
install : true,
|
||||
dependencies : dependencies,
|
||||
include_directories : [],
|
||||
)
|
||||
|
||||
test_wg = executable('test_wg', ['./wireguard/wgcpp.cpp', './wireguard/wireguard.c', './tests/wg_device.cpp'])
|
||||
|
||||
test('wg', test_wg)
|
0
server/controller/TestController.hpp
Normal file
0
server/controller/TestController.hpp
Normal file
22
server/dto/DTOs.hpp
Normal file
22
server/dto/DTOs.hpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
#include "oatpp/core/data/mapping/type/Object.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
/* Begin DTO code-generation */
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
/**
|
||||
* Message Data-Transfer-Object
|
||||
*/
|
||||
class MessageDto : public oatpp::DTO {
|
||||
|
||||
DTO_INIT(MessageDto, DTO /* Extends */)
|
||||
|
||||
DTO_FIELD(Int32, statusCode); // Status code field
|
||||
DTO_FIELD(String, message); // Message field
|
||||
|
||||
};
|
||||
|
||||
/* TODO - Add more DTOs here */
|
||||
|
||||
/* End DTO code-generation */
|
||||
#include OATPP_CODEGEN_END(DTO)
|
54
server/server.cpp
Normal file
54
server/server.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include "./server_components.hpp"
|
||||
#include "./server.hpp"
|
||||
#include "oatpp/network/Server.hpp"
|
||||
#include "./dto/DTOs.hpp"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom Request Handler
|
||||
*/
|
||||
class Handler : public oatpp::web::server::HttpRequestHandler {
|
||||
private:
|
||||
/* Inject object mapper component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, m_objectMapper);
|
||||
public:
|
||||
|
||||
/**
|
||||
* Handle incoming request and return outgoing response.
|
||||
*/
|
||||
std::shared_ptr<OutgoingResponse> handle(const std::shared_ptr<IncomingRequest>& request) override {
|
||||
auto message = MessageDto::createShared();
|
||||
message->statusCode = 1024;
|
||||
message->message = "Hello DTO!";
|
||||
return ResponseFactory::createResponse(Status::CODE_200, message, m_objectMapper);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void Server::run() {
|
||||
|
||||
/* Register Components in scope of run() method */
|
||||
AppComponent components;
|
||||
|
||||
/* Get router component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
|
||||
|
||||
/* Route GET - "/hello" requests to Handler */
|
||||
router->route("GET", "/hello", std::make_shared<Handler>());
|
||||
|
||||
/* Get connection handler component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, connectionHandler);
|
||||
|
||||
/* Get connection provider component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, connectionProvider);
|
||||
|
||||
/* Create server which takes provided TCP connections and passes them to HTTP connection handler */
|
||||
oatpp::network::Server server(connectionProvider, connectionHandler);
|
||||
|
||||
/* Priny info about server port */
|
||||
OATPP_LOGI("MyApp", "Server running on port %s", connectionProvider->getProperty("port").getData());
|
||||
|
||||
/* Run server */
|
||||
server.run();
|
||||
}
|
4
server/server.hpp
Normal file
4
server/server.hpp
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
namespace Server{
|
||||
void run();
|
||||
}
|
49
server/server_components.hpp
Normal file
49
server/server_components.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
|
||||
#include "oatpp/web/server/HttpConnectionHandler.hpp"
|
||||
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
|
||||
|
||||
#include "oatpp/core/macro/component.hpp"
|
||||
|
||||
/**
|
||||
* Class which creates and holds Application components and registers components in oatpp::base::Environment
|
||||
* Order of components initialization is from top to bottom
|
||||
*/
|
||||
class AppComponent {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create ConnectionProvider component which listens on the port
|
||||
*/
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
|
||||
return oatpp::network::tcp::server::ConnectionProvider::createShared({"localhost", 8000, oatpp::network::Address::IP_4});
|
||||
}());
|
||||
|
||||
/**
|
||||
* Create Router component
|
||||
*/
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
|
||||
return oatpp::web::server::HttpRouter::createShared();
|
||||
}());
|
||||
|
||||
/**
|
||||
* Create ConnectionHandler component which uses Router component to route requests
|
||||
*/
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router); // get Router component
|
||||
return oatpp::web::server::HttpConnectionHandler::createShared(router);
|
||||
}());
|
||||
|
||||
/**
|
||||
* Create ObjectMapper component to serialize/deserialize DTOs in Contoller's API
|
||||
*/
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
|
||||
return oatpp::parser::json::mapping::ObjectMapper::createShared();
|
||||
}());
|
||||
|
||||
};
|
||||
|
14
subprojects/oatpp.wrap
Normal file
14
subprojects/oatpp.wrap
Normal file
|
@ -0,0 +1,14 @@
|
|||
[wrap-file]
|
||||
directory = oatpp-1.3.1
|
||||
source_url = https://github.com/oatpp/oatpp/archive/refs/tags/1.3.1.tar.gz
|
||||
source_filename = oatpp-1.3.1.tar.gz
|
||||
source_hash = 9dd31f005ab0b3e8895a478d750d7dbce99e42750a147a3c42a9daecbddedd64
|
||||
patch_filename = oatpp_1.3.1-2_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/oatpp_1.3.1-2/get_patch
|
||||
patch_hash = 55b1ca10e8ace40d6a95ef6c7e91a2de852e3aee74900ad7765697d7de014128
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/oatpp_1.3.1-2/oatpp-1.3.1.tar.gz
|
||||
wrapdb_version = 1.3.1-2
|
||||
|
||||
[provide]
|
||||
oatpp = oatpp_dep
|
||||
oatpp-test = oatpp_test_dep
|
45
tests/wg_device.cpp
Normal file
45
tests/wg_device.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "wireguard/wgcpp.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
int main(void) {
|
||||
Users users;
|
||||
WG wg(users, "wgdev1", 51820, 0xc0a80000,24);
|
||||
User &user = wg.add_cfg("Test");
|
||||
if (user.ipv4 != 0xc0a80002) {
|
||||
return 1;
|
||||
}
|
||||
wg.merge();
|
||||
for (auto stat : *wg.peer_state()) {
|
||||
printf("%d %x %s\n", stat.active, stat.ipv4, stat.pubkey);
|
||||
}
|
||||
|
||||
printf("user2,4 append\n");
|
||||
|
||||
User &user2 = wg.add_cfg("Test2");
|
||||
if (user2.ipv4 != 0xc0a80003) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
User &user4 = wg.add_cfg("Test4", 0xc0a80005);
|
||||
if (user4.ipv4 != 0xc0a80005) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
wg.merge();
|
||||
for (auto stat : *wg.peer_state()) {
|
||||
printf("%d %x %s\n", stat.active, stat.ipv4, stat.pubkey);
|
||||
}
|
||||
|
||||
printf("user 3 prepend\n");
|
||||
User &user3 = wg.add_cfg("Test3", 0xc0a80004);
|
||||
if (user3.ipv4 != 0xc0a80004) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
wg.merge();
|
||||
for (auto stat : *wg.peer_state()) {
|
||||
printf("%d %x %s\n", stat.active, stat.ipv4, stat.pubkey);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
16
wgcl.cpp
Normal file
16
wgcl.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include "./server/server.hpp"
|
||||
#include "oatpp/network/Server.hpp"
|
||||
#include "wireguard/wgcpp.hpp"
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
oatpp::base::Environment::init();
|
||||
|
||||
/* Run App */
|
||||
Server::run();
|
||||
|
||||
/* Destroy oatpp Environment */
|
||||
oatpp::base::Environment::destroy();
|
||||
|
||||
return 0;
|
||||
}
|
143
wireguard/wgcpp.cpp
Normal file
143
wireguard/wgcpp.cpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
#include "./wgcpp.hpp"
|
||||
#include "wireguard/wireguard.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <vector>
|
||||
|
||||
std::map<std::string_view, std::vector<User>> Users::acl_aggr() {
|
||||
std::map<std::string_view, std::vector<User>> acl_list;
|
||||
for (const User &usr : this->users) {
|
||||
for (const std::string_view member : usr.acl_member) {
|
||||
auto x = acl_list.find(member);
|
||||
if (x != acl_list.end()) {
|
||||
acl_list.at(member).push_back(usr);
|
||||
} else {
|
||||
std::vector<User> acl_members;
|
||||
acl_members.push_back(usr);
|
||||
acl_list[member] = acl_members;
|
||||
}
|
||||
}
|
||||
}
|
||||
return acl_list;
|
||||
}
|
||||
|
||||
void Users::sort_with_ip() {
|
||||
std::sort(this->users.begin(), this->users.end(),
|
||||
[](User &a, User &b) { return a.ipv4 < b.ipv4; });
|
||||
}
|
||||
|
||||
WG::WG(Users &wg_users, const char name[16], std::uint16_t port,
|
||||
uint32_t network, uint8_t cidr)
|
||||
: users(wg_users), network_ipv4(network), cidr(cidr) {
|
||||
wg_generate_private_key(this->wg_dev.private_key);
|
||||
wg_key_to_base64(this->b64_private_key, this->wg_dev.private_key);
|
||||
wg_generate_public_key(this->wg_dev.public_key, this->wg_dev.private_key);
|
||||
wg_key_to_base64(this->b64_public_key, this->wg_dev.public_key);
|
||||
this->wg_dev.first_peer = nullptr;
|
||||
this->wg_dev.last_peer = nullptr;
|
||||
|
||||
std::strncpy(this->wg_dev.name, name, 16);
|
||||
this->wg_dev.listen_port = port;
|
||||
this->wg_dev.flags = (enum wg_device_flags)(WGDEVICE_HAS_LISTEN_PORT |
|
||||
WGDEVICE_HAS_PRIVATE_KEY |
|
||||
WGDEVICE_HAS_PUBLIC_KEY);
|
||||
|
||||
uint32_t wildcard = 0xffffffff;
|
||||
|
||||
if (this->cidr < 32) {
|
||||
wildcard = ((1 << (32 - this->cidr)) - 1);
|
||||
}
|
||||
for (uint32_t i = 2; i < wildcard; i++) {
|
||||
if ((i ^ 255) != 0) {
|
||||
this->ipv4_pool.insert(this->network_ipv4 + i);
|
||||
}
|
||||
}
|
||||
for (const auto &user : wg_users.users) {
|
||||
this->ipv4_pool.erase(user.ipv4);
|
||||
}
|
||||
}
|
||||
|
||||
WG::WG(Users &wg_users, const char name[16], std::uint16_t port,
|
||||
uint32_t network, uint8_t cidr, std::string_view srv_priv_key,
|
||||
std::string_view srv_pub_key)
|
||||
: users(wg_users), network_ipv4(network), cidr(cidr) {
|
||||
std::strncpy(this->b64_private_key, srv_priv_key.data(), 45);
|
||||
std::strncpy(this->b64_public_key, srv_pub_key.data(), 45);
|
||||
wg_key_from_base64(this->wg_dev.private_key, this->b64_private_key);
|
||||
wg_key_from_base64(this->wg_dev.public_key, this->b64_public_key);
|
||||
|
||||
this->wg_dev.first_peer = nullptr;
|
||||
this->wg_dev.last_peer = nullptr;
|
||||
std::strncpy(this->wg_dev.name, name, 16);
|
||||
this->wg_dev.listen_port = port;
|
||||
this->wg_dev.flags = (enum wg_device_flags)(WGDEVICE_HAS_LISTEN_PORT |
|
||||
WGDEVICE_HAS_PRIVATE_KEY |
|
||||
WGDEVICE_HAS_PUBLIC_KEY);
|
||||
|
||||
uint32_t wildcard = 0xffffffff;
|
||||
|
||||
if (this->cidr < 32) {
|
||||
wildcard = ((1 << (32 - this->cidr)) - 1);
|
||||
}
|
||||
for (uint32_t i = 2; i < wildcard; i++) {
|
||||
if ((i ^ 255) != 0) {
|
||||
this->ipv4_pool.insert(this->network_ipv4 + i);
|
||||
}
|
||||
}
|
||||
for (const auto &user : wg_users.users) {
|
||||
this->ipv4_pool.erase(user.ipv4);
|
||||
}
|
||||
}
|
||||
|
||||
void WG::merge() {
|
||||
User *previous = nullptr;
|
||||
for (User &user : this->users.users) {
|
||||
if (previous) {
|
||||
previous->node.next_peer = &user.node;
|
||||
} else {
|
||||
previous = &user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
User &WG::add_cfg(strv name) {
|
||||
uint32_t ipv4 = this->ipv4_alloc();
|
||||
return this->add_cfg(name, ipv4);
|
||||
}
|
||||
|
||||
User &WG::add_cfg(strv name, uint32_t ipv4) {
|
||||
wg_key pub, priv;
|
||||
wg_generate_private_key(priv);
|
||||
wg_generate_public_key(pub, priv);
|
||||
User new_user(name, ipv4, pub, priv);
|
||||
this->users.users.push_back(new_user);
|
||||
return this->users.users.back();
|
||||
}
|
||||
std::vector<WGPeerStat> *WG::peer_state() {
|
||||
std::vector<WGPeerStat> *x = new std::vector<WGPeerStat>();
|
||||
for (User &user : this->users.users) {
|
||||
|
||||
WGPeerStat stat;
|
||||
stat.active = !(user.node.flags & WGPEER_REMOVE_ME);
|
||||
stat.ipv4 = user.node.first_allowedip->ip4.s_addr;
|
||||
wg_key_to_base64(stat.pubkey, user.node.public_key);
|
||||
x->push_back(stat);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
User::User(strv name, uint32_t ipv4, wg_key pubkey, wg_key privkey)
|
||||
: username(name), ipv4(ipv4) {
|
||||
memset(&this->node, 0, sizeof(wg_peer));
|
||||
this->node.flags = (enum wg_peer_flags)(WGPEER_HAS_PUBLIC_KEY | WGPEER_REPLACE_ALLOWEDIPS);
|
||||
wg_allowedip *allowed_ip = new wg_allowedip;
|
||||
allowed_ip->cidr = 32;
|
||||
allowed_ip->family = AF_INET;
|
||||
allowed_ip->ip4.s_addr = htonl(ipv4);
|
||||
this->node.first_allowedip = allowed_ip;
|
||||
this->node.last_allowedip = allowed_ip;
|
||||
memcpy(this->node.public_key, pubkey, sizeof(uint8_t) * 32);
|
||||
memcpy(this->privkey, privkey, sizeof(uint8_t) * 32);
|
||||
}
|
62
wireguard/wgcpp.hpp
Normal file
62
wireguard/wgcpp.hpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
extern "C" {
|
||||
#include "./wireguard.h"
|
||||
}
|
||||
|
||||
typedef std::string_view strv;
|
||||
|
||||
class User {
|
||||
public:
|
||||
std::string_view username;
|
||||
std::uint32_t ipv4;
|
||||
wg_peer node;
|
||||
std::set<std::string_view> acl_member;
|
||||
wg_key privkey;
|
||||
User(strv name, uint32_t ipv4, wg_key pubkey, wg_key privkey);
|
||||
};
|
||||
|
||||
class Users {
|
||||
public:
|
||||
std::vector<User> users;
|
||||
std::map<std::string_view, std::vector<User>> acl_aggr();
|
||||
void sort_with_ip();
|
||||
};
|
||||
|
||||
struct WGPeerStat {
|
||||
bool active;
|
||||
wg_key_b64_string pubkey;
|
||||
u_int32_t ipv4;
|
||||
};
|
||||
|
||||
class WG {
|
||||
private:
|
||||
wg_device wg_dev;
|
||||
std::set<uint32_t> ipv4_pool;
|
||||
|
||||
uint32_t ipv4_alloc() {
|
||||
uint32_t pick = *this->ipv4_pool.begin();
|
||||
this->ipv4_pool.erase(pick);
|
||||
|
||||
return pick;
|
||||
}
|
||||
wg_key_b64_string b64_private_key, b64_public_key;
|
||||
|
||||
public:
|
||||
Users &users;
|
||||
uint32_t network_ipv4;
|
||||
uint8_t cidr;
|
||||
uint32_t persistent_time = 0;
|
||||
WG(Users &wg_users, const char name[16], std::uint16_t port, uint32_t network,
|
||||
uint8_t cidr);
|
||||
WG(Users &wg_users, const char name[16], std::uint16_t port, uint32_t network,
|
||||
uint8_t cidr, std::string_view srv_priv_key, std::string_view srv_pub_key);
|
||||
User &add_cfg(strv name);
|
||||
User &add_cfg(strv name, uint32_t ipv4);
|
||||
void merge();
|
||||
std::vector<WGPeerStat> *peer_state();
|
||||
};
|
1756
wireguard/wireguard.c
Normal file
1756
wireguard/wireguard.c
Normal file
File diff suppressed because it is too large
Load diff
113
wireguard/wireguard.h
Normal file
113
wireguard/wireguard.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/*
|
||||
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef WIREGUARD_H
|
||||
#define WIREGUARD_H
|
||||
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef uint8_t wg_key[32];
|
||||
typedef char wg_key_b64_string[((sizeof(wg_key) + 2) / 3) * 4 + 1];
|
||||
|
||||
/* Cross platform __kernel_timespec */
|
||||
struct timespec64 {
|
||||
int64_t tv_sec;
|
||||
int64_t tv_nsec;
|
||||
};
|
||||
|
||||
typedef struct wg_allowedip {
|
||||
uint16_t family;
|
||||
union {
|
||||
struct in_addr ip4;
|
||||
struct in6_addr ip6;
|
||||
};
|
||||
uint8_t cidr;
|
||||
struct wg_allowedip *next_allowedip;
|
||||
} wg_allowedip;
|
||||
|
||||
enum wg_peer_flags {
|
||||
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
|
||||
};
|
||||
|
||||
typedef union wg_endpoint {
|
||||
struct sockaddr addr;
|
||||
struct sockaddr_in addr4;
|
||||
struct sockaddr_in6 addr6;
|
||||
} wg_endpoint;
|
||||
|
||||
typedef struct wg_peer {
|
||||
enum wg_peer_flags flags;
|
||||
|
||||
wg_key public_key;
|
||||
wg_key preshared_key;
|
||||
|
||||
wg_endpoint endpoint;
|
||||
|
||||
struct timespec64 last_handshake_time;
|
||||
uint64_t rx_bytes, tx_bytes;
|
||||
uint16_t persistent_keepalive_interval;
|
||||
|
||||
struct wg_allowedip *first_allowedip, *last_allowedip;
|
||||
struct wg_peer *next_peer;
|
||||
} wg_peer;
|
||||
|
||||
enum wg_device_flags {
|
||||
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
|
||||
};
|
||||
|
||||
typedef struct wg_device {
|
||||
char name[IFNAMSIZ];
|
||||
uint32_t ifindex;
|
||||
|
||||
enum wg_device_flags flags;
|
||||
|
||||
wg_key public_key;
|
||||
wg_key private_key;
|
||||
|
||||
uint32_t fwmark;
|
||||
uint16_t listen_port;
|
||||
|
||||
struct wg_peer *first_peer, *last_peer;
|
||||
} wg_device;
|
||||
|
||||
#define wg_for_each_device_name(__names, __name, __len) \
|
||||
for ((__name) = (__names), (__len) = 0; ((__len) = strlen(__name)); \
|
||||
(__name) += (__len) + 1)
|
||||
#define wg_for_each_peer(__dev, __peer) \
|
||||
for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer)
|
||||
#define wg_for_each_allowedip(__peer, __allowedip) \
|
||||
for ((__allowedip) = (__peer)->first_allowedip; (__allowedip); \
|
||||
(__allowedip) = (__allowedip)->next_allowedip)
|
||||
|
||||
int wg_set_device(wg_device *dev);
|
||||
int wg_get_device(wg_device **dev, const char *device_name);
|
||||
int wg_add_device(const char *device_name);
|
||||
int wg_del_device(const char *device_name);
|
||||
void wg_free_device(wg_device *dev);
|
||||
char *wg_list_device_names(void); /* first\0second\0third\0forth\0last\0\0 */
|
||||
void wg_key_to_base64(wg_key_b64_string base64, const wg_key key);
|
||||
int wg_key_from_base64(wg_key key, const wg_key_b64_string base64);
|
||||
bool wg_key_is_zero(const wg_key key);
|
||||
void wg_generate_public_key(wg_key public_key, const wg_key private_key);
|
||||
void wg_generate_private_key(wg_key private_key);
|
||||
void wg_generate_preshared_key(wg_key preshared_key);
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue