← networks book ⊞ All topics

Ethernet — Frame Format, MAC Addresses & EtherType

Put several computers on one shared wire and two questions appear immediately: who is this chunk of data for? and where does it start, where does it end, and did it survive the trip? Ethernet — the IEEE 802.3 family — answers both with a 48-bit hardware address and a fixed frame layout, and that answer has survived unchanged from 10 Mbps coaxial cable to 400 Gbps fibre. It is the concrete Layer-2 reality underneath every abstraction about "the link layer", and the source of the one number that keeps reappearing everywhere else in networking: 1500.

Key Components

MAC address
A 48-bit (6-byte) hardware address, normally burned into the network card and written as six hex pairs (a4:5e:60:12:34:56). The first three bytes are the OUI — an Organizationally Unique Identifier that IEEE assigns to a manufacturer — and the last three are the vendor's per-device serial. It is flat (no structure a forwarding device can summarise) and link-local: it identifies a card on one physical network, not a host on the internet.
Frame
The Layer-2 unit of data: a destination MAC, a source MAC, a type field, a payload, and a checksum, delimited on the wire by a fixed preamble. Everything above — IP packets, TCP segments, HTTP requests — travels as the payload of a frame across each individual hop.
EtherType
A 2-byte field naming which protocol is inside the payload. It is a demultiplexing pointer: without it, the receiver would hold 1500 bytes of anonymous data and no idea which stack to hand them to. 0x0800 means IPv4, 0x0806 means ARP, 0x86DD means IPv6.
FCS (Frame Check Sequence)
A 4-byte CRC-32 computed over the frame. The receiver recomputes it and compares. On a mismatch the frame is silently discarded — no error message, no retransmission. The FCS detects corruption; it never fixes it.
MTU (Maximum Transmission Unit)
The largest payload a single frame may carry: 1500 bytes on standard Ethernet. Together with a minimum total frame size of 64 bytes (payload padded to 46 if needed), it sets the size band every higher layer must live inside.

Concrete Example

Here is a complete, real-shaped Ethernet frame as a packet capture would show it — a host at 192.168.1.10 asking the local network who owns 192.168.1.1. Byte offsets are on the left, counted from the start of the frame (the preamble is stripped by the hardware before capture, and the FCS is usually stripped too):

0000  ff ff ff ff ff ff  a4 5e 60 12 34 56  08 06     ← dest MAC | src MAC | EtherType
0010  08 00 06 04 00 01  a4 5e 60 12 34 56  c0 a8 01 0a
0020  00 00 00 00 00 00  c0 a8 01 01  00 00 00 00 00 00
0030  00 00 00 00 00 00  00 00 00 00 00 00

Read the first fourteen bytes and the whole frame decodes itself:

OffsetBytesFieldMeaning
0–5ff ff ff ff ff ffDestination MACAll ones — broadcast. Every device on the local network must process this frame.
6–11a4 5e 60 12 34 56Source MACThe sender's card. a4:5e:60 is the OUI; 12:34:56 is the vendor's device portion.
12–1308 06EtherType0x0806 — the payload is ARP, not IP. Hand it to the ARP module.
14–4128 bytesPayloadThe ARP request itself: opcode 00 01 (request), sender IP c0 a8 01 0a = 192.168.1.10, target IP c0 a8 01 01 = 192.168.1.1, target MAC left as zeros because that is the unknown being asked about.
42–5900 × 18PaddingThe real payload is only 28 bytes. The minimum is 46, so the card pads with zeros — otherwise the frame would be illegally short.

That padding is worth pausing on. Header (14) + payload (28) = 42 bytes, but the minimum legal frame is 64 bytes including the 4-byte FCS. So the payload is padded to 46, giving 14 + 46 + 4 = 64. Small messages do not get a small frame; they get a padded one.

Change two bytes and the same envelope carries something completely different. A frame beginning:

3c 22 fb 01 02 03  a4 5e 60 12 34 56  08 00  45 00 ...
└──── dest MAC ───┘└──── src MAC ────┘└ 0x0800┘└ IPv4 header begins

