cs42200:spring19:labs:lab05

Packet Analyzer - Part I

  • Learn what packet analyzers (aka sniffers) do and why they are needed.
  • Learn how to run embedded software on a stand-alone computer (Xinu on a backend).
  • Write an Ethernet packet analyzer.

A packet analyzer (also known as a network analyzer, protocol analyzer, or packet sniffer) is a computer program that (possibly with hardware support) can obtain a copy of traffic passing over a computer network or segment of a network. As data streams flow across the network, the analyzer captures a copy of each packet, and decodes the packet, showing the contents of various fields in the packet headers and payload. Most analyzers can be configured to select some packets and ignore others. For example, a user can specify that the analyzer only display IP traffic, only display UDP traffic, etc. The meaning of fields in the packet are determined according to the appropriate standards (e.g., IEEE standards or RFCs).

Without a packet analyzer, it is almost impossible to understand what's actually happening under the hood in a network system. If two computers cannot communicate, a packet analyzer shows whether they are indeed sending packets, whether the packets are formatted correctly according to the standards, and whether the packet exchange is proceeding according to what the programmer expects. In addition, a packet analyzer helps us understand protocol operation. For example, you may be surprised at how many packets are actually sent when a computer uses TCP to connect to another computer, send, “Hello, world!”, and then close the connection.

tcpdump is a common packet analyzer that runs on the command line. It allows the user to intercept and display TCP/IP and other packets being transmitted or received over a network to which the computer is attached. There is a wrapper around tcpdump, called tcpdumpwrap, which has been made available to you to see how a packet analyzer looks like.

