COMPSCI 356 Computer Network Architecture: Lab 2 Simple Router
Start Soon
This assignment might take you longer time than you think to finish. START SOON!
Introduction
In this lab assignment you will be writing a simple router with a static routing table with Python. Your router will receive raw Ethernet frames. It will process the packets just like a real router, then forward them to the correct outgoing interface. We'll make sure you receive the Ethernet frames; your job is to create the forwarding logic so packets go to the correct interface.
Your router will route real packets from a emulated host (client) to two emulated application servers (http server 1/2) sitting behind your router. The application servers are each running an HTTP server. When you have finished the forwarding path of your router, you should be able to access these servers using regular client software. In addition, you should be able to ping and traceroute to and through a functioning Internet router. A sample routing topology is shown below:
If the router is functioning correctly, all of the following operations should work:
- Pinging from the client to any of the router's interfaces (192.168.2.1, 172.64.3.1, 10.0.1.1).
- Tracerouting from the client to any of the router's interfaces
- Pinging from the client to any of the app servers (192.168.2.2, 172.64.3.10)
- Tracerouting from the client to any of the app servers
- Downloading a file using HTTP from one of the app servers
Mininet & POX
This assignment runs on top of Mininet & POX. Mininet allows you to emulate a topology on a single machine. POX is an OpenFlow controller. It can control routers in Mininet. In this assignment, the router redirects every packets to POX controller, then POX controller redirects them to your code. You don't have to know how they work to complete this assignment.
Get Started
Environment Setup
You are required to finish all the labs in Ubuntu environment. We have set up an Ubuntu 12.04 virtual machine image for you. You can download it here (password:ubuntu). We will test your code in this virtual machine. Please download a VirtualBox and import the virtual machine image we provide.
All these frameworks run on Linux operating system. Configure them manually might requires a lot of time. They have been configured in the virtual machine image.
Test Connectivity of Your Emulated Topology
Start Mininet emulation by using the following command
cd ~/projects/cs144_lab3/ ./run_mininet.sh
You should be able to see some output like the following:
*** Shutting down stale SimpleHTTPServers *** Shutting down stale webservers server1 192.168.2.2 server2 172.64.3.10 client 10.0.1.100 sw0-eth1 192.168.2.1 sw0-eth2 172.64.3.1 sw0-eth3 10.0.1.1 *** Successfully loaded ip settings for hosts {'server1': '192.168.2.2', 'sw0-eth3': '10.0.1.1', 'sw0-eth1': '192.168.2.1', 'sw0-eth2': '172.64.3.1', 'client': '10.0.1.100', 'server2': '172.64.3.10'} *** Creating network *** Creating network *** Adding controller *** Adding hosts: client server1 server2 *** Adding switches: sw0 *** Adding links: (client, sw0) (server1, sw0) (server2, sw0) *** Configuring hosts client server1 server2 *** Starting controller *** Starting 1 switches sw0 *** setting default gateway of host server1 server1 192.168.2.1 *** setting default gateway of host server2 server2 172.64.3.1 *** setting default gateway of host client client 10.0.1.1 *** Starting SimpleHTTPServer on host server1 *** Starting SimpleHTTPServer on host server2 *** Starting CLI: mininet>
Keep this terminal open, as you will need the mininet command line for debugging. Now, use another terminal to continue the next step. To open a new terminal in the same directory of current terminal, you can right click current terminal and press "Open Terminal" or "Open Tab".
Mininet requires a controller, which we implemented in POX. To run the controller, use the following command to run the controller:
cd ~/projects/cs144_lab3/ ./run_pox.sh
You should be able to see some output like the following:
POX 0.2.0 (carp) / Copyright 2011-2013 James McCauley, et al. INFO:.home.ubuntu.projects.cs144_lab3.pox_module.cs144.srhandler:created server INFO:core:POX 0.2.0 (carp) is up. INFO:openflow.of_01:[16-a5-39-7e-79-41 1] connected
Now you are ready to test out the connectivity of the environment setup. To do so, run the binary file of the solution “sr_solution”
cd ~/projects/cs144_lab3/ ./sr_solution
You should be able to see some output like the following:
Using VNS sr stub code revised 2009-10-14 (rev 0.20) Loading routing table from server, clear local routing table. Loading routing table --------------------------------------------- Destination Gateway Mask Iface 10.0.1.100 10.0.1.100 255.255.255.255 eth3 192.168.2.2 192.168.2.2 255.255.255.255 eth1 172.64.3.10 172.64.3.10 255.255.255.255 eth2 --------------------------------------------- Client ubuntu connecting to Server localhost:8888 Requesting topology 0 successfully authenticated as ubuntu Loading routing table from server, clear local routing table. Loading routing table --------------------------------------------- Destination Gateway Mask Iface 10.0.1.100 10.0.1.100 255.255.255.255 eth3 192.168.2.2 192.168.2.2 255.255.255.255 eth1 172.64.3.10 172.64.3.10 255.255.255.255 eth2 --------------------------------------------- Router interfaces: eth3 HWaddrf2:87:91:7d:2e:7a inet addr 10.0.1.1 eth2 HWaddr46:d5:1e:89:53:0d inet addr 172.64.3.1 eth1 HWaddrbe:3c:a3:e6:1a:43 inet addr 192.168.2.1 <-- Ready to process packets -->
In this particular setup, 192.168.2.2 is the IP for server1, and 172.64.3.10 is the IP for server2. You can find the IP addresses in a file called IP_CONFIG.
Now, back to the terminal where Mininet is running. To issue an command on the emulated host, type the host name followed by the command in the Mininet console. For example, the following command issues 3 pings from the client to the server1.
mininet> client ping -c 3 192.168.2.2
You should be able to see the following output.
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data. 64 bytes from 192.168.2.2: icmp_req=1 ttl=63 time=66.9 ms 64 bytes from 192.168.2.2: icmp_req=2 ttl=63 time=49.9 ms 64 bytes from 192.168.2.2: icmp_req=3 ttl=63 time=68.8 ms
You can also use traceroute to see the route between client to server1.
mininet> client traceroute -n 192.168.2.2
You should be able to see the following output.
traceroute to 192.168.2.2 (192.168.2.2), 30 hops max, 60 byte packets 1 10.0.1.1 146.069 ms 143.739 ms 143.523 ms 2 192.168.2.2 226.260 ms 226.070 ms 225.868 ms
Finally, to test the web server is properly working at the server1 and server2, issue an HTTP request by using wget or curl.
mininet> client wget http://192.168.2.2
You should be able to see the following output.
--2012-12-17 06:52:23-- http://192.168.2.2/ Connecting to 192.168.2.2:80... connected. HTTP request sent, awaiting response... 200 OK Length: 161 [text/html] Saving to: `index.html' 0K 100% 17.2M=0s 2012-12-17 06:52:24 (17.2 MB/s) - `index.html' saved [161/161]
If you stop the './sr_solution', you will find the ping/traceroute/wget won't work anymore. In this assignment, you will replicate the functionality of sr_solution. To help you get started, we provide some starter code described in the following section..
We will use these test cases to grade your code.
Starter Code
You should now have all the pieces needed to build and run the router:
The starter source code
You can run the starter code as follows:
cd ~/projects/cs144_lab3/lab2/ ./sr
What you need to do is to finish the sr_py.py. We have provided you the skeleton code:
~/projects/python/sr_py.py
You can kill the process with:
./kill.sh
General Forwarding Logic
To get you started, an outline of the forwarding logic for a router follows, although it does not contain all the details. There are two main parts to this assignment: Handling ARP and IP forwarding
IP Forwarding
Given a raw Ethernet frame, if the frame contains an IP packet that is not destined towards one of our interfaces:
- Sanity-check the packet (meets minimum length and has correct checksum).
- Decrement the TTL by 1, and recompute the packet checksum over the modified header.
- Find out which entry in the routing table has the longest prefix match with the destination IP address.
Protocols to Understand
Ethernet
You are given a raw Ethernet frame and have to send raw Ethernet frames. You should understand source and destination MAC addresses and the idea that we forward a packet one hop by changing the destination MAC address of the forwarded packet to the MAC address of the next hop's incoming interface.
Internet Protocol
Before operating on an IP packet, you should verify its checksum and make sure it meets the minimum length of an IP packet. You should understand how to find the longest prefix match of a destination IP address in the routing table described in the "Getting Started" section. If you determine that a datagram should be forwarded, you should correctly decrement the TTL field of the header and recompute the checksum over the changed header before forwarding it to the next hop.
Internet Control Message Protocol
ICMP is a simple protocol that can send control information to a host. In this assignment, your router will use ICMP to send messages back to a sending host. You will need to properly generate the following ICMP messages (including the ICMP header checksum) in response to the sending host under the following conditions:
- Echo reply (type 0) Sent in response to an echo request (ping) to one of the router's interfaces. (This is only for echo requests to any of the router's IPs. An echo request sent elsewhere should be forwarded to the next hop address as usual.)
- Destination net unreachable (type 3, code 0) ** Sent if there is a non-existent route to the destination IP (no matching entry in routing table when forwarding an IP packet).
- Destination host unreachable (type 3, code 1) ** Sent if five ARP requests were sent to the next-hop IP without a response.
- Port unreachable (type 3, code 3) ** Sent if an IP packet containing a UDP or TCP payload is sent to one of the router's interfaces. This is needed for traceroute to work.
- Time exceeded (type 11, code 0) ** Sent if an IP packet is discarded during processing because the TTL field is 0. This is also needed for traceroute to work. The source address of an ICMP message can be the source address of any of the incoming interfaces, as specified in RFC 792. As mentioned above, the only incoming ICMP message destined towards the router's IPs that you have to explicitly process are ICMP echo requests. You may want to create additional structs for ICMP messages for convenience, but make sure to use the packed attribute so that the compiler doesn't try to align the fields in the struct to word boundaries:
Address Resolution Protocol
ARP is needed to determine the next-hop MAC address that corresponds to the next-hop IP address stored in the routing table. Without the ability to generate an ARP request and process ARP replies, your router would not be able to fill out the destination MAC address field of the raw Ethernet frame you are sending over the outgoing interface. Analogously, without the ability to process ARP requests and generate ARP replies, no other router could send your router Ethernet frames. Note that ARP requests are sent to the broadcast MAC address (ff-ff-ff-ff-ff-ff). ARP replies are sent directly to the requester's MAC address.
IP Packet Destinations
An incoming IP packet may be destined for one of your router's IP addresses, or it may be destined elsewhere. If it is sent to one of your router's IP addresses, you should take the following actions, consistent with the section on protocols above:
- If the packet is an ICMP echo request and its checksum is valid, send an ICMP echo reply to the sending host.
- If the packet contains a TCP or UDP payload, send an ICMP port unreachable to the sending host. Otherwise, ignore the packet. Packets destined elsewhere should be forwarded using your normal forwarding logic.
Code Overview
Basic Functions
Your router receives a raw Ethernet frame and sends raw Ethernet frames when sending a reply to the sending host or forwarding the frame to the next hop. The basic functions to handle these functions are:
def receive(raw, interface)
This method, is called by the router each time a packet is received. The "raw" argument points to the packet buffer which contains the full packet including the ethernet header. The name of the receiving interface is passed into the method as well.
def handle_ip(ether, interface)
This method should be called by `receive()` when the Ethernet frame is regarded as an IP packet. You should decide when to call this function in `receive()`, and handle all cases for IP packets in this method, including TTL expiration, destination unreachable, etc.
def handle_arp(ether, interface)
This method should be called by `receive()` when the Ethernet frame is regarded as an ARP packet. You should decide when to call this function in `receive()`, and handle all cases for ARP packets such as responding to the incoming ARP request.
Reference Binary
To help you debug your topologies and understand the required behavior we provide a reference binary and you can find it at ~/projects/cs144_lab3/sr_solution in your directory:
Required Functionality
- The router must successfully route packets between the Internet and the application servers.
- The router must correctly handle ARP requests and replies.
- The router must correctly handle traceroutes through it (where it is not the end host) and to it (where it is the end host).
- The router must respond correctly to ICMP echo requests.
- The router must handle TCP/UDP packets sent to one of its interfaces. In this case the router should respond with an ICMP port unreachable.
- The router must not needlessly drop packets (for example when waiting for an ARP reply)
Collaboration Policy
You should finish this assignment individually.
How to Submit
Submit the py (sr_py.py) file to Sakai. Upload the compressed file on Sakai.Acknowledgement
We thank the course staff of CS144 at Stanford University for their support. This lab is adapted from one of their assignments. You can visit their Wiki page here.
Last updated: 03/03/2020