pete > courses > CS 431 Spring 25 > Lecture 07: Network Layer II – IP details


Lecture 07: Network Layer II – IP details

Goals

last time, we saw how Ethernet was not sufficient for sending packets over an internetwork
we discussed the need for a new kind of address based on a host’s location within the internetwork, and consequently the need for routers and routing tables
recall that a router is a machine connected to multiple networks, whose job is to forward (what we will now call) packets between those networks
and a routing table is the data structure used by the router to decide where to forward a given packet
recall also that we’re now using the word "packet" to refer to the unit of data transmitted at the network (IP) layer

first, a word on vocabulary

I have tried to be fairly consistent in using the word "network" to refer to all the machines connected to the same link

and "internetwork" to refer to a collection of interconnected networks

in practice, the word "network" often has the meaning that I’ve been giving it, but it is also often used to mean (what I’ve been calling) an "internetwork"

let me complicate matters further by introducing the term subnet (short for "subnetwork"), which fairly unambiguously refers to a collection of hosts connected to the same link—ie, the same as the first definition of "network" given above

this word will be relevant shortly


we will shortly look at the RFC that defines IP, but before we do so, some words on history

IP was developed in conjunction with UDP, TCP, and ICMP, all of which we will work with

the reason they were developed together is that, taken individually, they don’t solve The Internetworking Problem

remember separation of concerns: different components of the system have responsibility for different behaviors/requirements, which saves us from having to think about everything at once

this work was funded in large part by the Defense Advanced Research Projects Agency, known as DARPA

which is why the early iteration of the Internet was known as DARPAnet


let us begin by looking at the structure of an IP packet and then we’ll figure out how it fits in with what we already know

IP is defined in RFC 760

the format of the header is given on page 11

it’s called a "header" because it comes at the beginning

just like Ethernet, an opaque payload follows

unlike Ethernet, there is nothing after the opaque payload (recall that, in Ethernet, the frame check sequence comes after the data)

I want to focus on just the "Source Address" and "Destination Address" fields for now, because they are what’s most relevant to what we talked about last time

we will get back to the rest later today


the address fields are what hold the dotted quad addresses we saw last time

so the IP address we write for human reading as 140.233.20.4 would appear in the source or destination address field as the sequence of bits 10001100 11101001 00010100 00000100

just as with Ethernet addresses, IP addresses are assigned to interfaces, NOT machines

this is important because we are now concerned with routers, which have multiple interfaces, each of which will have a different IP address and MAC address


so an IP packet is the thing host A might want to send to host D

if we’ve got an internetwork, connected together by routers, host A sends a packet to host D by first sending it to router R1, which sends it to router R2, which sends it to router R3, which finally sends the packet to D

a journey of 4 steps, which you will often hear called "hops" (at least by me)

to recall a diagram we looked at a few lectures ago, conceptually, the network (IP) layer code on host A is sending a packet to the network layer code on host D

+----------------+          +----------------+
| Network Layer  | -------> | Network Layer  |
+----------------+          +----------------+

      Host A                      Host D

clearly this involves the physical layer, because bits must be transmitted and received, but where does the link layer fit in?

note that host A sends the packet to R1, both of which are on the same link

then, R1 sends the packet to R2, both of which are also on the same link

and so on

so we’re going to use the link layer (Ethernet) functionality to deliver the packet one step (hop)

thus, we’ll be using four link-layer transmissions to accomplish the single delivery described above


here’s what will happen:

host A constructs the IP packet it wants to send to host D with source address set to the IP address of the interface on A and the destination address set to the IP address of the interface on D

and then sends this IP packet over the link to R1

which requires that host A put the IP packet inside an Ethernet frame, with source address set to the MAC address of the interface on host A and the destination address set to the MAC address of the interface on R1

it also means that the "type" field of the Ethernet header will be set to 0x0800, which is the code that signifies IP

the link layer on R1 will see the frame and say "yes, this is for me", then it will look at the type field and say "this payload is IP data" and pass the payload to the code that deals with IP packets

that code will say "this packet is not addressed to me, so I’m supposed to send it on its way to the next hop in its journey"

at which point R1 will consult its routing table (more on this in a moment), which will tell it that the next hop for this packet is R2

R1 then constructs an Ethernet frame with source address set to the MAC address of the interface it’s going to send the frame out on, destination address set to the MAC address of the interface on R2 on the same link

then R1 stuffs the IP packet inside the Ethernet frame and sends it out on the link

the same thing happens at R2 and at R3


when the packet arrives at host D, more or less the same thing happens

