It would be interesting to see how long since sending a SYN to a host we get a response back in the form of a SYN+ACK or a RST. Checking the time difference between the SYN and the response can give us an estimation of the round-trip time between the two hosts. For this exercise program, we read in TCP packets and check them for control flags. We are looking for SYN, RST, and SYN+ACK packets. When we see a SYN, we should record the timestamp of that packet, and when we see a response packet we should look up the time of the original packet and subtract to get an estimated round-trip time.
Using the three hash table helper functions below (saw_syn, saw_syn_ack, saw_rst) write a program which measures the time between a SYN packet and it's response. (Having students use their own hash table from data structures class makes more sense, but we're time constrained).
For every packet seen, check if it is a TCP/IP packet and that we captured enough bytes to be able to get the flags from the TCP header. If not, then skip this packet.
Use coral_read_clock_double(iface, timestamp) inside of pkthandler to get the timestamp of current packet.
Every time that a SYN+ACK (or RST) is seen and we have a timestamp for the corresponding SYN, output a tab separated line with: src_ip, dst_ip, src_port, dst_port, TYPE, DELTA. Where the src and dst are relative to the response packet. TYPE is "SA" or "R" as appropriate, DELTA is the time from SYN to response.
Start from template-synack.c and use the input trace: /usr/local/traces/dmoore/syn-rst.2.tcpdump
Modify code to print a message if a SYN+ACK or RST is seen without a corresponding previous SYN.
Questions: What can cause this to happen?
Sometimes the network will lose the first SYN packet, so the sender will retransmit it. Modify the code to detect duplicate SYNs.
Create a new function check_syn which is like saw_syn_ack in returing time of first SYN, but which does not remove the entry from the table. Use this to check for and print a line with TYPE of "DUP". For the DELTA use the time between this SYN and the previous.
Questions to think about: Might we see duplicate SYNs for other reasons? Why is the retransmission delta between duplicate SYNs what it is?
The th_flags field in a struct tcp has the bitfield for TCP control flags. Each individual bit position is available by symbolic name:
So for example, checking for the RST flag could be done with:
if (tcp->th_flags & TH_RST) ...
and checking for presence of both SYN and ACK could be done with:
if ((tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK))
...
Function to be called when we see a syn packet. Records where the syn came from and went to along with the time we saw it. If an entry is already present, update the stored time to time_seen.
Function to be called if we see a syn-ack packet. This will check for a matching syn packet and return the time we saw it. If there is no match, it will return 0. The original syn packet's information is removed from the table.
Function to be called if we see a rst packet. This will check for a matching syn packet and return the time we saw it. If there is no match, it will return 0. The original syn packet's information is removed from the table.