aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wg-rs/src/allowed_ip.rs32
-rw-r--r--wg-rs/src/device.rs67
-rw-r--r--wg-rs/src/lib.rs183
-rw-r--r--wg-rs/src/peer.rs78
-rw-r--r--wg-sys/src/lib.rs2
5 files changed, 189 insertions, 173 deletions
diff --git a/wg-rs/src/allowed_ip.rs b/wg-rs/src/allowed_ip.rs
new file mode 100644
index 0000000..b91c45a
--- /dev/null
+++ b/wg-rs/src/allowed_ip.rs
@@ -0,0 +1,32 @@
+use std::net::IpAddr;
+
+#[derive(Debug)]
+pub struct WgAllowedIp {
+ pub ip: IpAddr,
+ pub cidr: u8,
+}
+impl From<&wg_sys::wg_allowedip> for WgAllowedIp {
+ fn from(allowed_ip: &wg_sys::wg_allowedip) -> Self {
+ unsafe {
+ match allowed_ip.family as i32 {
+ wg_sys::AF_INET => Self {
+ ip: IpAddr::V4(
+ allowed_ip
+ .__bindgen_anon_1
+ .ip4
+ .as_ref()
+ .s_addr
+ .to_be()
+ .into(),
+ ),
+ cidr: allowed_ip.cidr,
+ },
+ wg_sys::AF_INET6 => Self {
+ ip: IpAddr::V6(allowed_ip.__bindgen_anon_1.ip6.as_ref().s6_addr.into()),
+ cidr: allowed_ip.cidr,
+ },
+ _ => unimplemented!("Unsupported family"),
+ }
+ }
+ }
+}
diff --git a/wg-rs/src/device.rs b/wg-rs/src/device.rs
new file mode 100644
index 0000000..c865c5b
--- /dev/null
+++ b/wg-rs/src/device.rs
@@ -0,0 +1,67 @@
+use std::ffi::CStr;
+
+use crate::{raw, WgPeer};
+
+#[derive(Debug)]
+pub struct WgDevice {
+ pub name: String,
+ pub ifindex: u32,
+ pub private_key: String,
+ pub public_key: String,
+ pub fwmark: u32,
+ pub listen_port: u16,
+ pub peers: Vec<WgPeer>,
+ pub flags: WgDeviceFlags,
+}
+
+#[allow(non_snake_case)]
+#[derive(Debug)]
+pub struct WgDeviceFlags {
+ pub ReplacePeers: bool,
+ pub HasPrivateKey: bool,
+ pub HasPublicKey: bool,
+ pub HasListenPort: bool,
+ pub HasFwmark: bool,
+}
+
+impl From<wg_sys::wg_device> for WgDevice {
+ fn from(device: wg_sys::wg_device) -> Self {
+ let mut dev = Self {
+ name: CStr::from_bytes_until_nul(
+ &device.name.iter().map(|&c| c as u8).collect::<Vec<u8>>(),
+ )
+ .unwrap()
+ .to_str()
+ .unwrap()
+ .to_string(),
+ ifindex: device.ifindex,
+ private_key: raw::wg_key_to_base64(device.private_key),
+ public_key: raw::wg_key_to_base64(device.public_key),
+ fwmark: device.fwmark,
+ listen_port: device.listen_port,
+ peers: vec![],
+ flags: WgDeviceFlags {
+ ReplacePeers: (device.flags.0 & wg_sys::wg_device_flags::WGDEVICE_REPLACE_PEERS.0)
+ != 0,
+ HasPrivateKey: (device.flags.0
+ & wg_sys::wg_device_flags::WGDEVICE_HAS_PRIVATE_KEY.0)
+ != 0,
+ HasPublicKey: (device.flags.0 & wg_sys::wg_device_flags::WGDEVICE_HAS_PUBLIC_KEY.0)
+ != 0,
+ HasListenPort: (device.flags.0
+ & wg_sys::wg_device_flags::WGDEVICE_HAS_LISTEN_PORT.0)
+ != 0,
+ HasFwmark: (device.flags.0 & wg_sys::wg_device_flags::WGDEVICE_HAS_FWMARK.0) != 0,
+ },
+ };
+
+ let mut peer_opt = unsafe { device.first_peer.as_ref() };
+
+ while let Some(peer) = peer_opt {
+ dev.peers.push(WgPeer::from(peer));
+ peer_opt = unsafe { peer.next_peer.as_ref() };
+ }
+
+ dev
+ }
+}
diff --git a/wg-rs/src/lib.rs b/wg-rs/src/lib.rs
index b0313b1..8c6fc8d 100644
--- a/wg-rs/src/lib.rs
+++ b/wg-rs/src/lib.rs
@@ -1,178 +1,13 @@
+mod allowed_ip;
+mod device;
+mod peer;
mod raw;
-use std::ffi::CStr;
-use std::net::{IpAddr, SocketAddr};
-use raw::wg_get_device;
+pub use allowed_ip::*;
+pub use device::*;
+pub use peer::*;
-#[derive(Debug)]
-pub struct WgDevice {
- pub name: String,
- pub ifindex: u32,
- pub private_key: String,
- pub public_key: String,
- pub fwmark: u32,
- pub listen_port: u16,
- pub peers: Vec<WgPeer>,
- pub flags: WgDeviceFlags,
-}
-
-#[allow(non_snake_case)]
-#[derive(Debug)]
-pub struct WgDeviceFlags {
- pub ReplacePeers: bool,
- pub HasPrivateKey: bool,
- pub HasPublicKey: bool,
- pub HasListenPort: bool,
- pub HasFwmark: bool,
-}
-
-impl From<wg_sys::wg_device> for WgDevice {
- fn from(device: wg_sys::wg_device) -> Self {
- let mut dev = Self {
- name: CStr::from_bytes_until_nul(
- &device.name.iter().map(|&c| c as u8).collect::<Vec<u8>>(),
- )
- .unwrap()
- .to_str()
- .unwrap()
- .to_string(),
- ifindex: device.ifindex,
- private_key: raw::wg_key_to_base64(device.private_key),
- public_key: raw::wg_key_to_base64(device.public_key),
- fwmark: device.fwmark,
- listen_port: device.listen_port,
- peers: vec![],
- flags: WgDeviceFlags {
- ReplacePeers: (device.flags.0 & wg_sys::wg_device_flags::WGDEVICE_REPLACE_PEERS.0)
- != 0,
- HasPrivateKey: (device.flags.0
- & wg_sys::wg_device_flags::WGDEVICE_HAS_PRIVATE_KEY.0)
- != 0,
- HasPublicKey: (device.flags.0 & wg_sys::wg_device_flags::WGDEVICE_HAS_PUBLIC_KEY.0)
- != 0,
- HasListenPort: (device.flags.0
- & wg_sys::wg_device_flags::WGDEVICE_HAS_LISTEN_PORT.0)
- != 0,
- HasFwmark: (device.flags.0 & wg_sys::wg_device_flags::WGDEVICE_HAS_FWMARK.0) != 0,
- },
- };
-
- let mut peer_opt = unsafe { device.first_peer.as_ref() };
-
- while let Some(peer) = peer_opt {
- dev.peers.push(WgPeer::from(peer));
- peer_opt = unsafe { peer.next_peer.as_ref() };
- }
-
- dev
- }
-}
-
-#[derive(Debug)]
-pub struct WgPeer {
- pub public_key: String,
- pub preshared_key: String,
- pub endpoint: SocketAddr,
- pub allowed_ips: Vec<WgAllowedIp>,
- pub rx_bytes: u64,
- pub tx_bytes: u64,
- pub persistent_keepalive: u16,
- pub last_handshake_time: (u64, u64),
- pub flags: WgPeerFlags,
-}
-#[allow(non_snake_case)]
-#[derive(Debug)]
-pub struct WgPeerFlags {
- pub RemoveMe: bool,
- pub ReplaceAllowedIps: bool,
- pub HasPublicKey: bool,
- pub HasPresharedKey: bool,
- pub HasPersistentKeepalive: bool,
-}
-
-impl From<&wg_sys::wg_peer> for WgPeer {
- fn from(peer: &wg_sys::wg_peer) -> Self {
- let endpoint = unsafe {
- match peer.endpoint.addr.as_ref().sa_family as i32 {
- wg_sys::AF_INET => SocketAddr::new(
- IpAddr::V4(peer.endpoint.addr4.as_ref().sin_addr.s_addr.to_be().into()),
- peer.endpoint.addr4.as_ref().sin_port.to_be(),
- ),
- wg_sys::AF_INET6 => SocketAddr::new(
- IpAddr::V6(peer.endpoint.addr6.as_ref().sin6_addr.s6_addr.into()),
- peer.endpoint.addr6.as_ref().sin6_port.to_be(),
- ),
- _ => unimplemented!("Unsupported family"),
- }
- };
-
- let mut wgpeer = Self {
- public_key: raw::wg_key_to_base64(peer.public_key),
- preshared_key: raw::wg_key_to_base64(peer.preshared_key),
- rx_bytes: peer.rx_bytes,
- tx_bytes: peer.tx_bytes,
- persistent_keepalive: peer.persistent_keepalive_interval,
- endpoint,
- last_handshake_time: (
- peer.last_handshake_time.tv_sec as u64,
- peer.last_handshake_time.tv_nsec as u64,
- ),
- allowed_ips: vec![],
- flags: WgPeerFlags {
- RemoveMe: (peer.flags.0 & wg_sys::wg_peer_flags::WGPEER_REMOVE_ME.0) != 0,
- ReplaceAllowedIps: (peer.flags.0
- & wg_sys::wg_peer_flags::WGPEER_REPLACE_ALLOWEDIPS.0)
- != 0,
- HasPublicKey: (peer.flags.0 & wg_sys::wg_peer_flags::WGPEER_HAS_PUBLIC_KEY.0) != 0,
- HasPresharedKey: (peer.flags.0 & wg_sys::wg_peer_flags::WGPEER_HAS_PRESHARED_KEY.0)
- != 0,
- HasPersistentKeepalive: (peer.flags.0
- & wg_sys::wg_peer_flags::WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL.0)
- != 0,
- },
- };
-
- let mut aip_opt = unsafe { peer.first_allowedip.as_ref() };
-
- while let Some(aip) = aip_opt {
- wgpeer.allowed_ips.push(WgAllowedIp::from(aip));
- aip_opt = unsafe { aip.next_allowedip.as_ref() };
- }
-
- wgpeer
- }
-}
-
-#[derive(Debug)]
-pub struct WgAllowedIp {
- pub ip: IpAddr,
- pub cidr: u8,
-}
-impl From<&wg_sys::wg_allowedip> for WgAllowedIp {
- fn from(allowed_ip: &wg_sys::wg_allowedip) -> Self {
- unsafe {
- match allowed_ip.family as i32 {
- wg_sys::AF_INET => Self {
- ip: IpAddr::V4(
- allowed_ip
- .__bindgen_anon_1
- .ip4
- .as_ref()
- .s_addr
- .to_be()
- .into(),
- ),
- cidr: allowed_ip.cidr,
- },
- wg_sys::AF_INET6 => Self {
- ip: IpAddr::V6(allowed_ip.__bindgen_anon_1.ip6.as_ref().s6_addr.into()),
- cidr: allowed_ip.cidr,
- },
- _ => unimplemented!("Unsupported family"),
- }
- }
- }
-}
+use raw::{wg_get_device, wg_set_device};
pub fn list_device_names() -> Vec<String> {
raw::wg_list_device_names()
@@ -196,6 +31,10 @@ pub fn get_device(name: &str) -> Result<WgDevice, String> {
Ok(WgDevice::from(dev))
}
+pub fn set_device(device: &WgDevice) {
+ // wg_set_device(device.into()).unwrap();
+}
+
#[cfg(test)]
mod test {
use super::*;
diff --git a/wg-rs/src/peer.rs b/wg-rs/src/peer.rs
new file mode 100644
index 0000000..dc1852e
--- /dev/null
+++ b/wg-rs/src/peer.rs
@@ -0,0 +1,78 @@
+use std::net::{SocketAddr, IpAddr};
+
+use crate::{WgAllowedIp, raw};
+
+#[derive(Debug)]
+pub struct WgPeer {
+ pub public_key: String,
+ pub preshared_key: String,
+ pub endpoint: SocketAddr,
+ pub allowed_ips: Vec<WgAllowedIp>,
+ pub rx_bytes: u64,
+ pub tx_bytes: u64,
+ pub persistent_keepalive: u16,
+ pub last_handshake_time: (u64, u64),
+ pub flags: WgPeerFlags,
+}
+#[allow(non_snake_case)]
+#[derive(Debug)]
+pub struct WgPeerFlags {
+ pub RemoveMe: bool,
+ pub ReplaceAllowedIps: bool,
+ pub HasPublicKey: bool,
+ pub HasPresharedKey: bool,
+ pub HasPersistentKeepalive: bool,
+}
+
+impl From<&wg_sys::wg_peer> for WgPeer {
+ fn from(peer: &wg_sys::wg_peer) -> Self {
+ let endpoint = unsafe {
+ match peer.endpoint.addr.as_ref().sa_family as i32 {
+ wg_sys::AF_INET => SocketAddr::new(
+ IpAddr::V4(peer.endpoint.addr4.as_ref().sin_addr.s_addr.to_be().into()),
+ peer.endpoint.addr4.as_ref().sin_port.to_be(),
+ ),
+ wg_sys::AF_INET6 => SocketAddr::new(
+ IpAddr::V6(peer.endpoint.addr6.as_ref().sin6_addr.s6_addr.into()),
+ peer.endpoint.addr6.as_ref().sin6_port.to_be(),
+ ),
+ _ => unimplemented!("Unsupported family"),
+ }
+ };
+
+ let mut wgpeer = Self {
+ public_key: raw::wg_key_to_base64(peer.public_key),
+ preshared_key: raw::wg_key_to_base64(peer.preshared_key),
+ rx_bytes: peer.rx_bytes,
+ tx_bytes: peer.tx_bytes,
+ persistent_keepalive: peer.persistent_keepalive_interval,
+ endpoint,
+ last_handshake_time: (
+ peer.last_handshake_time.tv_sec as u64,
+ peer.last_handshake_time.tv_nsec as u64,
+ ),
+ allowed_ips: vec![],
+ flags: WgPeerFlags {
+ RemoveMe: (peer.flags.0 & wg_sys::wg_peer_flags::WGPEER_REMOVE_ME.0) != 0,
+ ReplaceAllowedIps: (peer.flags.0
+ & wg_sys::wg_peer_flags::WGPEER_REPLACE_ALLOWEDIPS.0)
+ != 0,
+ HasPublicKey: (peer.flags.0 & wg_sys::wg_peer_flags::WGPEER_HAS_PUBLIC_KEY.0) != 0,
+ HasPresharedKey: (peer.flags.0 & wg_sys::wg_peer_flags::WGPEER_HAS_PRESHARED_KEY.0)
+ != 0,
+ HasPersistentKeepalive: (peer.flags.0
+ & wg_sys::wg_peer_flags::WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL.0)
+ != 0,
+ },
+ };
+
+ let mut aip_opt = unsafe { peer.first_allowedip.as_ref() };
+
+ while let Some(aip) = aip_opt {
+ wgpeer.allowed_ips.push(WgAllowedIp::from(aip));
+ aip_opt = unsafe { aip.next_allowedip.as_ref() };
+ }
+
+ wgpeer
+ }
+}
diff --git a/wg-sys/src/lib.rs b/wg-sys/src/lib.rs
index 2cf9dd9..6d7ac2d 100644
--- a/wg-sys/src/lib.rs
+++ b/wg-sys/src/lib.rs
@@ -6,4 +6,4 @@
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
-pub use libc::{AF_INET, AF_INET6}; \ No newline at end of file
+pub use libc::{AF_INET, AF_INET6};