is a unicast frame (a specific destination card, not all-ones) carrying an IPv4 packet (0x0800), whose own header starts with 45 — version 4, header length 5 words. The Ethernet layer neither knows nor cares what 45 00 ... means. It has done its entire job by the fourteenth byte: name a recipient, name a sender, name the protocol inside.

The ordering of those fields is deliberate. Destination comes first so a switch can read six bytes, look up its forwarding table, and begin sending the frame out the correct port while the rest of it is still arriving — a technique called cut-through switching. Put the destination at the end and that optimisation becomes impossible.

Visual Model

Think of a frame as a parcel on a conveyor belt. The belt first sends a run of alternating pulses so the receiving machine can lock onto the rhythm — that's the preamble, and it isn't part of the parcel at all. Then comes the label: to, from, what's inside. Then the contents. Then a tamper seal that tells you whether anything got scrambled in transit — but not what, and not how to fix it. If the seal is broken, the parcel goes in the bin and nobody is told.

The diagram below is drawn to scale in bytes, so the header really is that small next to the payload it escorts. Step through it — or click any field directly — and each field's size and purpose appears beside the field itself. The last two steps zoom into the destination address to show the two halves of a MAC and the single bit that decides whether a frame is for one device or for many.

Step 1 of N
Layer 1 sync — not counted in the frame the frame proper — 64 to 1518 bytes Preamble and start-frame delimiter Preamble 7 bytes SFD 1 B 8 bytes · clock sync, then "frame starts now" stripped by the hardware — never reaches software Destination MAC address Dest MAC 6 bytes 0 6 bytes · who the frame is for read first so a switch can forward before the frame finishes arriving Source MAC address Src MAC 6 bytes 6 6 bytes · who sent it switches learn port-to-address mappings from this field EtherType Type 2 B 12 2 bytes · which protocol is inside 0x0800 IPv4 · 0x0806 ARP · 0x86DD IPv6 · 0x8100 VLAN tag Payload Payload 46 – 1500 bytes 14 46–1500 bytes · the encapsulated Layer-3 packet short payloads are zero-padded to 46; the 1500 ceiling is the Ethernet MTU Frame check sequence FCS 4 B end 4 bytes · CRC-32 over the frame mismatch ⇒ the frame is silently dropped. Detection only, never repair. Anatomy of the 48-bit MAC address zoom: the 48 bits of that destination address a4 5e 60 12 34 56 OUI — 3 bytes, IEEE-assigned to the vendor 3 bytes assigned per device by that vendor 6 bytes = 48 bits, globally unique in theory The individual/group bit 1 0 1 0 0 1 0 0 byte 0 = ↑ low bit: 0 = unicast, 1 = multicast a4 → low bit 0 → this address is unicast ff:ff:ff:ff:ff:ff = all 48 bits set = broadcast

Loading…

Three destination kinds fall out of that last bit. A unicast address (low bit of the first byte clear) names one card; every other card sees the frame on a shared medium and discards it. A multicast address (low bit set) names a group, and only cards that have subscribed to it accept the frame. Broadcast, ff:ff:ff:ff:ff:ff, is simply the address with every bit set — the "everyone" group — and is how a device shouts at the entire local network when it has no idea who to talk to.

The arithmetic of the size limits is worth carrying around: 6 + 6 + 2 + 4 = 18 bytes of framing overhead on every frame. Maximum frame 1518 bytes = 1500 payload + 18. Minimum frame 64 bytes = 46 payload + 18. That 1500 is the Ethernet MTU, and because Ethernet is very nearly universal at the edge, IP sizes its packets to fit it and TCP's maximum segment size settles at roughly 1500 − 20 (IP header) − 20 (TCP header) = 1460. One hardware-era limit ripples all the way up the stack.

Deeper — Edge Cases & Gotchas

Why the minimum is 64 bytes — a fossil of shared cable

Early Ethernet was a single shared coaxial cable, half-duplex: one device could talk at a time, and two that started together collided. The access rule was CSMA/CD — Carrier Sense Multiple Access with Collision Detection: listen before transmitting, and if you hear a collision while transmitting, stop, wait a random interval, and retry. Detection only works while you are still sending, so a frame had to stay on the wire long enough for a collision at the far end to travel back before the sender finished. At 10 Mbps over the maximum cable span, that round trip works out to 64 bytes of transmission time. Hence the minimum, and hence the padding.

