wip
This commit is contained in:
parent
33a2dd685f
commit
c12c260696
58
Cargo.toml
58
Cargo.toml
@ -1,56 +1,2 @@
|
|||||||
[package]
|
[workspace]
|
||||||
name = "protomask"
|
members = ["libs/easy-tun"]
|
||||||
version = "0.2.0"
|
|
||||||
authors = ["Evan Pratten <ewpratten@gmail.com>"]
|
|
||||||
edition = "2021"
|
|
||||||
description = "A user space NAT64 implementation"
|
|
||||||
readme = "README.md"
|
|
||||||
homepage = "https://github.com/ewpratten/protomask"
|
|
||||||
documentation = "https://docs.rs/protomask"
|
|
||||||
repository = "https://github.com/ewpratten/protomask"
|
|
||||||
license = "GPL-3.0"
|
|
||||||
keywords = []
|
|
||||||
categories = []
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
[dependencies]
|
|
||||||
protomask-tun = { path = "protomask-tun", version = "0.1.0" }
|
|
||||||
tokio = { version = "1.29.1", features = [
|
|
||||||
"macros",
|
|
||||||
"rt-multi-thread",
|
|
||||||
# "process",
|
|
||||||
"sync"
|
|
||||||
] }
|
|
||||||
clap = { version = "4.3.11", features = ["derive"] }
|
|
||||||
serde = { version = "1.0.171", features = ["derive"] }
|
|
||||||
ipnet = { version = "2.8.0", features = ["serde"] }
|
|
||||||
hyper = { version = "0.14.27", features = ["server", "http1", "tcp"] }
|
|
||||||
owo-colors = { version = "3.5.0", features = ["supports-colors"] }
|
|
||||||
toml = "0.7.6"
|
|
||||||
log = "0.4.19"
|
|
||||||
fern = "0.6.2"
|
|
||||||
serde_path_to_error = "0.1.13"
|
|
||||||
thiserror = "1.0.43"
|
|
||||||
tun-tap = "0.1.3"
|
|
||||||
bimap = "0.6.3"
|
|
||||||
pnet_packet = "0.34.0"
|
|
||||||
rtnetlink = "0.13.0"
|
|
||||||
futures = "0.3.28"
|
|
||||||
prometheus = "0.13.3"
|
|
||||||
lazy_static = "1.4.0"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "protomask"
|
|
||||||
path = "src/cli/main.rs"
|
|
||||||
|
|
||||||
[package.metadata.deb]
|
|
||||||
section = "network"
|
|
||||||
assets = [
|
|
||||||
["target/release/protomask", "/usr/local/bin/protomask", "755"],
|
|
||||||
["./protomask.toml", "/etc/protomask.toml", "644"],
|
|
||||||
["README.md", "usr/share/doc/protomask/README.md", "644"]
|
|
||||||
]
|
|
||||||
conf-files = ["/etc/protomask.toml"]
|
|
||||||
depends = []
|
|
||||||
maintainer-scripts = "./debian/"
|
|
||||||
systemd-units = { enable = false }
|
|
20
libs/easy-tun/Cargo.toml
Normal file
20
libs/easy-tun/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "easy-tun"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Evan Pratten <ewpratten@gmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
description = "TUN interfaces made easy"
|
||||||
|
readme = "README.md"
|
||||||
|
homepage = "https://github.com/ewpratten/protomask/libs/easy-tun"
|
||||||
|
documentation = "https://docs.rs/easy-tun"
|
||||||
|
repository = "https://github.com/ewpratten/protomask"
|
||||||
|
license = "GPL-3.0"
|
||||||
|
keywords = []
|
||||||
|
categories = []
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "^1.29.1", features = ["sync", "rt"] }
|
||||||
|
log = "^0.4"
|
||||||
|
libc = "^0.2"
|
||||||
|
ioctl-gen = "^0.1.1"
|
||||||
|
rtnetlink = "^0.13.0"
|
0
libs/easy-tun/README.md
Normal file
0
libs/easy-tun/README.md
Normal file
110
libs/easy-tun/src/lib.rs
Normal file
110
libs/easy-tun/src/lib.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
use std::{
|
||||||
|
fs::{File, OpenOptions},
|
||||||
|
future::Future,
|
||||||
|
mem::size_of,
|
||||||
|
os::fd::{AsRawFd, IntoRawFd, RawFd},
|
||||||
|
};
|
||||||
|
|
||||||
|
use ioctl_gen::{ioc, iow};
|
||||||
|
use libc::{__c_anonymous_ifr_ifru, ifreq, ioctl, IFF_NO_PI, IFF_TUN, IF_NAMESIZE};
|
||||||
|
|
||||||
|
/// A TUN device
|
||||||
|
pub struct Tun {
|
||||||
|
/// Internal file descriptor for the TUN device
|
||||||
|
fd: File,
|
||||||
|
/// Device name
|
||||||
|
name: String,
|
||||||
|
/// Handle on the RTNETLINK connection
|
||||||
|
rt_connection_future: Box<dyn Future<Output = ()>>,
|
||||||
|
/// Handle on the RTNETLINK socket
|
||||||
|
rt_handle: rtnetlink::Handle,
|
||||||
|
/// Link index of the TUN device
|
||||||
|
link_index: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tun {
|
||||||
|
/// Creates a new Tun device with the given name.
|
||||||
|
///
|
||||||
|
/// The `name` argument must be less than the system's `IFNAMSIZ` constant,
|
||||||
|
/// and may contain a `%d` format specifier to allow for multiple devices with the same name.
|
||||||
|
pub fn new(dev: &str) -> Result<Self, std::io::Error> {
|
||||||
|
// Get a file descriptor for `/dev/net/tun`
|
||||||
|
log::trace!("Opening /dev/net/tun");
|
||||||
|
let fd = OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.write(true)
|
||||||
|
.open("/dev/net/tun")?;
|
||||||
|
|
||||||
|
// Copy the device name into a C string with padding
|
||||||
|
// NOTE: No zero padding is needed because we pre-init the array to all 0s
|
||||||
|
let mut dev_cstr = [0i8; IF_NAMESIZE];
|
||||||
|
let dev_bytes: Vec<i8> = dev.as_bytes().iter().map(|c| *c as i8).collect();
|
||||||
|
let dev_len = dev_bytes.len().min(IF_NAMESIZE);
|
||||||
|
log::trace!("Device name length after truncation: {}", dev_len);
|
||||||
|
dev_cstr[..dev_len].copy_from_slice(&dev_bytes[..dev_len]);
|
||||||
|
|
||||||
|
// Build an `ifreq` struct to send to the kernel
|
||||||
|
let mut ifr = ifreq {
|
||||||
|
ifr_name: dev_cstr,
|
||||||
|
ifr_ifru: __c_anonymous_ifr_ifru {
|
||||||
|
ifru_flags: (IFF_TUN | IFF_NO_PI) as i16,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make an ioctl call to create the TUN device
|
||||||
|
log::trace!("Calling ioctl to create TUN device");
|
||||||
|
let err = unsafe {
|
||||||
|
ioctl(
|
||||||
|
fd.as_raw_fd(),
|
||||||
|
iow!('T', 202, size_of::<usize>()) as u64,
|
||||||
|
&mut ifr,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
log::trace!("ioctl returned: {}", err);
|
||||||
|
|
||||||
|
// Check for errors
|
||||||
|
if err < 0 {
|
||||||
|
log::error!("ioctl failed: {}", err);
|
||||||
|
return Err(std::io::Error::last_os_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the name of the device
|
||||||
|
let name = unsafe { std::ffi::CStr::from_ptr(ifr.ifr_name.as_ptr()) }
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
// Create an rtnetlink connection
|
||||||
|
let (rt_connection, rt_handle, _) = rtnetlink::new_connection().map_err(|err| {
|
||||||
|
log::error!("Failed to open rtnetlink connection");
|
||||||
|
log::error!("{}", err);
|
||||||
|
err
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Build the TUN struct
|
||||||
|
Ok(Self {
|
||||||
|
fd,
|
||||||
|
name,
|
||||||
|
rt_connection_future: Box::new(rt_connection),
|
||||||
|
rt_handle,
|
||||||
|
link_index: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the name of the TUN device
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRawFd for Tun {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.fd.as_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoRawFd for Tun {
|
||||||
|
fn into_raw_fd(self) -> RawFd {
|
||||||
|
self.fd.into_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
56
protomask/Cargo.toml
Normal file
56
protomask/Cargo.toml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
[package]
|
||||||
|
name = "protomask"
|
||||||
|
version = "0.2.0"
|
||||||
|
authors = ["Evan Pratten <ewpratten@gmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
description = "A user space NAT64 implementation"
|
||||||
|
readme = "README.md"
|
||||||
|
homepage = "https://github.com/ewpratten/protomask"
|
||||||
|
documentation = "https://docs.rs/protomask"
|
||||||
|
repository = "https://github.com/ewpratten/protomask"
|
||||||
|
license = "GPL-3.0"
|
||||||
|
keywords = []
|
||||||
|
categories = []
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[dependencies]
|
||||||
|
protomask-tun = { path = "protomask-tun", version = "0.1.0" }
|
||||||
|
tokio = { version = "1.29.1", features = [
|
||||||
|
"macros",
|
||||||
|
"rt-multi-thread",
|
||||||
|
# "process",
|
||||||
|
"sync"
|
||||||
|
] }
|
||||||
|
clap = { version = "4.3.11", features = ["derive"] }
|
||||||
|
serde = { version = "1.0.171", features = ["derive"] }
|
||||||
|
ipnet = { version = "2.8.0", features = ["serde"] }
|
||||||
|
hyper = { version = "0.14.27", features = ["server", "http1", "tcp"] }
|
||||||
|
owo-colors = { version = "3.5.0", features = ["supports-colors"] }
|
||||||
|
toml = "0.7.6"
|
||||||
|
log = "0.4.19"
|
||||||
|
fern = "0.6.2"
|
||||||
|
serde_path_to_error = "0.1.13"
|
||||||
|
thiserror = "1.0.43"
|
||||||
|
tun-tap = "0.1.3"
|
||||||
|
bimap = "0.6.3"
|
||||||
|
pnet_packet = "0.34.0"
|
||||||
|
rtnetlink = "0.13.0"
|
||||||
|
futures = "0.3.28"
|
||||||
|
prometheus = "0.13.3"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "protomask"
|
||||||
|
path = "src/cli/main.rs"
|
||||||
|
|
||||||
|
[package.metadata.deb]
|
||||||
|
section = "network"
|
||||||
|
assets = [
|
||||||
|
["target/release/protomask", "/usr/local/bin/protomask", "755"],
|
||||||
|
["./protomask.toml", "/etc/protomask.toml", "644"],
|
||||||
|
["README.md", "usr/share/doc/protomask/README.md", "644"]
|
||||||
|
]
|
||||||
|
conf-files = ["/etc/protomask.toml"]
|
||||||
|
depends = []
|
||||||
|
maintainer-scripts = "./debian/"
|
||||||
|
systemd-units = { enable = false }
|
Loading…
x
Reference in New Issue
Block a user