The only files in the provided source that you may modify are sr_router.h and sr_router.c (this does not include bugfixes). You may, however, add your own files and update the Makefile to support them.
Debugging the source code for logic errors, crashes and memory leaks should not be any different than any other program. The use of valgrind and gdb is encouraged
In order to facilitate debugging of network traffic handled by your router, the sr stub code supports tcpdump compatible packet logging for all packets sent from and coming to the router. It is highly recommended that you get comfortable logging packets and viewing the logfiles in tcpdump as soon as possible.
To log packets, use the -l command line option for sr to specify a log file. All packets will then be written to this log file.
elaine15:~/tmp/sr_skel> ./sr -t 17 -l logfile
To view the log file using tcpdump use the -r command. It is also recommended that you use the -e command to print out headers, the -vvv command for verbose output and the -x command to print out the hex values of the packets. Output should look as follows:
elaine15:~/tmp/sr_skel> /usr/class/cs244a/bin/tcpdump -e -vvv -x -r logfile
19:51:31.809693 0:e0:81:3:fd:9e Broadcast arp 84: arp who-has 172.24.74.40 tell vr-firewall.Stanford.EDU
0001 0800 0604 0001 00e0 8103 fd9e ac18
4a11 0000 0000 0000 ac18 4a28 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
000a 0000 0260 0000 0000 0002 92d0 0000
0000 0000 0000
Another very useful tool you may want to play around with is WireShark.
Your code must be stable (e.g. not crash) with any packet it receives. You should also discard packets that are obviously corrupted e.g. if the IP version is not IPv4, if the packet length is negative or above the Ethernet MTU etc.
You have to support two cases:
The very first thing you are going to want to do when ready to start playing around with the skeleton code is connect to the VN server and verify that your topology exists. Once the code is compiled, run ./sr with your topology number (using the -t command line option to specify the topology number. A session using topology number 17 might look as follows:
elaine15:~/tmp/sr_skel> ./sr -t 17 Destination: 0.0.0.0 Gateway : 172.24.74.17 Mask : 0.0.0.0 Interface : eth0 Client pepe connecting to Server vr-server-b:12345 Requesting topology 17 Sending c_open (type=1 len=108) Received Hardware Info with 19 entries Fixed IP: 172.24.74.17 INTERFACE: eth0 Speed: 10 Hardware Address: 70:00:00:11:00:01 Ethernet IP: 172.24.74.40 Subnet: 0.0.0.0 Mask: 0.0.0.0 INTERFACE: eth1 Speed: 0 Hardware Address: 70:00:00:11:00:02 Ethernet IP: 172.24.74.241 Subnet: 0.0.0.0 Mask: 0.0.0.0 INTERFACE: eth2 Speed: 0 Hardware Address: 70:00:00:11:00:06 Ethernet IP: 172.24.74.242 Subnet: 0.0.0.0 Mask: 0.0.0.0 Interface: eth0 ip address 172.24.74.40 Interface: eth1 hardware address 70:00:00:11:00:02 ip address 172.24.74.241 Interface: eth2 hardware address 70:00:00:11:00:06 ip address 172.24.74.242
You can ignore most of this information, but do verify that the IPs on the router's interfaces do match those on the router of topology assigned to you.
To verify that your router does, in fact, receive packets, try pinging one of the interfaces. Your router should print the following:
*** -> Received packet of length 60
*** -> Received packet of length 60
*** -> Received packet of length 60
What packet do you think this is? If you are able to connect to the server and see packets, you are correctly set up to start the assignment.
I'm having trouble connecting to my topology, the error I'm getting is:
client casado connecting to Server 171.67.71.18:12345 Requesting topology 122 Sending c_open (type=1 len=108) vns server closed session. Reason: reservehost failed sr_destroy_INSTANCE leaking memory
The most likely cause for this error is that there is already a router connected to your topology. Typically this happens when students forget to properly kill their routers (often using ctrl^z which only suspends them). You determine if a router is connected to your topology by going to the following web page: http://vns-1.stanford.edu/summary. If there is a router on your topology then it is already in use. The page gives an indication of the user doing the connection as well as the connecting IP address. If the router is yours, kill the process and it will free up. If another student has mistakingly connected to your topology you'll have to contact them directly or your Prof/TA.
No, that is how it should be .The skeleton code currently does pretty much nothing. It sits there, waits for packets and just drops them. With the skeleton code you can't access any web page. You will see the ARP requests from the first hop, but since the stub code does not reply, the first hop does not know which hardware address to send the first TCP packet (SYN) to. To access the web pages you will have to write code. Actually if you can access a web page you have completed significant portions of the assignment!
The vns-firewall does not respond to timed out packets with the expected ICMP message- or rather, it does, but filtering on the Stanford network may keep your instance of traceroute from receiving the packet, particularly if you are working from off campus. As long as you are getting traceroute replies from 1) your router, and 2) the application server where appropriate, things are fine even if you're getting the "three asterisk" output at the line where you would expect to see the firewall.
If you're printing debug information or logging packets, on some topologies you may see what seems like an impossible series of events:
What's happening here is that your topology is slightly malfunctioning- your router is working correctly, but at the application server packets are being routed back out through the firewall directly rather than passing through your topology. This happens because interactions between the servers and the topologies that they are multiplexed to are governed by special routing rules called policy routes; policy routes enable a routing decision to be made based on both the source and destination address of a packet, rather than just the destination alone. Policy routes are used to make it appear like a single Linux server exists on several hundred topologies at the same time. Unfortunately, there are some limitations on policy routes enforced by the operating system; one of them is that there is a limited number of policy routes that a single server can hold. For most applications, this is never an issue as the server never binds to more than a small handful of IP addresses; even with a policy route for each one, you'd never run out. VNS, however, bumps up against the routing limits that are set by the operating system; because we might have a server that is multiplexed onto a large number of topologies, we can run out of policy route slots or have multiple topologies try to use the same slot. When this occurs, the system attempts to fail gracefully by routing packets back out directly through the firewall, preserving the forward path for the topology, but sending return-route packets (such as ICMP echo reply packets generated by the server) back out directly through the system firewall, rather than through the associated topology.
If your concerned that the reverse route might have problems on your topology, email vns-support@lists.stanford.edu- in some cases its possible to manually restore the proper routing for the return path.
No, sr_handlepacket( .. ) delivers ethernet packets without the preamble and without the CRC. Likewise, sr_send_packet(..) expects an ethernet packet without the preamble and CRC. All packets to/from these functions have the following header format:
DST SRC FRAME DATA MAC MAC TYPE +-------+-------+-------+-------------------+ |6 bytes|6 bytes|2 bytes| 46 - 1500 bytes | +-------+-------+-------+-------------------+
No, you can expect packets of up to 1514 bytes
You have to handle both ARP requests and replies.
A static, hard-coded ARP cache is NOT acceptable. You should have a sufficiently sized (e.g. 100) entry table that is dynamically filled with values when ARP replies are received. You do NOT have to implement any sophisticated search alogrithm such as hashing or RB Trees, a linear search is perfectly acceptable.
The answer to this question depends on whether you are required by your instructor to implement guarantees on timeouts by your instructor. If you are, then yes, you should use threading or signals to ensure that the ARP cache is cleaned out on time. Otherwise, you actually can take the simple solution and only check the ARP queue timeout whenever another packet is received. This is not entirely correct behavior as a packet could be in the ARP queue for a very long time. But usually retransmits will arrive soon after the first packet, it performs pretty well in reality.
The minimum size for the data segment of an Ethernet packet is 46 bytes, whereas an ARP packet is 28 bytes. The OS pads an extra 18 bytes on to the end of ARP packets to meet this minimum length requirement. You don't have to worry about adding padding when generating ARP packets it will be added by the OS.
5.
No, you don't.
Just ignore fragmentation. Today on the internet fragmentation is actually pretty rare. Treat fragmented packets as normal packets and you should be fine.
No, other than that your client may not crash if it receives a packet with ip options, you don't have to do anything with them. You don't have to parse them and it is acceptable to drop such packets or generate incorrect checksums for them.
No you don't.
Section 4.2.2.9 of the router rfc (1812) states:
"Note in particular that a router MUST NOT check the TTL of a packet except when forwarding it."
There are three types of checksums:
IP Checksums - All IP packets have these and for any forwarded/generated IP packet you have to verify/calculate it.
TCP/UDP checksum - this is an end-to-end checksum that you don't have to worry about. Due to the way it is calculated IP header modifications won't change its value.
ICMP Checksum - You should verify/calculate this for ICMP messages that you receive/send (but *NOT*for ICMP message that you forward, these should be treated as IP packets only). For infos how to do this see RFC 792.
The algorithm as well as sample source code is in Peterson & Davie, page 95. Be careful what parts of the package you calculate the checksum over. TCP and ICMP for example need to be treated differently. A great way to test if your function is working is to run it on arriving packets. If you get the same checksum that is already contained in the packet it looks like your algorithm is working. If you use this test, make sure not to include the old checksum (the one that is in the packet when it arrived) in your checksum calculation. In the original calculation this checksum was zero! A good way to check if you've calculated the correct checksum is to use WireShark, which will indicate if the checksum values are correct.
An older version of the stub code only saved the first 96 bytes of the packets it receives and the generated ICMP packets are 98 bytes, hence WireShark's checksum does not take into account the last 2 bytes. The latest version of the stub code has the packet dump length increased to 100 bytes. You may also modify sr_router.h to increase PACKET_DUMP_SIZE yourself.
There is no "right" value, however 64 is a good choice. You can easily test what your current operating system uses:
[root@gadshome appenz]# /usr/sbin/tcpdump -x & [1] 1435 tcpdump: listening on wlan0 [root@gadshome appenz]# ping 171.64.64.64 PING 171.64.64.64 (171.64.64.64) from 192.168.1.104 : 56(84) bytes of data. 64 bytes from 171.64.64.64: icmp_seq=0 ttl=238 time=33.461 msec 11:23:03.258943 192.168.1.104 > CS.Stanford.EDU: icmp: echo request (DF) 4500 0054 0000 4000 4001 8d18 c0a8 0168 ab40 4040 0800 dbaa 9c05 0000 1703 703c 0a0d 0400 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435
Byte 9 ist the TTL. Linux uses the TTL to 64 (Hex 40) as well, at least for PING messages.
You should support the following:
All other ICMP message that you receive you can ignore, however you should forward any icmp message that is not for the virtual router itself.
The client has to reply to all ICMP requests destined to IPs owned by the router's interfaces
For regular ICMP packets (such as ping packets destined for an application server) yes, you do. For ICMP error messages (such as Host Unreachable messages), no, you do not. While RFC 792 states that ICMP messages should not be sent about ICMP messages, later RFCs (particularly RFC 1812 and 1122) have qualified that point, stating instead that ICMP messages should not be sent as a result of receiving ICMP error messages. This distinction allows hosts to be notified in the event of an actual error (such as a ping packet being ignored), but prevents the network from being spammed with error messages flying back and forth in response to other errors.
Use the destination address of the packet you are responding to
Host unreach should be sent after 5 failed ARP attempts. Host unreaches should be sent back to the client after 5-7 seconds of sending the first ARP.