aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock16
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs56
3 files changed, 74 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5a09a45..e27c7d7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,5 +3,21 @@
3version = 4 3version = 4
4 4
5[[package]] 5[[package]]
6name = "ipnet"
7version = "2.11.0"
8source = "registry+https://github.com/rust-lang/crates.io-index"
9checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
10
11[[package]]
12name = "libc"
13version = "0.2.176"
14source = "registry+https://github.com/rust-lang/crates.io-index"
15checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
16
17[[package]]
6name = "netiso" 18name = "netiso"
7version = "0.1.0" 19version = "0.1.0"
20dependencies = [
21 "ipnet",
22 "libc",
23]
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"
4edition = "2024" 4edition = "2024"
5 5
6[dependencies] 6[dependencies]
7ipnet = "2.11.0"
8libc = "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;
6use std::io::{BufRead, Cursor, Read, Result, Write}; 6use std::io::{BufRead, Cursor, Read, Result, Write};
7use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket}; 7use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
8 8
9use ipnet::Ipv4Net;
10
9const FLAG_BROADCAST: u16 = 1 << 15; 11const FLAG_BROADCAST: u16 = 1 << 15;
10 12
11const OPTION_CODE_PAD: u8 = 0; 13const 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)]
353struct InterfaceAddr {
354 interface: String,
355 address: Ipv4Addr,
356 network: Ipv4Net,
357}
358
359fn 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
350fn main() { 406fn 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();