Prepare, configure, and manage Firecracker microVMs in seconds!
virtualization
linux
microvm
firecracker
1use rand::Rng;
2
3pub fn generate_unique_mac() -> String {
4 let mut rng = rand::thread_rng();
5
6 // First byte must have the least significant bit set to 0 (unicast)
7 // and the second least significant bit set to 0 (globally unique)
8 let first_byte = (rng.gen::<u8>() & 0xFC) | 0x02; // Set locally administered bit
9
10 // Generate the remaining 5 bytes
11 let mut mac_bytes = [0u8; 6];
12 mac_bytes[0] = first_byte;
13 for i in 1..6 {
14 mac_bytes[i] = rng.gen::<u8>();
15 }
16
17 // Format as a MAC address (XX:XX:XX:XX:XX:XX)
18 format!(
19 "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
20 mac_bytes[0], mac_bytes[1], mac_bytes[2], mac_bytes[3], mac_bytes[4], mac_bytes[5]
21 )
22}
23
24#[cfg(test)]
25mod tests {
26 use super::*;
27
28 #[test]
29 fn test_generate_unique_mac() {
30 let mac1 = generate_unique_mac();
31 let mac2 = generate_unique_mac();
32
33 // Check format (6 pairs of 2 hex digits separated by colons)
34 assert!(mac1.chars().count() == 17);
35 assert!(mac1.split(':').count() == 6);
36
37 // Check that the MAC is locally administered (second bit of first byte is 1)
38 let first_byte = u8::from_str_radix(&mac1[0..2], 16).unwrap();
39 assert_eq!(first_byte & 0x02, 0x02);
40 assert_eq!(first_byte & 0x01, 0x00); // Unicast
41
42 // Check uniqueness
43 assert_ne!(mac1, mac2);
44 }
45}