Protocol layers and encapsulation

Wrap data in transport, network, and link headers on the way down and unwrap it on the way up.

Python
def encapsulate(payload):
    segment = {"src_port": 50000, "dst_port": 80, "data": payload}
    packet = {"src_ip": "192.0.2.10", "dst_ip": "198.51.100.7", "data": segment}
    frame = {"src_mac": "aa:aa:aa:aa:aa:01", "dst_mac": "bb:bb:bb:bb:bb:02", "data": packet}
    return frame


def decapsulate(frame):
    packet = frame["data"]
    segment = packet["data"]
    return segment["data"]


frame = encapsulate("GET /")
print(list(frame))
print(frame["data"]["dst_ip"], frame["data"]["data"]["dst_port"])
print(decapsulate(frame))
Output
['src_mac', 'dst_mac', 'data']
198.51.100.7 80
GET /

Explanation

Network software is organized in layers, where each layer provides a service to the one above and uses the one below. The Internet's TCP/IP model has four: the link layer moves frames between neighbouring devices, the internet layer (IP) moves packets between hosts across networks, the transport layer (TCP or UDP) connects processes on those hosts using port numbers, and the application layer holds protocols such as HTTP and DNS. The OSI reference model splits the same ideas into seven layers and is mainly used as a teaching vocabulary.

As data goes down the stack, each layer encapsulates the data from above by adding its own header, and the link layer may also add a trailer. The units have names: an application message becomes a TCP segment (or UDP datagram), then an IP packet, then a link-layer frame. The receiver strips the headers in reverse order, which is decapsulation.

The program builds a frame as nested dictionaries. The addresses come from ranges reserved for documentation (RFC 5737), so they never refer to real hosts. The link layer uses MAC addresses for the next hop, IP addresses identify the endpoints across the whole path, and the ports identify the application on each endpoint. A real router rewrites the link-layer addresses at every hop but leaves the IP addresses and ports unchanged.

Explore the dry run
Guided walkthroughReady
1def encapsulate(payload):
2 segment = {"src_port": 50000, "dst_port": 80, "data": payload}
3 packet = {"src_ip": "192.0.2.10", "dst_ip": "198.51.100.7", "data": segment}
4 frame = {"src_mac": "aa:aa:aa:aa:aa:01", "dst_mac": "bb:bb:bb:bb:bb:02", "data": packet}
5 return frame
6
7
8def decapsulate(frame):
9 packet = frame["data"]
10 segment = packet["data"]
11 return segment["data"]
12
13
14frame = encapsulate("GET /")
15print(list(frame))
16print(frame["data"]["dst_ip"], frame["data"]["data"]["dst_port"])
17print(decapsulate(frame))

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
The transport layer adds port numbers so the data reaches the right application: port 80 is the conventional HTTP port.segment wraps the payload
—
The network layer wraps the segment with source and destination IP addresses.packet wraps the segment
—
The link layer wraps the packet with the MAC addresses of the next hop.packet wraps the segment
—
Each layer reads only its own header: IP uses dst_ip, the transport layer uses dst_port.packet wraps the segment
['src_mac', 'dst_mac', 'data']
198.51.100.7 80
The receiver strips the frame, packet, and segment headers in turn and recovers the original payload.packet wraps the segment
['src_mac', 'dst_mac', 'data']
198.51.100.7 80
GET /

Cost and common mistakes

Each layer adds a constant-size header, so encapsulating a payload of n bytes costs O(n) to copy it, plus O(1) per layer header.

  • Real headers are binary fields with fixed formats, not dictionaries. This model shows only the nesting.
  • MAC addresses change at every hop, while IP addresses stay the same from source to destination (ignoring NAT).
  • The OSI model and the TCP/IP model are not identical. The Internet protocols do not map one-to-one onto the seven OSI layers.

Try it yourself

Which header does a router read to decide where to forward a packet?

Reveal answer and reasoning

The IP (network layer) header, specifically the destination IP address. It does not need the transport or application data.

Further reading