Welcome, guest | Sign In | My Account | Store | Cart
#!/usr/local/bin/tclsh
#
# PFW - Portforwarder tcltk use at own risk, Norman Deppenbroek 2001
#
# forwarding raw data from a listening port, towards a standard remote address:port
# block by session limits and accesslist
#


namespace eval pfw {

        variable version        v0
.93
        variable copyright      
"PortForwarder $pfw::version by Nodep"
        variable debug          
False   # if true show packet size on stdout
        variable localhost      
0
        variable localport      
0
        variable remotehost    
0
        variable remoteport    
0
        variable maxsession    
0
        variable allowlist      
0
        variable denylist      
0


        proc time  
{}           { return [ clock format [ clock seconds ] -format %D-%T ] }
        proc
print { syntax }   { puts "[ pfw::time ] --> $syntax" }
               
               
namespace eval db {
                        variable cnt
0    

                        proc inc
{ } {
                               
return [ incr pfw::db::cnt ]
                       
}

                        proc dec
{ } {
                               
return [ set pfw::db::cnt [ expr $pfw::db::cnt - 1 ] ]
                       
}
               
               
}
}


 
# PROCEDURES START HERE #

proc sio
{ fromsock tosock ip port } {
       
         
if { [ catch { set data [read $fromsock] } merror ] } {
                pfw
::print "ERR: #$pfw::db::cnt \t $merror"
                pfw
::print "CLR: #$pfw::db::cnt \t $pfw::remotehost:$pfw::remoteport <-> $pfw::localhost:$pfw::localport <-> $ip:$port"
               
catch { close $fromsock }
               
catch { close $tosock   }
                pfw
::db::dec
               
return
         
}


         
if {[string length $data] == 0} {

               
catch { close $fromsock }
               
catch { close $tosock }  
                pfw
::print "CLR: #$pfw::db::cnt \t $pfw::localhost:$pfw::localport <-> $pfw::remotehost:$pfw::remoteport <->  $ip:$port"
                pfw
::db::dec
               
return      
         
}
               
if { $pfw::debug } { pfw::print "TRX: #$pfw::db::cnt \t $pfw::remotehost:$pfw::remoteport <-> $pfw::localhost:$pfw::localport

                if { [ catch { puts -nonewline $tosock $data } merror ] } {
                        pfw::print "
ERR: #$pfw::db::cnt \t $merror"
                        pfw
::print "CLR: #$pfw::db::cnt \t $pfw::remotehost:$pfw::remoteport <-> $pfw::localhost:$pfw::localport <-> $ip:$port
                        catch { close $fromsock }
                        catch { close $tosock }  
                        pfw::db::dec
                }
}
 
 
proc connect { serverhost serverport sockclient ip port} {

        pfw::db::inc

        if { $pfw::db::cnt < $pfw::maxsession } {

           if { [ lsearch -exact $pfw::allowlist $ip ] != -1 } {

                  if { [ catch { set sockserver [ socket $pfw::remotehost $pfw::remoteport ] } merror ] } {
                        pfw::print "
ERR: #$pfw::db::cnt \t $merror"
                        pfw
::print "CLR: #$pfw::db::cnt \t $pfw::localhost:$pfw::localport <-> $ip:$port"
                       
catch { close $sockclient }
                       
catch { close $sockserver }
                        pfw
::db::dec
                       
return
                 
}

                  pfw
::print "NEW: #$pfw::db::cnt \t $pfw::localhost:$pfw::localport <-> $ip:$port"
                  pfw
::print "CON: #$pfw::db::cnt \t $pfw::localhost:$pfw::localport <-> $ip:$port "
                  fconfigure $sockclient
-blocking 0 -buffering none -translation binary
                  fconfigure $sockserver
-blocking 0 -buffering none -translation binary
                  fileevent  $sockclient  readable
[list sio $sockclient $sockserver $ip $port ]
                  fileevent  $sockserver  readable
[list sio $sockserver $sockclient $ip $port ]

         
} else {

                  pfw
::print "INT: #$pfw::db::cnt \t $ip:$port rejected by accesslist!"
                 
catch { close $sockclient }
                  pfw
::db::dec

         
}


       
} else {

                pfw
::print "INT: #$pfw::db::cnt \t $ip:$port rejected, maxsession reached!"
               
catch { close $sockclient }
                pfw
::db::dec
       
}
 
}

# MAIN STARTS HERE #

if { $argc == 7 } {

               
set pfw::db::cnt        0
               
set pfw::localhost      [ lindex $argv 0 ]
               
set pfw::localport      [ lindex $argv 1 ]
               
set pfw::remotehost     [ lindex $argv 2 ]
               
set pfw::remoteport     [ lindex $argv 3 ]
               
set pfw::maxsession     [ lindex $argv 4 ]
               
set pfw::debug          [ lindex $argv 5 ]

               
if { [ catch { set infile [ open [ lindex $argv 6 ]] } merror ] } {
                        puts
"ERROR - $merror"
                       
exit

               
} else {

                       
set pfw::allowlist [ read $infile ]
                       
if { [ catch { close $infile } merror ] } {
                                puts
"ERROR - $merror"
                               
exit
                       
}
               
}
                 
                pfw
::print "---------------------------------------------------------------------------------------"
                pfw
::print "$pfw::copyright - $pfw::localhost:$pfw::localport <-> $pfw::remotehost:$pfw::remoteport"
                pfw
::print "Allowing connections from:"
               
for {set x 0} { $x < [ llength $pfw::allowlist ]} {incr x} {pfw::print [ lindex $pfw::allowlist $x ] }
                pfw
::print "---------------------------------------------------------------------------------------"  
                socket
-server [list connect $pfw::remotehost $pfw::remoteport ] -myaddr $pfw::localhost $pfw::localport
                vwait forever

} else {

        puts
"\n\n"
        puts
"------------------------------------"
        puts
"$pfw::copyright - Usage:"
        puts
"------------------------------------"
        puts
"$argv0 localhost localport remotehost remoteport maxsessions false|true xslist.pfw\n\n"
}
 




# make a file called xslist.pfw and store it in de directory where pfw.tcl
# is listed and executed. XSLIST.PFW contains 1 line of allowed ip addresses:
127.0.0.1 192.168.168.110 212.121.221.121 192.168.168.120 192.168.168.12

History