Networking 101
Alan Hicks

0. License

1. About this “Class”
1.1 Terms
1.2 Binary Arithmetic

2. Five Layers at a Glance
2.1 Physical Layer
2.2 Data-Link Layer
2.3 Network Layer
2.4 Transport Layer
2.5 Application Layer

3. Physical Layer
3.1 802.3 Cabling
3.2 Voltage Transmission
3.3 Repeaters
3.4 Hubs

4. Data-Link Layer
4.1 MAC Addressing
4.2 Bridges
4.3 Switches

5. Network Layer
5.1 IP Addressing
5.2 Subnetting
5.3 Route Determination
5.4 ICMP
5.5 ARP

6. Transport Layer
6.1 TCP
6.1.1 Ports
6.1.2 Flags
6.1.3 Connection Initialization
6.1.4 Connection Termination
6.2 UDP
6.2.1 Ports

7. Application Layer
7.1 DNS
7.2 DHCP

8. Packet Crafting
8.1 Application Data
8.2 Transport Wrap
8.3 Network Wrap
8.4 Data-Link Wrap
8.5 All Together Now

9. A Day in the TTL of a Packet
9.1 Traversing the Subnet for Fun and Profit
9.2 TCP – SYN to FIN

0. License

Copyright (c) 2007, Alan Hicks, Lizella GA

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections.

1. About this “Class”

This “Class” started out in April of 2007 when I noticed that quite a
lot of people in the Slackware community didn’t know much at all about
TCP/IP. This shocked me quite a bit, as everyone used the Internet
heavily, but not everyone knew much about the underlying protocols that
they used everyday. Many of these people were guys that I respected
for knowing lots of things that I have never had the time or
inclination to learn. So I held an impromptu “class” in the #slackware
channel of to explain some of this.

Many people thanked me for it, and it was logged and saved by several
who then referred it to others. However, I was never terribly
satisfied with it, as I felt the order was somewhat jumbled up as I
spoke on topics as they came up, rather than building upon earlier,
simpler facts. Just the same, you’ll probably have to read through
this twice to make sense of anything. In some respects, networking is
a closed loop. You can’t grasp the whole picture of early concepts
without understanding how they apply to later topics. Here, I try to
setup the most basic foundation in hopes that you’ll understand
everything I intend to get across.

1.1 Terms

In this “class” you’ll see quite a few terms that may not be in your
vocabulary. I’ll try to define a few of them up front.

node (n.) – Any single device on a network. A node can be a computer,
a network-enabled printer, a router, a managed switch, or something

bit bucket (n.) – That place where discarded bits are thrown.

copper (n.) – For purposes of this document, we are only talking about
Cat-5 and similar networking cables that send a signal down pairs of
copper wires. Many other methods of transmitting data are possible,
including fiber-opics, radio waves, even pidgeons (for very low
bandwidth purposes only of course)! Cat-5 and it’s derivatives are the
most common physical media for transmitting data however, so
canonically, copper means Cat-5 and similar cables.

TTL (n.) – Time to Live. In networking, this often isn’t in seconds,
but rather in nodes to traverse before dying.

LAN (n.) – Local Area Network. If you don’t know what this is already,
then this class may be a bit above your head. You need to go back and
take remedial courses.

canonnical (adj.) – The usual way.

1.2 Binary Arithmetic

So you can count to five on your fingers? Good for you. I can count to
31 on just one hand. The secret is binary math. As you probably
already know, computers deal exclusively with 1s and 0s. There is no
number “2” in a computer, nor a number “3”. Every number, every
letter, every pixel, every process is expressed as a string of
seemingly random 1s and 0s. How we determine what a particular string
of 1s and 0s means is what this section is all about.

Back to my example of counting to 31 on one hand. To achieve this
incredibly stupid and mundane feat, I need only look at my fingers as
bits in a computer. If the finger is down, that finger is a “0”. If
it is up, that finger is a “1”.

Decimal Binary
0 00000
1 00001
2 00010
3 00011
4 00100
5 00101
6 00110
7 00111
8 01000
9 01001
10 01010
11 01011
12 01100
13 01101
14 01110
15 01111
16 10000
.. …..
31 11111

Those of you who are particularly smart are thinking “Hmmm…. binary
means two, right? What are the powers of 2?”

Power Decimal Binary
0 1 00000001
1 2 00000010
2 4 00000100
3 8 00001000
4 16 00010000
5 32 00100000
6 64 01000000
7 128 10000000

We could go further out to the nth power, but this is as far as we need
to go for most practical purposes. Here you can easily see what I call
the “Staircase of Two”. Each power of 2 shifts the “1” to the left
just a single bit. Compare the above “base 2” table to the more
familiar “base 10” table.

Power Decimal Base Ten
0 1 00000001
1 10 00000010
2 100 00000100
.. … ……..
7 10000000 10000000

Here you can easily see the “ones place”, the “tens place”, the
“hundreds place” and so on. In binary, we have the same thing, except
that we have a “ones place”, a “twos place”, a “fours place”, an
“eights place” and so on.

Looking back at the binary table, you can see that by adding these
together, we can quickly create any number we choose. Let’s assume we
want to find the binary value of 47. To do this easily, we simply find
the largest power of two that’s smaller than 47, and put a “1” in that
power’s place. Then we subtract that value, and continue on down the
line. So what’s the largest power of 2 that’s not larger than 47? 32
is smaller, and 64 and above are too big, so we know that the first “1”
in our binary number will be in the sixth spot from the right (never
forget that the first place is the power of zero. Computers start
counting at zero, and you should too).

47 – 32 = 15

Our binary number looks something like this now.


What’s the largest power of 2 that’s not larger than 15? Well, the
next “place” in binary is 16, but that’s too large, so we’ll put a “0”


8 works! So there will be a “1” in the fourth place from the right.

15 – 8 = 7


7 – 4 = 3


3 – 2 = 1


1 – 1 = 0


Decimal 47 is Binary 00101111. That wasn’t so bad was it? Working in
reverse is even easier. What’s the value of 11011001? To figure this
out, we simply find the decimal value for each “1” and ignore the
values for each “0”.

11011001 = 128 + 64 + 16 + 8 + 1 = 201

An alternative way to look at this is to say that “11011001” has 1 128,
1 64, 0 32s, and so on.

1101001 = (1 * 128) + (1 * 64) + (0 * 32) + (1 * 16) + (1 * 8) +
(0 * 4) + (0 * 2) + (1 * 1)

You can also look at the decimal (base 10) number the very same way.

201 = (2 * 100) + (0 * 10) + (1 * 1)

Now that you know binary, not only can you count to 31 on one hand, but
you can also understand concepts like IP addressing and subnetting.

2. Five Layers at a Glance

