aboutsummaryrefslogtreecommitdiff
path: root/src/tunnel.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tunnel.rs')
-rw-r--r--src/tunnel.rs295
1 files changed, 0 insertions, 295 deletions
diff --git a/src/tunnel.rs b/src/tunnel.rs
deleted file mode 100644
index 74655dd..0000000
--- a/src/tunnel.rs
+++ /dev/null
@@ -1,295 +0,0 @@
-use crate::{Error, Result};
-
-use std::ffi::{c_char, c_int, CString};
-use std::io;
-use std::net::{Ipv4Addr, Ipv6Addr};
-
-use bitfield::bitfield;
-
-const SIOCADDTUNNEL: c_int = 0x89F0 + 1;
-const SIOCDELTUNNEL: c_int = 0x89F0 + 2;
-
-/// A handle to a 6in4 tunnel. The interface is automatically deleted on drop.
-#[derive(Debug)]
-pub struct Sit {
- name: String,
-}
-
-impl Drop for Sit {
- fn drop(&mut self) {
- let _ = self.do_delete();
- }
-}
-
-impl Sit {
- pub fn new(name: String, master: String, laddr: Ipv4Addr, raddr: Ipv4Addr) -> Result<Self> {
- let tnlname = CString::new(&*name)?;
- let ifmaster = CString::new(&*master)?;
- let sit0 = CString::new("sit0")?;
-
- let tnlname_signed = unsafe { &*(tnlname.as_bytes() as *const _ as *const [i8]) };
- let mut tnlname_arr = [0i8; libc::IFNAMSIZ];
- for (&i, o) in tnlname_signed.iter().zip(tnlname_arr.iter_mut()) {
- *o = i;
- }
-
- let sit0_signed = unsafe { &*(sit0.as_bytes() as *const _ as *const [i8]) };
- let mut sit0_arr = [0i8; libc::IFNAMSIZ];
- for (&i, o) in sit0_signed.iter().zip(sit0_arr.iter_mut()) {
- *o = i;
- }
-
- let mut vihl = VerIhl::default();
-
- vihl.set_version(4);
- vihl.set_ihl(5);
-
- let p = IpTunnelParm4 {
- name: tnlname_arr,
- link: unsafe { libc::if_nametoindex(ifmaster.as_ptr()) },
- i_flags: 0,
- o_flags: 0,
- i_key: 0,
- o_key: 0,
- iph: IpHdr4 {
- vihl,
- tos: 0,
- tot_len: 0,
- id: 0,
- frag_off: 0,
- check: 0,
- ttl: 64,
- protocol: libc::IPPROTO_IPV6 as u8,
- saddr: u32::from(laddr).to_be(),
- daddr: u32::from(raddr).to_be(),
- },
- };
-
- if p.link == 0 {
- return Err(Error::LinkNotFound(master));
- }
-
- let ifr = IfReq4 {
- name: sit0_arr,
- ifru_data: &p,
- };
-
- let fd = unsafe { libc::socket(libc::AF_INET, libc::SOCK_DGRAM, libc::IPPROTO_IP) };
- if fd < 0 {
- return Err(io::Error::last_os_error().into());
- }
-
- if unsafe { libc::ioctl(fd, SIOCADDTUNNEL, &ifr) } < 0 {
- return Err(io::Error::last_os_error().into());
- }
-
- // Errors are safe to ignore because they don't affect tunnel creation
- // but do leave the program in an inconsistent state.
- unsafe {
- libc::close(fd);
- }
-
- Ok(Self { name })
- }
-
- fn do_delete(&self) -> Result<()> {
- delete_tunnel(&self.name)
- }
-}
-
-/// A handle to a 4in6 tunnel. The interface is automatically deleted on drop.
-#[derive(Debug)]
-pub struct IpIp6 {
- name: String,
-}
-
-impl Drop for IpIp6 {
- fn drop(&mut self) {
- let _ = self.do_delete();
- }
-}
-
-impl IpIp6 {
- pub fn new(name: String, master: String, laddr: Ipv6Addr, raddr: Ipv6Addr) -> Result<Self> {
- let tnlname = CString::new(&*name)?;
- let ifmaster = CString::new(&*master)?;
- let ip6tnl0 = CString::new("ip6tnl0")?;
-
- let tnlname_signed = unsafe { &*(tnlname.as_bytes() as *const _ as *const [i8]) };
- let mut tnlname_arr = [0i8; libc::IFNAMSIZ];
- for (&i, o) in tnlname_signed.iter().zip(tnlname_arr.iter_mut()) {
- *o = i;
- }
-
- let ip6tnl0_signed = unsafe { &*(ip6tnl0.as_bytes() as *const _ as *const [i8]) };
- let mut ip6tnl0_arr = [0i8; libc::IFNAMSIZ];
- for (&i, o) in ip6tnl0_signed.iter().zip(ip6tnl0_arr.iter_mut()) {
- *o = i;
- }
-
- let p = IpTunnelParm6 {
- name: tnlname_arr,
- link: unsafe { libc::if_nametoindex(ifmaster.as_ptr()) },
- i_flags: 0,
- o_flags: 0,
- i_key: 0,
- o_key: 0,
- iph: IpHdr6 {
- saddr: u128::from(laddr).to_be(),
- daddr: u128::from(raddr).to_be(),
- },
- };
-
- if p.link == 0 {
- return Err(Error::LinkNotFound(master));
- }
-
- let ifr = IfReq6 {
- name: ip6tnl0_arr,
- ifru_data: &p,
- };
-
- let fd = unsafe { libc::socket(libc::AF_INET6, libc::SOCK_DGRAM, libc::IPPROTO_IP) };
- if fd < 0 {
- return Err(io::Error::last_os_error().into());
- }
-
- if unsafe { libc::ioctl(fd, SIOCADDTUNNEL, &ifr) } < 0 {
- return Err(io::Error::last_os_error().into());
- }
-
- // Errors are safe to ignore because they don't affect tunnel creation
- // but do leave the program in an inconsistent state.
- unsafe {
- libc::close(fd);
- }
-
- Ok(Self { name })
- }
-
- fn do_delete(&self) -> Result<()> {
- delete_tunnel(&self.name)
- }
-}
-
-fn delete_tunnel(name: &str) -> Result<()> {
- let tnlname = CString::new(name)?;
-
- let tnlname_signed = unsafe { &*(tnlname.as_bytes() as *const _ as *const [i8]) };
- let mut tnlname_arr = [0i8; libc::IFNAMSIZ];
- for (&i, o) in tnlname_signed.iter().zip(tnlname_arr.iter_mut()) {
- *o = i;
- }
-
- let p = IpTunnelParm4 {
- name: tnlname_arr,
- link: 0,
- i_flags: 0,
- o_flags: 0,
- i_key: 0,
- o_key: 0,
- iph: IpHdr4 {
- vihl: VerIhl::default(),
- tos: 0,
- tot_len: 0,
- id: 0,
- frag_off: 0,
- ttl: 0,
- protocol: 0,
- check: 0,
- saddr: 0,
- daddr: 0,
- },
- };
-
- let ifr = IfReq4 {
- name: tnlname_arr,
- ifru_data: &p,
- };
-
- let fd = unsafe { libc::socket(libc::AF_INET6, libc::SOCK_DGRAM, libc::IPPROTO_IP) };
- if fd < 0 {
- return Err(io::Error::last_os_error().into());
- }
-
- if unsafe { libc::ioctl(fd, SIOCDELTUNNEL, &ifr) } < 0 {
- return Err(io::Error::last_os_error().into());
- }
-
- // Errors are safe to ignore because they don't affect tunnel deletion
- // but do leave the program in an inconsistent state.
- unsafe {
- libc::close(fd);
- }
-
- Ok(())
-}
-
-bitfield! {
- #[derive(Default)]
- struct VerIhl(u8);
- impl Debug;
-
- version, set_version: 7, 4;
- ihl, set_ihl: 3, 0;
-}
-
-#[derive(Debug)]
-#[repr(C)]
-struct IpHdr4 {
- vihl: VerIhl,
- tos: u8,
- tot_len: u16,
- id: u16,
- frag_off: u16,
- ttl: u8,
- protocol: u8,
- check: u16,
- saddr: u32,
- daddr: u32,
-}
-
-#[derive(Debug)]
-#[repr(C)]
-struct IpTunnelParm4 {
- name: [c_char; libc::IFNAMSIZ],
- link: u32,
- i_flags: u16,
- o_flags: u16,
- i_key: u32,
- o_key: u32,
- iph: IpHdr4,
-}
-
-#[derive(Debug)]
-#[repr(C)]
-struct IfReq4 {
- name: [c_char; libc::IFNAMSIZ],
- ifru_data: *const IpTunnelParm4,
-}
-
-#[derive(Debug)]
-#[repr(C)]
-struct IpHdr6 {
- saddr: u128,
- daddr: u128,
-}
-
-#[derive(Debug)]
-#[repr(C)]
-struct IpTunnelParm6 {
- name: [c_char; libc::IFNAMSIZ],
- link: u32,
- i_flags: u16,
- o_flags: u16,
- i_key: u32,
- o_key: u32,
- iph: IpHdr6,
-}
-
-#[derive(Debug)]
-#[repr(C)]
-struct IfReq6 {
- name: [c_char; libc::IFNAMSIZ],
- ifru_data: *const IpTunnelParm6,
-}