Skip to content

Commit

Permalink
impl ipv6 linux
Browse files Browse the repository at this point in the history
  • Loading branch information
JosiasAurel committed Feb 24, 2024
1 parent 29d2bfa commit 26ebc51
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 9 deletions.
19 changes: 12 additions & 7 deletions tun/src/unix/apple/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use std::{io::{Error, IoSlice}, mem, net::{Ipv4Addr, SocketAddrV4}, os::fd::{AsRawFd, FromRawFd, RawFd}, ptr};
use std::net::{IpAddr, Ipv6Addr, SocketAddrV6};
use std::ptr::addr_of;
use std::{
io::{Error, IoSlice},
mem,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6},
os::fd::{AsRawFd, FromRawFd, RawFd},
ptr,
ptr::addr_of,
};

use byteorder::{ByteOrder, NetworkEndian};
use fehler::throws;
use libc::{c_char, iovec, writev, AF_INET, AF_INET6, sockaddr_in6};
use libc::{c_char, iovec, sockaddr_in6, writev, AF_INET, AF_INET6};
use nix::sys::socket::SockaddrIn6;
use socket2::{Domain, SockAddr, Socket, Type};
use tracing::{self, instrument};
Expand Down Expand Up @@ -69,11 +74,11 @@ impl TunInterface {

#[throws]
fn configure(&self, options: TunOptions) {
for addr in options.address{
for addr in options.address {
if let Ok(addr) = addr.parse::<IpAddr>() {
match addr {
IpAddr::V4(addr) => {self.set_ipv4_addr(addr)?}
IpAddr::V6(addr) => {self.set_ipv6_addr(addr)?}
IpAddr::V4(addr) => self.set_ipv4_addr(addr)?,
IpAddr::V6(addr) => self.set_ipv6_addr(addr)?,
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions tun/src/unix/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,25 @@ impl TunInterface {
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]
#[instrument]
pub fn set_broadcast_addr(&self, addr: Ipv4Addr) {
Expand Down
46 changes: 46 additions & 0 deletions tun/src/unix/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use std::{
ffi::CStr,
io::Error,
mem,
mem::MaybeUninit,
net::{IpAddr, SocketAddr},
os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd},
};

use tracing::instrument;

use crate::syscall;

mod queue;

#[cfg(target_vendor = "apple")]
Expand Down Expand Up @@ -60,6 +65,47 @@ impl TunInterface {
pub fn set_nonblocking(&mut self, nb: bool) {
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]
Expand Down
4 changes: 2 additions & 2 deletions tun/tests/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ fn test_set_get_ipv6() {
let addr = Ipv6Addr::new(1, 1, 1, 1, 1, 1, 1, 1);
tun.set_ipv6_addr(addr)?;

// let result = tun.ipv6_addr()?;
// assert_eq!(addr, result);
let result = tun.ipv6_addr()?;
assert_eq!(addr, result);
}

#[test]
Expand Down

0 comments on commit 26ebc51

Please sign in to comment.