Modern wired Ethernet is switched and full-duplex: each device has its own dedicated link to a switch and can send and receive simultaneously, so there is nothing to collide with and CSMA/CD is effectively dead. The 64-byte minimum survives anyway, because the frame format did not change. Wi-Fi, where the radio medium really is still shared, uses CSMA/CA — Collision Avoidance, since a radio cannot listen while transmitting.

MACs are link-local, and that is the whole point

A MAC address identifies a card on one physical network. When a packet crosses a router, the router strips the incoming frame, and builds a new frame with a new source MAC (its own outgoing card) and a new destination MAC (the next hop). The IP addresses inside are untouched. So a MAC address never travels more than one hop, while IP addresses travel end to end. MAC is flat, hardware-scoped, and local; IP is hierarchical, logical, and global. That division is why routers can scale — they aggregate hierarchical IP prefixes, which is impossible with flat addresses.

Best-effort by design: detection without repair

The FCS is a CRC-32 that catches essentially all realistic corruption — and then the receiving card throws the frame away without telling anyone. No negative acknowledgement, no Layer-2 retransmission. If the lost bytes mattered, TCP will notice the gap in its sequence numbers and retransmit; if they were a video frame over UDP, nothing happens at all and that is the correct outcome. This is the "smart edges, dumb middle" principle: the link layer stays cheap and fast, endpoints own reliability. A useful consequence for debugging — rising FCS error counters on a switch port point at a physical problem (bad cable, duplex mismatch, interference), not a software one.

Anti-pattern: treating a MAC address as a trustworthy device identity — for licensing, access control, or session binding.
# A MAC is a value in a register, not a fingerprint. It is changed in one command:
sudo ip link set dev eth0 down
sudo ip link set dev eth0 address 3c:22:fb:aa:bb:cc
sudo ip link set dev eth0 up

Why it breaks: the address is software-settable on essentially every operating system, so an attacker can impersonate a permitted device at will. Worse, the assumption now fails benignly too — modern phones and laptops ship with MAC randomization on by default, generating a fresh private address per network for privacy. A system keyed on "MAC = device" will both admit attackers and lock out honest users whose address changed overnight.

Anti-pattern: concluding that a valid FCS means the data arrived reliably, and building on Ethernet as if it were a delivered-or-error channel.
frame in  →  CRC-32 recomputed  →  mismatch  →  discard, increment counter, say nothing
                                                 (no NAK, no retry, no notification upward)

Why it breaks: the FCS answers exactly one question — "was this frame corrupted?" — and the only action on failure is deletion. It says nothing about frames that were dropped for congestion, never arrived, or arrived out of order. Application-level guarantees come from TCP's sequence numbers, acknowledgements and retransmissions at Layer 4, never from Layer 2.

Two demultiplexers that are easy to confuse

EtherType and TCP/UDP port numbers do the same kind of job at different layers, and conflating them is a common misstep. EtherType selects the Layer-3 protocol — should these bytes go to the IPv4 stack, the IPv6 stack, or the ARP module? A port number selects the Layer-4 application endpoint — should this data go to the web server or the SSH daemon? A frame carrying ARP (0x0806) has no ports at all, because it never reaches Layer 4.

Jumbo frames and the cost of the 18-byte tax

Those 18 framing bytes are paid per frame regardless of payload size, so a 64-byte minimum frame spends over a quarter of the wire on envelope. Data centres often raise the MTU to roughly 9000 bytes — jumbo frames — so that a bulk transfer pays the overhead six times less often and the receiving CPU handles far fewer interrupts. The catch is that every device along the path must agree; one link still set to 1500 in the middle turns a jumbo-frame deployment into mysterious, size-dependent failures.

Test Yourself

A frame arrives with destination MAC ff:ff:ff:ff:ff:ff and EtherType 0x0806. What is it, and which devices process it?

A frame's recomputed CRC does not match its FCS field. What does the receiving card do next?

Why does the number 1500 keep reappearing far above the link layer — in IP packet sizes, in TCP's maximum segment size, in fragmentation rules — when it is only an Ethernet limit?