| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package App::Manoc::Manifold::SNMP::Simple; | 
| 2 |  |  |  |  |  |  | #ABSTRACT: A simple client based on Net::SNMP | 
| 3 |  |  |  |  |  |  |  | 
| 4 | 1 |  |  | 1 |  | 6 | use Moose; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 5 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | our $VERSION = '2.99.2'; ##TRIAL VERSION | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | with | 
| 10 |  |  |  |  |  |  | 'App::Manoc::ManifoldRole::Base', | 
| 11 |  |  |  |  |  |  | 'App::Manoc::ManifoldRole::Host', | 
| 12 |  |  |  |  |  |  | 'App::Manoc::ManifoldRole::Hypervisor', | 
| 13 |  |  |  |  |  |  | 'App::Manoc::Logger::Role'; | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 | 1 |  |  | 1 |  | 5875 | use Net::SNMP 6.0 qw( :snmp DEBUG_ALL ENDOFMIBVIEW ); | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | use Carp qw(croak); | 
| 18 |  |  |  |  |  |  | use Try::Tiny; | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | has 'community' => ( | 
| 22 |  |  |  |  |  |  | is      => 'ro', | 
| 23 |  |  |  |  |  |  | isa     => 'Str', | 
| 24 |  |  |  |  |  |  | lazy    => 1, | 
| 25 |  |  |  |  |  |  | builder => '_build_community', | 
| 26 |  |  |  |  |  |  | ); | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | has 'version' => ( | 
| 30 |  |  |  |  |  |  | is      => 'ro', | 
| 31 |  |  |  |  |  |  | isa     => 'Str', | 
| 32 |  |  |  |  |  |  | lazy    => '1', | 
| 33 |  |  |  |  |  |  | builder => '_build_version', | 
| 34 |  |  |  |  |  |  | ); | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | has 'snmp_session' => ( | 
| 38 |  |  |  |  |  |  | is     => 'ro', | 
| 39 |  |  |  |  |  |  | isa    => 'Object', | 
| 40 |  |  |  |  |  |  | writer => '_set_snmp_session', | 
| 41 |  |  |  |  |  |  | ); | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | sub _build_community { | 
| 44 |  |  |  |  |  |  | my $self = shift; | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | return $self->credentials->{snmp_community} || 'public'; | 
| 47 |  |  |  |  |  |  | } | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | sub _build_version { | 
| 50 |  |  |  |  |  |  | my $self = shift; | 
| 51 |  |  |  |  |  |  | my $version = $self->credentials->{snmp_version} || 2; | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | my %version_map = ( | 
| 54 |  |  |  |  |  |  | '1'  => 'snmpv1', | 
| 55 |  |  |  |  |  |  | '2'  => 'snmpv2c', | 
| 56 |  |  |  |  |  |  | '2c' => 'snmpv2c', | 
| 57 |  |  |  |  |  |  | '3'  => 'snmpv3' | 
| 58 |  |  |  |  |  |  | ); | 
| 59 |  |  |  |  |  |  | return $version_map{$version}; | 
| 60 |  |  |  |  |  |  | } | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | sub connect { | 
| 64 |  |  |  |  |  |  | my ($self) = @_; | 
| 65 |  |  |  |  |  |  | my $opts = shift || {}; | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | my $info; | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | my %options; | 
| 70 |  |  |  |  |  |  | $options{-hostname} = $self->host; | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | my $extra_params = $self->extra_params; | 
| 73 |  |  |  |  |  |  | $options{-version}   = $self->version; | 
| 74 |  |  |  |  |  |  | $options{-community} = $self->community; | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | my @extra_options = qw(  -port -timeout -retries | 
| 77 |  |  |  |  |  |  | -localaddr -localport -username -authkey | 
| 78 |  |  |  |  |  |  | -authpassword -authprotocol | 
| 79 |  |  |  |  |  |  | -privkey -privpassword -privprotocol | 
| 80 |  |  |  |  |  |  | ); | 
| 81 |  |  |  |  |  |  | foreach (@extra_options) { | 
| 82 |  |  |  |  |  |  | $options{$_} = $extra_params->{$_} if exists $extra_params->{$_}; | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | # $options{-debug} = DEBUG_ALL | 
| 86 |  |  |  |  |  |  | #  if ( defined(_debug_level) && _debug_level > 1 ); | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | $options{-translate} = [ | 
| 89 |  |  |  |  |  |  | '-all'            => 1, | 
| 90 |  |  |  |  |  |  | '-octetstring'    => 0, | 
| 91 |  |  |  |  |  |  | '-null'           => 1, | 
| 92 |  |  |  |  |  |  | '-timeticks'      => 0, | 
| 93 |  |  |  |  |  |  | '-opaque'         => 1, | 
| 94 |  |  |  |  |  |  | '-nosuchobject'   => 1, | 
| 95 |  |  |  |  |  |  | '-nosuchinstance' => 1, | 
| 96 |  |  |  |  |  |  | '-endofmibview'   => 1, | 
| 97 |  |  |  |  |  |  | '-unsigned'       => 1, | 
| 98 |  |  |  |  |  |  | ]; | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | my $session; | 
| 101 |  |  |  |  |  |  | try { | 
| 102 |  |  |  |  |  |  | $session = Net::SNMP->session(%options); | 
| 103 |  |  |  |  |  |  | } | 
| 104 |  |  |  |  |  |  | catch { | 
| 105 |  |  |  |  |  |  | my $msg = "Could not connect to " . $self->host . " .$_"; | 
| 106 |  |  |  |  |  |  | $self->log->error($msg); | 
| 107 |  |  |  |  |  |  | return; | 
| 108 |  |  |  |  |  |  | }; | 
| 109 |  |  |  |  |  |  |  | 
| 110 |  |  |  |  |  |  | unless ($session) { | 
| 111 |  |  |  |  |  |  | $self->log->error( "Could not connect to ", $self->host ); | 
| 112 |  |  |  |  |  |  | return; | 
| 113 |  |  |  |  |  |  | } | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | $self->_set_snmp_session($session); | 
| 116 |  |  |  |  |  |  | return 1; | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | #----------------------------------------------------------------------# | 
| 120 |  |  |  |  |  |  | # | 
| 121 |  |  |  |  |  |  | #                 SNMP scalar and table declaration | 
| 122 |  |  |  |  |  |  | # | 
| 123 |  |  |  |  |  |  | #----------------------------------------------------------------------# | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | sub has_snmp_scalar { | 
| 127 |  |  |  |  |  |  | my ( $name, %options ) = @_; | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | my $oid = $options{oid} or croak "oid attribute is required"; | 
| 130 |  |  |  |  |  |  | my $munger = $options{munger}; | 
| 131 |  |  |  |  |  |  |  | 
| 132 |  |  |  |  |  |  | my $attr_name    = "snmp_$name"; | 
| 133 |  |  |  |  |  |  | my $builder_name = "_build_${attr_name}"; | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | has $attr_name => ( | 
| 136 |  |  |  |  |  |  | is      => 'ro', | 
| 137 |  |  |  |  |  |  | lazy    => 1, | 
| 138 |  |  |  |  |  |  | builder => "_build_${attr_name}" | 
| 139 |  |  |  |  |  |  | ); | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | { | 
| 142 |  |  |  |  |  |  | no strict 'refs'; | 
| 143 |  |  |  |  |  |  | *{$builder_name} = sub { | 
| 144 |  |  |  |  |  |  | my $self = shift; | 
| 145 |  |  |  |  |  |  | $self->_mib_read_scalar( $oid, $munger ); | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  | } | 
| 148 |  |  |  |  |  |  | } | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  | sub has_snmp_table { | 
| 152 |  |  |  |  |  |  | my ( $name, %options ) = @_; | 
| 153 |  |  |  |  |  |  | my $table_oid = $options{oid}; | 
| 154 |  |  |  |  |  |  | $table_oid or croak "Table $name has no oid"; | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | my $columns = $options{columns}; | 
| 157 |  |  |  |  |  |  | $columns or croak "Table $name has no columns definition"; | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | my @column_names = keys %$columns; | 
| 160 |  |  |  |  |  |  | while ( my ( $col_name, $col_opts ) = each(%$columns) ) { | 
| 161 |  |  |  |  |  |  | ref $col_opts eq 'ARRAY' or $col_opts = [$col_opts]; | 
| 162 |  |  |  |  |  |  | my ( $sub_id, $munger ) = @$col_opts; | 
| 163 |  |  |  |  |  |  | my $col_oid = "$table_oid.1.$sub_id"; | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | my $attr_name    = "snmp_$col_name"; | 
| 166 |  |  |  |  |  |  | my $builder_name = "_build_${attr_name}"; | 
| 167 |  |  |  |  |  |  |  | 
| 168 |  |  |  |  |  |  | has $attr_name => ( | 
| 169 |  |  |  |  |  |  | is      => 'ro', | 
| 170 |  |  |  |  |  |  | lazy    => 1, | 
| 171 |  |  |  |  |  |  | builder => $builder_name, | 
| 172 |  |  |  |  |  |  | ); | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | { | 
| 175 |  |  |  |  |  |  | no strict 'refs'; | 
| 176 |  |  |  |  |  |  | *{$builder_name} = sub { | 
| 177 |  |  |  |  |  |  | my $self = shift; | 
| 178 |  |  |  |  |  |  | $self->_mib_read_tablerow( $col_oid, $munger ); | 
| 179 |  |  |  |  |  |  | } | 
| 180 |  |  |  |  |  |  | } | 
| 181 |  |  |  |  |  |  | } | 
| 182 |  |  |  |  |  |  | } | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | my $SNMPV2_MIB_OID = '1.3.6.1.2.1.1'; | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | has_snmp_scalar "sysDescr"    => ( oid => "$SNMPV2_MIB_OID.1" ); | 
| 188 |  |  |  |  |  |  | has_snmp_scalar "sysObjectID" => ( oid => "$SNMPV2_MIB_OID.2" ); | 
| 189 |  |  |  |  |  |  | has_snmp_scalar "sysUpTime"   => ( oid => "$SNMPV2_MIB_OID.3" ); | 
| 190 |  |  |  |  |  |  | has_snmp_scalar "sysName"     => ( oid => "$SNMPV2_MIB_OID.5" ); | 
| 191 |  |  |  |  |  |  | has_snmp_scalar "sysLocation" => ( oid => "$SNMPV2_MIB_OID.6" ); | 
| 192 |  |  |  |  |  |  | has_snmp_scalar "sysServices" => ( oid => "$SNMPV2_MIB_OID.7" ); | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  |  | 
| 195 |  |  |  |  |  |  | my $HOST_RESOURCES_MIB_OID = '1.3.6.1.2.1.25'; | 
| 196 |  |  |  |  |  |  | has_snmp_table 'hrSWInstalledTable' => ( | 
| 197 |  |  |  |  |  |  | oid     => "$HOST_RESOURCES_MIB_OID.6.3", | 
| 198 |  |  |  |  |  |  | columns => { | 
| 199 |  |  |  |  |  |  | 'hrSWInstalledIndex' => 1, | 
| 200 |  |  |  |  |  |  | 'hrSWInstalledName'  => 2, | 
| 201 |  |  |  |  |  |  | 'hrSWInstalledID'    => 3, | 
| 202 |  |  |  |  |  |  | 'hrSWInstalledType'  => 4, | 
| 203 |  |  |  |  |  |  | 'hrSWInstalledDate'  => [ 5, \&_munge_sw_installed_date ], | 
| 204 |  |  |  |  |  |  | }, | 
| 205 |  |  |  |  |  |  | ); | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  |  | 
| 208 |  |  |  |  |  |  | has_snmp_table 'hrDeviceTable' => ( | 
| 209 |  |  |  |  |  |  | oid     => "$HOST_RESOURCES_MIB_OID.3.2", | 
| 210 |  |  |  |  |  |  | index   => 'hrDeviceIndex', | 
| 211 |  |  |  |  |  |  | columns => { | 
| 212 |  |  |  |  |  |  | 'hrDeviceType'   => 2, | 
| 213 |  |  |  |  |  |  | 'hrDeviceDescr'  => 3, | 
| 214 |  |  |  |  |  |  | 'hrDeviceID'     => 4, | 
| 215 |  |  |  |  |  |  | 'hrDeviceStatus' => [ | 
| 216 |  |  |  |  |  |  | 5, | 
| 217 |  |  |  |  |  |  | sub { | 
| 218 |  |  |  |  |  |  | my $val   = shift; | 
| 219 |  |  |  |  |  |  | my @stati = qw(INVALID unknown running warning testing down); | 
| 220 |  |  |  |  |  |  | return $stati[$val]; | 
| 221 |  |  |  |  |  |  | } | 
| 222 |  |  |  |  |  |  | ], | 
| 223 |  |  |  |  |  |  | 'hrDeviceErrors' => 6, | 
| 224 |  |  |  |  |  |  | }, | 
| 225 |  |  |  |  |  |  | ); | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  | has_snmp_table 'hrProcessorTable' => ( | 
| 229 |  |  |  |  |  |  | oid     => "$HOST_RESOURCES_MIB_OID.3.3", | 
| 230 |  |  |  |  |  |  | index   => 'hrDeviceIndex', | 
| 231 |  |  |  |  |  |  | columns => { | 
| 232 |  |  |  |  |  |  | 'hrProcessorLoad' => 2, | 
| 233 |  |  |  |  |  |  | }, | 
| 234 |  |  |  |  |  |  | ); | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  |  | 
| 237 |  |  |  |  |  |  | my $UCD_SNMP_MIB_OID = '.1.3.6.1.4.1.2021'; | 
| 238 |  |  |  |  |  |  | has_snmp_scalar 'memTotalReal' => ( oid => "${UCD_SNMP_MIB_OID}.4.5", ); | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  |  | 
| 241 |  |  |  |  |  |  | my $VMWARE_SYSTEM_MIB = '.1.3.6.1.4.1.6876.1'; | 
| 242 |  |  |  |  |  |  | has_snmp_scalar 'vmwProdName'    => ( oid => "${VMWARE_SYSTEM_MIB}.1", ); | 
| 243 |  |  |  |  |  |  | has_snmp_scalar 'vmwProdVersion' => ( oid => "${VMWARE_SYSTEM_MIB}.1", ); | 
| 244 |  |  |  |  |  |  |  | 
| 245 |  |  |  |  |  |  | my $VMWARE_VMINFO_MIB_OID = '.1.3.6.1.4.1.6876.2'; | 
| 246 |  |  |  |  |  |  | has_snmp_table 'vmwVmTable' => ( | 
| 247 |  |  |  |  |  |  | oid     => "$VMWARE_VMINFO_MIB_OID.1", | 
| 248 |  |  |  |  |  |  | index   => "vmwVmIdx", | 
| 249 |  |  |  |  |  |  | columns => { | 
| 250 |  |  |  |  |  |  | vmwVmIdx         => 1, | 
| 251 |  |  |  |  |  |  | vmwVmDisplayName => 2, | 
| 252 |  |  |  |  |  |  | vmwVmGuestOS     => 4, | 
| 253 |  |  |  |  |  |  | vmwVmMemSize     => 5, | 
| 254 |  |  |  |  |  |  | vmwVmState       => 6, | 
| 255 |  |  |  |  |  |  | vmwVmCpus        => 9, | 
| 256 |  |  |  |  |  |  | vmwVmUUID        => 10 | 
| 257 |  |  |  |  |  |  | }, | 
| 258 |  |  |  |  |  |  | ); | 
| 259 |  |  |  |  |  |  |  | 
| 260 |  |  |  |  |  |  | #----------------------------------------------------------------------# | 
| 261 |  |  |  |  |  |  |  | 
| 262 |  |  |  |  |  |  | sub _build_boottime { | 
| 263 |  |  |  |  |  |  | my $self = shift; | 
| 264 |  |  |  |  |  |  | return time() - int( $self->snmp_sysUpTime / 100 ); | 
| 265 |  |  |  |  |  |  | } | 
| 266 |  |  |  |  |  |  |  | 
| 267 |  |  |  |  |  |  | sub _build_name { | 
| 268 |  |  |  |  |  |  | my $self = shift; | 
| 269 |  |  |  |  |  |  | return $self->snmp_sysName; | 
| 270 |  |  |  |  |  |  | } | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | sub _build_model { | 
| 273 |  |  |  |  |  |  | my $self = shift; | 
| 274 |  |  |  |  |  |  | warn "TODO"; | 
| 275 |  |  |  |  |  |  | return; | 
| 276 |  |  |  |  |  |  | } | 
| 277 |  |  |  |  |  |  |  | 
| 278 |  |  |  |  |  |  | sub _build_os { | 
| 279 |  |  |  |  |  |  | my $self = shift; | 
| 280 |  |  |  |  |  |  |  | 
| 281 |  |  |  |  |  |  | my $descr  = $self->snmp_sysDescr; | 
| 282 |  |  |  |  |  |  | my $vendor = $self->vendor; | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | $vendor eq 'Microsoft' and $descr =~ /Software: Windows/ and return "Windows"; | 
| 285 |  |  |  |  |  |  |  | 
| 286 |  |  |  |  |  |  | if ( $vendor eq 'NetSNMP' ) { | 
| 287 |  |  |  |  |  |  | my @fields = split /\s+/, $descr; | 
| 288 |  |  |  |  |  |  | return $fields[0]; | 
| 289 |  |  |  |  |  |  | } | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | if ( $vendor eq 'Cisco' ) { | 
| 292 |  |  |  |  |  |  | return 'ios-xe'   if ( $descr =~ /IOS-XE/ ); | 
| 293 |  |  |  |  |  |  | return 'ios-xr'   if ( $descr =~ /IOS XR/ ); | 
| 294 |  |  |  |  |  |  | return 'ios'      if ( $descr =~ /IOS/ ); | 
| 295 |  |  |  |  |  |  | return 'catalyst' if ( $descr =~ /catalyst/i ); | 
| 296 |  |  |  |  |  |  | return 'css'      if ( $descr =~ /Content Switch SW/ ); | 
| 297 |  |  |  |  |  |  | return 'css-sca'  if ( $descr =~ /Cisco Systems Inc CSS-SCA-/ ); | 
| 298 |  |  |  |  |  |  | return 'pix'      if ( $descr =~ /Cisco PIX Security Appliance/ ); | 
| 299 |  |  |  |  |  |  | return 'asa'      if ( $descr =~ /Cisco Adaptive Security Appliance/ ); | 
| 300 |  |  |  |  |  |  | return 'san-os'   if ( $descr =~ /Cisco SAN-OS/ ); | 
| 301 |  |  |  |  |  |  | } | 
| 302 |  |  |  |  |  |  |  | 
| 303 |  |  |  |  |  |  | if ( $vendor eq 'VMWare' ) { | 
| 304 |  |  |  |  |  |  | my $prodname = $self->snmp_vmwProdName; | 
| 305 |  |  |  |  |  |  | return $prodname if defined($prodname); | 
| 306 |  |  |  |  |  |  | } | 
| 307 |  |  |  |  |  |  |  | 
| 308 |  |  |  |  |  |  | return ''; | 
| 309 |  |  |  |  |  |  | } | 
| 310 |  |  |  |  |  |  |  | 
| 311 |  |  |  |  |  |  | sub _build_os_ver { | 
| 312 |  |  |  |  |  |  | my $self   = shift; | 
| 313 |  |  |  |  |  |  | my $descr  = $self->snmp_sysDescr; | 
| 314 |  |  |  |  |  |  | my $vendor = $self->vendor; | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | $vendor eq 'Microsoft' and | 
| 317 |  |  |  |  |  |  | $descr =~ /Windows Version\s+([\d\.]+)/ and | 
| 318 |  |  |  |  |  |  | return $1; | 
| 319 |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  | if ( $vendor eq 'NetSNMP' ) { | 
| 321 |  |  |  |  |  |  | my @fields = split /\s+/, $descr; | 
| 322 |  |  |  |  |  |  | return $fields[2]; | 
| 323 |  |  |  |  |  |  | } | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | if ( $vendor eq 'Cisco' ) { | 
| 326 |  |  |  |  |  |  | my $os = $self->os; | 
| 327 |  |  |  |  |  |  |  | 
| 328 |  |  |  |  |  |  | if ( defined $os && defined $descr ) { | 
| 329 |  |  |  |  |  |  | # Older Catalysts | 
| 330 |  |  |  |  |  |  | if ( $os eq 'catalyst' && $descr =~ m/V(\d{1}\.\d{2}\.\d{2})/ ) { | 
| 331 |  |  |  |  |  |  | return $1; | 
| 332 |  |  |  |  |  |  | } | 
| 333 |  |  |  |  |  |  |  | 
| 334 |  |  |  |  |  |  | if ( $os eq 'css' && | 
| 335 |  |  |  |  |  |  | $descr =~ m/Content Switch SW Version ([0-9\.\(\)]+) with SNMPv1\/v2c Agent/ ) | 
| 336 |  |  |  |  |  |  | { | 
| 337 |  |  |  |  |  |  | return $1; | 
| 338 |  |  |  |  |  |  | } | 
| 339 |  |  |  |  |  |  |  | 
| 340 |  |  |  |  |  |  | if ( $os eq 'css-sca' && | 
| 341 |  |  |  |  |  |  | $descr =~ m/Cisco Systems Inc CSS-SCA-2FE-K9, ([0-9\.\(\)]+) Release / ) | 
| 342 |  |  |  |  |  |  | { | 
| 343 |  |  |  |  |  |  | return $1; | 
| 344 |  |  |  |  |  |  | } | 
| 345 |  |  |  |  |  |  |  | 
| 346 |  |  |  |  |  |  | if ( $os eq 'pix' && | 
| 347 |  |  |  |  |  |  | $descr =~ m/Cisco PIX Security Appliance Version ([0-9\.\(\)]+)/ ) | 
| 348 |  |  |  |  |  |  | { | 
| 349 |  |  |  |  |  |  | return $1; | 
| 350 |  |  |  |  |  |  | } | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | if ( $os eq 'asa' && | 
| 353 |  |  |  |  |  |  | $descr =~ m/Cisco Adaptive Security Appliance Version ([0-9\.\(\)]+)/ ) | 
| 354 |  |  |  |  |  |  | { | 
| 355 |  |  |  |  |  |  | return $1; | 
| 356 |  |  |  |  |  |  | } | 
| 357 |  |  |  |  |  |  |  | 
| 358 |  |  |  |  |  |  | if ( $os =~ /^fwsm/ && $descr =~ m/Version (\d+\.\d+(\(\d+\)){0,1})/ ) { | 
| 359 |  |  |  |  |  |  | return $1; | 
| 360 |  |  |  |  |  |  | } | 
| 361 |  |  |  |  |  |  |  | 
| 362 |  |  |  |  |  |  | if ( $os eq 'ios-xr' && $descr =~ m/Version (\d+[\.\d]+)/ ) { | 
| 363 |  |  |  |  |  |  | return $1; | 
| 364 |  |  |  |  |  |  | } | 
| 365 |  |  |  |  |  |  |  | 
| 366 |  |  |  |  |  |  | } | 
| 367 |  |  |  |  |  |  |  | 
| 368 |  |  |  |  |  |  | if ( $os =~ /^ace/ && $self->can('entPhysicalSoftwareRev') ) { | 
| 369 |  |  |  |  |  |  | my $ver = $self->entPhysicalSoftwareRev->{1}; | 
| 370 |  |  |  |  |  |  | $ver and return $ver; | 
| 371 |  |  |  |  |  |  | } | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | # Newer Catalysts and IOS devices | 
| 374 |  |  |  |  |  |  | if ( defined $descr and | 
| 375 |  |  |  |  |  |  | $descr =~ m/Version (\d+\.\d+\([^)]+\)[^,\s]*)(,|\s)+/ ) | 
| 376 |  |  |  |  |  |  | { | 
| 377 |  |  |  |  |  |  | return $1; | 
| 378 |  |  |  |  |  |  | } | 
| 379 |  |  |  |  |  |  | }    # end of Cisco | 
| 380 |  |  |  |  |  |  |  | 
| 381 |  |  |  |  |  |  | if ( $vendor eq 'VMWare' ) { | 
| 382 |  |  |  |  |  |  | my $prodver = $self->snmp_vmwProdVersion; | 
| 383 |  |  |  |  |  |  | return $prodver if defined($prodver); | 
| 384 |  |  |  |  |  |  | } | 
| 385 |  |  |  |  |  |  |  | 
| 386 |  |  |  |  |  |  | return ''; | 
| 387 |  |  |  |  |  |  | } | 
| 388 |  |  |  |  |  |  |  | 
| 389 |  |  |  |  |  |  | sub _build_vendor { | 
| 390 |  |  |  |  |  |  | my $self = shift; | 
| 391 |  |  |  |  |  |  | my $info = $self->snmp_sysObjectID; | 
| 392 |  |  |  |  |  |  | return _sysObjectID2vendor($info) || ""; | 
| 393 |  |  |  |  |  |  | } | 
| 394 |  |  |  |  |  |  |  | 
| 395 |  |  |  |  |  |  | sub _build_serial { | 
| 396 |  |  |  |  |  |  | my $self = shift; | 
| 397 |  |  |  |  |  |  | return; | 
| 398 |  |  |  |  |  |  | } | 
| 399 |  |  |  |  |  |  |  | 
| 400 |  |  |  |  |  |  | sub _build_cpu_count { | 
| 401 |  |  |  |  |  |  | my $self = shift; | 
| 402 |  |  |  |  |  |  |  | 
| 403 |  |  |  |  |  |  | my $procLoad = $self->snmp_hrProcessorLoad; | 
| 404 |  |  |  |  |  |  |  | 
| 405 |  |  |  |  |  |  | return scalar( keys(%$procLoad) ); | 
| 406 |  |  |  |  |  |  | } | 
| 407 |  |  |  |  |  |  |  | 
| 408 |  |  |  |  |  |  | sub _build_cpu_model { "Unkown" } | 
| 409 |  |  |  |  |  |  |  | 
| 410 |  |  |  |  |  |  | sub _build_ram_memory { | 
| 411 |  |  |  |  |  |  | my $self   = shift; | 
| 412 |  |  |  |  |  |  | my $memTot = $self->snmp_memTotalReal; | 
| 413 |  |  |  |  |  |  | $memTot eq 'noSuchObject' and return; | 
| 414 |  |  |  |  |  |  | return int($memTot) / 1024; | 
| 415 |  |  |  |  |  |  | } | 
| 416 |  |  |  |  |  |  |  | 
| 417 |  |  |  |  |  |  | sub _build_kernel { undef } | 
| 418 |  |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | sub _build_kernel_ver { undef } | 
| 420 |  |  |  |  |  |  |  | 
| 421 |  |  |  |  |  |  | has 'package_name_parser' => ( | 
| 422 |  |  |  |  |  |  | is      => 'rw', | 
| 423 |  |  |  |  |  |  | isa     => 'Ref', | 
| 424 |  |  |  |  |  |  | lazy    => 1, | 
| 425 |  |  |  |  |  |  | builder => '_build_package_name_parser', | 
| 426 |  |  |  |  |  |  | ); | 
| 427 |  |  |  |  |  |  |  | 
| 428 |  |  |  |  |  |  | sub _build_package_name_parser { | 
| 429 |  |  |  |  |  |  | my $self = shift; | 
| 430 |  |  |  |  |  |  |  | 
| 431 |  |  |  |  |  |  | my $os = $self->os; | 
| 432 |  |  |  |  |  |  |  | 
| 433 |  |  |  |  |  |  | if ( $os eq 'Linux' ) { | 
| 434 |  |  |  |  |  |  | return sub { | 
| 435 |  |  |  |  |  |  | my $pkg = shift; | 
| 436 |  |  |  |  |  |  |  | 
| 437 |  |  |  |  |  |  | # redhat name, version release platform | 
| 438 |  |  |  |  |  |  | $pkg =~ /^(.+)-([^-]+)-([^-]+)\.(.*)$/ and | 
| 439 |  |  |  |  |  |  | return [ $1,   $2 ]; | 
| 440 |  |  |  |  |  |  | return     [ $pkg, undef ]; | 
| 441 |  |  |  |  |  |  | }; | 
| 442 |  |  |  |  |  |  | } | 
| 443 |  |  |  |  |  |  |  | 
| 444 |  |  |  |  |  |  | return sub { [ shift, undef ] }; | 
| 445 |  |  |  |  |  |  | } | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  | sub _build_installed_sw { | 
| 448 |  |  |  |  |  |  | my $self = shift; | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | my $installed = $self->snmp_hrSWInstalledName; | 
| 451 |  |  |  |  |  |  | my $parser    = $self->package_name_parser; | 
| 452 |  |  |  |  |  |  |  | 
| 453 |  |  |  |  |  |  | return [ map { $parser->($_) } values(%$installed) ]; | 
| 454 |  |  |  |  |  |  | } | 
| 455 |  |  |  |  |  |  |  | 
| 456 |  |  |  |  |  |  | sub _build_virtual_machines { | 
| 457 |  |  |  |  |  |  | my $self = shift; | 
| 458 |  |  |  |  |  |  |  | 
| 459 |  |  |  |  |  |  | if ( $self->vendor eq 'VMWare' ) { | 
| 460 |  |  |  |  |  |  | my @result; | 
| 461 |  |  |  |  |  |  |  | 
| 462 |  |  |  |  |  |  | $self->log->warn("Using vmware MIB to retrieve vm list "); | 
| 463 |  |  |  |  |  |  |  | 
| 464 |  |  |  |  |  |  | my $names    = $self->snmp_vmwVmDisplayName; | 
| 465 |  |  |  |  |  |  | my $uuids    = $self->snmp_vmwVmUUID; | 
| 466 |  |  |  |  |  |  | my $memsizes = $self->snmp_vmwVmMemSize; | 
| 467 |  |  |  |  |  |  | my $vcpus    = $self->snmp_vmwVmCpus; | 
| 468 |  |  |  |  |  |  |  | 
| 469 |  |  |  |  |  |  | while ( my ( $idx, $uuid ) = each(%$uuids) ) { | 
| 470 |  |  |  |  |  |  | my $vm_info = {}; | 
| 471 |  |  |  |  |  |  | $vm_info->{uuid}    = $uuid; | 
| 472 |  |  |  |  |  |  | $vm_info->{name}    = $names->{$idx}; | 
| 473 |  |  |  |  |  |  | $vm_info->{vcpus}   = $vcpus->{$idx}; | 
| 474 |  |  |  |  |  |  | $vm_info->{memsize} = $memsizes->{$idx}; | 
| 475 |  |  |  |  |  |  |  | 
| 476 |  |  |  |  |  |  | push @result, $vm_info; | 
| 477 |  |  |  |  |  |  | } | 
| 478 |  |  |  |  |  |  |  | 
| 479 |  |  |  |  |  |  | return \@result; | 
| 480 |  |  |  |  |  |  | } | 
| 481 |  |  |  |  |  |  | } | 
| 482 |  |  |  |  |  |  |  | 
| 483 |  |  |  |  |  |  | #----------------------------------------------------------------------# | 
| 484 |  |  |  |  |  |  | # | 
| 485 |  |  |  |  |  |  | #                   SNMP gory details start here.... | 
| 486 |  |  |  |  |  |  | # | 
| 487 |  |  |  |  |  |  | #----------------------------------------------------------------------# | 
| 488 |  |  |  |  |  |  |  | 
| 489 |  |  |  |  |  |  | # Implements get_scalar using Net::SNMP session | 
| 490 |  |  |  |  |  |  |  | 
| 491 |  |  |  |  |  |  | sub _get_scalar { | 
| 492 |  |  |  |  |  |  | my ( $self, $oid ) = @_; | 
| 493 |  |  |  |  |  |  |  | 
| 494 |  |  |  |  |  |  | my $session = $self->snmp_session; | 
| 495 |  |  |  |  |  |  |  | 
| 496 |  |  |  |  |  |  | #add istance number to the oid | 
| 497 |  |  |  |  |  |  | $oid .= '.0'; | 
| 498 |  |  |  |  |  |  |  | 
| 499 |  |  |  |  |  |  | $self->log->debug( $self->meta->name, "Fetching scalar $oid" ); | 
| 500 |  |  |  |  |  |  |  | 
| 501 |  |  |  |  |  |  | my $result = $session->get_request( '-varbindlist' => [$oid] ); | 
| 502 |  |  |  |  |  |  | $result or die "SNMP error " . $session->error(); | 
| 503 |  |  |  |  |  |  |  | 
| 504 |  |  |  |  |  |  | return $result->{$oid}; | 
| 505 |  |  |  |  |  |  | } | 
| 506 |  |  |  |  |  |  |  | 
| 507 |  |  |  |  |  |  | # Implements get_subtree using Net::SNMP session | 
| 508 |  |  |  |  |  |  |  | 
| 509 |  |  |  |  |  |  | sub _get_subtree { | 
| 510 |  |  |  |  |  |  | my ( $self, $oid ) = @_; | 
| 511 |  |  |  |  |  |  |  | 
| 512 |  |  |  |  |  |  | my @result; | 
| 513 |  |  |  |  |  |  |  | 
| 514 |  |  |  |  |  |  | my $s = $self->snmp_session; | 
| 515 |  |  |  |  |  |  | $oid eq '.' and $oid = '0'; | 
| 516 |  |  |  |  |  |  |  | 
| 517 |  |  |  |  |  |  | $self->log->debug( $self->meta->name, "Fetching subtree $oid" ); | 
| 518 |  |  |  |  |  |  |  | 
| 519 |  |  |  |  |  |  | my $last_oid = $oid; | 
| 520 |  |  |  |  |  |  |  | 
| 521 |  |  |  |  |  |  | if ( $s->version() == SNMP_VERSION_1 ) { | 
| 522 |  |  |  |  |  |  |  | 
| 523 |  |  |  |  |  |  | while ( defined $s->get_next_request( -varbindlist => [$last_oid] ) ) { | 
| 524 |  |  |  |  |  |  | my $returned_oid = ( $s->var_bind_names() )[0]; | 
| 525 |  |  |  |  |  |  | if ( !oid_base_match( $last_oid, $returned_oid ) ) { | 
| 526 |  |  |  |  |  |  | last; | 
| 527 |  |  |  |  |  |  | } | 
| 528 |  |  |  |  |  |  |  | 
| 529 |  |  |  |  |  |  | # store into result | 
| 530 |  |  |  |  |  |  | push @result, [ $returned_oid, $s->var_bind_list()->{$returned_oid} ]; | 
| 531 |  |  |  |  |  |  |  | 
| 532 |  |  |  |  |  |  | $last_oid = $returned_oid; | 
| 533 |  |  |  |  |  |  | } | 
| 534 |  |  |  |  |  |  |  | 
| 535 |  |  |  |  |  |  | } | 
| 536 |  |  |  |  |  |  | else { | 
| 537 |  |  |  |  |  |  |  | 
| 538 |  |  |  |  |  |  | GET_BULK: | 
| 539 |  |  |  |  |  |  | while ( | 
| 540 |  |  |  |  |  |  | defined $s->get_bulk_request( | 
| 541 |  |  |  |  |  |  | -maxrepetitions => 1, | 
| 542 |  |  |  |  |  |  | -varbindlist    => [$last_oid] | 
| 543 |  |  |  |  |  |  | ) | 
| 544 |  |  |  |  |  |  | ) | 
| 545 |  |  |  |  |  |  | { | 
| 546 |  |  |  |  |  |  | my @oids = $s->var_bind_names(); | 
| 547 |  |  |  |  |  |  |  | 
| 548 |  |  |  |  |  |  | if ( !scalar @oids ) { | 
| 549 |  |  |  |  |  |  | die('Received an empty varBindList'); | 
| 550 |  |  |  |  |  |  | } | 
| 551 |  |  |  |  |  |  |  | 
| 552 |  |  |  |  |  |  | foreach my $returned_oid (@oids) { | 
| 553 |  |  |  |  |  |  |  | 
| 554 |  |  |  |  |  |  | if ( !oid_base_match( $oid, $returned_oid ) ) { | 
| 555 |  |  |  |  |  |  | last GET_BULK; | 
| 556 |  |  |  |  |  |  | } | 
| 557 |  |  |  |  |  |  |  | 
| 558 |  |  |  |  |  |  | # Make sure we have not hit the end of the MIB. | 
| 559 |  |  |  |  |  |  | if ( $s->var_bind_types()->{$returned_oid} == ENDOFMIBVIEW ) { | 
| 560 |  |  |  |  |  |  | last GET_BULK; | 
| 561 |  |  |  |  |  |  | } | 
| 562 |  |  |  |  |  |  |  | 
| 563 |  |  |  |  |  |  | push @result, [ $returned_oid, $s->var_bind_list()->{$returned_oid} ]; | 
| 564 |  |  |  |  |  |  |  | 
| 565 |  |  |  |  |  |  | $last_oid = $returned_oid; | 
| 566 |  |  |  |  |  |  | } | 
| 567 |  |  |  |  |  |  | } | 
| 568 |  |  |  |  |  |  |  | 
| 569 |  |  |  |  |  |  | } | 
| 570 |  |  |  |  |  |  |  | 
| 571 |  |  |  |  |  |  | return \@result; | 
| 572 |  |  |  |  |  |  | } | 
| 573 |  |  |  |  |  |  |  | 
| 574 |  |  |  |  |  |  | sub _mib_read_scalar { | 
| 575 |  |  |  |  |  |  | my ( $self, $oid, $munger ) = @_; | 
| 576 |  |  |  |  |  |  |  | 
| 577 |  |  |  |  |  |  | my $v = $self->_get_scalar($oid); | 
| 578 |  |  |  |  |  |  | $munger and $v = $munger->($v); | 
| 579 |  |  |  |  |  |  | return $v; | 
| 580 |  |  |  |  |  |  | } | 
| 581 |  |  |  |  |  |  |  | 
| 582 |  |  |  |  |  |  | sub _mib_read_tablerow { | 
| 583 |  |  |  |  |  |  | my ( $self, $oid, $munger ) = @_; | 
| 584 |  |  |  |  |  |  |  | 
| 585 |  |  |  |  |  |  | my $row = $self->_get_subtree($oid); | 
| 586 |  |  |  |  |  |  |  | 
| 587 |  |  |  |  |  |  | my $ret = {}; | 
| 588 |  |  |  |  |  |  | foreach (@$row) { | 
| 589 |  |  |  |  |  |  |  | 
| 590 |  |  |  |  |  |  | # Don't optimize this RE! | 
| 591 |  |  |  |  |  |  | $_->[0] =~ /^$oid\.(.*)/ and $_->[0] = $1; | 
| 592 |  |  |  |  |  |  | $munger                  and $_->[1] = $munger->( $_->[1] ); | 
| 593 |  |  |  |  |  |  |  | 
| 594 |  |  |  |  |  |  | $ret->{ $_->[0] } = $_->[1]; | 
| 595 |  |  |  |  |  |  | } | 
| 596 |  |  |  |  |  |  |  | 
| 597 |  |  |  |  |  |  | return $ret; | 
| 598 |  |  |  |  |  |  | } | 
| 599 |  |  |  |  |  |  |  | 
| 600 |  |  |  |  |  |  | # Takes a BOOLEAN and makes it a nop|true|false string | 
| 601 |  |  |  |  |  |  |  | 
| 602 |  |  |  |  |  |  | sub _munge_bool { | 
| 603 |  |  |  |  |  |  | my $bool = shift; | 
| 604 |  |  |  |  |  |  | my @ARR  = qw ( nop  false true); | 
| 605 |  |  |  |  |  |  |  | 
| 606 |  |  |  |  |  |  | return $ARR[$bool]; | 
| 607 |  |  |  |  |  |  | } | 
| 608 |  |  |  |  |  |  |  | 
| 609 |  |  |  |  |  |  | # Takes a binary IP and makes it dotted ASCII | 
| 610 |  |  |  |  |  |  |  | 
| 611 |  |  |  |  |  |  | sub _munge_ipaddress { | 
| 612 |  |  |  |  |  |  | my $ip = shift; | 
| 613 |  |  |  |  |  |  | return join( '.', unpack( 'C4', $ip ) ); | 
| 614 |  |  |  |  |  |  | } | 
| 615 |  |  |  |  |  |  |  | 
| 616 |  |  |  |  |  |  | # Takes an octet stream (HEX-STRING) and returns a colon separated | 
| 617 |  |  |  |  |  |  | # ASCII hex string. | 
| 618 |  |  |  |  |  |  |  | 
| 619 |  |  |  |  |  |  | sub _munge_macaddress { | 
| 620 |  |  |  |  |  |  | my $mac = shift; | 
| 621 |  |  |  |  |  |  | $mac or return ""; | 
| 622 |  |  |  |  |  |  | $mac = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $mac ) ); | 
| 623 |  |  |  |  |  |  | return $mac if $mac =~ /^([0-9A-F][0-9A-F]:){5}[0-9A-F][0-9A-F]$/i; | 
| 624 |  |  |  |  |  |  | return "ERROR"; | 
| 625 |  |  |  |  |  |  | } | 
| 626 |  |  |  |  |  |  |  | 
| 627 |  |  |  |  |  |  | sub _munge_sw_installed_date { | 
| 628 |  |  |  |  |  |  | my $val = shift; | 
| 629 |  |  |  |  |  |  |  | 
| 630 |  |  |  |  |  |  | my ( $y, $m, $d, $hour, $min, $sec ) = unpack( 'n C6 a C2', $val ); | 
| 631 |  |  |  |  |  |  |  | 
| 632 |  |  |  |  |  |  | return "$y-$m-$d $hour:$min:$sec"; | 
| 633 |  |  |  |  |  |  |  | 
| 634 |  |  |  |  |  |  | } | 
| 635 |  |  |  |  |  |  |  | 
| 636 |  |  |  |  |  |  | my %ID_VENDOR_MAP = ( | 
| 637 |  |  |  |  |  |  | 9     => 'Cisco', | 
| 638 |  |  |  |  |  |  | 11    => 'HP', | 
| 639 |  |  |  |  |  |  | 18    => 'BayRS', | 
| 640 |  |  |  |  |  |  | 42    => 'Sun', | 
| 641 |  |  |  |  |  |  | 43    => '3Com', | 
| 642 |  |  |  |  |  |  | 45    => 'Baystack', | 
| 643 |  |  |  |  |  |  | 171   => 'Dell', | 
| 644 |  |  |  |  |  |  | 207   => 'Allied', | 
| 645 |  |  |  |  |  |  | 244   => 'Lantronix', | 
| 646 |  |  |  |  |  |  | 311   => 'Microsoft', | 
| 647 |  |  |  |  |  |  | 318   => 'APC', | 
| 648 |  |  |  |  |  |  | 674   => 'Dell', | 
| 649 |  |  |  |  |  |  | 1872  => 'AlteonAD', | 
| 650 |  |  |  |  |  |  | 1916  => 'Extreme', | 
| 651 |  |  |  |  |  |  | 1991  => 'Foundry', | 
| 652 |  |  |  |  |  |  | 2021  => 'NetSNMP', | 
| 653 |  |  |  |  |  |  | 2272  => 'Passport', | 
| 654 |  |  |  |  |  |  | 2636  => 'Juniper', | 
| 655 |  |  |  |  |  |  | 2925  => 'Cyclades', | 
| 656 |  |  |  |  |  |  | 3076  => 'Altiga', | 
| 657 |  |  |  |  |  |  | 3224  => 'Netscreen', | 
| 658 |  |  |  |  |  |  | 3375  => 'F5', | 
| 659 |  |  |  |  |  |  | 3417  => 'BlueCoatSG', | 
| 660 |  |  |  |  |  |  | 4526  => 'Netgear', | 
| 661 |  |  |  |  |  |  | 5624  => 'Enterasys', | 
| 662 |  |  |  |  |  |  | 5951  => 'Netscaler', | 
| 663 |  |  |  |  |  |  | 6027  => 'Force10', | 
| 664 |  |  |  |  |  |  | 6486  => 'AlcatelLucent', | 
| 665 |  |  |  |  |  |  | 6527  => 'Timetra', | 
| 666 |  |  |  |  |  |  | 6876  => 'VMWare', | 
| 667 |  |  |  |  |  |  | 8072  => 'NetSNMP', | 
| 668 |  |  |  |  |  |  | 9303  => 'PacketFront', | 
| 669 |  |  |  |  |  |  | 10002 => 'Ubiquiti', | 
| 670 |  |  |  |  |  |  | 11898 => 'Orinoco', | 
| 671 |  |  |  |  |  |  | 12325 => 'Pf', | 
| 672 |  |  |  |  |  |  | 12356 => 'Fortinet', | 
| 673 |  |  |  |  |  |  | 12532 => 'Neoteris', | 
| 674 |  |  |  |  |  |  | 14179 => 'Airespace', | 
| 675 |  |  |  |  |  |  | 14525 => 'Trapeze', | 
| 676 |  |  |  |  |  |  | 14823 => 'Aruba', | 
| 677 |  |  |  |  |  |  | 14988 => 'Mikrotik', | 
| 678 |  |  |  |  |  |  | 17163 => 'Steelhead', | 
| 679 |  |  |  |  |  |  | 25506 => 'H3C', | 
| 680 |  |  |  |  |  |  | 26543 => 'IBMGbTor', | 
| 681 |  |  |  |  |  |  | 30065 => 'Arista', | 
| 682 |  |  |  |  |  |  | 35098 => 'Pica8', | 
| 683 |  |  |  |  |  |  | ); | 
| 684 |  |  |  |  |  |  |  | 
| 685 |  |  |  |  |  |  | # Try to extract a vendor string from a sysObjectID. | 
| 686 |  |  |  |  |  |  |  | 
| 687 |  |  |  |  |  |  | sub _sysObjectID2vendor { | 
| 688 |  |  |  |  |  |  | my ($id) = @_; | 
| 689 |  |  |  |  |  |  | defined $id or return "NO VENDOR"; | 
| 690 |  |  |  |  |  |  |  | 
| 691 |  |  |  |  |  |  | $id =~ /^\.?1\.3\.6\.1\.4\.1\.(\d+)/ and return $ID_VENDOR_MAP{$1}; | 
| 692 |  |  |  |  |  |  | return "UNKNOWN"; | 
| 693 |  |  |  |  |  |  | } | 
| 694 |  |  |  |  |  |  |  | 
| 695 |  |  |  |  |  |  | no Moose; | 
| 696 |  |  |  |  |  |  | __PACKAGE__->meta->make_immutable; | 
| 697 |  |  |  |  |  |  |  | 
| 698 |  |  |  |  |  |  | # Local Variables: | 
| 699 |  |  |  |  |  |  | # mode: cperl | 
| 700 |  |  |  |  |  |  | # indent-tabs-mode: nil | 
| 701 |  |  |  |  |  |  | # cperl-indent-level: 4 | 
| 702 |  |  |  |  |  |  | # cperl-indent-parens-as-block: t | 
| 703 |  |  |  |  |  |  | # End: | 
| 704 |  |  |  |  |  |  |  | 
| 705 |  |  |  |  |  |  | __END__ | 
| 706 |  |  |  |  |  |  |  | 
| 707 |  |  |  |  |  |  | =pod | 
| 708 |  |  |  |  |  |  |  | 
| 709 |  |  |  |  |  |  | =head1 NAME | 
| 710 |  |  |  |  |  |  |  | 
| 711 |  |  |  |  |  |  | App::Manoc::Manifold::SNMP::Simple - A simple client based on Net::SNMP | 
| 712 |  |  |  |  |  |  |  | 
| 713 |  |  |  |  |  |  | =head1 VERSION | 
| 714 |  |  |  |  |  |  |  | 
| 715 |  |  |  |  |  |  | version 2.99.2 | 
| 716 |  |  |  |  |  |  |  | 
| 717 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 718 |  |  |  |  |  |  |  | 
| 719 |  |  |  |  |  |  | A simple SNMP client Manifold, entirely based on Net::SNMP avoiding | 
| 720 |  |  |  |  |  |  | the need of any MIB file. | 
| 721 |  |  |  |  |  |  |  | 
| 722 |  |  |  |  |  |  | =head1 CONSUMED ROLES | 
| 723 |  |  |  |  |  |  |  | 
| 724 |  |  |  |  |  |  | =over 4 | 
| 725 |  |  |  |  |  |  |  | 
| 726 |  |  |  |  |  |  | =item * | 
| 727 |  |  |  |  |  |  |  | 
| 728 |  |  |  |  |  |  | App::Manoc::ManifoldRole::Base | 
| 729 |  |  |  |  |  |  |  | 
| 730 |  |  |  |  |  |  | =item * | 
| 731 |  |  |  |  |  |  |  | 
| 732 |  |  |  |  |  |  | App::Manoc::ManifoldRole::Host | 
| 733 |  |  |  |  |  |  |  | 
| 734 |  |  |  |  |  |  | =item * | 
| 735 |  |  |  |  |  |  |  | 
| 736 |  |  |  |  |  |  | App::Manoc::ManifoldRole::Hypervisor | 
| 737 |  |  |  |  |  |  |  | 
| 738 |  |  |  |  |  |  | =item * | 
| 739 |  |  |  |  |  |  |  | 
| 740 |  |  |  |  |  |  | App::Manoc::Logger::Role | 
| 741 |  |  |  |  |  |  |  | 
| 742 |  |  |  |  |  |  | =back | 
| 743 |  |  |  |  |  |  |  | 
| 744 |  |  |  |  |  |  | =head1 ATTRIBUTES | 
| 745 |  |  |  |  |  |  |  | 
| 746 |  |  |  |  |  |  | =head2 community | 
| 747 |  |  |  |  |  |  |  | 
| 748 |  |  |  |  |  |  | SNMP community string | 
| 749 |  |  |  |  |  |  |  | 
| 750 |  |  |  |  |  |  | =head2 version | 
| 751 |  |  |  |  |  |  |  | 
| 752 |  |  |  |  |  |  | SNMP version: 1, 2c or 3. | 
| 753 |  |  |  |  |  |  |  | 
| 754 |  |  |  |  |  |  | =head2 snmp_session | 
| 755 |  |  |  |  |  |  |  | 
| 756 |  |  |  |  |  |  | The Net::SNMP session used by the manifold. | 
| 757 |  |  |  |  |  |  |  | 
| 758 |  |  |  |  |  |  | =head1 METHODS | 
| 759 |  |  |  |  |  |  |  | 
| 760 |  |  |  |  |  |  | =head2 connect | 
| 761 |  |  |  |  |  |  |  | 
| 762 |  |  |  |  |  |  | Connect the manifold using Net::SNMP and set snmp_session. | 
| 763 |  |  |  |  |  |  |  | 
| 764 |  |  |  |  |  |  | =head2 has_snmp_scalar($name, %attrs) | 
| 765 |  |  |  |  |  |  |  | 
| 766 |  |  |  |  |  |  | Creates a snmp_<$name> attribute with _build_$name builder.  The | 
| 767 |  |  |  |  |  |  | %attrs arra must define the "oid" paramater and can set a "munger" | 
| 768 |  |  |  |  |  |  | subroutine. | 
| 769 |  |  |  |  |  |  |  | 
| 770 |  |  |  |  |  |  | =head2 has_snmp_table( $name, %options ) | 
| 771 |  |  |  |  |  |  |  | 
| 772 |  |  |  |  |  |  | Creates a snmp_<columnname> accessor for each defined column. | 
| 773 |  |  |  |  |  |  |  | 
| 774 |  |  |  |  |  |  | =head1 SNMP ATTRIBUTES | 
| 775 |  |  |  |  |  |  |  | 
| 776 |  |  |  |  |  |  | =head2 SNMPV2 MIB | 
| 777 |  |  |  |  |  |  |  | 
| 778 |  |  |  |  |  |  | =over 4 | 
| 779 |  |  |  |  |  |  |  | 
| 780 |  |  |  |  |  |  | =item sysDescr | 
| 781 |  |  |  |  |  |  |  | 
| 782 |  |  |  |  |  |  | =item sysObjectID | 
| 783 |  |  |  |  |  |  |  | 
| 784 |  |  |  |  |  |  | =item sysName | 
| 785 |  |  |  |  |  |  |  | 
| 786 |  |  |  |  |  |  | =item sysLocation | 
| 787 |  |  |  |  |  |  |  | 
| 788 |  |  |  |  |  |  | =item sysServices | 
| 789 |  |  |  |  |  |  |  | 
| 790 |  |  |  |  |  |  | =back | 
| 791 |  |  |  |  |  |  |  | 
| 792 |  |  |  |  |  |  | =head2 HOST RESOURCES MIB | 
| 793 |  |  |  |  |  |  |  | 
| 794 |  |  |  |  |  |  | =over 4 | 
| 795 |  |  |  |  |  |  |  | 
| 796 |  |  |  |  |  |  | =item hrSWInstalledTable with columns | 
| 797 |  |  |  |  |  |  |  | 
| 798 |  |  |  |  |  |  | =over 4 | 
| 799 |  |  |  |  |  |  |  | 
| 800 |  |  |  |  |  |  | =item hrSWInstalledIndex | 
| 801 |  |  |  |  |  |  |  | 
| 802 |  |  |  |  |  |  | =item hrSWInstalledName | 
| 803 |  |  |  |  |  |  |  | 
| 804 |  |  |  |  |  |  | =item hrSWInstalledID | 
| 805 |  |  |  |  |  |  |  | 
| 806 |  |  |  |  |  |  | =item hrSWInstalledTypem | 
| 807 |  |  |  |  |  |  |  | 
| 808 |  |  |  |  |  |  | =item hrSWInstalledDate | 
| 809 |  |  |  |  |  |  |  | 
| 810 |  |  |  |  |  |  | =back | 
| 811 |  |  |  |  |  |  |  | 
| 812 |  |  |  |  |  |  | =item hrDeviceTable | 
| 813 |  |  |  |  |  |  |  | 
| 814 |  |  |  |  |  |  | =over 4 | 
| 815 |  |  |  |  |  |  |  | 
| 816 |  |  |  |  |  |  | =item hrDeviceType | 
| 817 |  |  |  |  |  |  |  | 
| 818 |  |  |  |  |  |  | =item hrDeviceDescr | 
| 819 |  |  |  |  |  |  |  | 
| 820 |  |  |  |  |  |  | =item hrDeviceID | 
| 821 |  |  |  |  |  |  |  | 
| 822 |  |  |  |  |  |  | =item hrDeviceStatus which can be one of these strings: INVALID unknown running warning testing down | 
| 823 |  |  |  |  |  |  |  | 
| 824 |  |  |  |  |  |  | =back | 
| 825 |  |  |  |  |  |  |  | 
| 826 |  |  |  |  |  |  | =item hrProcessorTable | 
| 827 |  |  |  |  |  |  |  | 
| 828 |  |  |  |  |  |  | =over 4 | 
| 829 |  |  |  |  |  |  |  | 
| 830 |  |  |  |  |  |  | =item hrDeviceIndex | 
| 831 |  |  |  |  |  |  |  | 
| 832 |  |  |  |  |  |  | =item hrProcessorLoad | 
| 833 |  |  |  |  |  |  |  | 
| 834 |  |  |  |  |  |  | =back | 
| 835 |  |  |  |  |  |  |  | 
| 836 |  |  |  |  |  |  | =back | 
| 837 |  |  |  |  |  |  |  | 
| 838 |  |  |  |  |  |  | =head2 UCD SNMP MIB | 
| 839 |  |  |  |  |  |  |  | 
| 840 |  |  |  |  |  |  | =over 4 | 
| 841 |  |  |  |  |  |  |  | 
| 842 |  |  |  |  |  |  | =item memTotalReal | 
| 843 |  |  |  |  |  |  |  | 
| 844 |  |  |  |  |  |  | =back | 
| 845 |  |  |  |  |  |  |  | 
| 846 |  |  |  |  |  |  | =head2 VMWare MIBs | 
| 847 |  |  |  |  |  |  |  | 
| 848 |  |  |  |  |  |  | =over 4 | 
| 849 |  |  |  |  |  |  |  | 
| 850 |  |  |  |  |  |  | =item vmwProdName | 
| 851 |  |  |  |  |  |  |  | 
| 852 |  |  |  |  |  |  | =item vmwProdVersion | 
| 853 |  |  |  |  |  |  |  | 
| 854 |  |  |  |  |  |  | =item vmwVmTable | 
| 855 |  |  |  |  |  |  |  | 
| 856 |  |  |  |  |  |  | =over 4 | 
| 857 |  |  |  |  |  |  |  | 
| 858 |  |  |  |  |  |  | =item vmwVmIdx | 
| 859 |  |  |  |  |  |  |  | 
| 860 |  |  |  |  |  |  | =item vmwVmDisplayName | 
| 861 |  |  |  |  |  |  |  | 
| 862 |  |  |  |  |  |  | =item vmwVmGuestOS | 
| 863 |  |  |  |  |  |  |  | 
| 864 |  |  |  |  |  |  | =item vmwVmMemSize | 
| 865 |  |  |  |  |  |  |  | 
| 866 |  |  |  |  |  |  | =item vmwVmState | 
| 867 |  |  |  |  |  |  |  | 
| 868 |  |  |  |  |  |  | =item vmwVmCpus | 
| 869 |  |  |  |  |  |  |  | 
| 870 |  |  |  |  |  |  | =item vmwVmUUID | 
| 871 |  |  |  |  |  |  |  | 
| 872 |  |  |  |  |  |  | =back | 
| 873 |  |  |  |  |  |  |  | 
| 874 |  |  |  |  |  |  | =back | 
| 875 |  |  |  |  |  |  |  | 
| 876 |  |  |  |  |  |  | =head1 AUTHORS | 
| 877 |  |  |  |  |  |  |  | 
| 878 |  |  |  |  |  |  | =over 4 | 
| 879 |  |  |  |  |  |  |  | 
| 880 |  |  |  |  |  |  | =item * | 
| 881 |  |  |  |  |  |  |  | 
| 882 |  |  |  |  |  |  | Gabriele Mambrini <gmambro@cpan.org> | 
| 883 |  |  |  |  |  |  |  | 
| 884 |  |  |  |  |  |  | =item * | 
| 885 |  |  |  |  |  |  |  | 
| 886 |  |  |  |  |  |  | Enrico Liguori | 
| 887 |  |  |  |  |  |  |  | 
| 888 |  |  |  |  |  |  | =back | 
| 889 |  |  |  |  |  |  |  | 
| 890 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE | 
| 891 |  |  |  |  |  |  |  | 
| 892 |  |  |  |  |  |  | This software is copyright (c) 2017 by Gabriele Mambrini. | 
| 893 |  |  |  |  |  |  |  | 
| 894 |  |  |  |  |  |  | This is free software; you can redistribute it and/or modify it under | 
| 895 |  |  |  |  |  |  | the same terms as the Perl 5 programming language system itself. | 
| 896 |  |  |  |  |  |  |  | 
| 897 |  |  |  |  |  |  | =cut |