1package iosxr; 2## 3## @PACKAGE@ @VERSION@ 4@copyright@ 5# 6# RANCID - Really Awesome New Cisco confIg Differ 7# 8# iosxr.pm - Cisco IOS-XR 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 $found_env; 21our $found_diag; 22our $found_version; 23our $config_register; # configuration register value 24 25our $type; # device model, from ShowVersion 26 27our $C0; # output formatting control 28our $E0; 29our $H0; 30our $I0; 31 32@ISA = qw(Exporter rancid main); 33#XXX @Exporter::EXPORT = qw($VERSION @commandtable %commands @commands); 34 35# load-time initialization 36sub import { 37 0; 38} 39 40# post-open(collection file) initialization 41sub init { 42 $proc = ""; 43 $found_env = 0; 44 $found_diag = 0; 45 $found_version = 0; 46 $config_register = undef; # configuration register value 47 48 # XXX $type = undef; # device model, from ShowVersion 49 50 $C0 = 0; # output formatting control 51 $E0 = 0; 52 $H0 = 0; 53 $I0 = 0; 54 55 # add content lines and separators 56 ProcessHistory("","","","!RANCID-CONTENT-TYPE: $devtype\n!\n"); 57 ProcessHistory("COMMENTS","keysort","B0","!\n"); 58 ProcessHistory("COMMENTS","keysort","D0","!\n"); 59 ProcessHistory("COMMENTS","keysort","F0","!\n"); 60 ProcessHistory("COMMENTS","keysort","G0","!\n"); 61 62 0; 63} 64 65# main loop of input of device output 66sub inloop { 67 my($INPUT, $OUTPUT) = @_; 68 my($cmd, $rval); 69 70TOP: while(<$INPUT>) { 71 tr/\015//d; 72CMD: if (/[>#]\s?exit$/) { 73 $clean_run = 1; 74 last; 75 } 76 if (/^Error:/) { 77 print STDOUT ("$host clogin error: $_"); 78 print STDERR ("$host clogin error: $_") if ($debug); 79 $clean_run = 0; 80 last; 81 } 82 while (/[>#]\s*($cmds_regexp)\s*$/) { 83 $cmd = $1; 84 if (!defined($prompt)) { 85 $prompt = ($_ =~ /^([^#]+#)/)[0]; 86 $prompt =~ s/([][}{)(+\\])/\\$1/g; 87 print STDERR ("PROMPT MATCH: $prompt\n") if ($debug); 88 } 89 print STDERR ("HIT COMMAND:$_") if ($debug); 90 if (! defined($commands{$cmd})) { 91 print STDERR "$host: found unexpected command - \"$cmd\"\n"; 92 $clean_run = 0; 93 last TOP; 94 } 95 if (! defined(&{$commands{$cmd}})) { 96 printf(STDERR "$host: undefined function - \"%s\"\n", 97 $commands{$cmd}); 98 $clean_run = 0; 99 last TOP; 100 } 101 $rval = &{$commands{$cmd}}($INPUT, $OUTPUT, $cmd); 102 delete($commands{$cmd}); 103 if ($rval == -1) { 104 $clean_run = 0; 105 last TOP; 106 } 107 if (defined($prompt)) { 108 if (/$prompt/) { 109 goto CMD; 110 } 111 } 112 } 113 } 114} 115 116# This routine parses "admin show version" 117sub ShowVersion { 118 my($INPUT, $OUTPUT, $cmd) = @_; 119 my($slave, $slaveslot); 120 print STDERR " In ShowVersion: $_" if ($debug); 121 122 while (<$INPUT>) { 123 tr/\015//d; 124 if (/^$prompt/) { $found_version = 1; last}; 125 next if (/^(\s*|\s*$cmd\s*)$/); 126 # filter the bloody cmd-line timestamp 127 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 128 return(1) if (/Line has invalid autocommand /); 129 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 130 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 131 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 132 return(0) if ($found_version); # Only do this routine once 133 return(-1) if (/command authorization failed/i); 134 135 if (/^Slave in slot (\d+) is running/) { 136 $slave = " Slave:"; 137 $slaveslot = ", slot $1"; 138 next; 139 } 140 /^(Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/ && 141 ProcessHistory("COMMENTS","keysort","F1", 142 "!Image:$slave Software: $2, $3\n") && next; 143 /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ && 144 ProcessHistory("COMMENTS","keysort","F2", 145 "!Image:$slave $1 Synced to mainline version: $2\n") && next; 146 /^Compiled (.*)$/ && 147 ProcessHistory("COMMENTS","keysort","F3", 148 "!Image:$slave Compiled: $1\n") && next; 149 /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/ && 150 ProcessHistory("COMMENTS","keysort","G1", 151 "!ROM Bootstrap: $3\n") && next; 152 /^Serial Number:\s+(.*)$/ && 153 ProcessHistory("COMMENTS","keysort","C1", "!$_") && next; 154 155 /^Activation Key:\s+(.*)$/ && 156 ProcessHistory("COMMENTS","keysort","C2", "!$_") && next; 157 /^ROM: \d+ Bootstrap .*(Version.*)$/ && 158 ProcessHistory("COMMENTS","keysort","G2", 159 "!ROM Image: Bootstrap $1\n!\n") && next; 160 /^ROM: .*(Version.*)$/ && 161 ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && next; 162 /^BOOTFLASH: .*(Version.*)$/ && 163 ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && next; 164 /^BOOTLDR: .*(Version.*)$/ && 165 ProcessHistory("COMMENTS","keysort","G4","!BOOTLDR: $1\n") && next; 166 /^System image file is "([^\"]*)", booted via (\S*)/ && 167# removed the booted source due to 168# CSCdk28131: cycling info in 'sh ver' 169# ProcessHistory("COMMENTS","keysort","F4","!Image: booted via $2, $1\n") && 170 ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") && 171 next; 172 /^System image file is "([^\"]*)"$/ && 173 ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next; 174 if (/(\S+(?:\sseries)?)\s+(?:\(([^)]+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i) { 175 $proc = $1; 176 my($cpu) = $2; 177 my($mem) = $3; 178 my($device) = "router"; 179 180 # the next line ought to be the more specific cpu info, grab it. 181 # yet, some boards/IOS vers have a processor ID line between these 182 # two. grrr. make sure we dont grab the "software" junk that 183 # follows these lines by looking for "CPU at " or the 2600s 184 # "processor: " unique string. there are undoubtedly many other 185 # incantations. for a slave, we dont get this info, its just a 186 # blank line. 187 $_ = <$INPUT>; 188 if (/processor board id/i) { 189 my($sn); 190 191 if (/processor board id (\S+)/i) { 192 $sn = $1; 193 $sn =~ s/,$//; 194 ProcessHistory("COMMENTS","keysort","D9", 195 "!Processor ID: $sn\n"); 196 } 197 $_ = <$INPUT>; 198 } 199 $_ = "" if (! /(cpu at |processor: |$cpu processor,)/i); 200 tr/\015//d; 201 s/implementation/impl/i; 202 if ($_ !~ /^\s*$/) { 203 chomp; 204 s/^/, /; 205 } 206 207 if ($proc =~ /1200[48]\/(GRP|PRP)/ || $proc =~ /1201[26]\/(GRP|PRP)/) { 208 $type = "12000"; 209 } elsif ($proc =~ /1201[26]-8R\/(GRP|PRP)/) { 210 $type = "12000"; 211 } elsif ($proc =~ /1240[48]\/(GRP|PRP)/ || $proc =~ /1241[06]\/(GRP|PRP)/) { 212 $type = "12400"; 213 } elsif ($proc =~ /ASR9K/) { 214 $_ = <$INPUT>; 215 $type = $proc; 216 if (/(ASR\S+)\s+(\SC)\s+Chassis/) { 217 $proc = $1; 218 } elsif (/(ASR\S+)\s+Chassis/) { 219 $proc = $1; 220 } elsif (/(ASR)\s+(9\d+)\s+.*\s+Chassis with/) { 221 tr/\015//d; 222 chomp; 223 $proc = $_; 224 } elsif (/(ASR)\s+(9\S+)\s+(\SC)\s+Chassis/) { 225 $proc = "ASR-". $2; 226 } elsif (/(ASR)\s+(9\S+)\s+Chassis/) { 227 $proc = "ASR-". $2; 228 } elsif (/(ASR\s+9922)/) { 229 $proc = "ASR-9922"; 230 } 231 $_ = ""; 232 } else { 233 $type = $proc; 234 } 235 236 print STDERR "TYPE = $type\n" if ($debug); 237 ProcessHistory("COMMENTS","keysort","A1", 238 "!Chassis type:$slave $proc - a $type $device\n"); 239 ProcessHistory("COMMENTS","keysort","B1", 240 "!Memory:$slave main $mem\n"); 241 if (defined($cpu)) { 242 ProcessHistory("COMMENTS","keysort","A3", 243 "!CPU:$slave $cpu$_$slaveslot\n"); 244 } 245 next; 246 } elsif (/^cisco (\S+(?:\sseries)?)\s+(?:\(([^)]*)\)\s+processor)/i) { 247 $proc = $1; 248 my($cpu) = $2; 249 my($device) = "router"; 250 251 print STDERR "TYPE = $type\n" if ($debug); 252 ProcessHistory("COMMENTS","keysort","A1", 253 "!Chassis type: $proc - a $proc $device\n"); 254 if (defined($cpu) && length($cpu)) { 255 ProcessHistory("COMMENTS","keysort","A3", 256 "!CPU:$cpu\n"); 257 } 258 } 259 /^(\d+[kK]) bytes of (non-volatile|NVRAM)/ && 260 ProcessHistory("COMMENTS","keysort","B3", 261 "!Memory: nvram $1\n") && next; 262 /^(\d+[kK]) bytes of flash memory/ && 263 ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") && 264 next; 265 /^(\d+[kK]) bytes of .*flash partition/ && 266 ProcessHistory("COMMENTS","keysort","B6", 267 "!Memory: flash partition $1\n") && next; 268 /^(\d+[kK]) bytes of Flash internal/ && 269 ProcessHistory("COMMENTS","keysort","B4", 270 "!Memory: bootflash $1\n") && next; 271 if (/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i) { 272 ProcessHistory("COMMENTS","keysort","B7", 273 "!Memory: pcmcia $2 $3$4 $1\n"); 274 next; 275 } 276 if (/^(\d+[kK]) bytes of (slot|disk)(\d)/i) { 277 ProcessHistory("COMMENTS","keysort","B7", 278 "!Memory: pcmcia $2$3 $1\n"); 279 next; 280 } 281 if (/^WARNING/) { 282 if (!defined($I0)) { 283 $I0 = 1; 284 ProcessHistory("COMMENTS","keysort","I0","!\n"); 285 } 286 ProcessHistory("COMMENTS","keysort","I1","! $_"); 287 } 288 if (/^Configuration register is (.*)$/) { 289 $config_register = $1; 290 next; 291 } 292 if (/^Configuration register on node \S+ is (.*)$/) { 293 $config_register = $1 if (length($config_register) < 1); 294 next; 295 } 296 } 297 return(0); 298} 299 300# This routine parses "admin show diag". 301sub AdminShowDiag { 302 my($INPUT, $OUTPUT, $cmd) = @_; 303 print STDERR " In AdminShowDiag: $_" if ($debug); 304 305 while (<$INPUT>) { 306 tr/\015//d; 307 last if (/^$prompt/); 308 next if (/^(\s*|\s*$cmd\s*)$/); 309 # filter the bloody cmd-line timestamp 310 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 311 return(1) if (/Line has invalid autocommand /); 312 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 313 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 314 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 315 return(-1) if (/command authorization failed/i); 316 317 # skip blank lines 318 /^$/ && next; 319 # NCS junk 320 next if (/^\S+ connected from 127.0.0.1 using console /); 321 next if (/# terminal length 0$/); 322 323 s/^NODE //; 324 # wtf are these? 325 next if (/(New Deviation|UDI_VID|Board State)/); 326 # skip insertion time 327 next if (/insertion time/i); 328 # skip board h/w revision junk 329 next if (/^(\s{2}board |\s{3,})/i); 330 331 ProcessHistory("SLOT","","","!$_"); 332 } 333 ProcessHistory("SLOT","","","!\n"); 334 return(0); 335} 336 337# This routine parses "admin show running". 338sub AdminShowRunning { 339 my($INPUT, $OUTPUT, $cmd) = @_; 340 print STDERR " In ShowRunning: $_" if ($debug); 341 342 while (<$INPUT>) { 343 tr/\015//d; 344 last if (/^$prompt/); 345 next if (/^(\s*|\s*$cmd\s*)$/); 346 # filter the bloody cmd-line timestamp 347 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 348 return(1) if (/Line has invalid autocommand /); 349 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 350 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 351 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 352 return(-1) if (/command authorization failed/i); 353 354 # skip blank lines 355 /^$/ && next; 356 # NCS junk 357 next if (/^\S+ connected from 127.0.0.1 using console /); 358 next if (/# terminal length 0$/); 359 360 /^building configuration/i && next; 361 if (/^(\s*secret) / && $filter_pwds >= 2) { 362 ProcessHistory("ASR","","","!$1 <removed>\n"); 363 next; 364 } 365 366 ProcessHistory("ASR","","","!$_"); 367 368 /^end$/ && last; 369 } 370 ProcessHistory("ASR","","","!\n"); 371 return(0); 372} 373 374# This routine parses "show diag". 375sub ShowDiag { 376 my($INPUT, $OUTPUT, $cmd) = @_; 377 print STDERR " In ShowDiag: $_" if ($debug); 378 379 while (<$INPUT>) { 380 tr/\015//d; 381 last if (/^$prompt/); 382 next if (/^(\s*|\s*$cmd\s*)$/); 383 # filter the bloody cmd-line timestamp 384 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 385 return(1) if (/Line has invalid autocommand /); 386 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 387 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 388 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 389 return(-1) if (/command authorization failed/i); 390 391 # skip blank lines 392 /^$/ && next; 393 # NCS junk 394 next if (/^\S+ connected from 127.0.0.1 using console /); 395 next if (/# terminal length 0$/); 396 397 s/^NODE //; 398 # wtf are these? 399 next if (/(New Deviation|UDI_VID|Board State)/); 400 401 ProcessHistory("SLOT","","","!$_"); 402 } 403 ProcessHistory("SLOT","","","!\n"); 404 return(0); 405} 406 407 408# This routine parses "admin show hw-module fpd location all" and 409# "show hw-module fpd" (eXR/eXR-lite). 410sub ShowHWfpd { 411 my($INPUT, $OUTPUT, $cmd) = @_; 412 print STDERR " In ShowRunning: $_" if ($debug); 413 414 while (<$INPUT>) { 415 tr/\015//d; 416 last if (/^$prompt/); 417 next if (/^(\s*|\s*$cmd\s*)$/); 418 # filter the bloody cmd-line timestamp 419 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 420 return(1) if (/Line has invalid autocommand /); 421 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 422 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 423 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 424 return(-1) if (/command authorization failed/i); 425 426 # skip blank lines 427 /^$/ && next; 428 429 # NCS junk 430 next if (/^\S+ connected from 127.0.0.1 using console /); 431 next if (/# terminal length 0$/); 432 433 /^notes:/i && last; 434 435 # remove trailing WS 436 s/\s+$/\n/; 437 438 ProcessHistory("FPD","","","!$_"); 439 } 440 ProcessHistory("FPD","","","!\n"); 441 return(0); 442} 443 444# This routine parses "show redundancy" 445sub ShowRedundancy { 446 my($INPUT, $OUTPUT, $cmd) = @_; 447 my($slave, $slaveslot); 448 print STDERR " In ShowRedundancy: $_" if ($debug); 449 450TOP: while (<$INPUT>) { 451 tr/\015//d; 452 last if (/^$prompt/); 453 next if (/^(\s*|\s*$cmd\s*)$/); 454 # filter the bloody cmd-line timestamp 455 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 456 return(1) if (/Line has invalid autocommand /); 457 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 458 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 459 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 460 461 # filter reload/boot info 462 if (/^reload and boot info/i) { 463 while (<$INPUT>) { 464 tr/\015//d; 465 last TOP if (/^$prompt/); 466 last if (/^\s*$/); 467 } 468 } 469 ProcessHistory("COMMENTS","keysort","F3", "!$_"); 470 } 471 ProcessHistory("COMMENTS","keysort","F3", "!\n"); 472 return(0); 473} 474 475# This routine parses "show install active" 476sub ShowInstallActive { 477 my($INPUT, $OUTPUT, $cmd) = @_; 478 print STDERR " In ShowInstallActive: $_" if ($debug); 479 480 while (<$INPUT>) { 481 tr/\015//d; 482 last if (/^$prompt/); 483 next if (/^(\s*|\s*$cmd\s*)$/); 484 # filter the bloody cmd-line timestamp 485 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 486 return(1) if (/^\s*\^\s*$/); 487 return(1) if (/Line has invalid autocommand /); 488 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 489 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 490 return(-1) if (/command authorization failed/i); 491 return(-1) if (/install director is not up or ready/i);# temp error 492 return(-1) if (/failed to output install information /i);# temp error 493 494 # FPD upgrade in progress on some hardware, reload/configuration change 495 # on those is not recommended as it might cause HW programming failure 496 # and result in RMA of the hardware. 497 # FPD upgrade has ended. 498 next if (/fpd upgrade has ended/i || 499 /fpd upgrade in progress /i || 500 /might cause hw programming failure/i || 501 /result in rma of the hardware/i); # useless FPD messages 502 503 ProcessHistory("COMMENTS","keysort","F5","!Image: $_") && next; 504 } 505 ProcessHistory("COMMENTS","keysort","F5","!\n"); 506 return(0); 507} 508 509# This routine parses "show memory summary" 510sub ShowMemorySum { 511 my($INPUT, $OUTPUT, $cmd) = @_; 512 print STDERR " In ShowMemorySum: $_" if ($debug); 513 514 # RP/0/RSP0/CPU0:r00.lab#show memory summary 515 # 516 # node: node0_RSP0_CPU0 517 # ------------------------------------------------------------------ 518 # 519 # Physical Memory: 27426M total (22146M available) 520 # Application Memory : 27426M (21819M available) 521 # Image: 4M (bootram: 0M) 522 # Reserved: 0M, IOMem: 0M, flashfsys: 0M 523 # Total shared window: 140M 524 while (<$INPUT>) { 525 tr/\015//d; 526 last if (/^$prompt/); 527 next if (/^(\s*|\s*$cmd\s*)$/); 528 # filter the bloody cmd-line timestamp 529 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 530 return(1) if (/Line has invalid autocommand /); 531 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 532 return(-1) if (/command authorization failed/i); 533 534 /physical memory:\s+(\d+[GMKB])\s+total/i && 535 ProcessHistory("COMMENTS","keysort","B1", 536 "!Memory: main $1\n") && next; 537 } 538 return(0); 539} 540 541# This routine parses "admin show env all" 542sub ShowEnv { 543 my($INPUT, $OUTPUT, $cmd) = @_; 544 # Skip if this is not a 7500, 7200, or 7000. 545 print STDERR " In ShowEnv: $_" if ($debug); 546 547 while (<$INPUT>) { 548 tr/\015//d; 549 if (/^$prompt/) { $found_env = 1; last}; 550 # filter the bloody cmd-line timestamp 551 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 552 next if (/^(\s*|\s*$cmd\s*)$/); 553 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 554 return(1) if (/Line has invalid autocommand /); 555 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 556 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 557 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 558 return(0) if ($found_env); # Only do this routine once 559 return(-1) if (/command authorization failed/i); 560 561 if (!defined($E0)) { 562 $E0 = 1; 563 ProcessHistory("COMMENTS","keysort","E0","!\n"); 564 } 565 566 if (/power budget summary for rack/i) { 567 ProcessHistory("COMMENTS","keysort","E1","!Power: $_"); 568 while (<$INPUT>) { 569 tr/\015//d; 570 goto OUT if (/^$prompt/); 571 last if (/^altitude information/i); 572 ProcessHistory("COMMENTS","keysort","E1","!Power: $_"); 573 } 574 next; 575 } 576 if (/power shelf \d+:/i) { 577 my($sep) = 0; 578 ProcessHistory("COMMENTS","keysort","E1","!Power: $_"); 579 while (<$INPUT>) { 580 tr/\015//d; 581 goto OUT if (/^$prompt/); 582 last if (/^altitude information/i); 583 last if (/^=+$/i && ($sep > 1)); 584 $sep++ if (/^=+$/i); 585 if (/^(\s+\S+\s+\S+-(?:AC|DC)\s+)(\S+\s+\S+\s+\S+\s+\S+)(\s+.*)/) { 586 $_ = sprintf("%s%-". length($2) ."s%s\n", $1, "", $3); 587 } 588 ProcessHistory("COMMENTS","keysort","E1","!Power: $_"); 589 } 590 next; 591 } 592 /^Power Supply Information$/ && next; 593 /^\s*Power Module\s+Voltage\s+Current$/ && next; 594 /^\s*(Power [^:\n]+)$/ && 595 ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && next; 596 /^\s*(Lower Power .*)/i && 597 ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; 598 /^\s*(redundant .*)/i && 599 ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; 600 /^\s*(RPS is .*)/i && 601 ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; 602 } 603OUT: 604 ProcessHistory("COMMENTS","keysort","E3","!\n"); 605 return(0); 606} 607 608# This routine parses "dir /all ((disk|slot)N|bootflash|nvram):" 609sub DirSlotN { 610 my($INPUT, $OUTPUT, $cmd) = @_; 611 print STDERR " In DirSlotN: $_" if ($debug); 612 613 my($dev) = (/\s([^\s]+):/); 614 615 while (<$INPUT>) { 616 tr/\015//d; 617 last if (/^$prompt/); 618 next if (/^(\s*|\s*$cmd\s*)$/); 619 # filter the bloody cmd-line timestamp 620 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 621 return(1) if /^\s*\^\s*$/; 622 return(1) if (/Line has invalid autocommand /); 623 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 624 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 625 return(1) if (/(No such device|Error Sending Request)/i); 626 return(1) if (/: path doesnot exists/i); # NCS 627 return(1) if (/: Path does not exist/i); # NCS 628 return(1) if (/\%Error: No such file or directory/); 629 return(1) if (/\%Error: No route to host/); 630 return(1) if (/No space information available/); 631 # Corrupt flash 632 /\%Error calling getdents / && 633 ProcessHistory("FLASH","","","!Flash: $dev: $_") && next; 634 return(-1) if (/\%Error calling/); 635 return(-1) if (/(: device being squeezed|ATA_Status time out)/i); # busy 636 return(-1) if (/\%Error opening \S+:\S+ \(Device or resource busy\)/i); 637 return(-1) if (/command authorization failed/i); 638 return(1) if (/(Open device \S+ failed|Error opening \S+:)/); 639 640 # Filter dhcp database 641 if (/dhcp_[^. ]*\.txt/) { 642 next; 643 } 644 # Filter debugging file dlbg.txt & dlbg.txt-1 only on ASR9k w/ XR 645 if ($proc =~ /ASR9K/ && /dlbg\.txt/) { 646 next; 647 } 648 # filter frequently changing files from IOX bootflash, hardiska, 649 # and nvram 650 if ($dev =~ /(bootflash|disk[0-9]|harddisk|nvram)/) { 651 if (/\s(\.python-history|aaa|\.bash_history|.sppdc)\s*$/ || 652 /\s(ce_switch.log\S*|cisco_support|errmsg_cont)\s*$/ || 653 /\s(genstr_cont|temp_cont|temp_cont|temp_static_data)\s*$/ || 654 /\s(uptime_cont|volt_cont|volt_hist)\s*$/) { 655 # change 656 # 57 -rw- 23100 <no date> volt_cont 657 # 614788 drwx 4096 Fri Aug 20 12:06:25 2010 temp_cont 658 # to 659 # -rw- <no date> volt_cont 660 # drwx temp_cont 661 if (/\s*\d+\s+(\S+\s+)(\d+)(\s+)(<no date>)(\s+)/) { 662 my($a, $sz, $c, $dt, $d, $rem) = ($1, $2, $3, $4, $5, $'); 663 my($szl) = length($sz); 664 my($fmt) = "%s%-". $szl ."s%s%s%s%s"; 665 $_ = sprintf($fmt, $c, $dt, $d, $rem); 666 ProcessHistory("FLASH","keysort",$rem,"!Flash: $dev: $_"); 667 next; 668 } elsif (/\s*\d+\s+(\S+\s+\d+\s+)(\d+\s+\w+\s+\d+\s+\d+:\d+)/ || 669 /\s*\d+\s+(\S+\s+\d+\s+)(\d+\s+\w+\s+\d+\s+\d{4})/) { 670 # XR >= 6.3; dir disk0:, but harddisk: is diff format. wtf 671 # drop fileno size, & date. 672 # " 8002 drwxr-xr-x 2 4096 Jan 17 15:27 np" 673 my($perm, $dt, $rem) = ($1, $2, $'); 674 my($dtl) = length($dt); 675 my($fmt) = "%s%-". $dtl ."s%s"; 676 $_ = sprintf($fmt, $perm, "", $rem); 677 ProcessHistory("FLASH","keysort",$rem,"!Flash: $dev: $_"); 678 next; 679 } elsif (/\s*\d+\s+(\S+\s+)(\d+)(\s+)(\w+ \w+\s+\d+ \d+:\d+:\d+ \d+)/) { 680 my($b, $sz, $c, $dt, $rem) = ($1, $2, $3, $4, $'); 681 my($szl, $dtl) = (length($sz), length($dt)); 682 my($fmt) = "%s%-". $szl ."s%s%-". $dtl ."s%s"; 683 $_ = sprintf($fmt, $b, "", $c, "", $rem); 684 ProcessHistory("FLASH","keysort",$rem,"!Flash: $dev: $_"); 685 next; 686 } 687 } else { 688 if (/\s*\d+\s+(\S+\s+)(\d+)(\s+)(<no date>\s+)/) { 689 my($sz, $c, $dt, $d, $rem) = ($1, $2, $3, $4, $'); 690 ProcessHistory("FLASH","keysort",$rem,"!Flash: $dev: $sz$c$dt$d$rem"); 691 next; 692 } elsif (/\s*\d+\s+(\S+\s+\d+\s+)(\d+\s+\w+\s+\d+\s+\d+:\d+)/ || 693 /\s*\d+\s+(\S+\s+\d+\s+)(\d+\s+\w+\s+\d+\s+\d{4})/) { 694 # XR >= 6.3; dir disk0:, but harddisk: is diff format. wtf 695 my($perm, $dt, $rem) = ($1, $2, $'); 696 ProcessHistory("FLASH","keysort",$rem,"!Flash: $dev: $perm$dt$rem"); 697 next; 698 } elsif (/\s*\d+\s+(\S+\s+)(\d+)(\s+)(\w+ \w+\s+\d+ \d+:\d+:\d+ \d+)/) { 699 # XR < 6.3 & etc. 700 my($b, $sz, $c, $dt, $rem) = ($1, $2, $3, $4, $'); 701 ProcessHistory("FLASH","keysort",$rem,"!Flash: $dev: $b$sz$c$dt$rem"); 702 next; 703 } 704 } 705 } 706 707 # XR: 822083584 bytes total (821081600 bytes free) 708 # eXR: 990484 kbytes total (813208 kbytes free) 709 if (/^\s*(\d+ k?bytes) total\s+\((\d+ k?bytes) free\)/i) { 710 ProcessHistory("FLASH","","","!Flash: $dev: " . 711 diskszsummary($1, $2) . "\n"); 712 next; 713 } 714 715 ProcessHistory("FLASH","","","!Flash: $dev: $_"); 716 } 717 ProcessHistory("","","","!\n"); 718 return(0); 719} 720 721# This routine parses "admin show variables boot" 722sub ShowBootVar { 723 my($INPUT, $OUTPUT, $cmd) = @_; 724 print STDERR " In ShowBootVar: $_" if ($debug); 725 726 while (<$INPUT>) { 727 # delete non-ascii chars, except new line 728 tr/ -~\n//cd; 729 last if (/^$prompt/); 730 next if (/\s*$cmd\s*$/); 731 # filter the bloody cmd-line timestamp 732 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 733 return(1) if (/^\s*\^\s*$/); 734 return(1) if (/Line has invalid autocommand /); 735 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 736 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 737 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 738 return(1) if (/Ambiguous command/i); 739 return(1) if (/(Open device \S+ failed|Error opening \S+:)/); 740 return(-1) if (/command authorization failed/i); 741 742 # skip blank lines 743 next if (/^\s*$/); 744 # NCS junk 745 next if (/^\S+ connected from 127.0.0.1 using console /); 746 next if (/# terminal length 0$/); 747 748 ProcessHistory("COMMENTS", "keysort", "C30", "! $_"); 749 } 750 ProcessHistory("COMMENTS", "keysort", "C39", "!\n"); 751 752 return(0); 753} 754 755# This routine parses "show controllers" 756sub ShowContAll { 757 my($INPUT, $OUTPUT, $cmd) = @_; 758 my($INT); 759 print STDERR " In ShowContAll: $_" if ($debug); 760 761 while (<$INPUT>) { 762 tr/\015//d; 763 last if (/^$prompt/); 764 next if (/^(\s*|\s*$cmd\s*)$/); 765 # filter the bloody cmd-line timestamp 766 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 767 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 768 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 769 # return(1) if ($type =~ /^(12[40]|7[05])/); 770 return(-1) if (/command authorization failed/i); 771 772 if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; } 773 /^(BRI unit \d)/ && 774 ProcessHistory("INT","","","!Interface: $1\n") && next; 775 /^LANCE unit \d, NIM/ && 776 ProcessHistory("INT","","","!Interface: $_") && next; 777 /^(LANCE unit \d)/ && 778 ProcessHistory("INT","","","!Interface: $1\n") && next; 779 /(Media Type is \S+),/ && 780 ProcessHistory("INT","","","!\t$1\n"); 781 if (/(M\dT[^ :]*:) show controller:$/) { 782 my($ctlr) = $1; 783 $_ = <$INPUT>; tr/\015//d; s/ subunit \d,//; 784 ProcessHistory("INT","","","!Interface: $ctlr $_"); 785 } 786 if (/^(\S+) : show controller:$/) { 787 my($ctlr) = $1; 788 $_ = <$INPUT>; tr/\015//d; s/ subunit \d,//; 789 ProcessHistory("INT","","","!Interface: $ctlr: $_"); 790 } 791 /^(HD unit \d), idb/ && 792 ProcessHistory("INT","","","!Interface: $1\n") && next; 793 /^HD unit \d, NIM/ && 794 ProcessHistory("INT","","","!Interface: $_") && next; 795 /^buffer size \d+ HD unit \d, (.*)/ && 796 ProcessHistory("INT","","","!\t$1\n") && next; 797 /^AM79970 / && ProcessHistory("INT","","","!Interface: $_") && next; 798 /^buffer size \d+ (Universal Serial: .*)/ && 799 ProcessHistory("INT","","","!\t$1\n") && next; 800 /^Hardware is (.*)/ && 801 ProcessHistory("INT","","","!Interface: $INT$1\n") && next; 802 /^(QUICC Serial unit \d),/ && 803 ProcessHistory("INT","","","!$1\n") && next; 804 /^QUICC Ethernet .*/ && 805 ProcessHistory("INT","","","!$_") && next; 806 /^DTE .*\.$/ && 807 ProcessHistory("INT","","","!\t$_") && next; 808 /^(cable type :.*),/ && 809 ProcessHistory("INT","","","!\t$1\n") && next; 810 /^(.* cable.*), received clockrate \d+$/ && 811 ProcessHistory("INT","","","!\t$1\n") && next; 812 /^.* cable.*$/ && 813 ProcessHistory("INT","","","!\t$_") && next; 814 } 815 return(0); 816} 817 818# This routine parses "show debug" 819sub ShowDebug { 820 my($INPUT, $OUTPUT, $cmd) = @_; 821 print STDERR " In ShowDebug: $_" if ($debug); 822 my($lines) = 0; 823 824 while (<$INPUT>) { 825 tr/\015//d; 826 last if (/^$prompt/); 827 next if (/^(\s*|\s*$cmd\s*)$/); 828 # filter the bloody cmd-line timestamp 829 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 830 return(1) if (/Line has invalid autocommand /); 831 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 832 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 833 return(-1) if (/command authorization failed/i); 834 835 /^No matching debug flags set$/ && next; 836 /^No debug flags set$/ && next; 837 ProcessHistory("COMMENTS","keysort","J1","!DEBUG: $_"); 838 $lines++; 839 } 840 if ($lines) { 841 ProcessHistory("COMMENTS","keysort","J0","!\n"); 842 } 843 return(0); 844} 845 846# This routine parses "admin show install active" 847sub ShowInstallSummary { 848 my($INPUT, $OUTPUT, $cmd) = @_; 849 print STDERR " In ShowInstallSummary: $_" if ($debug); 850 851 while (<$INPUT>) { 852 # delete non-ascii chars, except new line 853 tr/ -~\n//cd; 854 last if (/^$prompt/); 855 next if (/\s*$cmd\s*$/); 856 # filter the bloody cmd-line timestamp 857 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 858 return(1) if (/^\s*\^\s*$/); 859 return(1) if (/Line has invalid autocommand /); 860 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 861 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 862 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 863 return(1) if (/Ambiguous command/i); 864 return(1) if (/(Open device \S+ failed|Error opening \S+:)/); 865 return(-1) if (/command authorization failed/i); 866 return(-1) if (/inventory summary cannot be output/i); # temp error 867 return(-1) if (/currently affected by install operation/i);# temp error 868 return(-1) if (/install director is not up or ready/i);# temp error 869 870 # skip blank lines 871 next if (/^\s*$/); 872 # NCS junk 873 next if (/^\S+ connected from 127.0.0.1 using console /); 874 next if (/# terminal length 0$/); 875 876 ProcessHistory("COMMENTS", "keysort", "C15", "!Image: $_"); 877 } 878 ProcessHistory("COMMENTS", "keysort", "C10", "!\n"); 879 ProcessHistory("COMMENTS", "keysort", "C19", "!\n"); 880 881 return(0); 882} 883 884# This routine parses "show inventory". 885sub ShowInventory { 886 my($INPUT, $OUTPUT, $cmd) = @_; 887 print STDERR " In ShowInventory: $_" if ($debug); 888 889 while (<$INPUT>) { 890 # delete non-ascii chars, except new line 891 tr/ -~\n//cd; 892 return if (/^\s*\^$/); 893 last if (/^$prompt/); 894 next if (/^(\s*|\s*$cmd\s*)$/); 895 # filter the bloody cmd-line timestamp 896 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 897 return(1) if (/Line has invalid autocommand /); 898 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 899 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 900 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 901 return(-1) if (/command authorization failed/i); 902 903 # NCS junk 904 next if (/^\S+ connected from 127.0.0.1 using console /); 905 next if (/# terminal length 0$/); 906 907 # remove spaces after quotes 908 s/\"\s+/\"/g; 909 if (/^(name: "[^"]*",) (descr: "[^"]+")/i) { 910 ProcessHistory("INVENTORY","","", sprintf("!%-30s %s\n", $1, $2)); 911 next; 912 } 913 914 # XR flavor: 915 # NAME: "module 0/RSP0/CPU0", DESCR: "ASR9K Route Switch Processor with 880G/slot Fabric and 32GB" 916 # PID: A9K-RSP880-SE, VID: V01, SN: FOC1911VC2S 917 # 918 # eXR flavor: 919 # NAME: "0/RSP0-Motherboard", DESCR: "Motherboard Module" 920 # PID: N/A , VID: N/A , SN: N/A 921 # split PID/VID/SN line 922 if (/^ ?PID: (\S*)\s*, VID: (\S*)\s*,\s* SN: (\S*)\s*$/) { 923 my($pid,$vid,$sn) = ($1, $2, $3); 924 my($entries) = ""; 925 # filter <empty>, "0x" and "N/A" lines 926 if ($pid !~ /^(|0x|N\/A)$/) { 927 $entries .= "!PID: $pid\n"; 928 } 929 if ($vid !~ /^(|0x|N\/A)$/) { 930 $entries .= "!VID: $vid\n"; 931 } 932 if ($sn !~ /^(|0x|N\/A)$/) { 933 $entries .= "!SN: $sn\n"; 934 } 935 ProcessHistory("INVENTORY","","", "$entries"); 936 next; 937 } 938 ProcessHistory("INVENTORY","","","!$_"); 939 } 940 ProcessHistory("INVENTORY","","","!\n"); 941 942 return(0); 943} 944 945# This routine parses "admin show license" & "admin show license udi" 946sub ShowLicense { 947 my($INPUT, $OUTPUT, $cmd) = @_; 948 print STDERR " In ShowLicense: $_" if ($debug); 949 950 while (<$INPUT>) { 951 tr/\015//d; 952 # delete non-ascii chars, except new line 953 last if (/^$prompt/); 954 next if (/\s*$cmd\s*$/); 955 # filter the bloody cmd-line timestamp 956 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 957 return(1) if (/^\s*\^\s*$/); 958 next if (/^-+\^$/i); # NCS cmd-line error pointer 959 return(1) if (/Line has invalid autocommand /); 960 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 961 next if (/^(\e\[.\d+h)?sysadmin-vm:[^#]+# /i); # NCS 962 return(1) if (/^syntax error: element does not exist$/i); # NCS 963 return(1) if (/^syntax error: unknown argument$/i); # NCS 964 return(1) if (/Ambiguous command/i); 965 return(1) if (/(Open device \S+ failed|Error opening \S+:)/); 966 return(-1) if (/command authorization failed/i); 967 968 # show lic on o/s w/o licenses 969 s/info\s*: //; 970 971 # file feature status line (ASR9k, others?) 972 next if (/\s*status: /i); 973 974 # skip blank lines 975 next if (/^\s*$/); 976 # NCS junk 977 next if (/^\S+ connected from 127.0.0.1 using console /); 978 next if (/# terminal length 0$/); 979 980 # filter the BS from license broker 981 next if (/(renewal attempt|communication attempt):/i); 982 next if (/next registration attempt:/i); # timestamp 983 next if (/(period used:|requested time:)/i); # show lic feature 984 if (/(^\s*(evaluation )?period (left|remaining):\s*)\d+/i) { 985 ProcessHistory("COMMENTS","keysort","LICENSE","! $1<limited>\n"); 986 next; 987 } 988 989 # drop license counts 990 next if (/license usage:/i); 991 if (/(.*)count status/i) { 992 my($hdr) = $1; 993 my($len) = length($hdr); 994 995 $hdr =~ s/\s*$//; 996 ProcessHistory("COMMENTS", "keysort", "C20", "! $hdr\n"); 997 while (<$INPUT>) { 998 tr/\015//d; 999 return(0) if (/^$prompt/); 1000 1001 s/^(.{1,$len}).*/$1/; 1002 ProcessHistory("COMMENTS", "keysort", "C20", "! $_"); 1003 } 1004 next; 1005 } 1006 ProcessHistory("COMMENTS", "keysort", "C20", "! $_"); 1007 } 1008 ProcessHistory("COMMENTS", "keysort", "C20", "!\n"); 1009 1010 return(0); 1011} 1012 1013# This routine parses "show rpl maximum" 1014sub ShowRPL { 1015 my($INPUT, $OUTPUT, $cmd) = @_; 1016 print STDERR " In ShowRPL: $_" if ($debug); 1017 1018 while (<$INPUT>) { 1019 tr/\015//d; 1020 last if (/^$prompt/); 1021 next if (/^(\s*|\s*$cmd\s*)$/); 1022 # filter the bloody cmd-line timestamp 1023 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 1024 return(1) if /^\s*\^\s*$/; 1025 return(1) if (/Line has invalid autocommand /); 1026 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 1027 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 1028 return(1) if (/Ambiguous command/i); 1029 return(-1) if (/command authorization failed/i); 1030 1031 ProcessHistory("COMMENTS","keysort","RPLMAX","! $_"); 1032 } 1033 ProcessHistory("COMMENTS","keysort","RPLMAX","!\n"); 1034 return(0); 1035} 1036 1037# This routine parses "show vlan" 1038sub ShowVLAN { 1039 my($INPUT, $OUTPUT, $cmd) = @_; 1040 print STDERR " In ShowVLAN: $_" if ($debug); 1041 1042 while (<$INPUT>) { 1043 tr/\015//d; 1044 last if (/^$prompt/); 1045 next if (/^(\s*|\s*$cmd\s*)$/); 1046 # filter the bloody cmd-line timestamp 1047 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 1048 return(1) if /^\s*\^\s*$/; 1049 return(1) if (/Line has invalid autocommand /); 1050 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 1051 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 1052 return(1) if (/Ambiguous command/i); 1053 return(-1) if (/command authorization failed/i); 1054 1055 ProcessHistory("COMMENTS","keysort","IO","!VLAN: $_"); 1056 } 1057 ProcessHistory("COMMENTS","keysort","IO","!\n"); 1058 return(0); 1059} 1060 1061# This routine processes a "write term" 1062sub WriteTerm { 1063 my($INPUT, $OUTPUT, $cmd) = @_; 1064 print STDERR " In WriteTerm: $_" if ($debug); 1065 my($lineauto,$comment,$linecnt) = (0,0,0); 1066 1067 while (<$INPUT>) { 1068REPEAT: tr/\015//d; 1069 last if (/^$prompt/); 1070 # filter the bloody cmd-line timestamp 1071 next if (/^\w{3} \w{3,4} {1,3}\d{1,2} {1,2}\d{1,2}:\d+:\d+\.\d+ \S+$/); 1072 return(1) if (!$linecnt && /^\s+\^\s*$/); 1073 return(1) if (/Line has invalid autocommand /); 1074 return(1) if (/(Invalid (input|command) detected|Type help or )/i); 1075 return(1) if (/^(-+\^|syntax error: unknown argument)$/i); # NCS 1076 return(1) if (/\%Error: No such file or directory/); 1077 return(0) if ($found_end); # Only do this routine once 1078 return(-1) if (/command authorization failed/i); 1079 return(-1) if (/% ?configuration buffer full/i); 1080 /^! no configuration change since last restart/i && next; 1081 # skip emtpy lines at the beginning 1082 if (!$linecnt && /^\s*$/) { 1083 next; 1084 } 1085 if (!$linecnt && defined($config_register)) { 1086 ProcessHistory("","","", "!\nconfig-register $config_register\n"); 1087 } 1088 1089 # NCS junk 1090 next if (/^\S+ connected from 127.0.0.1 using console /); 1091 next if (/# terminal length 0$/); 1092 1093 /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked 1094 /% Configuration buffer full, / && return(-1); # buffer is in use 1095 $linecnt++; 1096 $lineauto = 0 if (/^[^ ]/); 1097 # skip the crap 1098 if (/^(##+|(building|current) configuration)/i) { 1099 while (<$INPUT>) { 1100 next if (/^Current configuration\s*:/i); 1101 next if (/^:/); 1102 next if (/^([%!].*|\s*)$/); 1103 next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S 1104 last; 1105 } 1106 tr/\015//d; 1107 } 1108 # some versions have other crap mixed in with the bits in the 1109 # block above 1110 /^! (Last configuration|NVRAM config last)/ && next; 1111 # and for the ASA 1112 /^: (Written by \S+ at|Saved)/ && next; 1113 1114 # skip consecutive comment lines to avoid oscillating extra comment 1115 # line on some access servers. grrr. 1116 if (/^!\s*$/) { 1117 next if ($comment); 1118 ProcessHistory("","","",$_); 1119 $comment++; 1120 next; 1121 } 1122 $comment = 0; 1123 1124 # Dog gone Cool matches to process the rest of the config 1125 /^tftp-server flash / && next; # kill any tftp remains 1126 /^ntp clock-period / && next; # kill ntp clock-period 1127 /^ length / && next; # kill length on serial lines 1128 /^ width / && next; # kill width on serial lines 1129 $lineauto = 1 if /^ modem auto/; 1130 /^ speed / && $lineauto && next; # kill speed on serial lines 1131 /^ clockrate / && next; # kill clockrate on serial interfaces 1132 if (/^(enable )?(password|passwd)( level \d+)? / && $filter_pwds >= 1) { 1133 ProcessHistory("ENABLE","","","!$1$2$3 <removed>\n"); 1134 next; 1135 } 1136 if (/^(enable secret) / && $filter_pwds >= 2) { 1137 ProcessHistory("ENABLE","","","!$1 <removed>\n"); 1138 next; 1139 } 1140 if (/^username (\S+)(\s.*)? secret /) { 1141 if ($filter_pwds >= 2) { 1142 ProcessHistory("USER","keysort","$1", 1143 "!username $1$2 secret <removed>\n"); 1144 } else { 1145 ProcessHistory("USER","keysort","$1","$_"); 1146 } 1147 next; 1148 } 1149 if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { 1150 if ($filter_pwds >= 2) { 1151 ProcessHistory("USER","keysort","$1", 1152 "!username $1$2 password <removed>\n"); 1153 } elsif ($filter_pwds >= 1 && $4 ne "5"){ 1154 ProcessHistory("USER","keysort","$1", 1155 "!username $1$2 password <removed>\n"); 1156 } else { 1157 ProcessHistory("USER","keysort","$1","$_"); 1158 } 1159 next; 1160 } 1161 if (/^( set session-key (in|out)bound ah \d+ )/ && $filter_pwds >= 1) { 1162 ProcessHistory("","","","!$1<removed>\n"); 1163 next; 1164 } 1165 if (/^( set session-key (in|out)bound esp \d+ (authenticator|cypher) )/ 1166 && $filter_pwds >= 1) { 1167 ProcessHistory("","","","!$1<removed>\n"); 1168 next; 1169 } 1170 if (/^(\s*)password / && $filter_pwds >= 1) { 1171 ProcessHistory("LINE-PASS","","","!$1password <removed>\n"); 1172 next; 1173 } 1174 if (/^(\s*)secret / && $filter_pwds >= 2) { 1175 ProcessHistory("LINE-PASS","","","!$1secret <removed>\n"); 1176 next; 1177 } 1178 if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { 1179 ProcessHistory("","","","! neighbor $1 password <removed>\n"); 1180 next; 1181 } 1182 if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) { 1183 ProcessHistory("","","","!$1 <removed>\n"); next; 1184 } 1185 if (/^(ip ftp password) / && $filter_pwds >= 1) { 1186 ProcessHistory("","","","!$1 <removed>\n"); next; 1187 } 1188 if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { 1189 ProcessHistory("","","","!$1 <removed>\n"); next; 1190 } 1191 # isis passwords appear to be completely plain-text 1192 if (/^\s+isis password (\S+)( .*)?/ && $filter_pwds >= 1) { 1193 ProcessHistory("","","","!isis password <removed>$2\n"); next; 1194 } 1195 if (/^\s+(domain-password|area-password) (\S+)( .*)?/ 1196 && $filter_pwds >= 1) { 1197 ProcessHistory("","","","!$1 <removed>$3\n"); next; 1198 } 1199 # this is reversable, despite 'md5' in the cmd 1200 if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { 1201 ProcessHistory("","","","!$1 <removed>\n"); next; 1202 } 1203 # this is also reversable, despite 'md5 encrypted' in the cmd 1204 if (/^( message-digest-key \d+ md5 (7|encrypted)) / 1205 && $filter_pwds >= 1) { 1206 ProcessHistory("","","","!$1 <removed>\n"); next; 1207 } 1208 if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) { 1209 ProcessHistory("","","","!$1 <removed> $'"); next; 1210 } 1211 # filter HSRP passwords 1212 if (/^(\s+standby \d+ authentication) / && $filter_pwds >= 1) { 1213 ProcessHistory("","","","!$1 <removed>\n"); next; 1214 } 1215 # this appears in "measurement/sla" images 1216 if (/^(\s+key-string \d?)/ && $filter_pwds >= 1) { 1217 ProcessHistory("","","","!$1 <removed>\n"); next; 1218 } 1219 if (/^( l2tp tunnel \S+ password)/ && $filter_pwds >= 1) { 1220 ProcessHistory("","","","!$1 <removed>\n"); next; 1221 } 1222 # i am told these are plain-text on the PIX 1223 if (/^(vpdn username (\S+) password)/) { 1224 if ($filter_pwds >= 1) { 1225 ProcessHistory("USER","keysort","$2","!$1 <removed>\n"); 1226 } else { 1227 ProcessHistory("USER","keysort","$2","$_"); 1228 } 1229 next; 1230 } 1231 # ASA/PIX keys in more system:running-config 1232 if (/^( pre-shared-key | key |failover key ).*/ && $filter_pwds >= 1) { 1233 ProcessHistory("","","","!$1 <removed> $'"); next; 1234 } 1235 if (/(\s+ldap-login-password )\S+(.*)/ && $filter_pwds >= 1) { 1236 ProcessHistory("","","","!$1 <removed> $'"); next; 1237 } 1238 # 1239 if (/^( cable shared-secret )/ && $filter_pwds >= 1) { 1240 ProcessHistory("","","","!$1 <removed>\n"); 1241 next; 1242 } 1243 /fair-queue individual-limit/ && next; 1244 # sort ip explicit-paths. 1245 if (/^ip explicit-path name (\S+)/) { 1246 my($key) = $1; 1247 my($expath) = $_; 1248 while (<$INPUT>) { 1249 tr/\015//d; 1250 last if (/^$prompt/); 1251 last if (! /^(ip explicit-path name |[ !])/); 1252 if (/^ip explicit-path name (\S+)/) { 1253 ProcessHistory("EXPATH","keysort","$key","$expath"); 1254 $key = $1; 1255 $expath = $_; 1256 } else { 1257 $expath .= $_; 1258 } 1259 } 1260 ProcessHistory("EXPATH","keysort","$key","$expath"); 1261 } 1262 # sort route-maps 1263 if (/^route-map (\S+)/) { 1264 my($key) = $1; 1265 my($routemap) = $_; 1266 while (<$INPUT>) { 1267 tr/\015//d; 1268 last if (/^$prompt/ || ! /^(route-map |[ !])/); 1269 if (/^route-map (\S+)/) { 1270 ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); 1271 $key = $1; 1272 $routemap = $_; 1273 } else { 1274 $routemap .= $_; 1275 } 1276 } 1277 ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); 1278 } 1279 # filter out any RCS/CVS tags to avoid confusing local CVS storage 1280 s/\$(Revision|Id):/ $1:/; 1281 # order access-lists 1282 /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && 1283 ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; 1284 # order extended access-lists 1285 /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && 1286 ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; 1287 /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && 1288 ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; 1289 /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && 1290 ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; 1291 # sort ipv{4,6} access-lists 1292 if ($aclfilterseq && /^ipv(4|6) access-list (\S+)\s*$/) { 1293 my($nlri, $key) = ($1, $2); 1294 my($seq, $cmd); 1295 ProcessHistory("ACL $nlri $key","","","$_"); 1296 while (<$INPUT>) { 1297 tr/\015//d; 1298 goto REPEAT if (/^$prompt/ || !/^(\s|\d|!)/); 1299 if (/^\s*!/) { 1300 ProcessHistory("ACL $nlri $key !", "", "", "$_"); 1301 next; 1302 } 1303 # ipv4 access-list name 1304 # remark NTP 1305 # deny ipv4 host 224.0.1.1 any 1306 # deny ipv4 239.0.0.0 0.255.255.255 any 1307 # permit udp any eq 123 any 1308 # permit ipv4 nnn.nnn.nnn.nnn/nn any 1309 # permit nnn.nnn.nnn.nnn/nn 1310 # ipv6 access-list name 1311 # permit ipv6 host 2001:nnnn::nnnn any 1312 # permit ipv6 2001:nnn::/nnn any 1313 # permit 2001:nnnn::/64 any 1314 # permit udp any eq 123 any 1315 my($seq, $cmd, $resid) = ($_ =~ /^\s*(\d+) (\w+) (.+)/); 1316 if ($cmd =~ /(permit|deny)/) { 1317 my($ip); 1318 my(@w) = ($resid =~ /(\S+) (\S+) (\S+\s)?(.+)/); 1319 for (my($i) = 0; $i < $#w; $i++) { 1320 if ($w[$i] eq "any") { 1321 if ($nlri eq "ipv4") { 1322 $ip = "255.255.255.255/32"; 1323 } else { 1324 $ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"; 1325 } 1326 last; 1327 } elsif ($w[$i] =~ /^[:0-9]/ || 1328 $2[$i] =~ /^[a-fA-F]{1,4}:/) { 1329 $ip = $w[$i]; 1330 $ip =~ s/\s+$//; # trim trailing WS 1331 last; 1332 } 1333 } 1334 ProcessHistory("ACL $nlri $key $cmd", "$aclsort", "$ip", 1335 " $cmd $resid\n"); 1336 } else { 1337 ProcessHistory("ACL $nlri $key $cmd", "", "", 1338 " $cmd $resid\n"); 1339 } 1340 } 1341 } 1342 # order arp lists 1343 /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && 1344 ProcessHistory("ARP","$aclsort","$1","$_") && next; 1345 /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(.*)/ && 1346 ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") 1347 && next; 1348 if ($aclfilterseq) { 1349 /^ip(v4|v6) prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\S+)(.*)/ && 1350 ProcessHistory("PACL $2 $4","$aclsort","$5","ip$1 prefix-list $2 $4 $5$6\n") 1351 && next; 1352 } 1353 # order logging statements 1354 /^logging (\d+\.\d+\.\d+\.\d+)/ && 1355 ProcessHistory("LOGGING","ipsort","$1","$_") && next; 1356 # order/prune snmp-server host statements 1357 # we only prune lines of the form 1358 # snmp-server host a.b.c.d <community> 1359 if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { 1360 if ($filter_commstr) { 1361 my($ip) = $1; 1362 my($line) = "snmp-server host $ip"; 1363 my(@tokens) = split(' ', $'); 1364 my($token); 1365 while ($token = shift(@tokens)) { 1366 if ($token eq 'version') { 1367 $line .= " " . join(' ', ($token, shift(@tokens))); 1368 if ($token eq '3') { 1369 $line .= " " . join(' ', ($token, shift(@tokens))); 1370 } 1371 } elsif ($token eq 'vrf') { 1372 $line .= " " . join(' ', ($token, shift(@tokens))); 1373 } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { 1374 $line .= " " . $token; 1375 } else { 1376 $line = "!$line " . join(' ', ("<removed>", 1377 join(' ',@tokens))); 1378 last; 1379 } 1380 } 1381 ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); 1382 } else { 1383 ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); 1384 } 1385 next; 1386 } 1387 if (/^(snmp-server community) (\S+)/) { 1388 if ($filter_commstr) { 1389 ProcessHistory("SNMPSERVERCOMM","keysort","$_", 1390 "!$1 <removed>$'") && next; 1391 } else { 1392 ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; 1393 } 1394 } 1395 # prune tacacs/radius server keys 1396 if (/^((tacacs|radius)-server\s(\w*[-\s(\s\S+])*\s?key) (\d )?\w+/ 1397 && $filter_pwds >= 1) { 1398 ProcessHistory("","","","!$1 <removed>$'"); next; 1399 } 1400 # order clns host statements 1401 /^clns host \S+ (\S+)/ && 1402 ProcessHistory("CLNS","keysort","$1","$_") && next; 1403 # order alias statements 1404 /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; 1405 # delete ntp auth password - this md5 is a reversable too 1406 if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { 1407 ProcessHistory("","","","!$1 <removed>\n"); next; 1408 } 1409 # order ntp peers/servers 1410 if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { 1411 my($sortkey) = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); 1412 ProcessHistory("NTP","keysort",$sortkey,"$_"); 1413 next; 1414 } 1415 # order ip host statements 1416 /^ip host (\S+) / && 1417 ProcessHistory("IPHOST","keysort","$1","$_") && next; 1418 # order ip nat source static statements 1419 /^ip nat (\S+) source static (\S+)/ && 1420 ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; 1421 # order atm map-list statements 1422 /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && 1423 ProcessHistory("ATM map-list","ipsort","$1","$_") && next; 1424 # order ip rcmd lines 1425 /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; 1426 1427 # system controller 1428 /^syscon address (\S*) (\S*)/ && 1429 ProcessHistory("","","","!syscon address $1 <removed>\n") && 1430 next; 1431 if (/^syscon password (\S*)/ && $filter_pwds >= 1) { 1432 ProcessHistory("","","","!syscon password <removed>\n"); 1433 next; 1434 } 1435 1436 /^ *Cryptochecksum:/ && next; 1437 1438 # catch anything that wasnt matched above. 1439 ProcessHistory("","","","$_"); 1440 # end of config. 1441 if (/^end$/) { 1442 $found_end = 1; 1443 return(0); 1444 } 1445 } 1446 1447 return(0); 1448} 1449 14501; 1451