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 / cisco.expect < prev    next >
Text File  |  2012-02-18  |  32KB  |  1,447 lines

  1. # @(#) $Id: cisco.expect 812 2012-02-18 06:09:03Z leres $ (LBL)
  2. #
  3. #  Copyright (c) 2002, 2006, 2007, 2008, 2009, 2010, 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. # cisco.expect - acld script for controlling a cisco router
  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 "warning: $err\n"
  48.         #send_error "$prog: warning: $err\n"
  49.     }
  50. }
  51.  
  52. set lastseq 2147483647
  53.  
  54. # Cleanup if our child dies
  55. trap { wait } SIGCHLD
  56.  
  57. # Higher level is easier if the prompt doesn't change
  58. proc prompt1 {} {
  59.     return "expect>"
  60. }
  61.  
  62. # Required procedures
  63.  
  64. proc attr {acl attrlist} {
  65.     global isipv6
  66.  
  67.     foreach attr $attrlist {
  68.         if { $attr == "ipv6" } {
  69.             set isipv6($acl) 1
  70.             continue
  71.         }
  72.         puts "attr-failed -"
  73.         puts "unknown attr \"$attr\""
  74.         puts "."
  75.         return
  76.     }
  77.     puts "attr"
  78.     return
  79. }
  80.  
  81. proc drop {addr acl seq} {
  82.     global logname
  83.  
  84.     if { [string first "/" $addr] > 0 } {
  85.         # Network with mask
  86.         set addr [prefix2wild $addr]
  87.         if {$addr == 1} {
  88.             puts "drop-failed -"
  89.             puts "Invalid prefix."
  90.             puts "."
  91.             return
  92.         }
  93.         aclcmd "drop" $acl $seq "" "deny ip $addr any"
  94.     } else {
  95.         # Host address
  96.         aclcmd "drop" $acl $seq "" "deny ip host $addr any"
  97.     }
  98.     #Reopen the logfile from time to time
  99.     log_file
  100.     log_file -a $logname
  101.     return
  102. }
  103.  
  104. proc blockhosthost {addr1 addr2 acl seq} {
  105.     aclcmd "blockhosthost" $acl $seq "" "deny ip host $addr1 host $addr2"
  106.     return
  107. }
  108.  
  109. proc dropudpport {port acl seq} {
  110.     aclcmd "dropudpport" $acl $seq "" "deny udp any any eq $port"
  111.     return
  112. }
  113.  
  114. proc droptcpport {port acl seq} {
  115.     aclcmd "droptcpport" $acl $seq "" "deny tcp any any eq $port"
  116.     return
  117. }
  118.  
  119. proc dropudpdsthostport {addr port acl seq} {
  120.     aclcmd "dropudpdsthostport" $acl $seq "" \
  121.         "deny udp any host $addr eq $port"
  122.     return
  123. }
  124.  
  125. proc droptcpdsthostport {addr port acl seq} {
  126.     aclcmd "droptcpdsthostport" $acl $seq "" \
  127.         "deny tcp any host $addr eq $port"
  128.     return
  129. }
  130.  
  131. proc ayt {} {
  132.     global cprompt
  133.  
  134.     sendcmd ""
  135.     set timeout 10
  136.     expect {
  137.         -re $cprompt {
  138.             # done
  139.         }
  140.         timeout {
  141.             puts "ayt-failed -"
  142.             puts "timeout ($timeout seconds)"
  143.             puts "."
  144.             exit
  145.         }
  146.         default {
  147.             puts "ayt-failed -"
  148.             puts "unknown error"
  149.             puts "."
  150.             exit
  151.         }
  152.  
  153.     }
  154.     puts "ayt"
  155.     return
  156. }
  157.  
  158. #$acl not used with Cisco sup720-3B when using 'tcam' command
  159. #(tcam command displays match count of ACEs processed by hardware, but no seq#)
  160. #$interface not used when using show ip access-list $acl
  161. proc listacl {acl interface} {
  162.     global cprompt
  163.     global currentmode
  164.  
  165.     set err [entermode "enable" ""]
  166.     if { $err != "" } {
  167.         puts "listacl-failed -"
  168.         puts "$err"
  169.         puts "."
  170.         return
  171.     }
  172.  
  173.     set ip [acl2ip $acl]
  174.  
  175.     set cmd "show $ip access-list $acl"
  176.     sendcmd "$cmd"
  177.     #(above command displays match count of ACEs processed by software)
  178.     #(below command displays match count of ACEs processed by hardware)
  179.     #sendcmd "show tcam interface &interface acl in ip"
  180.  
  181.     set timeout 10
  182.     expect {
  183.         -re "^$cmd\[\r\n]*\r\n" {
  184.             exp_continue
  185.         }
  186.         -re "(Standard IP|Extended IP|IPv6) access list $acl\[\r\n]*\r\n" {
  187.             puts "listacl -"
  188.             expect {
  189.                 -re "^ *(\[^\r\n]*)\[\r\n]*\r\n" {
  190.                     set str $expect_out(1,string)
  191.                     printacl $str
  192.                     exp_continue
  193.                 }
  194.                 -re "Connection to.*closed by remote host\." {
  195.                     puts "$what-failed -"
  196.                     puts "$expect_out(0,string)"
  197.                     puts "."
  198.                     exit
  199.                 }
  200.                 -re "Connection to.*closed\." {
  201.                     puts "$what-failed -"
  202.                     puts "$expect_out(0,string)"
  203.                     puts "."
  204.                     exit
  205.                 }
  206.                 -re $cprompt {
  207.                     # This action must be last
  208.                     puts "."
  209.                     return
  210.                 }
  211.                 timeout {
  212.                     puts "listacl-failed -"
  213.                     puts "timeout ($timeout seconds)"
  214.                     puts "."
  215.                     exit
  216.                 }
  217.                 default {
  218.                     puts "listacl-failed -"
  219.                     puts "reason unknown"
  220.                     puts "."
  221.                     exit
  222.                 }
  223.             }
  224.         }
  225.         -re "^ *(\[^\r\n]*)\[\r\n]*\r\n" {
  226.             set str $expect_out(1,string)
  227.             puts "listacl-failed -"
  228.             puts "unparsed \"$str\""
  229.             puts "."
  230.             exit
  231.         }
  232.         -re "Connection to.*closed by remote host\." {
  233.             puts "$what-failed -"
  234.             puts "$expect_out(0,string)"
  235.             puts "."
  236.             exit
  237.         }
  238.         -re "Connection to.*closed\." {
  239.             puts "$what-failed -"
  240.             puts "$expect_out(0,string)"
  241.             puts "."
  242.             exit
  243.         }
  244.         -re $cprompt {
  245.             # Empty: the ACL doesn't exist
  246.             puts "listacl -"
  247.             puts "."
  248.             return
  249.         }
  250.         timeout {
  251.             puts "listacl-failed -"
  252.             puts "timeout ($timeout seconds)"
  253.             puts "."
  254.             exit
  255.         }
  256.         default {
  257.             puts "listacl-failed -"
  258.             puts "reason unknown"
  259.             puts "."
  260.             exit
  261.         }
  262.     }
  263.     return
  264. }
  265.  
  266. # List both IPv4 and IPv6 routes
  267. # XXX there's no easy way to return an error if IPv4 are listed ok
  268. # but IPv6 routes fail
  269. proc listroute {} {
  270.     global currentmode
  271.  
  272.     set err [entermode "enable" ""]
  273.     if { $err != "" } {
  274.         puts "listroute-failed -"
  275.         puts "$err"
  276.         puts "."
  277.         return
  278.     }
  279.     puts "listroute -"
  280.     _listroute ip
  281.     _listroute ipv6
  282.     puts "."
  283.     return
  284. }
  285.  
  286. proc login {addr cuser cpass1 cpass2 euser epass1 epass2} {
  287.     global spawn_id
  288.     global cprompt
  289.     global currentmode
  290.  
  291.     # Fire up subprocess
  292.     set pid [spawn ssh "-2ax" "-o" "stricthostkeychecking=no" $euser@$addr]
  293.  
  294.     # Wait for connect
  295.     set timeout 10
  296.     expect {
  297.         eof {
  298.             catch {close} err
  299.             # Don't hammer on router if we're misconfigured
  300.             sleep 10
  301.             puts "login-failed -"
  302.             puts "child died (1)"
  303.             puts "."
  304.             exit
  305.         }
  306.         timeout {
  307.             catch {close} err
  308.             puts "login-failed -"
  309.             puts "connect timeout ($timeout seconds)"
  310.             puts "."
  311.             exit
  312.         }
  313.         "Connection refused" {
  314.             catch {close} err
  315.             # Don't hammer on router if we're misconfigured
  316.             sleep 10
  317.             puts "login-failed -"
  318.             puts "connection refused"
  319.             puts "."
  320.             exit
  321.         }
  322.         "assword: " {
  323.             #done
  324.         }
  325.         default {
  326.             #exec kill $pid
  327.             catch {close} err
  328.             puts "login-failed -"
  329.             puts "unknown response: $expect_out(buffer)"
  330.             puts "."
  331.             #return
  332.             exit
  333.         }
  334.     }
  335.  
  336.     #sendpass for non-autoenable users
  337.     #set cprompt "\[^>\r\n]*>"
  338.     #if { ![sendpass "connect" $cuser $cpass1 $cpass2] } {
  339.     #    close
  340.     #    return
  341.     #}
  342.     #set currentmode "connect"
  343.     #sendcmd "enable"
  344.  
  345.     set cprompt "\[^#\r\n]*#"
  346.     if { ![sendpass "enable" $epass1 $epass2] } {
  347.         catch {close} err
  348.         return
  349.     }
  350.  
  351.     sendcmd "terminal length 0"
  352.     expect -re $cprompt
  353.  
  354.     set currentmode "enable"
  355.     puts "login -"
  356.     puts "child ssh pid is $pid"
  357.     puts "."
  358.     return
  359. }
  360.  
  361. proc logout {} {
  362.     global currentmode
  363.  
  364.     set err [entermode "enable" ""]
  365.     if { $err != "" } {
  366.         puts "logout-failed -"
  367.         puts "$err"
  368.         puts "."
  369.         #return
  370.         exit
  371.     }
  372.  
  373.     set currentmode "logout"
  374.     sendcmd "logout"
  375.     set timeout 10
  376.     expect {
  377.         -re "(\[^\r\n]*)\[\r\n]*\r\n.*#" {
  378.             catch {close} err
  379.             puts "logout"
  380.             puts "$expect_out(1,string)"
  381.             puts "."
  382.             return
  383.         }
  384.         -re "Connection to.*closed by remote host\." {
  385.             catch {close} err
  386.             puts "logout"
  387.             puts "$expect_out(0,string)"
  388.             puts "."
  389.             exit
  390.         }
  391.         -re "Connection to.*closed\." {
  392.             catch {close} err
  393.             puts "logout"
  394.             puts "$expect_out(0,string)"
  395.             puts "."
  396.             exit
  397.         }
  398.         timeout {
  399.             puts "logout-failed -"
  400.             puts "timeout ($timeout seconds)"
  401.             puts "."
  402.             exit
  403.         }
  404.         default {
  405.             puts "logout-failed -"
  406.             puts "reason unknown"
  407.             puts "."
  408.             exit
  409.         }
  410.     }
  411.     return
  412. }
  413.  
  414. proc nonullzero {addr} {
  415.     nullzerocmd "nonullzero" $addr "no"
  416.     return
  417. }
  418.  
  419. #if route already exists, IOS returns normally (no error).
  420. proc nullzero {addr} {
  421.     nullzerocmd "nullzero" $addr {}
  422.     return
  423. }
  424.  
  425. proc permitudpdsthostport {addr port acl seq} {
  426.     aclcmd "permitudpdsthostport" $acl $seq "" \
  427.         "permit udp any host $addr eq $port"
  428.     return
  429. }
  430.  
  431. proc permittcpdsthostport {addr port acl seq} {
  432.     aclcmd "permittcpdsthostport" $acl $seq "" "permit tcp any host $addr eq $port"
  433.     return
  434. }
  435.  
  436. #if sequence number doesn't exist, IOS returns normally (no error).
  437. proc restore {addr acl seq} {
  438.     aclcmd "restore" $acl $seq "no" ""
  439.     return
  440. }
  441.  
  442. #if sequence number doesn't exist, IOS returns normally (no error).
  443. proc restorehosthost {addr1 addr2 acl seq} {
  444.     aclcmd "restorehosthost" $acl $seq "no" ""
  445.     return
  446. }
  447.  
  448. #if sequence number doesn't exist, IOS returns normally (no error).
  449. proc restoreudpport {port acl seq} {
  450.     aclcmd "restoreudpport" $acl $seq "no" "deny udp any any eq $port"
  451.     return
  452. }
  453.  
  454. #if sequence number doesn't exist, IOS returns normally (no error).
  455. proc restoretcpport {port acl seq} {
  456.     aclcmd "restoretcpport" $acl $seq "no" "deny tcp any any eq $port"
  457.     return
  458. }
  459.  
  460. #if sequence number doesn't exist, IOS returns normally (no error).
  461. proc restoreudpdsthostport {addr port acl seq} {
  462.     aclcmd "restoreudpdsthostport" $acl $seq "no" ""
  463.     return
  464. }
  465.  
  466. #if sequence number doesn't exist, IOS returns normally (no error).
  467. proc restoretcpdsthostport {addr port acl seq} {
  468.     aclcmd "restoretcpdsthostport" $acl $seq "no" ""
  469.     return
  470. }
  471.  
  472. proc sync {} {
  473.     global cprompt
  474.     global currentmode
  475.     global currentacl
  476.  
  477.     set err [entermode "enable" ""]
  478.     if { $err != "" } {
  479.         puts "sync-failed -"
  480.         puts "$err"
  481.         puts "."
  482.         return
  483.     }
  484.     sendcmd "write memory"
  485.     set timeout 30
  486.     expect {
  487.         -re "Building configuration...\[^\r\n]*\r\n" {
  488.             #puts "Writing config to NVRAM..."
  489.             exp_continue
  490.         }
  491.         -re "(startup-config file open failed\[^\r\n]*)\[r\n]*\r\n.*#" {
  492.             puts "sync-failed -"
  493.             puts "$expect_out(1,string)"
  494.             return
  495.         }
  496.         -re $cprompt {
  497.             puts "sync"
  498.             return
  499.         }
  500.         timeout {
  501.             puts "sync-failed -"
  502.             puts "timeout ($timeout seconds)"
  503.             puts "exiting"
  504.             puts "."
  505.             exit
  506.         }
  507.         default {
  508.             puts "sync-failed -"
  509.             puts "$expect_out(buffer)"
  510.             puts "exiting"
  511.             puts "."
  512.             exit
  513.         }
  514.     }
  515. }
  516.  
  517. proc unpermitudpdsthostport {addr port acl seq} {
  518.     aclcmd "unpermitudpdsthostport" $acl $seq "no" ""
  519.     return
  520. }
  521.  
  522. #if sequence number doesn't exist, IOS returns normally (no error).
  523. proc unpermittcpdsthostport {addr port acl seq} {
  524.     aclcmd "unpermittcpdsthostport" $acl $seq "no" ""
  525.     return
  526. }
  527.  
  528. # Local procedures
  529.  
  530. # Returns "ip" or "ipv6" based on the acl name
  531. proc acl2ip {acl} {
  532.     global isipv6
  533.  
  534.     if [catch { set ipv6 [set isipv6($acl)] } err] {
  535.         set ipv6 0
  536.     }
  537.  
  538.     if { $ipv6 } {
  539.         set ip "ipv6"
  540.     } else {
  541.         set ip "ip"
  542.     }
  543.  
  544.     return $ip
  545. }
  546.  
  547. proc aclcmd {what acl seq pre cmd} {
  548.     global cprompt
  549.     global lastseq
  550.  
  551.     if { $seq != 0 } {
  552.         if { $seq > $lastseq } {
  553.             puts "$what-failed -"
  554.             puts "sequence too large ($seq > $lastseq)"
  555.             puts "."
  556.             return
  557.         }
  558.  
  559.         set ip [acl2ip $acl]
  560.  
  561.         if { $ip == "ip" } {
  562.             set cmd "$seq $cmd"
  563.         } else {
  564.             set cmd "sequence $seq $cmd"
  565.         }
  566.     }
  567.     if { [string length $pre] > 0 } {
  568.         set cmd "$pre $cmd"
  569.     }
  570.  
  571.     set err [entermode "acl" $acl]
  572.     if { $err != "" } {
  573.         puts "$what-failed -"
  574.         puts "$err"
  575.         puts "."
  576.         return
  577.     }
  578.     sendcmd "$cmd"
  579.     set timeout 30
  580.     expect {
  581.         #generic error catcher for cisco
  582.         -re "(%\[^\r\n]*)\[\r\n]*\r\n.*#" {
  583.             puts "$what-failed -"
  584.             puts "$expect_out(1,string)"
  585.             puts "."
  586.             return
  587.         }
  588.         -re "Connection to.*closed by remote host\." {
  589.             puts "$what-failed -"
  590.             puts "$expect_out(0,string)"
  591.             puts "."
  592.             exit
  593.         }
  594.         -re "Connection to.*closed\." {
  595.             puts "$what-failed -"
  596.             puts "$expect_out(0,string)"
  597.             puts "."
  598.             exit
  599.         }
  600.         -re $cprompt {
  601.             # success
  602.             puts "$what"
  603.             return
  604.         }
  605.         timeout {
  606.             puts "$what-failed -"
  607.             puts "aclcmd: timeout ($timeout seconds)"
  608.             puts "."
  609.             exit
  610.         }
  611.         default {
  612.             puts "$what-failed -"
  613.             puts "aclcmd: unknown problem"
  614.             puts "."
  615.             exit
  616.         }
  617.     }
  618. }
  619.  
  620. proc _listroute {ip} {
  621.     global cprompt
  622.  
  623.     set what ""
  624.     set src ""
  625.     set dst ""
  626.  
  627.     sendcmd "show $ip route"
  628.     set timeout 10
  629.     # Loop over routes
  630.     expect {
  631.         -re "^Gateway of last resort is (\[^ \r\n]+) to network (\[^ \r\n]+)\[\r\n]*\r\n" {
  632.             # IPv4 (Cisco's are so funny)
  633.             set what "S"
  634.             set src $expect_out(2,string)
  635.             set dst $expect_out(1,string)
  636.             printroute $what $src $dst
  637.             exp_continue
  638.         }
  639.         -re "^Codes:\[^\r\n]+\[\r\n]*\r\n" {
  640.             exp_continue
  641.         }
  642.         -re "^show \[^\r\n]+\[\r\n]*\r\n" {
  643.             exp_continue
  644.         }
  645.         -re "^IPv6 Routing Table \[^\r\n]+\[\r\n]*\r\n" {
  646.             exp_continue
  647.         }
  648.         -re "^(\[CS])\[* ] +(\[^ \r\n]+) is directly connected, (\[^\r\n]+)\[\r\n]*\r\n" {
  649.             set what $expect_out(1,string)
  650.             set src $expect_out(2,string)
  651.             set dst {}
  652.             printroute $what $src $dst
  653.             exp_continue
  654.         }
  655.         -re "^(\[BCS])\[* ] +(\[^ \r\n]+) \[^ \r\n]+ via (\[^,\r\n]+)\[^\r\n]*\[\r\n]*\r\n" {
  656.             set what $expect_out(1,string)
  657.             set src $expect_out(2,string)
  658.             set dst $expect_out(3,string)
  659.             printroute $what $src $dst
  660.             exp_continue
  661.         }
  662.  
  663.         -re "^(\[BCSL])\[* ] +(\[^ \r\n]+) \[^\r\n]+\[\r\n]*\r\n" {
  664.             # IPv6: first line
  665.             set what $expect_out(1,string)
  666.             set src $expect_out(2,string)
  667.             set dst {}
  668.             exp_continue
  669.         }
  670.         -re "^(\[BCSL])\[* ] +(\[^ \r\n]+) \[^\r\n]+\[\r\n]*\r\n" {
  671.             # IPv6: first line
  672.             # B   2A03:C600::/32 [20/0]
  673.             set what $expect_out(1,string)
  674.             set src $expect_out(2,string)
  675.             exp_continue
  676.         }
  677.         -re "^(\[BCSL])\[* ] +(\[^\r\n]+)\[\r\n]*\r\n" {
  678.             # IPv6: first line
  679.             set what $expect_out(1,string)
  680.             set src $expect_out(2,string)
  681.             exp_continue
  682.         }
  683.  
  684.         -re "^ +via (\[^,\r\n]+), \[^\r\n]+\[\r\n]*\r\n" {
  685.             # IPv6: second line
  686.             set dst $expect_out(1,string)
  687.             printroute $what $src $dst
  688.             exp_continue
  689.         }
  690.         -re "^ +via (\[^\r\n]+)\[\r\n]*\r\n" {
  691.             # IPv6: second line
  692.             set dst $expect_out(1,string)
  693.             printroute $what $src $dst
  694.             exp_continue
  695.         }
  696.  
  697.         -re "^ +(\[^ \r\n]+) is subnetted, \[^\r\n]+\[\r\n]*\r\n" {
  698.             # Skip
  699.             exp_continue
  700.         }
  701.         -re "^ +(\[^ \r\n]+) is variably subnetted, \[^\r\n]+\[\r\n]*\r\n" {
  702.             # Skip
  703.             exp_continue
  704.         }
  705.         -re "^ +\[^ \r\n]+ - \[^ \r\n]+ \[^\r\n]+\[\r\n]*\r\n" {
  706.             exp_continue
  707.         }
  708.         -re "^ *(\[^\r\n]+)\[\r\n]*\r\n" {
  709.             puts "# junk $expect_out(1,string)"
  710.             exp_continue
  711.         }
  712.         -re $cprompt {
  713.             # This action must be last
  714.             # done
  715.             return
  716.         }
  717.         timeout {
  718.             puts "# timeout ($timeout seconds)"
  719.         }
  720.     }
  721.     puts "."
  722.     return
  723. }
  724.  
  725. proc printacl {str} {
  726.     # Break into a list
  727.     set av [split $str " "]
  728.     set an [llength $av]
  729.  
  730.     # XXX gag me: remove empty elements (caused by multiple blanks)
  731.     set n 0
  732.     while { $n < $an } {
  733.         if { [lindex $av $n] == "" } {
  734.             set av [concat [lrange $av 0 [expr $n - 1]] \
  735.                 [lrange $av [expr $n + 1] [expr $an - 1]]]
  736.             set an [expr $an - 1]
  737.         } else {
  738.             incr n
  739.         }
  740.         #remove carraige return from last element...
  741.         if { $n == [expr $an - 1] } {
  742.             set lastav [lindex $av $n]
  743.             set newav [string trimright $lastav " \r\n"]
  744.             lset av $n $newav
  745.         }
  746.     }
  747.  
  748.     if { $an < 5 } {
  749.         error "# printacl: not enough args \"$str\""
  750.     }
  751.  
  752.     if  { [lindex $av [expr $an - 2]] == "sequence" } {
  753.         # deny ipv6 host 2001:400:610:102::CB any sequence 1002
  754.         # This is the "new" ipv6 way
  755.         set seq [lindex $av [expr $an - 1]]
  756.  
  757.         # Remove sequence from argument vector
  758.         set an [expr $an - 2]
  759.         set av [lrange $av 0 [expr $an - 1]]
  760.     } elseif  { [lindex $av 0] == "seq" } {
  761.         # This is the old extended access-list way
  762.         set seq [lindex $av 1]
  763.  
  764.         # Remove sequence from argument vector
  765.         set av [lrange $av 2 $an]
  766.         set an [expr $an - 2]
  767.     } else {
  768.         # 60090 deny tcp any host 198.128.24.1 eq 22 (319 matches)
  769.         # This is the normal extended access-list way
  770.         set seq [lindex $av 0]
  771.  
  772.         # Remove sequence from argument vector
  773.         set av [lrange $av 1 $an]
  774.         set an [expr $an - 1]
  775.     }
  776.  
  777.     set avn [lindex $av [expr $an - 1]]
  778.     if { $avn == "matches)" || $avn == "match)" } {
  779.         set count [lindex $av [expr $an - 2]]
  780.         set count [string trimleft $count "("]
  781.  
  782.         # Remove from argument vector
  783.         set an [expr $an - 2]
  784.         set av [lrange $av 0 $an]
  785.     } else {
  786.         set count 0
  787.     }
  788.  
  789.     set which [lindex $av 0]
  790.     if { $which == "deny" } {
  791.         set which "block"
  792.     } elseif { $which != "permit" } {
  793.         error "# printacl: can't find permit/deny \"$av\""
  794.     }
  795.  
  796.     set proto [lindex $av 1]
  797.     set what "unknown # $str"
  798.     set append ""
  799.     if { $proto == "ip" || $proto == "ipv6" || $proto == "icmp" } {
  800.         if { $proto == "icmp" } {
  801.             set protostr $proto
  802.         } else {
  803.             set protostr ""
  804.         }
  805.         if { $an == 5 &&
  806.             [lindex $av 2] == "host" &&
  807.             [lindex $av 4] == "any" } {
  808.             # "permithost/blockhost"
  809.             # "permitimcphost/blockicmphost"
  810.             # deny ip host 10.0.0.1 any
  811.             # 0    1  2    3        4
  812.             set what "[set which][set protostr]host"
  813.             append append [lindex $av 3]
  814.         } elseif { $an == 6 &&
  815.             [lindex $av 2] == "host" &&
  816.             [lindex $av 4] == "host" } {
  817.             # "permithosthost/blockhosthost"
  818.             # "permiticmphosthost/blockicmphosthost"
  819.             # deny ip host 1.2.3.4 host 4.5.6.7
  820.             # 0    1  2    3       4    5
  821.             set what "[set which][set protostr]hosthost"
  822.             append append "[lindex $av 3] [lindex $av 5]"
  823.         } elseif { $an == 5 &&
  824.             [split [lindex $av 3] "."] > 0 &&
  825.             [lindex $av 4] == "any" } {
  826.             set wild [lindex $av 3]
  827.             set wild [wild2width $wild]
  828.             # "permitnet/blocknet"
  829.             # "permiticmpnet/blockicmpnet"
  830.             # permit ip 10.0.0.0 0.0.0.225 any
  831.             # 0      1  2        3         4
  832.             set what "[set which][set protostr]net"
  833.             append append [lindex $av 2]$wild
  834.         } elseif { $an == 5 &&
  835.             [lrange $av 2 3] == "any host" } {
  836.             # "permitdsthost/blockdsthost"
  837.             # "permiticmpdsthost/blockicmpdsthost"
  838.             # permit icmp any host 10.0.0.1
  839.             # 0      1    2   3    4
  840.             set what "$which[set protostr]dsthost"
  841.             append append "[lindex $av 4]"
  842.         } elseif { $an == 5 &&
  843.             [split [lindex $av 4] "."] > 0 &&
  844.             [lindex $av 2] == "any"} {
  845.             set wild [lindex $av 4]
  846.             set wild [wild2width $wild]
  847.             # "permitdstnet/blockdstnet"
  848.             # "permiticmpdstnet/blockicmpdstnet"
  849.             # "show ip accounting" style
  850.             #    (net and mask width one word)
  851.             # permit ip any 10.0.0.0 0.255.255.255
  852.             # 0      1  2   3        4
  853.             set what "[set which][set protostr]dstnet"
  854.             append append [lindex $av 3]$wild
  855.         } elseif { $an == 4 && [lrange $av 2 3] == "any any" } {
  856.             # "permitany/blockany"
  857.             # "permiticmpany/blockicmpany"
  858.             # permit ip any any
  859.             # 0      1  2   3
  860.             set what "[set which][set protostr]any"
  861.         } elseif { $an == 6 &&
  862.             [split [lindex $av 3] "."] > 0 &&
  863.             [lindex $av 4] == "host" } {
  864.             set wild [lindex $av 3]
  865.             set wild [wild2width $wild]
  866.             # "permitnethost/blocknethost"
  867.             # "permiticmpnethost/blockicmpnethost"
  868.             # permit ip 10.0.0.0 0.0.0.255 host 10.1.2.3
  869.             # 0      1  2        3         4    5
  870.             set what "$which[set protostr]nethost"
  871.             append append "[lindex $av 2]$wild [lindex $av 5]"
  872.         }
  873.  
  874.        } elseif { $proto == "udp" || $proto == "tcp" } {
  875.         if { $an == 6 &&
  876.            [lrange $av 2 4] == "any any eq" } {
  877.             # "permitudpport/blockudpport"
  878.             # "permittcpport/blocktcpport"
  879.             # deny udp any any eq 666
  880.             # 0    1   2   3   4  5
  881.             set port [lindex $av 5]
  882.             if {[regexp {[a-z]} $port result]} {
  883.                 set port [name2num $proto $port]
  884.             }
  885.             set what "$which[set proto]port"
  886.             #append append [lindex $av 5]
  887.             append append $port
  888.         } elseif { $an == 7 &&
  889.             [lindex $av 2] == "host" &&
  890.             [lrange $av 4 5] == "any eq" } {
  891.             # "permitudphostport/blockudphostport"
  892.             # "permittcphostport/blocktcphostport"
  893.             # permit udp host 10.0.0.1 any eq 666
  894.             # 0      1   2    3        4   5  6
  895.             set port [lindex $av 6]
  896.             if {[regexp {[a-z]} $port result]} {
  897.                 set port [name2num $proto $port]
  898.             }
  899.             set what "$which[set proto]hostport"
  900.             append append "[lindex $av 3] $port"
  901.         } elseif { $an == 7 &&
  902.             [lrange $av 2 3] == "any host" &&
  903.             [lindex $av 5] == "eq" } {
  904.             # "permitudpdsthostport/blockudpdsthostport"
  905.             # "permittcpdsthostport/blocktcpdsthostport"
  906.             # permit udp any host 10.0.0.1 eq 666
  907.             # 0      1   2   3    4        5  6
  908.             set port [lindex $av 6]
  909.             if {[regexp {[a-z]} $port result]} {
  910.                 set port [name2num $proto $port]
  911.             }
  912.             set what "$which[set proto]dsthostport"
  913.             append append "[lindex $av 3] $port"
  914.         } elseif { $an == 7 &&
  915.             [lindex $av 2] == "host" &&
  916.             [lindex $av 4] == "eq" &&
  917.             [lindex $av 6] == "any" } {
  918.             # "permitudphostsrcport/blockudphostsrcport"
  919.             # "permittcphostsrcport/blocktcphostsrcport"
  920.             # permit udp host 10.0.0.1 eq 666 any
  921.             # 0      1   2    3        4  5   6
  922.             set port [lindex $av 5]
  923.             if {[regexp {[a-z]} $port result]} {
  924.                 set port [name2num $proto $port]
  925.             }
  926.             set what "$which[set proto]hostsrcport"
  927.             append append "[lindex $av 3] $port"
  928.         } elseif { $an == 8 &&
  929.             [lindex $av 2] == "host" &&
  930.             [lindex $av 4] == "host" &&
  931.             [lindex $av 6] == "eq" } {
  932.             # "permitudphostpairdstport/blockudphostpairdstport"
  933.             # "permittcphostpairdstport/blocktcphostpairdstport"
  934.             # permit udp host 10.0.0.1 host 10.0.0.2 eq 666
  935.             # 0      1   2    3        4    5        6  7
  936.             set port [lindex $av 7]
  937.             if {[regexp {[a-z]} $port result]} {
  938.                 set port [name2num $proto $port]
  939.             }
  940.             set what "$which[set proto]hostpairdstport"
  941.             append append "[lindex $av 3] [lindex $av 5] $port"
  942.         } elseif { $an == 5 &&
  943.             [lrange $av 2 3] == "any host" } {
  944.             # "permitudpdsthost/blockudpdsthost"
  945.             # "permittcpdsthost/blocktcpdsthost"
  946.             # permit udp any host 10.0.0.1
  947.             # 0      1   2   3    4
  948.             set what "$which[set proto]dsthost"
  949.             append append "[lindex $av 4]"
  950.         }
  951.     }
  952.  
  953.     set msg "$seq $count $what"
  954.     if { $append != "" } {
  955.         append msg " $append"
  956.     }
  957.     puts $msg
  958.     return
  959. }
  960.  
  961. proc printroute {what src dst} {
  962.  
  963.     # Strip trailing /32 from host routes
  964.     if { [string first "." $src] > 0 } {
  965.         set w "32"
  966.     } else {
  967.         set w "128"
  968.     }
  969.     set i [string first "/$w" $src]
  970.     if { $i > 1 } {
  971.         set src [string range $src 0 [expr $i - 1]]
  972.     }
  973.  
  974.     if { $what == "C" || $what == "L" } {
  975.         # interface
  976.         puts "I $src"
  977.     } elseif { $what == "O" || $what == "B" || $what == "R" } {
  978.         # dynamic
  979.         puts "D $src $dst"
  980.     } elseif { $what == "S" } {
  981.         if { $dst == "Nu 0" || $dst == "Null0" } {
  982.             # null zero
  983.             puts "N $src"
  984.         } else {
  985.             # static
  986.             puts "S $src $dst"
  987.         }
  988.     } else {
  989.         puts "# unknown $what $src $dst"
  990.     }
  991.     return
  992. }
  993.  
  994. proc nullzerocmd {what addr pre} {
  995.     global cprompt
  996.  
  997.     set err [entermode "config" {}]
  998.     if { $err != "" } {
  999.         puts "$what-failed -"
  1000.         puts "$err"
  1001.         puts "."
  1002.         return
  1003.     }
  1004.  
  1005.     if { [string first "." $addr] > 0 } {
  1006.         set ip "ip"
  1007.     } else {
  1008.         set ip "ipv6"
  1009.     }
  1010.  
  1011.     if { [string first "/" $addr] > 0 } {
  1012.         # Network with mask
  1013.         set addr [prefix2mask $addr]
  1014.         if {$addr == 1} {
  1015.             puts "nullzerocmd-failed -"
  1016.             puts "Invalid prefix."
  1017.             puts "."
  1018.             return
  1019.         }
  1020.         set cmd "$ip route $addr null 0"
  1021.     } elseif { $ip == "ip"  }  {
  1022.         # IPv4 host address
  1023.         set cmd "ip route $addr 255.255.255.255 null 0"
  1024.     } else {
  1025.         # IPv6 host address
  1026.         set cmd "ipv6 route $addr/128 null 0"
  1027.     }
  1028.     if { $pre != "" } {
  1029.         set cmd "$pre $cmd"
  1030.     }
  1031.     sendcmd $cmd
  1032.     set timeout 10
  1033.     expect {
  1034.         #generic error catcher for cisco
  1035.         -re "(%\[^\r\n]*)\[\r\n]*\r\n.*#" {
  1036.             puts "$what-failed -"
  1037.             puts "$expect_out(1,string)"
  1038.             puts "."
  1039.             return
  1040.         }
  1041.         -re "Connection to.*closed by remote host\." {
  1042.             puts "$what-failed -"
  1043.             puts "$expect_out(0,string)"
  1044.             puts "."
  1045.             exit
  1046.         }
  1047.         -re "Connection to.*closed\." {
  1048.             puts "$what-failed -"
  1049.             puts "$expect_out(0,string)"
  1050.             puts "."
  1051.             exit
  1052.         }
  1053.         -re $cprompt {
  1054.             # This action must be last
  1055.             # success
  1056.             puts "$what"
  1057.             return
  1058.         }
  1059.         timeout {
  1060.             puts "$what-failed -"
  1061.             puts "nullzerocmd: timeout ($timeout seconds)"
  1062.             puts "."
  1063.             exit
  1064.         }
  1065.         default {
  1066.             puts "$what-failed -"
  1067.             puts "nullzerocmd: unknown problem"
  1068.             puts "."
  1069.             return
  1070.         }
  1071.     }
  1072.     return
  1073. }
  1074.  
  1075. proc sendcmd {cmd} {
  1076.     global spawn_id
  1077.  
  1078.     if [catch {send -- "$cmd\r"} err] {
  1079.         puts "sendcmd: $err"
  1080.         # exit so acld will start a fresh expect session
  1081.         exit
  1082.     }
  1083.     return 1
  1084. }
  1085.  
  1086. # $user not used with the cisco
  1087. proc sendpass {what pass1 pass2} {
  1088.     global spawn_id
  1089.     global cprompt
  1090.  
  1091.     # Send first password
  1092.     sendcmd "$pass1"
  1093.  
  1094.     set timeout 10
  1095.     set which "first"
  1096.     expect {
  1097.         timeout {
  1098.             puts "login-failed -"
  1099.             puts "sendpass: timeout ($timeout seconds)"
  1100.             puts "."
  1101.             return 0
  1102.         }
  1103.         "Received disconnect from " {
  1104.             puts "login-failed -"
  1105.             puts "device timed out while waiting for password"
  1106.             puts "."
  1107.             return 0
  1108.         }
  1109.         "Password:" {
  1110.             if { $which == "first" } {
  1111.                 set which "second"
  1112.                 sendcmd "$pass2"
  1113.                 exp_continue
  1114.             }
  1115.         }
  1116.         -re $cprompt {
  1117.             return 1
  1118.         }
  1119.         default {
  1120.             puts "login-failed -"
  1121.             puts "can't get here"
  1122.             puts "."
  1123.             return 0
  1124.         }
  1125.     }
  1126. }
  1127.  
  1128. # Modes we currently know about:
  1129. #
  1130. #    enable
  1131. #    config
  1132. #    acl
  1133. #
  1134. # This table tells entermode how to get from one mode to another
  1135. #
  1136. set modemoves(enable,enable)    { }
  1137. set modemoves(enable,config)    { "config t" }
  1138. set modemoves(enable,acl)    { "config t" "acl" }
  1139.  
  1140. set modemoves(config,enable)    { "exit" }
  1141. set modemoves(config,config)    { }
  1142. set modemoves(config,acl)    { "acl" }
  1143.  
  1144. set modemoves(acl,enable)    { "exit" "exit" }
  1145. set modemoves(acl,config)    { "exit" }
  1146. set modemoves(acl,acl)        { "acl" }
  1147.  
  1148. proc entermode {mode acl} {
  1149.     global cprompt
  1150.     global currentmode
  1151.     global currentacl
  1152.     global modemoves
  1153.  
  1154.     set timeout 10
  1155.     if [catch {set moves $modemoves($currentmode,$mode)} err] {
  1156.         puts "entermode: $err"
  1157.         # exit so acld will start a fresh expect session
  1158.         exit
  1159.     }
  1160.     set n [llength $moves]
  1161.     if { $n == 0 } {
  1162.         return ""
  1163.     }
  1164.  
  1165.     set ip [acl2ip $acl]
  1166.  
  1167.     set errstr ""
  1168.     for { set i 0 } { $i < $n } { incr i } {
  1169.         set move [lindex $moves $i]
  1170.         if { $move != "acl" } {
  1171.             set cmd "$move"
  1172.         } elseif { $currentmode != "acl" || $currentacl != $acl } {
  1173.             if { $ip == "ip" } {
  1174.                 set cmd "ip access-list extended $acl"
  1175.             } else {
  1176.                 set cmd "ipv6 access-list $acl"
  1177.             }
  1178.         } else {
  1179.             # already there
  1180.             continue
  1181.         }
  1182.  
  1183.         sendcmd "$cmd"
  1184.         expect {
  1185.             #generic error catcher for cisco
  1186.             -re "(%\[^\r\n]*)\[\r\n]*\r\n.*#" {
  1187.             puts "entermode failed -"
  1188.             puts "$expect_out(1,string)"
  1189.             puts "."
  1190.             return
  1191.             }
  1192.             #This error not supported on cisco (but we need an equivalent)
  1193.             -re "(% Error: IPv6 Access-list not supported on this CAM profile\.)\[\r\n]*\r\n" {
  1194.                 set errstr "$expect_out(1,string)"
  1195.                 set currentmode "config"
  1196.                 exp_continue
  1197.             }
  1198.             -re "Connection to.*closed by remote host\." {
  1199.                 puts "entermode failed -"
  1200.                 puts "$expect_out(0,string)"
  1201.                 puts "."
  1202.                 exit
  1203.             }
  1204.             -re "Connection to.*closed\." {
  1205.                 puts "entermode failed -"
  1206.                 puts "$expect_out(0,string)
  1207.                 puts "."
  1208.                 exit
  1209.             }
  1210.             -re $cprompt {
  1211.                 # This action must be last
  1212.                 # done
  1213.             }
  1214.             timeout {
  1215.                 puts "entermode: timeout ($timeout seconds)"
  1216.                 exit
  1217.             }
  1218.         }
  1219.  
  1220.         # Bail at the first sign of trouble
  1221.         if { $errstr != "" } {
  1222.             break
  1223.         }
  1224.  
  1225.         # Keep track of current mode in case we're making more than one
  1226.         if { $move == "config t" } {
  1227.             set currentmode "config"
  1228.         } else {
  1229.             set currentmode $mode
  1230.         }
  1231.         if { $move == "acl" } {
  1232.             set currentacl $acl
  1233.         }
  1234.     }
  1235.     return $errstr
  1236. }
  1237.  
  1238. # Calculate ip address with subnet mask given an ip address with
  1239. # subnet mask prefix (A.B.C.D/xx). Used by proc 'nullzerocmd'
  1240. proc prefix2mask {addr} {
  1241.     set iplist [split $addr "/"]
  1242.     set ipaddr [lindex $iplist 0]
  1243.     set prefix [lindex $iplist 1]
  1244.     set numOctet 0
  1245.     set mask ""
  1246.  
  1247.     if { ($prefix < 0) || ($prefix > 32) } {
  1248.         #puts "invalid prefix ($prefix)."
  1249.         return 1
  1250.     }
  1251.  
  1252.     set fullOct [expr $prefix / 8]
  1253.     set partOct [expr $prefix % 8]
  1254.  
  1255.     while {$fullOct > 0} {
  1256.         append mask 255
  1257.         incr fullOct -1
  1258.         if {$numOctet < 3} {
  1259.             append mask "."
  1260.         }
  1261.         incr numOctet
  1262.     }
  1263.  
  1264.     if {$partOct > 0} {
  1265.         set num 0
  1266.         for {set j $partOct} {$j > 0} {incr j -1} {
  1267.             set bit [expr 8-$j]
  1268.             set num [expr pow(2, $bit) + $num]
  1269.         }
  1270.  
  1271.         #num became float after doing math,
  1272.         #need to cast it back to an int
  1273.         set num [expr int($num)]
  1274.         append mask $num
  1275.         incr numOctet
  1276.         if {$numOctet <= 3} {
  1277.             append mask "."
  1278.         }
  1279.     }
  1280.  
  1281.     while {$numOctet <= 3} {
  1282.         append mask "0"
  1283.         incr numOctet
  1284.         if {$numOctet <= 3} {
  1285.             append mask "."
  1286.         }
  1287.     }
  1288.  
  1289.     set result "$ipaddr $mask"
  1290.     return $result
  1291. }
  1292.  
  1293. # Calculate Cisco wildcard given a prefix (e.g. /24)
  1294. # Used by proc 'drop'
  1295. proc prefix2wild {addr} {
  1296.     set iplist [split $addr "/"]
  1297.     set ipaddr [lindex $iplist 0]
  1298.     set prefix [lindex $iplist 1]
  1299.     set numOctet 0
  1300.     set wild ""
  1301.  
  1302.     if { ($prefix < 1) || ($prefix > 32) } {
  1303.         #puts "invalid prefix ($prefix)."
  1304.         return 1
  1305.     }
  1306.     set emptyOct [expr $prefix / 8]
  1307.     set partOct [expr $prefix % 8]
  1308.     while {$emptyOct > 0} {
  1309.         append wild 0
  1310.         incr emptyOct -1
  1311.         if {$numOctet < 3} {
  1312.             append wild "."
  1313.         }
  1314.         incr numOctet
  1315.     }
  1316.     if {$partOct > 0} {
  1317.         set num 0
  1318.         for {set j $partOct} {$j > 0} {incr j -1} {
  1319.             set bit [expr 8-$j]
  1320.             set num [expr pow(2, $bit) + $num]
  1321.         }
  1322.         set num [expr 255 - $num]
  1323.         #num became float after doing math,
  1324.         #so need to cast it back to an int
  1325.         set num [expr int($num)]
  1326.         append wild $num
  1327.         incr numOctet
  1328.         if {$numOctet <= 3} {
  1329.             append wild "."
  1330.         }
  1331.     }
  1332.     while {$numOctet <= 3} {
  1333.         append wild "255"
  1334.         incr numOctet
  1335.         if {$numOctet <= 3} {
  1336.             append wild "."
  1337.         }
  1338.     }
  1339.     set result "$ipaddr $wild"
  1340.     return $result
  1341. }
  1342.  
  1343. # Calculate mask width (number of subnet mask bits) given a cisco style "wildcard"
  1344. # Used by proc 'printacl'
  1345. proc wild2width {wild} {
  1346.     set av [split $wild "."]
  1347.     set an [llength $av]
  1348.  
  1349.     if { $an != 4 } {
  1350.         error "# wild2width: wrong number of octets ($an != 4)"
  1351.     }
  1352.  
  1353.     set width 0
  1354.     for { set i [expr $an - 1] } { $i >= 0 } { incr i -1} {
  1355.         set octet [lindex $av $i]
  1356.         while {$octet > 0} {
  1357.             incr width
  1358.             set octet [expr $octet / 2]
  1359.         }
  1360.     }
  1361.     set width [expr 32 - $width]
  1362.     return "/$width"
  1363. }
  1364.  
  1365. #The following arrays are used by proc 'name2num' (below)...
  1366. #TCP
  1367. set tcp(bgp)        179
  1368. set tcp(chargen)    19
  1369. set tcp(cmd)        514
  1370. set tcp(daytime)    13
  1371. set tcp(discard)    9
  1372. set tcp(domain)        53
  1373. set tcp(echo)        7
  1374. set tcp(exec)        512
  1375. set tcp(finger)        79
  1376. set tcp(ftp)        21
  1377. set tcp(ftp-data)    20
  1378. set tcp(gopher)        70
  1379. set tcp(hostname)    101
  1380. set tcp(ident)        113
  1381. set tcp(irc)        194
  1382. set tcp(klogin)        543
  1383. set tcp(kshell)        544
  1384. set tcp(login)        513
  1385. set tcp(lpd)        515
  1386. set tcp(nntp)        119
  1387. set tcp(pim-auto-rp)    496
  1388. set tcp(pop2)        109
  1389. set tcp(pop3)        110
  1390. set tcp(smtp)        25
  1391. set tcp(sunrpc)        111
  1392. set tcp(tacacs)        49
  1393. set tcp(talk)        517
  1394. set tcp(telnet)        23
  1395. set tcp(uucp)        540
  1396. set tcp(whois)        43
  1397. set tcp(www)        80
  1398.  
  1399. #UDP
  1400. set udp(biff)        512
  1401. set udp(bootpc)        68
  1402. set udp(bootps)        67
  1403. set udp(discard)    9
  1404. set udp(dnsix)        195
  1405. set udp(domain)        53
  1406. set udp(echo)        7
  1407. set udp(isakmp)        500
  1408. set udp(mobile-ip)    434
  1409. set udp(nameserver)    42
  1410. set udp(netbios-dgm)    138
  1411. set udp(netbios-ns)    137
  1412. set udp(netbios-ss)    139
  1413. set udp(non500-isakmp)    4500
  1414. set udp(ntp)        123
  1415. set udp(pim-auto-rp)    496
  1416. set udp(rip)        520
  1417. set udp(snmp)        161
  1418. set udp(snmptrap)    162
  1419. set udp(sunrpc)        111
  1420. set udp(syslog)        514
  1421. set udp(tacacs)        49
  1422. set udp(talk)        517
  1423. set udp(tftp)        69
  1424. set udp(time)        37
  1425. set udp(who)        513
  1426. set udp(xdmcp)        177
  1427.  
  1428. # Convert user-friendly port name to port number
  1429. # Used by 'printacl'
  1430. proc name2num {proto name} {
  1431.     global tcp
  1432.     global udp
  1433.     set portnum "unknown"
  1434.     if { $proto == "tcp" } {
  1435.         set portnum $tcp($name)
  1436.     } elseif { $proto == "udp" } {
  1437.         set portnum $udp($name)
  1438.     }
  1439.     #puts "leaving proc name2num..."
  1440.     #puts "return value is $portnum"
  1441.     return $portnum
  1442. }
  1443.  
  1444. # These are required to be at the end
  1445. log_user 0
  1446. interpreter
  1447.