mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-05-14 09:33:43 +02:00
Add IPv6 setup stuff to mac_feth_tap.
This commit is contained in:
parent
f63f04737b
commit
fd6cf33e97
2 changed files with 46 additions and 15 deletions
|
@ -41,13 +41,3 @@ target_include_directories(
|
||||||
PUBLIC
|
PUBLIC
|
||||||
${CMAKE_BINARY_DIR}/core
|
${CMAKE_BINARY_DIR}/core
|
||||||
)
|
)
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
add_executable(MacEthernetTapAgent MacEthernetTapAgent.c MacEthernetTapAgent.h)
|
|
||||||
target_include_directories(MacEthernetTapAgent PRIVATE ${CMAKE_BINARY_DIR})
|
|
||||||
target_include_directories(
|
|
||||||
MacEthernetTapAgent
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_BINARY_DIR}/core
|
|
||||||
)
|
|
||||||
endif(APPLE)
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This creates a pair of feth devices with the lower numbered device
|
* This creates a pair of feth devices with the lower numbered device
|
||||||
* being the ZeroTier virtual interface and the other being the device
|
* being the ZeroTier virtual interface and the higher being the device
|
||||||
* used to actually read and write packets. The latter gets no IP config
|
* used to actually read and write packets. The latter gets no IP config
|
||||||
* and is only used for I/O. The behavior of feth is similar to the
|
* and is only used for I/O. The behavior of feth is similar to the
|
||||||
* veth pairs that exist on Linux.
|
* veth pairs that exist on Linux.
|
||||||
|
@ -16,9 +16,10 @@
|
||||||
* is limited to 2048. AF_NDRV packet injection is required to inject
|
* is limited to 2048. AF_NDRV packet injection is required to inject
|
||||||
* ZeroTier's large MTU frames.
|
* ZeroTier's large MTU frames.
|
||||||
*
|
*
|
||||||
* All this stuff is completely undocumented. A lot of tracing through
|
* This is all completely undocumented. Finding it and learning how to
|
||||||
* the Darwin/XNU kernel source was required to find feth in the first place
|
* use it required sifting through XNU/Darwin kernel source code on
|
||||||
* and figure out how to make this work.
|
* opensource.apple.com. Needless to say we are exploring other options
|
||||||
|
* for future releases, but this works for now.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
@ -26,7 +27,7 @@ use std::collections::BTreeSet;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr::{null_mut, copy_nonoverlapping};
|
use std::ptr::{null_mut, copy_nonoverlapping};
|
||||||
use std::mem::transmute;
|
use std::mem::{transmute, zeroed};
|
||||||
use std::os::raw::{c_int, c_uchar, c_ulong, c_void};
|
use std::os::raw::{c_int, c_uchar, c_ulong, c_void};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
@ -88,6 +89,45 @@ lazy_static! {
|
||||||
static ref MAC_FETH_BPF_DEVICES_USED: Mutex<BTreeSet<u32>> = Mutex::new(BTreeSet::new());
|
static ref MAC_FETH_BPF_DEVICES_USED: Mutex<BTreeSet<u32>> = Mutex::new(BTreeSet::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn device_ipv6_set_params(device: &String, perform_nud: bool, accept_ra: bool) -> bool {
|
||||||
|
let dev = device.as_bytes();
|
||||||
|
let mut ok = true;
|
||||||
|
unsafe {
|
||||||
|
|
||||||
|
let s = osdep::socket(osdep::AF_INET6 as c_int, osdep::SOCK_DGRAM as c_int, 0);
|
||||||
|
if s < 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut nd: osdep::in6_ndireq = zeroed();
|
||||||
|
copy_nonoverlapping(dev.as_ptr(), nd.ifname.as_mut_ptr().cast::<u8>(), if dev.len() > (nd.ifname.len() - 1) { nd.ifname.len() - 1 } else { dev.len() });
|
||||||
|
if osdep::ioctl(s, osdep::c_SIOCGIFINFO_IN6, (&nd as *mut osdep::in6_ndireq).cast()) == 0 {
|
||||||
|
let oldflags = nd.ndi.flags;
|
||||||
|
if perform_nud {
|
||||||
|
nd.ndi.flags |= osdep::ND6_IFF_PERFORMNUD as osdep::u_int32_t;
|
||||||
|
} else {
|
||||||
|
nd.ndi.flags &= !(osdep::ND6_IFF_PERFORMNUD as osdep::u_int32_t);
|
||||||
|
}
|
||||||
|
if nd.ndi.flags != oldflags {
|
||||||
|
if osdep::ioctl(s, osdep::c_SIOCSIFINFO_FLAGS, (&nd as *mut osdep::in6_ndireq).cast()) != 0 {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ifr: osdep::in6_ifreq = zeroed();
|
||||||
|
copy_nonoverlapping(dev.as_ptr(), ifr.ifr_name.as_mut_ptr().cast::<u8>(), if dev.len() > (ifr.ifr_name.len() - 1) { ifr.ifr_name.len() - 1 } else { dev.len() });
|
||||||
|
if osdep::ioctl(s, if accept_ra { osdep::c_SIOCAUTOCONF_START } else { osdep::c_SIOCAUTOCONF_STOP }, (&ifr as *mut osdep::in6_ifreq).cast()) != 0 {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
osdep::close(s);
|
||||||
|
}
|
||||||
|
ok
|
||||||
|
}
|
||||||
|
|
||||||
impl MacFethTap {
|
impl MacFethTap {
|
||||||
/// Create a new MacFethTap with a function to call for Ethernet frames.
|
/// Create a new MacFethTap with a function to call for Ethernet frames.
|
||||||
/// The function F should return as quickly as possible. It should pass copies
|
/// The function F should return as quickly as possible. It should pass copies
|
||||||
|
@ -129,6 +169,7 @@ impl MacFethTap {
|
||||||
}
|
}
|
||||||
device_feth_ctr += 1;
|
device_feth_ctr += 1;
|
||||||
}
|
}
|
||||||
|
device_ipv6_set_params(&device_name, true, false);
|
||||||
|
|
||||||
let cmd = Command::new(IFCONFIG).arg(&device_name).arg("create").spawn();
|
let cmd = Command::new(IFCONFIG).arg(&device_name).arg("create").spawn();
|
||||||
if cmd.is_err() {
|
if cmd.is_err() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue