免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2046 | 回复: 0
打印 上一主题 下一主题

aclmaker 脚本 [复制链接]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-10-03 20:57 |只看该作者 |倒序浏览
#!/usr/local/bin/perl5.00502 -w
# $Id: aclmaker,v 1.27 2003/06/17 22:59:21 elr Exp elr $
# SF RELEASE VERSION: 1.03
# manipulate Cisco access lists over an existing tty
# meant to be run as a subshell under telnet/kermit or
# any other connectivity program that leaves /dev/fd3 open
# to the session.
####### BUGS not fixed yet
#######  list of non-existent access-list does not return an error
#######  numeric standard ACL, empty last line, cannot save on router
#######  empty access lists mishandled - can't be deleted or installed
#######
####### FEATURES wanted
#######  --help option should call perldoc
use strict;
use Expect;
use IO::File;
use Getopt::Std 'getopts';
use File::Temp qw/ :mktemp  /;
use vars qw($opt_V $opt_O $opt_F $opt_E $opt_D $opt_v $opt_q $opt_f $opt_d $opt_b);
my $options = "b:d:f:qv" . "DE:F:O:V:";
my $usage=
"Usage: aclmaker [-v] [-d dir] [-f file] {command} access-list-name
Manipulate Cisco access control lists on a session previously opened
on file descriptor 3.  Invoke via subshell from "telnet", "kermit" or other
Telnet client that allows subshell to inherit telnet session on fd3.
Options:
   -f file       # use "file" instead of same name as ACL
   -d dir        # use "dir" to store local copy instead of current dir
   -v            # verbose mode - show progress of all router operations
Advanced options:
    -b len      # specify maximum buffer length [256] in kilobytes
    -q          # quiet mode, only show errors
    -D          # turn on script debugging
    -E timeout  # set Expect timeout [15]
    -F fdnum    # use a different file descriptor (or device path)
    -O fdnum    # output file descriptor (or path), if needed
    -V {1|2|3}  # turn on verbose Expect debugging
Commands:
    list [aclname]  # list out acl, or list names of all acls on router
    get   aclname   # copy acl from router to local file
    diff  aclname   # compare acl on router against local file
    test  aclname   # send acl to router (with dummy name) and check for errors
    put   aclname   # tests acl, saves it to router if it has no errors
    del   aclname   # deletes acl from router
    list config     # print out router's running configuration
    get  config     # copy router's running configuration to local file
    cmd  IOS-CMD    # send arbitrary command to router and display results
For the full man page, try 'perldoc $0' .
";
   
  
getopts( $options );
# arguments
my $debug= $opt_D || 0;
my $expectdebug= $opt_V || 0;
my $ExpectTimeout= $opt_E || 15;
my $maxbuf= ($opt_b || 256 ) * 1024;
my $verbose= $opt_v || 0;
my $quiet= $opt_q || 0;
my $fdnum=  $opt_F || "3";
my $outputfd=  $opt_O || "";
my $acldir= $opt_d || ".";
my ($myname)= ($0 =~ m!([^/]+)$! );
die "$myname: missing commandn" . $usage unless defined($ARGV[0]);
my $command= $ARGV[0];
# Environment stuff
my $TMPDIR=  $ENV{'TMPDIR'} || "/tmp";
my $DIFF="diff";
my $DIFFOPTS="";
if ($command eq "diff" and @ARGV > 1 and $ARGV[1] =~ /^-/)
{
    $DIFFOPTS="";
    while ($ARGV[1] =~ /^-/) # diff options?
    {
        $DIFFOPTS= $DIFFOPTS . $ARGV[1];
        shift @ARGV;
    }
}
die "$myname: missing aclnamen" . $usage unless defined($ARGV[1]) or $command eq "list";
my $aclname= $ARGV[1] || "";
my $aclpath= $acldir . "/" . ($opt_f || $aclname);
# globals for various parameters discovered from the router
my ($routername, $running_config);
my $term_lines= 0;
my $term_width= 0;
my @config; # array version of $running_config
my %acldirectory;
# router-specific stuff - this might change with different IOS versions
my $router_interface_prompt_str= '(config-[a-z()]*if)#';
my $router_config_prompt_str= '(co(nfig)?)#';
my $router_acl_prompt_str= '(config-(ext|std)-na(cl)?)#';
my $router_length_match= '^Length: (d+) lines, Width: (d+) columns';
# max length of cisco prompt seems to be 30 chars, less 17 for length of
# "(config-ext-nacl)", less one for good luck
my $max_routername_match= 12;
my @aclranges=
( 1,99,    #         IP standard access list
  100,199, #         IP extended access list
  200,299, #         Protocol type-code access list
  300,399, #         DECnet access list
  400,499, #         XNS standard access list
  500,599, #         XNS extended access list
  600,699, #         Appletalk access list
  700,799, #         48-bit MAC address access list
  800,899, #         IPX standard access list
  900,999, #         IPX extended access list
  1000,1099, #       IPX SAP access list
  1100,1199, #       Extended 48-bit MAC address access list
  1200,1299, #       IPX summary address access list
  1300,1999, #       IP standard access list (expanded range)
  2000,2699, #       IP extended access list (expanded range)
);
my ($router_prompt, $router_interface_prompt,
    $router_config_prompt, $router_acl_prompt);
