A MAC address is a link-layer identifier for a hardware device. Unlike an IP address, it identifies an interface independently of the network and is used by devices sharing a physical or wireless link. section 8.6
A MAC address differs from an IP address in several practical ways:
- MAC addresses are not hierarchical, so numerically nearby addresses need not be physically or organizationally nearby. section 8.6
- A MAC address is 48 bits, or 6 bytes; IPv4 addresses are 32 bits and IPv6 addresses are 128 bits. section 8.6
- Universal addresses are assigned during manufacture, while locally administered addresses can be created by software. section 8.6
- Unicast addresses target direct communication between two points, while multicast addresses affect whether a device accepts a frame. section 8.6
Generating a locally administered unicast address
A Rust program can represent a MAC address as six bytes, fill those bytes with random data, and display them in hexadecimal form separated by colons. Setting the two low-order flag bits in the first byte to 1 marks each generated address as locally assigned and unicast. section 8.6.1
Listing 8.17 Creating macgen, a MAC address generator
1 extern crate rand;
2
3 use rand::RngCore;
4 use std::fmt;
5 use std::fmt::Display;
6
7 #[derive(Debug)]
8 struct MacAddress([u8; 6]); #1
9
10 impl Display for MacAddress {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 let octet = &self.0;
13 write!(
14 f,
15 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", #2
16 octet[0], octet[1], octet[2], #2
17 octet[3], octet[4], octet[5] #2
18 )
19 }
20 }
21
22 impl MacAddress {
23 fn new() -> MacAddress {
24 let mut octets: [u8; 6] = [0; 6];
25 rand::thread_rng().fill_bytes(&mut octets);
26 octets[0] |= 0b_0000_0011; #3
27 MacAddress { 0: octets }
28 }
29
30 fn is_local(&self) -> bool {
31 (self.0[0] & 0b_0000_0010) == 0b_0000_0010
32 }
33
34 fn is_unicast(&self) -> bool {
35 (self.0[0] & 0b_0000_0001) == 0b_0000_0001
36 }
37 }
38
39 fn main() {
40 let mac = MacAddress::new();
41 assert!(mac.is_local());
42 assert!(mac.is_unicast());
43 println!("mac: {}", mac);
44 }
Inspect the complete generator structure: its six-byte representation, display formatting, random-byte generation, and address-construction method. section 8.6.1

