Core CS · Computer Networks
Forty-eight bits say who, one flag byte says where it stops
A network card holds an address it did not choose, and the link hands it a stream of bits with no punctuation in it. This lesson answers the two questions every arriving frame poses: who is this for, and where does it end.
Stuff one payload bit by bit, then unstuff it and check it survived →01 The idea
Two questions, asked of every frame that arrives
The physical layer hands the data link layer a run of bits. That is all it hands up. No start, no end, no names, no sizes. Every card on the link sees the same signal at the same instant, so nothing outside the stream can help: both of the questions that follow have to be answered from inside the bits themselves.
The first question is who is this frame for. It is answered by an address sitting in the first six bytes of the frame, 48 bits long, called the MAC address. The interesting thing about it is not its length. It is that the address is flat. Nothing inside it says where the card is. Two cards with consecutive addresses can be on opposite sides of the planet, and two cards on the same desk can share not a single bit. A flat address is perfectly good for saying which card and completely useless for saying which direction, and that single property is the reason a second addressing scheme had to be invented one layer up.
The second question is where does this frame start and stop. It sounds like the easier of the two and it is not. If the receiver has to find the boundaries inside the stream, then whatever marks a boundary must be a pattern the payload can never produce. Not a rare pattern, not an unlikely one: an impossible one. The payload is arbitrary bits, so the only way to make a pattern impossible in it is for the sender to go through every payload and actively remove the possibility. That work is called stuffing, and it is the price of being able to find a frame again.
Both answers live at layer 2 and both are cheap. Addressing costs twelve bytes at the front of every frame, six for the destination and six for the source. The framing costs one flag pattern at each end plus a bit or a byte here and there inside. In exchange the receiver can pull a specific frame, addressed to a specific card, out of an undifferentiated stream of electrical transitions.
02 Worked example
One frame, three cards, and only one of them keeps it
Three machines hang off one switch, and a router sits on a fourth port. The frame arrives from the router. The switch was powered on a moment ago, so its address table is still empty and it has nowhere specific to send this frame; it floods it out of every port except the one it came in on. All three machines receive it. That is not a contrived setup, it is what a switch does for every destination it has not yet learned, and it is precisely the situation the accept test exists for.
Here is the front of the frame. Ethernet II puts the destination address first, ahead of the source and ahead of the EtherType, and the ordering is deliberate: a card can begin deciding whether the frame is for it while the rest of the frame is still arriving.
destination MAC 08 00 27 6E 1A C5 6 bytes who this frame is for source MAC 00 00 0C 3A 5F 90 6 bytes the router's card, which sent it EtherType 08 00 2 bytes 0x0800, so the payload is IPv4 14 bytes the whole Ethernet II header
Now take the destination apart. This is the only address the lesson uses, so learn its two halves here.
08 : 00 : 27 : 6E : 1A : C5 48 bits = 6 bytes = 12 hex digits \__________/ \__________/ OUI NIC-specific OUI 24 bits. IEEE assigns this block to one manufacturer. NIC-specific 24 bits. That manufacturer numbers its own cards, so one block holds 2^24 = 16,777,216 addresses.
08:00:27 is a real block. It is the one VirtualBox gives to every virtual network card it creates, which is why a lab full of virtual machines all have addresses starting the same way. 00:00:0C is Cisco’s, one of the oldest OUIs there is. The block tells you who built the card and nothing else whatsoever: not where it is, not what it is plugged into, not who owns it now.
Two bits inside that first byte carry meaning, and they are the lowest two, which is the far end from where you start reading the hex. Get into the habit of converting the first byte and counting from the right.
first byte 0x08 = 0 0 0 0 1 0 0 0 7 6 5 4 3 2 1 0 bit number, counted from the right | | | +-- bit 0, the I/G bit. 0 = unicast, 1 = a group +---- bit 1, the U/L bit. 0 = globally assigned, 1 = set locally
So 08:00:27:6E:1A:C5 is a unicast address that came out of an IEEE-assigned block. Read left to right the frame now walks through five steps, and the highlighted one is where the first question is finally answered.
Here is that fourth step run three times, once per card on the link. Nothing in the frame changed; only the card reading it did.
| The card | Its own address | Destination in the frame | What it does |
|---|---|---|---|
| The laptop | 08:00:27:6E:1A:C5 | 08:00:27:6E:1A:C5 |
All 48 bits match. Accept. Verify the FCS, strip the header and trailer, read EtherType 0x0800 and hand the packet to IPv4. |
| The server | 00:00:0C:8A:41:D2 | 08:00:27:6E:1A:C5 |
No match, not the broadcast address, not a group it joined, not promiscuous. Discard, in the card. The CPU is never interrupted and the operating system never learns the frame existed. |
| The printer | 08:00:27:9F:03:11 | 08:00:27:6E:1A:C5 |
The first three bytes are identical, because the same company made both cards. That means nothing at all. Discard. An OUI is not a prefix and matching one is not partial delivery. |
The printer row is the one worth keeping. Two addresses sharing 24 bits are no closer to each other than two that share none, because the shared bits describe a factory rather than a place. That is what flat means in practice, and section 03 turns it into the reason IP exists.
And notice what every card had to do before any of this. It had to know where the six bytes of destination address began. Nothing in a bit stream is labelled, so before the first question can be asked at all, the second one has to have been answered.
03 Mechanics
MAC against IP, and five ways to find a frame boundary
Two tables. The first is the comparison that comes up in almost every networking interview, and the rows that decide it are not the first two. The second is the menu of framing methods, one of which you will step through in section 04.
| Property | MAC address | IPv4 address |
|---|---|---|
| Length | 48 bits = 6 bytes = 12 hex digits | 32 bits = 4 bytes = four decimal octets |
| Layer | 2, data link | 3, network |
| Written as | 08:00:27:6E:1A:C5 | 10.0.0.7 |
| Assigned by | IEEE sells the 24-bit OUI to a manufacturer, which numbers its own cards. Written into the card at the factory. | Whoever runs the network the device is plugged into: DHCP, a static config, an ISP. It belongs to the position, not to the card. |
| Structure | flat — no part of it says where the card is | hierarchical — a network prefix on the left, a host part on the right |
| Can it be summarised | no — a switch needs one table row per address it forwards to | yes — one entry for 10.1.0.0/16 covers all 65,534 hosts behind it |
| Scope | one link — it never crosses a router | end to end — it is meaningful the whole way |
| Crossing a router | both are replaced, at every hop | neither changes (NAT aside) |
| Resolved from the other by | ARP: “who has 10.0.0.7? tell 10.0.0.1”, answered with a MAC. IPv6 uses NDP instead. | DNS maps a name to an address. Nothing routinely maps a MAC back to an IP. |
| Everybody on the link | FF:FF:FF:FF:FF:FF | the all-ones host address of the subnet, e.g. 10.0.0.255 in 10.0.0.0/24 |
Why flat is the row that matters, and why IP had to be invented. Do the arithmetic. A MAC address is 48 bits, so the space holds 2^48 = 281,474,976,710,656 addresses; fix the two flag bits for a globally assigned unicast address and 2^22 = 4,194,304 OUIs of 2^24 addresses each still gives 2^46 = 70,368,744,177,664 of them. Size was never the problem. The problem is that the space has no structure. If the internet forwarded on MAC addresses, a router would need one table entry for every network card on Earth, and there would be no shorter way to write it, because nothing in a MAC address tells you which addresses are near each other. IP is hierarchical, so 10.1.0.0/16 is one entry covering 65,534 hosts and a router only has to know the prefix. Layer 3 does not exist because layer 2 lacked addresses. It exists because layer 2 addresses cannot be summarised.
The two bits inside the first byte, and the addresses they explain. Bit 0 is the I/G bit: 0 for a single card, 1 for a group. Bit 1 is the U/L bit: 0 for an address out of an IEEE block, 1 for one set locally. Four addresses fall straight out of that. FF:FF:FF:FF:FF:FF is every bit set, so its I/G bit is set too, which makes broadcast a special case of multicast rather than a third category. 01:00:5E:xx:xx:xx carries IPv4 multicast and 33:33:xx:xx:xx:xx carries IPv6 multicast, both with bit 0 set. 01:80:C2:00:00:00 is where a switch sends its spanning tree BPDUs. And any address with the U/L bit set announces itself as software-assigned: 52:54:00 is what QEMU and KVM hand a virtual card, and 0x52 = 0101 0010 has bit 1 set.
Burned in does not mean unchangeable, and this is a security answer. Burned in describes where the default comes from, not where the card reads its address at run time. The address a card puts in the source field lives in a register the driver writes at initialisation, and one command overwrites it: ip link set dev eth0 address 02:11:22:33:44:55 on Linux, with an equivalent on every other operating system. So MAC filtering is not a security control. Every permitted address travels in the clear in the header of every frame on the link, so anyone who can hear the link can read one and use it, and the filter now says yes to the attacker. Treat a MAC address as a hint about identity, never as proof of it. That 02 is deliberate, by the way: 0x02 = 0000 0010 has the U/L bit set, which is the correct convention for an address you made up.
Now the other question. The receiver holds a stream of bits and has to recover the boundaries from inside it. There are five ways, and one of them does not really work.
| Method | How the boundary is found | Cost | Where it fails, and who uses it |
|---|---|---|---|
| Byte count | A field in the header says how many bytes follow. The receiver counts them and expects the next frame to start there. | 0 extra bytes |
Corrupt the count and the receiver restarts in the wrong place. The next count it reads is really a byte of payload, so every following boundary is wrong too and nothing in the stream can pull it back. Unusable on its own. |
| Byte stuffing | A FLAG byte marks both ends. Any FLAG inside the payload gets an ESC byte in front of it, and any ESC gets another ESC in front of it. | up to 2x |
Only works on byte-aligned data. This is what PPP does on an asynchronous link, with FLAG 0x7E and ESC 0x7D. |
| Bit stuffing | The flag is 01111110. The sender inserts a 0 after any five consecutive 1s in the payload, so six 1s in a row can only ever be a flag. | +1 bit per 5, worst case +20% |
Works on any number of bits, aligned or not, which is why HDLC and everything descended from it uses it. This is the one in section 04. |
| Coding violation | The line code has symbols that valid data can never produce, so one of them marks the boundary. | 0 payload bits |
Only available when the physical layer has spare symbols. 4B/5B leaves codes unassigned; Manchester-coded Ethernet guarantees a mid-bit transition, so the absence of one is not a legal data symbol. |
| Fixed size | Every frame is the same length, so after one synchronisation the boundaries are arithmetic. | padding waste |
ATM cells are always 53 bytes, a 5-byte header and a 48-byte payload. Rare, because real traffic is bursty: a one-byte message still costs a whole cell and a 1500-byte packet needs 32 of them. |
Byte stuffing, worked on three bytes. Take the most awkward payload possible: three bytes reading FLAG, ESC, FLAG. The rule inserts an ESC in front of any FLAG or ESC, so the payload becomes ESC FLAG, ESC ESC, ESC FLAG: six bytes. Wrapped in its own two flags the line carries FLAG · ESC FLAG ESC ESC ESC FLAG · FLAG, eight bytes to deliver three. The receiver reads left to right: an ESC means “the next byte is data, whatever it looks like”, and a FLAG that was not preceded by an ESC is the end of the frame. Escaping the escape is not tidiness, it is what makes the rule reversible. Without it a receiver could not tell an ESC the payload genuinely contained from one the sender inserted, and every byte after that point would be read wrongly. The worst case is a payload that is nothing but FLAG bytes, which doubles.
The receiver’s decision in bit stuffing is three-way, not two-way. Having counted five consecutive 1s, the receiver looks at what comes next. A 0 means the sender inserted it, so remove it and reset. A 1 followed by a 0 completes 01111110 and ends the frame. A 1 followed by another 1 is neither: seven or more consecutive 1s is HDLC’s abort signal, telling the receiver to throw away the partial frame it has been building. Three outcomes from two bits, and the third one is the reason a single flipped bit in a stuffed stream is a framing failure rather than a data error.
What Ethernet actually does, and why interviews ask about HDLC instead. Ethernet does not stuff anything. A frame is preceded by a 7-byte preamble of alternating 1s and 0s so the receiver’s clock can lock on, then a 1-byte start frame delimiter 10101011 whose final pair breaks the alternation and says the frame begins on the next bit. The end is found from the signal itself: the transmitter stops, and the standard requires a 96-bit interframe gap before anyone may start again. Ethernet also carries a length or type field and enforces a 64-byte minimum frame, so sender and receiver have more than one way to agree on the size. Stuffing questions in interviews almost always mean HDLC or PPP, because those run over links whose physical layer offers no such help.
05 Cheat sheet
The answers they ask you to produce out loud
Every row is something an interviewer can ask you to state or compute in under ten seconds. The right-hand column is the specific wrong answer that gets given, not a general warning.
| What they ask | The answer | The trap |
|---|---|---|
| How long is a MAC address | 48 bits = 6 bytes = 12 hex digits | Answering 64 bits, or reading the twelve hex digits as twelve bytes. |
| What the two halves are | first 3 bytes = OUI, assigned by IEEE to one maker; last 3 = numbered by that maker | calling the OUI a network prefix — it names a factory, not a place, and nothing can be routed on it |
| The broadcast address | FF:FF:FF:FF:FF:FF | Writing five pairs instead of six, or FF:FF:FF:FF:FF:FE. |
| Unicast or multicast | bit 0 of the FIRST byte, the I/G bit. 0 = one card, 1 = a group | Looking at the last byte. The flag is in the first byte and it is the lowest bit of it. |
| Locally administered | bit 1 of the first byte, the U/L bit. 1 = set by software | Not recognising that 02:… and 52:54:00 announce themselves as made up. |
| When a card accepts a frame | own address, broadcast, a joined multicast group, or promiscuous mode | Forgetting the discard happens in the card, so the CPU is never interrupted at all. |
| MAC versus IP, in one line | MAC is flat and link-local; IP is hierarchical and end to end | saying layer 2 versus layer 3 and stopping — that is the label, not the difference |
| What a router rewrites | both MAC addresses, every hop. Neither IP address. | Reversing it. This is the single most asked version of the comparison. |
| What maps an IP to a MAC | ARP on the local link for IPv4; NDP for IPv6 | Saying DNS. DNS maps a name to an address; it never produces a MAC. |
| The HDLC flag | 01111110 = 0x7E | Quoting 01111111, or eight 1s, or 0xFE. |
| The bit stuffing rule | insert a 0 after five consecutive 1s; the receiver removes a 0 that follows five 1s | saying “after six 1s” — by the time six exist the flag has already occurred |
| Worst-case stuffing cost | bit stuffing +20%; byte stuffing 2x | Quoting the worst case as the typical case. Both are ceilings, reached only by adversarial payloads. |
| Why a byte count alone fails | a corrupted count destroys the boundary of every following frame | Answering “the frame is lost”. One frame is lost; the synchronisation is lost for good. |
06 Where & why
Where these bits become something you can print, change and capture
None of this is invented for exams. The address is a register you can overwrite from a shell, the framing scheme is a one-word setting on a router interface, and the OUI you see in a capture is a lookup rather than something the frame carries.
ip link show eth0 prints link/ether 08:00:27:6e:1a:c5, and once you change it with ip link set dev eth0 address 02:11:22:33:44:55 the same command also reports permaddr, the one still sitting in the card. Two values, side by side, on one line: that is the proof that “burned in” and “in use” are different things, and it takes about four seconds to produce.
Wireshark replaces the first three bytes of every address it displays with the manufacturer name from the IEEE registry, which makes a capture readable and makes it very easy to forget that the frame carries 48 bits and nothing else. Switch the display off and the illusion goes with it. The same pane is where you confirm the destination really is first in the header, ahead of the source.
A home access point’s “allowed devices” list matches on MAC, and every allowed MAC travels unencrypted in the header of every frame even on a WPA2 or WPA3 network, because the header has to stay readable for the frame to be delivered at all. Copy one, and the filter says yes. That same visibility is why iOS, Android and Windows now transmit a random locally administered address while scanning, so a shop cannot follow a phone by its card.
On a Cisco serial interface the default layer 2 encapsulation is HDLC, which bit-stuffs, and typing encapsulation ppp does not change that: on a synchronous line PPP borrows HDLC framing and bit-stuffs too. Move the same PPP to an asynchronous line and it switches to byte stuffing, and goes one step further than the textbook rule: after inserting escape 0x7D it also XORs the following byte with 0x20, so flag 0x7E travels as 0x7D 0x5E and the escape itself as 0x7D 0x5D, keeping control characters off a line that a modem might act on.
07 Interview questions
What they actually ask
MAC addressing is asked in almost every networking round, usually as a warm-up that turns into the MAC-versus-IP comparison within two follow-ups. Framing is asked less often but more sharply, because it has a right answer you either can or cannot produce.
How long is a MAC address, and what are its parts?
How does a card tell a unicast address from a multicast one?
What is the U/L bit for?
When does a network card accept a frame?
MAC addresses are burned into the card, so can I use one to identify a device?
MAC address versus IP address.
If MAC addresses already identify every card in the world, why do we need IP at all?
What is the framing problem?
Why is a byte count on its own a bad way to frame?
Explain bit stuffing.
Why does byte stuffing have to escape the escape byte?
Does Ethernet use bit stuffing?
08 Practice problems
Six to work out on paper
For every address question, convert the byte you need into eight bits before you say anything. For every stuffing question, write the output stream out in full and count in that stream, not in the input. Almost every wrong answer in this topic comes from counting in the wrong one of the two.