appendKeyedPair
deleteElement
replaceValue
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
It's easier for a human to work with names like
Programs like
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
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:
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:
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
The
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 192.168.1.2 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:
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, 123.45.67.89, etc). We
can join these two pieces of information into a single identifier with
a line like this:
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:
The key first key (
Many sites will have multiple servers at the different addresses.
can resolve the different addresses to the same name with a program like
The file IP2Name.txt has the lookup table
built in the previous exercise. This table will let our application
convert the IP Addresses in
This can be read as a keyed list with code like this:
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:
google.com
or facebook.com
.
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.
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.
################################################################
# 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"
# 50.53.114.66.in-addr.arpa 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
}
66.114.53.42
72.233.104.123
216.176.180.53
204.176.49.116
16:02:14 7723 2999 192.168.1.2 -> mail.emich.edu 443
16:02:19 534 2183 192.168.1.2 -> 0.channel41.facebook.com 80
16:02:40 20247 1098 192.168.1.249 -> 204.176.49.116 80
16:03:17 534 2183 192.168.1.2 -> 0.channel41.facebook.com 80
16:04:15 534 2181 192.168.1.2 -> 0.channel41.facebook.com 80
16:04:52 460 882 192.168.1.231 -> 204.176.49.2 80
IP2Name.txt
.
IP2Name.txt
file should start like this:
204.176.49.116 sjmedia01.tivo.com.
204.176.49.2 204.176.49.2
204.176.49.65 mind.tivo.com.
72.233.104.123 wordpress.com.
72.233.104.124 wordpress.com.
practice.txt
file.
Notice that there are three conversations between 192.168.1.2 and facebook
in just this small section.
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
endloop
set localIP [lindex $line 3]
set remoteIP [lindex $line 5]
set id $localIP~[getValue $IPName $remoteIP]
{192.168.1.2~mail.emich.edu 15342 192.168.2.231~mind.tivo.com 3721 ...}
192.168.1.2~mail.emich.edu
) shows
that this is conversation between the 192.168.1.2 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.
nslookup
or whois
.
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.
set if [open IP2Name.txt r]
set IPName [split [read $if]]
close $if
192.168.1.2 <-> mail.emich.edu: IN: 15342 OUT: 5954
192.168.1.2 <-> 0.channel41.facebook.com: IN: 4272 OUT: 17462
192.168.1.249 <-> sjmedia01.tivo.com.: IN: 20247 OUT: 1098
192.168.1.231 <-> 204.176.49.2: IN: 1380 OUT: 1980
192.168.1.249 <-> mind.tivo.com.: IN: 3721 OUT: 2195