TUCoPS :: Cisco :: ciscoacl.pl

Anti-Spoofing rules generator for Cisco boxes

#!/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
#

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH