Fwd: Re: [fw-wiz] Cisco acls

From: Mark Teicher (mht3_at_earthlink.net)
Date: 03/21/05

  • Next message: Jeff Moss: "[fw-wiz] Black Hat Briefings & Trainings: Registration now open!"
    To: firewall-wizards@honor.icsalabs.com
    Date: Mon, 21 Mar 2005 06:31:14 -0500
    
    

    >
    >
    >Something like this
    >
    >#
    ># $rule = {
    ># "sourceline" => $_, # input text line
    ># "line" => $line, # line number
    ># "id" => $rule_id, # unique ID number
    ># "list" => $list, # list number (e.g. 101)
    ># "action" => $action, # permit or deny
    ># "protocol" => $protocol, # protocol (e.g. ip or tcp)
    ># "src" => $src, # source address
    ># "srcmask" => $srcmask, # source mask
    ># "dst" => $dst, # destination address
    ># "dstmask" => $dstmask, # destination mask
    ># "lowport" => $lowport, # low port number of range
    ># "highport" => $highport, # high port number of range
    ># "excludeport" => $excludeport, # excluded (neq) port number
    ># "dynamic" => $dynamic, # dynamic name
    ># "timeout" => $timeout, # dynamnic timeout
    ># "precedence" => $precedence, # precedence
    ># "tos" => $tos, # type of service
    ># "established" => $established, # 1 if "established" keyword
    ># "log" => $log, # 1 if "log" keyword
    ># "type" => $type, # ICMP or IGMP type
    ># "code" => $code, # ICMP code
    ># };
    >use strict;
    >use Socket;
    >
    >my $ALLONES = hex ("ffffffff");
    >
    >my %precedence_names = (
    > "critical" => 0,
    > "flash" => 1,
    > "flash-override" => 2,
    > "immediate" => 3,
    > "internet" => 4,
    > "network" => 5,
    > "priority" => 6,
    > "routine" => 7,
    >);
    >
    >my %tos_names = (
    > "none" => 0,
    > "min-monetary-cost" => 2,
    > "max-reliability" => 4,
    > "max-throughput" => 8,
    > "min-delay" => 16,
    >);
    >
    >my %icmp_names = (
    > "echo-reply" => [ 0, undef ],
    > "echo" => [ 8, undef ],
    > "packet-too-big" => [ 3, 4 ],
    >);
    >
    >my %igmp_names = (
    >);
    >
    >my %tcp_names = (
    > "bgp" => undef,
    > "chargen" => 19,
    > "daytime" => 13,
    > "discard" => 9,
    > "domain" => 53,
    > "echo" => 7,
    > "finger" => 79,
    > "ftp" => 21,
    > "ftp-data" => 20,
    > "gopher" => 70,
    > "hostname" => 101,
    > "irc" => 529,
    > "klogin" => 543,
    > "kshell" => 544,
    > "lpd" => undef,
    > "nntp" => 119,
    > "pop2" => 109,
    > "pop3" => 110,
    > "smtp" => 25,
    > "sunrpc" => 111,
    > "syslog" => 514,
    > "tacacs-ds" => 65,
    > "talk" => 517,
    > "telnet" => 23,
    > "time" => 37,
    > "uucp" => 540,
    > "whois" => 43,
    > "www" => 80,
    >);
    >
    >my %udp_names = (
    > "biff" => 512,
    > "bootpc" => 68,
    > "bootps" => 67,
    > "discard" => 9,
    > "dns" => 53,
    > "dnsix" => 90,
    > "echo" => 7,
    > "mobile-ip" => undef,
    > "nameserver" => 42,
    > "netbios-dgm" => 138,
    > "netbios-ns" => 137,
    > "ntp" => 123,
    > "rip" => undef,
    > "snmp" => 161,
    > "snmptrap" => 162,
    > "sunrpc" => 111,
    > "syslog" => 514,
    > "tacacs-ds" => 65,
    > "talk" => 517,
    > "tftp" => 69,
    > "time" => 37,
    > "who" => 513,
    > "xdmcp" => 177,
    >);
    >#
    ># Unique rule ID number, incremented every time a rule is parsed.
    >#
    >my $rule_id = 1;
    >
    >#
    ># Convert the internal representation of an IP address or mask
    ># into a string in A.B.C.D format.
    >#
    >sub addrstring
    >{
    > my ($addr) = @_;
    >
    > return (inet_ntoa (pack ("I1", $addr)));
    >}
    >
    >#
    ># Convert an address and mask into a string. If $new_format is
    ># 1 and the mask is all ones or all zeroes, "any" or "host A.B.C.D"
    ># will be returned, as appropriate. Otherwise the address and mask
    ># will be converted into A.B.C.D format, and concatenated with a space
    ># in between.
    >#
    >sub addr_mask_string
    >{
    > my ($addr, $mask, $new_format) = @_;
    > my $retval;
    >
    > if ($new_format && $addr == 0)
    > {
    > $retval ="any";
    > }
    > elsif ($new_format && $mask == 0)
    > {
    > $retval ="host " . addrstring ($addr);
    > }
    > else
    > {
    > $retval = addrstring ($addr) . " " . addrstring ($mask);
    > }
    >
    > return ($retval);
    >}
    >
    >#
    ># Print a rule to the passed file handle. If $parsed is 1, the
    ># internal parsed format will be used, otherwise the original line
    ># (stored with the rule structure) will be output. If $short is 1,
    ># a format that excludes certain information will be output; this is
    ># used by the matrix program, since the source and destination address
    ># are printed at the top of each group.
    >#
    >sub printrule
    >{
    > my ($rule, $fh, $parsed, $short) = @_;
    > my (%rule) = %$rule;
    >
    > $fh = *STDOUT unless (defined ($fh));
    >
    > unless ($parsed || $short)
    > {
    > print ($fh $rule{sourceline});
    > return;
    > }
    >
    > unless ($short)
    > {
    > print ($fh "access-list ", $rule{list});
    > print ($fh " dynamic ", $rule{dynamic}) if ($rule{dynamic});
    > print ($fh " timeout ", $rule{timeout}) if ($rule{timeout});
    > print ($fh " ");
    > }
    >
    > print ($fh $rule{action});
    >
    > if ($rule{list} <= 100)
    > {
    > print ($fh " ", addr_mask_string ($rule{src}, $rule{srcmask}))
    > unless ($short);
    >
    > if ($rule{log})
    > {
    > print (" ") unless ($short);
    > print ($fh "log");
    > }
    > print ($fh "\n");
    > }
    > else
    > {
    > print ($fh " ", $rule{protocol});
    >
    > unless ($short)
    > {
    > print ($fh
    > " ", addr_mask_string ($rule{src}, $rule{srcmask}, 1),
    > " ", addr_mask_string ($rule{dst}, $rule{dstmask}, 1));
    > }
    >
    > if ($rule{protocol} eq "tcp" || $rule{protocol} eq "udp")
    > {
    > if (defined ($rule{excludeport}))
    > {
    > print ($fh " neq ", $rule{excludeport});
    > }
    > elsif (defined ($rule{lowport}))
    > {
    > if ($rule{lowport} == $rule{highport})
    > {
    > print ($fh " eq ", $rule{lowport});
    > }
    > elsif ($rule{lowport} == 1)
    > {
    > print ($fh " lt ", $rule{highport} + 1);
    > }
    > elsif ($rule{highport} == 65535)
    > {
    > print ($fh " gt ", $rule{lowport} - 1);
    > }
    > else
    > {
    > print ($fh " range ", $rule{lowport}, " ",
    > $rule{highport});
    > }
    > }
    > }
    >
    > print ($fh " ", $rule{type}) if ($rule{type} ne undef);
    > print ($fh " ", $rule{code}) if ($rule{code} ne undef);
    >
    > print ($fh " precedence ", $rule{precedence})
    > if ($rule{precedence} ne -1);
    > print ($fh " tos ", $rule{tos}) if ($rule{tos} ne -1);
    >
    > print ($fh " established") if ($rule{established});
    > print ($fh " log") if ($rule{"log"});
    >
    > print ($fh "\n");
    > }
    >}
    >
    >#
    ># Parse a single IP address or mask into our internal representation.
    >#
    >sub parseaddr
    >{
    > my ($addr) = @_;
    > return (unpack ("I1", inet_aton ($addr)));
    >}
    >
    >#
    ># Parse an address and mask into the internal representation.
    ># the address and mask are assumed to be at the beginning of the
    ># passed-in array; the array is shifted to consume the address
    ># information. New acl formats "any" and "host A.B.C.D" are
    ># handled.
    >#
    ># The address and mask are copied into the scalar variables
    ># pointed to by the $addr and $mask references. The subroutine
    ># returns 1 if the address and mask match (i.e. all 1 bits
    ># in the mask are 0 in the address); if not, the address is
    ># changed to match the mask, and 0 is returned.
    >#
    ># This subroutine is intended to be called only by parserule, below.
    >#
    >sub parse_addr_mask
    >{
    > my ($fields, $addr, $mask) = @_;
    > my $valid = 1;
    >
    > for (@$fields[0])
    > {
    > /any/ and do {
    > $$addr = unpack ("I1", inet_aton ("0.0.0.0"));
    > $$mask = unpack ("I1",
    > inet_aton ("255.255.255.255"));
    > shift @$fields;
    > last;
    > };
    >
    > /host/ and do {
    > $$addr = unpack ("I1", inet_aton
    > ("@$fields[1]"));
    > $$mask = unpack ("I1", inet_aton ("0.0.0.0"));
    > shift @$fields;
    > shift @$fields;
    > last;
    > };
    >
    > do {
    > $$addr = unpack ("I1", inet_aton
    > ("@$fields[0]"));
    > $$mask = unpack ("I1", inet_aton
    > ("@$fields[1]"));
    > shift @$fields;
    > shift @$fields;
    > };
    > }
    >
    > if (($$addr & ~($$mask)) != $$addr)
    > {
    > $$addr &= ~($$mask);
    > $valid = 0;
    > }
    >
    > return ($valid);
    >}
    >
    >#
    ># Output an error message regarding a rule. This is a convenience
    ># function for parserule, below.
    >#
    >sub rule_error
    >{
    > my ($fh, $sourceline, $line, @fields) = @_;
    >
    > return unless (defined ($fh));
    > print ($fh "Error at line $line: ", join ('', @fields),
    > ":\n$sourceline\n");
    >}
    >$action = $fields[0];
    > shift @fields;
    >
    > $protocol = $fields[0];
    > shift @fields;
    >
    > if (! parse_addr_mask (\@fields, \$src, \$srcmask) && $err_fh)
    > {
    > print ($err_fh
    > "Invalid source address for mask, line ",
    > $line, ":\n", $_);
    > print ($err_fh
    > "Source address changed to ", addrstring ($src), "\n\n");
    > }
    >
    > if (! parse_addr_mask (\@fields, \$dst, \$dstmask) && $err_fh)
    > {
    > print ($err_fh
    > "Invalid destination address for mask, line ",
    > $line, ":\n", $_);
    > print ($err_fh
    > "Destination address changed to ", addrstring ($dst),
    > "\n\n");
    > }
    >
    > for ($i = 0; $i < @fields; $i++)
    > {
    > for ($fields[$i])
    > {
    > /^eq$/ and do {
    > $i++;
    > $lowport = $fields[$i];
    > $highport = $lowport;
    > next;
    > };
    >
    > /^neq$/ and do {
    > $i++;
    > $excludeport = $fields[$i];
    > next;
    > };
    >
    > /^gt$|^ge$/ and do {
    > $i++;
    > $lowport = $fields[$i];
    > $lowport++ if /gt/;
    > $highport = 65535;
    > next;
    > };
    >
    > /^lt$|^le$/ and do {
    > $i++;
    > $lowport = 1;
    > $highport = $fields[$i];
    > $highport-- if /lt/;
    > next;
    > };
    >
    > /^range$/ and do {
    > $i++;
    > $lowport = $fields[$i];
    > $i++;
    > $highport = $fields[$i];
    > next;
    > };
    >
    > /^precedence$/ and do {
    > $i++;
    > $precedence = $fields[$i];
    > next;
    > };
    >
    > /^tos$/ and do {
    > $i++;
    > $tos = $fields[$i];
    > next;
    > };
    >
    > /^established$/ and do {
    > $established = 1;
    > next;
    > };
    >
    > /^log$/ and do {
    > $log = 1;
    > next;
    > };
    >
    > do {
    > if (($protocol eq "icmp" ||
    > $protocol eq "igmp") &&
    > $type == undef)
    > {
    > $type = $fields[$i];
    > next;
    > }
    >
    > if ($protocol eq "icmp" &&
    > $type ne undef &&
    > $code eq undef)
    > {
    > $code = $fields[$i];
    > next;
    > }
    >
    > rule_error ($err_fh,
    > $sourceline, $line,
    > $fields[$i],
    > ": unknown token",
    > ", ignoring rule");
    > return (undef);
    > };
    > }
    > }
    >
    > $tos = $tos_names{$tos} if ($tos_names{$tos} ne undef);
    > $precedence = $precedence_names{$precedence}
    > if ($precedence_names{$precedence} ne undef);
    >
    > if ($protocol eq "icmp" && $icmp_names{$type} ne undef)
    > {
    > @fields = @{$icmp_names{$type}};
    > $type = $fields[0];
    > $code = $fields[1];
    > }
    > elsif ($protocol eq "tcp")
    > {
    > $lowport = $tcp_names{$lowport}
    > if ($tcp_names{$lowport} ne undef);
    >
    > $highport = $tcp_names{$highport}
    > if ($tcp_names{$highport} ne undef);
    >
    > $excludeport = $tcp_names{$excludeport}
    > if ($tcp_names{$excludeport} ne undef);
    > }
    > elsif ($protocol eq "udp")
    > {
    > $lowport = $udp_names{$lowport}
    > if ($udp_names{$lowport} ne undef);
    >
    > $highport = $udp_names{$highport}
    > if ($udp_names{$highport} ne undef);
    >
    > $excludeport = $udp_names{$excludeport}
    > if ($udp_names{$excludeport} ne undef);
    > }
    >
    > if (defined ($lowport) && $lowport =~ /[a-zA-Z]/)
    > {
    > rule_error ($err_fh, $sourceline, $line,
    > "$lowport: unknown $protocol port name, ignoring rule");
    > return (undef);
    > }
    >
    > if (defined ($highport) && $highport =~ /[a-zA-Z]/)
    > {
    > rule_error ($err_fh, $sourceline, $line,
    > "$highport: unknown $protocol port name, ignoring rule");
    > return (undef);
    > }
    >
    > if (defined ($excludeport) && $excludeport =~ /[a-zA-Z]/)
    > {
    > rule_error ($err_fh, $sourceline, $line,
    > "$excludeport: unknown $protocol port name, ignoring rule");
    > return (undef);
    > }
    >
    > if (defined ($type) && $type =~ /[a-zA-Z]/)
    > {
    > rule_error ($err_fh, $sourceline, $line,
    > "$type: unknown $protocol type name, ignoring rule");
    > return (undef);
    > }
    >
    > if (defined ($code) && $code =~ /[a-zA-Z]/)
    > {
    > rule_error ($err_fh, $sourceline, $line,
    > "$code: unknown $protocol code name, ignoring rule");
    > return (undef);
    > }
    > }
    >
    > $rule = {
    > "sourceline" => $_,
    > "line" => $line,
    > "id" => $rule_id,
    > "list" => $list,
    > "action" => $action,
    > "protocol" => $protocol,
    > "src" => $src,
    > "srcmask" => $srcmask,
    > "dst" => $dst,
    > "dstmask" => $dstmask,
    > "lowport" => $lowport,
    > "highport" => $highport,
    > "excludeport" => $excludeport,
    > "dynamic" => $dynamic,
    > "timeout" => $timeout,
    > "precedence" => $precedence,
    > "tos" => $tos,
    > "established" => $established,
    > "log" => $log,
    > "type" => $type,
    > "code" => $code,
    > };
    >
    > return ($rule);
    >}
    >
    >#
    ># Initialize an access control list in the data structure.
    >#
    >sub initacl
    >{
    > my ($acls, $list) = @_;
    >
    > $acls->{$list} = ();
    > ${$acls->{$list}}{num} = $list;
    > ${$acls->{$list}}{numrules} = 0;
    > @{${$acls->{$list}}{rules}} = ();
    > %{${$acls->{$list}}{src}} = ();
    > %{${$acls->{$list}}{dst}} = ();
    > %{${$acls->{$list}}{index}} = ();
    > %{${$acls->{$list}}{unique}} = ();
    >}
    >
    >#
    ># Add a rule to the data structure.
    >#
    >sub addrule
    >{
    > my ($acls, $rule) = @_;
    > my $list = $rule->{list};
    > my $src = $rule->{src};
    > my $srcmask = $rule->{srcmask};
    > my $dst = $rule->{dst};
    > my $dstmask = $rule->{dstmask};
    > my $protocol = $rule->{protocol};
    > my $established = $rule->{established};
    > my $precedence = $rule->{precedence};
    > my $tos = $rule->{tos};
    > my $dynamic = $rule->{dynamic};
    > my $lowport = $rule->{lowport};
    > my $highport = $rule->{highport};
    > my $excludeport = $rule->{excludeport};
    > my $type = $rule->{type};
    > my $code = $rule->{code};
    >
    > initacl ($acls, $list) unless (${$acls->{$list}}{num} == $list);
    > $rule_id++;
    >
    > #
    > # These are truly ugly, but they build a data structure that
    > # makes the checking we need to do much more efficient.
    > #
    > ${$acls->{$list}}{numrules}++;
    > push (@{${$acls->{$list}}{rules}}, $rule);
    >
    > if ($list > 0 && $list <= 100)
    > {
    > push (@{${${${$acls->{$list}}{index}}{$srcmask}}{$src}}, $rule);
    > return;
    > }
    >
    > push
    > (@{${${${${${${${${${$acls->{$list}}{index}}{$srcmask}}{$src}}{$dstmask}}{$dst}}{$protocol}}{$precedence}}{$tos}}{$dynamic}},
    > $rule);
    >
    > my $unique_index =
    > $protocol .
    > ((defined ($lowport)) ? $lowport : 1) .
    > ((defined ($highport)) ? $highport : 65535) .
    > ((defined ($excludeport)) ? $excludeport : 0) .
    > ((defined ($type)) ? $type : -1) .
    > ((defined ($code)) ? $code : -1);
    >
    >
    >${${${${${${$acls->{$list}}{unique}}{$src}}{$srcmask}}{$dst}}{$dstmask}}{$unique_index}
    >= $rule;
    >
    > return if (rule_matchall ($rule) || rule_antispoof ($rule));
    >
    > push (@{${${${$acls->{$list}}{src}}{$srcmask}}{$src}}, $rule)
    > unless ($srcmask == $ALLONES);
    >
    > push (@{${${${$acls->{$list}}{dst}}{$dstmask}}{$dst}}, $rule)
    > unless ($dstmask == $ALLONES);
    >}
    >
    >#
    ># Parse all the access control lists in the file pointed to by
    ># $in_fh.
    >#
    >sub parseacls
    >{
    > my ($in_fh, $err_fh) = @_;
    > my (%acls);
    > my ($line) = 0;
    >
    > while (<$in_fh>)
    > {
    > $line++;
    >
    > if (s/^no access-list (\d+)$/$1/)
    > {
    > chomp;
    >
    > if ($acls{$_})
    > {
    > print ($err_fh
    > "Error at line $line: Redefined access list $_.\n")
    > if ($err_fh);
    > }
    >
    > initacl (\%acls, $_);
    > next;
    > }
    >
    > next if (! /^access-list / || /^!/);
    > addrule (\%acls, parserule ($err_fh, $line, $_));
    > }
    >
    > return (%acls);
    >}
    >
    >#
    ># Return true if the rule pointed to by $compare matches all the
    ># ports specified in the rule pointed to by $rule. For example,
    ># if $compare specifies a range of 100-200, and $rule specifies
    ># the single port 150, rule_matchports will return true. If the
    ># opposite is true ($rule specifies the range, and $compare
    ># specifies the single port), rule_matchports will return false.
    >#
    ># If the low and high port numbers are undefined, the rule matches
    ># all ports; if $compare matches all ports, rule_matchports will
    ># always return true.
    >#
    >sub rule_matchports
    >{
    > my ($rule, $compare) = @_;
    >
    > return
    > (
    > (
    > $compare->{lowport} eq undef &&
    > $compare->{excludeport} eq undef
    > ) ||
    > (
    > $rule->{lowport} >= $compare->{lowport} &&
    > $rule->{highport} <= $compare->{highport} &&
    > $rule->{excludeport} == $compare->{excludeport}
    > )
    > );
    >}
    >
    >#
    ># Return true if $rule and $compare specify the same ICMP or IGMP
    ># types, or if $compare matches all types.
    >#
    >sub rule_matchtypes
    >{
    > my ($rule, $compare) = @_;
    >
    > return ($compare->{type} eq undef || $rule->{type} eq $compare->{type});
    >}
    >
    >#
    ># Return true if $rule and $compare specify the same ICMP
    ># codes, or if $compare matches all codes.
    >#
    >sub rule_matchcodes
    >{
    > my ($rule, $compare) = @_;
    >
    > return ($compare->{code} eq undef || $rule->{code} eq $compare->{code});
    >}
    >
    >#
    ># Return true if $rule and $compare are identical.
    >#
    >sub rule_identical
    >{
    > my ($rule, $compare) = @_;
    >
    > return ($rule->{action} eq $compare->{action} &&
    > $rule->{lowport} == $compare->{lowport} &&
    > $rule->{highport} == $compare->{highport} &&
    > $rule->{excludeport} == $compare->{excludeport} &&
    > $rule->{protocol} eq $compare->{protocol} &&
    > $rule->{type} eq $compare->{type} &&
    > $rule->{code} eq $compare->{code} &&
    > $rule->{dynamic} eq $compare->{dynamic} &&
    > $rule->{timeout} eq $compare->{timeout} &&
    > $rule->{src} == $compare->{src} &&
    > $rule->{established} == $compare->{established} &&
    > $rule->{log} == $compare->{log} &&
    > $rule->{srcmask} == $compare->{srcmask} &&
    > $rule->{dst} == $compare->{dst} &&
    > $rule->{dstmask} == $compare->{dstmask});
    >}
    >
    >#
    ># Return true if $rule matches all sources, destinations, and ports.
    ># This will match regardless of protocol, so (for example)
    ># "permit tcp any any" is considered a "match all" rule.
    >#
    >sub rule_matchall
    >{
    > my ($rule) = @_;
    >
    > return ($rule->{srcmask} == $ALLONES &&
    > $rule->{dstmask} == $ALLONES &&
    > $rule->{lowport} == undef &&
    > $rule->{highport} == undef &&
    > $rule->{excludeport} == undef &&
    > $rule->{type} == undef &&
    > $rule->{code} == undef);
    >}
    >
    >#
    ># Return true if $rule is an "anti-spoofing" rule, defined as matching
    ># all IP protocols, with either a source or destination of "any".
    >#
    >sub rule_antispoof
    >{
    > my ($rule) = @_;
    >
    > return (
    > (
    > ( $rule->{srcmask} == $ALLONES && $rule->{dstmask} !=
    > $ALLONES ) ||
    > ( $rule->{dstmask} == $ALLONES && $rule->{srcmask} != $ALLONES )
    > ) &&
    > $rule->{protocol} eq "ip");
    >}
    >
    >#
    ># Find rules that indicate that the same IP address is on both sides
    ># of the router. This subroutines searches $acl for rules whose
    ># destination address and mask match the source of $rule, or whose
    ># source address and mask match the destination of $rule.
    >#
    >sub aclconflicts
    >{
    > my ($rule, $acl) = @_;
    > my (@matches) = ();
    > my %acl = %$acl;
    >
    >
    > return (@matches) if (rule_matchall ($rule) || rule_antispoof ($rule));
    >
    > foreach my $dstmask (keys (%{$acl{dst}}))
    > {
    > my $dstaddr = ($rule->{src} & ~($dstmask + 0));
    >
    > if (${${${acl}{dst}}{$dstmask}}{$dstaddr} ne undef)
    > {
    > foreach my $compare (@{${${${acl}{dst}}{$dstmask}}{$dstaddr}})
    > {
    > next if ($rule->{line} > $compare->{line});
    > push (@matches, $compare);
    > }
    > }
    > }
    >
    > foreach my $srcmask (keys (%{$acl{src}}))
    > {
    > my $srcaddr = $rule->{dst} & ~($srcmask + 0);
    >
    > if (${${${acl}{src}}{$srcmask}}{$srcaddr} ne undef)
    > {
    > foreach my $compare (@{${${${acl}{src}}{$srcmask}}{$srcaddr}})
    > {
    > next if ($rule->{line} > $compare->{line});
    > push (@matches, $compare);
    > }
    > }
    > }
    >
    > return (@matches);
    >}
    >
    >#
    ># Find all rules in an access control list that match the same
    ># source and destination addresses that $rule matches. If $skipsame
    ># is true, $rule itself will be left out of the match list. If
    ># $subsets is true, rules that match fewer ports or ICMP/IGMP types
    ># will be included, otherwise only rules that match the same ports
    ># and types, or that have a broader range of ports or types, will
    ># be returned.
    >#
    >sub aclmatch
    >{
    > my ($rule, $acl, $skipsame, $subsets) = @_;
    > my (@matches) = ();
    > my %acl = %$acl;
    >
    > foreach my $srcmask (keys (%{$acl{index}}))
    > {
    > next if ($srcmask < $rule->{srcmask});
    >
    > my $srcaddr = $rule->{src} & ~($srcmask + 0);
    >
    > next if (${${${acl}{index}}{$srcmask}}{$srcaddr} eq undef);
    >
    > if ($acl{num} <= 100)
    > {
    > my @srcmatches = @{${${${acl}{index}}{$srcmask}}{$srcaddr}};
    > foreach my $compare (@srcmatches)
    > {
    > next if ($skipsame && $rule->{id} == $compare->{id});
    > push (@matches, $compare);
    > }
    >
    > next;
    > }
    >
    > my %srcmatches = %{${${${acl}{index}}{$srcmask}}{$srcaddr}};
    >
    > foreach my $dstmask (keys (%srcmatches))
    > {
    > next if ($dstmask < $rule->{dstmask});
    >
    > my $dstaddr = $rule->{dst} & ~($dstmask + 0);
    >
    > next if (${$srcmatches{$dstmask}}{$dstaddr} eq undef);
    >
    > my %dstmatches = %{${$srcmatches{$dstmask}}{$dstaddr}};
    >
    > foreach my $compare
    > (@{${${$dstmatches{$rule->{protocol}}}{$rule->{precedence}}{$rule->{tos}}}{$rule->{dynamic}}})
    > {
    > next if ($skipsame && $rule->{id} == $compare->{id});
    >
    > push (@matches, $compare) if
    > (
    > $subsets ||
    > (
    > $rule->{established} eq $compare->{established} &&
    > rule_matchports ($rule, $compare) &&
    > rule_matchtypes ($rule, $compare) &&
    > rule_matchcodes ($rule, $compare)
    > )
    > );
    > }
    >
    > next if ($rule->{protocol} eq "ip");
    >
    > foreach my $compare
    > (@{${${$dstmatches{"ip"}}{$rule->{precedence}}{$rule->{tos}}}{$rule->{dynamic}}})
    > {
    > next if ($skipsame && $rule->{id} == $compare->{id});
    >
    > push (@matches, $compare) if
    > (
    > $subsets ||
    > (
    > $rule->{established} eq $compare->{established} &&
    > rule_matchports ($rule, $compare) &&
    > rule_matchtypes ($rule, $compare) &&
    > rule_matchcodes ($rule, $compare)
    > )
    > );
    > }
    > }
    > }
    >
    > return (sort { $a->{line} <=> $b->{line} } @matches);
    >}
    >
    >#
    ># Look up a packet in an ACL.
    >#
    >sub acllookup
    >{
    > my ($acl, $src, $dst, $protocol, @options) = @_;
    > my ($port, $type, $code) = (undef, undef, undef);
    >
    > $src = parseaddr ($src);
    > $dst = parseaddr ($dst);
    >
    > if ($protocol eq "tcp" || $protocol eq "udp")
    > {
    > $port = $options[0];
    > }
    > elsif ($protocol eq "icmp" || $protocol eq "igmp")
    > {
    > $type = $options[0];
    > $code = $options[1] if ($protocol eq "icmp");
    > }
    >
    > #
    > # Build a "rule" structure out of the packet information,
    > # and search the ACL for matches.
    > #
    > my $packet = {
    > "line" => 0,
    > "id" => 0,
    > "list" => 0,
    > "action" => undef,
    > "protocol" => $protocol,
    > "src" => $src,
    > "srcmask" => 0,
    > "dst" => $dst,
    > "dstmask" => 0,
    > "lowport" => $port,
    > "highport" => $port,
    > "excludeport" => undef,
    > "dynamic" => undef,
    > "timeout" => undef,
    > "precedence" => -1,
    > "tos" => -1,
    > "established" => 0,
    > "log" => undef,
    > "type" => $type,
    > "code" => $code,
    > };
    >
    > return (aclmatch ($packet, $acl, 0, 0));
    >}
    >
    >#
    ># Perl requires modules to return a true value.
    >#
    >1;
    >
    >
    >
    >At 08:50 PM 3/16/2005, Steve Saeedi wrote:
    >>Try the command show access-list <access-list> and look at the hitcnt.
    >>
    >>epix1(config)# sh access-list cluster
    >>access-list cluster; 122 elements
    >>access-list cluster line 1 permit icmp any any (hitcnt=283183)
    >>access-list cluster line 2 permit tcp 10.1.40.0 255.255.255.0
    >>object-group internal-dns-servers eq domain
    >>access-list cluster line 2 permit tcp 10.1.40.0 255.255.255.0 host mobra
    >>eq domain (hitcnt=0)
    >>access-list cluster line 2 permit tcp 10.1.40.0 255.255.255.0 host area51
    >>eq domain (hitcnt=0)
    >>access-list cluster line 3 permit udp 10.1.40.0 255.255.255.0
    >>object-group internal-dns-servers eq domain
    >>access-list cluster line 3 permit udp 10.1.40.0 255.255.255.0 host mobra
    >>eq domain (hitcnt=6853)
    >>access-list cluster line 3 permit udp 10.1.40.0 255.255.255.0 host area51
    >>eq domain (hitcnt=7231)
    >>[...]
    >>
    >>same goes for conduits
    >>
    >>- Steve
    >>
    >>
    >>On Mar 8, 2005, at 4:06 AM, Mark Teicher wrote:
    >>
    >>>Has anyone seen or heard of a Cisco ACL lint checker to validate whether
    >>>a certain acl is being utilized or at all. What about old acls that
    >>>have been around for a while, and no one understands why they were
    >>>inserted in the first place.
    >>>
    >>>
    >>>
    >>>At 01:47 PM 3/1/2005, Bruce Smith wrote:
    >>>>Hi Eric
    >>>>
    >>>>Yep, that's what we've experienced. What our network engineer does is edit
    >>>>the acl in notepad or similar, first line the no access-list xxx line, and
    >>>>then pastes the whole thing into the telnet client. The acl is regenerated
    >>>>very rapidly and the open time is a minimum. We use QVTTerm and the normal
    >>>>paste option. Also, make sure there's a blank line at the end of the acl
    >>>>before you copy and paste or the last command doesn't get run
    >>>>automatically.
    >>>>
    >>>>Regards
    >>>>
    >>>>Bruce Smith
    >>>>Consultent Engineer - NMMU
    >>>>
    >>>>-----Original Message-----
    >>>>From: firewall-wizards-admin@honor.icsalabs.com
    >>>>[mailto:firewall-wizards-admin@honor.icsalabs.com] On Behalf Of Eric
    >>>>Appelboom
    >>>>Sent: Tuesday, March 01, 2005 05:53 PM
    >>>>To: firewall-wizards@honor.icsalabs.com
    >>>>Subject: [fw-wiz] Cisco acls
    >>>>
    >>>>
    >>>>
    >>>>Hi,
    >>>>
    >>>>I would appreciate some comments with regard to the extensive use of
    >>>>cisco routers acls
    >>>>To protect numerous networks.
    >>>>
    >>>>My concern is that when someone amends an access-list one generally
    >>>>enters, no access-list 177 and
    >>>>Then pastes in the new access list. Does this mean that for a period of
    >>>>time there is no protection on the
    >>>>Network that the acls applies?
    >>>>
    >>>>Best Regards
    >>>>Eric
    >>>>MWEB: S.A.'s trusted Internet Service Provider. Just Like that.
    >>>>To join, click here or call 08600 32000.
    >>>>_______________________________________________
    >>>>firewall-wizards mailing list
    >>>>firewall-wizards@honor.icsalabs.com
    >>>>http://honor.icsalabs.com/mailman/listinfo/firewall-wizards
    >>>>
    >>>>_______________________________________________
    >>>>firewall-wizards mailing list
    >>>>firewall-wizards@honor.icsalabs.com
    >>>>http://honor.icsalabs.com/mailman/listinfo/firewall-wizards
    >>>
    >>>_______________________________________________
    >>>firewall-wizards mailing list
    >>>firewall-wizards@honor.icsalabs.com
    >>>http://honor.icsalabs.com/mailman/listinfo/firewall-wizards

    _______________________________________________
    firewall-wizards mailing list
    firewall-wizards@honor.icsalabs.com
    http://honor.icsalabs.com/mailman/listinfo/firewall-wizards


  • Next message: Jeff Moss: "[fw-wiz] Black Hat Briefings & Trainings: Registration now open!"

    Relevant Pages

    • Re: Masked Textbox
      ... > Public Sub New ... > Protected Overloads Overrides Sub Dispose ... The following procedure is required by the Component Designer ... > Public Property Mask() As String ...
      (microsoft.public.dotnet.languages.vb)
    • Re: Query an IP from file
      ... But if the network data files include too much IPs,my program used up all memory and couldn't get continued. ... sub query_an_ip { ... my $file = shift; ... # translate netnum and mask to int ...
      (perl.beginners)
    • Re: Userform Date Formatting MM/DD/YYYY
      ... There are 3 textboxes, one for the month, one for the day, and one for the ... Private Sub spnDay_Change ... Private Sub spnMonth_Change ... > Are you sure there isn't some way I could get that> software date mask to work? ...
      (microsoft.public.excel.programming)
    • RE: loop Question
      ... # number of mask bits => inverted Bit mask ... # in host byte order. ... sub ip_to_number { ... # assume our network is 192.168.1.0/24 ...
      (perl.beginners)
    • Re: Sub enclosures questions
      ... Now - the bigger the box, the lower fequency response you can get, ... The specs on the sub said it ... Does it matter which face of the enclosure the drivers and ports are ...
      (rec.audio.car)