# interface generated by SpecTcl version 1.0 from /export/home/sparker/psh/scripts/tcpgraph/tcpgraphif.ui
#   root     is the parent window for this user interface

proc tcpgraphif_ui {root args} {

	# this treats "." as a special case

	if {$root == "."} {
	    set base ""
	} else {
	    set base $root
	}
    
	frame $base.frame#1

	button $base.button#1 \
		-command loadfile \
		-text {Read File}

	button $base.button#4 \
		-command {exit 0} \
		-text Quit

	label $base.label#1 \
		-text Plug-Ins

	listbox $base.listbox#1 \
		-height 12 \
		-width 35 \
		-xscrollcommand "$base.scrollbar#1 set" \
		-yscrollcommand "$base.scrollbar#2 set"

	scrollbar $base.scrollbar#2 \
		-command "$base.listbox#1 yview" \
		-orient v

	scrollbar $base.scrollbar#1 \
		-command "$base.listbox#1 xview" \
		-orient horizontal


	# Geometry management

	grid $base.frame#1 -in $root	-row 2 -column 3 
	grid $base.button#1 -in $root	-row 1 -column 1 
	grid $base.button#4 -in $root	-row 1 -column 2 
	grid $base.label#1 -in $root	-row 1 -column 3 
	grid $base.listbox#1 -in $root	-row 2 -column 1  \
		-sticky nesw
	grid $base.scrollbar#2 -in $root	-row 2 -column 2  \
		-sticky ns
	grid $base.scrollbar#1 -in $root	-row 3 -column 1  \
		-sticky ew

	# Resize behavior management

	grid rowconfigure $root 1 -weight 0 -minsize 30
	grid rowconfigure $root 2 -weight 1 -minsize 30
	grid rowconfigure $root 3 -weight 0 -minsize 30
	grid columnconfigure $root 1 -weight 1 -minsize 30
	grid columnconfigure $root 2 -weight 0 -minsize 30
	grid columnconfigure $root 3 -weight 0 -minsize 30
# additional interface code

global tk_library
source $tk_library/tkfbox.tcl

# A global "window id" to help make unique widget names
# Note that the expected use is as a suffix to a name
# supplied by some plugin
global winid
set winid 1

set types {
	{{All Files}	{[^.]}}
}

proc loadfile {} {
	set types {{{All Files} {*}}}
	if {[set filename [tk_getOpenFile -filetypes $types]] != ""} {
		;# Open snoop file, read and parse its contents
		puts "read $filename here."
		scansfile $filename
	}
}

proc scansfile {snoopfile} {
	global HalfConnNames HalfConnBytes
	global ConnNames
	global HalfConnDStart HalfConnDEnd HalfConnSegs
	global HalfConnTime HalfConnISS
	global HalfConnAck HalfConnWin
	global HalfConnFlags
	puts "scan file $snoopfile"

	popen file f $snoopfile
	pinit file p
	set pcount 0

	while {[f.read p] != "eof"} {
		incr pcount
		if {![regexp ip [ptbl p]]} {
			continue
		}
		if {[pget p ip proto] != "tcp"} {
			continue
		}
		set x "[format "%s_%s_%s_%s" [pget p ip src] [pget p tcp sport] [pget p ip dst] [pget p tcp dport]]"
		set y "[format "%s_%s_%s_%s" [pget p ip dst] [pget p tcp dport] [pget p ip src] [pget p tcp sport]]"
		if {[regexp $x [array names HalfConnNames]] == 0} {
			;# New connection found
			puts "New half-conn: $x"
			.listbox#1 insert end $x
			set HalfConnNames($x) [pget p tcp seq]:[pget p tcp ack]-[pget p tcp flags]
			set HalfConnBytes($x) 0
			set HalfConnSegs($x) 0
			set HalfConnISS($x) [pget p tcp seq]
			puts "New conn $x ACK [pget p tcp ack] SEQ [pget p tcp seq]"
		}
		incr HalfConnSegs($x)
		set ix ${x}_$HalfConnSegs($x)
		set seglen [expr [pget p ip len] - [plen p ip] - [plen p tcp]]
		set HalfConnFlags($ix) [pget p tcp flags]
		if {[regexp SYN $HalfConnFlags($ix)]} {
			incr seglen
		}
		if {[regexp FIN $HalfConnFlags($ix)]} {
			incr seglen
		}
		set HalfConnBytes($x) [expr $HalfConnBytes($x) + $seglen]
		set HalfConnDStart($ix) \
			[expr [pget p tcp seq] - $HalfConnISS($x)]
		set HalfConnDEnd($ix) \
			[expr $seglen + [pget p tcp seq] - $HalfConnISS($x)]
		set HalfConnTime($ix) [pget p file time]

		if {[regexp ACK $HalfConnFlags($ix)]} {
			set HalfConnAck($ix) [pget p tcp ack]
		}
		set HalfConnWin($ix) [pget p tcp win]
		if {( $pcount % 8192) == 0} {
			puts "processed $pcount packets..."
		}
	}
	puts "File read $snoopfile complete.  $pcount packets."
	pclose file f
	pfree p
}

puts "add checkbuttons"


set n 1
global plugins
foreach plugin [glob /opt/psh/tcllib/tcpgraph/*.plugin] {
	if [catch "source $plugin" outstr] {
		puts "Error in test $plugin: $outstr"
		continue
	}
	set name [plugin_name]
	checkbutton .frame#1.$n -text $name -variable plugins($plugin)
	pack .frame#1.$n
	incr n
}

proc filterOn {w y} {
	global plugins

	puts "identify selected connection"
	set index [$w nearest $y]
	set connid [lrange [.listbox#1 get $index] 0 3]
	puts "process active plugins on $connid"
	foreach i [array names plugins] {
		puts "plugin: $i status $plugins($i)"
		if {$plugins($i) == 1} {
			source $i
			plugin_main $connid
		}
	}
}
bind .listbox#1 <Button-1> {filterOn %W %y}





























# end additional interface code

}


# Allow interface to be run "stand-alone" for testing

catch {
    if {$argv0 == [info script]} {
	wm title . "tcpgraph"
	tcpgraphif_ui .
    }
}
