Enable specifying the network interface and fix command line options. v2.6
authorPat Thoyts <patthoyts@users.sourceforge.net>
Wed, 2 Dec 2009 23:38:53 +0000 (23:38 +0000)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Wed, 2 Dec 2009 23:38:53 +0000 (23:38 +0000)
This patch restricts the listening socket to the localhost interface
by default and permits specifying other (or all) interfaces.
The command line options processing is generalized now to permit additional
options -myaddr and -timeformat.

Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
bin/sockspy.tcl

index e7d03bbcd398f9a0f32e336db3d1d066333c3e2e..95ba3772d14e14125334ed2d31270e8f01507551 100644 (file)
@@ -16,10 +16,15 @@ exec wish $0 ${1+"$@"}
 # 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
@@ -93,6 +98,7 @@ array set state {
     time 1
     timeFormat ""
     timeFormatDefault "%H:%M:%S "
+    myaddr localhost
 }
 
 # variables to save across runs
@@ -108,6 +114,7 @@ set saveList {
     state(timeFormat)
     state(fontSize)
     state(showsockname)
+    state(myaddr)
     extract(client)
     extract(server)
     extract(meta2)
@@ -920,7 +927,9 @@ proc DoListen {} {
     # 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"
@@ -1027,7 +1036,11 @@ proc GetSetup {} {
     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
@@ -1045,8 +1058,8 @@ proc GetSetup {} {
     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
@@ -1075,23 +1088,27 @@ proc GetSetup {} {
     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 .
@@ -1108,11 +1125,16 @@ proc GetSetup {} {
 # 
 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)
@@ -1517,6 +1539,13 @@ proc useRegistry {} {
     return $r
 }
 
+proc Pop {varname {nth 0}} {
+    upvar $varname args
+    set r [lindex $args $nth]
+    set args [lreplace $args $nth $nth]
+    return $r
+}
+
 ################################################################
 ################################################################
 ################################################################
@@ -1530,38 +1559,60 @@ if {[catch {package present uri}]} {
 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