From 7a52879e0db0e4fb311ec840938c5fc4e5775afc Mon Sep 17 00:00:00 2001 From: diogo464 Date: Wed, 8 Oct 2025 18:07:45 +0100 Subject: added list_network_interfaces function --- src/main.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 07e4eec..321b5ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,8 @@ pub mod wire; use std::io::{BufRead, Cursor, Read, Result, Write}; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket}; +use ipnet::Ipv4Net; + const FLAG_BROADCAST: u16 = 1 << 15; const OPTION_CODE_PAD: u8 = 0; @@ -347,6 +349,60 @@ fn write_boot_ack(xid: u32, chaddr: [u8; 16], client_uuid: Option>) -> R Ok(writer) } +#[derive(Debug, Clone)] +struct InterfaceAddr { + interface: String, + address: Ipv4Addr, + network: Ipv4Net, +} + +fn list_network_interfaces() -> Result> { + unsafe { + let mut ifap: *mut libc::ifaddrs = std::ptr::null_mut(); + + if libc::getifaddrs(&mut ifap) != 0 { + return Err(std::io::Error::last_os_error()); + } + + let mut interfaces = Vec::new(); + let mut current = ifap; + + while !current.is_null() { + let ifa = &*current; + + if !ifa.ifa_addr.is_null() { + let addr_family = (*ifa.ifa_addr).sa_family; + let name = std::ffi::CStr::from_ptr(ifa.ifa_name) + .to_string_lossy() + .into_owned(); + + match addr_family as i32 { + libc::AF_INET => { + let addr = ifa.ifa_addr as *const libc::sockaddr_in; + let mask = ifa.ifa_netmask as *const libc::sockaddr_in; + + let addr = Ipv4Addr::from((*addr).sin_addr.s_addr.to_ne_bytes()); + let mask = Ipv4Addr::from((*mask).sin_addr.s_addr.to_ne_bytes()); + let network = Ipv4Net::with_netmask(addr, mask).unwrap().trunc(); + + interfaces.push(InterfaceAddr { + interface: name, + address: addr, + network, + }); + } + _ => {} + } + } + + current = ifa.ifa_next; + } + + libc::freeifaddrs(ifap); + Ok(interfaces) + } +} + fn main() { let socket67 = UdpSocket::bind("0.0.0.0:67").unwrap(); socket67.set_broadcast(true).unwrap(); -- cgit