The TCP/IP suite makes use of five different layers to get its job
done. You can think of the layers in much the same way that you think
of a stack of blocks. At the bottom is the physical layer, and at the
top is the application layer. Things start at the top and slowly work
their way down the layers to create a network frame. Each of these
layers will be briefly explained now; we will go into more depth in
later sections.

2.1 Physical Layer

The lowermost layer in our stack of blocks is the physical layer. This
layer consists of basically any physical part of your network.
“Physical” is a bit of a misnomer though, as it includes non-physical
transmission media such as light or radio signals. Basically anything
that is capable of actually transmitting data is part of the physical
layer. This includes network cards, copper wires, fiber-optic cable,
radio waves, and even infra-red light. The physical layer turns the
digital packet into some form of anaolgue signal that can be
transmitted to another node on the network.

2.2 Data-Link Layer

The Data-Link Layer is the first layer of the TCP/IP stack that
actually crafts part of the packet. This layer is also responsible for
determining what machine will receive a packet on any given
network-layer subnet.

2.3 Network Layer

The Network Layer is responsible for addressing hosts that may or may
not be on your particular LAN. It is the only protocol that
understands routing and can address packets to machines not on your

2.4 Transport Layer

The Transport Layer is responsible for communicating between the
Network layer and the Application layer. It is responsible for
determining what application a givin packet will reach. It is also the
only layer that can garauntee data transmission.

2.5 Application Layer

The Application Layer is responsible for formatting the data that will
be transmitted to a remote host. It includes most of the higher order
protocols you may be familiar with such as DHCP, DNS, and HTTP.

3. Physical Layer

As we discussed, the physical layer is responsible for transforming
digital signals. How this happens depends on the transmission media of
course. Fiber-optic cables send light signals of course. Copper wires
transmit data in voltage fluctuations. Radio communications send the
signal along a certain radio frequency. We’ll only discuss the most
common (copper) below.

3.1 802.3 Cabling
802.3 is the IEEE spec that defines ethernet. The most common
transmission media for Internet traffic is copper cable. Ethernet has
reached speeds of 10, 100, 1000, and even 10000 megabits per second
(Mbps). Cabling has changed over time from incredibly thick coax cable
to thin twisted pair copper which is prevalent today. A typical cable
consists for four pairs of copper with each pair twisted about itself.
This twists generates a small electromagnetic shield around the cable
that helps prevent interference and increases the amount of data that
can be sent through the wire in a given period of time.

A typical Cat5e cable is terminated in an RJ-45 connecter that looks
like an oversized phone jack. Inside the cable you will find 4
different colored pairs of wire. In 10/100 Mbps ethernet, only pairs 1
and 2 transmit data. Pairs 3 and 4 are left vacant, but can be used to
power a remote node using Power of Etherner (PoE).

Pair 1: Orange / Orange-white
Pair 2: Green / Green-white
Pair 3: Blue / Blue-white
Pair 4: Brown / Brown-white

Unfortuantely, how these pairs are wired is a little counter-intuitive,
and depends on whether you are using an intermediate hub or switch, or
if you are connecting two Network Interface Cards (NICs) directly. The
typical way of terminating these cables is known as 568B. A 568B
termination looks a bit like this.

RJ-45 Terminator
|| Orange-white ——–||
|| Orange ——–||
=============|| Green-white ——–||
Cat5e Cable || Blue ——–||
=============|| Blue-white ——–||
|| Green ——–||
|| Brown-white ——–||
|| Brown ——–||

If both ends of the cable are terminated in this fasion, then the cable
is called a patch cable. However, if only one end is terminated in the
following fasion, then the cable is known as a crossover cable and can
connect two computers without an intervening switch or hub.

RJ-45 Terminator
|| Green-white ——–||
|| Green ——–||
=============|| Orange-white ——–||
Cat5e Cable || Brown ——–||
=============|| Brown-white ——–||
|| Orange ——–||
|| Blue-white ——–||
|| Blue ——–||

Those of you who are ahead of the class are wondering why this isn’t
necessary if the cable is to be plugged into a hub or switch. The
reason is that certain pairs of wire are for sending data and others
are for receiving data. A hub or switch has these reversed. Here’s a
standard cable for a 10/100Mb ethernet connection with the pairs marked
according to whether they are to transmit or receive data.

NIC Hub or Switch
=================== =================
|| Output —–|| 1 1 ||—- Input ||
|| Output —–|| 2 2 ||—- Input ||
|| Input —–|| 3 3 ||—- Output ||
|| Unused —–|| 4 4 ||—- Unused ||
|| Unusued —–|| 5 5 ||—- Unused ||
|| Input —–|| 6 6 ||—- Output ||
|| Unused —–|| 7 7 ||—- Unused ||
|| Unused —–|| 8 8 ||—- Unused ||
=================== =================

Here, you would want to use a patch cable, as the NIC’s Output lines up
with the hub’s input and vice-versa. A crossover cable simply handles
this for you if the two interface ports have the same pin setup.
Consider this example:

=================== =================
|| Output —–|| 1 1 ||—- Output ||
|| Output —–|| 2 2 ||—- Output ||
|| Input —–|| 3 3 ||—- Ipnut ||
|| Unused —–|| 4 4 ||—- Unused ||
|| Unusued —–|| 5 5 ||—- Unused ||
|| Input —–|| 6 6 ||—- Input ||
|| Unused —–|| 7 7 ||—- Unused ||
|| Unused —–|| 8 8 ||—- Unused ||
=================== =================

If we were to connect a patch cable between these two NICs, no data
could flow through as each NIC would attempt to transmit and receive on
the same pairs. But by connecting a cross-over cable:

=================== =================
|| Output —–|| 1 3 ||—- Output ||
|| Output —–|| 2 6 ||—- Output ||
|| Input —–|| 3 1 ||—- Ipnut ||
|| Unused —–|| 4 4 ||—- Unused ||
|| Unusued —–|| 5 5 ||—- Unused ||
|| Input —–|| 6 2 ||—- Input ||
|| Unused —–|| 7 7 ||—- Unused ||
|| Unused —–|| 8 8 ||—- Unused ||
=================== =================

… everything flows smoothly.

3.2 Voltage Transmission

So now that we know what each cable is for, and how to wire up a cable,
how does a NIC actually transmit data? To understand this, we have to
answer the age old question: “What is digital anyway?” A google search
will return all kinds of definitons for “digital”, but none of them are
very clear unless you already understand “digital”. Here is my simpler
definition. “Digital” is just a way of interpreting an anaolgue signal.

Your copper cable always carries a voltage, and as this voltage
changes, the remote NIC interprets this change as either a 1 or a 0.
Let’s assuming your NIC is capable of procucing voltages between 1 and 5
volts and that above 3 Volts is considered a “1” and below 3 Volts is
considered a “0”. Voltage always changes on a curve that resembled a
sine wave (yes, you should have paid attention in your high school Trig
class). Another one of my insanely ugly ASCII-art graphs follows