my $session;
my $sessionout;  # if using separate pipes for input/output to session
my ($fdinput, $fdoutput);
sub close_router #
# don't use docommand here to avoid recursive errors
{
    print $sessionout chr(26); # just in case, leave config mode
    print $sessionout "terminal length $term_lines ! restore old settingr";
    print $sessionout "terminal width  $term_width ! restore old settingr";
    warn "$myname: sent closing commands { ^Z / terminal length $term_lines / terminal width $term_width }n"
            if $debug;
    $session->clear_accum();
    $session->close;
    exit;
}
sub fatal
{
    warn "$myname: $_[0]n";
    close_router();
    exit 23;
}
sub docommand # send-str, expect-str or expect-str array
              # if no expect-strs supplied, default to router prompt
              # all expect-strs are forced to be regular expressions
{
    my $sendme= $_[0];
    my @expectme= @_;
    shift @expectme;
    $expectme[0]= $router_prompt if @expectme == 0;
    my @expectargs= @expectme;
    if (length($sendme))
    {
        warn "$myname: sending { $sendme } to router...n" if $debug;
        $session->clear_accum();
        print $sessionout "$sendmer";
    } else
    { warn "$myname: null send string, skipping send...n" if $debug;}
    map {$_= ['-re', $_] } @expectargs;
   
    my ($matchindex, $error, $successmatch, $beforematch, $aftermatch)=
        $session->expect($ExpectTimeout, @expectargs);
    fatal("failed to get match { " . join(" | ", @expectme) .
        " } on command:nt$sendme")
            if ! defined($matchindex);
    warn "$myname: matched pattern#$matchindex: $expectme[$matchindex - 1]n"
        if $debug;
    return $matchindex;
}
sub get_prompt # figure out what router prompt is
{
    $session->clear_accum();
    print $sessionout "r";
    $session->expect($ExpectTimeout, ['-re', '^S+#']) ||
#    $session->expect($ExpectTimeout, ['-re', '^[^ #]+#$']) ||
        warn "$myname: error synchronizing with router promptn";
    warn "$myname: sent CR, received { " .
        $session->exp_before . $session->exp_match . " }n"
            if $debug;
    $session->clear_accum();
    print $sessionout "r";
    $session->expect($ExpectTimeout, ['-re', '^S+#']) ||
        fatal("cannot find enabled router prompt: got:nt" .
            $session->exp_before() . "n");
    warn "$myname: sent CR, received { " .
        $session->exp_before . $session->exp_match . " }n"
            if $debug;
    return $session->exp_match();
}
sub open_router  ### set up the Expect stuff and initialize the router
{
    if ($expectdebug) {
        $Expect::Debug= $expectdebug;
        $Expect::Exp_Internal=1;
    }
    $fdinput = new IO::File;
    # open fd3 by default ($fdnum=="3"), or use whatever user supplies
    my $fdpath= "+open($fdpath)) {
        die("$myname: must be run from telnet subshell: cannot open file $fdnum: $!n");
    }
    $session= Expect->exp_init($fdinput);
    if ($outputfd eq "")
    {
        $sessionout= $session; # just one fd
    } else {
        $fdoutput= new IO::File;
        $fdpath= "+open($fdpath)) {
            die("$myname: cannot open file $fdnum for output: $!n");
        }
        $fdoutput->autoflush(1);
        $sessionout= $fdoutput;
    }
    # discover the router prompt
    my $currentprompt= get_prompt();
    print "$myname: found Cisco prompt: $currentpromptn" if $debug;
    ($routername)= $currentprompt =~ /^([^(#]+)/;
    my $shortname= substr($routername, 0, $max_routername_match). '[^#]*';
    $router_prompt= '^' . $shortname . '((S+))?#';
    $router_interface_prompt= "^" . $shortname . $router_interface_prompt_str;
    $router_config_prompt= "^" . $shortname . $router_config_prompt_str;
    $router_acl_prompt=    "^" . $shortname . $router_acl_prompt_str;
    if ($currentprompt =~ /((config|cfg)/)
    {
        warn "$myname: router '$routername' seems to be in config mode, will fix...n";
        docommand("end");
    }
    # assume normal terminal settings
    $term_lines= 24;
    $term_width= 80;
    # try to auto-detect existing terminal settings
    my $rc= docommand("show term | inc Len", $router_length_match, "^% ");
    if ($rc == 1) { # router supports "| inc"
        my (@matches)= $session->exp_match() =~ /$router_length_match/o;
        if (@matches == 2)
        {
            $term_lines= $matches[0];
            $term_width= $matches[1];
        }
        else {
            warn "$myname: router '$routername': parse error getting terminal parameters";
        }
    }
    docommand(""); # resynch with prompt
    docommand("terminal length 0 ! $myname");
    docommand("terminal width  0 ! $myname");
    # router configs can be big, up the maximum buffer size:
    $session->match_max($maxbuf);
}
sub load_config # fetches current config
{
    docommand("show running-config ! downloading...");
    $running_config= $session->exp_before();
    # remove serial port cruft:  extra CR and NULLs
    my $serialcruft="1500";  # quoted to avoid binary chars in script
    $running_config =~ s/$serialcruft//g;
    @config= split('rn', $running_config);
    # trim junk in top of buffer
    while (@config and ($config[0] !~ /^!$/)) { shift @config; }
}
sub get_acl # acl-name   ### returns full acl out of $running_config
{
    my ($acl)= @_;
    my ($stuff, $match, @results);
   
    if ($acl =~ /^d+$/)  # support numbered lists too!
    {
        $match= 'rn((access-list ' . $acl . 's+[^rn]+rn)+)';
    } else {
        $match= 'rn(ip access-list (extended|standard) '
            . $acl . '(rns[^rn]*)+rn)';
    }
    @results= ($running_config =~ /$match/s); # treat as single string
    if (@results)
    { $stuff= $results[0]; $stuff=~ s/r//g; return $stuff;}
    else
    { return ""; } # no match
}
sub abort_acl # name, offending-line
{
    my ($name, $line)= @_;
    if ($name =~ /^d+$/)
    {
        docommand("no access-list $name");
    }
    else
    {
        docommand("no ip access-list extended $name");
        docommand("no ip access-list standard $name");
    }
    fatal("invalid input detected.  Offending line was:nt$line");
}
sub delete_acl # aclname, [acltype]
{
    my $name= $_[0];
    my $acltype= $_[1] || "";
    my $acl= get_acl($name);
    my @aclines= split('n', $acl);  # get_acl already trimmed CRs
    if ( $acltype eq "" and length($acl) == 0)
    {
        warn("$myname: $routername: no ACL named '$name' found to deleten")
            if $verbose;
        return 0;
    }
    # determine ACL type
    elsif ( $acltype eq "numbered"  or $name =~ /^d+/ )
    {
        docommand("no access-list $name");
        warn "$myname: $routername: numbered ACL '$name' deletedn"
            if $verbose;
        return 1;
    }
    elsif ( ( $acltype =~ /^(extended|standard)$/ )or
        $aclines[0] =~ /^ip access-list (extended|standard) $names*$/)
    {
        docommand("no ip access-list $1 $name");
        warn "$myname: $routername: $1 ACL '$name' deletedn"
            if $verbose;
        return 1;
    }
    else
    {
        fatal("unparsable access list found: $acl($acltype)");
    }
}
sub disable_interface_acls # array of [interface, access-group line]
{
    my ($aclname, $testname, @interfaces) = @_;
    my $applytest;
    foreach my $item (@interfaces)
    {
        $applytest= $$item[1];
        $applytest=~ s/access-groups+$aclnames+/access-group $testname /;
        docommand("interface $$item[0]", $router_interface_prompt);
        docommand("no $$item[1]", $router_interface_prompt);
        warn "$myname: $routername: $$item[0]: NO $$item[1]n" if $verbose;
        if (length($testname) > 0)
        {
            docommand($applytest, $router_interface_prompt);
            warn "$myname: $routername: $$item[0]: $applytestn" if $verbose;
        }
    }
}
sub enable_interface_acls # array of [interface, access-group line]
{
    my ($aclname, $testname, @interfaces) = @_;
    my $removetest;
    foreach my $item (@interfaces)
    {
        $removetest= $$item[1];
        $removetest=~ s/access-groups+$aclnames+/access-group $testname /;
        docommand("interface $$item[0]", $router_interface_prompt);
        if (length($testname) > 0)
        {
            docommand("no $removetest");
            warn "$myname: $routername: $$item[0]: NO $removetestn" if $verbose;
        }
        docommand("$$item[1]", $router_interface_prompt);
        warn "$myname: $routername: $$item[0]: $$item[1]n" if $verbose;
    }
}
sub put_acl  # delete the named ACL and install a new one
{
    my ($name, $testname, @aclines)= @_;
    my @interfaces;
    my ($match, $rc, $accessgroup, $interface);
    $match= 'rninterfaces([^rn]+)(rns[^rn]*)+rn ip access-groups+'
        . $name . 's+(S+)rn';
    while ($rc= $running_config =~ /$match/gs) # treat as single string
    {
        my $thing= $&;
        $interface=   $1;
        ($accessgroup)= $thing =~ /s([^rn]+)rn$/s;
        chomp $accessgroup;
        push @interfaces, [$interface, $accessgroup];
        warn "$myname: $name: Interface $interface / $accessgroup / $thingn"
            if $debug;
    }
    disable_interface_acls($name, $testname, @interfaces);
    delete_acl($name);
    foreach my $line (@aclines)
    {
        my $rc;
        chomp $line;
        next unless $line =~ /S/;  # skip any blank lines
        $rc= docommand($line,
            'rn% Invalid ',
            'rn% ',
        $name =~ /^d+$/ ? $router_config_prompt : $router_acl_prompt);
        if ($rc  0 and $aclhi > 0;
    # now that we know the range, find an empty number
    for ($i= $aclhi; $i >= $acllo; $i-- )
    {
        return $i if !exists($acldirectory{$i}) and $i != $aclnum;
    }
    fatal("no free ACLs in the range [$acllo..$aclhi] for testing $aclnum");
}
sub test_acl # aclname, acl-array ### see if acl syntax is OK
{
    my ($name, @aclines)= @_;
    my $testname;
    my $testtype;
    if ($name =~ /^d+/)
    {
        fatal("ACL number in file $aclpath does not match '$name'")
            if (grep  $_ !~ /^s*access-lists+$nameb/, @aclines);
        $testtype= "numbered";
        $testname= get_test_num($name);
        map {$_ =~ s/^s*access-lists+$nameb/access-list $testname/;}
            @aclines;
    } else {
        fatal("ACL declaration line in file $aclpath does not match '$name'")
        unless $aclines[0] =~ /^s*ips+access-lists+(extended|standard)s+$nameb/;
        $testtype= $1;
        $testname= "test-$name";
        shift @aclines; # first line is OK, replace it with testname
        unshift @aclines, ("ip access-list $testtype $testname");
    }
    put_acl($testname, "", @aclines);
    warn "$myname: $routername: Test of ACL '$name' with name '$testname' passesn" if $verbose;
    return ($testname, $testtype);
}
sub copy_acl_to_file # aclname, filename
{
    my ($aclname, $aclpath)= @_;
    my $acl=  get_acl($aclname);
    fatal("ACL $aclname does not exist on $routername")
        unless length($acl) > 0;
    open ACL, ">$aclpath" or fatal("Cannot open output file $aclpath: $!");
    print ACL $acl;
    close ACL;
    warn "$myname: $routername: Retrieved ACL '$aclname' and saved in $aclpathn" unless $quiet;
}
sub save_config_to_file # filename
{
    my $configfile;
    if (defined $_[0]) {
        $configfile= $_[0];
        $configfile =~ s/[+&|]//g;
        open CONFIG, ">$configfile" or
            fatal("Cannot write to $configfile: $!");
    }
    else {
        $configfile= "STDOUT";
        open CONFIG, ">&=1"; # use stdout
    }
    print CONFIG join("n", @config) . "n";
    close CONFIG;
    warn "$myname: $routername: wrote running config to $configfilen"
        unless $quiet;
}
#################### MAIN main MAIN main ##################
open_router();
load_config()  unless $command eq "cmd";
load_acl_dir() unless $command eq "cmd";
if ($command eq "get")
{
    if ($aclname eq "config" or $aclname eq "${routername}.config")
    {
        save_config_to_file("$acldir/$routername.config");
        close_router;
    }
    copy_acl_to_file($aclname, $aclpath);
}
elsif ($command eq "diff")
{
    my ($fh, $filename) = mkstemp( "$TMPDIR/$routername.$aclname.acl.XXXXXX" );
    fatal("Cannot create temporary filename in $TMPDIR: $!") unless
        -w $filename;
    copy_acl_to_file($aclname, $filename);
    my $diffcmd= "$DIFF $DIFFOPTS  $filename  $aclname";
    print "==== $diffcmdn";
    system($diffcmd);
    unlink($filename);
}
elsif ($command eq "put" or $command eq "test")
{
    open ACL, ";
    docommand("configure terminal", $router_config_prompt);
    my ($testname, $acltype)= test_acl($aclname, @acl);
    warn "$myname: $routername: Test of ACL '$aclname' (file $aclpath) successfuln" unless $quiet or $command ne "test";
    put_acl($aclname, $testname, @acl) if $command eq "put";
    delete_acl($testname, $acltype);
    warn "$myname: $routername: Updated ACL '$aclname' with contents of $aclpathn" unless $quiet or $command ne "put";
}
elsif ($command eq "del")
{
    docommand("configure terminal", $router_config_prompt);
    my $rc= delete_acl($aclname);
    warn "$myname: $routername: No ACL '$aclname' found to deleten"
        if $rc == 0 and !$quiet;
    warn "$myname: $routername: ACL '$aclname' deletedn"
        if $rc == 1 and !$quiet;
}
elsif ($command eq "list")
{
    if ($aclname eq "config") {
        save_config_to_file();  # actually stdout
        close_router;
    }
    if (length($aclname) == 0) # list all
    {
        print join("n", sort keys %acldirectory), "n";
        warn "$myname: $routername: Listing of all ACLs completen" unless $quiet;
    }
    else
    {
        print get_acl($aclname);
        warn "$myname: $routername: Listing of ACL '$aclname' completen" unless $quiet;
    }
}
elsif ($command eq "cmd")
{
    while ( shift @ARGV ne "cmd") {};
    my $command= join(' ', @ARGV);
    docommand("$command");
    my $results= $session->exp_before();
    $results=~ s/r//g;
    print $results, "n";
    warn "$myname: $routername: execution of command '$command' complete.n"
        unless $quiet;
}
else
{
    fatal("unknown command: $command");
}
close_router();
__END__
=head1 NAME
aclmaker - manipulate Cisco IOS extended named access control lists (ACLs)
=head1 SYNOPSIS
B  [I] [I] [I]  {I} I
=head1 DESCRIPTION
B is a tool to retrieve, save, list, or delete access
control lists on a Cisco IOS router.  You must first use I,
I, or other appropriate terminal emulator program to connect
to the Cisco router and log in as the enabled user.  You may then
spawn a subshell and invoke B.
B works by using file descriptor 3, which is left open by the
parent terminal emulator program and allowed to be inherited by subprocesses,
no doubt for this very purpose.
B lets you copy an ACL from the router and save it on
your local filesystem, or send a file from your local filesystem
to the router to be saved as an ACL.  It also lets you list out
a directory of ACLs on the router, delete ACLs from the router,
and run arbitrary IOS commands (and pipe them to other Unix
commands, if you like).
Normally, all operations that require a local file assume that
the file is in the current directory, using the same name as
the access list supplied on the command line to B.
This can be overridden with the I and I options (see below).
To prevent common mistakes, B will first test the ACL
under a different name to make sure it does not cause a syntax error
when loaded on the router.  Once this test passes, B will check
to see if the ACL is used as an input or output filter on any interfaces.
If it is, then B will issue commands to prevent communications
from being interrupted by a partially loaded access list.  (See the
B section below for the exact details.)
=head1 OPTIONS
=item B I  specify the maximum buffer length, in kilobytes [256k
by default].  Since B reads in the router's entire configuration,
you would need to increase this parameter if the router's configuration
exceeds the default size.  You may also need to increase the Expect
timeout (see the B option below), especially if you are communicating
over a slow line.
=item B I  use I as the directory for the local file instead
of the current working directory.
=item B I  use I as the name of the local file instead of
the I specified on the command line.
=item B  quiet mode - suppress all status messages except for errors
=item B  verbose mode - show status of each router operation.
=head2 Advanced Options
=item B  turn on script debugging [off by default].  Commands
sent to the router, and the matching responses, will be shown on stderr.
=item B I  set Expect timeout in seconds [15 by default].
=item B I  specify the file to use to reach the router's
session [file descriptor 3 by default].  If I is not a
decimal integer, it will be interpreted as a file path.
=item B I  specify the file to use for output to the
router's session, if input and output are split across separate
file descriptors.
=item B I  set Expect debugging to I.  Zero (the default) disables
debugging, values from 1 to 3 show increasing levels of debugging.  Setting
this value to 3 will show the entire Expect buffer, which will create very
large debug output.
=head1 COMMANDS
=item B [I]   list the contents of I on standard
output, or, if no I is supplied, list out all named ACLS
on the router.
=item B 'config'   list out the router's running configuration
=item B I   copy ACL from router to a local file.
=item B 'config'   copy router's running config to a local file
(named 'I.config').
=item B I.config   Same as 'get config'.
=item B I I   run the "diff" command
to compare the ACL on the router against a local file with the
corresponding name.  The ACL is first downloaded from the router to
a temporary file in /tmp (or the directory named in the TMPDIR
environment variable).
=item B I   send ACL to the router with the name
'test-I' and see if it causes a syntax error.  The dummy ACL
is then deleted.
=item B I  tests the ACL as described in the B command
above, then saves the ACL to the router as I if the ACL did not
cause any syntax errors.
=item B I  delete the ACL I from the router.
=item B I  send arbitrary command to router and display
the results on standard output.
=head1 EXAMPLES
 Router# ^]
 telnet> !
 $ aclmaker list
From the telnet session to the router, use the telnet escape
character and then invoke a subshell with the "!" command.
You are now ready to use B.
=item B
Retrieves the ACL 'wan-in' and saves it
as the file 'wan-in' in the current directory.
=item B
Takes the file /conf/routers/sanjose/wan-out and saves
it as an ACL named 'wan-out' on the router.
=item B
On a system that supports /proc, this tells B to use
process PROCNUM's file descriptor 5 for input from the router's
session, and to send commands to the router on the process's
file descriptor 7.  This is meant for use with encrypted communications
program (such as SSH or Kerberized telnet) to communicate with the
router.  The communications program needs to be started under
special circumstances (such as in ksh's two-way pipe mode) for
this to work.  This method of using B through an SSH
session is deprecated in favor of using I, version 8.0
or later, as described below.
=head1 USING SSH, CU, AND OTHER PROGRAMS
Since B expects a cleartext connection to a
Cisco router, it cannot work directly with sessions started
via B.  However, it is possible to use B anyway
by first using I, version 8.0 or higher, to invoke B.
 $ kermit
 C-Kermit 8.0.201, 8 Feb 2002, for NetBSD 1.5
   Copyright (C) 1985, 2002,
   Trustees of Columbia University in the City of New York.
 Type ? or HELP for help.
 C-Kermit>ssh username@myrouter.example.com
 Connecting via command "ssh -e none username@myrouter.example.com"
And subsequently issuing the C-Kermit local shell escape sequence (the
default value is Control- !), you can invoke B in the usual
fashion.  This works because C-Kermit leaves file descriptor 3 open to
the pseudo-tty that is in use by the B session.
If you do not have I available, or if you wish to use B,
B, or another remote access program that is not compatible
with B, another workaround is to first do "telnet localhost"
and log in again to your local machine.  From the new session, run B,
B, or the like to reach your router, then do a local escape back to
the shell that you invoked "telnet localhost" in.  You will now be
able to run B.
=head1 TESTING ACLS
B always tests a new ACL before saving it to the router.
The testing process works as follows:
First, B checks whether the name (or number) of the ACL
in the file supplied matches the ACL name specified on the command
line.  B will fail immediately if these names do not match.
B then tries to install the ACL into the router under
another name (or number).  For named ACLs, B prepends
"test-" to the existing name.  For numbered ACLs, B
looks for an unused number in the same range as the existing
number.  If the renamed (or renumbered) ACL fails to load,
the process is aborted (and the test ACL is deleted).
Once the test ACL has loaded sucessfully, B looks for
any interfaces that use the target ACL as an "ip access group".
B then issues commands to disable those access groups
and re-enable them with the test ACL.  The target ACL is then
loaded, and the interfaces are then switched back to use the
target ACL for their "ip access group".  This prevents
accidental lockout while partially loading an ACL that is active
on an interface, and also minimizes the time that the interface goes
unprotected with no ACL applied to it.
=head1 NOTES
B manipulates the "terminal length" of the router to
prevent the router from pausing during output displays.  If B
is aborted during its run, it may leave the router in a state where
output pausing is disabled.
When you return to your router session (by exiting the subshell)
after running B, you may see the output of B's
attempts to restore the router environment (such as a "terminal length"
command).  This is normal.
=head1 AUTHOR
B was written by Ed Ravin , and is made
available to the public by courtesy of PANIX (http://www.panix.com).
This script is licensed under the GPL.  B requires the Expect,
IO-Tty, and File-Temp Perl modules.
脚本不是我写的.但是希望能够对大家有用.

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12/showart_160.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP