trafmon.rb
#-------------------------------------------------------------------------
# Traffic Distribution 
#    Analyze the capture file for traffic chart
#
# You may use this code freely in your commercial and non-commercial work.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
#
# Copyright (c) Unleash Networks 2005, All rights reserved
#----------------------------------------------------------------------------
 
require 'rubygems'
require 'win32ole'
require 'fox16'
include Fox
require 'UnleashCharts'
include UnleashCharts
 
class ChartWindow < FXMainWindow
 
	def initialize(theapp)
 
			# base class
			super(theapp, "Traffic over Time", nil, nil, DECOR_ALL,
						0,0,600,300)
 
			# single horizontal panel
			@contents = FXHorizontalFrame.new(self,
				LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0)
 
			# vertical frame
			@canvasFrame = FXVerticalFrame.new(@contents,
				LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,
				0,0,0,0,10,10,10,10)
 
			# actual canvas (whew!)
			@canvas = UnTimeSeriesChart.new(@canvasFrame)
 
	end
 
 
	def create
		super
		show(PLACEMENT_SCREEN)
	end	
 
 
	def setModel (mod)
		@canvas.setModel( mod)
	end
 
end
 
 
class TimeBuckets
 
	@captureFile
	@sampleInterval
 
	attr_reader	:maxval,:minval,:startTime,:endTime
	attr_reader	:valunits
 
	def initialize(filename, sampleintvl)
		@sampleInterval = sampleintvl
		@captureFile=filename
 
		# just read first and last in order to set the 
		# scales
		unsniffDB = WIN32OLE.new("Unsniff.Database")
		unsniffDB.OpenForRead(filename)
		packetIndex = unsniffDB.PacketIndex
		firstPkt = packetIndex.Item(0)
		lastPkt  = packetIndex.Item(packetIndex.Count-1)
 
		# set start timestamp
		@startTime = Time.at(firstPkt.TimestampSecs,firstPkt.TimestampUSecs)
 
		# set end timestamp
		@endTime = Time.at(lastPkt.TimestampSecs,lastPkt.TimestampUSecs)
 
		print "Start time = #{@startTime}\n"
		print "End time = #{@endTime}\n"
 
		@maxval = 800000 # 1 mBps max
		@minval = 0
		@valunits = "bps"
 
		unsniffDB.Close()
	end
 
	def totalTimeUSecs 
		secdiff = @endTime.tv_sec - @startTime.tv_sec 
		usdiff = @endTime.tv_usec - @startTime.tv_usec
		if usdiff < 0
			usdiff =  usdiff + ::USECPERSEC
			secdiff = secdiff-1
		end
 
		totalTimeUSecs = (secdiff * ::USECPERSEC) + usdiff
	end
 
	def each_val
 
 
		unsniffDB = WIN32OLE.new("Unsniff.Database")
		unsniffDB.OpenForRead(@captureFile)
		packetIndex = unsniffDB.PacketIndex
		nPackets = unsniffDB.PacketCount
		currSecs = @startTime.tv_sec
		byteCount = 0
		idx=0
		while (idx < nPackets)
 
			pkt = packetIndex.Item(idx)
 
			if pkt.TimestampSecs == currSecs
				byteCount += pkt.Length
			else
				yield Time.at(currSecs), 8*byteCount,  DataPointStyle.new(DataPointStyle::LINEHEIGHT,"o")
				byteCount = 0
				currSecs = pkt.TimestampSecs
			end
 
			idx+=1
 
		end
 
		unsniffDB.Close
 
	end
 
	def yscalelabel
		"Traffic"
	end
 
	def xscalelabel
		"Time"
	end
 
end
 
 
USAGE = "trafmon <capture-filename> "
 
if ARGV.length != 1
	puts USAGE
	exit 1
end
 
 
# Classify incoming packets into time buckets
lenBuckets = TimeBuckets.new(ARGV[0],1000)
#lenBuckets.each_val do |tm, val|
#	print "Secs = #{tm.tv_sec},   Val = #{val}\n";
#end
 
# A new Fox Application and MainWindow object
theApp = FXApp.new
theMainWindow = ChartWindow.new(theApp)
theMainWindow.setModel(lenBuckets)
 
 
# Run application
theApp.create
theMainWindow.show
theApp.run