5 | . . .
4.5 | . . . .
V 4 | . . . .
o 3.5 | . . . .
l 3 | ===========================================================
t 2.5 | . . .
s 2 | . . .
1.5 | . . .
1 | . . .
| 0 | | 1 | | 1 | | 0 |

This should clearly show how changing voltage, even though the change
is analogue, can be interpreted as ones and zeros digitally.

3.3 Repeaters

A repeater is really a simple device that takes a signal in and
amplifies it. Repeaters are necessary to send data along particularly
long cables because the signal tends to degrade at distances longer
than 100 meters. So if you wanted to ensure the integrity of a
transmission between two nodes that were 200 meters apart, you would
use two 100 meter long cables and connect them to a repeater in the
middle. Simple, yes?

3.4 Hubs

Hubs are devices with lots and lots of ethernet ports and basically
“split” a cable so that a single packet reaches multiple nodes. A
hub’s singular function is to accept signals on any of its interfaces,
and propogate those signals down all of its other ports. Basically, a
hub is nothing more than a multi-port repeater. Use of a hub allows
one node to contact multiple other nodes. Today, however, hubs have
fallen out of favor due to the prevalence of switches (we will discuss
switches below) for a variety of reasons. The main problem with a hub,
is that only one node may send data at a time, and each node is
reponsible for collision detection. Collisions occur when more than 1
node attempts to send data at a time. Most hubs are capable of
disconnecting a node that is producing more than its fair share of
collisions, preventing a single mis-behaving machine from bringing down
the entire network, but this is still far from an ideal solution.

Hubs are considered “dumb” devices, because they replicate data
unneccessarily. Only the single machine that a packet is destined for
needs to receive the packet, but a hub has no way of knowing what that
machine is, or even where it is located. Thus, a hub just “spams” each
signal it receives to every machine it can reach.

I am reminded of a joke told by the famous country comedian and Grand
Ole Opry star Minnie Pearl that is perhaps the best analogy to the way
a hub works that I can think of.

“I was going down to the store here in Nashville the other day and this
city slicker laughed as I walked by. He turned around to his friend
and says ‘She don’t look very country to me.’ His friend he laughed
and said ‘Yeah, I bet she couldn’t tell a goose from a gander.’ I
tried to ignore them, but I just couldn’t help myself so I walked over
and promptly told them ‘Well now in Grinder’s Switch we don’t worry
about that, we just put ’em all in a pen together and let ’em figure it
out for themselves.”

This is precisely how a hub works. A gander (male goose) wants to talk
to the female of the species, so he goes over to Minnie Pearl and honks
at her. She doesn’t know who he wants to speak with and really doesn’t
care, so she tosses him in a pen with all the other geese. Every
single goose (whether a goose or a gander) gets to hear our gander
honk, and every other one ignores our gander unless it happens to be
the goose our gander wants to talk to.

Looking back on it, maybe that isn’t the best analogy of a hub? :^)

4. Data-Link Layer

This is the layer where things actually get interesting. The Data-Link
Layer is responsible for sending packets “somewhere”, even if
“somewhere” isn’t their final destination.

4.1 MAC Addressing

Every NIC, every switch, every modem, every device that connects to a
network has a Media Access Control (MAC) Address that is set by the
device’s manufacturer and is generally unchangeable. This address
uniquely identifies a single device on a network segment, allowing us
to address data for that particular device. In an ethernet frame, we
include two of these, a destination MAC address, and the source MAC

When you send a packet, the packet is tagged with your MAC address as
the “source MAC”, and you will set the “destination MAC” to the address
of the node you wish to reach, or to your router’s MAC address if the
final node isn’t on your subnet. This will all make more sense when we
look at the Network Layer.

4.2 Bridges

Bridges were designed as a way of limiting collisions on a network
using hubs to connect many different machines by “partitioning” the
network. A bridge is basically a dedicated computer with more than one
NIC that sits between two or more hubs. A bridge works like a hub, but
with one exception. A bridge has “brains” and can “remember” what
machines are on either “side” of it. When it receives a packet, it
consults its memory to see if the destination MAC is on the same
interface that the source MAC was on. If so, it discards the packet.
However, if they are on different interfaces, it propogates the packet
only along the proper interface. A couple of diagrams may help

======================= =======================
| Hub A |——————–| Hub B |
======================= =======================
| | | |
| | | |
========== ========== ========== ==========
| Node 1 | | Node 2 | | Node 3 | | Node 2 |
========== ========== ========== ==========

In this example, if Node 1 sends a packet to Node 2, the packet
traverses both hubs, so nodes 2, 3, and 4 will all see the packet.
Only node 2 will act on it, and the others will ignore it. Obviously,
this is less efficient since every single node has to do collision
detection for three other nodes.

======================= ========== =======================
| Hub A |—–| Bridge |—–| Hub B |
======================= ========== =======================
| | | |
| | | |
========== ========== ========== ==========
| Node 1 | | Node 2 | | Node 3 | | Node 2 |
========== ========== ========== ==========

In this example network, if Node 1 sends a packet to Node 2, both Node
2 and the bridge see the packet. Node 2 accepts the packet, and the
bridge silently drops the packet to the bit bucket. Now suppose Node 1
sends a packet to Node 3. Node 2 and the bridge will see the packet.
Node 2 will drop the packet in its bit bucket, but the bridge will send
the packet over to Hub B where both Node 3 and Node 4 will see it.
Node 3 will act on the packet and Node 4 will ignore it. This is much
more efficient as each node only has to do collision detection for two
other devices (the other node on its hub, and the bridge). You can see
how this improves things if you have dozens or hundreds of nodes on a
hub network. Today however, bridges have lost their role as
performance enhancers due to the prevalence of switches, and you’ll
soon find out exactly why. Bridges are primarily used today as
specialized devices such as transparent firewalls or data filters, but
that is a discussion for a future class.

4.3 Switches

At first glance, switches are indistinquishable from hubs. They look
identical, but the magic is all on the inside. Whereas hubs operate
entirely on the physical layer, a switch steps up to the data-link
layer and functions more like a bridge than a hub. If you recall from
the earlier example, every node on a hub has to do collision detection
and prevention with every other node on the hub and any other hubs that
are directly attached to it. If a node is attached to a switch on the
other hand, it only has to avoid collisions with the switch itself.
How is this possible? Well, that’s where the magic comes in.

Imagine if you will, that every single port on a hub was a bridge.
This bridge would only send any given packet directly to the single
machine the packet is destined to. This is exactly how a switch
operates. By “memorizing” the MAC addresses of all devices attached to
it, a switch is capable of looking at a packet’s destination, and
sending the packet out only the single port that the destination node
is attached to. This means that on a switch, a machine will only see
packets that are intended for it. Not only does this prevent
collisions, but it also increases overall throughput as multiple
machines may send packets at the same time. Another ugly diagram.

