Last updated: 11/10/2003
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:
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 memoryThe 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.
What is the best methodology for debugging my router?
Debugging the source code for logic errors, crashes and memory leaks should not be any different than any other program. The use of purify 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 logfileTo 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 logfileAnother very useful tool you may want to play around with is ethereal.
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
What are good references for dealing
with protocol headers?
I tried running the skeleton code and
then accessing one of the webservers, however it doesn't work. Is
there something wrong?
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!
How do I write and test a function that
calculates the IP Checksum
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
ethereal which will indicate if the checksum values are correct.
Do I have to handle Muticast in my Router
No, you don't.
What ARP functionality do I have to handle?
You have to handle both ARP requests and replies.
How do I have to deal with fragmented
packets?
Just ignore fragmentation. Today on the internet fragmentation is
actually pretty rare. Treat fragmented packets as normal packets
and you should be fine.
How do we implement the arp queue
timeout? Should we use multiple threads or a timer?
You actually can take the simple solution and only check the
arp queue timeout whenever another packet is received. This is not
entirely correct behaviour 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.
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.
What
types of ICMP messages do I have to generate
You should support the following:
Does the client have to reply to
ICMP Echo Requests on all three interfaces or just on the
primary interface?
The client has to reply to all ICMP requests destined to IPs owned by
the router's interfaces
Do I have to be able to handle IP Options
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.
How do I implement the ARP cache? Is
a static table sufficient? Do I need a hash table?
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.
What kind of sanity checks should I perform
on the packer header?
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.
Do I have to deal with the ethernet preamble/crc?
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 | +-------+-------+-------+-------------------+
Why are the arp packets I get from sr_send_packet( .. ) 60 bytes instead of
42?
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.
Every once in awhile my router fails with the error, "Error: could not read
full command length from server"
Download the latest version of the stub code (the fix is in sr_vns_comm.c).
When exactly should I generate an ICMP timeout message?
ICMP timeout should be generated when the TTL field in the IP header of
an incoming packet is one or zero before it is decremented. Only
generating an ICMP message if the TTL of the packet is zero after
decrementing will lead to strange traceroute output and won't get full
credit.
Ethereal reports that the ICMP checksums generated by the unix ping
application are wrong. What is going on!?
The stub code only saves the first 96 bytes of the packets it receives and
the generated ICMP packets are 98 bytes, hence Ethereal'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.
Why do I keep getting a segfault when attempting to access memebers of struct
ip?
An older version of the stub code did not have the "packed" attribute
appended to the struct definition in sr_protocols.h. You can either add this
by hand or replace your sr_protocols.h with the sr_protocols.h in the current
release of the stub code.
So EXACTLY how many ARP requests must I send to a host withouth a response
before I send an ICMP host unreach packet back to the sending host?
5 or 6. There have been conflicting answers to this so either is fine.
What sort of routing entries do we need to support in the routing table?
You have to support two cases:
Which files in the stub code can I modify?
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.
Do I have to check/decrement the TTL in the IP header if the packet is
addressed to me?
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."