Chapter 1 · Hands-on labs
Six short labs that turn the slides into commands you actually run. Each maps to a Chapter 1 topic, takes a few minutes, and ends by connecting what you saw back to the concept.
sudo apt install -y <tool>. The ❯ shown in code blocks is just the prompt — the Copy button copies only the command.We’ll make two programs talk over the loopback link (127.0.0.1) so you can watch every component at work.
Start the RECEIVER in Terminal A — listen on TCP port 9000:
nc -lvp 9000
listening on [any] 9000 ...
Start the SENDER in Terminal B — connect, type a line, press Enter:
nc 127.0.0.1 9000
Hello receiver, this is the sender.
You just moved a message from a sender to a receiver over a medium, obeying a protocol:
| Component | In this lab |
|---|---|
| Message | the text you typed |
| Sender | nc 127.0.0.1 9000 (Terminal B) |
| Receiver | nc -lvp 9000 (Terminal A) |
| Medium | the loopback link lo + the TCP connection |
| Protocol | TCP — the rules both ends follow |
Full-duplex: keep both connected and type in both terminals. Text flows both ways at once — like a phone call.
Simplex (one-way): a receiver that only receives, a sender that only sends:
# Terminal A (receiver only)
nc -lvp 9000 > received.txt
# Terminal B (sender only; -N closes after sending)
echo "one way only" | nc -N 127.0.0.1 9000
# back in Terminal A: Ctrl-C, then read the file
cat received.txt
nc processes, your text, the link, and TCP. Both typing at once = full-duplex; a one-way pipe into a listener = simplex.nc chat? (answer below)Flags: Kali ships OpenBSD netcat. If your nc rejects -lvp, use nc -lv 9000. For “close after send” use -N (OpenBSD) or -q1 (traditional).
One character = one byte (8 bits). Show “A” as binary, hex and decimal:
echo -n "A" | xxd -b echo -n "A" | xxd echo -n "A" | od -An -tu1
00000000: 01000001 A
00000000: 41 A
65So A = 01000001 = 0x41 = 65 — exactly the example on the “It all comes down to bits” slide.
Convert a number between decimal, hex and binary — no maths by hand (an IP octet like 192 is written all three ways):
printf '%X\n' 192 printf '%d\n' 0xC0 echo "obase=2; 192" | bc
C0 192 11000000
ASCII (1 byte) vs Unicode / UTF-8 (more bytes). Watch the byte count grow:
echo -n 'A' | xxd echo -n 'é' | xxd echo -n '€' | xxd
A = 41 (1 byte — ASCII) é = c3a9 (2 bytes — Unicode/UTF-8) € = e282ac (3 bytes — Unicode/UTF-8)
Plain English fits in one ASCII byte; accented or other-language characters need Unicode’s extra bytes — that’s precisely why Unicode exists.
Images are bit patterns too. Every file begins with a signature you can read:
printf '\x89PNG\r\n\x1a\n' | xxd printf 'GIF89a' | xxd
00000000: 8950 4e47 0d0a 1a0a .PNG.... 00000000: 4749 4638 3961 GIF89a
Latency & jitter — ping a public host ten times:
ping -c 10 8.8.8.8
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=12.3 ms ... (9 more) ... rtt min/avg/max/mdev = 11.8/12.5/14.0/0.71 ms
Read it: time= is latency (round-trip delay). On the last line, avg is typical latency and mdev is jitter — how much it wobbles. Low mdev = smooth; high mdev = choppy video calls.
Throughput — run both ends of iperf3 yourself (loopback, or two LAN machines):
# Terminal A (server)
iperf3 -s
# Terminal B (client)
iperf3 -c 127.0.0.1
[ ID] Interval Transfer Bitrate Retr [ 5] 0.00-10.00 sec 52.1 GBytes 44.8 Gbits/sec 0 sender [ 5] 0.00-10.00 sec 52.1 GBytes 44.8 Gbits/sec receiver
That Bitrate is throughput. The Retr column counts TCP retransmits; anything > 0 means some throughput was wasted re-sending — so goodput is a little lower.
Latency along a path, live (press q to quit):
mtr 8.8.8.8
Your node’s interfaces (its links):
ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 192.168.1.23/24 fe80::a1b2.../64
eth0 / wlan0 is a link; 192.168.1.23 is your address on the LAN; /24 is the LAN’s subnet.
The gateway — the “door” to every other network:
ip route
default via 192.168.1.1 dev eth0 ... 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.23
192.168.1.1 is your default gateway (the router) — the exit toward the WAN / Internet.
Neighbour nodes you’ve exchanged frames with (the local ARP table):
ip neigh
Discover every node on your LAN with a ping sweep (your own LAN only!):
sudo nmap -sn 192.168.1.0/24
Nmap scan report for 192.168.1.1 Host is up. Nmap scan report for 192.168.1.23 Host is up. Nmap scan report for 192.168.1.42 Host is up. Nmap done: 256 IP addresses (3 hosts up) scanned
Trace the path to a distant site:
traceroute -n www.google.com
1 192.168.1.1 1.0 ms <- your gateway (your LAN) 2 10.20.30.1 8.4 ms <- your ISP edge (local) 3 100.66.0.5 12.1 ms <- ISP core (regional/national) ... 8 142.250.74.36 30.2 ms <- Google's network (destination)
Each line is one router on the way. Those separate networks, joined end to end, are the Internet — “a network of networks.”
Who owns each hop? — the ISP hierarchy made visible:
whois 100.66.0.5 | grep -iE "OrgName|netname|descr"
Run whois on a few hop IPs and you’ll walk up the tiers: your local ISP, then regional / national backbones, then the destination’s provider.
Distance = latency. Watch per-hop delay climb live:
mtr -n 8.8.8.8
No server to set up — we’ll talk to a real website by hand, in one terminal.
Speak HTTP by hand — type the request exactly (the blank line at the end matters):
printf 'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n' | nc example.com 80
HTTP/1.1 200 OK Content-Type: text/html Content-Length: 1256 ... <!doctype html><html> ... <h1>Example Domain</h1> ... </html>
| Element | In this request |
|---|---|
| Syntax | the exact format: METHOD PATH VERSION, then headers, then a blank line |
| Semantics | meaning: GET = “send me the page”; 200 = OK; 404 = not found |
| Timing | the blank line says “I’m done — your turn”; send it too early/late and the exchange breaks |
Break the syntax on purpose — send nonsense instead of a valid request line:
printf 'BADREQUEST\r\n\r\n' | nc example.com 80
HTTP/1.0 400 Bad Request
Wrong syntax = no communication — exactly the slide’s “connected but not communicating.”
Let a tool obey the rules for you, verbosely (> = your request, < = the reply):
curl -v http://example.com/
Watch the protocol on the wire (second terminal, needs sudo), then re-run Step 1:
sudo tcpdump -i any -A -nn 'tcp port 80'
You’ll see the TCP handshake (timing) and the ASCII GET / HTTP/1.1 (syntax) right inside the packet.
GET /nope HTTP/1.1). Which status code comes back, and what does that show about semantics? (answer below)Lab 1. A walkie-talkie is half-duplex — one person talks at a time. Imitate it on one shared nc chat by agreeing to say “over” and take turns.
Lab 2. 01001000 = 64 + 8 = 72 = the letter H.
Lab 3. The router has lower latency (one hop on your LAN). The server abroad is many hops across the WAN, so its round-trip is much higher — distance & hop count add delay.
Lab 4. A /24 has 8 host bits → 2⁸ = 256 − 2 (network + broadcast) = 254 usable hosts.
Lab 5. Usually hop 2–3 — the first hop whose whois org differs from your router, or where the RTT first jumps. That’s your ISP’s edge.
Lab 6. 404 Not Found. The response is still valid HTTP (same syntax) — only its meaning changed. That’s semantics: the status code carries what happened.
| This lab’s tool | Returns in… |
|---|---|
| tcpdump (Lab 6) | Chapter 2 — Wireshark: the same packets, with a GUI |
| traceroute / TTL (Lab 5) | Chapter 4 & 5 — the IP TTL field and how traceroute exploits it |
| ip / nmap addresses (Lab 4) | Chapter 4 & 6 — IP addressing, masks and subnetting |
| ping / ICMP (Lab 3) | Chapter 5 — ICMP Echo Request/Reply in depth |