When tcpdump finishes capturing packets, it will report counts of:

  • packets captured (this is the number of packets that tcpdump has received and processed);
  • packets received by filter (the meaning of this depends on the OS in which you're running tcpdump, and possibly on the way the OS was configured - if a filter was specified on the command line, in some OSes it counts packets regardless of whether they were matched by the filter expression and, even if they were matched by the filter expression, regardless of whether tcpdump has read and processed them yet, in other OSes it counts only packets that were matched by the filter expression regardless of whether tcpdump has read and processed them yet, and in other OSes it counts only packets that were matched by the filter expression and were processed by tcpdump);
  • packets dropped by kernel (this is the number of packets that were dropped, due to a lack of buffer space, by the packet capture mechanism in the OS in which tcpdump is running, if the OS reports that information to applications; if not, it will be reported as 0).

Lets start a packet capture(on, say, xinu01):

sudo /usr/local/etc/tcpdumpwrap-net133 -v

This captures all the packets on the network interface eth0.1218. Now setup a communication channel for this port to simulate network traffic. The simplest way would be to send ping requests to the interface. Alternatively, you can use nc (netcat) to establish a connection as follows.

For example: Analyze packets on xinu01 on the interface eth0.1218(ip xx.xx.xx.xx). And send some data to xinu01 from, say, xinu02.
On xinu01:

nc -lu -p port_number

On xinu02:

nc -u xx.xx.xx.xx port_number

Anything typed at the second console will be sent to the first, and vice-versa. Now, you would see packets being displayed in the output of tcpdumpwrap-eth0.1218. the verbose option -v produces (slightly more) verbose output. For example, the time to live, identification, total length and options in an IP packet are printed.

Example packet trace:

xinu01 59 $ nc -lu -p <port>
test
xinu02 80 $ nc -u 128.10.3.51 <port>
test
xinu01 60 $ sudo /usr/local/etc/tcpdumpwrap-net133 -v
tcpdump: listening on eth0.1218, link-type EN10MB (Ethernet), capture size 262144 bytes
09:36:27.214695 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 84c2.00:24:14:64:df:00.802b, length 42
	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
	root-id 84c2.00:24:14:64:df:00, root-pathcost 0, port-role Designated
09:36:27.896167 IP (tos 0x0, ttl 1, id 22402, offset 0, flags [DF], proto UDP (17), length 199)
    xinu09-133.cs.purdue.edu.46555 > 239.255.255.250.1900: UDP, length 171
09:36:28.070698 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has xinuserver-133.cs.purdue.edu (Broadcast) tell xinuserver-133.cs.purdue.edu, length 42
09:36:28.722992 IP (tos 0x0, ttl 1, id 63200, offset 0, flags [DF], proto UDP (17), length 199)
    xinu11-133.cs.purdue.edu.60366 > 239.255.255.250.1900: UDP, length 171
09:36:29.227867 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 84c2.00:24:14:64:df:00.802b, length 42
	message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s
	root-id 84c2.00:24:14:64:df:00, root-pathcost 0, port-role Designated
09:36:29.543462 IP (tos 0x0, ttl 64, id 15840, offset 0, flags [DF], proto UDP (17), length 34)
    xinu02-133.cs.purdue.edu.57237 > xinu01-133.cs.purdue.edu.50000: UDP, length 6
09:36:29.724087 IP (tos 0x0, ttl 1, id 63394, offset 0, flags [DF], proto UDP (17), length 199)

The last line shows received UDP message of test.

This is just a demonstration of how a packet analyzer works. There are many more complex packet analyzers, out of which a popular choice is Wireshark. It is very similar to tcpdump, but has a graphical front-end, plus some integrated sorting and filtering options. You can use Wireshark on your machine to analyze packets.

Xinu (“XINU Is Not Unix”, a recursive acronym) is a Unix-like operating system originally developed by Professor Comer at Purdue as a research project in the 1970s and used for instruction starting in the 1980s. The name is both recursive, and is “Unix” spelled backwards. It has been ported to many hardware platforms, including the DEC PDP-11 and VAX systems, Sun-2 and Sun-3 workstations, Intel x86, PowerPC G3 and MIPS. Xinu was also used for some models of Lexmark printers and in other commercial products.

In the rest of the labs, you will implement a packet analyzer in Xinu. First, you need to download the source code of Xinu from the following URL and learn how to compile and run it on the Xinu backend machines in the following guide.

$ mkdir -p ~/cs422/
$ cd ~/cs422
$ wget http://courses.cs.purdue.edu/_media/cs42200:spring19:lab05.tar.gz -O lab05.tar.gz
$ tar xvf lab05.tar.gz
$ rm lab05.tar.gz

To use Xinu, several environment variables must be set.

First, log onto one of the front-ends xinu01.cs.purdue,edu, xinu02.cs.purdue.edu, .. up to xinu21.cs.purdue.edu.

Second, add /p/xinu/bin to your PATH environment variable. Please modify ~/.bashrc by adding the following line:

export PATH=${PATH}:/p/xinu/bin

Third, run source ~/.bashrc to make the change to take effect.

Before running Xinu on one of the backend machines, you must first compile Xinu source code into a binary.

$ cd ~/cs422/lab05/compile
$ make clean
$ make

Now, you have your binary named xinu under the directory. Note that you should compile every time you make changes to the Xinu source code.

Now, this is time to download your Xinu binary to one of the backend machines and run it. cs-status and cs-console are command-line tools that help you to do that.

$ cs-status -c quark

will show you who, if anyone, is logged onto each backend machine and how long they have been using it. Backends are named from galileo101 to galileo196. You should pick a free backend to run your Xinu binary. Assume that you picked galileo125 which was free. Then,

$ cs-console galileo125

will assign the backend machine for you to run your Xinu binary. Alternatively, simply using cs-console -c quark will return the first available backend machine to you.

After getting the backend machine, you should type

(control-@) OR (control-spacebar)

to escape to the local command mode. After that,

(command-mode) d    // download command
file: xinu      // tell it to download 'xinu'

to download your compiled xinu binary file. After downloading, you should powercycle the machine.

(control-@) OR (control-spacebar)

(command-mode) p    //power cycle the backend

After a few seconds, XINU will boot. if you want to download your compiled xinu binary file and powercycle the machine, you can use g as follows:

(control-@) OR (control-spacebar)

(command-mode) g   //download you compiled ''xinu'' and powecycle the machine. 

To quit, you should

(control-@) OR (control-spacebar)

(command-mode) q    //quit

Here is an example output that you will see:

xinu01 81 $ cs-console galileo125
connection 'galileo125', class 'quark', host 'xinuserver.cs.purdue.edu'


(command-mode) g
Using file: xinu
connection 'galileo125-dl', class 'DOWNLOAD', host 'xinuserver.cs.purdue.edu'
 272 -rw-rw-rw-   1 newxinu   127500 Jun  7 11:27 /tftpboot/galileo125.xbin
cp-download complete

connection 'galileo125-pc', class 'POWERCYCLE', host 'xinuserver.cs.purdue.edu'
CLA50000




.
.
. // some menus
.
.

Xboot for galileo -- version #1   Thu Jan  4 00:04:24 EST 2018

Ethernet Link is Up
MAC address is 98:4f:ee:00:3d:7d
Obtained IP address  128.10.136.125   (0x800a887d)
[XBOOT] Loading Xinu...

Xinu for galileo -- version #6  (arastega)  Thu Jun  7 11:14:45 EDT 2018

Ethernet Link is Up
MAC address is 98:4f:ee:00:3d:7d
 250084896 bytes of free memory.  Free list:
           [0x0015A1E0 to 0x0EFD8FFF]
           [0x0FDEF000 to 0x0FDEFFFF]
    104441 bytes of Xinu code.
           [0x00100000 to 0x001197F8]
    135944 bytes of data.
           [0x0011CFE0 to 0x0013E2E7]



------------------------------------------
   __    __   _____    _   _    _    _    
   \ \  / /  |__ __|  | \ | |  | |  | |   
    \ \/ /     | |    |  \| |  | |  | |   
    / /\ \    _| |_   | \   |  | |  | |   
   / /  \ \  |     |  | | \ |  \  --  /   
   --    --   -----    -   -     ----     
------------------------------------------


Welcome to Xinu!


xsh $ help

shell commands are:

argecho      date         help         memstat      udp          ?            
arp          devdump      ipaddr       ping         udpecho      
cat          echo         kill         ps           udpeserver   
clear        exit         memdump      sleep        uptime       
xsh $ 

Please do not leave a running copy of your Xinu on a backend. This will prevent anyone from using that backend and will create problems when more people want the backends.

Note: we removed the code in the main which creates the process for the shell, so you won't see exactly the same output as above

To see what packets are actually being received, you need to obtain a copy of all Ethernet frames that arrive, and dump the packet in appropriate format. In our Lab 06, we will dump the Ethernet frame packet to just print out source address, destination address, packet type, and first 15 bytes after the Ethernet type in hexadecimal format.

SOURCE -> DESTINATION, PACKET_TYPE, FIRST_15_BYTES_AFTER_ETHERNET_TYPE_IN_HEXADECIMAL\n

Your task is to fill out function void packetdump(struct netpacket *pptr) appropriately in net/packetdump.c to dump one packet. You will need to understand the structure of an Ethernet frame. Please refer to the definition of struct netpacket in Xinu file include/net.h.

For example, if the frame has MAC source address 0xa1a2a3a4a5a6, MAC destination address 0xb1b2b3b4b5b6, an Ethernet type field that indicates IPv4, and first 15 bytes of the payload are: 0x45 0x00 0x02 0x20 0x0f 0x26 0x40 0x00 0xff 0x11 0x5a 0x01 0x80 0x0a 0x88, then you should print out:

a1:a2:a3:a4:a5:a6 -> b1:b2:b3:b4:b5:b6, IPv4, 45 00 02 20 0f 26 40 00 ff 11 5a 01 80 0a 88 \n

For the packet type, you only need to identify IPv4, and ARP. For other types, you should print the type value in hexadecimal in the form 0xXXXX, where the uppercase X's are hex digits. To find the official types, look at http://standards.ieee.org/develop/regauth/ethertype/eth.txt to figure out types of the packet.

Remember that all fields in headers are in network byte order when you receive a packet

Important note: DO NOT USE printf() TO print text. Instead, when implementing packetdump() function, you must use kprintf().

Before attempting to dump packets, you need to enable promiscuous mode. Promiscuous mode makes the interface hardware accept and pass along all traffic it receives rather than passing only the restricted set of frames the hardware normally accepts. Promiscuous mode is normally used for packet sniffing that takes place on a router or on a computer connected to a hub (instead of a switch).

To enable promiscuous code, you must call the following function:

control(ETHER0, ETH_CTRL_PROMISC_ENABLE, 0, 0);

Later, you can choose to disable promiscuous mode by calling:

control(ETHER0, ETH_CTRL_PROMISC_DISABLE, 0, 0);

Insert the call to enable promiscuous mode in function netin() in net/net.c before the while() loop.

Insert a call to your void packetdump(struct netpacket *pptr) in the while() loop in function netin() in file net/net.c, which will print each incoming ethernet frame.

When successfully implemented, you should see the output of packetdump() like this following snippet:

00:1a:a0:df:90:5d -> ff:ff:ff:ff:ff:ff, ARP, 00 01 08 00 06 04 00 02 00 1a a0 df 90 5d 80
98:4f:ee:00:1e:45 -> ff:ff:ff:ff:ff:ff, IPv4, 45 00 01 04 00 00 40 00 40 11 28 11 80 0a 88
  • Does your Xinu code successfully compile and work when downloaded to XINU backends?
  • Does Xinu print out all incoming packets in promiscuous mode?
  • Does Xinu correctly print out source, destination, packet type, and first 15 bytes in hexadecimal?

Note that your directory structure should look like this:

~/cs422
~/cs422/lab05
~/cs422/lab05/compile
~/cs422/lab05/config
~/cs422/lab05/device
...

Run make clean before you turnin your work.

cd ~/cs422/lab05/compile
make clean  

You should use turnin command to submit your whole directory.

cd ~/cs422
turnin -c cs422 -p lab05 lab05

You can check with turnin -v.

turnin -c cs422 -p lab05 -v
Grading Rubric Points
TA test cases +15
Overall organization of the program +2
Coding style, commenting, etc +2
Makefile, compile and run +1
  • cs42200/spring19/labs/lab05.txt
  • Last modified: 2019/02/20 15:05
  • by yang1492