|
#!/usr/local/bin/perl # # Generates anti-spoofing ACL's for Cisco routers # based on SNMP interface & routing information # # (c) Jens Hektor, August 2000 # hektor@rz.rwth-aachen.de # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. use Socket ; use strict; my ( $router, $snmpfile, $routefile, @snmpwalk, @in, $nexthop_default, $interface_default, $ohoh_flag, $ip1, $ip2, $ip3, $ip4, $default_net, $int_def_name, $null_if, $list_direct_networks, $int_net_msk_list, $net_msk_list, @list, $n, $interface, $int_name, $netmask, $int_list, $j, $i, $found, @list2, $k, $list_indirect_networks, $next_hop, $d, $d1, $m, @nexthop_list, @route_interface_list, @route_mask_list, @interface_descr_list, @interface_index_list, $redo, $s, $yn, @args, $acl, $i_name, $inc_file, $command, $l, $output, $acl_file, $acl_file1, $acl_file2, $acl_file3, $acl_file4, $acl_file5, @acl_file_list, $bits, $router_file, $router_note, @blocked_port_list, @blocked_net_list ) ; # # Here we keep the list of denied ports, in this case: # # Netbus 1.5, BackOrifice # @blocked_port_list = ( "udp", "12345", "tcp", "12345", "udp", "31337", "tcp", "31337", ) ; # # here we keep blocked network adresses # @blocked_net_list = ( "1.1.0.0", "2.2.0.0" ) ; # this function handles blocked ports & networks # uses @blocked_port_list, @blocked_net_list, see above # sub blocked { no strict "refs" ; my ( $OUTFILE, $aclnumber ) = @_ ; my ( @ports ) = @blocked_port_list ; my ( @nets ) = @blocked_net_list ; my ( $t1, $t2 ) ; print $OUTFILE "!\n" ; print $OUTFILE "! denied ports\n" ; print $OUTFILE "!\n" ; while ( 0 <= $#ports ) { $t1 = shift ( @ports ) ; $t2 = shift ( @ports ); print $OUTFILE "access-list $aclnumber deny $t1 any any eq $t2\n" ; } print $OUTFILE "!\n" ; print $OUTFILE "! denied network adresses\n" ; print $OUTFILE "!\n" ; while ( 0 <= $#nets ) { $t1 = shift ( @nets ) ; print $OUTFILE "access-list $aclnumber deny ip any host $t1\n" ; } } # # This function matches host/mask with net/mask # sub is_in_net { my ( $host, $network, $mask ) = @_ ; my ( $h, $n, $m ) ; $h = inet_aton ( $host ) ; $n = inet_aton ( $network ) ; $m = inet_aton ( $mask ) ; if ( inet_ntoa ( $h & $m ) ne inet_ntoa ( $n & $m ) ) { return 0 ; } return 1 ; } # # inverts netmask as needed for cisco acl's # sub inv_mask { my ( $mi ) = @_ ; my ( $mo, $t ) ; $t = inet_aton ( $mi ) ; $mo = inet_ntoa ( ~$t ) ; return $mo ; } # # # function for generating access list on the local interfaces # sub local_acl { my ( $include_file, $aclnumber, $network, @included_acl, $out_acl, $out_file, $out_hd, $t1, $t2 ) ; my ( @myargs ) = @_ ; $out_file = shift ( @_) ; open OUTFILE, ">$out_file" or die "Can't open $out_file\n" ; print OUTFILE "!\n" ; print OUTFILE "! ===========================\n" ; print OUTFILE "! This ACL was generated with\n" ; print OUTFILE "! $0\n" ; print OUTFILE "! ===========================\n" ; print OUTFILE "! on\n" ; $t1 = localtime ; print OUTFILE "! $t1\n" ; print OUTFILE "! by\n" ; $t1 = getlogin ; print OUTFILE "! $t1\n" ; print OUTFILE "! with the arguments\n" ; while ( 0 <= $#myargs ) { $t1 = shift ( @myargs ) ; $t2 = shift ( @myargs ) ; print OUTFILE "! $t1\t$t2\n" ; } print OUTFILE "!\n" ; $include_file = shift ( @_) ; $interface = shift ( @_ ) ; $aclnumber = shift ( @_ ) ; print OUTFILE "! delete old list\n" ; print OUTFILE "!\n" ; print OUTFILE "interface $interface\n" ; print OUTFILE "no ip access-group in\n" ; print OUTFILE "no access-list $aclnumber\n" ; print OUTFILE "!\n" ; print OUTFILE "! established tcp connections may pass fast\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber permit tcp any any established\n" ; blocked ( 'OUTFILE', $aclnumber ) ; print OUTFILE "!\n" ; print OUTFILE "! no communication with private networks\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber deny ip any 127.0.0.0 0.255.255.255\n" ; print OUTFILE "access-list $aclnumber deny ip any 10.0.0.0 0.255.255.255\n" ; print OUTFILE "access-list $aclnumber deny ip any 172.16.0.0 0.15.255.255\n" ; print OUTFILE "access-list $aclnumber deny ip any 192.168.0.0 0.0.255.255\n" ; print OUTFILE "!\n" ; print OUTFILE "! no broadcasting\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber deny ip any 0.255.255.255 255.0.0.0\n" ; print OUTFILE "access-list $aclnumber deny ip any 0.0.255.255 255.255.0.0\n" ; print OUTFILE "access-list $aclnumber deny ip any 0.0.0.255 255.255.255.0\n" ; print OUTFILE "!\n" ; print OUTFILE "! special includes follow here\n" ; print OUTFILE "!\n" ; if ( -f $include_file ) { open INCLUDEFILE, "$include_file" or die "Can't open $include_file\n" ; @included_acl =<INCLUDEFILE> ; close INCLUDEFILE ; $out_acl = "@included_acl" ; $out_acl =~ s/ACLNUMBER/$aclnumber/g ; print OUTFILE $out_acl ; } print OUTFILE "!\n" ; print OUTFILE "! Antispoofing\n" ; print OUTFILE "!\n" ; while ( 0 <= $#_ ) { $network = shift ( @_ ) ; $netmask = shift ( @_ ); print OUTFILE "access-list $aclnumber permit ip $network $netmask any\n" ; print OUTFILE "access-list $aclnumber permit igmp $network $netmask any\n" ; } print OUTFILE "!\n" ; print OUTFILE "! special rule for multicast\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber permit ip 224.0.0.0 15.255.255.255 any\n" ; print OUTFILE "!\n" ; print OUTFILE "! final default rule\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber deny ip any any log\n" ; print OUTFILE "!\n" ; print OUTFILE "! activate new list\n" ; print OUTFILE "!\n" ; print OUTFILE "interface $interface\n" ; print OUTFILE "ip access-group $aclnumber in\n" ; close OUTFILE ; } # # function for generating access list on the default interfaces # sub default_acl { my ( $include_file, $aclnumber, $network, @included_acl, $out_acl, $out_file, $t1, $t2 ) ; my ( @myargs ) = @_ ; $out_file = shift ( @_) ; open OUTFILE, ">$out_file" or die "Can't open $out_file\n" ; print OUTFILE "!\n" ; print OUTFILE "! ===========================\n" ; print OUTFILE "! This ACL was generated with\n" ; print OUTFILE "! $0\n" ; print OUTFILE "! ===========================\n" ; print OUTFILE "! on\n" ; $t1 = localtime ; print OUTFILE "! $t1\n" ; print OUTFILE "! by\n" ; $t1 = getlogin ; print OUTFILE "! $t1\n" ; print OUTFILE "! with the arguments\n" ; while ( 0 <= $#myargs ) { $t1 = shift ( @myargs ) ; $t2 = shift ( @myargs ) ; print OUTFILE "! $t1\t$t2\n" ; } print OUTFILE "!\n" ; $include_file = shift ( @_) ; $interface = shift ( @_ ) ; $aclnumber = shift ( @_ ) ; print OUTFILE "! delete old list\n" ; print OUTFILE "!\n" ; print OUTFILE "interface $interface\n" ; print OUTFILE "no ip access-group in\n" ; print OUTFILE "no access-list $aclnumber\n" ; print OUTFILE "!\n" ; print OUTFILE "! established tcp connections may pass fast\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber permit tcp any any established\n" ; blocked ( 'OUTFILE', $aclnumber ) ; print OUTFILE "!\n" ; print OUTFILE "! no communication from private networks\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber deny ip 127.0.0.0 0.255.255.255 any\n" ; print OUTFILE "access-list $aclnumber deny ip 10.0.0.0 0.255.255.255 any\n" ; print OUTFILE "access-list $aclnumber deny ip 172.16.0.0 0.15.255.255 any\n" ; print OUTFILE "access-list $aclnumber deny ip 192.168.0.0 0.0.255.255 any\n" ; print OUTFILE "!\n" ; print OUTFILE "! no broadcasting\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber deny ip any 0.255.255.255 255.0.0.0\n" ; print OUTFILE "access-list $aclnumber deny ip any 0.0.255.255 255.255.0.0\n" ; print OUTFILE "access-list $aclnumber deny ip any 0.0.0.255 255.255.255.0\n" ; print OUTFILE "!\n" ; print OUTFILE "! Antispoofing\n" ; print OUTFILE "!\n" ; while ( 0 <= $#_ ) { $network = shift ( @_ ) ; $netmask = shift ( @_ ); print OUTFILE "access-list $aclnumber deny ip $network $netmask any\n" ; } print OUTFILE "!\n" ; print OUTFILE "! special includes follow here\n" ; print OUTFILE "!\n" ; if ( -f $include_file ) { open INCLUDEFILE, "$include_file" or die "Can't open $include_file\n" ; @included_acl =<INCLUDEFILE> ; close INCLUDEFILE ; $out_acl = "@included_acl" ; $out_acl =~ s/ACLNUMBER/$aclnumber/g ; print OUTFILE $out_acl ; } print OUTFILE "!\n" ; print OUTFILE "! final default rule\n" ; print OUTFILE "!\n" ; print OUTFILE "access-list $aclnumber permit ip any any\n" ; print OUTFILE "!\n" ; print OUTFILE "! activate new list\n" ; print OUTFILE "!\n" ; print OUTFILE "interface $interface\n" ; print OUTFILE "ip access-group $aclnumber in\n" ; close OUTFILE ; } # # here starts main # if ( $#ARGV != 0 ) { print "usage $0: router\n" ; exit 1 ; } $router = $ARGV[0] ; if ( ! -d $router ) { print "there is no directory for $router, creating ...\n" ; mkdir $router, 0755 ; } $snmpfile = $router . "/" . $router . "-snmpwalk" ; $routefile = $router . "/" . $router . "-routes" ; # # get routing data via snmp # $redo = 1 ; while ( $redo == 1 ) { if ( -f $snmpfile ) { open WC, "cat $snmpfile | wc -l |" ; $s = <WC> ; close WC ; if ( $s > 0 ) { print "There exists already a snmp-walk of router $router.\n" ; print "Because snmpwalks can last a couple of minutes or\n" ; print "sometimes fail, we can reuse this older file.\n" ; print "\n" ; print "Shall I reuse that file [y,n,default=y] ?\n" ; $yn = getc ; if ( $yn eq "\n" || $yn eq "y" || $yn eq "Y" ) { $redo = 0 ; } } } if ( $redo == 1 ) { print "getting snmp info from $router, this may take some time\n" ; open SNMPWALK, "snmpwalk $router public | " ; @snmpwalk = <SNMPWALK> ; close SNMPWALK ; open SNMPWALK, ">$snmpfile" or die "Can't open $snmpfile\n" ; print SNMPWALK @snmpwalk ; close SNMPWALK ; open WC, "cat $snmpfile | wc -l |" ; $s = <WC> ; close WC ; if ( $s == 0 ) { print "seems that snmpwalk failed, retrying ...\n" ; sleep 1 ; } else { $redo = 0 ; } } } open SNMPWALK, "$snmpfile" or die "Can't open $snmpfile\n" ; @snmpwalk =<SNMPWALK> ; close SNMPWALK ; open ROUTE, ">$routefile" or die "Can't open $routefile\n" ; # # setup several lists that are used in loops and therefor expensive # @nexthop_list = grep /ip.ipRouteTable.ipRouteEntry.ipRouteNextHop/, @snmpwalk ; @route_interface_list = grep /ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex/, @snmpwalk ; @route_mask_list = grep /ip.ipRouteTable.ipRouteEntry.ipRouteMask/, @snmpwalk ; @interface_descr_list = grep /interfaces.ifTable.ifEntry.ifDescr/, @snmpwalk ; @interface_index_list = grep /at.atTable.atEntry.atIfIndex/, @snmpwalk ; # # find out the default-router and its interface # @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteNextHop.0.0.0.0/, @nexthop_list ; $nexthop_default = "@in" ; $nexthop_default =~ s/.*IpAddress: // ; chomp ( $nexthop_default ) ; @in = grep /$nexthop_default /, @interface_index_list ; $interface_default = "@in" ; $interface_default =~ s/.* = // ; chomp ( $interface_default ) ; # # this is an ugly fix in case we do not have the default router directly connected # is has not been worked out completely and in case we come into here there will # for sure show up problems later # $ohoh_flag = 0 ; if ( $interface_default == "" ) { $ohoh_flag = 1 ; print "*** ohoh I do not like this section and will propably fail ...\n" ; ($ip1, $ip2, $ip3, $ip4) = split ( /\./, $nexthop_default ) ; $default_net = $ip1 . "." . $ip2 . "." . $ip3 ; @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteNextHop.$default_net/, @nexthop_list ; $nexthop_default = pop(@in) ; $nexthop_default =~ s/.*IpAddress: // ; chomp ( $nexthop_default ) ; @in = grep /$nexthop_default /, @interface_index_list ; $interface_default = "@in" ; $interface_default =~ s/.* = // ; chomp ( $interface_default ) ; } @in = grep /interfaces.ifTable.ifEntry.ifDescr.$interface_default /, @interface_descr_list ; $int_def_name = "@in" ; $int_def_name =~ s/.* = // ; $int_def_name =~ s/\"//g ; ( $int_def_name ) = split ( / /, $int_def_name ) ; chomp ( $int_def_name ) ; # # find out the Null0 interface, later ignoring everything routed via that interface # @in = grep /Null0/, @interface_descr_list ; $null_if = "@in" ; $null_if =~ s/.* = // ; ( $null_if ) = split ( / /, $null_if ) ; chomp ( $null_if ) ; # print $null_if ; # # we will store routing information in a file # print "defaultrouter: ", $nexthop_default, "\n" ; print ROUTE "defaultrouter: ", $nexthop_default, "\n" ; print "defaultinterface: ", $int_def_name, " (", $interface_default, ")\n" ; print ROUTE "defaultinterface: ", $int_def_name, " (", $interface_default, ")\n" ; # # find the direct attached networks and build up interface/network list # if ( $ohoh_flag == 0 ) { @in = grep !/ = $interface_default$/, @route_interface_list ; @in = grep !/ = $null_if$/, @in ; @in = grep !/ = 0/, @in ; $list_direct_networks = "@in" ; $list_direct_networks =~ s/ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex.//g ; $list_direct_networks =~ s/= .*\n//g ; } else { @in = grep !/ = 0/, @route_interface_list ; $list_direct_networks = "@in" ; $list_direct_networks =~ s/ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex.//g ; $list_direct_networks =~ s/= .*\n//g ; } # print "List of directly connected networks: ", $list_direct_networks ; # # get the interface numbers and associate the networks with them # $int_net_msk_list = "" ; $net_msk_list = "" ; @list = split ( " ", $list_direct_networks ) ; foreach $n ( @list ) { # print $n ; @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex.$n /, @route_interface_list ; $interface = "@in" ; $interface =~ s/.* = // ; chomp ( $interface ) ; @in = grep /interfaces.ifTable.ifEntry.ifDescr.$interface /, @interface_descr_list ; $int_name = "@in" ; $int_name =~ s/.* = // ; $int_name =~ s/\"//g ; ( $int_name ) = split ( / /, $int_name ) ; chomp ( $int_name ) ; # print $n, $interface, $int_name ; if ( $int_name eq "" ) { print "no interface name for interface $interface (network $n), skipping\n" ; next ; } if ( $int_name eq $null_if ) { print "no useful interface name for interface $interface (Name = $int_name) (network $n), skipping\n" ; next ; } @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteMask.$n /, @route_mask_list ; $netmask = "@in" ; $netmask =~ s/.*IpAddress: // ; chomp ( $netmask ) ; print "network $n with netmask $netmask via interface $int_name\n" ; print ROUTE "network $n with netmask $netmask via interface $int_name\n" ; $int_net_msk_list = $int_net_msk_list . " " . $int_name . " " . $n . " " . $netmask ; $net_msk_list = $net_msk_list . " " . $n . " " . $netmask ; } # # setup a list of interfaces # $int_list = "" ; $j = 0 ; @list = split ( " ", $int_net_msk_list ) ; foreach $i ( @list ) { if ( $j == 0 ) { $found = 0 ; @list2 = split ( " ", $int_list ) ; foreach $k ( @list2 ) { if ( $k eq $i ) { $found = 1 ; last ; } } if ( $found == 0 ) { $int_list = $int_list . " " . $i ; } } $j = ( $j + 1 ) % 3 ; } # print "List of interfaces $int_list\n" ; # # find the networks we route except those on default-interface # @in = grep / = 0/, @route_interface_list ; @in = grep !/0\.0\.0\.0/, @in ; $list_indirect_networks = "@in" ; $list_indirect_networks =~ s/ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex.//g ; $list_indirect_networks =~ s/= .*\n//g ; # print "List of indirectly connected networks:", $list_indirect_networks ; # # find out how we route and complete interface/network/netmask list # @list = split ( " ", $list_indirect_networks ) ; foreach $n ( @list ) { @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteNextHop.$n /, @nexthop_list ; $next_hop = "@in" ; $next_hop =~ s/.*IpAddress: // ; chomp ( $next_hop ) ; # print "Nexthop for $n:", $next_hop, "\n" ; $found = 0 ; @list2 = split ( " ", $list_direct_networks ) ; $d = "" ; foreach $d1 ( @list2 ) { @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteMask.$d1 /, @route_mask_list ; $m = "@in" ; $m =~ s/.*IpAddress: // ; chomp ( $m ) ; if ( is_in_net ( $next_hop, $d1, $m ) == 1 ) { $found = $found + 1 ; if ( $found == 1 ) { $d = $d1 ; } else { $d = $d . " " . $d1 ; } # last ; } } if ( $found == 0 ) { print "An error occured while trying to match\n" ; print "the host $next_hop as gateway for $n\n" ; print "against the network list $list_direct_networks\n" ; print "check your routing tables (?)\n" ; exit 1 ; } if ( $found > 1 ) { print "Warning: $found routes found ($d), taking the most narrow\n" ; $bits = "0.0.0.0" ; @list2 = split ( " ", $d ) ; foreach $d1 ( @list2 ) { @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteMask.$d1 /, @route_mask_list ; $m = "@in" ; $m =~ s/.*IpAddress: // ; chomp ( $m ) ; if ( ( $bits cmp $m ) < 0 ) { $d = $d1 ; $bits = $m ; } } } # print "Network: $n routed via net $d\n" ; @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteIfIndex.$d /, @route_interface_list ; $interface = "@in" ; $interface =~ s/.* = // ; chomp ( $interface ) ; @in = grep /interfaces.ifTable.ifEntry.ifDescr.$interface /, @interface_descr_list ; $int_name = "@in" ; $int_name =~ s/.* = // ; $int_name =~ s/\"//g ; ( $int_name ) = split ( / /, $int_name ) ; chomp ( $int_name ) ; if ( $int_name eq "" ) { print "no interface name for interface $interface (network $n), skipping\n" ; next ; } @in = grep /ip.ipRouteTable.ipRouteEntry.ipRouteMask.$n /, @route_mask_list ; $netmask = "@in" ; $netmask =~ s/.*IpAddress: // ; chomp ( $netmask ) ; print "network $n with netmask $netmask via interface $int_name\n" ; print ROUTE "network $n with netmask $netmask via interface $int_name\n" ; $int_net_msk_list = $int_net_msk_list . " " . $int_name . " " . $n . " " . $netmask ; $net_msk_list = $net_msk_list . " " . $n . " " . $netmask ; } # print "Combined list of interfaces and networks and netmasks:", $int_net_msk_list ; close ROUTE ; print "networks lists are complete, generating acl's\n" ; # # re-order into the format: include-file interface acl-number network netmask [network netmask ...] # netmasks are inverted as needed for cisco-acl's # there is the possibility to have an include-file named <router>-inc-<interface> # if some additional paket filtering is done there # $acl = 110 ; @list = split ( " ", $int_list ) ; foreach $i ( @list ) { print "interface: $i\n" ; $i_name = $i ; $i_name =~ s/\//_/g ; $inc_file = $router . "/" . $router . "-inc-" . $i_name ; $command = $inc_file . " " . $i . " " . $acl ; $found = 0 ; $j = 0 ; $output = 0 ; @list2 = split ( " ", $int_net_msk_list ) ; foreach $l ( @list2 ) { if ( $j == 0 ) { if ( $l eq $i ) { $output = 2 ; } } elsif ( $output > 0 ) { if ( $output == 1 ) { $l = inv_mask ( $l ) ; } $command = $command . " " . $l ; $output = $output - 1 ; } $j = ( $j + 1 ) % 3 ; } # print "$command\n" ; # # here we are ready to generate the list # but we will keep backups of the old lists # in case of manual additions # $acl_file = $router . "/" . $router . "." . $i_name . ".acl." . $acl ; $acl_file1 = $acl_file . ".~1~" ; $acl_file2 = $acl_file . ".~2~" ; $acl_file3 = $acl_file . ".~3~" ; $acl_file4 = $acl_file . ".~4~" ; $acl_file5 = $acl_file . ".~5~" ; rename $acl_file4, $acl_file5 ; rename $acl_file3, $acl_file4 ; rename $acl_file2, $acl_file3 ; rename $acl_file1, $acl_file2 ; rename $acl_file, $acl_file1 ; $command = $acl_file . " " . $command ; #print $command ; @list2=split ( " ", $command ) ; local_acl ( @list2 ) ; unshift @acl_file_list, $acl_file ; $acl = $acl + 1 ; } # # and finally we will create an ACL for the default interface # if ( $ohoh_flag == 0 ) { print "interface: $int_def_name\n" ; $i_name = $int_def_name ; $i_name =~ s/\//_/g ; $acl = 100 ; $acl_file = $router . "/" . $router . "." . $i_name . ".acl." . $acl ; $acl_file1 = $acl_file . ".~1~" ; $acl_file2 = $acl_file . ".~2~" ; $acl_file3 = $acl_file . ".~3~" ; $acl_file4 = $acl_file . ".~4~" ; $acl_file5 = $acl_file . ".~5~" ; rename $acl_file4, $acl_file5 ; rename $acl_file3, $acl_file4 ; rename $acl_file2, $acl_file3 ; rename $acl_file1, $acl_file2 ; rename $acl_file, $acl_file1 ; $inc_file = $router . "/" . $router . "-inc-" . $i_name ; $command = $inc_file . " " . $int_def_name . " " . $acl ; $j = 0 ; @list = split ( " ", $net_msk_list ) ; foreach $l ( @list ) { if ( $j == 1 ) { $l = inv_mask ( $l) ; } $command = $command . " " . $l ; $j = ( $j + 1 ) % 2 ; } # print "$command\n" ; $command = $acl_file . " " . $command ; @list=split ( " ", $command ) ; default_acl ( @list ) ; unshift @acl_file_list, $acl_file ; } # # postprocessing: # putting all into one file and keeping backups # $router_file=$router . ".all" ; $router_note=$router . ".note" ; # # process backups # if ( ! -d "acl-archive" ) { mkdir "acl-archive", 0755 ; } $acl_file1 = "acl-archive/" . $router_file . ".~1~" ; $acl_file2 = "acl-archive/" . $router_file . ".~2~" ; $acl_file3 = "acl-archive/" . $router_file . ".~3~" ; $acl_file4 = "acl-archive/" . $router_file . ".~4~" ; $acl_file5 = "acl-archive/" . $router_file . ".~5~" ; rename $acl_file4, $acl_file5 ; rename $acl_file3, $acl_file4 ; rename $acl_file2, $acl_file3 ; rename $acl_file1, $acl_file2 ; rename $router_file, $acl_file1 ; # # generate one file containing all ACL's without comments # open ACLFILE, ">$router_file" or die "Can't open $router_file\n" ; foreach $i ( @acl_file_list ) { open ACLFILEIN, "$i" or die "Can't open $i\n" ; @list =<ACLFILEIN> ; print ACLFILE @list ; close ACLFILEIN ; } close ACLFILE ; # # show the .note File, where the admin should keep # comments on the $ROUTER_FILE # if ( -f $router_note ) { print "There exists a file $router_note, which contains the following information\n" ; print "--------------------------------------------------------------------------\n" ; open NOTEFILE, "$router_note" or die "Can't open $router_note\n" ; @list =<NOTEFILE> ; print @list ; close NOTEFILE ; print "--------------------------------------------------------------------------\n" ; } # # we are done #