Overview

While working on this lab, its highly recommended that you keep open the following files/terminals to help with reference and debugging:

  • Code editor with sr_router.c, sr_protocol.h

  • Terminal ssh ed to the VM, and execute ./run_mininet.sh

  • Open up a terminal at the client and two terminals at the router using xterm client and xterm sw0 (twice).

  • Function Reference List on your web browser

sr_handlepacket

The function of sr_handlepacket is to parse the Ethernet header and hand the packet stripped of the Ethernet header to handle_ip or handle_arp. This function is sr_handlepacket. The figure below illustrates this.

Step1

  • sr_handlepacket takes as input:

    • struct sr_instance * sr: an instance of the router

    • uint8_t packet: the packet with the ethernet header

    • unsigned int len: the length of the packet

    • char * interface: and the router’s interface name (eth0, eth1, eth2)

  • Read the comments for the first function call sr_get_interface. Take a look at the Function Reference List. Note that sr_get_interface:

    • takes as input: the router instance, and a valid interface to this router at (eth0, eth1, eth2).

    • returns: an interface of type struct sr_if for the router,

    • The fields of struct sr_if include an IP and MAC address of the router.

ToDos in sr_handlepacket

  1. Step 1: call ether_to_me to check if the packet is destined to this router. Inputs to ether_to_me:

    1. Router’s MAC address: This is returned as a field in sr_get_interface

    2. Destination MAC address of the packet: In the packet’s ethernet header. We can access the ethernet header by creating a struct pointer similar to Labs 5 and 6. Something like:

      //defined in sr_protocol.h
      struct sr_ethernet_hdr * ehdr = (struct sr_ethernet_hdr *) packet;
      ehdr -> ether_dhost //gives us the destination ethernet header of the packet.
    3. If ether_to_me does not return 1, then just return at this point. Else, we check if the packet has a valid length.

  2. The packet should atleast be as big as the ethernet header for it to be valid. So a check would look like the following:

    if(len < sizeof(struct sr_ethernet_hdr)){
      return;
    }
  3. Once both checks pass, we can now parse the packet depending on ether_type field of the struct sr_ethernet_hdr. Lines 192-195 of sr_protocol.h specify the ether_types you should process. Note these macros are defined in host-byte order while the packet’s ether_type field is in network-byte order! To compare the packet’s ether_type with IP or ARP you could write:

    if (ehdr->ether_type == htons(ethertype_arp))..else...IP
  4. Depending on whether it is an IP or ARP packet your code should strip the ethernet header and pass off the packet to either handle_ip or handle_arp. For e.g., passing it to handle_arp, we would need to change both packet and len to accommodate the packet without the ethernet header. You can use pointer arithmetic to pass the packet without the ethernet header, as packet + sizeof(struct sr_ethernet_hdr) or as ehdr + 1. The len would need to be decremented by sizeof(struct sr_ethernet_hdr).

  5. You are now ready to start on handle_arp! Note that this time, we want a pointer to the packet header of type struct sr_arp_hdr (also defined in sr_protocol.h) since our packet now starts at the ARP header.

Testing

Once you have written the case for arp_op_request in handle_arp you can check if your ARP responses work using Wireshark. To setup wireshark you would need the following:

  1. At the router terminal xterm sw0, start wireshark. Ignore the warning message that pops up. In wireshark start monitoring packets on sw0- (eth0, eth1, eth2).

  2. Open a different router terminal and cd router and run make and run your router code ./sr.

  3. Open up a client terminal xterm client, and issue a HTTP request to one of the servers: wget 192.168.2.2.

  4. Now, you should be able to see the ARP request in Wireshark that the client issued to the router, and if your code is correct, you should be returning an ARP response. You should also see subsequent TCP packets trying to flow through the router and failing (since we haven’t implemented forwarding yet). You can now stop wireshark and continue to write up your code for the router.

At any point if you would like to debug your code, you can run sr_solution to see what a working solution would look like and inspect the fields for the various protocol headers in wireshark.