Networking Fundamentals · beginner · ~10 min
- Explain what a layered network model is and why networks are built that way - Name the layers of both the OSI (7-layer) and TCP/IP (4-layer) models and match them up - Describe **encapsulation** and **decapsulation** and trace a packet down and back up the stack - Identify which addressing lives at each layer: MAC (Link), IP (Internet), ports (Transport) - Map a real protocol (HTTP, TCP, IP, Ethernet, ARP, DNS) to its layer - Use "layer N" shorthand the way network engineers and security analysts do
Sending data across a network is a big problem: cables fail, packets take different routes, machines run different operating systems, and thousands of programs share one network card. Trying to solve all of that in one giant piece of software would be a nightmare. So networking is built in layers, where each layer solves one narrow job and hands its result to the next.
Think of posting a letter. You write the message (that's your job), you put it in an envelope with an address (the postal service's job), the post office sorts it and routes it between cities (another job), and a truck physically carries it down a road (yet another job). Each step trusts the step below it to do its part and does not care how. Networks work the same way: your web browser writes an HTTP request and trusts the layers underneath to actually move the bytes.
Two standard descriptions of these layers exist. The OSI model has 7 layers and is mostly a teaching and vocabulary reference. The TCP/IP model has 4 layers and is what the real internet runs on. They describe the same journey at different levels of detail. This lesson is the foundation for everything else in networking. Once you can place a protocol at its layer, the next lessons — starting with IP addresses: IPv4, IPv6, public vs private — will make far more sense, because you will already know which layer IP lives at and what job it does there.
Layering is not academic trivia — it is the map every network engineer and security analyst carries in their head. When something breaks or needs defending, the first question a professional asks is "which layer is this?" because the answer tells you which tool to reach for and where a fix belongs.
The same map guides defence. A firewall that filters by port works at Layer 4; a web application firewall that inspects HTTP works at Layer 7; a switch that isolates traffic works at Layer 2. If you know the layer, you know where the control goes. That single habit — "name the layer first" — separates people who guess from people who diagnose.
Definition. A layered model splits communication into stacked levels, each responsible for one job and each talking only to the layer directly above and below it.
Plain language. Each layer is a specialist that trusts its neighbours. The Transport layer worries about which program gets the data and does not care whether the physical link is copper, fibre, or Wi-Fi. The Link layer moves bits across one hop and does not care whether those bits are a web page or an email.
How it works internally. Each layer defines a clean interface to the layer above ("give me your data, I'll deliver it") and adds its own header — a small block of control information placed in front of the data. Because the interface is fixed, you can swap out one layer's technology (Wi-Fi for Ethernet) without changing anything above it.
When it helps / when it doesn't. Layering makes systems modular, testable, and interoperable across vendors. The cost is a little overhead (every layer adds a header) and occasional inefficiency, but the clarity is worth it. Do not treat the boundaries as physically real — they are a conceptual division; a single network card driver may touch several layers.
Common pitfall. Beginners think a layer is a piece of hardware. It is not. A layer is a role. One program or one chip can perform several roles.
Knowledge check (explain in your own words): Why can you switch from a wired connection to Wi-Fi without reinstalling your web browser? Which layer changed, and which layers did not notice?
Definition. The Open Systems Interconnection (OSI) model is a 7-layer reference model published by ISO, used mainly for teaching and shared vocabulary.
7 Application <- HTTP, DNS, SSH (what the user's app speaks)
6 Presentation <- encoding, TLS encryption, compression
5 Session <- setting up / tearing down conversations
4 Transport <- TCP, UDP, ports, reliability
3 Network <- IP addresses, routing between networks
2 Data Link <- MAC addresses, Ethernet frames, switches
1 Physical <- cables, radio waves, voltages, bits on the wire
Plain language. Read it top-to-bottom as data leaving your machine, or bottom-to-top as data arriving. Layers 5-7 are all "software near the app"; layers 1-2 are "the actual wire."
When to use it. Use OSI when you need precise words. Saying "that's a layer-7 problem" instantly tells a colleague you mean the application, not the cable.
Common pitfall. In the real world, layers 5, 6, and 7 blur together — most people lump them into "the application." Do not over-obsess about whether TLS is "layer 6" or "layer 7"; the boundary is fuzzy on purpose.
Definition. The TCP/IP model is the 4-layer model the internet is actually built on: Link, Internet, Transport, Application.
How it maps to OSI.
| TCP/IP layer | OSI layer(s) | Job | Example protocols |
|---|---|---|---|
| Application | 5, 6, 7 | App-level meaning | HTTP, DNS, SSH, SMTP |
| Transport | 4 | End-to-end delivery, ports | TCP, UDP |
| Internet | 3 | Addressing + routing between networks | IP, ICMP |
| Link | 1, 2 | One physical hop | Ethernet, Wi-Fi, ARP |
When to use it. Use TCP/IP when talking about how the internet really works. It is simpler and matches actual software (the code that runs your network stack is organized this way).
Common pitfall. Mixing the two numbering systems. "Layer 4" means Transport in both models (they agree there), but "Layer 2" only exists in OSI — in TCP/IP it is folded into "Link." When someone says a layer number, they almost always mean the OSI number.
Knowledge check (concept): A DNS lookup and a web page both travel over the internet. Which TCP/IP layer are DNS and HTTP at, and which layer moves them across networks?
Definition. Each layer identifies endpoints in its own way, because each layer answers a different question.
| Layer | Address type | Answers the question |
|---|---|---|
| Link | MAC address (e.g. a4:5e:60:...) |
Which device on this local hop? |
| Internet | IP address (e.g. 93.184.216.34) |
Which host anywhere on the internet? |
| Transport | Port number (e.g. 443) |
Which program on that host? |
Plain language. MAC gets a frame across one link, IP gets a packet across the world, and the port picks which app receives it once it arrives. All three are needed to reach, say, the web server process on a specific machine.
Common pitfall. Thinking an IP address alone identifies a program. It does not — the port does that. 93.184.216.34 is a machine; 93.184.216.34:443 is the HTTPS server on that machine.
Definition. Encapsulation is the process by which each layer, on the way down, wraps the data from the layer above inside its own header (and sometimes a trailer). Decapsulation is the reverse on the way up: each layer strips its own header and passes the rest upward.
How it works internally. Your HTTP request is treated as opaque payload by TCP. TCP prepends its header (with the port) to make a segment. IP treats the whole segment as payload and prepends its header (with the IP addresses) to make a packet. Ethernet treats the whole packet as payload and wraps it with a header and trailer to make a frame — then the bits go on the wire.
SENDING (encapsulation, top -> down)
[ HTTP data ] Application
[ TCP hdr | HTTP data ] Transport (segment)
[ IP hdr | TCP hdr | HTTP data ] Internet (packet)
[ Eth hdr | IP hdr | TCP hdr | HTTP data | Eth trailer ] Link (frame)
| |
+---------- on the wire --------+
RECEIVING (decapsulation, bottom -> up): strip each header in reverse
When it matters. This is exactly what you see in a packet capture (e.g. Wireshark): the outer Ethernet header first, then IP, then TCP, then the application data buried inside. Reading a capture is peeling these layers apart.
Common pitfall. Assuming the innermost data is at the front of the bytes. It is the opposite — the outermost (Link) header comes first on the wire, and the application data is deepest inside.
Knowledge check (predict the order): A packet arrives at your network card. In what order does your computer strip the headers — TCP first or Ethernet first? Why?
This is a concept lesson, so there is no language syntax. The key structure to memorize is the layer stack and the naming of each unit as it grows:
Application data -> "data" / "message"
+ Transport header -> "segment" (TCP) or "datagram" (UDP)
+ Internet header -> "packet"
+ Link header/trailer -> "frame"
The vocabulary matters: saying "the TCP segment" or "the IP packet" tells other engineers exactly which layer you mean. Note that TCP/IP "Layer" folds OSI layers 1-2 together, and OSI "Layer 4" and TCP/IP "Transport" are the same thing.
Networks are built in layers. Each layer does one job.
When sending, a layer hands its result to the layer below. When receiving, it hands the result to the layer above. Two models describe this.
The OSI model is a teaching reference. Its layers are:
You will hear engineers say "that's a layer-7 problem" (application) or "a layer-2 issue" (switching).
TCP/IP is what the internet actually runs. It is the practical model.
| TCP/IP layer | Does what | Examples |
|---|---|---|
| Application | App-level protocols | HTTP, DNS, SSH, SMTP |
| Transport | End-to-end delivery, ports | TCP, UDP |
| Internet | Addressing and routing between networks | IP, ICMP |
| Link | One physical hop | Ethernet, ARP, Wi-Fi |
When you send data, each layer wraps the layer above it in its own header.
Your HTTP request becomes a TCP segment, inside an IP packet, inside an Ethernet frame.
The receiver unwraps these in reverse order. A pentester reading a packet capture is literally peeling these layers apart.
Because networking data is layered bytes, a great way to feel encapsulation is to parse a header yourself. Below is a complete, runnable C11 program that reads the first bytes of a mock IPv4 header out of a byte buffer and pulls out the layered fields — exactly the kind of thing a packet analyzer does at Layer 3. (This parses a buffer only; it opens no sockets and touches no real network.)
#include <stdio.h>
#include <stdint.h>
/* A mock 20-byte IPv4 header (RFC 791 layout), as it would appear
* inside a captured frame. Byte 0 packs two 4-bit fields:
* high nibble = version (4), low nibble = IHL (header length in 32-bit words).
* Bytes 2-3 are the total length, big-endian (network byte order). */
static const uint8_t packet[20] = {
0x45, /* version=4, IHL=5 -> header is 5*4 = 20 bytes */
0x00, /* type of service */
0x00, 0x3C, /* total length = 0x003C = 60 bytes */
0x1C, 0x46, 0x40, 0x00,
0x40, 0x06, /* TTL=64, protocol=6 (TCP) */
0x00, 0x00, /* header checksum (zeroed for this mock) */
93, 184, 216, 34, /* source IP 93.184.216.34 */
10, 0, 0, 5 /* dest IP 10.0.0.5 */
};
int main(void) {
/* Guard: we must have at least the 4 fixed bytes we read below. */
if (sizeof packet < 4) {
fprintf(stderr, "buffer too small for an IPv4 header\n");
return 1;
}
uint8_t version = packet[0] >> 4; /* high nibble */
uint8_t ihl = packet[0] & 0x0F; /* low nibble */
uint32_t header_bytes = (uint32_t)ihl * 4; /* IHL counts 32-bit words */
/* Total length is big-endian: high byte first, then low byte. */
uint16_t total_len = ((uint16_t)packet[2] << 8) | packet[3];
uint8_t protocol = packet[9]; /* which Transport protocol is inside */
printf("IP version : %u\n", version);
printf("Header length : %u bytes\n", header_bytes);
printf("Total length : %u bytes\n", total_len);
printf("Payload length : %u bytes\n", total_len - header_bytes);
printf("Next layer : %s\n", protocol == 6 ? "TCP (Transport)" : "other");
return 0;
}
What it does. It reads the Internet-layer (Layer 3) header out of a byte buffer and reports the version, how many bytes the header itself occupies, the total length of the whole packet, and how much of that is payload handed up to the Transport layer. The protocol field (value 6) tells the receiver that a TCP segment is encapsulated inside — a direct demonstration of one layer pointing to the next.
Expected output:
IP version : 4
Header length : 20 bytes
Total length : 60 bytes
Payload length : 40 bytes
Next layer : TCP (Transport)
Edge cases to keep in mind. Multi-byte network fields are big-endian, so you must combine bytes explicitly rather than casting the pointer (a raw cast would give the wrong value on a little-endian CPU like x86). A real parser must also check that header_bytes and total_len fit inside the actual buffer before trusting them, and that total_len >= header_bytes so the payload subtraction cannot underflow.
Walking the key example top to bottom:
#include <stdint.h> brings in the fixed-width types uint8_t and uint16_t. Network parsing needs exact byte sizes, so int is not good enough.packet[20] array is our stand-in for the Internet-layer header as it would sit inside a captured frame. Byte 0 is 0x45.version = packet[0] >> 4 shifts 0x45 right by 4 bits, leaving 0x4 = 4. This is the high nibble.ihl = packet[0] & 0x0F masks off the high nibble, leaving 0x5 = 5. IHL counts 32-bit words.header_bytes = ihl * 4 converts 5 words into 20 bytes — the size of the header itself.total_len = (packet[2] << 8) | packet[3] rebuilds a big-endian 16-bit number: 0x00 << 8 is 0x0000, OR-ed with 0x3C gives 0x003C = 60.protocol = packet[9] is 0x06 = 6, the IANA number for TCP. This is the field that says "a Transport-layer TCP segment is wrapped inside me."total_len - header_bytes = 60 - 20 = 40, the payload the Internet layer hands up to Transport.A trace of the values as they are computed:
| Step | Expression | Bytes used | Result |
|---|---|---|---|
| version | packet[0] >> 4 |
0x45 |
4 |
| ihl | packet[0] & 0x0F |
0x45 |
5 |
| header_bytes | ihl * 4 |
— | 20 |
| total_len | (packet[2]<<8) | packet[3] |
0x00 0x3C |
60 |
| payload | total_len - header_bytes |
— | 40 |
| protocol | packet[9] |
0x06 |
6 (TCP) |
The result is produced because the IPv4 header is a fixed, well-defined layout: once you know where each field lives and how wide it is, extracting it is pure bit and byte arithmetic. That is precisely the mental model of decapsulation — this is the Internet layer being peeled off to reveal what the Transport layer will receive next.
Mistake 1: Reading a multi-byte field with a plain pointer cast.
/* WRONG on x86: treats bytes as little-endian */
uint16_t total_len = *(uint16_t *)&packet[2]; /* gives 0x3C00 = 15360! */
Network fields are big-endian ("network byte order"), but x86 is little-endian, so the cast reverses the bytes. Correct version:
uint16_t total_len = ((uint16_t)packet[2] << 8) | packet[3]; /* 60 */
How to catch it: if a length or port comes out absurdly large (like 15360 for a 60-byte packet), suspect byte order.
Mistake 2: Confusing the two models' layer numbers. Saying "IP is Layer 4" mixes the models. IP is the Internet layer in TCP/IP, which corresponds to OSI Layer 3. Transport (TCP/UDP) is Layer 4. Prevent it: when you hear a bare number, assume OSI numbering, and remember only Transport happens to share the number 4.
Mistake 3: Thinking a port belongs to the IP address. Learners write "connect to IP 1.2.3.4:443" and assume the port is part of the address. The IP is Internet-layer; the port is Transport-layer. They are two different layers glued together in the display. Prevent it: remember MAC -> IP -> port answer three separate questions (this link, this host, this program).
Mistake 4: Believing the innermost data comes first in the bytes. On the wire the outermost (Link) header is first and the application data is deepest inside. Reading a capture front-to-back means going outside-in. Prevent it: picture the nested-envelope diagram from the encapsulation section.
Mistake 5: Treating layers as physical boxes. "Show me the Transport layer chip." There isn't one — a layer is a role that software performs, not a component you can point at.
Because this lesson mixes a concept with a small parser, here are both angles.
When the parser gives wrong numbers:
printf("%02x", packet[i])) and combine them by hand to confirm.* 4 gives 5 instead of 20.version prints as something other than 4 -> you probably forgot the >> 4 and read the whole byte 0x45 = 69.Common compiler warnings for this kind of code:
(uint16_t) casts, as shown.-fsanitize=address and run; it will flag out-of-bounds reads immediately. Always bounds-check before indexing a buffer you did not fill yourself.When you are debugging a real network problem, ask "which layer?" in order:
ping your gateway.ping 8.8.8.8.Going bottom-up like this is the fastest way to find where a connection breaks, because a failure at a low layer makes every higher layer look broken.
Parsing network data in C is a classic source of vulnerabilities, because the bytes come from outside and you cannot trust them. The key defensive habits for header parsing:
packet[9] (or read header_bytes worth of data) without first confirming the buffer is at least that long. A malicious or truncated packet that claims a 20-byte header but is only 3 bytes long will make a naive parser read out of bounds — undefined behaviour and a potential crash or leak. Validate len >= needed first.total_len and IHL fields are attacker-controllable. Check header_bytes <= total_len and total_len <= actual_buffer_len before using them, or the subtraction total_len - header_bytes can underflow (it is unsigned, so 20 - 60 wraps to a huge number) and you may read far past the buffer.uint8_t/uint16_t make field sizes explicit; int sizes vary and invite mistakes.The broader security lesson connects straight back to layering: validation belongs at the layer that owns the data. An Internet-layer parser validates IP-header fields; the Transport layer validates ports and segment lengths; the Application layer validates the actual request. Each layer distrusts its input.
Where this shows up.
Best-practice habits.
1. (Beginner) Match protocols to layers. Take this list — HTTP, TCP, IP, Ethernet, UDP, ARP, DNS, ICMP — and write each next to its TCP/IP layer (Application, Transport, Internet, Link). Then convert each to its OSI layer number. Concepts: layer mapping, the two models. Hint: ARP and Ethernet are the same layer; DNS and HTTP are the same layer.
2. (Beginner) Name the units. For a browser loading a web page, write the four names the data is called as it moves down the stack (data -> ? -> ? -> ?), and state which header adds the port number and which adds the IP addresses. Concepts: encapsulation, segment/packet/frame vocabulary, per-layer addressing.
3. (Intermediate) Extend the parser. Starting from the lesson's C program, also extract and print the source and destination IP addresses (bytes 12-15 and 16-19) in dotted-decimal form (e.g. 93.184.216.34). Requirements: print both addresses; do not hard-code the digits. Example output: Source: 93.184.216.34 Dest: 10.0.0.5. Hint: each address is four separate bytes; loop or print %u.%u.%u.%u.
4. (Intermediate) Add safety. Modify the parser to take the buffer length as a parameter and reject bad input: return an error if the buffer is shorter than 20 bytes, if IHL < 5, or if total_len < header_bytes. Requirements: no read past the buffer; print a clear error and return non-zero on bad input. Concepts: bounds checking, never trusting length fields, unsigned underflow. Hint: validate before you compute the payload length.
5. (Challenge) Trace a full round trip on paper. Pick a scenario: your laptop requests https://example.com over Wi-Fi. Write, step by step, what each layer adds on the way out of your laptop, what your Wi-Fi router does at the Link and Internet layers, and what each layer strips when the reply arrives. For each step name the address type in play (MAC, IP, or port). Requirements: cover both encapsulation and decapsulation and at least one intermediate hop. Concepts: everything in the lesson. Hint: the MAC address changes at every hop, but the IP addresses stay the same end-to-end — explain why.