8000 dhcpd: retrieve the MAC address using `SIOCGIFHWADDR` ioctl · Andy-Python-Programmer/dhcpd@3e26412 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3e26412

Browse files
dhcpd: retrieve the MAC address using SIOCGIFHWADDR ioctl
Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
1 parent 94aade6 commit 3e26412

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
lines changed

Cargo.lock

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ byteorder = { version = "*", default-features = false }
1010
num-derive = { version = "0.3", default-features = false }
1111
num-traits = { version = "0.2", default-features = false }
1212
libc = "0.2.139"
13+
spin = "*"

src/main.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ extern crate num_derive;
55

66
use num_traits::FromPrimitive;
77

8-
use std::{error::Error, fmt::Display, net::UdpSocket};
8+
use spin::Once;
9+
use std::{error::Error, fmt::Display, io, net::UdpSocket};
910

1011
use byteorder::{ByteOrder, NetworkEndian};
1112
use simple_endian::BigEndian;
@@ -33,9 +34,6 @@ impl Display for Ipv4Addr {
3334
}
3435
}
3536

36-
// FIXME: The MAC address is usually obtained by using getifaddrs() which currently
37-
// is unimplemented in mlibc.
38-
const MAC_ADDRESS: &[u8] = &[52, 54, 0, 12, 34, 56];
3937
const DHCP_XID: u32 = 0x43424140;
4038

4139
#[derive(Debug, Copy, Clone, PartialEq)]
@@ -74,7 +72,7 @@ struct Header {
7472
impl Header {
7573
fn new(htype: HType) -> Self {
7674
let mut client_hw_addr = [0; 16];
77-
client_hw_addr[0..6].copy_from_slice(MAC_ADDRESS);
75+
client_hw_addr[0..6].copy_from_slice(get_macaddress());
7876

7977
Self {
8078
htype,
@@ -328,7 +326,7 @@ impl<'a> OptionsWriter<'a> {
328326
fn set_client_identifier(mut self) -> Self {
329327
let mut data = [0; 7];
330328
data[0] = HType::Ethernet as u8;
331-
data[1..].copy_from_slice(MAC_ADDRESS);
329+
data[1..].copy_from_slice(get_macaddress());
332330

333331
self.insert(OptionKind::ClientIdentifier, data.as_slice());
334332
self
@@ -352,6 +350,29 @@ impl<'a> Drop for OptionsWriter<'a> {
352350
}
353351
}
354352

353+
pub fn cvt(t: i32) -> io::Result<i32> {
354+
if t == -1 {
355+
Err(io::Error::last_os_error())
356+
} else {
357+
Ok(t)
358+
}
359+
}
360+
361+
fn get_macaddress<'a>() -> &'a [u8; 6] {
362+
static CACHED: Once<[u8; 6]> = Once::new();
363+
CACHED
364+
.try_call_once(|| unsafe {
365+
let fd = cvt(libc::socket(libc::AF_INET, libc::SOCK_DGRAM, 0))?;
366+
367+
let mut buffer = [0u8; 6];
368+
cvt(libc::ioctl(fd, libc::SIOCGIFHWADDR, buffer.as_mut_ptr()))?;
369+
370+
Ok::<[u8; 6], io::Error>(buffer)
371+
})
372+
// FIXME: Should we panic here?
373+
.expect("[ DHCPD ] (EE) failed to retrieve the mac address")
374+
}
375+
355376
pub fn main() -> Result<(), Box<dyn Error>> {
356377
let socket = UdpSocket::bind(("0.0.0.0", 68))?;
357378
socket.connect(("255.255.255.255", 67))?;

0 commit comments

Comments
 (0)
0