home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.ee.lbl.gov
/
2014.05.ftp.ee.lbl.gov.tar
/
ftp.ee.lbl.gov
/
acld-1.11.tar.gz
/
acld-1.11.tar
/
acld-1.11
/
ipfw.expect
< prev
next >
Wrap
Text File
|
2012-02-17
|
10KB
|
505 lines
# @(#) $Id: ipfw.expect 811 2012-02-18 04:50:40Z leres $ (LBL)
#
# Copyright (c) 2006, 2007, 2008, 2009, 2011, 2012
# The Regents of the University of California. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that: (1) source code distributions
# retain the above copyright notice and this paragraph in its entirety, (2)
# distributions including binary code include the above copyright notice and
# this paragraph in its entirety in the documentation or other materials
# provided with the distribution, and (3) all advertising materials mentioning
# features or use of this software display the following acknowledgement:
# ``This product includes software developed by the University of California,
# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
# the University nor the names of its contributors may be used to endorse
# or promote products derived from this software without specific prior
# written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# ipfw.expect - acld script for controlling ipfw style firewall
#
#
# Always include an explicit "return" in each procedure:
#
# This will cause an expect error if the procedure is supposed
# to kreturn a value
#
# Always exclude \r\n in negated regex character classes:
#
# Otherwise the regex can match more than one line
#
set timeout 10
match_max 2048
set cprompt "\[^#\r\n]*#"
set currentmode "logout"
set currentacl ""
set f "expect.log"
set logname "/var/log/acld/expect.log"
if [catch {log_file -a $logname} err] {
#send_error "$prog: warning: $err\n"
set logname $f
if [catch {log_file -a $logname} err] {
#send_error "$prog: warning: $err\n"
}
}
set lastseq 65535
# Higher level is easier if the prompt doesn't change
proc prompt1 {} {
return "expect>"
}
# Required procedures
proc attr {acl attrlist} {
# ignore
puts "attr"
return
}
proc drop {addr acl seq} {
global logname
# Reopen the logfile from time to time
log_file
log_file -a $logname
# ipfw add 888 deny ip from 10.0.0.1 to any via $acl in
ipfwcmd "drop" $seq "add $seq deny ip from $addr to any via $acl in"
return
}
proc blockhosthost {addr1 addr2 acl seq} {
ipfwcmd "blockhosthost" $seq \
"add $seq deny ip from $addr1 to $addr2 via $acl in"
return
}
proc dropudpport {port acl seq} {
ipfwcmd "dropudpport" $seq \
"add $seq deny udp from any to any $port via $acl in"
return
}
proc droptcpport {port acl seq} {
ipfwcmd "droptcpport" $seq
"add $seq deny tcp from any to any $port via $acl in"
return
}
proc droptcpdsthostport {addr port acl seq} {
ipfwcmd "droptcpport" $seq \
"add $seq deny tcp from any to $addr $port via $acl in"
return
}
proc ayt {} {
puts "ayt"
return
}
proc listacl {acl interface} {
set pid [spawn /sbin/ipfw -a list]
set timeout 10
set init 0
expect {
-re "^(\[0-9]+ +\[0-9]+ \[^\r\n]*)\r\n" {
if { $init == 0 } {
puts "listacl -"
set init 1
}
# Break into a list
set av [split $expect_out(1,string) " "]
set an [llength $av]
# XXX gag me: remove empty elements
# (caused by multiple blanks)
set n 0
while { $n < $an } {
if { [lindex $av $n] == "" } {
set av [concat [lrange $av 0 \
[expr $n - 1]] [lrange $av \
[expr $n + 1] [expr $an - 1]]]
set an [expr $an - 1]
} else {
incr n
}
}
set n [lsearch $av "via"]
if { $n <= 0 } {
set n [lsearch $av "recv"]
}
if { $n > 0 } {
# we have a via interface
if { $interface == "" } {
exp_continue
}
set n [expr $n + 1]
if { $n > $an } {
# XXX can this happen?
exp_continue
}
set v [lindex $av $n]
if { $v != $interface } {
exp_continue
}
} else {
# we don't have a via interface
if { $interface != "" } {
exp_continue
}
}
printacl $an $av
exp_continue
}
-re "^(ipfw: \[^\r\n]+)\r\n" {
# We've already declared success
puts " $expect_out(1,string)"
}
timeout {
# We've already declared success
puts "# timeout ($timeout seconds)"
}
}
catch {close} err
wait
puts "."
return
}
proc printroute {what src dst} {
# Strip trailing /32 from host routes
set i [string first "/32" $src]
if { $i > 1 } {
set src [string range $src 0 [expr $i - 1]]
} elseif { $src == "default" } {
set src "0.0.0.0/0"
} elseif { [regexp ^(\[0-9\]+\.\[0-9\]+\.\[0-9\]+)(/\[0-9\]+)\$ $src x three rest] } {
# 128.3.64/24 -> 128.3.64.0/24
set src "$three.0$rest"
}
if { $what == "UH" && $src == $dst && $src == "127.0.0.1" } {
# Ignore loopback
return
}
puts "S $src $dst"
return
}
proc listroute {} {
# Fire up command
set pid [eval spawn netstat -rn]
set what "listroute"
# Find end of comment/header
set timeout 10
expect {
-re "Expire\r\n" {
# done
}
timeout {
catch {close} err
wait
puts "$what-failed -"
puts "timeout ($timeout seconds)"
puts "."
return
}
eof {
# no routes, eh?
puts "$what-failed"
puts "."
return
}
default {
catch {close} err
wait
puts "$what-failed -"
puts "unknown problem:"
puts "$expect_out(buffer)"
puts "."
return
}
}
# List out routes
puts "listroute -"
set timeout 10
expect {
-re "^(\[^ \r\n]+) +(link#\[^ \r\n]*) +(\[^ \r\n]+) +\[^\r\n]+\r\n" {
exp_continue
}
-re "^(\[^ \r\n]+) +(\[0-9A-Fa-f:]+) +(\[^ \r\n]+) +\[^\r\n]+\r\n" {
exp_continue
}
-re "^(\[^ \r\n]+) +(\[^ \r\n]+) +(\[^ \r\n]+) +\[^\r\n]+\r\n" {
printroute $expect_out(3,string) \
$expect_out(1,string) $expect_out(2,string)
exp_continue
}
-re "^(\[^\r\n]*)\r\n" {
puts "\"$expect_out(1,string)\""
exp_continue
}
eof {
# done
}
default {
catch {close} err
wait
puts "$what-failed -"
puts "unknown problem:"
puts "$expect_out(buffer)"
puts "."
return
}
timeout {
catch {close} err
wait
puts "$what-failed -"
puts "timeout ($timeout seconds)"
puts "."
return
}
}
puts "."
catch {close} err
wait
return
}
proc login {addr cuser cpass1 cpass2 euser epass1 epass2} {
puts "login"
return
}
proc logout {} {
puts "logout"
return
}
proc nonullzero {addr} {
puts "nonullzero-failed -"
puts "not implemented"
puts "."
return
}
proc nullzero {addr} {
puts "nullzero-failed -"
puts "not implemented"
puts "."
return
}
proc permitudpdsthostport {addr port acl seq} {
ipfwcmd "permitudpdsthostport" $seq \
"permit udp from any to $addr $port via $acl in"
return
}
proc permittcpdsthostport {addr port acl seq} {
ipfwcmd "permittcpdsthostport" $seq \
"permit tcp from any to $addr $port via $acl in"
return
}
proc restore {addr acl seq} {
ipfwcmd "restore" $seq "delete $seq"
return
}
proc restorehosthost {addr1 addr2 acl seq} {
ipfwcmd "restorehosthost" $seq "delete $seq"
return
}
proc restoreudpport {port acl seq} {
ipfwcmd "restoreudpport" $seq "delete $seq"
return
}
proc restoretcpport {port acl seq} {
ipfwcmd "restoretcpport" $seq "delete $seq"
return
}
proc restoretcpdsthostport {addr port acl seq} {
ipfwcmd "restoretcpport" $seq "delete $seq"
return
}
proc sync {} {
puts "sync"
return
}
proc unpermitudpdsthostport {addr port acl seq} {
ipfwcmd "unpermitudpdsthostport" $seq "delete $seq"
return
}
proc unpermittcpdsthostport {addr port acl seq} {
ipfwcmd "unpermittcpdsthostport" $seq "delete $seq"
return
}
# Local procedures
proc ipfwcmd {what seq cmd} {
global lastseq
if { $seq != 0 } {
if { $seq > $lastseq } {
puts "$what-failed -"
puts "sequence too large ($seq > $lastseq)"
puts "."
return
}
}
# Fire up command
set pid [eval spawn /sbin/ipfw $cmd]
set timeout 10
set result ""
expect {
-re "^ipfw: warning: interface \[^\r\n]+ does not exist\r\n" {
exp_continue
}
-re "^(ipfw: \[^\r\n]+)\r\n" {
catch {close} err
wait
puts "$what-failed -"
puts "$expect_out(1,string)"
puts "."
return
}
-re "^(0*$seq \[^\r\n]+)\r\n" {
set result "$expect_out(1,string)"
exp_continue
}
timeout {
catch {close} err
wait
puts "$what-failed -"
puts "ipfwcmd: timeout ($timeout seconds)"
puts "."
return
}
eof {
# done
}
default {
catch {close} err
wait
puts "$what-failed -"
puts "ipfwcmd: unknown problem"
puts "$expect_out(buffer)"
puts "."
return
}
}
catch {close} err
wait
if { $result != "" } {
puts "$what -"
puts "$result"
puts "."
} else {
puts "$what"
}
return
}
proc printacl { an av } {
# remove log option
set n [lsearch $av "log"]
if { $n > 0 } {
set av [lreplace $av $n $n]
set an [expr $an - 1]
puts "+ av $av"
puts "+ an $an"
}
if { $an < 4 } {
error "# printacl: not enough args \"$av\""
}
set seq [lindex $av 0]
set count [lindex $av 1]
set which [lindex $av 3]
if { $which == "deny" || $which == "reset" || $which == "unreach" } {
set which "block"
} elseif { $which == "allow" } {
set which "permit"
} else {
error "# printacl: can't find permit/deny \"$av\""
}
set proto [lindex $av 4]
set what "unknown # $av"
set append ""
if { $proto == "ip" } {
if { $an >= 8 &&
[lindex $av 5] == "from" &&
[lrange $av 7 8] == "to any" } {
# "permit/block"
# 123 0 0 deny ip from 10.0.0.1 to any
# 123 0 0 deny ip from 10.0.0.1 to any in recv fxp1
# 0 1 2 3 4 5 6 7 8
set what "$which"
append what "host"
append append [lindex $av 6]
}
}
set msg "$seq $count $what"
if { $append != "" } {
append msg " $append"
}
puts $msg
return
}
# These are required to be at the end
log_user 0
interpreter