Cisco-Version

 view release on metacpan or  search on metacpan

lib/Cisco/Version.pm  view on Meta::CPAN

		'chassis_type'			=>	'chassis-type',
		'memory'			=>	'memory',
		'confreg'			=>	'confreg',
		'pwdrecovery'			=>	'pwdrecovery',
		'flash_filesystems_sizes'	=>	'flash_filesystems_sizes',
		'flash_largest_size'		=>	'flash_largest_size',
	);



sub new()  {
	my ($this, $show_version) = @_;
	my  $class = ref($this) || $this;
	my  $self = {};	
	
	$self->{'show_version'} = $show_version;	# full output of "show version"
	
	$self->{'parsed'} = {};					#	this will contain hash of parsed parameters
	$self->{'not_found'} = '<NOT FOUND>';	#   this value is returned if a parameter was not found in show version

##      these are the possible values we can expect for now	

lib/Cisco/Version.pm  view on Meta::CPAN

    	if ($line =~ /of physical memory \(DRAM\)$/)              {  $self->_process_additional_memory($line); };
    	if ($line =~ /^Configuration register is/i)               {  $self->_process_configuration_register($line);  };
    	if ($line =~ /password-recovery mechanism/)               {  $self->_process_password_recovery($line);  };
    	if ($line =~ /^[0-9]+K .*(?:PCMCIA |[fF]lash[^-]|ATA )/)  {  $self->_process_flash($line);  };
    }

}



sub AUTOLOAD()  {
	my ($self,@args) = @_;
	my $cmd = $Cisco::Version::AUTOLOAD;
	my $parm;
	
	$cmd =~ s/.*:://;
	$parm = $cmd;
	$parm =~ s/get_//;
	
	if ( ($cmd =~ /^get_/) && (defined($CMD{"$parm"})) )  {
		return $self->get_parameter($parm);
	}
	else {
		croak("function $cmd does not exist");
	}
}




sub get_parameter()  {
	my ($self, $parm) = @_;
	
	if (defined($self->{'parsed'}->{$CMD{"$parm"}}))  {
		return $self->{'parsed'}->{$CMD{"$parm"}};
	}
	else  {
		return  $self->{'not_found'};
	}
}


##
## returns a reference to the 'parsed' hash,
## this contains all the elements that were found in 'show version'
##
sub get_summary()  {
	my ($self) = shift;
	
	return $self->{'parsed'};
}


sub get_not_found_value()  {
	my ($self) = shift;
	
	return $self->{'not_found'};
}

sub set_not_found_value()  {
	my ($self, $value) = @_;
	
	$self->{'not_found'} = $value if (defined($value));
}


## look for bootstrap version
sub _process_rom()  {
	my ($self, $line) = @_;
	my $version;
	
	&_debug("parsing bootstrap", $line);
	
	if ( ($line !~ /(?:bootstrap|ROM: [0-9]+\.[0-9]+)/i) || ($line =~ /bootstrap program/i) )  {
		&_info("IGNORE - $line");
	}
	
	else  {

lib/Cisco/Version.pm  view on Meta::CPAN

			
			&_debug("result = $version");
		}
		else  {
			&_warn("bootstrap version not found", $line);
		}
	}
}


sub _process_software_version()  {
	my ($self, $line) = @_;
	my ($sw_version, $sw_type, $sw_featureset);

	&_debug("parsing software version", $line);
	
	if ($line =~ /^(?:Cisco IOS Software|IOS \(tm\))[, ]+(.*) Software \((.*)\).*Version ([^ ,]+)/)  {
		$sw_type = $1;
		$sw_featureset = $2;
		$sw_version = $3;
		

lib/Cisco/Version.pm  view on Meta::CPAN

		&_debug("result = $sw_featureset");
		&_debug("result = $sw_version");
	}
	else  {
		&_error("software version, type or featureset cannot be parsed", $line);
	}
}



sub _process_bootloader()  {
	my ($self, $line) = @_;
	my ($bl_version, $bl_type, $bl_featureset);

	&_debug("parsing bootloader", $line);

	if ($line =~ /^BOOTLDR: (.*) (?:Software|Boot Loader) \((.*)\).*Version ([^ ,]+)/)  {
		$bl_type = $1;
		$bl_featureset = $2;
		$bl_version = $3;
		

lib/Cisco/Version.pm  view on Meta::CPAN

		&_debug("result = $bl_featureset");
		&_debug("result = $bl_version");
	}
	else  {
		&_error("bootloader version, type or featureset cannot be parsed", $line);
	}
}



sub _process_uptime()  {
	my ($self, $line) = @_;
	my ($host, $uptime);

	&_debug("parsing uptime", $line);
	
	if ($line =~ /^ *(?:(.*) uptime is|Switch Uptime|Uptime for this control processor is)[^0-9]+(.*minutes*)/)  {
		if ($1 && $2)  {
			$host = $1;
			$self->{'parsed'}->{'hostname'} = $host;
		}

lib/Cisco/Version.pm  view on Meta::CPAN


		&_debug("result = $uptime");
	}
	else  {
		&_error("uptime cannot be parsed", $line);
	}
}



sub _process_reload_reason()  {
	my ($self, $line) = @_;
	my $reason;

	&_debug("parsing reload reason", $line);
	
	if ($line =~ /System returned to ROM by (.*)/)  {
		$reason = $1;
		($reason)?($self->{'parsed'}->{'reload-reason'} = $reason):(&_warn("reload reason was not found", $line));

		&_debug("result = $reason");
	}
	else  {
		&_error("reload reason cannot be parsed", $line);
	}
}


