1package nxos; 2## 3## @PACKAGE@ @VERSION@ 4@copyright@ 5# 6# RANCID - Really Awesome New Cisco confIg Differ 7# 8# nxos.pm - Cisco NX-OS rancid procedures 9 10use 5.010; 11use strict 'vars'; 12use warnings; 13no warnings 'uninitialized'; 14require(Exporter); 15our @ISA = qw(Exporter); 16 17use rancid @VERSION@; 18 19our $proc; 20our $type; # device model, from ShowVersion 21 22our $C0; # output formatting control 23our $E0; 24our $H0; 25our $DO_SHOW_VLAN; 26 27@ISA = qw(Exporter rancid main); 28#XXX @Exporter::EXPORT = qw($VERSION @commandtable %commands @commands); 29 30# load-time initialization 31sub import { 32 0; 33} 34 35# post-open(collection file) initialization 36sub init { 37 $proc = ""; 38 $type = undef; # device model, from ShowVersion 39 40 $C0 = 0; # output formatting control 41 $E0 = 0; 42 $H0 = 0; 43 $DO_SHOW_VLAN = 1; 44 45 # add content lines and separators 46 ProcessHistory("","","","!RANCID-CONTENT-TYPE: $devtype\n!\n"); 47 ProcessHistory("COMMENTS","keysort","B0","!\n"); 48 ProcessHistory("COMMENTS","keysort","D0","!\n"); 49 ProcessHistory("COMMENTS","keysort","F0","!\n"); 50 ProcessHistory("COMMENTS","keysort","G0","!\n"); 51 52 0; 53} 54 55# main loop of input of device output 56sub inloop { 57 my($INPUT, $OUTPUT) = @_; 58 my($cmd, $rval); 59 60TOP: while(<$INPUT>) { 61 tr/\015//d; 62 63 if (/[>#]\s?exit$/) { 64 print STDERR ("$host: found exit\n") if ($debug); 65 $clean_run = 1; 66 last; 67 } 68 if (/^Error:/) { 69 print STDOUT ("$host clogin error: $_"); 70 print STDERR ("$host clogin error: $_") if ($debug); 71 $clean_run = 0; 72 last; 73 } 74 while (/#\s*($cmds_regexp)\s*$/) { 75 $cmd = $1; 76 if (!defined($prompt)) { 77 $prompt = ($_ =~ /^([^#]+#)/)[0]; 78 $prompt =~ s/([][}{)(\\])/\\$1/g; 79 print STDERR ("PROMPT MATCH: $prompt\n") if ($debug); 80 } 81 print STDERR ("HIT COMMAND:$_") if ($debug); 82 if (! defined($commands{$cmd})) { 83 print STDERR "$host: found unexpected command - \"$cmd\"\n"; 84 $clean_run = 0; 85 last TOP; 86 } 87 if (! defined(&{$commands{$cmd}})) { 88 printf(STDERR "$host: undefined function - \"%s\"\n", 89 $commands{$cmd}); 90 $clean_run = 0; 91 last TOP; 92 } 93 $rval = &{$commands{$cmd}}($INPUT, $OUTPUT, $cmd); 94 delete($commands{$cmd}); 95 if ($rval == -1) { 96 $clean_run = 0; 97 print STDERR ("$host: $cmd failed: $rval\n") if ($debug); 98 last TOP; 99 } 100 if (/[>#]\s?exit$/) { 101 print STDERR ("$host: found exit\n") if ($debug); 102 $clean_run = 1; 103 last TOP; 104 } 105 } 106 } 107} 108 109# This routine parses "show version" 110sub ShowVersion { 111 my($INPUT, $OUTPUT, $cmd) = @_; 112 print STDERR " In ShowVersion: $_" if ($debug); 113 114 while (<$INPUT>) { 115 tr/\015//d; 116 last if (/^$prompt/); 117 next if (/^(\s*|\s*$cmd\s*)$/); 118 return(1) if /Line has invalid autocommand /; 119 return(1) if /(Invalid input detected|Type help or )/; 120 return(-1) if (/\% Invalid command at /); 121 return(-1) if (/No token match at /); # 1000v 122 return(-1) if (/\% Permission denied/); 123 return(-1) if (/command authorization failed/i); 124 125 if (/^Cisco (Nexus|Storage Area Networking) Operating System/) { $type = "NXOS";} 126 if (/^Software$/) { 127 while (<$INPUT>) { 128 tr/\015//d; 129 last if (/^$prompt/); 130 next if (/^\s*$cmd\s*$/); 131 132 if (/^$/) { 133 goto EndSoftware; 134 } 135 /\s*([^:]*:)\s*(.*)$/ && 136 ProcessHistory("COMMENTS","keysort","C1", 137 "!Software: $1 $2\n") && next; 138 } 139 } 140EndSoftware: 141 if (/^Hardware$/) { 142 while (<$INPUT>) { 143 tr/\015//d; 144 last if (/^$prompt/); 145 next if (/^\s*$cmd\s*$/); 146 147 if (/^\s*cisco (Nexus[ \d]+) /) { 148 # cisco Nexus7000 C7010 (10 Slot) Chassis ("Supervisor module-1X") 149 # cisco Nexus7000 C7018 (18 Slot) Chassis ("Supervisor module-1X") 150 # cisco Nexus5548 Chassis ("O2 32X10GE/Modular Supervisor") 151 # cisco Nexus 4000 Chassis ("20x10GE/supervisor") 152 $proc = $1; 153 } 154 155 if (/^$/) { 156 goto EndHardware; 157 } 158 if (/^\s*(.*) CPU\s*with (\d*) kB(.*)$/) { 159 my($tmp) = int($2 / 1024); 160 ProcessHistory("COMMENTS","keysort","A2", 161 "!Hardware: $1 CPU with $tmp MB$3\n"); 162 next; 163 } 164 if (/^\s*(.*)\s*with (\d*) kB(.*)$/) { 165 my($tmp) = int($2 / 1024); 166 ProcessHistory("COMMENTS","keysort","A2", 167 "!Hardware: $1with $tmp MB$3\n"); 168 next; 169 } 170 /^\s*(.*)$/ && 171 ProcessHistory("COMMENTS","keysort","A2", 172 "!Hardware: $1\n") && next; 173 } 174 } 175EndHardware: 176 if (/^\s+(bootflash|slot0):\s+(\d+) kB(.*)$/) { 177 my($tmp) = int($2 / 1024); 178 ProcessHistory("COMMENTS","keysort","B1", 179 "!Memory: $1: $tmp MB$3\n"); 180 next; 181 } 182 183 } 184 185 print STDERR "TYPE = $type\n" if ($debug); 186 # XXX $proc is never set 187 ProcessHistory("COMMENTS","keysort","A1", 188 "!Chassis type: $proc - a $type router\n"); 189 ProcessHistory("COMMENTS","keysort","B0", "!\n"); 190 ProcessHistory("COMMENTS","keysort","C0", "!\n"); 191 ProcessHistory("COMMENTS","","", "!\n"); 192 return(0); 193} 194 195# This routine parses "show version build-info" 196sub ShowVersionBuild { 197 my($INPUT, $OUTPUT, $cmd) = @_; 198 print STDERR " In ShowVersionBuild: $_" if ($debug); 199 200 while (<$INPUT>) { 201 tr/\015//d; 202 last if (/^$prompt/); 203 next if (/^(\s*|\s*$cmd\s*)$/); 204 return(1) if /Line has invalid autocommand /; 205 return(1) if /(Invalid input detected|Type help or )/; 206 return(1) if (/\% Invalid command at /); 207 return(1) if (/No token match at /); # 1000v 208 return(-1) if (/\% Permission denied/); 209 return(-1) if (/command authorization failed/i); 210 211 /^Built By / && ProcessHistory("COMMENTS","","", "!Build: $_"); 212 /^On Date / && ProcessHistory("COMMENTS","","", "!Build: $_"); 213 /^From Tree / && ProcessHistory("COMMENTS","","", "!Build: $_"); 214 /^Base Tag / && ProcessHistory("COMMENTS","","", "!Build: $_"); 215 /^Release for / && ProcessHistory("COMMENTS","","", "!Build: $_"); 216 } 217 ProcessHistory("COMMENTS","","","!\n"); 218 return(0); 219} 220 221# This routine parses "show license *" 222sub ShowLicense { 223 my($INPUT, $OUTPUT, $cmd) = @_; 224 print STDERR " In ShowLicense: $_" if ($debug); 225 226 while (<$INPUT>) { 227 tr/\015//d; 228 last if (/^$prompt/); 229 next if (/^(\s*|\s*$cmd\s*)$/); 230 return(1) if /(Invalid input detected|Type help or )/; 231 return(1) if (/\% Invalid command at /); 232 return(-1) if (/No token match at /); # 1000v 233 return(-1) if (/\% Permission denied/); 234 return(-1) if (/command authorization failed/i); 235 236 /^-+$/ && next; # Skip lines of all dashes. 237 s/ Grace .+$/ Grace/; # Drop anything after Grace. 238 ProcessHistory("COMMENTS","","", "!LIC: $_"); 239 } 240 ProcessHistory("COMMENTS","","","!\n"); 241 return(0); 242} 243 244# This routine parses "show system redundancy status" 245sub ShowRedundancy { 246 my($INPUT, $OUTPUT, $cmd) = @_; 247 print STDERR " In ShowRedundancy: $_" if ($debug); 248 249 while (<$INPUT>) { 250 tr/\015//d; 251 last if (/^$prompt/); 252 next if (/^(\s*|\s*$cmd\s*)$/); 253 return(1) if /Line has invalid autocommand /; 254 return(1) if /(Invalid input detected|Type help or )/; 255 return(1) if (/\% Invalid command at /); 256 return(1) if (/.* command is not support/i); 257 return(-1) if (/No token match at /); # 1000v 258 return(-1) if (/\% Permission denied/); 259 return(-1) if (/command authorization failed/i); 260 261 s/ +$//; # Drop trailing ' ' 262 ProcessHistory("COMMENTS","","","!Red: $_"); 263 } 264 ProcessHistory("COMMENTS","","","!\n"); 265 return(0); 266} 267 268# This routine parses "show environment" 269sub ShowEnv { 270 my($INPUT, $OUTPUT, $cmd) = @_; 271 print STDERR " In ShowEnv: $_" if ($debug); 272 273 while (<$INPUT>) { 274 tr/\015//d; 275 last if (/^$prompt/); 276 next if (/^(\s*|\s*$cmd\s*)$/); 277 next if (/^\s*\^\s*$/); 278 return(1) if /Line has invalid autocommand /; 279 return(1) if /(Invalid input detected|Type help or )/; 280 return(1) if (/\% Invalid command at /); 281 return(1) if (/ .* command is not support/i); 282 return(1) if (/No token match at /); # 1000v 283 return(-1) if (/\% Permission denied/); 284 return(-1) if (/command authorization failed/i); 285 286 s/ +$//; # Drop trailing ' ' 287 next if (/Fan Zone Speed:/); 288 if (/(control temperature|monitor temperature)/i) { 289 ProcessHistory("COMMENTS","","","!Env: $_"); 290 while (<$INPUT>) { 291 tr/\015//d; 292 goto EndShowEnv if (/^$prompt/); 293 if (/(.*\s+\d+\s+\d+\s+)(\d+)(.*$)/) { 294 $_ = sprintf("%s%-". length($2)."s%s\n", $1, "", $3); 295 } 296 ProcessHistory("COMMENTS","","","!Env: $_"); 297 last if (/^\s*$/); 298 } 299 next; 300 } 301 ProcessHistory("COMMENTS","","","!Env: $_"); 302 } 303EndShowEnv: 304 ProcessHistory("COMMENTS","","","!\n"); 305 return(0); 306} 307 308# This routine parses "show environment temperature" 309sub ShowEnvTemp { 310 my($INPUT, $OUTPUT, $cmd) = @_; 311 print STDERR " In ShowEnvTemp: $_" if ($debug); 312 313 while (<$INPUT>) { 314 tr/\015//d; 315 last if (/^$prompt/); 316 next if (/^(\s*|\s*$cmd\s*)$/); 317 return(1) if /Line has invalid autocommand /; 318 return(1) if /(Invalid input detected|Type help or )/; 319 return(1) if (/No token match at /); # 1000v 320 return(1) if (/\% Invalid command at /);# 1000v has no support 321 return(-1) if (/\% Permission denied/); 322 return(-1) if (/command authorization failed/i); 323 324 s/ +$//; # Drop trailing spaces 325 326# Cut out CurTemp - drop the 2nd to last field. 327#-------------------------------------------------------------------- 328#Module Sensor MajorThresh MinorThres CurTemp Status 329# (Celsius) (Celsius) (Celsius) 330#5 Outlet1 (s1) 125 125 33 Ok 331#5 QEng1Sn1(s10) 115 105 39 Ok 332 if (/(control temperature|monitor temperature)/i) { 333 ProcessHistory("COMMENTS","","","!Env: $_"); 334 while (<$INPUT>) { 335 tr/\015//d; 336 goto EndShowEnvTemp if (/^$prompt/); 337 if (/(.*\s+\d+\s+\d+\s+)(\d+)(.*$)/) { 338 $_ = sprintf("%s%-". length($2)."s%s\n", $1, "", $3); 339 } 340 ProcessHistory("COMMENTS","","","!Env: $_"); 341 last if (/^\s*$/); 342 } 343 next; 344 } else { 345 next if (/INTAKE/); 346 next if (/ASIC/); 347 s/^(.+\s)(\S+\s+)(\S+\s*)$/$1$3/; 348 s/ +$//; # Drop trailing ' ' 349 ProcessHistory("COMMENTS","","","!Env: $_"); 350 } 351 } 352EndShowEnvTemp: 353 ProcessHistory("COMMENTS","","","!\n"); 354 return(0); 355} 356 357# This routine parses "show environment power" 358sub ShowEnvPower { 359 my($INPUT, $OUTPUT, $cmd) = @_; 360 print STDERR " In ShowEnvPower: $_" if ($debug); 361 362 while (<$INPUT>) { 363 tr/\015//d; 364 last if (/^$prompt/); 365 next if (/^(\s*|\s*$cmd\s*)$/); 366 next if (/^\s*\^\s*$/); 367 return(1) if /Line has invalid autocommand /; 368 return(1) if /(Invalid input detected|Type help or )/; 369 return(1) if (/\% Invalid command at /); 370 return(1) if (/No token match at /); # 1000v 371 return(-1) if (/\% Permission denied/); 372 return(-1) if (/command authorization failed/i); 373 374# Filter Actual Output/Draw. 375#Power Actual Total 376#Supply Model Output Capacity Status 377# (Watts ) (Watts ) 378#------- ------------------- ----------- ----------- -------------- 379#1 ------------ 0 W 0 W Absent 380#3 749 W 5480 W Ok 381# Actual Power 382#Module Model Draw Allocated Status 383# (Watts ) (Watts ) 384#------- ------------------- ----------- ----------- -------------- 385#2 NURBURGRING N/A 573 W Powered-Up 386#fan1 N/A 720 W Powered-Up 387# 388# ELSE 389# 390# nexus# sh environment power 391# Power Supply: 392# Voltage: 12 Volts 393# Power Actual Actual Total 394# Supply Model Output Input Capacity Status 395# (Watts ) (Watts ) (Watts ) 396# ------- ------------------- ---------- ---------- ---------- 397# -------------- 398# 1 N9K-PAC-650W-B 65 W 76 W 649 W Ok 399# 2 N9K-PAC-650W-B 70 W 84 W 649 W Ok 400# 401# 402# Power Usage Summary: 403# -------------------- 404# Power Supply redundancy mode (configured) PS-Redundant 405# Power Supply redundancy mode (operational) PS-Redundant 406# 407# Total Power Capacity (based on configured mode) 649.92 W 408# Total Grid-A (first half of PS slots) Power Capacity 649.92 W 409# Total Grid-B (second half of PS slots) Power Capacity 649.92 W 410# Total Power of all Inputs (cumulative) 1299.84 W 411# Total Power Output (actual draw) 136.00 W 412# Total Power Input (actual draw) 161.00 W 413# Total Power Allocated (budget) N/A 414# Total Power Available for additional modules N/A 415# 416# nexus# 417 if (/(.* +)(\d+ W +\d+ W)( +\d+ W.+)/) { 418 $_ = sprintf("%s%-". length($2)."s%s\n", $1, "", $3); 419 } elsif (/(.* +)(\d+(\.\d+)? W)( +\d+(\.\d+)? W.+)/) { 420 $_ = sprintf("%s%-". length($2)."s%s\n", $1, "", $4); 421 } 422 423 /actual draw/ && next; # Drop changing total power output. 424 425 s/ +$//; # Drop trailing ' ' 426 ProcessHistory("COMMENTS","","","!Env: $_"); 427 } 428 ProcessHistory("COMMENTS","","","!\n"); 429 return(0); 430} 431 432# This routine parses "show boot" 433sub ShowBoot { 434 my($INPUT, $OUTPUT, $cmd) = @_; 435 print STDERR " In ShowBoot: $_" if ($debug); 436 437 while (<$INPUT>) { 438 tr/\015//d; 439 last if (/^$prompt/); 440 next if (/^(\s*|\s*$cmd\s*)$/); 441 return(1) if /^\s*\^\s*$/; 442 return(1) if /Line has invalid autocommand /; 443 return(1) if /(Invalid input detected|Type help or )/; 444 return(1) if /Ambiguous command/i; 445 return(-1) if (/\% Invalid command at /); 446 return(-1) if (/No token match at /); # 1000v 447 return(-1) if (/\% Permission denied/); 448 return(-1) if (/command authorization failed/i); 449 450 s/ variable = / = /; 451 ProcessHistory("COMMENTS","","","!Variable: $_"); 452 } 453 ProcessHistory("COMMENTS","","","!\n"); 454 return(0); 455} 456 457# This routine parses "dir /all ((disk|slot)N|bootflash|nvram):" 458sub DirSlotN { 459 my($INPUT, $OUTPUT, $cmd) = @_; 460 print STDERR " In DirSlotN: $_" if ($debug); 461 my($free); 462 463 my($dev) = (/\s([^\s]+):/); 464 465 while (<$INPUT>) { 466 tr/\015//d; 467 last if (/^$prompt/); 468 next if (/^(\s*|\s*$cmd\s*)$/); 469 return(1) if /^\s*\^\s*$/; 470 return(1) if /Line has invalid autocommand /; 471 return(1) if /(Invalid input detected|Type help or )/; 472 return(1) if (/\% Invalid command at /); 473 return(1) if /(No such device|Error Sending Request)/i; 474 return(1) if /No such file or directory/; 475 return(1) if /No space information available/; 476 return(1) if / is either not present or not formatted/; 477 return(-1) if /\%Error calling/; 478 return(-1) if /(: device being squeezed|ATA_Status time out)/i; # busy 479 return(-1) if (/\% Permission denied/); 480 return(-1) if (/command authorization failed/i); 481 return(1) if /(Open device \S+ failed|Error opening \S+:)/; 482 483 # Drop ee.log 484 /\s+ee\.log(?:\..*)?$/ && next; 485 486 # Drop bootvar_debug log files 487 /\s+bootvar_debug\./ && next; 488 489 # Drop accounting.log* 490 /\s+accounting.log.*/ && next; 491 492 # Drop vtp_debug.log and vtp_debug_old.log CDETS bug CSCuy87611 493 /\s+vtp_debug(_old)?\.log$/ && next; 494 495 # Drop bcm_mem_lock_trace.log 496 /\s+bcm_mem_lock_trace\.log$/ && next; 497 498 next if (/BufferMonitor-1HourData/); 499 500 if (/( debug_logs| log)\/$/) { 501 # change 502 # 8192 Jan 08 14:05:05 2015 log/ 503 # to 504 # log/ 505 if (/(\s*\d+\s+)(\S+ \d+\s+\d+:\d+:\d+ \d+)(.*)/) { 506 my($a, $dt, $rem) = ($1, $2, $3); 507 my($dtl) = length($dt); 508 my($fmt) = "%s%-". $dtl ."s%s\n"; 509 $_ = sprintf($fmt, $a, "", $rem); 510 } 511 } 512 513 if (/^\s*(\d+) bytes free/i) { 514 $free = $1; 515 next; 516 } elsif (/^\s*(\d+) bytes used/i) { 517 next; 518 } elsif (/^\s*(\d+) bytes total/i) { 519 $_ = diskszsummary($1, $free, undef) . "\n"; 520 } 521 522 ProcessHistory("COMMENTS","","","!Flash: $dev: $_"); 523 } 524 ProcessHistory("COMMENTS","","","!\n"); 525 return(0); 526} 527 528# This routine parses "show module". 529sub ShowModule { 530 my($INPUT, $OUTPUT, $cmd) = @_; 531 print STDERR " In ShowModule: $_" if ($debug); 532 533 while (<$INPUT>) { 534 tr/\015//d; 535 return if (/^\s*\^$/); 536 last if (/online diag status/i); 537 last if (/^$prompt/); 538 next if (/^\s*$cmd\s*$/); 539 return(1) if (/\% Invalid command at /); 540 return(1) if (/\% Invalid number at /); 541 return(-1) if (/\% Permission denied/); 542 return(-1) if (/command authorization failed/i); 543 544 s/(.*) \*$/$1/; # Drop a trailing '*' 545 /^\* this terminal session/ && next; 546 s/ +$//; # Drop trailing ' ' 547 548 # filter fluctuating WWNs 549 if (/\s+World-Wide-Name.*/i) { 550 ProcessHistory("COMMENTS","","","!Mod: $_"); 551 while (<$INPUT>) { 552 tr/\015//d; 553 goto EndShowModule if (/^$prompt/); 554 last if (/^\s*$/); 555 if (/^(\d+\s+\S+\s+\S+)\s+.*$/) { 556 $_ = sprintf("%s\n", $1); 557 } 558 ProcessHistory("COMMENTS","","","!Mod: $_"); 559 } 560 } 561 ProcessHistory("COMMENTS","","","!Mod: $_"); 562 } 563EndShowModule: 564 ProcessHistory("COMMENTS","","","!\n"); 565 566 return(0); 567} 568 569# This routine parses "show interface transceiver". 570sub ShowIntTransceiver { 571 my($INPUT, $OUTPUT, $cmd) = @_; 572 print STDERR " In ShowtTransceiver: $_" if ($debug); 573 574 while (<$INPUT>) { 575 tr/\015//d; 576 return if (/^\s*\^$/); 577 last if (/^$prompt/); 578 next if (/^(\s*|\s*$cmd\s*)$/); 579 return(1) if /Line has invalid autocommand /; 580 return(1) if /(Invalid input detected|Type help or )/; 581 return(1) if (/\% Invalid command at /); 582 return(-1) if (/No token match at /); # 1000v 583 return(-1) if (/\% Permission denied/); 584 return(-1) if (/command authorization failed/i); 585 586 # filter out oscillating data from transceivers 587 next if (/(Temperature|Current|Power|Voltage)\s+:/); 588 589 ProcessHistory("COMMENTS","","","!$_"); 590 } 591 ProcessHistory("COMMENTS","","","!\n"); 592 593 return(0); 594} 595 596# This routine parses "show inventory". 597sub ShowInventory { 598 my($INPUT, $OUTPUT, $cmd) = @_; 599 print STDERR " In ShowInventory: $_" if ($debug); 600 601 while (<$INPUT>) { 602 tr/\015//d; 603 return if (/^\s*\^$/); 604 last if (/^$prompt/); 605 next if (/^(\s*|\s*$cmd\s*)$/); 606 return(1) if /Line has invalid autocommand /; 607 return(1) if /(Invalid input detected|Type help or )/; 608 return(1) if (/\% Invalid command at /); 609 return(-1) if (/No token match at /); # 1000v 610 return(-1) if (/\% Permission denied/); 611 return(-1) if (/command authorization failed/i); 612 613 if (/^(NAME: "[^"]*",)\s+(DESCR: "[^"]+")/) { 614 ProcessHistory("COMMENTS","","", sprintf("!%-30s %s\n", $1, $2)); 615 next; 616 } 617 # split PID/VID/SN line 618 if (/^PID: (\S*)\s*,\s+VID: (\S*)\s*,\s+SN: (\S*)\s*$/) { 619 my($entries) = ""; 620 $entries .= "!PID: $1\n" if ($1); 621 $entries .= "!VID: $2\n" if ($2); 622 $entries .= "!SN: $3\n" if ($3); 623 ProcessHistory("COMMENTS","","", "$entries"); 624 next; 625 } 626 # split broken PID/VID/SN lines. 627 if (/^PID: (\S*)\s*,\s+VID: (\S*)\s*$/) { 628 my($entries) = ""; 629 $entries .= "!PID: $1\n" if ($1); 630 $entries .= "!VID: $2\n" if ($2); 631 <$INPUT>; 632 tr/\015//d; 633 /^\s*,\s+SN: (\S*)\s*$/; 634 $entries .= "!SN: $1\n" if ($1); 635 ProcessHistory("COMMENTS","","", "$entries"); 636 next; 637 } 638 ProcessHistory("COMMENTS","","","!$_"); 639 } 640 ProcessHistory("COMMENTS","","","!\n"); 641 642 return(0); 643} 644 645# This routine parses "show vtp status" 646sub ShowVTP { 647 my($INPUT, $OUTPUT, $cmd) = @_; 648 print STDERR " In ShowVTP: $_" if ($debug); 649 650 while (<$INPUT>) { 651 tr/\015//d; 652 last if (/^$prompt/); 653 next if (/^(\s*|\s*$cmd\s*)$/); 654 return(1) if /^\s*\^\s*$/; 655 return(1) if /Line has invalid autocommand /; 656 return(1) if /(Invalid input detected|Type help or )/; 657 return(1) if (/\% Invalid command at /); 658 return(1) if (/No token match at /); # 1000v 659 return(-1) if (/\% Permission denied/); 660 return(-1) if (/command authorization failed/i); 661 next if (/^Configuration last modified by/); 662 # the pager can not be disabled per-session on the PIX 663 if (/^(<-+ More -+>)/) { 664 my($len) = length($1); 665 s/^$1\s{$len}//; 666 } 667 668 # Nexus 5k and 1000v do not support vtp 669 if (!/^VTP Operating Mode\s+:\s+(Transparent|Server)/) { 670 $DO_SHOW_VLAN = 0; 671 } 672 ProcessHistory("COMMENTS","","","!VTP: $_"); 673 } 674 ProcessHistory("COMMENTS","","","!\n"); 675 return(0); 676} 677 678# This routine parses "show vlan" 679sub ShowVLAN { 680 my($INPUT, $OUTPUT, $cmd) = @_; 681 print STDERR " In ShowVLAN: $_" if ($debug); 682 683 ($_ = <$INPUT>, return(1)) if (!$DO_SHOW_VLAN); 684 685 while (<$INPUT>) { 686 tr/\015//d; 687 last if (/^$prompt/); 688 next if (/^(\s*|\s*$cmd\s*)$/); 689 return(1) if /^\s*\^\s*$/; 690 return(1) if /Line has invalid autocommand /; 691 return(1) if /(Invalid input detected|Type help or )/; 692 return(-1) if (/\% Invalid command at /); 693 return(-1) if (/No token match at /); # 1000v 694 return(1) if /Ambiguous command/i; 695 return(-1) if (/\% Permission denied/); 696 return(-1) if (/command authorization failed/i); 697 # the pager can not be disabled per-session on the PIX 698 if (/^(<-+ More -+>)/) { 699 my($len) = length($1); 700 s/^$1\s{$len}//; 701 } 702 703 ProcessHistory("COMMENTS","","","!VLAN: $_"); 704 } 705 ProcessHistory("COMMENTS","","","!\n"); 706 return(0); 707} 708 709# This routine parses "show debug" 710sub ShowDebug { 711 my($INPUT, $OUTPUT, $cmd) = @_; 712 print STDERR " In ShowDebug: $_" if ($debug); 713 my($lines) = 0; 714 715 while (<$INPUT>) { 716 tr/\015//d; 717 last if (/^$prompt/); 718 next if (/^(\s*|\s*$cmd\s*)$/); 719 return(1) if /Line has invalid autocommand /; 720 return(1) if /(Invalid input detected|Type help or )/; 721 return(-1) if (/\% Invalid command at /); 722 return(-1) if (/No token match at /); # 1000v 723 return(-1) if (/command authorization failed/i); 724 return(-1) if (/could not retrieve info/i); 725 # XXX return(-1) if (/\% Permission denied/); 726 # NX 5000 bug? "show debug" generates 727 # "Permission denied" when using command authorization. -Per-Olof Olsson 728 next if (/\% Permission denied/); 729 730 /^No matching debug flags set$/ && next; 731 /^No debug flags set$/ && next; 732 ProcessHistory("COMMENTS","","","!DEBUG: $_"); 733 $lines++; 734 } 735 if ($lines) { 736 ProcessHistory("COMMENTS","","","!\n"); 737 } 738 return(0); 739} 740 741# This routine parses "show cores" 742sub ShowCores { 743 my($INPUT, $OUTPUT, $cmd) = @_; 744 print STDERR " In ShowCores: $_" if ($debug); 745 746 while (<$INPUT>) { 747 tr/\015//d; 748 last if (/^$prompt/); 749 next if (/^(\s*|\s*$cmd\s*)$/); 750 return(1) if /Line has invalid autocommand /; 751 return(1) if /(Invalid input detected|Type help or )/; 752 return(1) if (/\% Invalid command at /); 753 return(1) if (/No token match at /); # 1000v 754 return(-1) if (/\% Permission denied/); 755 return(-1) if (/command authorization failed/i); 756 757 ProcessHistory("COMMENTS","","","!CORES: $_"); 758 } 759 ProcessHistory("COMMENTS","","","!\n"); 760 return(0); 761} 762 763# This routine parses "show fex" and "show module fex" 764sub ShowFex { 765 my($INPUT, $OUTPUT, $cmd) = @_; 766 print STDERR " In ShowFex: $_" if ($debug); 767 768 while (<$INPUT>) { 769 tr/\015//d; 770 last if (/^$prompt/); 771 next if (/^(\s*|\s*$cmd\s*)$/); 772 return(1) if (/^\s*\^\s*$/); 773 return(1) if /Line has invalid autocommand /; 774 return(1) if /(Invalid input detected|Type help or )/; 775 return(1) if (/\% Invalid command at /); 776 return(1) if (/% Invalid number at /); # 1000v 777 return(-1) if (/\% Permission denied/); 778 return(-1) if (/command authorization failed/i); 779 780 ProcessHistory("COMMENTS","","","!FEX: $_"); 781 } 782 ProcessHistory("COMMENTS","","","!\n"); 783 return(0); 784} 785 786# This routine parses "show processes log" 787sub ShowProcLog { 788 my($INPUT, $OUTPUT, $cmd) = @_; 789 print STDERR " In ShowProcLog: $_" if ($debug); 790 791 while (<$INPUT>) { 792 tr/\015//d; 793 last if (/^$prompt/); 794 next if (/^(\s*|\s*$cmd\s*)$/); 795 return(1) if /Line has invalid autocommand /; 796 return(1) if /(Invalid input detected|Type help or )/; 797 return(1) if (/\% Invalid command at /); 798 return(-1) if (/No token match at /); # 1000v 799 return(-1) if (/\% Permission denied/); 800 return(-1) if (/command authorization failed/i); 801 802 ProcessHistory("COMMENTS","","","!PROC_LOGS: $_"); 803 } 804 ProcessHistory("COMMENTS","","","!\n"); 805 return(0); 806} 807 808# This routine processes a "write term" 809sub WriteTerm { 810 my($INPUT, $OUTPUT, $cmd) = @_; 811 print STDERR " In WriteTerm: $_" if ($debug); 812 my($lineauto,$comment,$linecnt) = (0,0,0); 813 814 while (<$INPUT>) { 815REPEAT: tr/\015//d; 816 last if (/^$prompt/); 817 return(1) if /Line has invalid autocommand /; 818 return(1) if (/(Invalid input detected|Type help or )/i); 819 return(-1) if (/\% Invalid command at /); 820 return(-1) if (/No token match at /); # 1000v 821 return(-1) if (/\% Permission denied/); 822 return(-1) if (/command authorization failed/i); 823 return(0) if ($found_end); # Only do this routine once 824 825 $linecnt++; 826 $lineauto = 0 if (/^[^ ]/); 827 828 # Dog gone Cool matches to process the rest of the config 829 /^!Command: show running-config/ && next; # kill this junk 830 /^!Time: / && next; # kill this junk 831 832 # Sort username and delete passwords. 833 if (/^username (\S+) password (\d) (\S+)(\s.*)$/) { 834 if ($filter_pwds >= 2) { 835 ProcessHistory("USER","keysort","$1", 836 "!username $1 password <removed>$4\n"); 837 } elsif ($filter_pwds >= 1 && $2 ne "5") { 838 ProcessHistory("USER","keysort","$1", 839 "!username $1 password <removed>$4\n"); 840 } else { 841 ProcessHistory("USER","keysort","$1","$_"); 842 } 843 next; 844 } 845 # Sort any other username info. 846 /^username (\S+) .*$/ && 847 ProcessHistory("USER","keysort","$1","$_") && next; 848 if (/^\s*(.*?neighbor \S*) password / && $filter_pwds >= 1) { 849 ProcessHistory("","","","! $1 password <removed>\n"); 850 next; 851 } 852 # sort ipv{4,6} access-lists 853 if ($aclfilterseq && /^ip(v4|v6)? access-list (\S+)\s*$/) { 854 my($nlri, $key) = ($1, $2); 855 my($seq, $cmd); 856 if (length($nlri) eq 0) { 857 $nlri = "ipv4"; # assume ip will become ipv4 at some point 858 } 859 ProcessHistory("ACL $nlri $key","","","$_"); 860 while (<$INPUT>) { 861 tr/\015//d; 862 goto REPEAT if (/^$prompt/ || !/^\s/); 863 if (/^\s*!/) { 864 ProcessHistory("ACL $nlri $key !", "", "", "$_"); 865 next; 866 } 867 # ip access-list copp-system-acl-bgp 868 # 10 permit tcp any gt 1024 any eq bgp 869 # 20 permit tcp any eq bgp any gt 1024 870 # ipv6 access-list copp-system-acl-bgp6 871 # 10 permit tcp any gt 1024 any eq bgp 872 # 20 permit tcp any eq bgp any gt 1024 873 # XXX this may need more format handling; going off email with 874 # a user. 875 my($seq, $cmd, $resid) = ($_ =~ /^\s*(\d+) (\w+) (.+)/); 876 if ($cmd =~ /(permit|deny)/) { 877 my($ip); 878 my(@w) = ($resid =~ /(\S+) (\S+) (\S+\s)?(.+)/); 879 for (my($i) = 0; $i < $#w; $i++) { 880 if ($w[$i] eq "any") { 881 if ($nlri eq "ipv4") { 882 $ip = "255.255.255.255/32"; 883 } else { 884 $ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"; 885 } 886 last; 887 } elsif ($w[$i] =~ /^[:0-9]/ || 888 $2[$i] =~ /^[a-fA-F]{1,4}:/) { 889 $ip = $w[$i]; 890 $ip =~ s/\s+$//; # trim trailing WS 891 last; 892 } 893 } 894 ProcessHistory("ACL $nlri $key $cmd", "$aclsort", "$ip", 895 " $cmd $resid\n"); 896 } else { 897 ProcessHistory("ACL $nlri $key $cmd", "", "", 898 " $cmd $resid\n"); 899 } 900 } 901 } 902 903 # Why was this commented out? It shows up in the raw text... 904 if (/^(snmp-server community) (\S+)/) { 905 if ($filter_commstr) { 906 ProcessHistory("SNMPSERVERCOMM","keysort","$_", 907 "!$1 <removed>$'") && next; 908 } else { 909 ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; 910 } 911 } 912 # order/prune snmp-server host statements 913 # we only prune lines of the form 914 # snmp-server host a.b.c.d <community> 915 if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { 916 if ($filter_commstr) { 917 my($ip) = $1; 918 my($line) = "snmp-server host $ip"; 919 my(@tokens) = split(' ', $'); 920 my($token); 921 while ($token = shift(@tokens)) { 922 if ($token eq 'version') { 923 $line .= " " . join(' ', ($token, shift(@tokens))); 924 if ($token eq '3') { 925 $line .= " " . join(' ', ($token, shift(@tokens))); 926 } 927 } elsif ($token eq 'vrf') { 928 $line .= " " . join(' ', ($token, shift(@tokens))); 929 } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { 930 $line .= " " . $token; 931 } else { 932 $line = "!$line " . join(' ', ("<removed>", 933 join(' ',@tokens))); 934 last; 935 } 936 } 937 ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); 938 } else { 939 ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); 940 } 941 next; 942 } 943 # Sort snmp user and delete passwords. 944 if (/^snmp-server user (\S+) (\S+) auth md5 (\S+) priv (\S+) localizedkey$/) { 945 if ($filter_pwds >= 2) { 946 ProcessHistory("SNMP-USER","keysort","$1", 947 "!snmp-server user $1 $2 auth md5 <removed> priv <removed> localizedkey\n"); 948 } else { 949 ProcessHistory("SNMP-USER","keysort","$1","$_"); 950 } 951 next; 952 } 953 # Sort any other snmp user info. 954 /^snmp-server user (\S+) .*$/ && 955 ProcessHistory("SNMP-USER","keysort","$1","$_") && next; 956 # Delete bgp passwords. 957 if (/^(\s*)password (\d) (\S+)(\s.*)?$/) { 958 if ($filter_pwds >= 2) { 959 ProcessHistory("","","","!$1password <removed>$4"); 960 } elsif ($filter_pwds >= 1 && $2 ne "5") { 961 ProcessHistory("","","","!$1password <removed>$4"); 962 } else { 963 ProcessHistory("","","","$_"); 964 } 965 next; 966 } 967 968 # prune tacacs/radius server keys: 969 # tacacs-server host 196.23.0.13 key 7 "xxxxxxx" port 50 timeout 10 970 if (/^((tacacs|radius)-server.*?\bkey\b.*?) ".*?"(.*)/ 971 && $filter_pwds >= 1) { 972 ProcessHistory("","","","!$1 <removed>$3\n"); next; 973 } 974 975 # order cli alias names 976 /^cli alias name (\S+) .*$/ && 977 ProcessHistory("CLI-ALIAS","keysort","$1","$_") && next; 978 # order snmp-server enable trap statements 979 /^snmp-server enable traps (.*)$/ && 980 ProcessHistory("SNMP-TRAPS","keysort","$1","$_") && next; 981 982 # catch anything that wasnt matched above. 983 ProcessHistory("","","","$_"); 984 # end of config. the ": " game is for the PIX 985 if (/^(: +)?end$/) { 986 $found_end = 1; 987 return(0); 988 } 989 } 990 # The ContentEngine lacks a definitive "end of config" marker. If we 991 # know that it is NXOS and we have seen at least 5 lines 992 # of write term output, we can be reasonably sure that we got the config. 993 if (($type eq "NXOS") && $linecnt > 5) { 994 $found_end = 1; 995 return(0); 996 } 997 998 return(0); 999} 1000 10011; 1002