COMS7201 – Computer Networks 1

Computer Networks 1 (COMS7201/COMS3200) is a course I took at UQ as part of the Graduate Diploma of IT. It covered many aspects of networking:

  • Round Trip Time calculation (processing delay, propagation delay, bandwidth etc.)
  • HTTP Request creation and parsing
  • Introductory security and encryption
  • Packet Analysis in Wireshark
  • Network Layers: Link, Transport, Network, Application
  • Flow and Congestion control, reliable delivery in TCP
  • Routing algorithms.
  • Wireless and Multimedia Networking Introduction
  • A bunch of protocols (at varying details):
    • HTTP, FTP, POP, SMTP
    • TCP, UDP, TLS
    • IP, Software-Defined-Networking, IPv4, IPv6, NAT
    • Border Gateway Protocol, ICMP, SNMP
    • Ethernet, Multiple Access Protocols, Collision Detection, 802.11 Wi-Fi, ARP

Tutorials and Practicals

The tutorials consisted of calculations and practice exercises like RTT calculation, Djistra’s algorithm, SDN rule creation, among others. The practicals were lab exercises using Wireshark to analyse packets and gain a practical understanding of the concepts taught about various protocols.

Assignments/Projects

Probably the most interesting parts about this subject were the assignments, as this gave us hands-on experience with the protocols we were learning about and the sense of achievement that comes with developing your own solution to the problem. We could choose to write the coding assignments in any language we liked, though the textbook used Python and I am most experienced with it so I stuck with it.

Assignment 1

Assignment 1 consisted of three parts:

  1. A math problem to calculate the time for an HTTP request to complete over a satellite link, taking into account the propagation, processing time, DNS request and SYN/ACK packets.
  2. A packet analysis problem where we had to read a Wireshark capture and determine facts about the email exchange captured.
  3. A programming task to open a TCP connection to various websites (using the socket libraries) and sent appropriate HTTP GET headers to the site and parse the HTTP response to determine and display the following:
    • IP Address and Port of the server and client
    • Reply Code
    • Date
    • Last Modified
    • Content-Encoding
    • Moved To (and for extra marks, follow subsequent redirects each time determining the above)

Part C

For this programming part, I broke up the code into short methods to simplify the development and my own testing. Also, since I was trying to follow redirects, breaking the main analysis into a method separate from the main code, enabled me to loop and follow the redirects in a tidier fashion.

Originally I made individual methods to process the responses and discover the header information, but eventually, I realised that it’s easier to loop over each line in the headers, and use Python’s str.startswith() function to process each data point. This does have the drawback of not being unit-testable, but for this small assignment, I didn’t care.

for line in reply.decode().splitlines():
            if line.startswith("Date: "):
                date = gmt_aest(line[6:])
            if line.startswith("Last-Modified: "):
                last_modified = gmt_aest(line[15:])
            if line.startswith("Content-Encoding: "):
                content_encoding = line[17:]
            if line.startswith("Location: "):
                moved_to = line[10:]

To handle the redirect following, I made the main method call the analysis method in a loop, and break out of the loop if the analysis didn’t return an HTTP 301 or 302. Technically, the loop guard is the inverse so it will loop while it’s a redirect code or it’s the first time in the loop (so that something would actually happen. Sometimes it’s easier to invert the logic.).

The full code is available on Github (assignment 1)

Assignment 2

Assignment 2 consisted of 3 parts also:

  1. An online quiz with questions about various protocols that we have to research to answer and some calculations. The lecturer chose to make it an online quiz to save marking time
  2. A Wireshark packet capture analysis task, answering questions about network communication during a file transfer, specifically the TCP communication.
  3. A programming part to write our own DNS query tool. For extra marks also write a simple GUI for entering the DNS server, host to query and the output.

Part C

The task required that we write our own DNS requests and process the responses. DNS is a lower level than HTTP so this required us to actually hand-craft (or partially programmatically generate) the bytes to make up the various Request Questions and any binary flags and parse the Response Answers. I used the following web resources to help tremendously in this exercise:

The first one was quite useful for just starting – even knowing where to begin was a challenge, so Routley’s guide provided a great start – of course, the assignment was more involved. Zytrax’s guides were used in this and the next assignment for their easy to understand breakdown of the various bytes and binary flags.

I built methods for both creating the request and parsing the response, as well as a bunch of smaller methods to parse various responses and generate requests.

One library I used which was quite helpful was bitstring – a module for aiding in the creation of byte() objects build up from binary data. I used this to generate the flag bytes where the byte resolves to a binary value, and each bit represents a particular flag.

Parsing the basic A Records was “easy enough”, but unfortunately the CNAME and MX Records used pointers to other parts of the response message to save “precious” bytes. Tracing pointers around the response bytes was quite hard particularly the way I structured my code and it was getting too stressful. At the same time, we were informed that we could use the Python library dnslib to help. In my case, I’d already coded much of the packet encoding/decoding by hand, but I wanted to finish the MS and CNAME records too, so I used the library for those parts. But this made the code slightly kludgy.

But I learnt heaps during the assignment as it wasn’t against the rules so it doesn’t matter. In hindsight, I think if I’d used an OOP approach, for the response/request, I’d more easily be able to trace the pointers programmatically by keeping the message and its parts around in memory.

For extra marks still, we could create a nice GUI for our application – as it was a while since I had last used Tkinter it took me a few hours to wrap my head around it again, but I managed to come up with a nice GUI using built-in controls.

Screenshot of my GUI

I wanted to use a list of DNS servers and Hosts to query in the source code so I could just click one in the demo during class. To create the buttons dynamically, I ended up using a lambda function with Tkinter to pass the label of the button to the function which sets the DNS and host.

The complete code is available on Github (Assignment 2)

Assignment 3

Assignment 3 was a bit different – since it was getting closer to the end of the semester, the lecturer gave us a choice of two parts for the assignment, and the better mark would count toward the final grade.

  • An online quiz which involved research and calculation to answer questions about various protocols and technologies.
  • A programming part to create our own ping and traceroute combination program.

Part B

For this assignment, we required to write a program that pinged a host a few times, calculating the average Round Trip Time, and also calculate the number of hops to reach the host.

Using the skills and resources I had learnt from the Assignment 2 Part C, I was able to create the ICMP packet myself (mostly) and parse the response.

I used the same technique as Windows does to count the hops – that is, incrementing the TTL each time until I no longer receive a TTL Expired packet back.

Truth be told, I had problems creating the IP layer header and the IP/ICMP checksum. To help with this I called the socket library’s function to create the IP header for me and ended up hardcoding the checksum into the ICMP header based on Wireshark’s correction of it.

I did actually create the IP header with a fixed checksum but even with a fixed TTL, it didn’t work for some reason. And towards the end of the assignment, I almost got the checksum calculator working, but ran out of time and patience. Plus, it was not necessary anyway.

At a later date, I’d like to come back to this assignment and fix the checksum and IP header. The One’s Complement checksum isn’t hard, just a lot to think about.

You can view the complete work at Github (Assignment 3)

Overall

Generally, I enjoyed this course, tutorials and the assessment, gaining a hands-on understanding of binary and hexadecimal is useful, and the assignments pushed me to solve problems I wouldn’t have expected to try to solve.