Compare commits
4 commits
abf1101484
...
2f0e41bb92
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f0e41bb92 | ||
|
|
4fe62c0a66 | ||
|
|
e8d19986bc | ||
|
|
807dffa3be |
5 changed files with 84 additions and 12 deletions
|
|
@ -1,13 +1,11 @@
|
||||||
use std::{
|
use std::{io::{Error, IoSlice}, mem, net::{Ipv4Addr, SocketAddrV4}, os::fd::{AsRawFd, FromRawFd, RawFd}, ptr};
|
||||||
io::{Error, IoSlice},
|
use std::net::{IpAddr, Ipv6Addr, SocketAddrV6};
|
||||||
mem,
|
use std::ptr::addr_of;
|
||||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4},
|
|
||||||
os::fd::{AsRawFd, FromRawFd, RawFd},
|
|
||||||
};
|
|
||||||
|
|
||||||
use byteorder::{ByteOrder, NetworkEndian};
|
use byteorder::{ByteOrder, NetworkEndian};
|
||||||
use fehler::throws;
|
use fehler::throws;
|
||||||
use libc::{c_char, iovec, writev, AF_INET, AF_INET6};
|
use libc::{c_char, iovec, sockaddr_in6, writev, AF_INET, AF_INET6};
|
||||||
|
use nix::sys::socket::SockaddrIn6;
|
||||||
use socket2::{Domain, SockAddr, Socket, Type};
|
use socket2::{Domain, SockAddr, Socket, Type};
|
||||||
use tracing::{self, instrument};
|
use tracing::{self, instrument};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::{
|
||||||
fs::OpenOptions,
|
fs::OpenOptions,
|
||||||
io::{Error, Write},
|
io::{Error, Write},
|
||||||
mem,
|
mem,
|
||||||
net::{Ipv4Addr, Ipv6Addr, SocketAddrV4},
|
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4},
|
||||||
os::{
|
os::{
|
||||||
fd::RawFd,
|
fd::RawFd,
|
||||||
unix::io::{AsRawFd, FromRawFd, IntoRawFd},
|
unix::io::{AsRawFd, FromRawFd, IntoRawFd},
|
||||||
|
|
@ -15,7 +15,7 @@ use socket2::{Domain, SockAddr, Socket, Type};
|
||||||
use tracing::{info, instrument};
|
use tracing::{info, instrument};
|
||||||
|
|
||||||
use super::{ifname_to_string, string_to_ifname};
|
use super::{ifname_to_string, string_to_ifname};
|
||||||
use crate::TunOptions;
|
use crate::{syscall, TunOptions};
|
||||||
|
|
||||||
mod sys;
|
mod sys;
|
||||||
|
|
||||||
|
|
@ -114,6 +114,25 @@ impl TunInterface {
|
||||||
Ipv4Addr::from(u32::from_be(addr.sin_addr.s_addr))
|
Ipv4Addr::from(u32::from_be(addr.sin_addr.s_addr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[throws]
|
||||||
|
#[instrument]
|
||||||
|
pub fn ipv6_addrs(&self) -> Vec<Ipv6Addr> {
|
||||||
|
let ip_addrs = self.ip_addrs()?;
|
||||||
|
let mut ipv6_addrs: Vec<Ipv6Addr> = vec![];
|
||||||
|
|
||||||
|
for ip_addr in ip_addrs.iter() {
|
||||||
|
if ip_addr.is_ipv6() {
|
||||||
|
match ip_addr {
|
||||||
|
IpAddr::V6(addr) => {
|
||||||
|
ipv6_addrs.push(*addr);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ipv6_addrs
|
||||||
|
}
|
||||||
|
|
||||||
#[throws]
|
#[throws]
|
||||||
#[instrument]
|
#[instrument]
|
||||||
pub fn set_broadcast_addr(&self, addr: Ipv4Addr) {
|
pub fn set_broadcast_addr(&self, addr: Ipv4Addr) {
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,13 @@ ioctl_write_ptr_bad!(if_set_addr6, libc::SIOCSIFADDR, libc::in6_ifreq);
|
||||||
ioctl_write_ptr_bad!(if_set_brdaddr, libc::SIOCSIFBRDADDR, libc::ifreq);
|
ioctl_write_ptr_bad!(if_set_brdaddr, libc::SIOCSIFBRDADDR, libc::ifreq);
|
||||||
ioctl_write_ptr_bad!(if_set_mtu, libc::SIOCSIFMTU, libc::ifreq);
|
ioctl_write_ptr_bad!(if_set_mtu, libc::SIOCSIFMTU, libc::ifreq);
|
||||||
ioctl_write_ptr_bad!(if_set_netmask, libc::SIOCSIFNETMASK, libc::ifreq);
|
ioctl_write_ptr_bad!(if_set_netmask, libc::SIOCSIFNETMASK, libc::ifreq);
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! syscall {
|
||||||
|
($call: ident ( $($arg: expr),* $(,)* ) ) => {{
|
||||||
|
match unsafe { ::libc::$call($($arg, )*) } {
|
||||||
|
-1 => Err(::std::io::Error::last_os_error()),
|
||||||
|
res => Ok(res),
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
ffi::CStr,
|
||||||
io::Error,
|
io::Error,
|
||||||
|
mem,
|
||||||
mem::MaybeUninit,
|
mem::MaybeUninit,
|
||||||
|
net::{IpAddr, SocketAddr},
|
||||||
os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd},
|
os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd},
|
||||||
};
|
};
|
||||||
|
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
use crate::syscall;
|
||||||
|
|
||||||
mod queue;
|
mod queue;
|
||||||
|
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
|
|
@ -60,6 +65,47 @@ impl TunInterface {
|
||||||
pub fn set_nonblocking(&mut self, nb: bool) {
|
pub fn set_nonblocking(&mut self, nb: bool) {
|
||||||
self.socket.set_nonblocking(nb)?;
|
self.socket.set_nonblocking(nb)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[throws]
|
||||||
|
#[instrument]
|
||||||
|
pub fn ip_addrs(&self) -> Vec<IpAddr> {
|
||||||
|
let mut result: Vec<IpAddr> = vec![];
|
||||||
|
let mut addrs: *mut libc::ifaddrs = std::ptr::null_mut();
|
||||||
|
let if_name = self.name()?;
|
||||||
|
syscall!(getifaddrs(&mut addrs as *mut _))?;
|
||||||
|
unsafe {
|
||||||
|
while !addrs.is_null() {
|
||||||
|
let addr = &*addrs;
|
||||||
|
addrs = addr.ifa_next;
|
||||||
|
|
||||||
|
let name = CStr::from_ptr(addr.ifa_name).to_str().unwrap();
|
||||||
|
if if_name != name {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let family = (*addr.ifa_addr).sa_family;
|
||||||
|
let addr_len = match family as i32 {
|
||||||
|
libc::AF_INET => mem::size_of::<libc::sockaddr_in>(),
|
||||||
|
libc::AF_INET6 => mem::size_of::<libc::sockaddr_in6>(),
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (_, sock_addr) = socket2::SockAddr::try_init(|addr_storage, len| {
|
||||||
|
*len = addr_len as u32;
|
||||||
|
std::ptr::copy_nonoverlapping(
|
||||||
|
addr.ifa_addr as *const libc::c_void,
|
||||||
|
addr_storage as *mut _,
|
||||||
|
addr_len,
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(socket_addr) = sock_addr.as_socket() {
|
||||||
|
result.push(socket_addr.ip());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,8 @@ fn test_set_get_ipv6() {
|
||||||
|
|
||||||
let addr = Ipv6Addr::new(1, 1, 1, 1, 1, 1, 1, 1);
|
let addr = Ipv6Addr::new(1, 1, 1, 1, 1, 1, 1, 1);
|
||||||
tun.set_ipv6_addr(addr)?;
|
tun.set_ipv6_addr(addr)?;
|
||||||
|
let result = tun.ipv6_addrs()?[0];
|
||||||
// let result = tun.ipv6_addr()?;
|
assert_eq!(addr, result);
|
||||||
// assert_eq!(addr, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue