Networks and Distributed Systems

Lab 1: Fun with Click
(Jinyang Li)
Home | Schedule | Labs | Discuss
This lab intends to give you some experience playing with a x86-based software router, the Click modular router. Click provides a software architecture for building extensible and configurable routers. A Click router is assembled from a number of smaller software modules called elements each of which implements a specific simple router function such as packet classification, scheduling, header checking etc. A Click configuration file "glues" the individual elements together to form a packet processing pipeline. You may find it helpful to skim through the original the Click paper.

Installation

You need access to a UNIX machine for this lab. Even though Click runs a variety of UNIXes such as Linux, BSD, Sun, Mac OS X, we will only provide technical support for the Linux/BSD platform.

Download the Click source tarball for this lab in your home directory.

$ cd ~
$ tar xzvf click-lab.tgz
$ cd click
$ ./configure --prefix=$HOME --enable-analysis --enable-test
...
$ make install
$ ~/bin/click conf/test.click
ok:   40 | 45000028 00000000 401177c3 01000001 02000002 13691369
ok:   40 | 45000028 00000000 401177c3 01000001 02000002 13691369
ok:   40 | 45000028 00000000 401177c3 01000001 02000002 13691369
ok:   40 | 45000028 00000000 401177c3 01000001 02000002 13691369
ok:   40 | 45000028 00000000 401177c3 01000001 02000002 13691369
The --prefix=$HOME configuration switch causes Click to install into your home directory. To run the Click driver and read its manual pages, you'll need to add $HOME/bin and $HOME/man to your PATH and MANPATH environment variables, respectively. Alternatively, if you have root privilege on your machine, you can install Click in /usr/local, /usr/local/click, or wherever you'd like.

The --enable-analysis and --enable-test configuration switches turn on support for two necessary sub-packages, including trace analysis and regression test elements.

If you get a bus error when running Click on a Solaris or other non-x86 machine, try running your conguration through click-align: click-align config.click | click.

Download this lab and in your home directory and untar it. Do all your problems in the lab1/ directory.

$ cd ~
$ tar xzvf lab1.tgz
$ cd lab1/
To check if your solutions are correct (TA will also be grading your labs using the same method), do
$ cd ~/lab1
$ make check

Basic packet manipulation

Problem 1: Create a router configuration file called p1.click. Your router reads packets from a tcpdump file called d1.dump, checks the correctness of IP header, routes all packets with
  • destination prefix 18/8 to file o1-1.dump
  • destination prefix 131.207/16 to file o1-2.dump
  • destination prefix 149.207/16 to file o1-3.dump
It discards all rest packets.

tcpdump is a program for reading and storing traces for captured packets. Running tcpdump on a particular network interface puts that interface in promiscous mode to capture all packets received on the medium regardless of hardware addresses. A tcpdump file's link type is called its encapsulation. We will be dealing with only raw IP encapsulation, where the files have no link-level headers; the first bytes in each packet will be an IPv4 header.

Hint: You need to make use of the FromDump, ToDump elements to read from and write to tcpdump files.

Queuing

Problem 2: (Thanks to Edddie for this problem) Create a router configuration file called p2.click. Your router reads from a tcpdump file called d2.dump, maintaining the timing of the dump file. (This means if adjacent packets in the dump file have timestamps that are 0.5 seconds apart, the packets should be emitted to the configuration 0.5 seconds apart). The packets should be written to o2.dump file except that:
  • Packets should be written to the dump file at a maximum rate of 1 Mbps. (i.e. you are simulating an output link whose capacity is 1Mbps). This means you need queueing and dropping in your configuration.
  • TCP should always get up to 75% of the bandwidth (up to 750Kbps). This means that if the TCP input rate is 750Kbps and the UDP input rate is also 750 Kbps, TCPs output rate will equal 750Kbps and UDPs output rate will be limited to 250Kbps. If the TCP input rate is less than 750Kbps, UDP and other kinds of traffic can take up the remainder.

Packet timestamps in the output file should reflect the 1Mbps rate limit.

Hint: Check out BandwidthShaper element

Problem 3: (playing with real packets using userlevel Click) Ph.D. students must complete this problem, masters' students may skip it if you do not have root access to your computer.

Create a router configuration file that routes packets between two tunnel interfaces. You should name the two interfaces clicktun0 (with IP 1.0.0.1) and clicktun1 (with IP 2.0.0.1). While the router is running, start a tcpserver that listens on clicktun0 interface (port 7777) ./tcpServer -l 1.0.0.1:7777. Then, you should be able to contact the server using a tcpclient that initiates connections to the server from the clicktun1 interface ./tcpClient -l 2.0.0.1 -o 1.1.1.1:7777

