Comments (3)
Hey, just wanted to let you guys know that I'm currently working on PR for IPV6 support.
I got it working on Mac, need to work on the other platforms you guys support and make sure the coding style matches. Don't worry about it saying 'broadcast' in the screenshot, IPv6 doesn't support it so I just skip over it.
from rust-tun.
Welcome your PR. Thanks.
from rust-tun.
Sorry for the long response, I ended up going with making a Apple TunnelProvider and using the 'createUDPSession' to connect to my rust socket, but here is what I had:
Since my ipv6 implementation is pretty badly formatted, I'll let the owner make changes to it:
[1] Add 'ifaddr_in6' structures mostly from libc.
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
//! Bindings to internal macOS stuff.
use libc::{c_char, c_uint, ifreq, sockaddr, sockaddr_in6, IFNAMSIZ};
use nix::{ioctl_readwrite, ioctl_write_ptr};
pub const UTUN_CONTROL_NAME: &str = "com.apple.net.utun_control";
pub const IN6_IFF_NODAD: i32 = 0x0020;
pub const IN6_IFF_SECURED: i32 = 0x0400;
#[allow(non_camel_case_types)]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ctl_info {
pub ctl_id: c_uint,
pub ctl_name: [c_char; 96],
}
#[allow(non_camel_case_types)]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ifaliasreq {
pub ifra_name: [c_char; IFNAMSIZ],
pub ifra_addr: sockaddr,
pub ifra_broadaddr: sockaddr,
pub ifra_mask: sockaddr,
}
#[allow(non_camel_case_types)]
#[repr(C)]
pub struct in6_ifaliasreq {
pub ifra_name: [c_char; IFNAMSIZ],
pub ifra_addr: sockaddr_in6,
pub ifra_dstaddr: sockaddr_in6,
pub ifra_prefixmask: sockaddr_in6,
pub ifra_flags: libc::c_int,
pub in6_addrlifetime: libc::in6_addrlifetime,
}
ioctl_readwrite!(ctliocginfo, b'N', 3, ctl_info);
ioctl_write_ptr!(siocsifflags, b'i', 16, ifreq);
ioctl_readwrite!(siocgifflags, b'i', 17, ifreq);
ioctl_write_ptr!(siocsifaddr, b'i', 12, ifreq);
ioctl_readwrite!(siocgifaddr, b'i', 33, ifreq);
ioctl_write_ptr!(siocsifdstaddr, b'i', 14, ifreq);
ioctl_readwrite!(siocgifdstaddr, b'i', 34, ifreq);
ioctl_write_ptr!(siocsifbrdaddr, b'i', 19, ifreq);
ioctl_readwrite!(siocgifbrdaddr, b'i', 35, ifreq);
ioctl_write_ptr!(siocsifnetmask, b'i', 22, ifreq);
ioctl_readwrite!(siocgifnetmask, b'i', 37, ifreq);
ioctl_write_ptr!(siocsifmtu, b'i', 52, ifreq);
ioctl_readwrite!(siocgifmtu, b'i', 51, ifreq);
ioctl_write_ptr!(siocaifaddr, b'i', 26, ifaliasreq);
ioctl_write_ptr!(siocdifaddr, b'i', 25, ifreq);
// basing off: https://opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/netinet6/in6_var.h
ioctl_write_ptr!(siocaifaddr_in6, b'i', 26, in6_ifaliasreq);
ioctl_write_ptr!(siocsifaddr_in6, b'i', 12, libc::in6_ifreq);
ioctl_readwrite!(siocgifaddr_in6, b'i', 33, libc::in6_ifreq);
[2]
In 'set_alias' function is where we set IP address and do pretty much everything for IPV6.
'set_destination' and 'broadaddr' is useless for IPV6 and in Device::new() there needs to be a way to set family dynamically
let ctl = Some(posix::Fd::new(
libc::socket(
/*AF_INET*/ AF_INET6,
SOCK_DGRAM, 0,
),
true,
)?);
fn set_alias(&mut self, addr: IpAddr, broadaddr: IpAddr, mask: IpAddr) -> Result<()> {
let tun_name = self.tun_name.as_ref().ok_or(Error::InvalidConfig)?;
let ctl = self.ctl.as_ref().ok_or(Error::InvalidConfig)?;
match addr {
IpAddr::V4(addr) => unsafe {
let mut req: ifaliasreq = mem::zeroed();
ptr::copy_nonoverlapping(
tun_name.as_ptr() as *const c_char,
req.ifra_name.as_mut_ptr(),
tun_name.len(),
);
req.ifra_addr = sockaddr_union::from((addr, 0)).addr;
req.ifra_broadaddr = sockaddr_union::from((broadaddr, 0)).addr;
req.ifra_mask = sockaddr_union::from((mask, 0)).addr;
if let Err(err) = siocaifaddr(ctl.as_raw_fd(), &req) {
return Err(io::Error::from(err).into());
}
let route = Route {
addr: std::net::IpAddr::V4(addr),
netmask: mask,
dest: broadaddr,
};
if let Err(e) = self.set_route(route) {
log::warn!("{e:?}");
}
Ok(())
},
IpAddr::V6(_addr) => unsafe {
let mut req: in6_ifaliasreq = mem::zeroed();
ptr::copy_nonoverlapping(
tun_name.as_ptr() as *const c_char,
req.ifra_name.as_mut_ptr(),
tun_name.len(),
);
req.ifra_addr = sockaddr_union::from((addr, 0)).addr6;
req.ifra_prefixmask = sockaddr_union::from((mask, 0)).addr6;
req.in6_addrlifetime.ia6t_vltime = 0xffffffff_u32;
req.in6_addrlifetime.ia6t_pltime = 0xffffffff_u32;
// https://opensource.apple.com/source/xnu/xnu-6153.61.1/bsd/netinet6/in6_var.h.auto.html
req.ifra_flags = IN6_IFF_NODAD;
if let Err(err) = siocaifaddr_in6(ctl.as_raw_fd(), &req) {
return Err(io::Error::from(err).into());
}
let route = Route {
addr,
netmask: mask,
dest: broadaddr,
};
if let Err(e) = self.set_route(route) {
log::warn!("{e:?}");
}
Ok(())
},
}
}
from rust-tun.
Related Issues (20)
- Suggestion: Changing the type of mtu from usize to u16 HOT 1
- Replacing `cidr_util` with `ipnet`
- ioctl is marked as "deprecated", should be replaced with nix HOT 1
- Please don't pump minor version with breaking changes. HOT 6
- Routing setup seems broken in macOS and FreeBSD HOT 1
- Win7 error HOT 1
- How to generate GUID (Windows) HOT 1
- Apple(iOS) libc::sockaddr_in does not impl Debug trait
- Request to be a co-contributor and publisher HOT 1
- question on IOS HOT 3
- [Feature Request] Use embedded wintun.dll HOT 22
- Custom loading of wintun.dll should be a feature HOT 5
- Can this crate use a pre-existing TUN interface? HOT 2
- Build failure on FreeBSD HOT 2
- examples: ping-tun HOT 1
- Why windows platform MTU is always 65535? HOT 1
- SetInterfaceDnsSettings was not supported by older version of Windows HOT 4
- Fails to build with [email protected] HOT 1
- v2.0.4 Build Error in openWRT HOT 4
- `AsyncDevice` does not expose `Device` methods HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rust-tun.