diff options
| author | diogo464 <[email protected]> | 2025-10-08 18:07:45 +0100 |
|---|---|---|
| committer | diogo464 <[email protected]> | 2025-10-08 18:07:45 +0100 |
| commit | 7a52879e0db0e4fb311ec840938c5fc4e5775afc (patch) | |
| tree | 80e1ef5630ce33f99638fdec6dee274c41609f34 /src | |
| parent | 8af019b563870c5f5441da299c1d226f87f2fcdb (diff) | |
added list_network_interfaces function
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 56 |
1 files changed, 56 insertions, 0 deletions
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; | |||
| 6 | use std::io::{BufRead, Cursor, Read, Result, Write}; | 6 | use std::io::{BufRead, Cursor, Read, Result, Write}; |
| 7 | use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket}; | 7 | use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket}; |
| 8 | 8 | ||
| 9 | use ipnet::Ipv4Net; | ||
| 10 | |||
| 9 | const FLAG_BROADCAST: u16 = 1 << 15; | 11 | const FLAG_BROADCAST: u16 = 1 << 15; |
| 10 | 12 | ||
| 11 | const OPTION_CODE_PAD: u8 = 0; | 13 | const OPTION_CODE_PAD: u8 = 0; |
| @@ -347,6 +349,60 @@ fn write_boot_ack(xid: u32, chaddr: [u8; 16], client_uuid: Option<Vec<u8>>) -> R | |||
| 347 | Ok(writer) | 349 | Ok(writer) |
| 348 | } | 350 | } |
| 349 | 351 | ||
| 352 | #[derive(Debug, Clone)] | ||
| 353 | struct InterfaceAddr { | ||
| 354 | interface: String, | ||
| 355 | address: Ipv4Addr, | ||
| 356 | network: Ipv4Net, | ||
| 357 | } | ||
| 358 | |||
| 359 | fn list_network_interfaces() -> Result<Vec<InterfaceAddr>> { | ||
| 360 | unsafe { | ||
| 361 | let mut ifap: *mut libc::ifaddrs = std::ptr::null_mut(); | ||
| 362 | |||
| 363 | if libc::getifaddrs(&mut ifap) != 0 { | ||
| 364 | return Err(std::io::Error::last_os_error()); | ||
| 365 | } | ||
| 366 | |||
| 367 | let mut interfaces = Vec::new(); | ||
| 368 | let mut current = ifap; | ||
| 369 | |||
| 370 | while !current.is_null() { | ||
| 371 | let ifa = &*current; | ||
| 372 | |||
| 373 | if !ifa.ifa_addr.is_null() { | ||
| 374 | let addr_family = (*ifa.ifa_addr).sa_family; | ||
| 375 | let name = std::ffi::CStr::from_ptr(ifa.ifa_name) | ||
| 376 | .to_string_lossy() | ||
| 377 | .into_owned(); | ||
| 378 | |||
| 379 | match addr_family as i32 { | ||
| 380 | libc::AF_INET => { | ||
| 381 | let addr = ifa.ifa_addr as *const libc::sockaddr_in; | ||
| 382 | let mask = ifa.ifa_netmask as *const libc::sockaddr_in; | ||
| 383 | |||
| 384 | let addr = Ipv4Addr::from((*addr).sin_addr.s_addr.to_ne_bytes()); | ||
| 385 | let mask = Ipv4Addr::from((*mask).sin_addr.s_addr.to_ne_bytes()); | ||
| 386 | let network = Ipv4Net::with_netmask(addr, mask).unwrap().trunc(); | ||
| 387 | |||
| 388 | interfaces.push(InterfaceAddr { | ||
| 389 | interface: name, | ||
| 390 | address: addr, | ||
| 391 | network, | ||
| 392 | }); | ||
| 393 | } | ||
| 394 | _ => {} | ||
| 395 | } | ||
| 396 | } | ||
| 397 | |||
| 398 | current = ifa.ifa_next; | ||
| 399 | } | ||
| 400 | |||
| 401 | libc::freeifaddrs(ifap); | ||
| 402 | Ok(interfaces) | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 350 | fn main() { | 406 | fn main() { |
| 351 | let socket67 = UdpSocket::bind("0.0.0.0:67").unwrap(); | 407 | let socket67 = UdpSocket::bind("0.0.0.0:67").unwrap(); |
| 352 | socket67.set_broadcast(true).unwrap(); | 408 | socket67.set_broadcast(true).unwrap(); |
