#!/usr/bin/perl
use strict;
use Getopt::Std;
use Net::Telnet;
my %globhash;
my %subhash;
my %args = ();
getopts("fksdu:p:i:c:h", \%args);
my @ips;
my $IP_FILE;
my $CONF_FILE;
my $debug = 0;
my $USER = '';
my $PASS = '';
$debug = 1 if $args{d};
$USER = $args{u} if $args{u};
$PASS = $args{p} if $args{p};
$IP_FILE = $args{i};
$CONF_FILE = $args{c};
if ($args{h}) {
&showhelp;
}
die "usage: $0 [-dupicskhf] -u <user> -p <pass> -i <ipfile> -c <conf f
+ile>" unless ($IP_FILE && $CONF_FILE);
open(IPS, "$IP_FILE");
while(<IPS>) {
chomp;
push @ips,$_;
}
close(IPS);
foreach my $ip (@ips) {
doaudit($ip);
unlink "$ip.tmp" if !$args{k};
}
sub showhelp {
print <<EOF
-u <user>: username of the juniper routers
-p <pass>: password of the juniper routers
-i <ipfile>: file of ip juniper ip address's
-c <config>: the audit configuration file (see README)
-d : debugging information (mucho text)
-s : show matched information also
(Not just the not matched)
-h : this help screen ;)
-k : keep a copy of the juniper's config file in <h
+ostname>.tmp
-f : show stuff that was left over that was in the
+juniper.conf
but not in the audit configuration file (stuff
+ that was in
the juniper.conf but not in the template
EOF
}
sub getconfig {
my($host) = @_;
my $t;
my $CMD = 'show configuration | no-more';
$t = new Net::Telnet (Timeout => 10);
$t->open("$host");
$t->login($USER, $PASS);
my @lines = $t->cmd($CMD);
open(TMP, ">$host.tmp");
foreach my $line (@lines) {
print TMP "$line";
}
close(TMP);
}
sub getintnames {
# usage getintnames(IP, TYPE(OC-3));
# returns array
my (@cardz,$slotcounter,$slot,$cardtype,$pic,$ports);
my($ip,$type) = @_;
my $t;
my $CMD = 'show chassis fpc pic-status';
$t = new Net::Telnet (Timeout => 10);
$t->open("$ip");
$t->login($USER, $PASS);
my @lines = $t->cmd($CMD);
foreach my $fpc (@lines) {
if ($fpc =~ /Slot (\d+?).*$/) {
$slotcounter = 1;
$slot = $1;
next;
}
if ($slotcounter eq 1) {
my $knownthing = 0;
if ($fpc =~ /PIC (\d+?)\s+(.*?)\,.*$/) {
$cardtype = $2;
$pic = $1;
if($cardtype =~ /$type/) {
$ports = $cardtype;
$ports =~ /^(\d)x.*/;
$ports = $1;
$knownthing = 1;
for (my $i = 0; $i < $
+ports; $i++) {
my $card = "so
+-$slot/$pic/$i";
push @cardz,$c
+ard;
}
}
}
}
}
return @cardz;
}
sub parsit {
my (@matched,@body);
my ($host,$where) = @_;
open(FILE, "$host.tmp");
my $inside = "";
my %hash = ();
while (<FILE>) {
chomp;
push @body,$_;
}
close(FILE);
while (my $line = shift @body) {
if($line =~ /^([^\{]+)\{/) {
my $start = $1;
$start =~ s/^\s+//g;
$start =~ s/\s+$//g;
if($inside) {
$inside .= ":$start";
}
else {
$inside = $start;
}
next;
}
elsif ($line =~ /\}/) {
push @{$hash{$inside}},undef;
if ($inside =~ /\w+(\:\w+)+/) {
my @tmp = split ':', $inside;
$#tmp--;
$inside = join ':', @tmp;
}
else {
$inside = "";
next;
}
}
else {
$line =~ s/^\s+//g;
$line =~ s/\s+$//g;
push @{$hash{$inside}},$line;
}
}
foreach my $thingy ( keys %hash ) {
foreach my $blah (@{ $hash{$thingy} }) {
$blah =~ s/^\s+//g;
push @matched,$blah if $thingy eq $where;
}
}
return @matched;
}
sub doaudit {
my($host) = @_;
my (@all);
getconfig($host);
open(FILE, "$CONF_FILE");
while(<FILE>) {
chomp;
s/^\#.*$//g; # i want comments damnit
s/\n$//g;
s/\s+$//g;
s/^\s+//g;
print "DEBUG: while(<FILE>) {: pushing $_ into \@all\n
+"
if $debug eq 1;
push @all, $_;
}
close(FILE);
print "\n\n"
if $debug eq 1;
my $startgroup = 0;
my $brackets = 0;
my $globalcounter = 0;
my $subcounter = 0;
my $group;
my $sub;
my %globhash = ();
my %subhash = ();
foreach my $line (@all) {
if ($line =~ /^GROUP: (\S+?)\s+\{$/) {
$group = $1;
$startgroup = 1;
print "DEBUG: \$line matched GROUP: $group\n"
if $debug eq 1;
next;
}
if ($startgroup eq 1) {
if ($line =~ /GLOBAL {$/) {
print "DEBUG: Matched GLOBAL for \"$li
+ne\"\n"
if $debug eq 1;
$globalcounter = 1;
next;
}
if ($globalcounter eq 1) {
print "DEBUG: \$globalcounter ='s 1\n"
if $debug eq 1;
if ($line =~ /}/) {
print "DEBUG: \$line matched }
+\n"
if $debug eq 1;
$globalcounter = 0;
next;
}
else {
print "DEBUG: \$line isnt }\n"
if $debug eq 1;
if ($globhash{$group} eq "") {
$globhash{$group} = "$
+line";
print "DEBUG globhash
+\$globhash{$group} = \"$line\"\n"
if $debug eq 1
+;
next;
}
else {
$globhash{$group} .= "
+!:!$line";
print "DEBUG globhash
+\$globhash\{$group\} = \"!:!$line\"\n"
if $debug eq 1
+;
next;
}
}
}
if ($line =~ /SUB: (.*?)\s+{$/) {
$sub = $1;
$subcounter = 1;
print "DEBUG \$line matched SUB: $line
+\n"
if $debug eq 1;
next;
}
if ($subcounter eq 1) {
print "DEBUG \$subcounter ='s 1: $line
+\n"
if $debug eq 1;
if ($line =~ /}/) {
$subcounter = 0;
print "DEBUG found } so \$subc
+ounter ='s 0 now\n"
if $debug eq 1;
next;
}
else {
my $both = "$group:$sub";
if ($subhash{$both} eq "") {
$subhash{$both} = "$li
+ne";
print "DEBUG subhash \
+{$both\} = \"$line\"\n"
if $debug eq 1
+;
next;
}
else {
$subhash{$both} .= "!:
+!$line";
print "DEBUG subhash \
+{$both\} = \"!:!$line\"\n"
if $debug eq 1
+;
next;
}
}
}
}
}
my $type;
print "\n$host audit\n----------------------------\n";
print "GLOBALS\n";
while(my($k,$v) = each %globhash) {
my @stuff = split(/!:!/,$v);
my $worde;
my @matched = parsit($host,$k);
for (my $j=0; $j < @stuff; $j++) {
$stuff[$j] =~ /(.*?):(.*?)$/;
$type = $1;
$worde = $2;
my $knownthing = 0;
for (my $i=0; $i < @matched; $i++) {
$worde =~ s/^\s+//g;
$matched[$i] =~ s/^\s+//g;
$matched[$i] =~ s/\s+$//g;
if ($type eq "EXACT") {
if ($worde eq $matched[$i]) {
print "\tMATCHED EXACT
+: $k -- $matched[$i]\n" if $args{s};
splice(@matched, $i, 1
+);
splice(@stuff, $j, 1);
$j--;
$i--;
$knownthing = 1;
}
}
if ($type eq "INCLUDE") {
if ($matched[$i] =~ /$worde/)
+{
print "\tMATCHED REGEX
+: $k -- $matched[$i]\n" if $args{s};
splice(@matched, $i, 1
+);
splice(@stuff, $j, 1);
$j--;
$i--;
$knownthing = 1;
}
}
}
}
if ($args{f}) {
print "\tNOT IN TEMPLATE:\n";
foreach my $crap (@matched) {
next if $crap =~ /^\s+$/;
print "\t\t$crap\n";
}
}
print "\tNOT IN HOSTS JUNIPER.CONF:\n";
foreach my $crap (@stuff) {
next if $crap =~ /^\s+$/;
print "\t\t$crap\n";
}
}
print "\nSUBS\n";
my @stuff;
while(my($k,$v) = each %subhash) {
my ($intmatch) = 0;
my ($worde);
my ($ktmp);
my $haveint = 0;
@stuff = split(/!:!/,$v);
if ($k =~ /MATCH-INTERFACES (.*?)($|:(.*))/) {
my $devtype = $1;
my $whatelse = $2;
my @intnames = getintnames($host,$devtype);
foreach my $int (@intnames) {
$ktmp = $k;
$ktmp =~ s/MATCH-INTERFACES.*?($|:)/$i
+nt:/g;
getsubs(\@stuff,$host,$ktmp);
}
next;
}
else {
$ktmp = $k;
getsubs(\@stuff,$host,$ktmp);
next;
}
sub getsubs {
my ($stuff,$host,$k) = @_;
my @matched = parsit($host,$k);
for (my $j=0; $j < @$stuff; $j++) {
$stuff->[$j] =~ /(.*?):(.*?)$/;
$type = $1;
$worde = $2;
my $knownthing = 0;
for (my $i=0; $i < @matched; $i++) {
$worde =~ s/^\s+//g;
$matched[$i] =~ s/^\s+//g;
$matched[$i] =~ s/\s+$//g;
if ($type eq "EXACT") {
if ($worde eq $matched
+[$i]) {
print "\t\t\tM
+ATCHED EXACT: $k -- $matched[$i]\n" if $args{s};
splice(@matche
+d, $i, 1);
$i--;
$knownthing =
+1;
}
}
if ($type eq "INCLUDE") {
if ($matched[$i] =~ /$
+worde/) {
print "\t\t\tM
+ATCHED REGEX: $k -- $matched[$i]\n" if $args{s};
splice(@matche
+d, $i, 1);
$i--;
$knownthing =
+1;
}
}
}
print "\tNOT IN JUNIPER.CONF: $k -- $w
+orde\n" if !$knownthing;
}
if ($args{f}) {
foreach my $crap (@matched) {
next if $crap =~ /^\s+$/;
next if $crap eq "";
print "\t\tNOT IN TEMPLATE $k
+-- $crap\n";
}
}
}
}
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.