@@ -5,7 +5,8 @@ extern crate num_derive;
5
5
6
6
use num_traits:: FromPrimitive ;
7
7
8
- use std:: { error:: Error , fmt:: Display , net:: UdpSocket } ;
8
+ use spin:: Once ;
9
+ use std:: { error:: Error , fmt:: Display , io, net:: UdpSocket } ;
9
10
10
11
use byteorder:: { ByteOrder , NetworkEndian } ;
11
12
use simple_endian:: BigEndian ;
@@ -33,9 +34,6 @@ impl Display for Ipv4Addr {
33
34
}
34
35
}
35
36
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 ] ;
39
37
const DHCP_XID : u32 = 0x43424140 ;
40
38
41
39
#[ derive( Debug , Copy , Clone , PartialEq ) ]
@@ -74,7 +72,7 @@ struct Header {
74
72
impl Header {
75
73
fn new ( htype : HType ) -> Self {
76
74
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 ( ) ) ;
78
76
79
77
Self {
80
78
htype,
@@ -328,7 +326,7 @@ impl<'a> OptionsWriter<'a> {
328
326
fn set_client_identifier ( mut self ) -> Self {
329
327
let mut data = [ 0 ; 7 ] ;
330
328
data[ 0 ] = HType :: Ethernet as u8 ;
331
- data[ 1 ..] . copy_from_slice ( MAC_ADDRESS ) ;
329
+ data[ 1 ..] . copy_from_slice ( get_macaddress ( ) ) ;
332
330
333
331
self . insert ( OptionKind :: ClientIdentifier , data. as_slice ( ) ) ;
334
332
self
@@ -352,6 +350,29 @@ impl<'a> Drop for OptionsWriter<'a> {
352
350
}
353
351
}
354
352
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
+
355
376
pub fn main ( ) -> Result < ( ) , Box < dyn Error > > {
356
377
let socket = UdpSocket :: bind ( ( "0.0.0.0" , 68 ) ) ?;
357
378
socket. connect ( ( "255.255.255.255" , 67 ) ) ?;
0 commit comments