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 >
Text File  |  2012-02-17  |  10KB  |  505 lines

  1. # @(#) $Id: ipfw.expect 811 2012-02-18 04:50:40Z leres $ (LBL)
  2. #
  3. #  Copyright (c) 2006, 2007, 2008, 2009, 2011, 2012
  4. #    The Regents of the University of California.  All rights reserved.
  5. #
  6. #  Redistribution and use in source and binary forms, with or without
  7. #  modification, are permitted provided that: (1) source code distributions
  8. #  retain the above copyright notice and this paragraph in its entirety, (2)
  9. #  distributions including binary code include the above copyright notice and
  10. #  this paragraph in its entirety in the documentation or other materials
  11. #  provided with the distribution, and (3) all advertising materials mentioning
  12. #  features or use of this software display the following acknowledgement:
  13. #  ``This product includes software developed by the University of California,
  14. #  Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  15. #  the University nor the names of its contributors may be used to endorse
  16. #  or promote products derived from this software without specific prior
  17. #  written permission.
  18. #  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  19. #  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  20. #  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  21. #
  22. # ipfw.expect - acld script for controlling ipfw style firewall
  23. #
  24.  
  25. #
  26. # Always include an explicit "return" in each procedure:
  27. #
  28. #    This will cause an expect error if the procedure is supposed
  29. #    to kreturn a value
  30. #
  31. # Always exclude \r\n in negated regex character classes:
  32. #
  33. #    Otherwise the regex can match more than one line
  34. #
  35.  
  36. set timeout 10
  37. match_max 2048
  38. set cprompt "\[^#\r\n]*#"
  39. set currentmode "logout"
  40. set currentacl ""
  41. set f "expect.log"
  42. set logname "/var/log/acld/expect.log"
  43. if [catch {log_file -a $logname} err] {
  44.     #send_error "$prog: warning: $err\n"
  45.     set logname $f
  46.     if [catch {log_file -a $logname} err] {
  47.         #send_error "$prog: warning: $err\n"
  48.     }
  49. }
  50.  
  51. set lastseq 65535
  52.  
  53. # Higher level is easier if the prompt doesn't change
  54. proc prompt1 {} {
  55.     return "expect>"
  56. }
  57.  
  58. # Required procedures
  59.  
  60. proc attr {acl attrlist} {
  61.  
  62.     # ignore
  63.     puts "attr"
  64.     return
  65. }
  66.  
  67. proc drop {addr acl seq} {
  68.     global logname
  69.  
  70.     # Reopen the logfile from time to time
  71.     log_file
  72.     log_file -a $logname
  73.  
  74.     # ipfw add 888 deny ip from 10.0.0.1 to any via $acl in
  75.     ipfwcmd "drop" $seq "add $seq deny ip from $addr to any via $acl in"
  76.     return
  77. }
  78.  
  79. proc blockhosthost {addr1 addr2 acl seq} {
  80.  
  81.     ipfwcmd "blockhosthost" $seq \
  82.         "add $seq deny ip from $addr1 to $addr2 via $acl in"
  83.     return
  84. }
  85.  
  86. proc dropudpport {port acl seq} {
  87.  
  88.     ipfwcmd "dropudpport" $seq \
  89.         "add $seq deny udp from any to any $port via $acl in"
  90.     return
  91. }
  92.  
  93. proc droptcpport {port acl seq} {
  94.  
  95.     ipfwcmd "droptcpport" $seq
  96.         "add $seq deny tcp from any to any $port via $acl in"
  97.     return
  98. }
  99.  
  100. proc droptcpdsthostport {addr port acl seq} {
  101.  
  102.     ipfwcmd "droptcpport" $seq \
  103.         "add $seq deny tcp from any to $addr $port via $acl in"
  104.     return
  105. }
  106.  
  107. proc ayt {} {
  108.  
  109.     puts "ayt"
  110.     return
  111. }
  112.  
  113. proc listacl {acl interface} {
  114.  
  115.     set pid [spawn /sbin/ipfw -a list]
  116.     set timeout 10
  117.     set init 0
  118.     expect {
  119.         -re "^(\[0-9]+ +\[0-9]+ \[^\r\n]*)\r\n" {
  120.             if { $init == 0 } {
  121.                 puts "listacl -"
  122.                 set init 1
  123.             }
  124.  
  125.             # Break into a list
  126.             set av [split $expect_out(1,string) " "]
  127.             set an [llength $av]
  128.  
  129.             # XXX gag me: remove empty elements
  130.             # (caused by multiple blanks)
  131.             set n 0
  132.             while { $n < $an } {
  133.                 if { [lindex $av $n] == "" } {
  134.                     set av [concat [lrange $av 0 \
  135.                         [expr $n - 1]] [lrange $av \
  136.                         [expr $n + 1] [expr $an - 1]]]
  137.                     set an [expr $an - 1]
  138.                 } else {
  139.                     incr n
  140.                 }
  141.             }
  142.  
  143.             set n [lsearch $av "via"]
  144.             if { $n <= 0 } {
  145.                 set n [lsearch $av "recv"]
  146.             }
  147.             if { $n > 0 } {
  148.                 # we have a via interface
  149.                 if { $interface == "" } {
  150.                     exp_continue
  151.                 }
  152.                 set n [expr $n + 1]
  153.                 if { $n > $an } {
  154.                     # XXX can this happen?
  155.                     exp_continue
  156.                 }
  157.                 set v [lindex $av $n]
  158.                 if { $v != $interface } {
  159.                     exp_continue
  160.                 }
  161.             } else {
  162.                 # we don't have a via interface
  163.                 if { $interface != "" } {
  164.                     exp_continue
  165.                 }
  166.             }
  167.  
  168.             printacl $an $av
  169.             exp_continue
  170.         }
  171.         -re "^(ipfw: \[^\r\n]+)\r\n" {
  172.             # We've already declared success
  173.             puts " $expect_out(1,string)"
  174.         }
  175.         timeout {
  176.             # We've already declared success
  177.             puts "# timeout ($timeout seconds)"
  178.         }
  179.     }
  180.     catch {close} err
  181.     wait
  182.     puts "."
  183.     return
  184. }
  185.  
  186. proc printroute {what src dst} {
  187.  
  188.     # Strip trailing /32 from host routes
  189.     set i [string first "/32" $src]
  190.     if { $i > 1 } {
  191.         set src [string range $src 0 [expr $i - 1]]
  192.     } elseif { $src == "default" } {
  193.         set src "0.0.0.0/0"
  194.     } elseif { [regexp ^(\[0-9\]+\.\[0-9\]+\.\[0-9\]+)(/\[0-9\]+)\$ $src x three rest] } {
  195.         # 128.3.64/24 -> 128.3.64.0/24
  196.         set src "$three.0$rest"
  197.     }
  198.     if { $what == "UH" && $src == $dst && $src == "127.0.0.1" } {
  199.         # Ignore loopback
  200.         return
  201.     }
  202.     puts "S $src $dst"
  203.     return
  204. }
  205.  
  206. proc listroute {} {
  207.  
  208.     # Fire up command
  209.     set pid [eval spawn netstat -rn]
  210.  
  211.     set what "listroute"
  212.  
  213.     # Find end of comment/header
  214.     set timeout 10
  215.     expect {
  216.         -re "Expire\r\n" {
  217.             # done
  218.         }
  219.         timeout {
  220.             catch {close} err
  221.             wait
  222.             puts "$what-failed -"
  223.             puts "timeout ($timeout seconds)"
  224.             puts "."
  225.             return
  226.         }
  227.         eof {
  228.             # no routes, eh?
  229.             puts "$what-failed"
  230.             puts "."
  231.             return
  232.         }
  233.         default {
  234.             catch {close} err
  235.             wait
  236.             puts "$what-failed -"
  237.             puts "unknown problem:"
  238.             puts "$expect_out(buffer)"
  239.             puts "."
  240.             return
  241.         }
  242.     }
  243.  
  244.     # List out routes
  245.     puts "listroute -"
  246.     set timeout 10
  247.     expect {
  248.         -re "^(\[^ \r\n]+) +(link#\[^ \r\n]*) +(\[^ \r\n]+) +\[^\r\n]+\r\n" {
  249.             exp_continue
  250.         }
  251.         -re "^(\[^ \r\n]+) +(\[0-9A-Fa-f:]+) +(\[^ \r\n]+) +\[^\r\n]+\r\n" {
  252.             exp_continue
  253.         }
  254.         -re "^(\[^ \r\n]+) +(\[^ \r\n]+) +(\[^ \r\n]+) +\[^\r\n]+\r\n" {
  255.             printroute $expect_out(3,string) \
  256.                 $expect_out(1,string) $expect_out(2,string)
  257.             exp_continue
  258.         }
  259.         -re "^(\[^\r\n]*)\r\n" {
  260.             puts "\"$expect_out(1,string)\""
  261.             exp_continue
  262.         }
  263.         eof {
  264.             # done
  265.         }
  266.         default {
  267.             catch {close} err
  268.             wait
  269.             puts "$what-failed -"
  270.             puts "unknown problem:"
  271.             puts "$expect_out(buffer)"
  272.             puts "."
  273.             return
  274.         }
  275.         timeout {
  276.             catch {close} err
  277.             wait
  278.             puts "$what-failed -"
  279.             puts "timeout ($timeout seconds)"
  280.             puts "."
  281.             return
  282.         }
  283.     }
  284.     puts "."
  285.     catch {close} err
  286.     wait
  287.     return
  288. }
  289.  
  290. proc login {addr cuser cpass1 cpass2 euser epass1 epass2} {
  291.  
  292.     puts "login"
  293.     return
  294. }
  295.  
  296. proc logout {} {
  297.  
  298.     puts "logout"
  299.     return
  300. }
  301.  
  302. proc nonullzero {addr} {
  303.  
  304.     puts "nonullzero-failed -"
  305.     puts "not implemented"
  306.     puts "."
  307.     return
  308. }
  309.  
  310. proc nullzero {addr} {
  311.  
  312.     puts "nullzero-failed -"
  313.     puts "not implemented"
  314.     puts "."
  315.     return
  316. }
  317.  
  318. proc permitudpdsthostport {addr port acl seq} {
  319.  
  320.     ipfwcmd "permitudpdsthostport" $seq \
  321.         "permit udp from any to $addr $port via $acl in"
  322.     return
  323. }
  324.  
  325. proc permittcpdsthostport {addr port acl seq} {
  326.  
  327.     ipfwcmd "permittcpdsthostport" $seq \
  328.         "permit tcp from any to $addr $port via $acl in"
  329.     return
  330. }
  331.  
  332. proc restore {addr acl seq} {
  333.  
  334.     ipfwcmd "restore" $seq "delete $seq"
  335.     return
  336. }
  337.  
  338. proc restorehosthost {addr1 addr2 acl seq} {
  339.  
  340.     ipfwcmd "restorehosthost" $seq "delete $seq"
  341.     return
  342. }
  343.  
  344. proc restoreudpport {port acl seq} {
  345.  
  346.     ipfwcmd "restoreudpport" $seq "delete $seq"
  347.     return
  348. }
  349.  
  350. proc restoretcpport {port acl seq} {
  351.  
  352.     ipfwcmd "restoretcpport" $seq "delete $seq"
  353.     return
  354. }
  355.  
  356. proc restoretcpdsthostport {addr port acl seq} {
  357.  
  358.     ipfwcmd "restoretcpport" $seq "delete $seq"
  359.     return
  360. }
  361.  
  362. proc sync {} {
  363.  
  364.     puts "sync"
  365.     return
  366. }
  367.  
  368. proc unpermitudpdsthostport {addr port acl seq} {
  369.  
  370.     ipfwcmd "unpermitudpdsthostport" $seq "delete $seq"
  371.     return
  372. }
  373.  
  374. proc unpermittcpdsthostport {addr port acl seq} {
  375.  
  376.     ipfwcmd "unpermittcpdsthostport" $seq "delete $seq"
  377.     return
  378. }
  379.  
  380. # Local procedures
  381.  
  382. proc ipfwcmd {what seq cmd} {
  383.     global lastseq
  384.  
  385.     if { $seq != 0 } {
  386.         if { $seq > $lastseq } {
  387.             puts "$what-failed -"
  388.             puts "sequence too large ($seq > $lastseq)"
  389.             puts "."
  390.             return
  391.         }
  392.     }
  393.  
  394.     # Fire up command
  395.     set pid [eval spawn /sbin/ipfw $cmd]
  396.  
  397.     set timeout 10
  398.     set result ""
  399.     expect {
  400.         -re "^ipfw: warning: interface \[^\r\n]+ does not exist\r\n" {
  401.  
  402.             exp_continue
  403.         }
  404.         -re "^(ipfw: \[^\r\n]+)\r\n" {
  405.             catch {close} err
  406.             wait
  407.             puts "$what-failed -"
  408.             puts "$expect_out(1,string)"
  409.             puts "."
  410.             return
  411.         }
  412.         -re "^(0*$seq \[^\r\n]+)\r\n" {
  413.             set result "$expect_out(1,string)"
  414.             exp_continue
  415.         }
  416.         timeout {
  417.             catch {close} err
  418.             wait
  419.             puts "$what-failed -"
  420.             puts "ipfwcmd: timeout ($timeout seconds)"
  421.             puts "."
  422.             return
  423.         }
  424.         eof {
  425.             # done
  426.         }
  427.         default {
  428.             catch {close} err
  429.             wait
  430.             puts "$what-failed -"
  431.             puts "ipfwcmd: unknown problem"
  432.             puts "$expect_out(buffer)"
  433.             puts "."
  434.             return
  435.         }
  436.     }
  437.     catch {close} err
  438.     wait
  439.     if { $result != "" } {
  440.         puts "$what -"
  441.         puts "$result"
  442.         puts "."
  443.     } else {
  444.         puts "$what"
  445.     }
  446.     return
  447. }
  448.  
  449. proc printacl { an av } {
  450.  
  451.     # remove log option
  452.     set n [lsearch $av "log"]
  453.     if { $n > 0 } {
  454.         set av [lreplace $av $n $n]
  455.         set an [expr $an - 1]
  456.  
  457.         puts "+ av $av"
  458.         puts "+ an $an"
  459.     }
  460.  
  461.     if { $an < 4 } {
  462.         error "# printacl: not enough args \"$av\""
  463.     }
  464.  
  465.     set seq [lindex $av 0]
  466.     set count [lindex $av 1]
  467.  
  468.     set which [lindex $av 3]
  469.     if { $which == "deny" || $which == "reset" || $which == "unreach" } {
  470.         set which "block"
  471.     } elseif { $which == "allow" } {
  472.         set which "permit"
  473.     } else {
  474.         error "# printacl: can't find permit/deny \"$av\""
  475.     }
  476.  
  477.     set proto [lindex $av 4]
  478.     set what "unknown # $av"
  479.     set append ""
  480.     if { $proto == "ip" } {
  481.         if { $an >= 8 &&
  482.             [lindex $av 5] == "from" &&
  483.             [lrange $av 7 8] == "to any" } {
  484.             # "permit/block"
  485.             # 123 0 0 deny ip from 10.0.0.1 to any
  486.             # 123 0 0 deny ip from 10.0.0.1 to any in recv fxp1
  487.             # 0   1 2 3    4  5    6        7  8
  488.             set what "$which"
  489.             append what "host"
  490.             append append [lindex $av 6]
  491.         }
  492.     }
  493.  
  494.     set msg "$seq $count $what"
  495.     if { $append != "" } {
  496.         append msg " $append"
  497.     }
  498.     puts $msg
  499.     return
  500. }
  501.  
  502. # These are required to be at the end
  503. log_user 0
  504. interpreter
  505.