1. Download the keyedListLibByValue.tcl file. Rename it keyedListLibByReference.tcl and modify these procedures to use call by reference instead of call by value:

    The getValue procedure does not modify the contents of the list, and does not need to be modified for performance. However, to keep the calls to these procedures consistent, you might want to modify it also.

    Modify the test procedure you wrote for the previous lab 5 to test the by Reference version of the keyed list library.


  2. When working the output from various ethernet sniffers, the source and destination addresses may be reported as IP numbers, not as fully qualified domain names.

    It's easier for a human to work with names like google.com or facebook.com.

    Programs like whois and nslookup will query the nameservers and convert the IP addresses to a name. Depending on your connectivity and loads, this lookup can take many seconds.

    There are many more packets than there are individual sites visited. In order to make an program that analyzes tcpdump output run in a reasonable time, you'll want to cache a number to name lookup table.

    The keyed list is a useful tool for this. The key will be the IP address, and the value will be the name of the system at that address. If the IP address exists in the keyed list the readValue will return name almost instantly. If the IP address is not in the list, readValue will return an empty string, and we know that the code needs to resolve the name.

    The "convert an IP address into a name" functionality is the sort of thing that should be put into a procedure. By putting it into a procedure, we can provide a simple access to several lines of code. If a better way to solve the problem presents itself later, we can change the code inside the procedure without breaking other scripts that use it.

    A procedure to convert IP addresses to names looks like this:

    # proc address2name {listName address}--
    #    resolve an IP address into a name and save it for future use
    # Arguments
    #   listName	The keyed list of IP addresses and site names
    #   address     The IP address to check
    # Results
    #   The list passed (by name) to this procedure may be modified.
    proc address2name {listName address} {
      upvar $listName addrList
      # Try to convert the IP address to a name with the keyed list.
      set name [getValue $addrList $address]
      if {$name eq ""} {
        # If the IP address is not in the list, use nslookup to
        # find the name and save it.
        set txt [exec nslookup $address] 
        set lst [split $txt]
        # Look for line like by searching for list element "name"
        #	name = ord-agg-n40.panthercdn.com.
        set pos [lsearch $lst name]
        if {$pos > 0} {
          # If "name" is found, the qualified name is the element after
          # the = - skip 2 to get the name.
          incr pos 2
          set name [lindex $lst $pos]
        } else {
          # If $pos < 0, then there is no name identified, 
          # use the IP address as the resolved name.
          set name $address
        appendKeyedPair addrList $address $name
      return $name

    Add some more code around this procedure to loop through a set of IP addresses and print the full name.

    Here is a set of IP addresses to use:



  3. Get the practice.txt file from the previous lab. It looks like this:

    16:02:14	7723	2999	->	mail.emich.edu 	443
    16:02:19	534	2183	->	0.channel41.facebook.com 	80
    16:02:40	20247	1098	-> 	80
    16:03:17	534	2183	->	0.channel41.facebook.com 	80
    16:04:15	534	2181	->	0.channel41.facebook.com 	80
    16:04:52	460	882	-> 	80

    Rework the previous solution to step through this file and convert the addresses in field 5 to names.

    Instead of printing the output to the screen, write it to a file named IP2Name.txt.

    The IP2Name.txt file should start like this:

 sjmedia01.tivo.com. mind.tivo.com. wordpress.com. wordpress.com.


  4. Look at the practice.txt file. Notice that there are three conversations between and facebook in just this small section.

    When we are trying to track usage on the network, we want to know which sites are talking to what other sites. For example, we want to combine all the conversations between and facebook.com into one line and display the total number of bytes transferred between the two sites. We want to do the same with the other conversations.

    We can do this with a keyed list. The key is some identifier for the conversation, and the value will be a running total.

    In English, the loop looks like this:

    loop on each line from the tcpdump file
      create an identifier based on this line
      retrieve the value associated with that identifier
      add the bytes transfered in this line
      update the keyed list with the new value

    The first trick is to construct an identifier for each conversation. We can do this as the lines are being processed.

    The two pieces of information we are connecting are the internal (192.168.1.x) and external site (facebook.com,, etc). We can join these two pieces of information into a single identifier with a line like this:

        set localIP [lindex $line 3]
        set remoteIP [lindex $line 5]
        set id $localIP~[getValue $IPName $remoteIP]

    The tilde (~) is a symbol that we know won't appear in the actual data, so it's safe to use it to join the two data (local IP and remote IP) into a single identifier

    This id can be used as a key into a keyed list to generate totals of the conversations. We can use two keyed lists, one to hold a running total of bytes received and one to hold a running total of bytes transmitted.

    The keyed lists will look something like this:

     { 15342 3721 ...}

    The key first key ( shows that this is conversation between the on the internal network and mail.emich.edu on the external network, and the number 15342 is the value associated with that key - the number of bytes received from mail.emich.edu.

    Many sites will have multiple servers at the different addresses. can resolve the different addresses to the same name with a program like nslookup or whois.

    The file IP2Name.txt has the lookup table built in the previous exercise. This table will let our application convert the IP Addresses in practice.txt to site names. Note that not all IP addresses resolve. Some are "hidden" and only accessed by other pages that know hardcoded addresses for game servers, ad servers, etc. When the address didn't resolve, this file puts the original address into the list.

    This can be read as a keyed list with code like this:

    set if [open IP2Name.txt r]
    set IPName [split [read $if]]
    close $if

    Write an application to read the two files, and combine the data into a report of internal IP addresses and how much data they exchange with each external site.

    The results should look like this:

 <-> mail.emich.edu:  IN: 15342 OUT: 5954 <-> 0.channel41.facebook.com:  IN: 4272 OUT: 17462 <-> sjmedia01.tivo.com.:  IN: 20247 OUT: 1098 <->  IN: 1380 OUT: 1980 <-> mind.tivo.com.:  IN: 3721 OUT: 2195


Copyright Clif Flynt 2010