summaryrefslogtreecommitdiff
path: root/src/setup.rs
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2025-07-18 18:46:55 +0100
committerdiogo464 <[email protected]>2025-07-18 18:46:55 +0100
commit75ccbd675c22fb3275c5763518c3b97819db4c53 (patch)
tree1ff2a44abcac884875f80a44a569681e0f2d7a7d /src/setup.rs
init
Diffstat (limited to 'src/setup.rs')
-rw-r--r--src/setup.rs212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/setup.rs b/src/setup.rs
new file mode 100644
index 0000000..e7d454c
--- /dev/null
+++ b/src/setup.rs
@@ -0,0 +1,212 @@
1use std::net::{IpAddr, SocketAddr};
2
3use ipnet::IpNet;
4use netlink_packet_wireguard::{
5 constants::{AF_INET, AF_INET6, WGDEVICE_F_REPLACE_PEERS, WGPEER_F_REPLACE_ALLOWEDIPS},
6 nlas::{WgAllowedIp, WgAllowedIpAttrs, WgDeviceAttrs, WgPeer, WgPeerAttrs},
7 Wireguard, WireguardCmd,
8};
9
10use super::Key;
11
12#[derive(Debug)]
13pub struct PeerDescriptor {
14 pub(super) public_key: Key,
15 pub(super) preshared_key: Option<Key>,
16 pub(super) endpoint: Option<SocketAddr>,
17 pub(super) keepalive: Option<u16>,
18 pub(super) allowed_ips: Option<Vec<IpNet>>,
19}
20
21impl PeerDescriptor {
22 pub fn new(public_key: Key) -> Self {
23 Self {
24 public_key,
25 preshared_key: None,
26 endpoint: None,
27 keepalive: None,
28 allowed_ips: None,
29 }
30 }
31
32 pub fn preshared_key_optional(mut self, preshared_key: Option<Key>) -> Self {
33 self.preshared_key = preshared_key;
34 self
35 }
36
37 pub fn preshared_key(mut self, preshared_key: Key) -> Self {
38 self.preshared_key = Some(preshared_key);
39 self
40 }
41
42 pub fn endpoint_optional(mut self, endpoint: Option<SocketAddr>) -> Self {
43 self.endpoint = endpoint;
44 self
45 }
46
47 pub fn endpoint(mut self, endpoint: SocketAddr) -> Self {
48 self.endpoint = Some(endpoint);
49 self
50 }
51
52 pub fn keepalive_optional(mut self, keepalive: Option<u16>) -> Self {
53 self.keepalive = keepalive;
54 self
55 }
56
57 pub fn keepalive(mut self, keepalive: u16) -> Self {
58 self.keepalive = Some(keepalive);
59 self
60 }
61
62 pub fn allowed_ip_optional(self, allowed_ip: Option<IpNet>) -> Self {
63 if let Some(allowed_ip) = allowed_ip {
64 self.allowed_ip(allowed_ip)
65 } else {
66 self
67 }
68 }
69
70 pub fn allowed_ip(mut self, allowed_ip: IpNet) -> Self {
71 let mut allowed_ips = self.allowed_ips.take().unwrap_or_default();
72 allowed_ips.push(allowed_ip);
73 self.allowed_ips = Some(allowed_ips);
74 self
75 }
76
77 pub fn allowed_ips_optional(self, allowed_ips: Option<Vec<IpNet>>) -> Self {
78 if let Some(allowed_ips) = allowed_ips {
79 self.allowed_ips(allowed_ips)
80 } else {
81 self
82 }
83 }
84
85 pub fn allowed_ips(mut self, allowed_ips: Vec<IpNet>) -> Self {
86 self.allowed_ips = Some(allowed_ips);
87 self
88 }
89
90 pub(super) fn into_wireguard(self) -> WgPeer {
91 let mut nlas = Vec::new();
92 nlas.push(WgPeerAttrs::PublicKey(self.public_key.into_array()));
93 nlas.extend(
94 self.preshared_key
95 .map(|key| WgPeerAttrs::PresharedKey(key.into_array())),
96 );
97 nlas.extend(self.endpoint.map(WgPeerAttrs::Endpoint));
98 nlas.extend(self.keepalive.map(WgPeerAttrs::PersistentKeepalive));
99 nlas.extend(self.allowed_ips.map(|allowed_ips| {
100 WgPeerAttrs::AllowedIps(allowed_ips.into_iter().map(ipnet_to_wg).collect())
101 }));
102 nlas.push(WgPeerAttrs::Flags(WGPEER_F_REPLACE_ALLOWEDIPS));
103 WgPeer(nlas)
104 }
105}
106
107#[derive(Debug)]
108pub struct DeviceDescriptor {
109 pub(super) addresses: Vec<IpNet>,
110 pub(super) private_key: Option<Key>,
111 pub(super) listen_port: Option<u16>,
112 pub(super) fwmark: Option<u32>,
113 pub(super) peers: Option<Vec<PeerDescriptor>>,
114}
115
116impl Default for DeviceDescriptor {
117 fn default() -> Self {
118 Self::new()
119 }
120}
121
122impl DeviceDescriptor {
123 pub fn new() -> Self {
124 Self {
125 addresses: Vec::default(),
126 private_key: None,
127 listen_port: None,
128 fwmark: None,
129 peers: None,
130 }
131 }
132
133 pub fn address(mut self, address: IpNet) -> Self {
134 self.addresses.push(address);
135 self
136 }
137
138 pub fn addresses(mut self, addresses: impl IntoIterator<Item = IpNet>) -> Self {
139 self.addresses.extend(addresses);
140 self
141 }
142
143 pub fn private_key(mut self, key: Key) -> Self {
144 self.private_key = Some(key);
145 self
146 }
147
148 pub fn listen_port(mut self, port: u16) -> Self {
149 self.listen_port = Some(port);
150 self
151 }
152
153 pub fn listen_port_optional(mut self, port: Option<u16>) -> Self {
154 self.listen_port = port;
155 self
156 }
157
158 pub fn fwmark(mut self, fwmark: u32) -> Self {
159 self.fwmark = Some(fwmark);
160 self
161 }
162
163 pub fn peer(mut self, peer: PeerDescriptor) -> Self {
164 let mut p = self.peers.take().unwrap_or_default();
165 p.push(peer);
166 self.peers = Some(p);
167 self
168 }
169
170 pub fn peers(mut self, peers: impl IntoIterator<Item = PeerDescriptor>) -> Self {
171 let mut p = self.peers.take().unwrap_or_default();
172 p.extend(peers);
173 self.peers = Some(p);
174 self
175 }
176
177 pub(super) fn into_wireguard(self, device_name: String) -> Wireguard {
178 let mut nlas = Vec::new();
179 nlas.push(WgDeviceAttrs::IfName(device_name));
180 nlas.extend(
181 self.private_key
182 .map(|key| WgDeviceAttrs::PrivateKey(key.into_array())),
183 );
184 nlas.extend(self.listen_port.map(WgDeviceAttrs::ListenPort));
185 nlas.extend(self.fwmark.map(WgDeviceAttrs::Fwmark));
186 nlas.extend(self.peers.map(|peers| {
187 WgDeviceAttrs::Peers(
188 peers
189 .into_iter()
190 .map(PeerDescriptor::into_wireguard)
191 .collect(),
192 )
193 }));
194 nlas.push(WgDeviceAttrs::Flags(WGDEVICE_F_REPLACE_PEERS));
195
196 Wireguard {
197 cmd: WireguardCmd::SetDevice,
198 nlas,
199 }
200 }
201}
202
203fn ipnet_to_wg(net: IpNet) -> WgAllowedIp {
204 let mut nlas = Vec::default();
205 nlas.push(WgAllowedIpAttrs::Cidr(net.prefix_len()));
206 nlas.push(WgAllowedIpAttrs::IpAddr(net.addr()));
207 match net.addr() {
208 IpAddr::V4(_) => nlas.push(WgAllowedIpAttrs::Family(AF_INET)),
209 IpAddr::V6(_) => nlas.push(WgAllowedIpAttrs::Family(AF_INET6)),
210 }
211 WgAllowedIp(nlas)
212}