aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuanhao Yin <sopium@mysterious.site>2017-03-25 13:34:56 +0800
committerGuanhao Yin <sopium@mysterious.site>2017-03-25 13:34:56 +0800
commit55a0ed12c2c75219b311ef2872ba73360793e436 (patch)
tree718bc4b68afe961a101912e32f34cc5689d3273b
parentExpose WgStateOut and PeerStateOut (diff)
downloadwireguard-rs-55a0ed12c2c75219b311ef2872ba73360793e436.tar.xz
wireguard-rs-55a0ed12c2c75219b311ef2872ba73360793e436.zip
Add functions to convert between uapi/libc types and Rust std types
-rw-r--r--src/uapi.rs88
1 files changed, 87 insertions, 1 deletions
diff --git a/src/uapi.rs b/src/uapi.rs
index b87878b..713411a 100644
--- a/src/uapi.rs
+++ b/src/uapi.rs
@@ -1,11 +1,32 @@
+// Copyright 2017 Sascha Grunert, Guanhao Yin <sopium@mysterious.site>
+
+// This file is part of WireGuard.rs.
+
+// WireGuard.rs is free software: you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+
+// WireGuard.rs is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with WireGuard.rs. If not, see <https://www.gnu.org/licenses/>.
+
+
//! Mapping to the `WireGuard` user API
use std::convert::{AsMut, AsRef};
use std::fmt::{Debug, Result, Formatter};
use std::marker::PhantomData;
use std::mem::transmute;
+use std::net::{IpAddr, SocketAddr};
+use std::time::{SystemTime, UNIX_EPOCH};
-use libc::{in_addr, in6_addr, sockaddr, sockaddr_in, sockaddr_in6, timeval};
+use libc::{in_addr, in6_addr, sockaddr, sockaddr_in, sockaddr_in6, timeval, AF_INET, AF_INET6};
+use nix::sys::socket as nix;
const IFNAMSIZ: usize = 16;
const WG_KEY_LEN: usize = 32;
@@ -152,3 +173,68 @@ pub struct WgEndpoint {
/// The union field size as placeholder
pub union_size: [u32; 7usize],
}
+
+// Conversion between uapi/libc types <-> Rust std types.
+
+/// Convert `SystemTime` to `struct timeval`.
+pub fn system_time_to_timeval(t: &SystemTime) -> timeval {
+ let d = t.duration_since(UNIX_EPOCH).unwrap();
+ timeval {
+ tv_sec: d.as_secs() as i64,
+ tv_usec: (d.subsec_nanos() / 1000) as i64,
+ }
+}
+
+/// Convert `IpAddr` to `(family, Addr)`.
+pub fn ip_addr_to_addr(a: &IpAddr) -> (i32, Addr) {
+ match *a {
+ IpAddr::V4(ref a) => {
+ let mut out: Addr = unsafe_zeroed();
+ *out.ip4.as_mut() = nix::Ipv4Addr::from_std(a).0;
+ (AF_INET, out)
+ },
+ IpAddr::V6(ref a) => {
+ let mut out: Addr = unsafe_zeroed();
+ *out.ip6.as_mut() = nix::Ipv6Addr::from_std(a).0;
+ (AF_INET6, out)
+ }
+ }
+}
+
+/// Convert `(family, Addr)` to `IpAddr`.
+pub fn addr_to_ip_addr(family: i32, a: &Addr) -> IpAddr {
+ match family {
+ AF_INET => IpAddr::V4(nix::Ipv4Addr(*a.ip4.as_ref()).to_std()),
+ AF_INET6 => IpAddr::V6(nix::Ipv6Addr(*a.ip6.as_ref()).to_std()),
+ f => panic!("Unknown addr family {}", f),
+ }
+}
+
+/// Convert `SocketAddr` to `WgEndpoint`.
+pub fn socket_addr_to_wg_endpoint(a: &SocketAddr) -> WgEndpoint {
+ let mut out: WgEndpoint = unsafe_zeroed();
+
+ match nix::InetAddr::from_std(a) {
+ nix::InetAddr::V4(a) => *out.addr4.as_mut() = a,
+ nix::InetAddr::V6(a) => *out.addr6.as_mut() = a,
+ }
+
+ out
+}
+
+/// Convert `WgEndpoint` to `SocketAddr`.
+pub fn wg_endpoint_to_socket_addr(e: &WgEndpoint) -> SocketAddr {
+ match e.addr.as_ref().sa_family as i32 {
+ AF_INET => {
+ nix::InetAddr::V4(*e.addr4.as_ref()).to_std()
+ },
+ AF_INET6 => {
+ nix::InetAddr::V6(*e.addr6.as_ref()).to_std()
+ },
+ f => panic!("Unknown addr family {}", f),
+ }
+}
+
+fn unsafe_zeroed<T>() -> T {
+ unsafe { ::std::mem::zeroed() }
+}