# spy on conversation between a tcp client and server
#
# usage: sockspy clientPort serverHost serverPort
-# -or- sockspy -proxy proxyPort
# clientPort - port to which clients connect
# serverHost - machine where real server runs
# serverPort - port on which real server listens
+# -or- sockspy -proxy proxyPort
+# -or- sockspy -socks socksPort
+#
+# additional options:
+# -myaddr name - localhost or 0.0.0.0 or some other interface
+# -timeformat fmt - set the time display format
#
# e.g. to snoop on http connections to a web server:
# sockspy 8080 www.some.com 80
time 1
timeFormat ""
timeFormatDefault "%H:%M:%S "
+ myaddr localhost
}
# variables to save across runs
state(timeFormat)
state(fontSize)
state(showsockname)
+ state(myaddr)
extract(client)
extract(server)
extract(meta2)
# Listen on clntPort or proxyPort for incoming connections
set port $SP(clntPort)
if {$state(proxy) ne "none"} {set port $SP(proxyPort)}
- set n [catch {set state(listen) [socket -server clntConnect $port]} emsg]
+ set n [catch {
+ set state(listen) \
+ [socket -server clntConnect -myaddr $state(myaddr) $port]} emsg]
if {$n} {
INFO "socket open error: $emsg"
if {$NS ne "::ttk"} {.dlg.socks configure -anchor w}
${NS}::label .dlg.sl1 -text "Proxy Port:" -anchor e
${NS}::entry .dlg.se1 -textvariable SP(proxyPort)
-
+
+ ${NS}::checkbutton .dlg.local -text "Listen on all interfaces" \
+ -variable state(myaddr) -onvalue 0.0.0.0 -offvalue localhost
+ if {$NS ne "::ttk"} {.dlg.local configure -anchor w}
+
${NS}::label .dlg.cllabel -text "Command Line Equivalent"
${NS}::entry .dlg.clvar -textvariable SP(cmdLine)
# -state readonly doesn't seem to work, sigh
grid rowconfigure .dlg 2 -minsize 8
pack .dlg.msg -in .dlg.top -side top -fill x -padx 2 -pady 1
- pack .dlg.fforward .dlg.fproxy .dlg.fsocks .dlg.fcmdline -in .dlg.top \
- -side top -fill x -padx 2 -pady 2
+ pack .dlg.fforward .dlg.fproxy .dlg.fsocks .dlg.local .dlg.fcmdline \
+ -in .dlg.top -side top -fill x -padx 2 -pady 2
grid .dlg.cllabel -in .dlg.fcmdline -row 0 -column 0 -sticky w
grid .dlg.clvar -in .dlg.fcmdline -row 1 -column 0 -sticky ew
grid columnconfigure .dlg.fforward 2 -weight 1
grid columnconfigure .dlg.fforward 3 -minsize 10
grid rowconfigure .dlg.fforward 4 -minsize 10
- raise .dlg
bind .dlg <Return> [list .dlg.ok invoke]
bind .dlg <Escape> [list .dlg.cancel invoke]
GetSetup2
- .dlg.pe1 icursor end
- .dlg.fe2 icursor end
+ foreach entry {.dlg.pe1 .dlg.fe2 .dlg.se1} {
+ $entry icursor end
+ }
# trace all variables involved in the Setup window
trace variable state(proxy) w cmdlineUpdate
trace variable SP w cmdlineUpdate
cmdlineUpdate SP servHost w
- focus -force [expr {$state(proxy) ne "none" ? ".dlg.pe1" : ".dlg.fe2"}]
+ switch -exact -- $state(proxy) {
+ "http" { set focus .dlg.pe1 }
+ "socks" { set focus .dlg.se1 }
+ default { set focus .dlg.fe2 }
+ }
+ focus -force $focus
tk::PlaceWindow .dlg widget .
- raise .dlg
wm deiconify .dlg
tkwait window .dlg
wm deiconify .
#
proc GetSetup2 {} {
global state
- array set s {1 normal 0 disabled}
- if {$state(proxy) eq "none"} { array set s {0 normal 1 disabled} }
+ switch -exact -- $state(proxy) {
+ "none" {array set s {0 normal 1 disabled 2 disabled}}
+ "http" {array set s {0 disabled 1 normal 2 disabled}}
+ "socks" {array set s {0 disabled 1 disabled 2 normal}}
+ }
.dlg.pl1 config -state $s(1)
.dlg.pe1 config -state $s(1)
+ .dlg.sl1 config -state $s(2)
+ .dlg.se1 config -state $s(2)
foreach w {1 2 3} {
.dlg.fl$w config -state $s(0)
.dlg.fe$w config -state $s(0)
return $r
}
+proc Pop {varname {nth 0}} {
+ upvar $varname args
+ set r [lindex $args $nth]
+ set args [lreplace $args $nth $nth]
+ return $r
+}
+
################################################################
################################################################
################################################################
timestampInit
stateRestore
-if {$state(gui)} { createMain }
+set showconfig 1
+while {[string match -* [set option [lindex $argv 0]]]} {
+ switch -exact -- $option {
+ -local {
+ set state(proxy) none
+ set clntPort 8080
+ set servHost localhost
+ set servPort 80
+ set showconfig 0
+ }
+ -proxy {
+ set state(proxy) http
+ if {[llength $argv] > 1 && ![string match -* [lindex $argv 1]]} {
+ set SP(proxyPort) [Pop argv 1]
+ set showconfig 0
+ }
+ }
+ -socks {
+ set state(proxy) socks
+ if {[llength $argv] > 1 && ![string match -* [lindex $argv 1]]} {
+ set SP(proxyPort) [Pop argv 1]
+ set showconfig 0
+ }
+ }
+ -myaddr {
+ set state(myaddr) [Pop argv 1]
+ }
+ -timeformat {
+ set state(timeFormat) [Pop argv 1]
+ }
+ -hex { set state(ascii) 0 }
+ -ascii { set state(ascii) 1 }
+ default {
+ return -code error "invalid option \"$option\": must be\
+ -local, -proxy, -socks or -myaddr"
+ }
+ }
+ Pop argv
+}
-if {[lindex $argv 0] == "-local"} {
- set argv [list 8080 localhost 80]
- set argc 3
+# If there are more args, it's for forwarding
+if {[llength $argv] > 0} {
+ foreach {SP(clntPort) sh sp} $argv break
+ set state(proxy) none
+ if {$sh ne ""} {set SP(servHost) $sh}
+ if {$sp ne ""} {set SP(servPort) $sp ; set showconfig 0}
}
-if {[lindex $argv 0] == "-proxy"} {
- set state(proxy) http
- if {$argc == 2} {
- set SP(proxyPort) [lindex $argv 1]
- DoListen
- } else {
- GetSetup
- }
-} elseif {[lindex $argv 0] eq "-socks"} {
- set state(proxy) socks
- if {[scan [lindex $argv 1] %d SP(proxyPort)] == -1} {
- set SP(proxyPort) 1080 ;# FIX ME - overwrites saved port num
- GetSetup
- } else {
- DoListen
- }
+if {$state(gui)} { createMain }
+
+if {$showconfig} {
+ GetSetup
} else {
- if {$argc >= 1} { set SP(clntPort) [lindex $argv 0] }
- if {$argc >= 2} { set SP(servHost) [lindex $argv 1] }
- if {$argc >= 3} { set SP(servPort) [lindex $argv 2] }
- if {$argc >= 3} {
- DoListen
- } else {
- GetSetup
- }
+ DoListen
}
if {$state(extract)} createExtract