Assignment 3
Assignment 3
Assignment 3
1. Introduction 1
3. TCP connections 4
4. Mappings 4
4.1 Cleaning up defunct mappings 5
5. Implementation 5
5.1 Mapping data structure and concurrency 5
5.2 Download skeleton code 6
5.3 Test connectivity of your emulated topology 7
5.3.1 Configure the environment 7
5.3.2 Start Mininet 7
5.3.3 Start POX 8
5.3.4 Start reference solution 9
5.4 Tracking Connections 11
5.5 Adding command-line flags 11
5.6 Reference Implementation 12
6. Testing 12
7. Deliverables 12
8. Submissions 13
1. Introduction
In this assignment you will be writing a simple NAT that can handle ICMP and TCP. It
will implement a subset of the functionality specified by RFC5382 and RFC5508.
Before beginning this lab, it is crucial that you:
As with "Static Router", we will create a NAT that sits in Mininet between the app
servers and the client. The internal interface of the NAT faces the client, while the
external interfaces are connected to app servers. The app servers are "outside" the
NAT, while the client is "inside."
The topology of NAT is as follows, where the NAT's internal interface (eth1) faces the
client and its external interface (eth2) has two application servers connected with a
switch:
A correct implementation should support the following operations from the emulated
client host:
● Pinging the NAT's internal interface from the emulated client host;
● Pinging any of the app servers (e.g. 172.64.3.21, 172.64.3.22 above);
● Downloading files using HTTP from the app servers. All packets to external hosts
(app servers) should appear to come from eth2's address (e.g. 172.64.3.1
above);
Your NAT builds on the "static router". You must add a new command-line flag, -n,
which controls whether the NAT is enabled. If the -n flag is not passed, then the router
should act following the requirements of "static router". For example, it should be
possible to traceroute across the router when the -n flag is not passed. All of the ICMP
errors in "static router" still apply. More precisely:
● Your NAT MUST generate and process ICMP messages as per the "static
router";
● Your NAT MUST translate ICMP echo requests from internal addresses to
external addresses, and MUST correctly translate the corresponding ICMP echo
replies;
● ICMP echo requests MUST be external host independent: two requests from the
same internal host with the same query identifier to different external hosts
MUST have the same external identifier;
● An ICMP query mapping MUST NOT expire less than 60 seconds after its last
use. This value MUST be configurable, as described below;
Other "static router" ICMP behavior should continue to work properly (e.g. responding to
an ECHO request from an external host addressed to the NAT's external interface).
3. TCP connections
When an internal host opens a TCP connection to an external host, your NAT must
rewrite the packet so that it appears as if it is coming from the NAT's external address.
This requires allocating a globally unique port, under a set of restrictions as detailed
below. The requirements for your NAT are a subset of those in specified in RFC5382; in
some cases they are more restrictive. Refer to the RFC for details on the terms used.
Your NAT has the following requirements:
4. Mappings
When assigning a port to a mapping, you are free to choose a port any way you choose.
The only requirement is that you do not use the well-known ports (0-1023).
As noted above, mappings should be Endpoint Independent. Once a mapping is made
between an internal host's (ip, port) pair to an external port in the NAT, any traffic from
that host's (ip, port) directed to any external host, and any traffic from any external host
to the mapped external port will be rewritten and forwarded accordingly.
The periodic function that handles timeouts should fire in its own separate thread (more
on threading below). The following three timeout intervals for mappings should be
configurable via command-line flags:
TCP Established Idle Timeout applies to TCP connections in the established (data
transfer) state. TCP Transitory Idle Timeout applies to connections in other states (e.g.
LISTEN). Refer to the TCP state diagram.
5. Implementation
Be sure to study how the ARP cache works. For handling timeouts, a separate thread is
spawned (at the top of sr_router.c) that periodically runs. NAT timeouts should have
their own thread as well. Because the main forwarding thread and the ARP cache
timeout thread share the data structure, the ARP cache accessors and mutators use
locks. Be sure that your NAT's mapping data structure uses locks as well,
otherwise nasty concurrency bugs will be sure to crop up.
In addition, be careful how your mapping table returns mappings, you do not want to
hand out pointers to structures that may be freed by the periodic timeout. Take a look at
the sr_arpcache_lookup code in the ARP cache.
To get you started on the right track, we provide skeleton code for a possible NAT
mapping data structure. You will use the same environment that we set up in "simple
router" for this assignment. For detailed instructions, please refer to Environment Setup
and Simple Router.
This assignment would require some thread programming.There are also many
resources on the web explaining why and when systems use them. Finally, there are
lots of good pthreads tutorials on the web, for concrete programming guidance. You can
also use the ARP cache code as a guide. Since this isn't a high performance system,
it's better to be conservative with your locks; a race condition is much harder to debug
than a deadlock.
> cd ~
> https://[email protected]/cs561-17sp/cs561-as3.git
> cd cs561-as3
The skeleton code resides in router/. The router directory is the same starter code for
the 2nd assignment. You should make a copy of your “Static Router” into the NAT
directory as follows:
> pwd
/home/networks/cs561-as3
> cp -r ~/cs561-as2/router ./
Now untar the file sr_nat_table.tar. Then you will find two files, sr_nat.c and sr_nat.h.
You also need to copy the rtable into the directory.
> ./run_mininet.sh
You should see an output that looks like this (except for the IP addresses).
5.3.3 Start POX
Start the Mininet controller (and wait for it to print some messages)
> ./run_pox.sh
> ./sr_nat -n
Note that “-n” means NAT is enabled. You should see an output like this:
To see whether the NAT is doing the translation, let’s do a tcpdump at server1 and
observe the packet is going to be received at the server 1. To do so, go to the terminal
where you run the Mininet, type the following command in the Mininet command line
interface (CLI) to bring up the terminal of server1.
Now, back to the Mininet CLI to send some ping packets from client to server1:
On the Mininet CLI, you should be able to see the following output:
On the server1 terminal, you should be able to see the following output:
Note the packets received at server1 is from 172.64.3.1, which is the IP of NAT's
external interface, instead of 10.0.1.100, the IP of the client host.
Now, let’s disable NAT and compare. Back to the terminal where you run “./sr_nat -n”,
use control-c to stop the current “./sr_nat -n” process, and run the following command
> ./sr_nat
Also using tcpdump on server1's terminal to see the packets reaches server1:
This time, since the NAT is disabled, the source IP shows the client's IP (10.0.1.100)
instead.
When rewriting TCP packets, remember to update the checksum (over the pseudo-
header, tcp header, and payload). The TCP checksum is calculated like the IP
checksum, so you can reuse the cksum function. Note that if the checksum is incorrect
when the packet comes in, you can drop it; you should not "correct the checksum" as
that would hide potential attackers or errors.
It would enable NAT functionality, timeout ICMP mappings after 70 seconds, TCP
mappings with at least one established connection after 7440 seconds, and TCP
mappings with only transitory connections after 40 seconds.
6. Testing
We’re testing your code in the following three scenarios. Please refer to our binary
solution for expected behavior. You should do tcpdump at the server side to make
sure where the packet is from. And you should test the following cases in the
mininet client.
You’re recommended to think more about testing cases and describe in the document.
7. Deliverables
● Final source code: Remember one of the goals of this assignment is for you to
build a basic NAT. Therefore, your final code MUST be runnable as a single shell
command (“./router/sr -n”). We will test your code in the same setup.
● README: This file should be 1-3 page document describing your high-level
design, implementation, and special testing cases.
8. Submissions
The assignment is due June 7th at 5pm for group submissions.
Make sure your names are on the README. Create a tarball of the cs561-as3 folder with your
updates to the started code. Submit your tar-ball to the course dropbox. NOTE: we
recommend you to use the referenced solution (./sr_nat -n) to test your code before
submission.