liveBook · Manning

Mac address

As explained in Rust in Action: Systems programming concepts and techniques

A MAC address is a link-layer identifier assigned to a network interface for communication on a local physical or wireless link.

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

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Explains byte width, administration forms, transmission modes, and flag bits, then implements generation without detailing complete Ethernet frame processing.
Examples
Uses address-layout figures, unicast and multicast comparisons, and a Rust macgen program for virtual hardware.
What it assumes
Assumes basic networking context while introducing the distinction between IP addresses, MAC addresses, physical links, wireless links, and frames.
What you can do after
Build it from scratch in Rust using random bytes, six-byte storage, hexadecimal formatting, and local-unicast flag assignment.
How it connects
Connects MAC addresses with IP addresses, Ethernet, IPv4, IPv6, LANs, WiFi, Bluetooth, frames, and raw TCP.

Also explained in

Compare how 2 books explain mac address →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.