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 --- Cargo.lock | 16 ++++++++++++++++ Cargo.toml | 2 ++ src/main.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 5a09a45..e27c7d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,22 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "libc" +version = "0.2.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" + [[package]] name = "netiso" version = "0.1.0" +dependencies = [ + "ipnet", + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index b0abcfb..9a079c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] +ipnet = "2.11.0" +libc = "0.2.176" 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