with the exception that the network layer on host D recognizes that the destination IP address matches the address of its own interface, and therefore concludes that the packet is destined for itself, and passes it up to other code to deal with


the idea of putting the IP packet inside an Ethernet frame is called encapsulation and is one of the ways we achieve separation of concerns

because it causes the information relevant to the link layer to be kept separate from the information relevant to the network layer


if we transform the conceptual diagram above into something that reflects the full reality, we get something like this:

   |                                       ^
   v                                       |
+-----+   +-----+   +-----+   +-----+   +-----+   
| IP  |   | IP  |   | IP  |   | IP  |   | IP  |   
+-----+   +-----+   +-----+   +-----+   +-----+   
   |        ^ |       ^ |       ^ |       ^ |
   v        | v       | v       | v       | v
+-----+   +-----+   +-----+   +-----+   +-----+   
| Eth |   | Eth |   | Eth |   | Eth |   | Eth |   
+-----+   +-----+   +-----+   +-----+   +-----+   
   |        ^ |       ^ |       ^ |       ^ |
   v        | v       | v       | v       | v
+-----+   +-----+   +-----+   +-----+   +-----+   
| PHY |-->| PHY |-->| PHY |-->| PHY |-->| PHY |   
+-----+   +-----+   +-----+   +-----+   +-----+   

Host A      R1        R2        R3      Host D

where packets are passed between the IP and Eth boxes

frames are passed between the Eth and PHY boxes

and electrical signals are passed among the PHY boxes


this diagram really drives home the idea that this network is not like the old phone network

remember that, in the phone network, a single uninterrupted electrical circuit was established between the caller and the callee

and the electrical signals traversed the entire circuit in one go

there are two major differences here:

another word for this kind of network is a store and forward network

because a router will store the incoming packet and then forward it to the next hop


speaking of which, how does each router know which hop is the next one?

this is where the routing table we discussed last time comes into play

remember that the routing table contains records that describe which router can deliver packets to which network(s)

ie, it contains all the information required to figure out the next hop

so, in the above example, R1 would have a record that says "a packet for host D should be sent through R2"

perhaps surprisingly, host A also acts like a router: it’s going to have a routing table with a record that says "a packet for host D should be sent through R1"


so what do these records look like?

let’s see!

on Linux first, because they’re more readable given what we know right now:

$ netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.3.0.1        0.0.0.0         UG        0 0          0 wlan0
10.3.0.0        0.0.0.0         255.255.0.0     U         0 0          0 wlan0

this routing table contains two routes: the final two rows of the output

let’s start with the second route

the "Destination" and "Genmask" fields together specify the network this route applies to

the Genmask tells us which bits of the Destination specify the network

in this case, the Genmask is 255.255.0.0, which represents the 32-bit sequence of 16 ones followed by 16 zeroes

because the Genmask starts with 16 ones, this tells us that the first 16 bits of the Destination field specify the network

the Destination field is 10.3.0.0; the first 16 bits are 10.3; therefore, this route applies to all hosts whose IP address begins with 10.3

therefore, this route applies to any packet destined for an IP address beginning with 10.3

which is where the other columns come into play

the Gateway field tells us the IP address of the router to which the packet should be sent

sometimes, though, the destination IP address is on a network to which the sending host is directly connected: this is reflected by a Gateway value of 0.0.0.0

the Iface field specifies the network interface out which a packet matching this route should be sent

in the case of the output above, this is wlan0, which is the wireless interface on my laptop

to sum up the final route above: any packet destined for a host whose IP address begins with 10.3 can be sent directly to that host on the network to which wlan0 is attached


before we look at the first route, let’s consider how we determine (computationally) that a given route applies to a particular packet

example #1: we have a packet whose destination IP address is 10.3.86.94

we humans can clearly see that this address being with 10.3 and therefore the second route applies, but what is a computer to do?

remember that all these values are being represented as 32-bit things (not even integers, really)

and this route’s Genmask of 255.255.0.0 tells us that the first 16 bits of the destination IP address must match the first 16 bits of the Destination field in the route

so here’s what we do:


example #2: we have a packet whose destination IP address is 140.233.20.202

again, we humans can clearly see that the second route does not apply because it doesn’t begin with 10.3

but here is how we computationall come to the same conclusion:

IP address: 140.233.20.202 -> 1000 1100 1110 1001 0001 0100 1100 1010
Genmask:    255.255.0.0    -> 1111 1111 1111 1111 0000 0000 0000 0000
bitwise-and                   1000 1100 1110 1001 0000 0000 0000 0000 -> 140.233.0.0

140.233.0.0 does not match the Destination field of this route (10.3), therefore the route does not apply


