Due: Tuesday, December 10, 11.59PM

1. Handy references:

2. Lab 7 Goals

  • Understand how a router encapsulates and decapsulates packets at the the Link and Network layer.

  • Hands-on experience of how a router really works, and parsing and understanding a large code base.

  • Packet handling and forwarding at a router.

  • Using Wireshark and tshark to help analyze incoming and outgoing packets.

3. Overview & Requirements

For this lab, you will implement a fully functional Internet router that routes real network traffic. The goal is to give you hands-on experience as to how a router really works. 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. 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 servers 1 and 2) sitting behind your router, each on a different network. 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. Additionally, you should be able to ping and traceroute to and through a functioning Internet router. The emulated topology is depicted below:

sr topo
Figure 1. The figure shows a small network topology with a router with three interfaces, the first interface connects to HTTP Server 1, the second interface to HTTP Server 2 and the third interface connects to a Client. HTTP Server 1 has IP address 192./168.2.2 and HTTP Server 2 has IP address 172.64.3.10 and the Client as an IP address 10.0.1.100. The router’s three interface addresses are 192.168.2.1, 172.64.3.1 and 10.0.1.1.

3.1. Flowchart

The figure below describes the overall functionality of the router. As a router we receive a packet, which is an ethernet frame.

  • The first check is to see if it is a valid ethernet frame and is it destined to the ethernet interface the packet arrived at. If not, we can drop the packet immediately (just return from the function immediately).

  • If the packet is destined to the correct interface, then we look at the type of the Ethernet packet, and check if it is an ARP or an IP packet. We will assume all the packets are IPv4 packets. If it is neither of these two, then we will drop the packet as before.

  • If the packet is an ARP message we need to check if it is a request or a reply.

    • An ARP reply indicates that the router is learning about an IP to MAC address mapping. Usually this is the answer to a request that we sent out as the router. We will store that in an ARP table, and the next time we do this look-up we have this available.

    • If the packet is an ARP request, we have to check if the ARP request is destined to the router, at the correct interface. If not, we drop the ARP request, otherwise we generate an ARP reply and send that out.

  • If it is an IP packet, we will strip of the Ethernet header, and look at the IP layer header, and check to see if this packet is destined to the correct router interface.

    • If the IP packet is not destined to the router, then we need to do a lookup in our router table that is provided, and decide which interface to send it out.

    • If it is destined to you the router, we will check to see if it is an ICMP echo message or a ping message. If not, we send back an ICMP message to say "Protocol Unreachable" (i.e., the router does not speak that protocol). If it is an ICMP message we will send back an ICMP ping reply.

Flowchart
Figure 2. Flowchart for processing a packet at the router.

Requirements:

You will be responsible for implementing important elements of several subsystems within the router. The majority of the code which makes the router work, including the routing tables, is provided for you. The functionality should be the same as the provided sr_solution. All code must be added to sr_router.c and sr_router.h. You are responsible for implementing (not necessarily in this order!):

  • Please go through Function Reference Guide to get a more detailed breakdown of each function.

  • sr_handlepacket(): parse the provided ethernet frame, verify that it is valid and to this interface, and call handle_ip() or handle_arp() as needed.

  • handle_arp(): handle incoming ARP requests by sending a reply if necessary.

  • handle_ip(): verify the validity of the IP header, handle packets destined for the router (only ICMP Ping must be handled, all data packets should receive an error response), and forward/drop packets NOT addressed to this router as appropriate.

  • rtable_find_route(): find the best route in the routing table, and return a pointer to that element in the linked list of routing table entries.

  • router_queue_ethernet_frame(): craft an outgoing ethernet packet based on the given payload, source, and destination, and send it out via sr_send_packet.

  • ip_send_packet_from(): allocate a new IP packet, set its headers and payload correctly, and call router_send_ethernet_frame to send it along.

  • icmp_send(): allocate, fill, and send a new ICMP packet using network_send_packet or network_send_packet_from. If the src ip is null, you can use network_send_packet to set the src ip based on the routing decision for the destination.

  • handle_arpreq(): for packets waiting on an arp request, first check whether they’ve been waiting so long as to timeout. If so, send an ICMP host unreachable packet to the source(es), and clear the request from the arp cache; if not, send a new arp request and update the valid time and send times.

4. Getting Started

To get started on sr_handlepacket take a look at the hints here.

5. Testing

