busyserver.rb
# ------------------------------------------------------------------
# busyservers.rb	Print busy servers information	
#	usage : busyservers <capture-file> 
#
#
# ------------------------------------------------------------------
require 'win32ole'
 
USAGE = "busyservers <capture-filename> "
 
if ARGV.length != 1
	puts USAGE
	exit 1
end
 
class ServerEntry
	attr_writer	:bytesin, :bytesout, :connections
	attr_reader	:bytesin, :bytesout, :connections
 
	def initialize (addr, port)
		@addr = addr
		@port   = port
		@bytesin = 0
		@bytesout = 0
		@connections = 0
	end
 
	def getkey
		s=@addr + "_" + @port
		s.squeeze
	end
 
	def to_s
		"Server  #{@addr} Port #{@port} [Connections #{@connections}]\n" +
		"          /         \\        \n" +
		"        (in)        (out)     \n" +
		" #{@bytesin} bytes\t\t#{@bytesout} bytes\n\n"
	end			
 
end
 
 
InputFile = ARGV[0]
UnsniffDB = WIN32OLE.new("Unsniff.Database")
UnsniffDB.OpenForRead(InputFile)
serverMap = Hash.new
unknown_cnt = 0
 
PacketIndex = UnsniffDB.PacketIndex
prevlayer=nil
(0..PacketIndex.Count-1).each do |idx|
	pkt = PacketIndex.Item(idx)
	layers = pkt.Layers
	layers.each do |lyr| 
		if lyr.Name == "TCP" 
			saddr = prevlayer.FindField("Source IP")
			daddr = prevlayer.FindField("Dest IP")
			syn   = lyr.FindField("SYN")
			ack   = lyr.FindField("ACK")
			sport = lyr.FindField("Src Port")
			dport = lyr.FindField("Dest Port")
			keyval_1 = daddr.Value + "_" + dport.Value
			keyval_2 = saddr.Value + "_" + sport.Value
 
			#print "s: #{syn.Value}\ta: #{ack.Value}\n"
			srv_entry = serverMap[keyval_1]
			if srv_entry
				srv_entry.bytesin += pkt.Length
			else 
				srv_entry = serverMap[keyval_2]
				if srv_entry
					srv_entry.bytesout += pkt.Length
				end
			end
 
 
			# When a SYN Segment is seen a server is accessed
			if syn.Value == "1 (Set)" && ack.Value == "0 (Clear)"
				if !srv_entry
				   serverMap[keyval_1] = ServerEntry.new(daddr.Value, dport.Value)
				   srv_entry = serverMap[keyval_1]
				end
				srv_entry.connections += 1
			end
 
		else
			prevlayer = lyr
		end
	end
end
 
# all accounting has been done, just sort by totalbytes and print the servers
serverArr = serverMap.values
serverArr.sort! { |a,b|  b.bytesin + b.bytesout <=> a.bytesin + a.bytesout }
serverArr.each {|val| print val}
 
 
UnsniffDB.Close()