the Genmask field is also called the "Subnet mask" or the "Netmask"

the generic idea here is that it is a bitmask: it tells us which bits to pay attention to (the ones that correspond to the network portion of the IP address) and which to ignore (the ones that correspond to the host portion of the IP address)


with that in mind, let us now consider the first route

the Genmask is 0.0.0.0, and therefore any IP address we bitwise-AND it with will produce 0.0.0.0

which is the value of the Destination field

meaning that this route will apply to ALL packets

that makes this the default route, meaning the route that is used if all other routes in the table fail to match

a network that has a single path to the outside world, like a home network or Middlebury’s (sort of), will always have a default route because that’s the way packets get to the Internet at large

we will get a glimpse of what the Internet looks like outside such networks in a few lectures


a noteworthy aspect of the routing table given above is that there are some packets to which both routes will apply

specifically, any packet destined for the 10.3 network will match both routes

so how does the system decide which route to choose?

the naive answer (which is sufficient for this course) is that that most specific route will be chosen

concretely, that means the route with the "longest" Genmask

or rather, the most ones in the Genmask field: so a route with Genmask 255.255.255.0 would take precedence over a route with Genmask 255.255.0.0


now let’s look at the routing table on FreeBSD

$ netstat -rn4
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
default            10.0.2.2           UGS         em0
10.0.2.0/24        link#1             U           em0
10.0.2.15          link#1             UHS         lo0
127.0.0.1          link#2             UH          lo0

the Destination and Gateway fields look familiar, but the Genmask and Iface fields are nowhere to be found!

the Iface field is easy: it’s just been renamed "Netif": here the network interface is called em0

the Genmask field is a bit tricker, but the information is there

look at the Destination field of the second route: 10.0.2.0/24

that "/24" means "a Genmask with the first 24 bits set to one": alternatively, 255.255.255.0

(in my opinion, this organization makes more sense that the Linux table, where the Destination and Genmask fields are separated by the Gateway field, even though it’s a bit less verbose)


we also see a new network, 127.0.0.1, and a new interface, lo0

this is the "loopback" interface

it’s an imaginary interface (meaning that there is no physical device to which it corresponds) that exists entirely within the kernel

its purpose is to allow us to run software that does IP-ish stuff entirely self-contained within the machine itself

I could set up a process that binds to 127.0.0.1 and another process that connects to 127.0.0.1 and they can use IP to talk to each other, even though the packets never leave the machine

this is really helpful when you’re writing software that naturally breaks into separate components, and you want those components to work when run on different machines but also when run on the same machine

you don’t have to code it any differently, you just have to change the IP addresses


the FreeBSD routing table also uses a different notation to indicate that the destination is on a locally-connected network: that’s what "link#1" and "link#2" mean

on that point, it also has a discrete route for the IP address assigned the em0 interface: 10.0.2.15 (note the "H" in the Flags field, indicating that this route applies to a specific host, not an entire network)

furthermore, it uses the word "default" instead of 0.0.0.0 as the destination for the default route


these routing tables are all well and good, but how do they get populated in the first place?

for that matter, how does an interface know what its IP address and netmask should be?

we will look at both of these questions soon, but not today

for now, let’s get back to…


the rest of the fields of the IPv4 header

(recall: page 11 of RFC 760)

version: 4 (ie, 0100)

IHL: internet header length, length of header as multiple of 32 bits; usually 5, meaning no options

type of service: speed vs reliability, not guaranteed to take effect

total length: header plus data in octets

identification: if the packet needs to be broken up ("fragmented", usually because the MTU of a link along the way is too small), this allows the receiver to reconstruct it

flags: stuff about fragmentation (later, if at all)

fragment offset: same

time to live: will get back to this

protocol: identifies how to interpret payload, just like the Type field of the Ethernet header

header checksum: verifies integrity of header only, "16 bit one’s complement of the one’s complement sum of all 16 bit words in the header" (implementation given in RFC 1071)

options: variable, very rarely used, support/interpretation/implementation varies wildly (paper later)


now: time to live, usually abbreviated TTL

8-bit field, interpreted as an unsigned integer

set by the sender and decremented by each router in the route

when a router decrements it to zero, the packet is dropped

this is to prevent a packet from traversing a cycle in the network

this is usually the only field in the IP packet that is modified by routers as the packet passes through

interestingly, when a packet is dropped this way, sometimes the dropping does not happen silently

but how does the router report that the packet was dropped?

next time!


but before we go, here is the full logic implemented by the IP component for SENDING a packet:

and for RECEIVING a packet:


other foreshadowing questions:

Last modified: