vlandiff.in 2.86 KB
Newer Older
1
#!/usr/bin/perl -w
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2 3 4 5 6 7 8

#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002 University of Utah and the Flux Group.
# All rights reserved.
#

9
use Getopt::Std;
10 11 12 13
#
# vlandiff - Show differences between switch state and vlan table, if any
#

14 15 16
#
# Configure variables
#
17
$ENV{'PATH'} = '@prefix@/sbin:@prefix@/bin:/bin';
18 19
use lib '@prefix@/lib';
use libdb;
20

21 22
my %opt = ();
getopts('v',\%opt);
23

24 25 26 27
my $debug = 0;
if ($opt{v}) {
    $debug = 1;
}
28

29 30 31
if (@ARGV) {
    die "Usage: $0 [-v]\n";
}
32 33 34

my %table = ();
my %switch= ();
35
my %id = ();
36 37 38

# Get all the vlans from the table

39 40
my $result = DBQueryFatal("select id,members from vlans");
while (@row = $result->fetchrow_array()) {
41 42 43
    my ($vlan_id, $members) = @row;
    my @list = split(" ",$members);

44 45 46 47 48 49
    foreach $port (@list) {
	my ($node,$card) = split(":",$port);
	if ($card =~ /[a-zA-Z]/) {
	    # specified ala ethX
	    my $result2 = DBQueryFatal("select card from interfaces ".
		    "where node_id='$node' and iface='$card'");
50 51
	    ($card) = $result2->fetchrow_array();
	    debug("Had '$port', changed to '$node:$card'\n");
52 53
	    $port = "$node:$card";
	}
54
    }
55 56 57

    $table{$vlan_id} = \@list;
    debug("In table: vlan $vlan_id: $table{$vlan_id}\n");
58 59 60 61 62
}

# Get all the vlans from the switch

my $list;
63
my $vlan=0;
64 65
open(LIST,"snmpit -l |") || die ("vlandiff: couldn't run snmpit: $!\n");
while(<LIST>) {
66
    chop;
67 68 69 70 71 72 73 74 75 76 77

    # Skip heaer lines
    if (/(^VLAN)|(^--)/) { next; }

    # Ignore the pid/eid and vlan_name
    if ( /^(\S+)\s+\S*\s+\S*\s+(.*)$/ ) {
	my $vlan_id = $1;
	my $members = $2;
	debug("VLAN id $vlan_id has members $members\n");
	$switch{$vlan_id} = [ split(" ",$members) ];
	$vlan = $vlan_id;
78
    } elsif ( /^\s+(.*)?$/ ) {
79 80 81 82 83
	# These lines are continuations of multi-line meber lists
	my $members = $1;
	if (!defined $members) { $list = ""; } else { $list = $members; }
	push @{$switch{$vlan}}, split(" ",$list);
	debug("On switch: vlan $vlan: $switch{$vlan}\n");
84
    }
85 86 87 88 89 90
}
close(LIST);

# Compare all of them...

foreach $key (sort keys %table) {
91 92 93 94 95 96 97 98
    if ( defined $switch{$key} ) {
	# Hacky 'one liner' list comparison
	if (join("\0",sort(@{$switch{$key}}))
		eq join("\0",sort(@{$table{$key}}))) {
	    # If its in both lists, delete it from both
	    debug("vlan table:$key ($table{$key}) matches switch:$key ($switch{$key})\n");
	    delete $switch{$key};
	    delete $table{$key};
99 100
	}
    }
101 102 103 104 105 106 107
}

# Print out the difference

my $rv = 0;

if (keys %table) {
108 109
    print "In vlans table only:\n";
    foreach $key(sort keys %table) {
110
	print "$key\t", join(" ",@{$table{$key}}), "\n";
111 112
    }
    $rv++;
113 114 115
}

if (keys %switch) {
116 117
    print "On switch only:\n";
    foreach $key(sort keys %switch) {
118
	print "$key\t", join(" ",@{$switch{$key}}), "\n";
119 120
    }
    $rv++;
121 122
}

123
debug("Exiting with value $rv\n");
124 125


126 127 128
# Return 0 if same, 1 for a one-sided diff, 2 for a two-sided diff
# (Could be changed to return total # of different vlans)
exit($rv);
129 130 131 132 133 134

sub debug(@) {
    if ($debug) {
	warn @_;
    }
}