Homework 8: Packet routing

In this assignment 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 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:

The homework template is available at:

git@git.uicbits.net:cs450-f13/public/homeworks/hw7

THE VIRTUAL NETWORK SETUP

We still use Mininet to simulate the network topology. The detailed method to have mininet setup is on homework 6 webpage. Besides that, in the hw8 folder, you need to so the following configuration:

Step 1: Environment configuration

./config.sh

If you got error message saying cannot find Pyhton.h, run the following command first:

sudo apt-get install python-dev

Step 2: Test the connectivity of your simulated network

./run_mininet.sh

And you will see the following if it runs correctly:

*** 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, (Do not do ctrl-z)

Now you can test the connectivity. Open another terminal and run the binary file

./sr_solution

And you will see

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    HWaddr86:05:70:7e:eb:56
        inet addr 10.0.1.1
eth2    HWaddrb2:9e:54:d8:9d:cd
		inet addr 172.64.3.1
eth1    HWaddr36:61:7c:4f:b6:7b
		inet addr 192.168.2.1
-- Ready to process packets -- 

This sr_solution has the function that you need to finish. With sr_solution running, you can run ping, traceroute, wget correctly from the client xterm. To run your own code, you will want to kill the sr_solution program, and run your own instead.

REQUIRED FUNCTIONALITY

If the router is functioning correctly, all of the following operations should work:

  1. Pinging from the client to any of the router’s interfaces (192.168.2.1, 172.64.3.1, 10.0.1.1).

  2. Tracerouting from the client to any of the router’s interfaces

  3. Pinging from the client to any of the app servers (192.168.2.2, 172.64.3.10)

  4. Tracerouting from the client to any of the app servers

  5. Downloading a file using HTTP from one of the app servers The majority of the code which makes the router work is provided for you.

ROLLING YOUR OWN ROUTER USING MININET

You will be responsible for implementing important elements of several subsystems within the router. The function should be the same with sr_solution provided. All code must be added to sr_router.c and sr_router.h. You are responsible for implementing:

in 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.

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

  2. in 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.

  3. in 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.

  4. in 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. in network_send_packet_from(): allocate a new IP packet, set its headers and payload correctly, and call router_send_ethernet_frame to send it along.

  5. in 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.

  6. in handle_arpreq(), for waiting packet on a arp request, first check whether it has been timeout, if so, send icmp host unreachable ICMP packet to the source, then clear the request in arp cache; if not, send a new arp request and update the valid time and send times.

DETAILING WITH PROTOCOL HEADERS

Within the sr framework you will be dealing directly with raw Ethernet packets. There are a number of resources which describe the protocol headers in detail, including Stevens UNP, www.networksorcery.com and the Internet RFC’s for ARP (RFC826), IP (RFC791), and ICMP (RFC792). The stub code itself provides some data structures in sr_protocols.h which you may use to manipulate headers. There is no requirement that you use the provided data structures, you may prefer to write your own or use standard system includes.

SIMPLIFYING ASSUMPTION/REQUIREMENT

  1. no IP Options

  2. noIP Fragmentation

  3. no IPv6 all

  4. non-ICMP messages sent directly to routers receive an ‘ICMP Protocol Unreachable’ message in reply.

  5. the only ICMP message you must reply to is ICMP Ping.

  6. all ARP packets must be for the Ethernet hardware type and IP protocol type.

  7. only ARP Requests and ARP Replies are to be processed.

DEBUGGING TOOLS

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

./sr -l logname.pcap

You can use tcpdump to display the packets of the log file in a readable form:

  
tcpdump -r  logfile  -e -vvv -x

Besides SR, you can also use mininet to monitor the traffic 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 mininet CLI:

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

or you can bring up a terminal inside server1 by

mininet> xterm server1

then inside the newly popped xterm,

sudo tcpdump -n -i server1-eth0

There are also some debugging functions provided. In sr_utils.c there are several functions, like:

  1. print_hdrs(uint8_t *buf, uint32_t length)

    Prints out all possible headers starting from the Ethernet header in the packet

  2. 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.

To find more information, you can access https://github.com/mininet/mininet/wiki/Simple-Router. But do not use the template code it provedes, it’s not compatible with our mininet version.