Ethernet, MAC addresses and switches

Inside a home, office or university building, computers are joined by Ethernet cables or Wi-Fi into a local area network (LAN). The link layer moves frames from one device to the next one on the same network.

MAC addresses

Every network card has a 48-bit MAC address, written as six hex pairs such as 3c:22:fb:91:0a:7e. It is set by the maker and names the card, not its location. ff:ff:ff:ff:ff:ff is the broadcast address: a frame sent to it reaches every device on the LAN.

An Ethernet frame holds the destination MAC, the source MAC, a type (for example "IPv4 inside"), the data (46 to 1500 bytes) and a CRC-32 (see the previous lesson).

Switches learn by themselves

A switch joins many devices. It keeps a table: MAC address → port. Nobody fills this table in. For every frame that arrives:

  1. Learn: the frame's source address is reachable through the port it came in on.
  2. Forward: if the destination is in the table, send the frame out of that one port.
  3. Flood: if not (or it is a broadcast), send it out of every port except the one it came from.
table = {}                       # MAC address -> port
frames = [("A", "B", 1), ("B", "A", 2), ("C", "A", 3), ("A", "C", 1), ("B", "ff", 2)]

for src, dst, port in frames:
    table[src] = port            # learn where the sender is
    if dst in table and dst != "ff":
        print(src, "->", dst, ": forward out of port", table[dst])
    else:
        print(src, "->", dst, ": flood out of every port but", port)
print("table:", table)
Open in compiler

After a few frames, almost nothing is flooded. An old hub repeated every frame to every port, so all devices shared one link and their frames could collide; a switch gives each port its own.

ARP: from an IP address to a MAC address

Programs use IP addresses, but a frame needs a MAC address. ARP (Address Resolution Protocol) asks the whole LAN: "Who has 192.168.1.1? Tell 192.168.1.10." The owner answers with its MAC address, and the asker keeps the answer in its ARP cache for a few minutes.

lan = {"192.168.1.1": "aa:aa:aa:00:00:01", "192.168.1.20": "aa:aa:aa:00:00:20"}
cache = {}

def mac_for(ip):
    if ip in cache:
        return cache[ip] + " (from the cache)"
    print("broadcast: who has", ip, "?")
    if ip not in lan:
        return "no answer"
    cache[ip] = lan[ip]          # the owner replies; remember it
    return cache[ip]

print(mac_for("192.168.1.1"))
print(mac_for("192.168.1.1"))
print(mac_for("192.168.1.99"))
Open in compiler

To reach a computer on another network, your computer does not ARP for it: it sends the frame to the MAC address of its default gateway (the router), which passes the packet on.

Common mistakes

  • Thinking MAC addresses are used across the internet. They only matter on one link; routers replace the MAC addresses at every hop, while the IP addresses stay the same.
  • Thinking a switch learns from destination addresses. It learns only from source addresses.
  • Mixing up the broadcast MAC address ff:ff:ff:ff:ff:ff with an IP broadcast address.

Quick check

1. How long is a MAC address?
2. A switch has no entry for a frame's destination. What does it do?
3. What does ARP find?
4. Which address does a switch learn from each frame?
My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.