The following functionality should behave correctly (as the provided sr_solution does) in your submission:

  1. Pinging from the client to any of the router’s interfaces (192.168.2.1, 172.64.3.1, 10.0.1.1). To generate a ping from the client to the router, open a new gray box for the client from the mininet command line interface. (You can open a terminal to any of the machines in the topology in the following manner).

    mininet> xterm client #client
    mininet> xterm sw0    #router
    mininet> xterm server1 #server1
    mininet> xterm server2 #server2

    With your sr_router running on the router, you can run Wireshark on the client in the background and then ping the router:

    # client gray box
    /Lab7# wireshark & # & sets the process to run in the background
    /Lab7# ping 10.0.1.1

    Wireshark should show you two ARP entries, that correspond to the request and response.

    We know that an ARP response has your MAC address and IP address in the response fields, so you should check that these header fields are correctly set.

  2. If your ARP response from the router works, then the router’s MAC address should now be stored in the client’s ARP cache. You can check the client’s ARP cache, in the client’s gray box as follows:

    # client gray box
    /Lab7# arp -n
    
    #====== if your ARP response works ====== #
    Address   HWtype  HWaddress           Flags Mask    Iface
    10.0.1.1  ether   92:28:93:8f:bd:e0   C             client-eth0
    
    #====== if your ARP response is not there yet ====== #
    Address   HWtype  HWaddress   Flags Mask   Iface
    10.0.1.1  (incomplete)                     client-eth0
  3. Tracerouting from the client to any of the router’s interfaces.

  4. Pinging from the client to both of the HTTP servers (192.168.2.2, 172.64.3.10).

  5. Tracerouting from the client to both of the HTTP servers.

  6. Downloading a file using HTTP from both of the servers.

6. Assumptions

You may make the following simplifying assumptions:

  • You don’t need to worry about IP options, they won’t be used.

  • You don’t need to worry about IP fragmentation.

  • You only need to handle IPv4 (no IPv6).

  • When it comes to packets addressed to your router, you only need to handle ICMP Ping messages. For anything else, you may reply with an 'ICMP Protocol Unreachable' message.

  • For ARP, all packets will be for the Ethernet hardware type and IP protocol type, and you don’t need to handle anything other than ARP requests and ARP replies.

7. Environment

For this lab, we’ll be using mininet again, only this time, our topology will be a bit more complex than before. To set up a mininet virtual machine, refer to the environment section of lab 5. Rather than running mn directly, this time we’ll use some scripts to make launching it easier.

ssh -Y localhost -p 22222 -l mininet

Before you get started, you’ll need to run a script that will prepare your environment and install a few packages:

chmod +x *.sh
./config.sh

You should only need to run config.sh once for your VM, but it won’t hurt to execute it multiple times.

From there, you can launch mininet using another script:

./run_mininet.sh

Keep the mininet terminal open and running in the foreground (don’t do ctrl-z). This should also pop-up a terminal for executing commands at the client (10.0.1.100 in the image above). In a second terminal window, execute the router code. I’ve provided a reference implementation named sr_solution, which you can execute now. You will, of course, eventually want to execute your own version, which will be named sr (built from the router directory).:

./sr_solution

OR

./router/sr

8. Grading Rubric

This assignment is worth seven points.

  • 1 - Router responds to ARP requests that query its own interfaces.

  • 1 - Router responds to ICMP echo messages with ICMP echo replies.

  • 1 - Router sends back ICMP protocol unreachable upon receiving any IP packets that are destined for the router that are not ICMP echo.

  • 1 - The client is able to ping and traceroute through the router to either server.

  • 1 - The client is able to download files from both servers via HTTP.

  • 1 - Router sends ICMP destination unreachable messages for destinations that do not send ARP replies.

9. Tips

  • START EARLY! The earlier you start, the sooner you can ask questions if you get stuck. Test your code in small increments. It’s much easier to localize a bug when you’ve only changed a few lines.

  • You can log the packets received and generated by your SR program by using the -l parameter. The file will be in pcap format, i.e., you can use wireshark or tcpdump to read it:

./sr -l logname.pcap
  • You can also use mininet to monitor the traffic that goes in and out of the emulated nodes, i.e., router, server1 and server2. Take server1 as an example, to see the packets in and out of it, go to the mininet CLI:

    mininet> server1 sudo tcpdump -n -i server1-eth0

    or you can bring up a terminal inside server1 with:

    mininet> xterm server1

    and then run whatever you like (e.g., wireshark) inside the newly popped-up xterm.

  • Within the sr framework you will be dealing directly with raw Ethernet packets. There is some code in sr_protocols.h that you may use to manipulate headers, or you may prefer to write your own or use standard system includes.

  • There are also some debugging functions provided in sr_utils.c, like:

    • print_hdrs(uint8_t *buf, uint32_t length) - Prints out all possible headers starting from the Ethernet header in the packet.

    • print_addr_ip_int(uint32_t ip) - Prints out a formatted IP address from a uint32_t. Make sure you are passing the IP address in the correct byte ordering.

  • Because you have root account access on your VM, you will have the necessary permissions to run Wireshark. You may find that to be useful while debugging!

  • If you have any questions about the lab requirements or specification, please post on Piazza.

10. Submitting

Please remove any debugging output prior to submitting.

To submit your code, simply commit your changes locally using git add and git commit. Then run git push while in your lab directory.