sub _process_reload_time()  {
	my ($self, $line) = @_;
	my $time;

	&_debug("parsing reload time", $line);
	
	if ($line =~ /restarted.* at (.*)/)  {
		$time = $1;
		($time)?($self->{'parsed'}->{'reload-time'} = $time):(&_warn("reload time was not found", $line));

		&_debug("result = $time");
	}
	else  {
		&_error("reload time cannot be parsed", $line);
	}
}


sub _process_image_file()  {
	my ($self, $line) = @_;
	my $image;

	&_debug("parsing image file info", $line);
	
	if ($line =~ /System image file is \"(.*)\"/)  {
		$image = $1;
		($image)?($self->{'parsed'}->{'image-file'} = $image):(&_warn("image file was not found", $line));

		&_debug("result = $image");

lib/Cisco/Version.pm  view on Meta::CPAN

	}
}


##
## tries to calculate the memory
## This is no exact science so be careful ...
##  Here's how we do it by default to get memory in MB : (main memory + shared IO memory) / 1024
## But there are a few exceptions.
## 
sub _process_memory()  {
	my ($self, $line) = @_;
	my ($memory, $chassis);
	my ($main_mem, $io_mem);

	&_debug("parsing memory", $line);
	
	if ($line =~ /cisco ([^ ]+).*with (?:([0-9]+)K |([0-9]+)K\/([0-9]+)K).*memory.*/i)  {
		$chassis = $1;
		
		if ($3 && $4)  {

lib/Cisco/Version.pm  view on Meta::CPAN

		&_error("memory or chassis type cannot be parsed", $line);
	}
}



##
## some smaller routers have extra line with 'additional' DRAM
## this should be added to the RAM we already found
##
sub _process_additional_memory() {
	my ($self, $line) = @_;
	my ($memory);
	
	if ($line =~ /([0-9]+)M .* of physical memory \(DRAM\)$/)  {
		$memory = int($1 + .5);

		($memory)?($self->{'parsed'}->{'memory'} = $self->{'parsed'}->{'memory'} + $memory):(&_warn("additional DRAM was not found", $line));
	}
	else  {
		&_error("unable to parse additional DRAM", $line);
	}
}




sub _process_configuration_register()  {
	my ($self, $line) = @_;
	my ($confreg);

	&_debug("parsing configuration register", $line);
	
	if ($line =~ /^Configuration register is (.*)/)  {
		$confreg = $1;
		
		($confreg)?($self->{'parsed'}->{'confreg'} = $confreg):(&_warn("configuration register was not found", $line));

		&_debug("result = $confreg");
	}
	else  {
		&_error("unable to parse configuration register", $line);
	}
}


sub _process_password_recovery()  {
	my ($self, $line) = @_;
	my ($recovery);

	&_debug("parsing password recovery mechanism", $line);
	
	if ($line =~ /password-recovery mechanism is ([a-zA-Z]+)/)  {
		$recovery = $1;

		($recovery)?($self->{'parsed'}->{'pwdrecovery'} = $recovery):(&_warn("password recovery mechanism was not found", $line));

lib/Cisco/Version.pm  view on Meta::CPAN


##
## Flash info is also difficult to parse as a chassis may have multiple
## filesystems. Also not all chassis types report flash info.
## Usually we're only interested in largest filesystem only so this is what 
## we try to parse :
##
## List of all flash filesystem sizes is kept as flash_filesystems_sizes
## Largest flash filesystem is reported as flash_largest_size
##
sub _process_flash()  {
	my ($self, $line) = @_;
	my ($flash);
	
	&_debug("parsing flash info", $line);
	
	if ($line =~ /^([0-9]+)K .*(?:PCMCIA |[fF]lash[^-]|ATA )/)  {
		$flash = int(($1 / 1024) + .5);
		
		if ($flash)  {
			if (!defined($self->{'parsed'}->{'flash_filesystems_sizes'}))	{

lib/Cisco/Version.pm  view on Meta::CPAN

	else  {
		&_error("unable to parse flash", $line);
	}
}



##
## carp a log message, regardless of $DEBUG value
##
sub _log()  {
	my ($msg, $line) = @_;
	
	if ($line)  {
		$msg = $msg . " [$line]";
	}
	
	&carp($msg);
}


##
## carp a log message, only if $DEBUG >= 1
##
sub _error()  {
	my ($msg, $line) = @_;
	
	if ($DEBUG >= 1)  {
		&_log("ERROR: ".$msg, $line);
	}
}


##
## carp a log message, only if $DEBUG >= 2
##
sub _warn()  {
	my ($msg, $line) = @_;
	
	if ($DEBUG >= 2)  {
		&_log("WARN: ".$msg, $line);
	}
}


##
## carp a log message, only if $DEBUG >= 3
##
sub _info()  {
	my ($msg, $line) = @_;
	
	if ($DEBUG >= 3)  {
		&_log("INFO: ".$msg, $line);
	}
}


##
## carp a log message, only if $DEBUG >= 3
##
sub _debug()  {
	my ($msg, $line) = @_;
	
	if ($DEBUG >= 4)  {
		&_log("DEBUG: ".$msg, $line);
	}
}

1; # End of Cisco::Version


t/test_parse_show_version.pl  view on Meta::CPAN

print "'not found value' = ", $sv->get_not_found_value(), "\n";

## let's print a dump of all the parameters we found
print &Dumper($sv->get_summary());


##
## this is an example output of a Cisco router 'show version'
## put your own version to test
##
sub sample_show_version()  {

return <<END

Cisco IOS Software, 2800 Software (C2800NM-ADVIPSERVICESK9-M), Version 12.4(8), RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2006 by Cisco Systems, Inc.
Compiled Mon 15-May-06 14:54 by prod_rel_team

ROM: System Bootstrap, Version 12.4(1r) [hqluong 1r], RELEASE SOFTWARE (fc1)



( run in 0.266 second using v1.01-cache-2.11-cpan-1f129e94a17 )