tcl wrapper for iptables

Here are some support routines I use to set up iptables under linux ... use with care, of course - CMcC

    #! /usr/bin/env tclsh
    
    # return the ip address of an interface
    proc ipofif {if} {
        return [lindex [regexp -inline {inet addr:([0-9.]+)} [exec /sbin/ifconfig $if]] 1]
    }
    
    # return the network mask of interface
    proc nmofif {if} {
        return [lindex [regexp -inline {Mask:([0-9.]+)} [exec /sbin/ifconfig $if]] 1]
    }
    
    # return the complete set of enabled interfaces
    proc enumerateif {} {
        set result {}
        foreach {junk if} [regexp -all -inline -line {^([a-zA-Z0-9:]+)[ \t]} [exec /sbin/ifconfig]] {
            lappend result $if
        }
        return $result
    }
    
    proc iptables {args} {
        set code [catch {eval exec iptables $args} result]
        if {$code} {
            puts stderr "IPTABLES ERROR: $args - $result"
        }
    }
    
    # Create new chain, or flush existing
    proc newchain {chain} {
        if {[catch {exec iptables -F $chain}]} {
            iptables -N $chain
        }
    }
    
    # block anything to or from this IP
    proc block {ip {how REJECT}} {
        set how LOGDROP
        iptables -A INPUT -j $how --source $ip
        iptables -A FORWARD -j $how --destination $ip
        iptables -A OUTPUT -j $how --destination $ip
    }
    
    proc accept {input args} {
        eval iptables -A $input $args -j ACCEPT
    }
    
    proc drop {input args} {
        set log [string range [string map {-- ""} $args] 0 28]
        eval iptables -A $input $args -j LOG --log-level warning --log-prefix [list $log]
        eval iptables -A $input $args -j LOGDROP
        #eval iptables -A $input $args -j DROP
    }
    
    # Accept tcp connections on a certain interface to a certain port
    proc allow {dest ifs {proto tcp}} {
        puts stderr "Allow $proto connections to port $dest from interfaces $ifs"
        foreach if $ifs {
            iptables -A ${proto}_ok -m multiport -p $proto --in-interface $if --destination $::all($if) --destination-ports [join $dest ,] -j ACCEPT
        }
    }
    
    ## redirect $destport $sourceIF $to
    proc redir {dest_port source to {proto tcp}} {
        puts stderr "Redirect $proto connections from $source interface to port $dest_port to $to"
        #allow $dest_port $source $proto
    
        set me [lindex [split $::all($source) /] 0]
    
        iptables -t nat -p $proto -A PREROUTING --destination $me --destination-port $dest_port -j DNAT --to-destination $to
    }
    
    # classify interfaces into global arrays by category
    # by string matching network masks
    proc classify {args} {
        foreach if [enumerateif] {
            set ::all($if) "[ipofif $if]/[nmofif $if]"
            puts stderr "if $if: $::all($if)"
    
            foreach {arr match} {
                if {[string match $match $::all($if)]} {
                    array set ::$arr $if $::all($if)
                }
            }
        }
    }