| Switch A |
| 1 | | 2 | | 3 | | 4 | | 5 | | 6 |
===== ===== ===== ===== ===== =====
| | | | | |
| | | | | |
========== ========== ========== ========== ========== ==========
| Node A | | Node B | | Node C | | Node D | | Node E | | Node F |
========== ========== ========== ========== ========== ==========

This is a typical 6-port switch with 6 nodes attached to it. Say that
Node A wants to send a packet to Node B. The switch receives the
packet on port 1, looks at its ARP table, and determines that the
packet is destined for Node B, which it knows is on port 2. The packet
is sent out port 2, and only out port 2. Nodes C, D, E, and F never
see the packet and in fact, will never even know it existed. Moreover,
Node C can send Node D a packet at the same time without fear of
collision, since the packets don’t travel on the same physical link.

It’s important to remember that switches are *not* security devices,
but rather performance devices. It is possible to flood a switch’s ARP
table and make it either crash, or convert to working as a hub
depending on the make and model. You should never rely on a switch as
a way of preventing disclosure of information.

5. Network Layer

This is without a doubt the funnest, and most difficult layer to truely
learn. Without this layer, no machine could address any other machine
without knowing its MAC address, and those machines would have to be on
connected hubs, bridges, and switches. The Network Layer is
responsible for determining the final destination of a packet and
determining just how to get there from here.

5.1 IP Addressing

Alright, so you all know what an IP address is don’t you? Everyone has
one these days. In fact, some of us have lots of them. They’re those
funny little numbers like What do they mean? Why
can’t I just use whatever numbers I want there? And why do they only
go up to 255?

Simply put, an IP address is a 32-bit binary number. It’s a string of
1s and 0s 32 digits long. For various reasons, we split that 32-bit
number up into 4 8-bit numbers. Let me use a common example. is a common IP address on many private networks as it’s
one of the most easily remembered default IP addresses for a private
LAN. (We’ll discuss private IP ranges later. For now, play along.)
What does the computer see when we send a packet to this address? To
answer that question we need to know something about binary arithmetic.
If you boldy skipped section 1.2, shame on you! Go back and read it
now before proceeding further, as I won’t explain it again. = 11000000.10101000.00000001.01100110

In reality, the dots don’t exist. They are only there to help us work
with four 8-bit numbers instead of 1 big 32-bit number. In reality,
the computer just sees “11000000101010000000000101100110”.

So now you know what an IP address is. Just like with the MAC address,
every packet has a Destination IP Address and a Source IP Address.

5.2 Subnetting

Subnetting today is properly called “Classless Inter-Domain Routing”
and is formally described in the RFCs 1518 and 1519.

Subnetting is a way of determined what IP addresses are on our network.
Basically, it tells us what nodes we can talk to directly without
communicating through a router of some sort. You’ve probably seen
subnets like or heard of them talked about as, but what do those numbers mean?

A subnet mask (or just a net mask for short) is a bit mask that
basically tells the computer not to look at certain numbers. To
understand this, we have to look at those numbers in binary. = 11111111.11111111.11111111.00000000 = 11000000.10101000.00000001.01100110

In this example, a node (be that a computer, a managed switch, a
router, or something else) can look at these two numbers and self to
itself “looks like all numbers that begin 192.168.1 are on the same

Another way of looking writing this is The /n tells
us how many bits is in the bitmask. In this case, 24.

/24 = 11111111.11111111.11111111.00000000 = 11000000.10101000.00000001.01100110

A helpful little table here should help you understand the basics.

Subnet Bitmask Value
=============== ======= =================================== /32 11111111.11111111.11111111.11111111 /31 11111111.11111111.11111111.11111110 /30 11111111.11111111.11111111.11111100 /29 11111111.11111111.11111111.11111000 /28 11111111.11111111.11111111.11110000 /27 11111111.11111111.11111111.11100000 /26 11111111.11111111.11111111.11000000 /25 11111111.11111111.11111111.10000000 /24 11111111.11111111.11111111.00000000 /16 11111111.11111111.00000000.00000000 /8 11111111.00000000.00000000.00000000 /0 00000000.00000000.00000000.00000000

This is a table of the most common subnets you will run across from the
smallest (/32, a single node) to the widest (/0, everything).

The number of address on a given subnet is easily found using the
following formula.

max_addr = 2^(32 – bit_mask)

So, if your bitmask is /32…

max_addr = 2^(32 – 32) = 2^0 = 1

If it’s /24…

max_addr = 2$(32 – 24) = 2^8 = 256

But what IP addresses are included in one of those subnets? It’s easy
to figure out that means all addresses from
to, but what about some obscure ones like To determine this, we’ll have to simply count up
from 0.

A /29 subnet has 8 IP Addresses, meaning that there is exactly 32 /29
subnets inside a /24 subnet. Let me make another table.

Subnet Min IP Max IP
====== ====== ======

An alternative way of looking at this is to split the subnets one at a
time. Here we start with a known /24 and break it down into two /25s.
Whichever /25 contains our IP address will be broken down into two /26s
and so on until we reach the final /29.

Subnet Min IP Max IP
====== ====== ======

Simple, right? Well, it used to be even simpler when we only had three

Years ago, when the Internet was young, there were only three subnets.
These were believed to be sufficient at the time, because the Internet
was mostly private, very small, and no one dreamed that so many people
would be on it today. (Technically, there were others as well, but
they were restricted to specialty uses such as multi-cast. We will not
discuss them further.)

Class Network Addresses
===== ======= =========
A 16,777,216
B 65,536
C 256

If an organization needed 300 IP addresses, they were given 65,536. If
they needed 100,000, they were given 16,777,216. Clearly this was very
wasteful, and created shortages. To address this, subnetting was
invented, allowing organizations such as ISPs to get only as many IPs
as they needed (or pretty close to it). If I need 300 IP addresses, I
don’t need a /16. A /25 includes 512 IP Addresses, and that’s more
than enough without waisting the other 65,024. Today, you’ll still
hear this terminology from time to time. People often refer to any /24
subnet as a “Class C” network for example.

5.3 Route Determination

Finally! Things have gotten interesting. At last we have come to that
part of networking that allows us to send information in the form of
packets to places that we’ve never seen. Subnetting tells us what IP
Addresses we should be able to communicate with without going through a
router, but what about other IP Addresses?

Every computer has a routing table, though it looks different depending
on your operating system. Here’s what my routing table currently looks
like on Slackware Linux 12.0.

root@robin:~# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface U 0 0 0 eth0 U 0 0 0 lo UG 0 0 0 eth0

This should be fairly self-explainitory. When a packet is sent out to
an IP Address, the kernel begins checking the Destination IP Address
against the “Destination” column of the routing table until it finds a
match. The last row “” is a catch-all. Whenever it finds a
match, it acts on it based on the rules in the other columns.