The tcpClient and tcpServer programs can be obtained by typing make in your lab1/ directory.

Note: tcpClient and tcpServer are included in your problem set directory.

Tunnel interface on Linux/BSD is a way for a kernel to deliver packets to userlevel programs. The KernelTun element will set up a tunnel interface with a name and IP address of your choice (you need root access to create a tunnel interface).

Set up clicktun0 with 1.0.0.1/8 and clicktun1 with 2.0.0.1/8 and print out all packets read from both tunnels in Click and push them back to the same tunnel. Type the commands ifconfig and route, do you see the tunnel interface in your routing table? If you type ping 1.0.0.1, does Click get those packets? How about ping 1.1.1.1? When you ping 1.0.0.1, the packets get sent straight via the loopback interface back to the kernel because 1.0.0.1 is an IP address local to the machine. On the other hand, packets with destination 1.1.1.1 are sent to the clicktun0 interface according to the routing table. But of course, there is no address 1.1.1.1 on your machine and if Click pushes those packets out of the tunnel interface again, they will be dropped by the kernel.

Hint: You need to use the IPRewriter element to rewrite the source and destination IP address fields in all the captured packets. To make the before mentioned tcp client and server communicate while passing all packets via Click, packets from clicktun0 with addresses 2.0.0.1->1.1.1.1 need to be rewritten to 2.1.1.1->1.0.0.1. Similarly, packets from clicktun1 with addresses 1.0.0.1->2.1.1.1 need to be rewritten to 1.1.1.1->2.0.0.1. This fools the tcpclient program into thinking it's communicating with 1.1.1.1 and the tcpserver into thinking it's talking to 2.1.1.1.

Do not test your IPRewriter element with ping, because it only works for TCP/UDP packets.

Writing simple Click elements

Problem 4 (A Censoring router)

Based on your configuration from Problem 2, write an element to inspect the contents of all TCP packets so if any packets contain the string ilovenyc, they will be dropped.

Write a new configuration file called p4.click with the new element. Your router reads packets from trace file d4.dump and writes them to output trace file o4.dump except those with the keyword "ilovenyc".

For those who have done problem 3, you can also test it with the tcpClient and tcpServer program by trying to have tcpClient send "ilovenyc" to the server. What do you see? Can you send any other bytes to the server afterwards? Why?

StringMatch is the name of the new element that you are going to write to detect specific keywords in packets. There is already a skeleton StringMatch element available as click/elements/tcpudp/stringmatch.[cc|hh]. Read through both files carefully, add in the necessary functionalities to complete the element.

Problem 5 (A Censoring router, continued)

Instead of dropping packets, upon detecting packets with string ilovenyc, your router fabricates TCP reset packets and sends them to both ends to shut down the connection. You do not need to drop any packets.

Write a new configuration file called p5.click with the new element. Your router reads packets from trace file d5.dump, detects if there's "ilovenyc" appearing anywhere in the packet, generates TCP reset packets if necessary and pushes all packets (original and fabricated) to output trace file o5.dump

For those who have done problem 3, you may test it with the tcpClient and tcpServer programs. Have tcpClient send "ilovenyc" to the server. What do you see this time?

FakeTCPReset is the name of the new element that you are going to write to detect specific keywords in packets. There is already a skeleton FakeTCPReset element available as click/elements/tcpudp/faketcpreset.[cc|hh]. Read through both files carefully, add in the necessary functionalities to complete the element.

Extra credit fun stuff

You might wonder what the real uses are for the toy router you have implemented in problem 4 & 5. In fact, these content inspecting routers are real products out there and they do both good and evil.

The good thing such routers do is to stop worms from spreading. Most existing worms have some identifiable pattern in their packet contents. Therefore, routers can effectively stop known worms from propagating further by dropping packets or resetting connections if those identifiable patterns are found. Our router is not very sophisticated; the StringMatch element simply tries to match a substring in the packet content. As a result, the kinds of patterns that can be specified are very restricted. Today, industry and research community are moving towards designing fast algorithms to let routers perform the more powerful regular expression matching in packet contents. For those who are curious, you can read the latest work here. There's also a nice public review for this paper.

Building fast content inspecting router is no easy matter (Enterprise routers/switches forward traffic at 10-20Gbps); how fast can your router forward packets while inspecting their contents w/o StringMatch? How about w/ StringMatch? Test it with your tunnelling router from Problem 3. For the adventurous ones, you can also test using kernel module click.

As the title of the problem suggests, content inspecting routers can also be used for censorship. And you can try your hands on playing with real TCP resetting routers following the examples in this paper.