1# $Id: sonde-stp-catalyst.pl,v 1.1.1.1 2008/06/13 08:55:51 pda Exp $ 2# 3# 4# ################################################################### 5# boggia : Creation : 27/03/08 6# 7# fonctions qui permettent de r�cup�rer en SNMP l'etat du spanning 8# tree sur les commutateurs Cisco 9# 10# Resultats possibles de requetes : 11# 1 - disabled 12# 2 - blocking 13# 3 - listening 14# 4 - learning 15# 5 - forwarding 16# 6 - broken 17 18sub get_stp_catalyst 19{ 20 my ($base,$host,$community,$l_param) = @_; 21 22 my @fichier = (); 23 # teste si l'equipement est toujours en cours d'interrogation 24 #print "($host,$community,$l_param)\n"; 25 opendir(REPLOCK,$config{'dir_lock'}); 26 @fichier = grep(/$host/,readdir REPLOCK); 27 closedir(REPLOCK); 28 29 # si pas de lock 30 if(! $fichier[0]) 31 { 32 open(LOCK,">$config{'dir_lock'}/$host.lock"); 33 close(LOCK); 34 35 my $dir_result = "$config{'dir_res_stp'}"; 36 open(FICH,">$dir_result/$host"); 37 close(FICH); 38 39 my ($snmp, $error) = Net::SNMP->session( 40 -hostname => $host, 41 -community => $community, 42 -port => 161, 43 -timeout => $config{"snmp_timeout"}, 44 -retries => 2, 45 -nonblocking => 0x1, 46 -version => "2c" ); 47 48 if (!defined($snmp)) 49 { 50 #writelog("get_stp_catalyst",$config{syslog_facility},"info", 51 # "\t -> ERROR: SNMP connect error: $error"); 52 } 53 else 54 { 55 my $bridgeOid = "1.3.6.1.2.1.17.1.1.0"; 56 my $r = $snmp->get_request( 57 -varbindlist => [$bridgeOid], 58 -callback => [ \&get_snmp_bridge_id,$host,$community,$l_param,$bridgeOid] ); 59 } 60 61 unlink "$config{'dir_lock'}/$host.lock"; 62 } 63 else 64 { 65 #writelog("get_stp_catalyst",$config{syslog_facility},"info", 66 # "\t -> WARNING : $host toujours en cours d'interrogation"); 67 } 68} 69 70 71sub get_snmp_bridge_id 72{ 73 my ($session,$host,$communaute,$liste_vlans,$bridgeOid) = @_; 74 75 if (!defined($session->var_bind_list)) 76 #l'equipement ne repond pas 77 { 78 my $error = $session->error; 79 #writelog("get_stp_catalyst",$config{syslog_facility},"info", 80 # "\t -> ERROR: get_stp_catalyst($host) Error: $error"); 81 #print "ERROR: get_stp_catalyst($host) Error: $error\n"; 82 } 83 else 84 # l'equipement repond 85 { 86 # repertoire dans lequel seront stockes les resultats 87 my $elem; 88 89 my $bridgeId = $session->var_bind_list->{$bridgeOid}; 90 91 $bridgeId = set_Id2Mac($bridgeId); 92 93 $BridgeID{$bridgeId} = $host; 94 #print "\nget_snmp_bridge_id($host,$communaute) bridgeId = $bridgeId"; 95 96 my @vlans = split(/:/,$liste_vlans); 97 98 foreach $elem (@vlans) 99 { 100 if($elem=~/[0-9]+/) 101 { 102 #print "vlan $elem :\n"; 103 104 my $community = "$communaute\@$elem"; 105 106 my ($snmp, $error) = Net::SNMP->session( 107 -hostname => $host, 108 -community => $community, 109 -port => 161, 110 -timeout => $config{"snmp_timeout"}, 111 -retries => 2, 112 -nonblocking => 0x1, 113 -version => "2c" ); 114 115 if (!defined($snmp)) 116 { 117 #writelog("get_assoc_ap",$config{syslog_facility},"info", 118 # "\t -> ERROR: SNMP connect error: $error"); 119 #print "ERROR: SNMP connect error: $error\n"; 120 } 121 else 122 { 123 #recuperation de la racine du spanning Tree 124 my $rootBridgeOid = "1.3.6.1.2.1.17.2.5.0"; 125 my $r = $snmp->get_request( 126 -varbindlist => [$rootBridgeOid], 127 -callback => [ \&get_snmp_rootBridge,$host,$community,$elem,$rootBridgeOid,$bridgeId] ); 128 } 129 } 130 } 131 } 132} 133 134 135sub get_snmp_rootBridge 136{ 137 my ($session,$host,$community,$vlan,$rootBridgeOid,$bridgeId) = @_; 138 139 if (!defined($session->var_bind_list)) 140 #l'equipement ne repond pas 141 { 142 my $error = $session->error; 143 #writelog("get_stp_catalyst",$config{syslog_facility},"info", 144 # "\t -> ERROR: get_stp_catalyst($host) Error: $error"); 145 #print "ERROR: get_stp_catalyst($host) Error: $error\n"; 146 } 147 else 148 # l'equipement repond 149 { 150 # repertoire dans lequel seront stockes les resultats 151 my $rootBridgeId = $session->var_bind_list->{$rootBridgeOid}; 152 153 $rootBridgeId = set_Id2Mac($rootBridgeId); 154 155 #print "\nget_snmp_rootBridge($host,$community,$vlan,$rootBridgeOid) rootBridgeId = $rootBridgeId"; 156 #print "\nget_stp_catalyst($host) $bridgeId = $bridgeId"; 157 158 my ($snmp, $error) = Net::SNMP->session( 159 -hostname => $host, 160 -community => $community, 161 -port => 161, 162 -timeout => $config{"snmp_timeout"}, 163 -retries => 2, 164 -nonblocking => 0x1, 165 -version => "2c" ); 166 167 if (!defined($snmp)) 168 { 169 #writelog("get_assoc_ap",$config{syslog_facility},"info", 170 # "\t -> ERROR: SNMP connect error: $error"); 171 ##print "ERROR: SNMP connect error: $error\n"; 172 } 173 else 174 { 175 #recuperation du Root Port 176 my $rootPortOid = "1.3.6.1.2.1.17.2.7.0"; 177 my $r = $snmp->get_request( 178 -varbindlist => [$rootPortOid], 179 -callback => [ \&get_snmp_rootPort,$host,$community,$vlan,$rootPortOid,$bridgeId,$rootBridgeId] ); 180 } 181 } 182} 183 184 185sub get_snmp_rootPort 186{ 187 my ($session,$host,$community,$vlan,$rootPortOid,$bridgeId,$rootBridgeId) = @_; 188 189 if (!defined($session->var_bind_list)) 190 #l'equipement ne repond pas 191 { 192 my $error = $session->error; 193 #writelog("get_stp_catalyst",$config{syslog_facility},"info", 194 # "\t -> ERROR: get_stp_catalyst($host) Error: $error"); 195 #print "ERROR: get_stp_catalyst($host) Error: $error\n"; 196 } 197 else 198 # l'equipement repond 199 { 200 my $rootPort = $session->var_bind_list->{$rootPortOid}; 201 #print "\nget_stp_catalyst($host) $bridgeId = $bridgeId"; 202 203 my ($snmp, $error) = Net::SNMP->session( 204 -hostname => $host, 205 -community => $community, 206 -port => 161, 207 -timeout => $config{"snmp_timeout"}, 208 -retries => 2, 209 -nonblocking => 0x1, 210 -version => "2c" ); 211 212 if (!defined($snmp)) 213 { 214 #writelog("get_assoc_ap",$config{syslog_facility},"info", 215 # "\t -> ERROR: SNMP connect error: $error"); 216 #print "ERROR: SNMP connect error: $error\n"; 217 } 218 else 219 { 220 my $state_oid = '1.3.6.1.2.1.17.2.15.1.3'; 221 my $res = $snmp->get_table( 222 $state_oid, 223 -callback => [ \&get_snmp_port_state,$host,$community,$vlan,$state_oid,$bridgeId,$rootBridgeId,$rootPort] ); 224 } 225 } 226} 227 228 229sub get_snmp_port_state 230{ 231 my ($session,$host,$community,$vlan,$state_oid,$bridgeId,$rootBridgeId,$rootPort) = @_; 232 233 if(defined($session->var_bind_list())) 234 { 235 # Extract the response. 236 my $key = ''; 237 my $hashref = $session->var_bind_list(); 238 my $compteur = 0; 239 240 my $dir_result = "$config{'dir_res_stp'}"; 241 open(FICH,">>$dir_result/$host"); 242 243 print FICH "\nVlan$vlan bridgeId=$bridgeId\n"; 244 print FICH "Vlan$vlan rootBridgeId=$rootBridgeId ($BridgeID{$rootBridgeId})\n"; 245 246 $stpInfos{"$host:$vlan:bridgeId"} = $bridgeId; 247 $stpInfos{"$host:$vlan:rootBridgeId"} = $rootBridgeId; 248 249 my $param = $community."@".$host; 250 251 foreach $key (keys %$hashref) 252 { 253 my $nom_interf; 254 255 $compteur ++; 256 chomp($key); 257 258 my @decomp_oid = split(/\./,$key); 259 my $index_stp_if = pop(@decomp_oid); 260 my $etat = $$hashref{$key}; 261 262 my $indexif = "1.3.6.1.2.1.17.1.4.1.2.$index_stp_if"; 263 264 &snmpmapOID("indexif","1.3.6.1.2.1.17.1.4.1.2.$index_stp_if"); 265 my @desc_inter = &snmpget($param, "indexif"); 266 267 &snmpmapOID("index","1.3.6.1.2.1.2.2.1.2.$desc_inter[0]"); 268 my @nom_inter = &snmpget($param, "index"); 269 270 print FICH "Vlan$vlan $nom_inter[0]"; 271 272 my $nom_etat; 273 if($etat == 1) 274 { 275 print FICH "\tdisabled"; 276 $nom_etat = "disabled"; 277 } 278 elsif($etat == 2) 279 { 280 print FICH "\tblocking"; 281 $nom_etat = "blocking"; 282 } 283 elsif($etat == 3) 284 { 285 print FICH "\tlistening"; 286 $nom_etat = "listening"; 287 } 288 elsif($etat == 4) 289 { 290 print FICH "\tlearning"; 291 $nom_etat = "learning"; 292 } 293 elsif($etat == 5) 294 { 295 print FICH "\tforwarding"; 296 $nom_etat = "forwarding"; 297 } 298 elsif($etat == 6) 299 { 300 print FICH "\tbroken"; 301 $nom_etat = "broken"; 302 } 303 if($index_stp_if == $rootPort) 304 { 305 print FICH "\t-> root\n"; 306 $stpInfos{"$host:$vlan:rootPort"} = $nom_inter[0]; 307 } 308 else 309 { 310 print FICH "\n"; 311 } 312 $stpPorts{"$host:$vlan:$nom_inter[0]"} = $nom_etat; 313 } 314 close (FICH); 315 316 if($compteur == 0) 317 { 318 #print "WARNING : $host, $vlan : aucun port actif dans l'instance de STP\n"; 319 } 320 } 321 else 322 { 323 #print "ERROR: get_stp_catalyst($host,$community) : etat des ports du STP, pas de reponse\n"; 324 } 325} 326 327 328 329sub compare_stp_state 330{ 331 my ($key,$key2); 332 open(FICH,">$config{'dir_res_stp'}/stp.output.tmp"); 333 334 foreach $key (keys %stpInfos) 335 { 336 if($key=~/(.*):(.*):bridgeId/) 337 { 338 print FICH "\n"; 339 print FICH "$1:$2:bridgeId = $stpInfos{\"$1:$2:bridgeId\"}\n"; 340 print FICH "$1:$2:rootBridgeId = $stpInfos{\"$1:$2:rootBridgeId\"}($BridgeID{$stpInfos{\"$1:$2:rootBridgeId\"}})\n"; 341 if(defined($stpInfos{"$1:$2:rootPort"})) 342 { 343 print FICH "$1:$2:rootPort = $stpInfos{\"$1:$2:rootPort\"}\n"; 344 } 345 else 346 { 347 print FICH "$1:$2:bridgeId = AUCUN\n"; 348 } 349 350 my $host = $1; 351 my $vlan = $2; 352 foreach $key2 (keys %stpPorts) 353 { 354 if($key2=~/$host:$vlan:(.*)/) 355 { 356 print FICH "$host:$vlan:$1 = $stpPorts{\"$host:$vlan:$1\"}\n"; 357 } 358 } 359 } 360 } 361 close(FICH); 362 363 system("sort -t: +1n +0d $config{'dir_res_stp'}/stp.output > $config{'dir_res_stp'}/stp.output.sorted"); 364 system("sort -t: +1n +0d $config{'dir_res_stp'}/stp.output.tmp > $config{'dir_res_stp'}/stp.output.tmp.sorted"); 365 366 my $message = "Alertes Spanning Tree\n\n"; 367 my $res = `diff -u $config{'dir_res_stp'}/stp.output.sorted $config{'dir_res_stp'}/stp.output.tmp.sorted`; 368 369 if($res ne "") 370 { 371 $message = "$message $res"; 372 #print "$message"; 373 #system("echo \"$message\" | mail -s \"[AUTO] Spanning Tree Topo changes\" seb\@crc.u-strasbg.fr"); 374 system("mv $config{'dir_res_stp'}/stp.output.tmp $config{'dir_res_stp'}/stp.output"); 375 } 376} 377 378 379return 1; 380 381 382 383