Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/default_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fn main() {
println!("Default Gateway: (Not found)");
}
println!("DNS Servers: {:?}", interface.dns_servers);
println!("MTU: {:?}", interface.mtu);
println!("Default: {}", interface.default);
}
Err(e) => {
Expand Down
1 change: 1 addition & 0 deletions examples/list_interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ fn main() {
println!("Gateway: (Not found)");
}
println!("DNS Servers: {:?}", interface.dns_servers);
println!("MTU: {:?}", interface.mtu);
println!("Default: {}", interface.default);
println!();
}
Expand Down
1 change: 1 addition & 0 deletions src/interface/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub mod netlink {
receive_speed: None,
gateway: None,
dns_servers: Vec::new(),
mtu: None,
default: false,
};

Expand Down
3 changes: 3 additions & 0 deletions src/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ pub struct Interface {
pub gateway: Option<NetworkDevice>,
/// DNS server addresses for the network interface
pub dns_servers: Vec<IpAddr>,
/// Maximum Transmission Unit (MTU) for the network interface
pub mtu: Option<u32>,
/// Whether this is the default interface for accessing the Internet.
pub default: bool,
}
Expand Down Expand Up @@ -145,6 +147,7 @@ impl Interface {
receive_speed: None,
gateway: None,
dns_servers: Vec::new(),
mtu: None,
default: false,
}
}
Expand Down
73 changes: 73 additions & 0 deletions src/interface/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,78 @@ pub fn is_physical_interface(interface: &Interface) -> bool {
|| (!interface.is_loopback() && !linux::is_virtual_interface(&interface.name))
}

#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd"
))]
fn get_mtu(ifa: &libc::ifaddrs, _name: &str) -> Option<u32> {
if !ifa.ifa_data.is_null() {
let data = unsafe { &*(ifa.ifa_data as *mut libc::if_data) };
Some(data.ifi_mtu as u32)
} else {
None
}
}

#[cfg(any(target_os = "linux", target_os = "android"))]
fn get_mtu(_ifa: &libc::ifaddrs, name: &str) -> Option<u32> {
use libc::{c_char, c_int, close, ifreq, ioctl, socket, AF_INET, SIOCGIFMTU, SOCK_DGRAM};
use std::os::unix::io::RawFd;
use std::ptr;

// Create a socket for ioctl operations
let sock: RawFd = unsafe { socket(AF_INET, SOCK_DGRAM, 0) };
if sock < 0 {
eprintln!(
"Failed to create socket: {:?}",
std::io::Error::last_os_error()
);
return None;
}

let mut ifr: ifreq = unsafe { mem::zeroed() };

// Set the interface name (must not exceed `IFNAMSIZ`)
let c_interface = CString::new(name).ok()?;
// Ensure null termination
let bytes = c_interface.to_bytes_with_nul();
if bytes.len() > ifr.ifr_name.len() {
eprintln!("Interface name too long: {}", name);
unsafe { close(sock) };
return None;
}

unsafe {
ptr::copy_nonoverlapping(
bytes.as_ptr() as *const c_char,
ifr.ifr_name.as_mut_ptr(),
bytes.len(),
);
}

// Retrieve the MTU using ioctl
let ret: c_int = unsafe { ioctl(sock, SIOCGIFMTU as _, &mut ifr) };
if ret < 0 {
eprintln!(
"ioctl(SIOCGIFMTU) failed for {}: {:?}",
name,
std::io::Error::last_os_error()
);
unsafe { close(sock) };
return None;
}

let mtu = unsafe { ifr.ifr_ifru.ifru_mtu } as u32;

// Close the socket
unsafe { close(sock) };

Some(mtu)
}

#[cfg(target_os = "android")]
pub fn unix_interfaces() -> Vec<Interface> {
use super::android;
Expand Down Expand Up @@ -387,6 +459,7 @@ fn unix_interfaces_inner(
receive_speed: None,
gateway: None,
dns_servers: Vec::new(),
mtu: get_mtu(addr_ref, &name),
default: false,
};
ifaces.push(interface);
Expand Down
1 change: 1 addition & 0 deletions src/interface/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ pub fn interfaces() -> Vec<Interface> {
Some(default_gateway)
},
dns_servers,
mtu: Some(cur.Mtu),
default,
};
Some(interface)
Expand Down