Let’s try an example. My computer (robin, wishes to send
a packet to another (solitude, It forms a packet and
sets the Destination IP Address to The kernel checks
its routing table and finds a match.

Destination Gateway Genmask Flags MSS Window irtt Iface U 0 0 0 eth0

The first thing it checks for is the use of a “Gateway” (or router). In
this case, Gateway has the value of Next, it looks at
“Genmask”, which tells the kernel the subnet mask for that
“Destination”, in this case The next field is “Flags”
and has the value “U”, telling the kernel that this route is “up”. Of
the rest of the columns, only “Iface” is of any concern to us right
now. (For more information, check the man page for route(8).) This
tells the kernel what interface to send the packet out, in this case,

Now, another example. Suppose robin wants to talk to
which it learns has an IP address of The kernel begins
to check the routing table and find no match until it reached the

Destination Gateway Genmask Flags MSS Window irtt Iface UG 0 0 0 eth0

In this example, the “Flags” are “UG”. According to the man page for
route(8), this means that the route is up, and tells the kernel to use
the “Gateway” The packet will also leave interface
eth0. Simple enough? Let’s look at the routing table of the router
that robin is using.

root@sanctuary:~# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface U 0 0 0 eth1 U 0 0 0 eth0 U 0 0 0 lo UG 0 0 0 eth1

Note that the first route is a /27 network containing 16 IP addresses.
The second is a typical /24 private network. robin, solitude,
sanctuary, and a host of other machines are on the
subnet. Meanwhile, sanctuary’s default gateway is located on the subnet.

That packet robin sends to google will be received by sanctuary on
eth0. Since sanctuary doesn’t know anything about the IP
Address, the packet is caught by sanctuary’s catch-all route and sent
to its router, That address is in turn matched by the “Destination” and sent of “Iface” eth1.

It’s important to note that no packet is transmitted to an IP Address.
IP Addresses are merely used to determine the route that a packet must
take to reach its eventual destination. Packets are instead
transmitted to MAC Addresses. This will all make sense later when we
put everything together.

5.4 ICMP

ICMP is formally described in RFC 792.

Internet Control Message Protocol, or ICMP for short, is mostly used to
transmit error messages between machines. For example, if a router
can’t seem to find a node you’re attempting to communicate with, you
may see an “ICMP Destination Unreachable” error message. ICMP is used
to transmit the most basic of information between nodes, and is highly
specialized to this task to the point that it cannot carry arbitrary
data in the way that TCP or UDP can (more on these later). Each ICMP
packet is given a certain “type” that specifies its use. Certain types
may have a (sometimes optional) data section that can carry some small
amount of arbitrary data.

The most common intentional use of ICMP by a user is the ping(8)
program. ping generates an ICMP type 8 packet. Type 8 is known as the
“Echo Request”. When a machine receives such a packet, it replies to
it with an ICMP type 0 “Echo Reply” packet.

Another common way of using ICMP is the traceroute(8) command. This
works by generating UDP packets with very short Time To Live (TTL)
values. If a router sees a packet with a TTL value of 0, it will send
out an ICMP type 11 “Time Exceeded” packet. Since every router that
handles a packet must decriment the TTL value by 1, this creates an
easy method of seeing what routers (and how many) two nodes are
communicating through.

By far the most common uses of ICMP packets however, are those you
never see. ICMP will send error messages telling a sending node that
no more bandwidth is available. It will tell the sending node to
redirect a message to a different route. In short, ICMP is the often
unseen little janitor of the TCP/IP Suite that keeps everything clean
and tidy and informs everyone when the floor is wet and slippery.

5.5 ARP

ARP is formally described in RFC 826.

ARP is a protocol used to resolve hardware addresses from network
addresses. Canonically, this means that if you know a node’s IP
Address, you’ll use ARP to discover its MAC Address. Simple, right?
ARP packets are non-routable, so they will only tell you the MAC
Addresses of nodes on your LAN. A typical ARP dialogue looks like

robin: “Hey! Who out there is”
solitude: “Huh? Oh that’s me! I’m 00:B0:D0:23:62:F2.”

And now robin knows that maps to 00:B0:D0:23:62:F2.
That’s really all there is to it. We’ll show some actual examples
later which will help you better visulalize this.

6. Transport Layer

The Transport Layer is every bit as simple and complex as the network
layer. It is responsible for communicating the wishes of the
Application Layer with the Network Layer, and in some cases, is
responsible for ensuring that data arrives at its destination. You
might think of the Transport Layer as a postman. He accepts letters
(data) from you, and passes them off to be routed to their final
destination. If you have to be certain the letter arrives at its
destination, you can send it certified mail and get reasonable
confirmation that it was indeed delivered.

6.1 TCP

TCP is formally described in RFC 793.

Transmission Control Protocol is the most widely used protocol in the
transport layer, and the only thing in the entire TCP/IP suite that
garauntees delivery of packets by using some fairly ingenious
techniques. To start, TCP marks every packet with a sequence
identification number. In the event that some packets are received out
of order, the receiving node can re-arrange them correctly. Also, TCP
requires an acknowledgement of receipt for every packet, so the sending
node knows without doubt if a packet was received. Finally, TCP
includes a rudimentary checksum to verify that the data sent has not
been changed en route.

TCP is known as a “connection oriented” protocol, because it sends all
data in the framework of an open connection, rather than simply firing
the data off like every other protocol and hoping the destination node
receives it.

6.1.1 Ports

Ports are a way of communicating with the Application Layer. TCP has
65,536 total ports. Every TCP packet has a Source Port and a
Destination Port. When a TCP packet is received, the kernel looks at
the port number (1 – 65,536) and determines what application to send
the data to based on this information.

6.1.2 Flags

TCP makes use of a number of “Flags” to specify the type of TCP packet
in much the same way that ICMP does. Unlike ICMP, a TCP packet can
have multiple flags set at the same time. In this document, we’re only
going to discuss the four most common.

SYN – Synchronize and prepare for a connection
ACK – Acknowledge that a packet has been received (and which one)
FIN – Finished sending data
RST – Reset connection immediately

6.1.3 Connection Initialization

The three-way handshake is used to initiate a TCP connection. It’s
responsible for ensuring that both end nodes are available and are
ready for data to be transmitted.

Let’s assume that robin decides to get some files from solitude on a
TCP connection. First, robin sends a packet to solitude telling him
that robin is trying to initiate a TCP connection with a SYN packet.

As soon as solitude receives this packet, he knows that robin wants to
talk to him and acknowledges it with a SYN-ACK packet.

Finally, when robin receives this packet, he replies with an ACK to
solitude. This packet is sometimes called the SYN-ACK-ACK packet, but
it’s really just an ACK packet. Anyhow, this lets both nodes know that
everything is ready to roll. It all goes something like this.

robin to solitude – SYN
solitude to robin – SYN-ACK
robin to solitude – ACK

At this point, they are ready to transmit information. Robin can send
TCP packets without any flags and solitude will reply to each packet
with an ACK so robin knows the data was received. If for whatever
reason, robin doesn’t see an ACK packet for some data it sent, it will
resend that packet.

6.1.4 Connection Termination

So now that we know how to initiate a TCP connection, how do we stop
one? The answer is the four-way handshake.

To stop a TCP connection gracefully, both sides must agree that all
data transmission has finished. When each node has completed all the
transmission it intends to do, it will send a FIN packet. This is
responded to by an ACK. Once both nodes have sent FIN and ACK packets,
the connection is over. The reason that both nodes must agree that a
transmission is over is simple. One node may no longer wish to send
data, but the other still has lots to transmit. When one node has
finished a connection but the other hasn’t, the connection is called

Here’s an example. Going back to robin and solitude, robin has
requested a rather large file be sent to him. Once this file has begun
transmission, robin decides that he no longer wishes to send anymore
requests and gives solitude a FIN packet. solitude ACKs the FIN, but
continues to send that large file until that is complete before sending
its own FIN. Here we will begin with the three-way handshake, begin
transmitting data, and end with a four-way handshake.

Sender Receiver Flags Content
====== ======== ===== =======
(three-way handshake)
robin solitude SYN
solitude robin SYN-ACK
robin solitude ACK
(begin data transmission)
robin solitude Give me BIG_FILE
solitude robin ACK
soliude robin BIG_FILE part 1
robin solitude ACK
soliude robin BIG_FILE part 2
robin solitude ACK
soliude robin BIG_FILE part 3
robin solitude ACK
soliude robin BIG_FILE part 4
robin solitude ACK
(begin four-way handshake)
robin solitude FIN
solitude robin ACK
(half-open connection)
soliude robin BIG_FILE part 5
robin solitude ACK
soliude robin BIG_FILE part 6
robin solitude ACK
soliude robin BIG_FILE part 7
robin solitude ACK
soliude robin BIG_FILE part 8
robin solitude ACK
(complete four-way handshake)
solitude robin FIN
robin solitude ACK
(connection tore down)

There is one other way to tear down a TCP connection, and that is the
deadly RST packet! When one node sends the other node an RST packet,
everything is over. Both nodes immediately cease transmiting data and
close the connection.

6.2 UDP

UDP is formally described in RFC 768.

UDP is, quite simply, the retarded cousin of TCP. UDP’s one and only
focus is to communicate between the Network Layer and the Application
Layer. At first glance, it looks a lot like TCP, but unlike it’s
genious cousin, UDP can’t work on connections. Rather, UDP simply
“fires and forgets”. This is actually preferred for many forms of
transmission. Since UDP doesn’t clutter up things witk sequence
numbers, flags, handshakes, and acknowledgements, it can transmit data
a lot faster than TCP. For anything that needs to function in
real-time, like a video game or streaming audio, it’s preferable to
loose some data or have it arrive out of order rather than waiting for
out of sequence information to be resent.

6.2.1 Ports

UDP ports work exactly the same way that TCP ports do. They are simply
placeholders that tell the kernel what application to hand the data off
to. It’s important to note though, that UDP and TCP ports are
exclusive. UDP port 80 and TCP port 80 are entirely different and may
go to different applications.

7. Application Layer

The Application Layer is responsible for talking to the Transport
Layer, and finally talking to the kernel or any user-land applications
that make network requests. We won’t go into much detail here, as
there are literally hundreds of common protocols, thousands of uncommon
ones, and untold millions of network applications. There are however,
two notable protocols that bare mentioning here as they allow are
responsible for setting things up for the Network Layer.

7.1 DNS

As we all know, computers work with numbers, and in networking, those
numbers usually take the form of IP Addresses. But human beings aren’t
good at remembering long strings of numbers, otherwise we’d not call
computers by names. The Domain Name System (or Service) is what allows
us to turn domain names like into IP Addresses
like DNS will play a key roll in some of the examples
we will use in later sections.

7.2 DHCP

The Dynamic Host Control Protocol is an ingenious method of assigning
IP Addresses to nodes. Instead of requiring a person to input an IP
Address for a machine, DHCP will instead assign that, along with a lot
of other helpful network information for him. DHCP operates by sending
a UDP packet to the broadcast address Unless a
machine is acting as a DHCP server, the packet will be silently
dropped. But, a DHCP server will reply with another packet that
includes all the information that machine needs to setup basic network
services: IP Address, Subnet Mask, Routers, DNS Servers, and optionally
much much more.

8. Packet Crafting

So now that we know about all the different layers and all the
different things that play a part in networking, let’s build an actual
packet, hand-crafted with love. For our purposes, we’re going to skip
DNS and assume we know the IP Addresses. This is a data packet being
crafted by ( destined for the
webserver at (

8.1 Application Data

All packets begin at the Application Layer. In this case, our
application is Firefox. I’ve just opened it on my laptop, and am in
the process of making a request for Since I’m
making an HTTP connection (that’s what that whole http:// thing is all
about after all), Firefox knows that I’m making a TCP connection to
port 80 at But first, it has to form the data portion of
the packet. This data portion is referred to as the packet’s
“payload”. Every other portion of a packet is designed to get the
payload to its destination and has no meaning outside of that.

At this point, our packet is nothing but a payload and looks like this:

| Payload |

8.2 Transport Wrapping

Here things become interesting. This is the first layer that will add
information to the payload and begin forming something more than just
raw data. Here, we add a number of fields. This adding of fields is
known as “wrapping” because of the way it encapsulates higher layers in
lower layers. I won’t go into details on all of the possible fields,
but pretty much everything is shown below.

| Src Port | Dst Port |
| Sequence Num |
| Acknowledgement Num |
| Data Offset | Reserved | Flags | Window |
| Checksum | Urgent Pointer |
| Options |
| Payload |

Source Port – 16 bits
Destination Port – 16 bits
Sequence Number – 32 bits
Acknowledgement Number – 32 bits
Data Offset – 4 bits
Reserved – 4 bits
Flags – 8 bits
Window – 16 bits
Checksum – 16 bits
Urgent Pointer – 16 bits
Options – 32 bits (if present)

Notice how I have divided up the lines into discrete 32-bit segments?
This is perhaps the easiest way to look at the actual data of a packet,
in binary 32-bit words. Each line is one word.

Here we’ve added the “Source Port”, “Destination Port”, “Sequence
Number”, “Acknowledgement Number”, “Data Offset”, “Reserved”, “Flags”,
“Window”, “Checksum”, “Urgent Pointer and “Options” fields. We haven’t
previously discussed several of these fields, so now’s the time to do
just that.

Data Offset – This is the size of the TCP Header in 32-bit chunks (or
words). This lets us know exactly where the header ends and the
Payload begins.
Reserved – These bits aren’t currently used and should always be 0.
Flags – Each bit represents a different flag: SYN, ACK, FIN, ACK, and
Window – this is basically the most data that the destination node
can receive at a time.
Checksum – this is just a basic error-checking routine similar to
the parity bit in ASCII.
Urgent Pointer – this is largely unused and we won’t muddy the waters
by discussing it now.
Options – Another mostly unused field that we will ignore in this

8.3 Network Wrapping

Now we get to add actual routing information to the packet.

| Version | Header Length | Type of Service | Total Length |
| Identification Number | Flags | Fragment Offset |
| TTL | Protocol | Header Checksum |
| Src Addr |
| Dst Addr |
| Options |
| TCP Header |
| Payload |

Version – 4 bits
Header Length – 4 bits
Type of Service – 8 bits
Total Length – 16 bits
Identification Number – 16 bits
Flags – 3 bits
Fragment Offset – 13 bits
TTL – 8 bits
Protocol – 8 bits
Header Checksum – 16 bits
Source Address – 32 bits
Destination Address – 32 bits
Options – 32 bits

The first thing you’ll notice is that rather than repeat everything we
just did in “Transport Wrapping”, we just referred to it as the “TCP
Header”. Now let’s discuss those parts of the IP Header.

Version – Either 4 or 6 for IPv4 or IPv6. In this document, we only
discuss IPv4. Just know that the version can also be 6.
Header Length – This is basically identical to the Data Offset we saw
in Transport Wrapping. It is the entire length of the IP Header.
Type of Service – This was originally intended to specify a
preference for fast transport or higher reliability. It is now
almost entirely unused.
Total Length – The total length of the packet. Header Length tells
us where the IP Header ends. Total Length tells us where the
entire packet ends.
Identification Number – This is used for identifying IP fragments.
Fragments are created when a node can’t deal with the entire
packet at once, so the packet is split (fragmented) into smaller
packets and each is given an Identification Number. Otherwise,
this is set to 0.
Flags – Used to enforce or deny fragmentation.
Fragment Offset – If the packet is a fragment, this is the number of
bytes that have been handled by previous fragments.
TTL – the number of intermediary routers allowed to handle the
packet before failing. This field gets decrimented each time
a router handles it.
Protocol – What Transport Layer protocol we are using. In
this particular example, it’s TCP, but it could be UDP as well.
This is necessary so the receiving node (or any firewalls in
between) don’t confuse the Transport Layer’s header.
Header Checksum – Similar to the TCP Checksum, except that this
has to be recalculated at each point because the TTL value
has changed.
Source Address – The IP Address of the original sending node.
Destination Address – The IP Address of the final receiving node.
Options – Again, a variable length field that can contain a lot
of optional data.

Now things are starting to look like a packet!

8.4 Data-Link Wrapping

Now we get to the final step of adding information to the packet.

| Dst MAC |
| Src MAC |
| IP Header |
| TCP Header |
| Payload |
| Checksum |

Destination Mac – 48 bits
Source Mac – 48 bits
Checksum – 32 bits

This is all pretty self-explainatory. The only part we haven’t
discussed previously is “Checksum”.

Checksum – a standard cyclic redundancy check to check for errors.
This is very similar to an md5sum in many ways.

At this point, the packet is ready for transmission on the physical

8.5 All Together Now

Now that we’ve lovingly crafted a packet by hand, let’s fill in the
values for this packet, and see how it fairs out in the real world.
Here, we’re going to assume that (
wishes to serve an HTTP document to
( We’ll just call the payload “Payload” rather than
create a fictional web page to include there. :^) Some of the other
data will be fictionalized as well, such as Data Offset and Total
Length. In no cases is any fictional data important to the
understanding of the concepts discussed here

As much as possible, I’ll use binary values to show information.

To start, we’ll just look at the transport headers and add on other

| Src Port | Dst Port |
| Sequence Number |
| Acknowledgement Number |
| Data Offset | Reserved | Flags | Window |
| Checksum | Urgent Pointer |
| Options |
| Payload |


Type Binary (0 – 15) Explaination
—- —————- ————
Source Port 0000000001010000 80
Destination Port 0011001101011001 13145
Sequence Number 0000000000000000 1
Acknowledgement Num 0000000000000000 0
Data Offset 0101 5
Reserved 0000 (Not Used Here)
Flags 00000000 (No Flags Set)
Window 0000000000000000 (Not described here)
Checksum 0010010010101101 (Made up checksum)
Urgent Pointer 0000000000000000 (Not Used Here)
Options (Not Included) (Not Used Here)

As you can see, this packet is leaving port 80, going to port 13,145,
and is the first packet in the sequence. Since there are no flags set,
we know this isn’t a SYN, ACK, FIN, RST, or any other special TCP
packet. This is just a plain old packet that sends data in a
connection that has already been set up. Since this isn’t an ACK
packet, the Acknowledgement Number is set to “0”. As you can clearly
see, there are 5 32-bit “words” before we reach the payload, so our
Data Offset is set to “5”. Easy isnt’t it? The Checksum was simply
made up by me.

Now that we’ve got the Transport layer finished, it’s time to add on
the Network Layer.

| Version | Header Length | Type of Service | Total Length |
| Identification Number | Flags | Fragment Offset |
| TTL | Protocol | Header Checksum |
| Src Addr |
| Dst Addr |
| Options |
| TCP Header |
| Payload |

|———-TCP Header———-|

Type Binary (0 – 15) Explaination
—- —————- ————
Version 0100 4
Header Length 0101 5
Type of Service 0000000 (Not Used)
Total Length 00010110010010100 11412
Identification 00000000000000000 (Not Used)
Flags 000 (No Flags)
Fragment Offset 0000000000000 (Not Used)
TTL 00100000 32
Protocol 00000110 5 (TCP)
Header Checksum 0010100000101000 (Made up checksum)
Source Addr 0100000110110010
Destination Addr 1101000000111110
Options (Not Included) (Not Used Here)

Last but not least, we’ll wrap the packet at the Data-Link Layer.

| Dst MAC |
| Src MAC |
| IP Header |
| TCP Header |
| Payload |
| Checksum |

|———-IP Header———–|
|———-TCP Header———-|

Type Binary (0 – 15) Explaination
—- —————- ————
Destination Mac 0000000000110000 00:30:88:01:df:c8
Source Mac 0000000010100000 00:a0:cc:db:1a:1a
Checksum 1010010001110101 (Made up checksum)

In this case, the Destination MAC Address is the MAC Address of
barnowl’s router and the Source MAC Address is the MAC Address of
barnowl himself. Always remember that these two values change
everytime you traverse a subnet.

So, what does the entire packet look like?



– Destination MAC Address
– Source MAC Address
– Version
– Header Length
– Type of Service
– Total Length
– Identification
– Flags
– Fragment Offset
– Transport-Layer Protocol
– TCP Header Checksum
– Source Addr
– Destination Address
– Options
– Source Port
– Destination Port
– Sequence Number
– Acknowledgement Number
– Data Offset
– Reserved
– Flags
– Window
– Checksum
– Urgent Pointer
– Options
– Payload
– Data-Link Layer Checksum

9. A Day in the TTL of a Packet

Well, we’ve constructed packets and we’ve learned what everything does.
Now it’s time to look at sets of packets.

9.1 Traversing the Subnet for Fun and Profit

I’ve told you that a packet changes; well, now it’s time to learn just
how it changes. To start with, everytime a packet crosses a router, it
gets an entirely new Data-Link Layer header. This is necessary because
every piece of information changes to facilitate transmisison to the
next hop in its route. Here’s an example traceroute to show all the
routers a packet must traverse to reach its final destination. (Note
that this is different for any two end-points.)

alan@barnowl:~$ traceroute
traceroute to (, 30 hops max, 38 byte packets
1 ( 10.995 ms 10.719 ms 10.061 ms
2 ( 11.065 ms 17.416 ms 11.568 ms
3 ( 28.803 ms 28.021 ms 27.323 ms
4 ( 52.084 ms 49.295 ms 48.048 ms
5 ( 48.053 ms 48.754 ms 46.608 ms
6 ( 46.302 ms 48.079 ms 48.281 ms
7 ( 48.547 ms 47.749 ms 48.046 ms
8 ( 91.512 ms 92.027 ms 50.797 ms
9 ( 46.791 ms 66.366 ms 46.293 ms
10 ( 47.392 ms 48.306 ms 48.727 ms
11 ( 54.673 ms 54.511 ms 56.307 ms
12 ( 55.511 ms 54.668 ms 61.301 ms
13 ( 53.960 ms 55.394 ms 54.176 ms
14 ( 55.427 ms 54.033 ms 54.917 ms
15 ( 54.133 ms 54.531 ms 54.634 ms
16 ( 54.458 ms 55.880 ms 60.577 ms
17 ( 55.187 ms 56.556 ms 55.906 ms

Here we can see that we’ll have to make 17 hops to reach our
destination. I’m only going to detail one of these hops in addition to
those fields in the packet header that are prone to change. We’re
going back to the example of serving part of an
HTTP document to Here’s our packet again.

|——–TCP Header————|

When barnowl’s router receives this packet, the first thing it does is
strip the Data-Link Layer away. Everything in this layer will be

|———-TCP Header———-|

At this point, the router will decriment the TTL value
by 1 and re-value the Header Checksum. (Again, I’m filling in random
values for the checksum.)

|———-TCP Header———-|

The TTL has been decrimented from 01000000 to 00111111 (63). Now it’s
time for a routing decision. Just like barnowl determined that
cardinal wasn’t on its LAN (or any network that it knew anything
about), the router must make the same decision, consulting its routing
table to decide where to forward the packet next. Once it has decided,
it’s time to re-wrap the packet at the Data-Link Layer, however,
everything has changed. The packet is now being sent out from a
different Source MAC Address and is being sent to a different
Destination MAC Address. (Since I cannot determine either of these
addresses, I am making up values for them.)

New Dst MAC Addr: 00:02:43:d7:a6:20
New Src MAC Addr: 00:ca:10:08:46:8e

|———–TCP Header———|

This continues until the packet reaches its final destination (or until
the TTL value drops to 0 and the packet is discarded).

9.2 TCP from SYN to FIN

I thought it would be of benefit to show an actual TCP connection from
start to finish. Here, I have striped the Data-Link Header for clarity.
The IP Header has been left in, but largely stripped of extraneous
data. In addition, we won’t be looking at any of the packets in this
connection in binary form, and rather than entering IP Addresses for
the nodes involved, we’ll simply use the short form of their host-name.

Let’s assume (IP Addr wants to retrieve
a web page from (IP Addr
Naturally, the first thing it needs to do is initiate a three-way

robin -> cardinal
Src Port 3560
Dst Port 80
Flags SYN
Seq Num 0
Ack Num 0

cardinal -> robin
Src Port 80
Dst Port 3560
Seq Num 0
Ack Num 0

robin -> cardinal
Src Port 3560
Dst Port 80
Flags ACK
Seq Num 0
Ack Num 0

At this point, the three-way handshake has been initialized and we’re
ready for the first packets with any real data in them to be

robin -> cardinal
Src Port 3560
Dst Port 80
Flags None
Seq Num 1
Ack Num 0
Payload “Give me index.html”

cardinal -> robin
Src Port 80
Dst Port 3560
Flags ACK
Seq Num 0
Ack Num 1

robin has asked for the document “index.html” and cardinal has
responded with an acknowledgement. Next, cardinal will begin to send
the page.

cardinal -> robin
Src Port 80
Dst Port 3560
Flags None
Seq Num 1000
Ack Num 0
Payload “Part 0 of index.html.”

robin -> cardinal
Src Port 3560
Dst Port 80
Flags ACK
Seq Num 0
Ack Num 1000

cardinal -> robin
Src Port 80
Dst Port 3560
Flags None
Seq Num 1001
Ack Num 0
Payload “Part 1 of index.html.”

robin -> cardinal
Src Port 3560
Dst Port 80
Flags ACK
Seq Num 0
Ack Num 1001

cardinal has sent the first 2 parts of the page (remember, computers
always start counting at 0 and you should too!) and robin has
acknowledged both of those parts. Now, robin decides that it’s ready
to terminate the connection.

robin -> cardinal
Src Port 3560
Dst Port 80
Flags FIN
Seq Num 0
Ack Num 0

cardinal -> robin
Src Port 80
Dst Port 3560
Seq Num 0
Ack Num 0

robin has sent a FIN packet to cardinal, asking cardinal to tear-down
the connection gracefully. cardinal has in turn acknowledged this
termination request, but isn’t yet finished sending the web page. (If
robin wanted cardinal to immediately drop what it was doing and tear
down the connection, he would have sent an RST packet instead.)

cardinal -> robin
Src Port 80
Dst Port 3560
Flags None
Seq Num 1002
Ack Num 0
Payload “Part 2 of index.html.”

robin -> cardinal
Src Port 3560
Dst Port 80
Flags ACK
Seq Num 0
Ack Num 1002

cardinal -> robin
Src Port 80
Dst Port 3560
Flags None
Seq Num 1003
Ack Num 0
Payload “Part 3 of index.html.”

robin -> cardinal
Src Port 3560
Dst Port 80
Flags ACK
Seq Num 0
Ack Num 1003

Now that cardinal has completed sending all its data, it will let robin
know that it too is closing the connection.

cardinal -> robin
Src Port 80
Dst Port 3560
Flags FIN
Seq Num 0
Ack Num 0

robin -> cardinal
Src Port 3560
Dst Port 80
Seq Num 0
Ack Num 0

And now the connection is completely torn down.