SNMP-Info-3.39000755000765000024 013215550564 12710 5ustar00oliverstaff000000000000SNMP-Info-3.39/Build.PL000444000765000024 156213215550564 14345 0ustar00oliverstaff000000000000use strict; use warnings; use Module::Build; Module::Build->new( module_name => 'SNMP::Info', license => 'bsd', dist_author => 'Eric A. Miller ', # dynamic_config => 1, configure_requires => { 'Module::Build' => '0.42', }, # build_requires => { # }, requires => { 'SNMP' => '0', 'Math::BigInt' => '0', }, # recommends => { # }, test_requires => { 'Test::More' => '0.88', }, # script_files => [ # ], # share_dir => 'share', meta_merge => { resources => { homepage => 'http://netdisco.org/', bugtracker => 'https://github.com/netdisco/snmp-info/issues', repository => 'https://github.com/netdisco/snmp-info', MailingList => 'https://lists.sourceforge.net/lists/listinfo/snmp-info-users', IRC => 'irc://irc.freenode.org/#netdisco', }, }, )->create_build_script; SNMP-Info-3.39/Changes000444000765000024 12275113215550564 14410 0ustar00oliverstaff000000000000SNMP::Info - Friendly OO-style interface to Network devices using SNMP. version 3.39 (2017-12-17) [ENHANCEMENTS] * #236 Enhanced Ubiquiti device support (L. Begnaud) * add HP J9774A model (H. Teulahti) [BUG FIXES] * fix scripts (F. Mass) * fix CiscoASA typos (laelly) version 3.38 (2017-10-23) [ENHANCEMENTS] * Layer2::Airespace several newer 802.11 data rates added [BUG FIXES] * #232 Improve generic Info::Layer3 serial number detection version 3.37 (2017-07-11) [ENHANCEMENTS] * Layer3::Juniper fixed to return os_ver for JUNOS 14.x and higher version 3.36 (2017-06-28) [ENHANCEMENTS] * Migrate to Module::Build for distribution maintenance version 3.35 (2017-06-28) [ENHANCEMENTS] * Include loading of LLDP-EXT-MED-MIB in LLDP.pm [BUG FIXES] * #180 support CiscoConfig on Nexus (sf.net:scratchfury) * #50 remove interface specific part from vrf interfaces on IOS (W. Vandersmissen) * #211 f5 class should respect UseEnums when faking i_type version 3.34 (2016-11-20) [ENHANCEMENTS] * Support Cisco IPS Modules homed on the Cisco ASA (M. Kraus) [BUG FIXES] * Serial number on Nexus 9372 (genereic check for ID before using) (M. Caines) version 3.33 (2016-04-27) [ENHANCEMENTS] * Move author-only tests to xt directory so they aren't run on installation by users [BUG FIXES] * Correct device serial number reporting for Cisco Nexus 5k switches with software version >= 7 version 3.32 (2016-04-26) [ENHANCEMENTS] * Add 200 Mbps and 2.0 Gbps aliases to SPEED_MAP * Add Palo Alto support * Add VMware support * Support for propMultiplexor as ifType * Add device MAC to APC UPS * [#61] Report APC model for PDU products * Removed DeviceMatrix from the distribution [BUG FIXES] * Support undefined (noSuchInstance) values in Offline mode * Do not init table cache if Cache provided by user * Avoid deep recusion when AUTOLOAD and carp collide * Detect Cisco VG350s as L3 devices instead of APs * fix for 'Use of inherited AUTOLOAD for non-method SNMP::Info::Layer2::HP::agg_ports_ifstack() is deprecated' * Workaround in IPv6.pm to deal with possibly incorrect IPV6-MIB implementations * [#71] AUTOLOAD typo-catcher search for SNMP::Info no longer anchored * [#70] Respect version/comm/secname on passed Session obj version 3.31 (2016-01-22) [ENHANCEMENTS] * Support for CiscoSB OS and Version (D. Tuecks) * SONMP support for Enhanced Topology Table * Add support for channelized interfaces in L3::Passport [BUG FIXES] * Correct link to MIB tarball version 3.30 (2015-11-16) [ENHANCEMENTS] * RT #106254: Add new sysObjectID mapping for Ubiquiti [BUG FIXES] * Correct link to MIB tarball * Correct port indexing of newer VSP 4K and 8K in L3::Passport * Statistics in the sysIfxStatTable are 64-bit counters, so they should override the 64-bit methods. version 3.29 (2015-10-13) [ENHANCEMENTS] * Add IPv6::ipv6_addr() method to map IPv6 interface address indexes to actual addresses * Add support for (remote) IPv6 addresses to LLDP::lldp_addr() * Add LLDP::lldp_ipv6() and LLDP::lldp_mac() so that remote management addresses of specific types can be requested version 3.28 (2015-06-18) [ENHANCEMENTS] * Add Layer3::Huawei class for Huawei Quidway switches * Modified generic Layer3::Cisco class: use community based indexing if the device returns a value for vtpVersion [BUG FIXES] * Correct port indexing of VSP 4K in L3::Passport version 3.27 (2015-05-05) [ENHANCEMENTS] * Cisco Aironet PSU information * Only log adding mibdirs at debug level 2 [BUG FIXES] * [#221] Drop Cisco Voice VLAN 4096 version 3.26 (2015-03-07) [ENHANCEMENTS] * Add fan and psu reporting to Layer3::Dell * Include Voice VLANs in (tagged) VLAN Membership on Cisco devices [BUG FIXES] * Fix typo in MRO::print_superclasses version 3.25 (2015-02-25) [ENHANCEMENTS] * Add new model name mappings for to Layer2::HP version 3.24 (2015-02-04) [ENHANCEMENTS] * Support RSTP and ieee8021d STP operating modes in RapidCity [BUG FIXES] * Fix single instance leafs defined in %FUNCS to behave like table leafs * Fix incorrect FDB ID to VLAN ID mapping in Bridge and L3:Enterasys version 3.23 (2014-12-09) [ENHANCEMENTS] * Update MIB used in L1::Asante * Enhanced STP support for L3::Extreme [BUG FIXES] * Fix Cisco VLAN membership issue introduced in 3.22 related to capturing port VLANs on Cisco interfaces which are configured for trunking but are not in operational trunking mode version 3.22 (2014-12-02) [NEW FEATURES] * Support obtaining FDB in Avaya SPBM edge deployments in L2::Baystack NOTE: This requires a RAPID-CITY MIB with the rcBridgeSpbmMacTable * Support for Fortinet devices in new class L3::Fortinet [ENHANCEMENTS] * Include LLDP support in base Layer2 and Layer3 classes. Due to the widespread adoption of LLDP, this should improve mapping networks when devices aren't supported in a more specific class. * No longer ignore interfaces based on name, in base L2/L3/L7 device classes. For several device classes SNMP::Info will now return tunnel interfaces and/or loopbacks, if present. * Use dot1qVlanCurrentTable if available to capture dynamic and static VLANs, fall back to dot1qVlanStaticTable if not available. * New method i_vlan_membership_untagged() for VLANs transmitted as untagged frames. * Capture Aruba AP hardware and software version when available * New STP methods to support gathering information from devices running mutiple STP instances such as PVST and MST * Enhanced STP support for Avaya and Foundry classes [BUG FIXES] * [#64] Misdetection: Wireless APs, add products MIB to L2::3Com * Use FDB ID to VID mapping if available to determine end station VLAN rather than assuming they are the same. * Capture port VLANs on Cisco interfaces which are configured for trunking but are not in operational trunking mode * Correct munging of stp_p_port(), i_stp_port(), and stp_root() methods in Bridge * In LLDP.pm don't create a variable in a conditional version 3.20 (2014-09-08) [NEW FEATURES] * Override layers in Juniper for routers with switch modules [BUG FIXES] * Update MANIFEST to include Ubiquiti files version 3.19 (2014-08-01) [NEW FEATURES] * Support for Ubiquiti Access Points in new class L2::Ubiquiti (begemot) * Preliminary support for 3Com switches in new class L2::3Com (begemot) [BUG FIXES] * Fix Avaya detection lldp_port() * Silence uninitialized value warning in L3::Cisco * H3C fixes (begemot) * Only use L2::ZyXEL_DSLAM for ZyXEL DSL modules version 3.18 (2014-07-02) [ENHANCEMENTS] * Pseudo ENTITY-MIB methods added to L3::Tasman for hardware information * Capture VPC Keepalive IP addresses in L3::Nexus (jeroenvi) * L2::Netgear inheritance clean up and removal of unnecessary c_* methods defined in Info base class [BUG FIXES] * Correctly identify device type (class) for instantiated objects which have overridden layers. * [#58] Fix inheritance in L3::FWSM and L3::CiscoASA * [#71] Don't try to match on a false port description in lldp_if * [#54] Possible bad values returned for cdp_id and lldp_port with some HP gear (Joel Leonhardt) version 3.17 (2014-06-23) [ENHANCEMENTS] * POD tests are not required for distribution. version 3.16 (2014-06-23) [ENHANCEMENTS] * Add method resolution discovery in SNMP::Info::MRO helper module * Consolidate CiscoImage class into CiscoStats class * Clean up inheritance for Cisco classes. With this change all applicable classes now inherit CiscoAgg, CiscoStpExtensions, CiscoPortSecurity, CiscoPower, and LLDP classes. * Remove inheritance of classes the devices do not support in L3::FWSM and L3::CiscoASA [BUG FIXES] * Use CiscoVTP methods to get interface VLAN in L3::Cisco rather than solely relying on the interface description. version 3.15 (2014-07-10) [NEW FEATURES] * Offline mode and Cache export/priming. [ENHANCEMENTS] * Return serial number for Cisco 3850 from entPhysicalSerialNum [BUG FIXES] * Cisco SB serial number probably did not work version 3.14 (2014-06-07) [ENHANCEMENTS] * Improvements to Mikrotik module (Alex Z) * Don't unshift length from broken lldpRemManAddrTable implementations (G. Shtern) * 802.3ad LAG support in Layer3::H3C * Add LLDP capabilities to Layer2::HPVC class [BUG FIXES] * Return correct VLAN info with qb_fw_table() on Layer2::HP version 3.13 (2014-03-27) [ENHANCEMENTS] * Cisco PAgP support added to LAG method * HP ProCurve LAG support by inheriting Info::Aggregate class version 3.12 (2014-02-10) [ENHANCEMENTS] * Modify L3::Passport to obtain forwarding table information from RAPID-CITY if information is not available in either Q-BRIDGE-MIB or BRIDGE-MIB. Needed for VSP 9000 prior to version 4.x (Tobias Gerlach) [BUG FIXES] * [#52] NETSCREEN-IP-ARP-MIB considered harmful * Foundry/Brocade aggreate port master ifIndex resolved properly version 3.11 (2014-01-26) [NEW FEATURES] * [#31] port-channel (aggregate) support. Aggregate support added in new agg_ports() method. Inital support added for Arista (ifStack), Avaya (MLT), Brocade (MST), and Cisco (802.3ad). [ENHANCEMENTS] * Use Q-BRIDGE-MIB as default with fallback to BRIDGE-MIB across all classes for the fw_mac, fw_port, and fw_status methods * Additional support for Avaya 8800 series in L3::Passport [BUG FIXES] * Modify cdp_cap() to handle devices which return space delimited strings for cdpCacheCapabilities rather than hex strings * [#51] Netdisco shows broken topology for devices with no alias entry for primary IP - Collect nsIfMngIp when getting IP interfaces in L3::Netscreen * Fix Extreme XOS i_vlan_membership - Revert [28bbe0], fix bug with untagged being added to @ret twice (Robert Kerr) * Skip default CPU management addresses on VSP and 8800/8600 series in L3::Passport to prevent erroneous duplicate addresses version 3.10 (2013-12-16) [BUG FIXES] * Data values of zero are now sent to munge method instead of skipped version 3.09 (2013-12-15) [NEW FEATURES] * [#45] IBM (Blade Network Technologies) Rackswitch support in new class L3::IBMGbTor * [] set_i_untagged combines both set_i_vlan and set_i_pvid in one method * [#41] Riverbed Steelhead support added in new class L3::Steelhead * New c_cap(), cdp_cap(), and lldp_cap() methods which return a hash of arrays with each array containing the system capabilities reported as supported by the remote system via CDP or LLDP. [ENHANCEMENTS] * Remove "Switch" from model name in L3::Foundry * [#49] IOS-XR support, add identification of IOS XR and version in CiscoStats * Aruba POE Support * Aruba utilizes Q-BRIDGE-MIB when available for VLAN information to better support wired switches * Add lldp_platform() method which uses lldp_rem_sysdesc() or lldp_rem_sysname() to provide a clue to type of remote LLDP capable device. * [RT#78232] Extend cdpCacheCapabilities to show more CDP bits [BUG FIXES] * Modify _xos_i_vlan_membership() in L3::Extreme to only include tagged ports * When determining the BSSID in Airespace there is only one hexadecimal digit available so skip if outside the range of 1-16, 17 is reserved for 3rd party AP's * Don't assume entity index 1 is the chassis and has serial in Layer3 * Capture serial number on newer Aruba devices * munge_bits() correctly unpacks BITS * Fix for single instance table leafs in test_class_mocked.pl * Fix power module indexing version 3.08 (2013-10-22) [ENHANCEMENTS] * Rewrite of L3::Aruba, now supports pseudo ENTITY-MIB methods to gather module information, more interface information for APs, more wireless information to include client stats, and arpnip information from wireless clients. WARNING: AP device interfaces are now based on AP MAC and radio versus BSSID to align with other wireless classes. * [#64] Add i_speed_admin() to L2::2900 (psychiatric) * [#66] Support for VSS via CISCO-VIRTUAL-SWITCH-MIB in L3::6500 * [#67] Add the possibility to set speed for Layer3::C4000 (psychiatric) * [#69] set speed and duplex on Cisco VSS system (psychiatric) * munge_null() now removes all non-printable control characters * Support Aironet standalone access points (Layer2::Aironet) running IOS15 * lldp_port() returns port ID instead of port description if the port ID subtype is "interface name". This improves the ability to correlate ports by name when a port description is also set. * Add docs note about make_snmpdata.pl under EXTENDING SNMP::Info * [#46] Brocade (Foundry) Module Support * Brocade (Foundry) POE Support * Support peth_port_power() power supplied by PoE ports in L2::Baystack * Update test_class.pl utility to allow ignore of snmp.conf and test summarize more standard class methods * On EOS, the LLDP port ID is a dot1d port * Use LLDP in Layer3::Aruba, for switches * Clean up more model names in L2::Baystack [BUG FIXES] * [#68] Fix device_port entries for switches with non-unique ifDesc (Nic Bernstein) * Don't try to munge undef values * [#49] Perl 5.18 UNIVERSAL::can change could cause infinite loop * Silence warning from uninitialized variable in L3::Passport e_descr() version 3.07 (2013-10-01) [ENHANCEMENTS] * Support for Pica8 switches in L3::Pica8 * Factor out cache/munge code from global/attr methods [BUG FIXES] * [#48] Switch duplicate J9624A for J9626A in Layer2/HP (R. Kerr) * Correct device serial number reporting for Nexus devices * Override ipAddrTable methods in L3::Nexus as some versions do not index the table with the IPv4 address in accordance with the MIB definition. version 3.05 (2013-08-16) [ENHANCEMENTS] * [#47] Add model info on HP 2530 and HP 2920 series * Add support for Cisco Small Business series Layer2/CiscoSB class * Add proper LLDP support to Netgear.pm * Change $netgear->interfaces() to use ifName rather than ifDescr as the former is unique per interface while the latter is not. If ifName is not present, concatenate ifDescr and ifIndex to achieve a unique value. * Properly report hardware version, Serial No. and OS Version for Netgear. version 3.03 (2013-07-11) [BUG FIXES] * Add missing =back to POD (A. Hartmaier) version 3.02 (2013-07-08) [ENHANCEMENTS] * Properly pull os_ver from Netgear GS series switches. * Support Alcatel devices with layer3 features. * Identify Cisco Aironet 1140 APs as Layer2::Aironet * LAN switch support added to Layer3::Aruba class * [RT#86725] - Identify Cisco Catalyst 3850 as Layer3::C6500 (C. Causer) version 3.01 (2013-04-13) [API Changes] * The methods c_ip(), c_if(), c_port(), c_id(), and c_platform() now represent common topology methods and will try to return a combined hash of data from all L2 topology protocols either running on the device or specified in the method call. The topology specific methods have been been prefixed with the protocol name in lowercase so that they can be called directly, sonmp_ip(), cdp_ip(), etc. * L2::Bay and L2::Foundry have been removed from the distribution. Both classes were depreciated and all functionality is available through L2::Baystack and L3::Foundry. [NEW FEATURES] * [3160037] - Support _raw suffix on methods to skip munging * [3185391] - Support for F5 devices in new class L3::F5 * [3323814] - Arp support for Netscreen (David Baldwin) * [3323821] - Support for Netscreen w/ WLAN (eg SSG5) (David Baldwin) * [3599277] - Q-BRIDGE Support to collect VLAN in macsuck * [3033731] - Alcatel-Lucent OmniSwich AMAP Support in new AMAP class * [3598896] - Lantronix device support (J R Binks) * [3598337] - Lantronix SLC support * Support for Cisco ASA in L3::CiscoASA (Kraus/Hartmaier/Bernstein) * Support for Avaya VSP 9000 series in L3::Passport * Support for Avaya VSP 7000 series in L2::Baystack * Support Avaya (Trapeze) Wireless Controllers in new class L2::NWSS2300 * Support Juniper (Trapeze) Wireless Controllers in new class L2::Trapeze * Support for newer Radware Alteon ADC switches 4408/4416/5412/5224 and older AWS 2000/3000 series in existing L3::AlteonAD * Support for H3C & HP A-series in new class L3::H3C * Support for Citrix Netscaler appliances in new class L7::Netscaler * New configuration option IgnoreNetSNMPConf will ignore Net-SNMP configuration files on object initialization * Two new utilities added in t/util to assist in developing device support; make_snmpdata.pl gathers SNMP data (snmpwalk) in a format that can be used with test_class_mocked.pl which mocks an SNMP agent to enable testing with no network access to a device. [ENHANCEMENTS] * UNIVERSAL::can() now works with dynamic methods * Dynamically generated methods are added to symbol table to avoid AUTOLOAD on subsequent calls * L2::Airespace now supports 802.11n client tx rates * L2::Airespace now reports AP Ethernet MAC as port MAC for radio ports * CiscoStats improvements to determine os versions, eg IOS XE ver on Sup7L-E * CiscoStats now reports 'ios-xe' if the device runs IOS XE (used to be 'ios') * Improved support of XOS based Extreme devices [BUG FIXES] * [3564920] - lldp_if gives wrong data for Enterasys version 2.11 (2012-12-09) [BUG FIXES] * Add fall-back for sysDescr on Force10 version 2.10 (2012-12-08) [NEW FEATURES] * Support for Force10 devices (W. Bulley) version 2.09 (2012-11-28) [NEW FEATURES] * New method i_ssidmac() to get BSSID's from AP's with initial support in L2::Aironet and Airespace classes * Support for Avaya Secure Routers in new class L3::Tasman * Add EDP and LLDP L2 Topology to L3::Extreme * [3185393] Support for Juniper SSL VPN in new class L7::Neoteris * [3381027] Support for Cisco Nexus in new class L3::Nexus * [1424336] Support for Extreme Discovery Protocol (EDP) [ENHANCEMENTS] * [3017571] Add LLDP support for NetSNMP device class (begemot) * [3418918] Extreme devices now report OS as either extremeware or xos * [2809045] Strip preceding netscreen from model name in L3::Netscreen * [] Classify Linksys 2024 as L3::Dell (Rogier Krieger) [BUG FIXES] * Fixed logic to return cached data for table methods when available and not a partial fetch * Fix typo in PoD for Bridge.pm and CiscoConfig.pm (William Bulley) * Fix/improve IPv6 neighbor cache handling, especially for Cisco Nexus version 2.08 (2012-07-15) [NEW FEATURES] * Basic support for APC UPS devices * [2993691] Support for SonicWALL devices in new class L3::SonicWALL (phishphreek) * [2996795] Support for Kentrox devices in new class L2::Kentrox (phishphreek) * [] Basic support for Blue Coat proxy devices in new class L3::BlueCoatSG (jeroenvi) * [] Support Cisco 6500 / Sup2T in L3::C6500 class (jeroenvi) [ENHANCEMENTS] * Pseudo ENTITY-MIB methods added to L3::Juniper for hardware information * Add method to report current transmit power of the radio interface, dot11_cur_tx_pwr_mw(), in Airespace class * [3085411] Activate L3 properties for Netgear GSM7224v2 (phishphreek) * [3085413] SNMP OIDs for Netgear Serial and OS Ver (phishphreek) * [3286549] Dell LLDP Support (Nico Giefing) * [3469527] Netgear LLDP Support (Nic Bernstein) * [3472052] moduleSerialNumber support for Cisco Stack (Slava) * [3523320] Better VLAN support in Juniper class (Web Bulley) * [3532261] LLDP support in C6500 and related (Carlos Vicente) * [3538949] Updated switch models in L2::HP (jeroenvi) [BUG FIXES] * Get OS version for Juniper devices not reporting in sysDescr * Correct base MAC reporting for Juniper devices * Correct reporting of SSID broadcast status in Airespace class * [3541442] Change L2::Catalyst port names to what is reported in CDP * [2132349] Add an additional check to get Foundry OS version * [2929883] [3413999] LLDP interface mapping issue * [3297786] LLDP TimeMark component defaults to zero (David Baldwin) * [2988163] Detect Juniper SSG firewalls as Layer3::Netscreen (R. Kerr) * [3317739] Fix for Baystack without POE on stack member 1 (David Baldwin) * [2037444] os_ver fails on some Extreme versions (Robert Kerr) * [2980789] Fix root_ip to try OSPF RouterID first (Brian De Wolf) * [2986858] Fix the patch from this ticket (Oliver Gorwits) * [3136084] Rename Allied Telesyn to Allied Telesis (Oliver Gorwits) * [3268104] CiscoVTP.pm i_vlan_membership() array bounds (Michael Sanderson) * [3497004] Clarify POD description of default values (a2w) * [3502533] Layer2/Baystack interface indexes > 513 (Robert Nyqvist) version 2.06 (2011-09-28) [NEW FEATURES] * Support for PacketFront devices in new class L3::PacketFront * Support for Mikrotik devices in new class L3::Mikrotik * Support for HP VirtualConnect switches in new class L2::HPVC * Support for ADSL-LINE-MIB in new class AdslLine [ENHANCEMENTS] * POD clarification on i_speed() munging by Info.pm * Added i_stack_status method that can be used for finding the parent interface for e.g. ADSL interface speed determination [BUG FIXES] * [3344843] Fix returning serial() and os_ver() for web-managable HP switches, introduced by HP/HP4000 class split, reported by J R Binks * [2809033] Put L2-only Cisco blade switches in L3::C6500 * [3408506] Fix uninitialized value in IPv6 when neighbor state is incomplete (Michael Borgelt) version 2.05 (2011-06-23) + Fix broken function call in L2::Aironet + Promote L2::Aruba to L3::Aruba, as Aruba devices can be L3 entities and provide L3 information. version 2.04 (2011-03-31) + Support for older HP switch models moved to new L2::HP4000 class + Fix VLAN changing in L2::HP and L2::HP4000 classes * Updated model lists in HP classes + [2980782] Added L3::CiscoFWSM for Cisco Firewall Services Modules (Brian De Wolf) + Added L3::Pf for FreeBSD PFSense Firewalls (max) * Added specific functions for neighbor mgmt addresses to CDP class * Implemented os_bin() method in CiscoStats + [2980787] Fix for C1900 bp_index not containing interfaces. (Brian De Wolf) + [2599795] Added vendor_i_type() method to HP and HP4000 clases + [2688801] Minor modification for obscure Proxim/Orinoco device (jrbinks) + [3051443] Add PoE measured power per port to Cisco, Extrme and HP classes (jeroenvi) * Minor tweaks to support devices without sysServices * Added Cisco CBS3xxx blade switches to L3::C6500 * Fix for FWSMs not being detected properly. Special thanks goes to Jukka Pirhonen for pointing it out. (Brian De Wolf) + Added support for IPv6 to physical address mapping * Added ME340x to L3::C3550 * Added new ProCurve models to HP class * Fixed i_speed_raw not returning raw values (Alexander Hartmaier) version 2.01 (06/12/09) + Added CiscoStpExtensions Class (Carlos Vicente) + Added Layer3::Arista (fenner) + [2020353] Added L3::Altiga for Cisco (Altiga) VPN3000 Concentrators (Jeroen van Ingen) * Fixed RFC1213-MIB vs IF-MIB collision in ifOperStatus * Updated test_class.pl for better debug info and relative path * Add cisco vendor detection by OID in Layer3.pm (Sam Stickland) * Fix CaSe of EtherLike-MIB in EtherLike.pm (Alexander Hartmaier) * Added Cisco FWSM to L3::Cisco * Added s222_rp to L3::C6500 * Added CIGESM to L2::C2900 * Added Airespace WLC to L2::Airespace * Updated POD and DeviceMatrix quite a bit * Added ENTITY-MIB to CiscoStats for better model handling above * Fix networkaddress handling in LLDP-MIB * Added CiscoConfig to L2::Aironet, L3::C3550 classes * Better SSID capabilities for L2::Aironet * Fix CDP vs LLDP in c_id() for HP Class * test_class.pl improvements version 2.00 (08/01/08) + Support for Alcatel-Lucent OmniSwitch via L3::AlcatelLucent + Support for Alcatel-Lucent Service Router via L3::Timetra + Support for Alcatel-Lucent OmniAccess via L2::Aruba * Silence warnings in MAU due to uninitialized variables version 1.09 (07/22/08) - Beta/developer release + Added support for HP ProCurve Foundry OEM switches, such as the 9300 series, in new class L3::HP9300 (contributions from Douglas McKeown and Ivan Auger) + Added support for CISCO-PAE-MIB in CiscoPortSecurity (Kesy) + Support for D-Link devices through L3::Dell + Support for Linksys SRW2048 through L3::Dell + Support for IBM BladeCenter 4-Port GB Ethernet Switch Module through L3::Dell (Alex Kramarov) + Support for newer Nortel Alteon switches and Nortel BladeCenter Switch Modules in L3::AlteonAD + Support for Cisco 1250 series through L2::Aironet + Updates to fan, power supply, and serial number methods in L2::HP (Jeroen van Ingen) + Use Cisco Client Association MIBs for Aironet client reporting via fw_mac + Support VLANs on Aironet + Get the proper radio MAC address from aironet in MBSS mode + Additional wireless statistics from Aironet + Add support to specify MIB to resolve leaf names conflicts in %GLOBALS and %FUNCS. + Added munge_port_list() and modify_port_list() methods to assist in working with PortList objects. + Added set_multi() method to enable a SNMP set command on several new values in one request. Required for complex set operations on some agents. + Infrastructure for SNMPv3 support: + Save the SecName passed into the constructor + Create an update() function, which replaces the underlying SNMP session using different parameters. + Return the SecName instead of community from snmp_comm() when using SNMPv3. * L2::HP now isa Layer3 instead of Layer2 to support arpnip (Dudley Freeman) * Silence warnings from Cisco devices which don't return values for extended VLAN range (1024-4096) * Documentation coverage, spelling, and syntax updates * set_i_pvid(), set_i_vlan(), set_add_i_vlan_tagged(), set_remove_i_vlan_tagged() removed from Bridge and HP classes due to incompatibility across devices. version 1.07 (11/26/07) - Beta/developer release version 1.05 (11/25/07) - CVS only. No official release + Added support for LLDP in new class LLDP (contributions from Bernhard Augenstein) + Added device specific support for LLDP in L2::HP, L2::Baystack, L3::Enterasys and L3::Foundry + Added support for Enterasys devices as new class L3::Enterasys + Added support for Dell PowerConnect switches as new class L3::Dell + Added basic support for generic routers running Microsoft Windows OS as new class L3::Microsoft (begemot) + Added basic support for Sun routers as new class L3::Sun (begemot) + Added basic support for Juniper NetScreen devices as new class L3::Netscreen (Kent Hamilton) + Added support for Cyclades terminal servers as new class L1::Cyclades + Added support for Cisco (Airespace) wireless controllers as new class L2::Airespace + Added support for Nortel Ethernet Routing Switch 2500 series and Business Ethernet Switches (David Siebörger) + Update of L3::Foundry to support all Foundry devices including newer switches. Depreciate L2::Foundry. + Added generic device type detection using IANA assigned enterpise number extracted from sysObjectID + Added ifDiscards and other missing entries from IF-MIB::ifEntry (Greg King) + Added CGESM devices to L2::C2900 class (Alexander Hartmaier) + Added support for dual speed 10/100 hubs and i_speed() in L1::Bayhub + Added i_ssidlist(), i_ssidbcast(), and i_80211channel() methods to L2::Aruba, Airespace, and L2::NAP222x classes + New class IEEE802dot11 class for generic standards based wireless AP support to include i_ssidlist()and i_80211channel() methods. + L2::Orinoco inherits from new IEEE802dot11 for i_ssidlist()and i_80211channel() support. + Added new VLAN methods i_pvid(), i_vlan_membership(), set_i_pvid(), set_i_vlan(), set_add_i_vlan_tagged(), set_remove_i_vlan_tagged() to Bridge, CiscoVTP, Extreme, HP, and RapidCity classes. + Added set_i_speed_admin() method to RapidCity class, + Added set_i_duplex_admin() method to RapidCity class, + Added OSPF Neighbor Tables, SF Patch 1577918 to Layer 3 (Andrew Herrick) + Added CiscoConfig class, SF Patch 1555001 (Justin Hunter) + Enable load_ methods for %GLOBALS and MIB Leaf node names. + Enable dynamic methods in AUTOLOAD with MIB Leaf node names for loaded MIBs without definition in %FUNCS or %GLOBALS. Single instance mib leafs will be treated as a GLOBAL and returna scalar while mib leafs which reside in a table will be treated as a FUNC and return a reference to a hash. + Enable load_ methods for %GLOBALS and MIB Leaf node names. + Add loop detect option and code for getnext table column walks. + Add Layer3::NetSNMP for Net-SNMP-based hosts, part of SF patch 1557529 (Bradley Baetz). + Add EIGRP Neighbor Tables to L3::Cisco SF Patch 1577927 (Andrew Herrick) + Additions to CiscoQOS and CiscoStats (Alexander Hartmaier) + Emulate ENTITY-MIB Physical Table methods for devices which don't have ENTITY-MIB support in Airespace, Bayhub, Baystack, BayRS, NortelStack, and Passport classes. + Enable use of MIB Leaf node names in SNMP sets. + Add POWER-ETHERNET-MIB and CISCO-POWER-ETHERNET-EXT-MIB support. * Fix for bug where an SNMP error in any operation would cause subsequent table get operations to fail while using the same session, originally identified by Nicolai Petri. * Enable single instance partial table fetches (Alexander Hartmaier) * Enable partial table fetches in overriden table methods (Justin Hunter) * Allow partial table fetches with load_ methods. * Fixed vlan trunk port handling bug in L2:HP (Michael Robbert) * Correct bp_port() definition in Bridge class (Reported by Nicolai Petri) * Remove port security definitions from CiscoStack and move into new class CiscoPortSecurity. Needed to support devices such a L3::C4000 which support CISCO-PORT-SECURITY-MIB, but not CISCO-STACK-MIB. (Reported by Prakash RudraRaju) * Correct port numbering for Nortel 8110, 1100, 1150 in L3:Passport (Reported by David Pinkoski) * Documentation updates * Translate OIDs returned by Entity MIB e_type * Modify inheritance to use Cisco classes before generic classes * Create e_index method in ENTITY-MIB to facilitate emulation methods in other classes as entPhysicalIndex is not-accessible. * Only return MAC from munge_mac() if it actually is a MAC. Fix for netdisco where device would not be inserted in DB due to malformed MAC. * Enable SUPER class calls to find autoloaded methods (Bernhard Augenstein) * Clear attribute cache on sucessful SNMP set. * Improve accuracy of operational and administrative duplex reporting on devices using CiscoStack. * All i_type() methods now use standard IANAifType values. * Report bridge groups (VLANs) in L2::C1900. * Turn on bulkwalk for C6500. Users with buggy OS versions can turn it off when creating the object. * c_ip() now attempts to return only IPV4 addresses, use c_addr() for all address types. version 1.04 (07/08/06) + Added C1130 and C1240 to L2::Aironet (Ralf Gross) + Added detection for Cisco 2960, 2940, 3400 w/ MetroBase + Added generic L2::Cisco Class * Corrected detection for Cisco Supervisor Engine 2 and 32 (IOS). * Fixed warnings in CiscoStack * Updated ProCurve HP device detection for newer firmwares version 1.03 (04/14/06) - Beta/developer release * Use ipNetToMedia table instead of atTable for ARP * Remove CiscoStack from Layer3::C4000 * Fixed bug in MAU class when polling devices without MAU-MIB support version 1.01 (04/08/06) - Beta/developer release + Change version numbers to X.XX format. Odd releases are beta or developer only releases. Even are official releases. version 1.0 (04/07/06) - CVS only. No official release + Added Interface FlowControl status to CiscoStack (Nicolai Petri) + Added CiscoImage class (Matthew Tuttle) + Added C1200 and C350 IOS devices to L2::Aironet (Matthew Tuttle) + Added support for Foundry IronWare and gave L3::Foundry CPR + Added support for Foundry EdgeIrons as new class L2::Foundry + Added BulkWalk and BulkRepeaters options to new() + Added DebugSNMP option to new() + Added CISCO-ENTITY-VENDORTYPE-OID-MIB,CISCO-PRODUCTS-MIB,CISCO-STACK-MIB to CiscoStats.pm for model() + Check for bulkwalk_no() method + Added Entity.pm to L3 and L2 classes per N. Petri's suggestion. + Added support for Passport/Accelar 1100 and 1200 series in L3::Passport + Added support for Passport/Accelar 8100 series in L3::Passport + Added support for Passport 1600 series as new class, L3::N1600 + Added support for Extreme Alpine and Summit switches as new class L3:Extreme (Mike Hunter and Eric Miller) + Added support for Aruba wireless switches (Eric Miller and Brian Chow) + Added support for Nortel 2700 series (Airespace) wireless switches + Added support for Synoptics hubs as new class L1:S3000 + Added Cisco QOS and RTT classes (Alexander Hartmaier) + Added BGP Peer Table to L3 class (Carlos Vicente) + Added ipforwarding status to Info base class (Carlos Vicente) + Added STP port state to Bridge class (Alexander Barthel) + Added L3 support (arpnip) to Baystack class for routing capable switches + Added set_i_duplex_admin() and set_i_speed_admin() to C2900 class (Justin Hunter) + Added set_i_duplex_admin() and set_i_speed_admin() to CiscoStack class + CDP added to Aironet class + Added Juniper class + Added support for Catalyst 4000 and 4500, get admin. duplex and speed properly + Added i_speed_high(), which i_speed() uses if needed to support interfaces >4Gbps * More error checking in _load_attr() around bulkwalk code * Minor warning fix in L3::Aironet::os_ver() * Abstracted remaining Cisco stuff from L3 to L3::Cisco * Removed all Cisco stuff from L2 * Expanded Entity.pm to cover the whole ENTITY-MIB and improved docs. * changed all refs to $DEBUG to $self->debug() for reentrant code * [ 1111284 ] Parameters not being set with AutoSpecify - fixed. * Turned off BULKWALK for C1900 and C6500 classes. * Added exception handling for V2 ENDOFMIBVIEW * Fix in SONMP when topology not enabled * Fix in L3::Passport root_ip() * Fix in L3::Passport bp_index() some devices not returning complete index. * Enable set_i_up_admin() in Bayhub * Recognize new Nortel model names in Baystack and Passport classes * Orinoco class should now recognize more models * Cleanup model recognition in Baystack class, recognize more models * Modify Catalyst class to use CISCO-STACK-MIB for brige port index mapping some devices having problems returning complete index from BRIDGE-MIB * Check root ip for reachability before assignment * HP class should recognize more models * Fix in HP class for models not returning full bp_index * [ 1436103 ] L2::Aironet devices weren't getting their model translated properly verison 0.9 (11/15/04) + ** Added full Nortel/Bay/BayStack support by new developer Eric Miller. L2::Bay now depricated. + Added Alteon Ace support (Eric Miller) + Added Nortel Cotivity support (Eric Miller) + Added Nortel BayRS support (Eric Miller) + Added Nortel Centillion support (Eric Miller) + Added Nortel AP 222x support (Eric Miller) + Added Orinco AP support (Eric Miller) + Added i_lastchange() per suggestion of Nicolai Petri + Added BULKWALK patch by Bradley Baetz - This should greatly speed up requests on SNMPv2c devices. + Added MibDirs option to new() to allow specifying non-system MIB directories. * Added C3560s to the C3550 class. Thanks to Nicolai. * Fixed Bug where older Cisco's would append nulls to certain CDP information. Would come up a 'DBD::Pg parser' error in Netdisco * Changed so a failed _global() call is cached so it won't retry an error over and over again if the same global is used. * Added check in _set() to see if data came from sub or FUNCS/GLOBALS Fails if came from sub. version 0.8 (03/21/04) + Added Q-BRIDGE-MIB support to SNMP::Info::Bridge + Added Aironet AP4800 to Layer3::Aironet class + Added C3500XL devices to the Layer2::C2900 class + Added Cisco 3750 (37xxstack) to Layer3::C6500 class + Added Cisco Catalyst 4000 to Layer3::C6500 class + Added Cisco Catalyst 2970 to Layer3::C6500 Class * Made Cisco Commuinty string indexing a boolean method for clarification * Added VLAN info for HP devices using Q-BRIDGE-MIB * Fixed warning about uninitialized value in CiscoStats line 92 * Added for more serial# checking for L2 and L3 * Fixed warning in Layer2::Bay about non numeric port line 199 Contributions from Dmitry Sergienko: + Added Cisco Aironet BR500 and AP1200 to L2::Aironet Class * Fixed the Port name alias for Catalyst 2900 devices + Added Support For ZyXEL DSLAMs and Allied Telesys Switches version 0.7 (08/14/03) * Added Class for Catalyst 6500 Series - Layer3::C6500 * Added CiscoVTP support to 3550,2900, and Catalyst classes * Extracted VLAN stuff from Layer2::Catalyst to SNMP::Info::CiscoVTP * Extracted CISCO-STACK-MIB from Layer2::Catalyst to SNMP::Info::CiscoStack * Added 2950's to the Layer2::C2900 class * Added 3548's and 350x's to the Layer3::C3550 class * Broke out 3550's into separate device types (3550-24, 3550-48) * Added T1,dual T1, and T3 , ATM over OC-12 ... to the SPEED_MAP * Fixed speed map -- OC-1 -> OC-3 * Fixed Bug where Catalyst Switch running IOS would report CatOS as os() version 0.6 (06/18/03) * Minor Bug Fix. SNMP::Info::Layer2::Bay and SNMP::Info::Layer2::C1900 didn't return 1 and failed to load on some versions of Perl. version 0.5 (06/10/03) * Added ability to get paritial tables. For example to get the IP routing table for 128.114.* you can do $ipr = $dev->ipr_dest('128.114'); * Added IP Routing Table entries from RFC1213 to SNMP::Info * minor bug fixes version 0.4 (04/29/03) * BIG CHANGE ! Internal Data structure has changed. * Added clear_cache() method * Added NO_SUCH support for snmpget (TABLE) calls to get SNMP MIB II data from SNMP Version 1 devices. * Methods load_all() and all() have changed their return value. Sorry but the API had to change. * New object methods snmp_comm(), snmp_ver(), store(), class(), nosuch() to make it more OO happy. * Globals are now cached * Added new argument 'AutoSpecify' to new() to auto-connect with subclass detected in device_type() * New method specify() returns a new subclass object * Subclasses are automatically loaded when specify or autospecify is used! * Added methods for Interface statistics (ifInOctets ...) * Added methods for Memory and CPU statistics * Added SNMP::Info::Entity, moved out of L2-HP * Added SNMP::Info::Layer2::Aironet version 0.3 (03/06/03) * Fixed HP model() warning * Added error checking for responses of NOSUCHOBJECT and NOSUCHINSTANCE in _global and _load_attr * Added more debugging * Added info and munging for c_capabilities in SNMP::Info::CD Thanks to Martin Lorensen * Removed requirement for SNMP in the Makefile.PL and moved it to t/prereq.t so that the Module will install via CPAN without trying to install the old 4.2.0 version of SNMP on CPAN. Will now fail in the test phase. Thanks again to Martin Lorensen * Moved tests from test.pl to t/* version 0.2 (02/19/03) * Added put_() methods and support for SNMP put commands * Added SNMP::Info::Layer3::C3550 class for Cisco Catalyst 3550 * Fixed HP Detection in device_type() * Added Spanning Tree Protocol (STP) methods to SNMP::Info::Bridge * Removed HP Specific MIBS in SNMP::Info::Layer2 and cleaned up model() * Added poke for Bay 450 Switches * Mapped HP Part Numbers to model numbers J4812A => 2512 in SNMP::Info::Layer2::HP version 0.1 (12/30/02) * Initial Release * SubClasses Included: * SNMP::Info::Bridge * SNMP::Info::CDP * SNMP::Info::EtherLike * SNMP::Info::MAU * SNMP::Info::Layer1 o SNMP::Info::Layer1::Allied o SNMP::Info::Layer1::Asante * SNMP::Info::Layer2 o SNMP::Info::Layer2::Bay o SNMP::Info::Layer2::C1900 o SNMP::Info::Layer2::C2900 o SNMP::Info::Layer2::Catalyst o SNMP::Info::Layer2::HP * SNMP::Info::Layer3 o SNMP::Info::Layer3::Aironet o SNMP::Info::Layer3::Foundry SNMP-Info-3.39/LICENSE000444000765000024 324713215550564 14060 0ustar00oliverstaff000000000000All code from version 0.7 on Copyright (c) 2003-2016 Max Baker and SNMP::Info Developers All rights reserved. Original Code Copyright (c) 2002,2003 Regents of the University of California All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of California, Santa Cruz nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SNMP-Info-3.39/MANIFEST000444000765000024 750013215550564 14200 0ustar00oliverstaff000000000000Build.PL Changes contrib/DEVELOP contrib/util/docmunge contrib/util/make_dev_matrix.pl contrib/util/make_snmpdata.pl contrib/util/push_ver contrib/util/run_test contrib/util/test_class.pl contrib/util/test_class_mocked.pl lib/SNMP/Info.pm lib/SNMP/Info/AdslLine.pm lib/SNMP/Info/Aggregate.pm lib/SNMP/Info/Airespace.pm lib/SNMP/Info/AMAP.pm lib/SNMP/Info/Bridge.pm lib/SNMP/Info/CDP.pm lib/SNMP/Info/CiscoAgg.pm lib/SNMP/Info/CiscoConfig.pm lib/SNMP/Info/CiscoPortSecurity.pm lib/SNMP/Info/CiscoPower.pm lib/SNMP/Info/CiscoQOS.pm lib/SNMP/Info/CiscoRTT.pm lib/SNMP/Info/CiscoStack.pm lib/SNMP/Info/CiscoStats.pm lib/SNMP/Info/CiscoStpExtensions.pm lib/SNMP/Info/CiscoVTP.pm lib/SNMP/Info/EDP.pm lib/SNMP/Info/Entity.pm lib/SNMP/Info/EtherLike.pm lib/SNMP/Info/FDP.pm lib/SNMP/Info/IEEE802dot11.pm lib/SNMP/Info/IEEE802dot3ad.pm lib/SNMP/Info/IPv6.pm lib/SNMP/Info/Layer1.pm lib/SNMP/Info/Layer1/Allied.pm lib/SNMP/Info/Layer1/Asante.pm lib/SNMP/Info/Layer1/Bayhub.pm lib/SNMP/Info/Layer1/Cyclades.pm lib/SNMP/Info/Layer1/S3000.pm lib/SNMP/Info/Layer2.pm lib/SNMP/Info/Layer2/3Com.pm lib/SNMP/Info/Layer2/Airespace.pm lib/SNMP/Info/Layer2/Aironet.pm lib/SNMP/Info/Layer2/Allied.pm lib/SNMP/Info/Layer2/Baystack.pm lib/SNMP/Info/Layer2/C1900.pm lib/SNMP/Info/Layer2/C2900.pm lib/SNMP/Info/Layer2/Catalyst.pm lib/SNMP/Info/Layer2/Centillion.pm lib/SNMP/Info/Layer2/Cisco.pm lib/SNMP/Info/Layer2/CiscoSB.pm lib/SNMP/Info/Layer2/HP.pm lib/SNMP/Info/Layer2/HP4000.pm lib/SNMP/Info/Layer2/HPVC.pm lib/SNMP/Info/Layer2/Kentrox.pm lib/SNMP/Info/Layer2/N2270.pm lib/SNMP/Info/Layer2/NAP222x.pm lib/SNMP/Info/Layer2/Netgear.pm lib/SNMP/Info/Layer2/NWSS2300.pm lib/SNMP/Info/Layer2/Orinoco.pm lib/SNMP/Info/Layer2/Trapeze.pm lib/SNMP/Info/Layer2/Ubiquiti.pm lib/SNMP/Info/Layer2/ZyXEL_DSLAM.pm lib/SNMP/Info/Layer3.pm lib/SNMP/Info/Layer3/Aironet.pm lib/SNMP/Info/Layer3/AlcatelLucent.pm lib/SNMP/Info/Layer3/AlteonAD.pm lib/SNMP/Info/Layer3/Altiga.pm lib/SNMP/Info/Layer3/Arista.pm lib/SNMP/Info/Layer3/Aruba.pm lib/SNMP/Info/Layer3/BayRS.pm lib/SNMP/Info/Layer3/BlueCoatSG.pm lib/SNMP/Info/Layer3/C3550.pm lib/SNMP/Info/Layer3/C4000.pm lib/SNMP/Info/Layer3/C6500.pm lib/SNMP/Info/Layer3/Cisco.pm lib/SNMP/Info/Layer3/CiscoASA.pm lib/SNMP/Info/Layer3/CiscoFWSM.pm lib/SNMP/Info/Layer3/CiscoSwitch.pm lib/SNMP/Info/Layer3/Contivity.pm lib/SNMP/Info/Layer3/Dell.pm lib/SNMP/Info/Layer3/DLink.pm lib/SNMP/Info/Layer3/Enterasys.pm lib/SNMP/Info/Layer3/Extreme.pm lib/SNMP/Info/Layer3/F5.pm lib/SNMP/Info/Layer3/Force10.pm lib/SNMP/Info/Layer3/Fortinet.pm lib/SNMP/Info/Layer3/Foundry.pm lib/SNMP/Info/Layer3/H3C.pm lib/SNMP/Info/Layer3/HP9300.pm lib/SNMP/Info/Layer3/Huawei.pm lib/SNMP/Info/Layer3/IBMGbTor.pm lib/SNMP/Info/Layer3/Juniper.pm lib/SNMP/Info/Layer3/Lantronix.pm lib/SNMP/Info/Layer3/Microsoft.pm lib/SNMP/Info/Layer3/Mikrotik.pm lib/SNMP/Info/Layer3/N1600.pm lib/SNMP/Info/Layer3/Netscreen.pm lib/SNMP/Info/Layer3/NetSNMP.pm lib/SNMP/Info/Layer3/Nexus.pm lib/SNMP/Info/Layer3/PacketFront.pm lib/SNMP/Info/Layer3/PaloAlto.pm lib/SNMP/Info/Layer3/Passport.pm lib/SNMP/Info/Layer3/Pf.pm lib/SNMP/Info/Layer3/Pica8.pm lib/SNMP/Info/Layer3/SonicWALL.pm lib/SNMP/Info/Layer3/Steelhead.pm lib/SNMP/Info/Layer3/Sun.pm lib/SNMP/Info/Layer3/Tasman.pm lib/SNMP/Info/Layer3/Timetra.pm lib/SNMP/Info/Layer3/VMware.pm lib/SNMP/Info/Layer7.pm lib/SNMP/Info/Layer7/APC.pm lib/SNMP/Info/Layer7/CiscoIPS.pm lib/SNMP/Info/Layer7/Neoteris.pm lib/SNMP/Info/Layer7/Netscaler.pm lib/SNMP/Info/LLDP.pm lib/SNMP/Info/MAU.pm lib/SNMP/Info/MRO.pm lib/SNMP/Info/NortelStack.pm lib/SNMP/Info/PowerEthernet.pm lib/SNMP/Info/RapidCity.pm lib/SNMP/Info/SONMP.pm LICENSE MANIFEST This list of files META.json META.yml t/00_load.t xt/.perltidyrc xt/00_local_distribution.t xt/00_local_docininfo.t xt/00_local_perlcritic.t xt/00_local_pod-coverage.t xt/00_local_pod.t xt/00_local_prereq.t xt/00_local_spelling.t xt/00_local_versionsync.t SNMP-Info-3.39/META.json000444000765000024 3643213215550564 14516 0ustar00oliverstaff000000000000{ "abstract" : "OO Interface to Network devices and MIBs through SNMP", "author" : [ "Eric A. Miller " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.4224", "license" : [ "bsd" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "SNMP-Info", "prereqs" : { "configure" : { "requires" : { "Module::Build" : "0.42" } }, "runtime" : { "requires" : { "Math::BigInt" : "0", "SNMP" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88" } } }, "provides" : { "SNMP::Info" : { "file" : "lib/SNMP/Info.pm", "version" : "3.39" }, "SNMP::Info::AMAP" : { "file" : "lib/SNMP/Info/AMAP.pm", "version" : "3.39" }, "SNMP::Info::AdslLine" : { "file" : "lib/SNMP/Info/AdslLine.pm", "version" : "3.39" }, "SNMP::Info::Aggregate" : { "file" : "lib/SNMP/Info/Aggregate.pm", "version" : "3.39" }, "SNMP::Info::Airespace" : { "file" : "lib/SNMP/Info/Airespace.pm", "version" : "3.39" }, "SNMP::Info::Bridge" : { "file" : "lib/SNMP/Info/Bridge.pm", "version" : "3.39" }, "SNMP::Info::CDP" : { "file" : "lib/SNMP/Info/CDP.pm", "version" : "3.39" }, "SNMP::Info::CiscoAgg" : { "file" : "lib/SNMP/Info/CiscoAgg.pm", "version" : "3.39" }, "SNMP::Info::CiscoConfig" : { "file" : "lib/SNMP/Info/CiscoConfig.pm", "version" : "3.39" }, "SNMP::Info::CiscoPortSecurity" : { "file" : "lib/SNMP/Info/CiscoPortSecurity.pm", "version" : "3.39" }, "SNMP::Info::CiscoPower" : { "file" : "lib/SNMP/Info/CiscoPower.pm", "version" : "3.39" }, "SNMP::Info::CiscoQOS" : { "file" : "lib/SNMP/Info/CiscoQOS.pm", "version" : "3.39" }, "SNMP::Info::CiscoRTT" : { "file" : "lib/SNMP/Info/CiscoRTT.pm", "version" : "3.39" }, "SNMP::Info::CiscoStack" : { "file" : "lib/SNMP/Info/CiscoStack.pm", "version" : "3.39" }, "SNMP::Info::CiscoStats" : { "file" : "lib/SNMP/Info/CiscoStats.pm", "version" : "3.39" }, "SNMP::Info::CiscoStpExtensions" : { "file" : "lib/SNMP/Info/CiscoStpExtensions.pm", "version" : "3.39" }, "SNMP::Info::CiscoVTP" : { "file" : "lib/SNMP/Info/CiscoVTP.pm", "version" : "3.39" }, "SNMP::Info::EDP" : { "file" : "lib/SNMP/Info/EDP.pm", "version" : "3.39" }, "SNMP::Info::Entity" : { "file" : "lib/SNMP/Info/Entity.pm", "version" : "3.39" }, "SNMP::Info::EtherLike" : { "file" : "lib/SNMP/Info/EtherLike.pm", "version" : "3.39" }, "SNMP::Info::FDP" : { "file" : "lib/SNMP/Info/FDP.pm", "version" : "3.39" }, "SNMP::Info::IEEE802dot11" : { "file" : "lib/SNMP/Info/IEEE802dot11.pm", "version" : "3.39" }, "SNMP::Info::IEEE802dot3ad" : { "file" : "lib/SNMP/Info/IEEE802dot3ad.pm", "version" : "3.39" }, "SNMP::Info::IPv6" : { "file" : "lib/SNMP/Info/IPv6.pm", "version" : "3.39" }, "SNMP::Info::LLDP" : { "file" : "lib/SNMP/Info/LLDP.pm", "version" : "3.39" }, "SNMP::Info::Layer1" : { "file" : "lib/SNMP/Info/Layer1.pm", "version" : "3.39" }, "SNMP::Info::Layer1::Allied" : { "file" : "lib/SNMP/Info/Layer1/Allied.pm", "version" : "3.39" }, "SNMP::Info::Layer1::Asante" : { "file" : "lib/SNMP/Info/Layer1/Asante.pm", "version" : "3.39" }, "SNMP::Info::Layer1::Bayhub" : { "file" : "lib/SNMP/Info/Layer1/Bayhub.pm", "version" : "3.39" }, "SNMP::Info::Layer1::Cyclades" : { "file" : "lib/SNMP/Info/Layer1/Cyclades.pm", "version" : "3.39" }, "SNMP::Info::Layer1::S3000" : { "file" : "lib/SNMP/Info/Layer1/S3000.pm", "version" : "3.39" }, "SNMP::Info::Layer2" : { "file" : "lib/SNMP/Info/Layer2.pm", "version" : "3.39" }, "SNMP::Info::Layer2::3Com" : { "file" : "lib/SNMP/Info/Layer2/3Com.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Airespace" : { "file" : "lib/SNMP/Info/Layer2/Airespace.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Aironet" : { "file" : "lib/SNMP/Info/Layer2/Aironet.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Allied" : { "file" : "lib/SNMP/Info/Layer2/Allied.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Baystack" : { "file" : "lib/SNMP/Info/Layer2/Baystack.pm", "version" : "3.39" }, "SNMP::Info::Layer2::C1900" : { "file" : "lib/SNMP/Info/Layer2/C1900.pm", "version" : "3.39" }, "SNMP::Info::Layer2::C2900" : { "file" : "lib/SNMP/Info/Layer2/C2900.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Catalyst" : { "file" : "lib/SNMP/Info/Layer2/Catalyst.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Centillion" : { "file" : "lib/SNMP/Info/Layer2/Centillion.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Cisco" : { "file" : "lib/SNMP/Info/Layer2/Cisco.pm", "version" : "3.39" }, "SNMP::Info::Layer2::CiscoSB" : { "file" : "lib/SNMP/Info/Layer2/CiscoSB.pm", "version" : "3.39" }, "SNMP::Info::Layer2::HP" : { "file" : "lib/SNMP/Info/Layer2/HP.pm", "version" : "3.39" }, "SNMP::Info::Layer2::HP4000" : { "file" : "lib/SNMP/Info/Layer2/HP4000.pm", "version" : "3.39" }, "SNMP::Info::Layer2::HPVC" : { "file" : "lib/SNMP/Info/Layer2/HPVC.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Kentrox" : { "file" : "lib/SNMP/Info/Layer2/Kentrox.pm", "version" : "3.39" }, "SNMP::Info::Layer2::N2270" : { "file" : "lib/SNMP/Info/Layer2/N2270.pm", "version" : "3.39" }, "SNMP::Info::Layer2::NAP222x" : { "file" : "lib/SNMP/Info/Layer2/NAP222x.pm", "version" : "3.39" }, "SNMP::Info::Layer2::NWSS2300" : { "file" : "lib/SNMP/Info/Layer2/NWSS2300.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Netgear" : { "file" : "lib/SNMP/Info/Layer2/Netgear.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Orinoco" : { "file" : "lib/SNMP/Info/Layer2/Orinoco.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Trapeze" : { "file" : "lib/SNMP/Info/Layer2/Trapeze.pm", "version" : "3.39" }, "SNMP::Info::Layer2::Ubiquiti" : { "file" : "lib/SNMP/Info/Layer2/Ubiquiti.pm", "version" : "3.39" }, "SNMP::Info::Layer2::ZyXEL_DSLAM" : { "file" : "lib/SNMP/Info/Layer2/ZyXEL_DSLAM.pm", "version" : "3.39" }, "SNMP::Info::Layer3" : { "file" : "lib/SNMP/Info/Layer3.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Aironet" : { "file" : "lib/SNMP/Info/Layer3/Aironet.pm", "version" : "3.39" }, "SNMP::Info::Layer3::AlcatelLucent" : { "file" : "lib/SNMP/Info/Layer3/AlcatelLucent.pm", "version" : "3.39" }, "SNMP::Info::Layer3::AlteonAD" : { "file" : "lib/SNMP/Info/Layer3/AlteonAD.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Altiga" : { "file" : "lib/SNMP/Info/Layer3/Altiga.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Arista" : { "file" : "lib/SNMP/Info/Layer3/Arista.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Aruba" : { "file" : "lib/SNMP/Info/Layer3/Aruba.pm", "version" : "3.39" }, "SNMP::Info::Layer3::BayRS" : { "file" : "lib/SNMP/Info/Layer3/BayRS.pm", "version" : "3.39" }, "SNMP::Info::Layer3::BlueCoatSG" : { "file" : "lib/SNMP/Info/Layer3/BlueCoatSG.pm", "version" : "3.39" }, "SNMP::Info::Layer3::C3550" : { "file" : "lib/SNMP/Info/Layer3/C3550.pm", "version" : "3.39" }, "SNMP::Info::Layer3::C4000" : { "file" : "lib/SNMP/Info/Layer3/C4000.pm", "version" : "3.39" }, "SNMP::Info::Layer3::C6500" : { "file" : "lib/SNMP/Info/Layer3/C6500.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Cisco" : { "file" : "lib/SNMP/Info/Layer3/Cisco.pm", "version" : "3.39" }, "SNMP::Info::Layer3::CiscoASA" : { "file" : "lib/SNMP/Info/Layer3/CiscoASA.pm", "version" : "3.39" }, "SNMP::Info::Layer3::CiscoFWSM" : { "file" : "lib/SNMP/Info/Layer3/CiscoFWSM.pm", "version" : "3.39" }, "SNMP::Info::Layer3::CiscoSwitch" : { "file" : "lib/SNMP/Info/Layer3/CiscoSwitch.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Contivity" : { "file" : "lib/SNMP/Info/Layer3/Contivity.pm", "version" : "3.39" }, "SNMP::Info::Layer3::DLink" : { "file" : "lib/SNMP/Info/Layer3/DLink.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Dell" : { "file" : "lib/SNMP/Info/Layer3/Dell.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Enterasys" : { "file" : "lib/SNMP/Info/Layer3/Enterasys.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Extreme" : { "file" : "lib/SNMP/Info/Layer3/Extreme.pm", "version" : "3.39" }, "SNMP::Info::Layer3::F5" : { "file" : "lib/SNMP/Info/Layer3/F5.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Force10" : { "file" : "lib/SNMP/Info/Layer3/Force10.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Fortinet" : { "file" : "lib/SNMP/Info/Layer3/Fortinet.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Foundry" : { "file" : "lib/SNMP/Info/Layer3/Foundry.pm", "version" : "3.39" }, "SNMP::Info::Layer3::H3C" : { "file" : "lib/SNMP/Info/Layer3/H3C.pm", "version" : "3.39" }, "SNMP::Info::Layer3::HP9300" : { "file" : "lib/SNMP/Info/Layer3/HP9300.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Huawei" : { "file" : "lib/SNMP/Info/Layer3/Huawei.pm", "version" : "3.39" }, "SNMP::Info::Layer3::IBMGbTor" : { "file" : "lib/SNMP/Info/Layer3/IBMGbTor.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Juniper" : { "file" : "lib/SNMP/Info/Layer3/Juniper.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Lantronix" : { "file" : "lib/SNMP/Info/Layer3/Lantronix.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Microsoft" : { "file" : "lib/SNMP/Info/Layer3/Microsoft.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Mikrotik" : { "file" : "lib/SNMP/Info/Layer3/Mikrotik.pm", "version" : "3.39" }, "SNMP::Info::Layer3::N1600" : { "file" : "lib/SNMP/Info/Layer3/N1600.pm", "version" : "3.39" }, "SNMP::Info::Layer3::NetSNMP" : { "file" : "lib/SNMP/Info/Layer3/NetSNMP.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Netscreen" : { "file" : "lib/SNMP/Info/Layer3/Netscreen.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Nexus" : { "file" : "lib/SNMP/Info/Layer3/Nexus.pm", "version" : "3.39" }, "SNMP::Info::Layer3::PacketFront" : { "file" : "lib/SNMP/Info/Layer3/PacketFront.pm", "version" : "3.39" }, "SNMP::Info::Layer3::PaloAlto" : { "file" : "lib/SNMP/Info/Layer3/PaloAlto.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Passport" : { "file" : "lib/SNMP/Info/Layer3/Passport.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Pf" : { "file" : "lib/SNMP/Info/Layer3/Pf.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Pica8" : { "file" : "lib/SNMP/Info/Layer3/Pica8.pm", "version" : "3.39" }, "SNMP::Info::Layer3::SonicWALL" : { "file" : "lib/SNMP/Info/Layer3/SonicWALL.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Steelhead" : { "file" : "lib/SNMP/Info/Layer3/Steelhead.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Sun" : { "file" : "lib/SNMP/Info/Layer3/Sun.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Tasman" : { "file" : "lib/SNMP/Info/Layer3/Tasman.pm", "version" : "3.39" }, "SNMP::Info::Layer3::Timetra" : { "file" : "lib/SNMP/Info/Layer3/Timetra.pm", "version" : "3.39" }, "SNMP::Info::Layer3::VMware" : { "file" : "lib/SNMP/Info/Layer3/VMware.pm", "version" : "3.39" }, "SNMP::Info::Layer7" : { "file" : "lib/SNMP/Info/Layer7.pm", "version" : "3.39" }, "SNMP::Info::Layer7::APC" : { "file" : "lib/SNMP/Info/Layer7/APC.pm", "version" : "3.39" }, "SNMP::Info::Layer7::CiscoIPS" : { "file" : "lib/SNMP/Info/Layer7/CiscoIPS.pm", "version" : "3.39" }, "SNMP::Info::Layer7::Neoteris" : { "file" : "lib/SNMP/Info/Layer7/Neoteris.pm", "version" : "3.39" }, "SNMP::Info::Layer7::Netscaler" : { "file" : "lib/SNMP/Info/Layer7/Netscaler.pm", "version" : "3.39" }, "SNMP::Info::MAU" : { "file" : "lib/SNMP/Info/MAU.pm", "version" : "3.39" }, "SNMP::Info::MRO" : { "file" : "lib/SNMP/Info/MRO.pm", "version" : "3.39" }, "SNMP::Info::NortelStack" : { "file" : "lib/SNMP/Info/NortelStack.pm", "version" : "3.39" }, "SNMP::Info::PowerEthernet" : { "file" : "lib/SNMP/Info/PowerEthernet.pm", "version" : "3.39" }, "SNMP::Info::RapidCity" : { "file" : "lib/SNMP/Info/RapidCity.pm", "version" : "3.39" }, "SNMP::Info::SONMP" : { "file" : "lib/SNMP/Info/SONMP.pm", "version" : "3.39" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/netdisco/snmp-info/issues" }, "homepage" : "http://netdisco.org/", "license" : [ "http://opensource.org/licenses/BSD-3-Clause" ], "repository" : { "url" : "https://github.com/netdisco/snmp-info" }, "x_IRC" : "irc://irc.freenode.org/#netdisco", "x_MailingList" : "https://lists.sourceforge.net/lists/listinfo/snmp-info-users" }, "version" : "3.39", "x_serialization_backend" : "JSON::PP version 2.94" } SNMP-Info-3.39/META.yml000444000765000024 2531613215550564 14345 0ustar00oliverstaff000000000000--- abstract: 'OO Interface to Network devices and MIBs through SNMP' author: - 'Eric A. Miller ' build_requires: Test::More: '0.88' configure_requires: Module::Build: '0.42' dynamic_config: 1 generated_by: 'Module::Build version 0.4224, CPAN::Meta::Converter version 2.150010' license: bsd meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: SNMP-Info provides: SNMP::Info: file: lib/SNMP/Info.pm version: '3.39' SNMP::Info::AMAP: file: lib/SNMP/Info/AMAP.pm version: '3.39' SNMP::Info::AdslLine: file: lib/SNMP/Info/AdslLine.pm version: '3.39' SNMP::Info::Aggregate: file: lib/SNMP/Info/Aggregate.pm version: '3.39' SNMP::Info::Airespace: file: lib/SNMP/Info/Airespace.pm version: '3.39' SNMP::Info::Bridge: file: lib/SNMP/Info/Bridge.pm version: '3.39' SNMP::Info::CDP: file: lib/SNMP/Info/CDP.pm version: '3.39' SNMP::Info::CiscoAgg: file: lib/SNMP/Info/CiscoAgg.pm version: '3.39' SNMP::Info::CiscoConfig: file: lib/SNMP/Info/CiscoConfig.pm version: '3.39' SNMP::Info::CiscoPortSecurity: file: lib/SNMP/Info/CiscoPortSecurity.pm version: '3.39' SNMP::Info::CiscoPower: file: lib/SNMP/Info/CiscoPower.pm version: '3.39' SNMP::Info::CiscoQOS: file: lib/SNMP/Info/CiscoQOS.pm version: '3.39' SNMP::Info::CiscoRTT: file: lib/SNMP/Info/CiscoRTT.pm version: '3.39' SNMP::Info::CiscoStack: file: lib/SNMP/Info/CiscoStack.pm version: '3.39' SNMP::Info::CiscoStats: file: lib/SNMP/Info/CiscoStats.pm version: '3.39' SNMP::Info::CiscoStpExtensions: file: lib/SNMP/Info/CiscoStpExtensions.pm version: '3.39' SNMP::Info::CiscoVTP: file: lib/SNMP/Info/CiscoVTP.pm version: '3.39' SNMP::Info::EDP: file: lib/SNMP/Info/EDP.pm version: '3.39' SNMP::Info::Entity: file: lib/SNMP/Info/Entity.pm version: '3.39' SNMP::Info::EtherLike: file: lib/SNMP/Info/EtherLike.pm version: '3.39' SNMP::Info::FDP: file: lib/SNMP/Info/FDP.pm version: '3.39' SNMP::Info::IEEE802dot11: file: lib/SNMP/Info/IEEE802dot11.pm version: '3.39' SNMP::Info::IEEE802dot3ad: file: lib/SNMP/Info/IEEE802dot3ad.pm version: '3.39' SNMP::Info::IPv6: file: lib/SNMP/Info/IPv6.pm version: '3.39' SNMP::Info::LLDP: file: lib/SNMP/Info/LLDP.pm version: '3.39' SNMP::Info::Layer1: file: lib/SNMP/Info/Layer1.pm version: '3.39' SNMP::Info::Layer1::Allied: file: lib/SNMP/Info/Layer1/Allied.pm version: '3.39' SNMP::Info::Layer1::Asante: file: lib/SNMP/Info/Layer1/Asante.pm version: '3.39' SNMP::Info::Layer1::Bayhub: file: lib/SNMP/Info/Layer1/Bayhub.pm version: '3.39' SNMP::Info::Layer1::Cyclades: file: lib/SNMP/Info/Layer1/Cyclades.pm version: '3.39' SNMP::Info::Layer1::S3000: file: lib/SNMP/Info/Layer1/S3000.pm version: '3.39' SNMP::Info::Layer2: file: lib/SNMP/Info/Layer2.pm version: '3.39' SNMP::Info::Layer2::3Com: file: lib/SNMP/Info/Layer2/3Com.pm version: '3.39' SNMP::Info::Layer2::Airespace: file: lib/SNMP/Info/Layer2/Airespace.pm version: '3.39' SNMP::Info::Layer2::Aironet: file: lib/SNMP/Info/Layer2/Aironet.pm version: '3.39' SNMP::Info::Layer2::Allied: file: lib/SNMP/Info/Layer2/Allied.pm version: '3.39' SNMP::Info::Layer2::Baystack: file: lib/SNMP/Info/Layer2/Baystack.pm version: '3.39' SNMP::Info::Layer2::C1900: file: lib/SNMP/Info/Layer2/C1900.pm version: '3.39' SNMP::Info::Layer2::C2900: file: lib/SNMP/Info/Layer2/C2900.pm version: '3.39' SNMP::Info::Layer2::Catalyst: file: lib/SNMP/Info/Layer2/Catalyst.pm version: '3.39' SNMP::Info::Layer2::Centillion: file: lib/SNMP/Info/Layer2/Centillion.pm version: '3.39' SNMP::Info::Layer2::Cisco: file: lib/SNMP/Info/Layer2/Cisco.pm version: '3.39' SNMP::Info::Layer2::CiscoSB: file: lib/SNMP/Info/Layer2/CiscoSB.pm version: '3.39' SNMP::Info::Layer2::HP: file: lib/SNMP/Info/Layer2/HP.pm version: '3.39' SNMP::Info::Layer2::HP4000: file: lib/SNMP/Info/Layer2/HP4000.pm version: '3.39' SNMP::Info::Layer2::HPVC: file: lib/SNMP/Info/Layer2/HPVC.pm version: '3.39' SNMP::Info::Layer2::Kentrox: file: lib/SNMP/Info/Layer2/Kentrox.pm version: '3.39' SNMP::Info::Layer2::N2270: file: lib/SNMP/Info/Layer2/N2270.pm version: '3.39' SNMP::Info::Layer2::NAP222x: file: lib/SNMP/Info/Layer2/NAP222x.pm version: '3.39' SNMP::Info::Layer2::NWSS2300: file: lib/SNMP/Info/Layer2/NWSS2300.pm version: '3.39' SNMP::Info::Layer2::Netgear: file: lib/SNMP/Info/Layer2/Netgear.pm version: '3.39' SNMP::Info::Layer2::Orinoco: file: lib/SNMP/Info/Layer2/Orinoco.pm version: '3.39' SNMP::Info::Layer2::Trapeze: file: lib/SNMP/Info/Layer2/Trapeze.pm version: '3.39' SNMP::Info::Layer2::Ubiquiti: file: lib/SNMP/Info/Layer2/Ubiquiti.pm version: '3.39' SNMP::Info::Layer2::ZyXEL_DSLAM: file: lib/SNMP/Info/Layer2/ZyXEL_DSLAM.pm version: '3.39' SNMP::Info::Layer3: file: lib/SNMP/Info/Layer3.pm version: '3.39' SNMP::Info::Layer3::Aironet: file: lib/SNMP/Info/Layer3/Aironet.pm version: '3.39' SNMP::Info::Layer3::AlcatelLucent: file: lib/SNMP/Info/Layer3/AlcatelLucent.pm version: '3.39' SNMP::Info::Layer3::AlteonAD: file: lib/SNMP/Info/Layer3/AlteonAD.pm version: '3.39' SNMP::Info::Layer3::Altiga: file: lib/SNMP/Info/Layer3/Altiga.pm version: '3.39' SNMP::Info::Layer3::Arista: file: lib/SNMP/Info/Layer3/Arista.pm version: '3.39' SNMP::Info::Layer3::Aruba: file: lib/SNMP/Info/Layer3/Aruba.pm version: '3.39' SNMP::Info::Layer3::BayRS: file: lib/SNMP/Info/Layer3/BayRS.pm version: '3.39' SNMP::Info::Layer3::BlueCoatSG: file: lib/SNMP/Info/Layer3/BlueCoatSG.pm version: '3.39' SNMP::Info::Layer3::C3550: file: lib/SNMP/Info/Layer3/C3550.pm version: '3.39' SNMP::Info::Layer3::C4000: file: lib/SNMP/Info/Layer3/C4000.pm version: '3.39' SNMP::Info::Layer3::C6500: file: lib/SNMP/Info/Layer3/C6500.pm version: '3.39' SNMP::Info::Layer3::Cisco: file: lib/SNMP/Info/Layer3/Cisco.pm version: '3.39' SNMP::Info::Layer3::CiscoASA: file: lib/SNMP/Info/Layer3/CiscoASA.pm version: '3.39' SNMP::Info::Layer3::CiscoFWSM: file: lib/SNMP/Info/Layer3/CiscoFWSM.pm version: '3.39' SNMP::Info::Layer3::CiscoSwitch: file: lib/SNMP/Info/Layer3/CiscoSwitch.pm version: '3.39' SNMP::Info::Layer3::Contivity: file: lib/SNMP/Info/Layer3/Contivity.pm version: '3.39' SNMP::Info::Layer3::DLink: file: lib/SNMP/Info/Layer3/DLink.pm version: '3.39' SNMP::Info::Layer3::Dell: file: lib/SNMP/Info/Layer3/Dell.pm version: '3.39' SNMP::Info::Layer3::Enterasys: file: lib/SNMP/Info/Layer3/Enterasys.pm version: '3.39' SNMP::Info::Layer3::Extreme: file: lib/SNMP/Info/Layer3/Extreme.pm version: '3.39' SNMP::Info::Layer3::F5: file: lib/SNMP/Info/Layer3/F5.pm version: '3.39' SNMP::Info::Layer3::Force10: file: lib/SNMP/Info/Layer3/Force10.pm version: '3.39' SNMP::Info::Layer3::Fortinet: file: lib/SNMP/Info/Layer3/Fortinet.pm version: '3.39' SNMP::Info::Layer3::Foundry: file: lib/SNMP/Info/Layer3/Foundry.pm version: '3.39' SNMP::Info::Layer3::H3C: file: lib/SNMP/Info/Layer3/H3C.pm version: '3.39' SNMP::Info::Layer3::HP9300: file: lib/SNMP/Info/Layer3/HP9300.pm version: '3.39' SNMP::Info::Layer3::Huawei: file: lib/SNMP/Info/Layer3/Huawei.pm version: '3.39' SNMP::Info::Layer3::IBMGbTor: file: lib/SNMP/Info/Layer3/IBMGbTor.pm version: '3.39' SNMP::Info::Layer3::Juniper: file: lib/SNMP/Info/Layer3/Juniper.pm version: '3.39' SNMP::Info::Layer3::Lantronix: file: lib/SNMP/Info/Layer3/Lantronix.pm version: '3.39' SNMP::Info::Layer3::Microsoft: file: lib/SNMP/Info/Layer3/Microsoft.pm version: '3.39' SNMP::Info::Layer3::Mikrotik: file: lib/SNMP/Info/Layer3/Mikrotik.pm version: '3.39' SNMP::Info::Layer3::N1600: file: lib/SNMP/Info/Layer3/N1600.pm version: '3.39' SNMP::Info::Layer3::NetSNMP: file: lib/SNMP/Info/Layer3/NetSNMP.pm version: '3.39' SNMP::Info::Layer3::Netscreen: file: lib/SNMP/Info/Layer3/Netscreen.pm version: '3.39' SNMP::Info::Layer3::Nexus: file: lib/SNMP/Info/Layer3/Nexus.pm version: '3.39' SNMP::Info::Layer3::PacketFront: file: lib/SNMP/Info/Layer3/PacketFront.pm version: '3.39' SNMP::Info::Layer3::PaloAlto: file: lib/SNMP/Info/Layer3/PaloAlto.pm version: '3.39' SNMP::Info::Layer3::Passport: file: lib/SNMP/Info/Layer3/Passport.pm version: '3.39' SNMP::Info::Layer3::Pf: file: lib/SNMP/Info/Layer3/Pf.pm version: '3.39' SNMP::Info::Layer3::Pica8: file: lib/SNMP/Info/Layer3/Pica8.pm version: '3.39' SNMP::Info::Layer3::SonicWALL: file: lib/SNMP/Info/Layer3/SonicWALL.pm version: '3.39' SNMP::Info::Layer3::Steelhead: file: lib/SNMP/Info/Layer3/Steelhead.pm version: '3.39' SNMP::Info::Layer3::Sun: file: lib/SNMP/Info/Layer3/Sun.pm version: '3.39' SNMP::Info::Layer3::Tasman: file: lib/SNMP/Info/Layer3/Tasman.pm version: '3.39' SNMP::Info::Layer3::Timetra: file: lib/SNMP/Info/Layer3/Timetra.pm version: '3.39' SNMP::Info::Layer3::VMware: file: lib/SNMP/Info/Layer3/VMware.pm version: '3.39' SNMP::Info::Layer7: file: lib/SNMP/Info/Layer7.pm version: '3.39' SNMP::Info::Layer7::APC: file: lib/SNMP/Info/Layer7/APC.pm version: '3.39' SNMP::Info::Layer7::CiscoIPS: file: lib/SNMP/Info/Layer7/CiscoIPS.pm version: '3.39' SNMP::Info::Layer7::Neoteris: file: lib/SNMP/Info/Layer7/Neoteris.pm version: '3.39' SNMP::Info::Layer7::Netscaler: file: lib/SNMP/Info/Layer7/Netscaler.pm version: '3.39' SNMP::Info::MAU: file: lib/SNMP/Info/MAU.pm version: '3.39' SNMP::Info::MRO: file: lib/SNMP/Info/MRO.pm version: '3.39' SNMP::Info::NortelStack: file: lib/SNMP/Info/NortelStack.pm version: '3.39' SNMP::Info::PowerEthernet: file: lib/SNMP/Info/PowerEthernet.pm version: '3.39' SNMP::Info::RapidCity: file: lib/SNMP/Info/RapidCity.pm version: '3.39' SNMP::Info::SONMP: file: lib/SNMP/Info/SONMP.pm version: '3.39' requires: Math::BigInt: '0' SNMP: '0' resources: IRC: irc://irc.freenode.org/#netdisco MailingList: https://lists.sourceforge.net/lists/listinfo/snmp-info-users bugtracker: https://github.com/netdisco/snmp-info/issues homepage: http://netdisco.org/ license: http://opensource.org/licenses/BSD-3-Clause repository: https://github.com/netdisco/snmp-info version: '3.39' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' SNMP-Info-3.39/contrib000755000765000024 013215550564 14350 5ustar00oliverstaff000000000000SNMP-Info-3.39/contrib/DEVELOP000444000765000024 256313215550564 15534 0ustar00oliverstaff000000000000SNMP::Info Developer Guidelines Coding Guidelines: - tab-width of 4, no tab characters - keep POD documentation up-to-date - always update ChangeLog before committing - check-in required mibs to netdisco-mibs and release new package if needed Release and Testing Instructions: - Please see misc/RELEASE in Netdisco ( http://netdisco.cvs.sourceforge.net/viewvc/netdisco/misc/RELEASE?view=markup ) and follow all testing and release guidelines FAQ: - Do I have to update the version number and timestamp in modified files before committing? -> No. These are RCS tags that are automatically updated by CVS when you commit - Should I add changes at the top of the ChangeLog? -> Yes. The changelog is created one commit at a time. If there isn't a section for the current version, then add one at the top and put your changes after. You can leave the date field for the release empty (). - What should I change the $VERSION to? -> If you are the first person to get to a file after a release, update it to either release++ or "release++ dash cvs". Example: File is marked 2.01, change it to 2.02-cvs with your new changes. Example: File is marked 2.02-cvs, no change until packaging for release when the -cvs is removed. TODO: Is there still an odd/even scheme as introduced by Eric? SNMP-Info-3.39/contrib/util000755000765000024 013215550564 15325 5ustar00oliverstaff000000000000SNMP-Info-3.39/contrib/util/docmunge000555000765000024 154013215550564 17211 0ustar00oliverstaff000000000000#!/usr/bin/perl -i.bak # # [Re-]write POD to create cross-links between Required MIBs, GLOBALS # and TABLE METHODS sections. # This is a horrible jumble of heuristics, but works with # all of the existing files. It has only one false positive: HP.pm's # mention of an SNMP::Info version number. # $section = undef; $waiting = 0; while (<>) { if (eof) { $section = undef; $waiting = 0; } if (/^=head(\d)/) { $sl = $1; if ($sl <= $level) { $section = undef; } if (/(TABLE METHODS|GLOBALS|Required MIBs)/) { $section = $1; $level = $sl; if ($section eq 'TABLE METHODS' || $section eq 'GLOBALS') { $waiting = 1; } } if ($waiting && /imported/i) { $waiting = 0; } } elsif (defined($section) && !$waiting && /^[^=]/ && /SNMP::Info/) { s,(?:L<)?(SNMP::Info[a-zA-Z0-9:]*)(?:/[^>]+)?(?:>)?,L<$1/"$section">,g; } print; } SNMP-Info-3.39/contrib/util/make_dev_matrix.pl000555000765000024 2361613215550564 21211 0ustar00oliverstaff000000000000#!/usr/bin/perl -w # $Id$ $DevMatrix = '../DeviceMatrix.txt'; $DevHTML = 'DeviceMatrix.html'; $DevPNG = 'DeviceMatrix.png'; $Attributes= {}; # Parse Data File $matrix = parse_data($DevMatrix); # Graph it for fun eval "use GraphViz::Data::Structure;"; if ($@) { print "GraphViz::Data::Structure not installed. $@\n"; } else { my %graph = (); foreach my $vendor (sort sort_nocase keys %$matrix){ $graph{$vendor} = {}; foreach my $family (sort sort_nocase keys %{$matrix->{$vendor}->{families}} ){ my @models; foreach my $mod (keys %{$matrix->{$vendor}->{families}->{$family}->{models}}){ push(@models,split(/\s*,\s*/,$mod)); } if (scalar @models){ $graph{$vendor}->{$family}=\@models; } else { $graph{$vendor}->{$family}=[]; } } } my $now = scalar localtime; my $gvds = GraphViz::Data::Structure->new(\%graph,Orientation=>'vertical', Colors=> 'Deep', graph => {label=>"SNMP::Info and Netdisco Supported Devices \n $now",'fontpath'=>'/usr/local/netdisco','fontname'=>'lucon',concentrate=>'true','overlap'=>'false',spline=>'true',bgcolor=>'wheat'}, node => {fontname=>'lucon'}, ); $gvds->graph()->as_png($DevPNG); } print "Creating $DevHTML\n"; open (HTML, "> $DevHTML") or die "Can't open $DevHTML. $!\n"; $old_fh = select(HTML); &html_head; print_vendors($matrix); foreach my $vendor (sort sort_nocase keys %$matrix){ print "$vendor\n"; print "
\n"; my $vendor_defaults = $matrix->{$vendor}->{defaults}; print_notes($vendor_defaults,1); my $families = $matrix->{$vendor}->{families}; foreach my $family (sort sort_nocase keys %$families ) { print "
$family Family\n"; my $family_defaults = $families->{$family}->{defaults}; print_notes($family_defaults,2); my $models = $families->{$family}->{models}; foreach my $model (sort sort_nocase keys %$models ){ my $model_defaults = $models->{$model}->{defaults}; print "
$model\n"; print "
\n"; print_notes($model_defaults,3); print "
\n"; print_headers(); print "\n"; foreach my $a (sort sort_nocase keys %$Attributes) { my $val; next if $a eq 'note'; $val = ['-']; $class = 'none'; if (defined $model_defaults->{$a}) { $val = $model_defaults->{$a}; $class = 'model'; } elsif (defined $family_defaults->{$a}){ $val = $family_defaults->{$a}; $class = 'family'; } elsif (defined $vendor_defaults->{$a}){ $val = $vendor_defaults->{$a}; $class = 'vendor'; } print " \n"; } print "
",join("
\n",@$val),"
\n"; print "
\n"; } } print "
\n"; } &html_tail; select ($old_fh); close (HTML) or die "Can't write $DevHTML. $!\n"; # Data Structures # Matrix = # ( vendor => { families => { family => family_hash }, # defaults => { cmd => [values] }, # } # ) # Family Hash # ( models => { model => model_hash }, # defaults => { cmd => [values] } # ) # Model Hash # ( defaults => { cmd => [values] } ) sub parse_data { my $file = shift; my %ignore = map { $_ => 1 } @_; my $Matrix; my @Lines; open (DM, "< $file") or die "Can't open $file. $!\n"; { @Lines = ; } close (DM); my ($device,$family,$vendor,$class); foreach my $line (@Lines){ chomp($line); # Comments $line =~ s/#.*//; # Blank Lines next if $line =~ /^\s*$/; # Trim whitespace $line =~ s/^\s+//; $line =~ s/\s+$//; my ($cmd,$value); if ($line =~ /^([a-z-_]+)\s*:\s*(.*)$/) { $cmd = $1; $value = $2; } else { print "What do i do with this line : $line \n"; next; } if (exists $ignore{$cmd}){ print "Ignoring $cmd\n"; } # Set Class {vendor,family,device} if ($cmd eq 'device-vendor'){ $vendor = $value; $family = $model = undef; $Matrix->{$vendor} = {} unless defined $Matrix->{$vendor}; $class = $Matrix->{$vendor}; $class->{defaults}->{type}='vendor'; next; } if ($cmd eq 'device-family'){ $family = $value; $model = undef; print "$family has no vendor.\n" unless defined $vendor; $Matrix->{$vendor}->{families}->{$family} = {} unless defined $Matrix->{$vendor}->{families}->{$family}; $class = $Matrix->{$vendor}->{families}->{$family}; $class->{defaults}->{type}='family'; next; } if ($cmd eq 'device') { $model = $value; print "$model has no family.\n" unless defined $family; print "$model has no vendor.\n" unless defined $vendor; $Matrix->{$vendor}->{families}->{$family}->{models}->{$model} = {} unless defined $Matrix->{$vendor}->{families}->{$family}->{models}->{$model}; $class = $Matrix->{$vendor}->{families}->{$family}->{models}->{$model}; $class->{defaults}->{type}='device'; next; } # Store attribute push (@{$class->{defaults}->{$cmd}} , $value); $Attributes->{$cmd}++; } return $Matrix; } sub sort_nocase { return lc($a) cmp lc($b); } sub print_notes { my $defaults = shift; my $level = shift; my $notes = $defaults->{note} || []; foreach my $note (@$notes){ if ($note =~ s/^!//){ $note = '' . $note . ''; } } if (scalar @$notes){ print "
\n"; my $print_note = join("\n
  • ",@$notes); print "
    • $print_note
    \n"; } } sub print_vendors { my $matrix=shift; print "

    Device Vendors

    \n"; foreach my $vendor (sort sort_nocase keys %$matrix){ print "[$vendor]\n"; } print "
    \n"; } sub html_head { print <<"end_head"; SNMP::Info - Device Compatibility Matrix

    SNMP::Info - Device Compatibility Matrix

    end_head } sub html_tail { print <<'end_tail';


    Color Key

    [Model Attribute] [Family Attribute] [Vendor Attribute]

    Attribute Key

    A value of - signifies the information is not specified and can not be assumed working.
    Arpnip Ability to collect ARP tables for MAC to IP translation.
    Class SNMP::Info Class the the device currently uses. Devices using more generic interfaces like Layer2 or Layer3 may eventually get their own subclass.
    Duplex Ability to cull duplex settings from device.
    • no - Can't recover current or admin setting.
    • link - Can get current setting only.
    • both - Can get admin and link setting.
    • write - Can get admin and link setting and perform sets.
    Macsuck Ability to get CAM tables for MAC to switch port mapping.
    • no - Have not found an SNMP method to get data yet.
    • yes - Can get through normal SWITCH-MIB method.
    • vlan - Have to re-connect to each VLAN and then fetch with normal method.
    Modules Ability to gather hardware module information.
    Portmac Whether the device will list the MAC address of the switch port on each switch port when doing a Macsuck.
    Topo Ability to get Layer 2 Topology Information from device if the protocol is enabled. SNMP::Info supports querying Link Layer Discovery Protocol (LLDP), Cisco Discovery Protocol (CDP), SynOptics/Bay/Nortel/Avaya Network Management Protocol (SONMP), Foundry/Brocade Discovery Protocol (FDP), Extreme Discovery Protocol (EDP), and Alcatel Mapping Adjacency Protocol (AMAP).
    Ver SNMP Protocol Version the device has to use.
    Vlan Ability to get VLAN port assignments.
    • no - Have not found an SNMP method to get data yet.
    • yes - Can read information.
    • write - Can read and write (set).
    end_tail } sub print_headers { print "\n"; foreach my $a (sort sort_nocase keys %$Attributes) { next if $a eq 'note'; print " $a\n"; } print "\n"; } SNMP-Info-3.39/contrib/util/make_snmpdata.pl000555000765000024 1260013215550564 20645 0ustar00oliverstaff000000000000#!/usr/bin/perl # # make_snmpdata.pl # # Copyright (c) 2012 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. use strict; use warnings; use Carp; use Getopt::Long; use Pod::Usage; use SNMP; local $| = 1; my $mibdirs = ['/usr/local/share/snmp/mibs']; my $comm = 'public'; my $ver = '2c'; my $dev; my $ignore = 0; my $help = 0; GetOptions( 'community=s' => \$comm, 'device=s' => \$dev, 'ignore' => \$ignore, 'mibdir=s' => \$mibdirs, 'version' => \$ver, 'help|?' => sub { pod2usage(2); }, ) or pod2usage(2); unless ( defined $dev && $ver =~ /[1|2c]/ ) { pod2usage(1); } local $ENV{'SNMPCONFPATH'} = '' if $ignore; local $ENV{'MIBDIRS'} = "$mibdirs" if $ignore; SNMP::addMibDirs($mibdirs); # Connect to Device my $sess = SNMP::Session->new( 'UseEnums' => 1, 'RetryNoSuch' => 1, 'DestHost' => $dev, 'Community' => $comm, 'Version' => $ver, 'UseSprintValue' => 1 ); my $sysdescr = $sess->get('sysDescr.0'); unless ( defined $sysdescr ) { die "Couldn't connect to $dev via snmp.\n"; } SNMP::loadModules(@ARGV); # Create a hash of MIB Modules for which we want results my %mib_hash = map {$_ => 1} @ARGV; # Add the common MIB Modules we always want my @common_mibs = ('SNMPv2-MIB', 'IF-MIB'); foreach my $mib (@common_mibs) { $mib_hash{$mib} = 1; } foreach my $key ( sort( keys %SNMP::MIB ) ) { my $module = $SNMP::MIB{$key}{moduleID} || ''; # IMPORTS pulls in many modules we don't want to walk # Only walk those we've specified next unless (defined $mib_hash{$module}); my $access = $SNMP::MIB{$key}{'access'} || ''; next unless ( $access =~ /Read|Create/x ); my $label = SNMP::translateObj( $key, 0, 1 ) || ''; snmpwalk($label); } sub snmpwalk { return unless defined $sess; my $label = shift; my $var = SNMP::Varbind->new( [$label] ); my $e = 0; my $last_iid = ''; my %seen = (); while ( !$e ) { $sess->getnext($var); $e = $sess->{ErrorNum}; return if $var->[0] ne $label; my $iid = $var->[1]; my $val = $var->[2]; return unless defined $iid; # Check to see if we've already seen this IID (looping) if ( defined $seen{$iid} and $seen{$iid} ) { warn "Looping on $label iid:$iid. Skipped.\n"; return; } else { $seen{$iid}++; } # why is it looping? return if $last_iid eq $iid; $last_iid = $iid; my $line = "$label.$iid = $val"; print "$line\n"; } return; } __END__ =head1 NAME make_snmpdata.pl - Tool to get SNMP data for the SNMP::Info testing framework =head1 AUTHOR Eric Miller =head1 SYNOPSIS make_snmpdata.pl [options] MIB-MODULE-1 MIB-MODULE-2 Options: -community SNMP Community -device IP Address to query -ignore Ignore Net-SNMP configuration file -mibdir Directory containing MIB Files -version SNMP version to use -help Brief help message =head1 OPTIONS =over 8 =item B<-community> SNMP Community, either 1 or 2c. Defaults to version 2c -community 2c =item B<-device> IP Address to query for the SNMP data. No default and a mandatory option. -device 127.0.0.1 =item B<-ignore > Ignore Net-SNMP configuration file snmp.conf. If this used mibdirs must be provided -ignore =item B<-mibdir> Directory containing MIB Files. Mutiple directories should be separated by a colon ':'. Defaults to /usr/local/share/snmp/mibs. -mibdir /usr/local/share/snmp/mibs/rfc:/usr/local/share/snmp/mibs/net-snmp =item B<-version> SNMP version to use. Only version 1 and 2c are supported. Defaults to 2c -version 2c =item B<-help> Print help message and exits. =back =head1 DESCRIPTION B will gather SNMP data by walking specified MIB files and output the data to a file which can be used by the SNMP::Info testing framework. =cut SNMP-Info-3.39/contrib/util/push_ver000555000765000024 160413215550564 17244 0ustar00oliverstaff000000000000#!/usr/bin/perl -w # $Id$ use File::Glob qw/bsd_glob/; my @pms = glob_rec("../../lib"); $new_version = shift @ARGV || die "missing new version\n"; foreach my $p (@pms) { print "$p\n"; rename($p,"$p.orig"); open (O,"<$p.orig") or die; open (P,">$p") or die "Can't open $p for write. $!\n"; while () { s/^\s*\$VERSION\s+=\s*'[^']+'\s*;/\$VERSION = '$new_version';/; s/^SNMP::Info - Version [\d.]+$/SNMP::Info - Version $new_version/; print P; } close O; close P or die "Can't write $p. $!\n"; unlink("$p.orig"); #last; } sub glob_rec { my $dir = shift; my @files = bsd_glob("$dir/*"); my @pms; foreach my $f (@files) { next if $f eq '\.$'; if (-d $f) { push @pms, glob_rec($f); next; } push @pms,$f if $f =~ /.pm$/; } return @pms; } SNMP-Info-3.39/contrib/util/run_test000555000765000024 20213215550564 17225 0ustar00oliverstaff000000000000#!/bin/sh # Run this from ../ /usr/local/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/$1 SNMP-Info-3.39/contrib/util/test_class.pl000555000765000024 1760113215550564 20213 0ustar00oliverstaff000000000000#!/usr/bin/perl # # test_class.pl # # Copyright (c) 2013 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. use strict; use warnings; use Carp; use Getopt::Long; use Pod::Usage; use SNMP::Info; my $EMPTY = q{}; # Default Values my $class = $EMPTY; my @dump = (); my $debug = 0; my $cache = 0; my $device = ''; my $comm = ''; my $ver = 2; my $ignore = 0; my $help = 0; my $nobulk = 0; my $mibdirs; my %dumped; GetOptions( 'c|class=s' => \$class, 'd|dev=s' => \$device, 's|comm=s' => \$comm, 'v|ver=i' => \$ver, 'i|ignore' => \$ignore, 'p|print=s' => \@dump, 'm|mibdir=s' => \$mibdirs, 'n|nobulk' => \$nobulk, 'x|debug+' => \$debug, 'k|cache' => \$cache, 'h|?|help' => sub { pod2usage(1); }, ); unless ( $device and $comm ) { pod2usage(2); } if ( $ignore && !defined $mibdirs ) { print "mibdirs must be provided if ignoring snmp.conf \n\n"; pod2usage(1); } local $ENV{'SNMPCONFPATH'} = $EMPTY if $ignore; local $ENV{'MIBDIRS'} = "$mibdirs" if $ignore; if ( defined $mibdirs ) { SNMP::addMibDirs($mibdirs); } $class = $class ? "SNMP::Info::$class" : 'SNMP::Info'; ( my $mod = "$class.pm" ) =~ s{::}{/}xg; # SNMP::Info::Layer3 => SNMP/Info/Layer3.pm if ( !eval { require $mod; 1; } ) { croak "Could not load $class. Error Message: $@\n"; } my $class_ver = $class->VERSION(); print "Class $class ($class_ver) loaded from SNMP::Info $SNMP::Info::VERSION.\n"; if ( scalar @dump ) { print 'Dumping : ', join( q{,}, @dump ), "\n" } my %args = (); if ($nobulk) { $args{BulkWalk} = 0; } my $dev = $class->new( 'AutoSpecify' => 0, 'AutoVerBack' => 0, 'Debug' => $debug, 'Version' => $ver, 'DestHost' => $device, 'Community' => $comm, %args ) or die "\n"; print "Connected to $device.\n"; print 'Detected Class: ', $dev->device_type(), "\n"; print "Using Class: $class (-c to change)\n"; my $layers = $dev->layers(); my $descr = $dev->description(); if ( !defined $layers || !defined $descr ) { die "Are you sure you got the right community string and version?\nCan't fetch layers or description.\n"; } print "\nFetching base info...\n\n"; my @base_fns = qw/vendor model os os_ver description contact location layers mac serial/; foreach my $fn (@base_fns) { test_global( $dev, $fn ); } print "\nFetching interface info...\n\n"; my @fns = qw/interfaces i_type i_ignore i_description i_mtu i_speed i_mac i_up i_up_admin i_name i_duplex i_duplex_admin i_stp_state i_vlan i_pvid i_lastchange/; foreach my $fn (@fns) { test_fn( $dev, $fn ); } print "\nFetching VLAN info...\n\n"; my @vlan = qw/v_index v_name/; foreach my $fn (@vlan) { test_fn( $dev, $fn ); } print "\nFetching topology info...\n\n"; my @topo = qw/c_if c_ip c_port c_id c_platform/; foreach my $fn (@topo) { test_fn( $dev, $fn ); } print "\nFetching module info...\n\n"; my @modules = qw/e_descr e_type e_parent e_name e_class e_pos e_hwver e_fwver e_swver e_model e_serial e_fru/; foreach my $fn (@modules) { test_fn( $dev, $fn ); } foreach my $fn (@dump) { if ( !$dumped{$fn} ) { test_fn( $dev, $fn ) } } if ($cache) { eval { require Data::Printer; } && eval { print "\nDumping cache...\n\n"; Data::Printer::p $dev; }; } #-------------------------------- sub test_global { my $info = shift; my $method = shift; my $value = $info->$method(); if ( !defined $value ) { printf "%-20s Does not exist.\n", $method; return 0; } $value =~ s/[[:cntrl:]]+/ /gx; if ( length $value > 60 ) { $value = substr $value, 0, 60; $value .= '...'; } printf "%-20s %s \n", $method, $value; return 1; } sub test_fn { my $info = shift; my $method = shift; my $results = $info->$method(); # If accidentally called on a global, pass it along nicely. if ( defined $results && !ref $results ) { return test_global( $dev, $method ); } if ( !defined $results && !scalar keys %{$results} ) { printf "%-20s Empty Results.\n", $method; return 0; } printf "%-20s %d rows.\n", $method, scalar keys %{$results}; if ( grep {/^$method$/x} @dump ) { $dumped{$method} = 1; foreach my $iid ( keys %{$results} ) { print " $iid : "; if ( ref( $results->{$iid} ) eq 'ARRAY' ) { print '[ ', join( ', ', @{ $results->{$iid} } ), ' ]'; } else { print $results->{$iid}; } print "\n"; } } return 1; } __END__ =head1 NAME test_class.pl - Test a device against an SNMP::Info class. =head1 AUTHOR Eric Miller =head1 SYNOPSIS test_class.pl [options] Options: -c|class SNMP::Info class to use, Layer2::Catalyst -d|dev Device -s|comm SNMP community -v|ver SNMP version -p|print Print values -i|ignore Ignore Net-SNMP configuration file -m|mibdir Directory containing MIB Files -n|nobulk Disable bulkwalk -x|debug Debugging flag -k|cache Dump cache (requires Data::Printer to be installed) -h|?|help Brief help message =head1 OPTIONS =over 8 =item B<-class> Specific SNMP::Info class to use. Defaults to SNMP::Info if no specific class provided. -class Layer2::Catalyst =item B<-dev> Device to test against. No default and a mandatory option. -dev 1.2.3.4 =item B<-comm> SNMP community string. No default and a mandatory option. -comm public =item B<-ver> SNMP version. Default 2. -ver 1 =item B<-print> Print values of a class method rather than summarizing. May be repeated multiple times. -print i_description -print i_type =item B<-ignore > Ignore Net-SNMP configuration file snmp.conf. If this used mibdirs must be provided. -ignore =item B<-mibdir> Directory containing MIB Files. Multiple directories should be separated by a colon ':'. -mibdir /usr/local/share/snmp/mibs/rfc:/usr/local/share/snmp/mibs/net-snmp =item B<-nobulk > Disable SNMP bulkwalk. Default bulkwalk is on and utilized with version 2. -nobulk =item B<-debug> Turns on SNMP::Info debug. -debug =item B<-cache> Dumps the table and leaf cache at the end of running. Requires that the L module be installed, otherwise does nothing. -cache =item B<-help> Print help message and exits. =back =head1 DESCRIPTION B will test a device against a specfied SNMP::Info class. This allows debugging and testing of live devices to include validating device support with existing classes. =cut SNMP-Info-3.39/contrib/util/test_class_mocked.pl000555000765000024 2455513215550564 21543 0ustar00oliverstaff000000000000#!/usr/bin/perl # # test_class_mocked.pl # # Copyright (c) 2012 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. use strict; use warnings; use Carp; use FindBin; use lib "$FindBin::Bin/../../.."; use File::Slurp qw(slurp); use Getopt::Long; use Pod::Usage; use SNMP::Info; use Test::MockObject::Extends; my $EMPTY = q{}; # Default Values my $class = $EMPTY; my @dump = (); my $debug = 0; my $mibdirs; my $ignore = 0; my $help = 0; my $file; my %dumped; GetOptions( 'c|class=s' => \$class, 'i|ignore' => \$ignore, 'p|print=s' => \@dump, 'x|debug+' => \$debug, 'm|mibdir=s' => \$mibdirs, 'file=s' => \$file, 'h|?|help' => sub { pod2usage(1); }, ); if ( !$file ) { pod2usage(1); } if ( $ignore && !defined $mibdirs ) { print "mibdirs must be provided if ignoring snmp.conf \n\n"; pod2usage(1); } local $ENV{'SNMPCONFPATH'} = $EMPTY if $ignore; local $ENV{'MIBDIRS'} = "$mibdirs" if $ignore; if ( defined $mibdirs ) { SNMP::addMibDirs($mibdirs); } $class = $class ? "SNMP::Info::$class" : 'SNMP::Info'; ( my $mod = "$class.pm" ) =~ s{::}{/}g; # SNMP::Info::Layer3 => SNMP/Info/Layer3.pm if ( !eval { require $mod; 1; } ) { croak "Could not load $class. Error Message: $@\n"; } my $class_ver = $class->VERSION(); print "Class $class ($class_ver) loaded from SNMP::Info $SNMP::Info::VERSION.\n"; if ( scalar @dump ) { print 'Dumping : ', join( q{,}, @dump ), "\n" } my $mocked = create_mock_session(); my $dev = $class->new( 'AutoSpecify' => 0, 'BulkWalk' => 0, 'Debug' => $debug, 'Session' => $mocked, ) or die "\n"; print 'Detected Class: ', $dev->device_type(), "\n"; print "Using Class: $class (-c to change)\n"; my $layers = $dev->layers(); my $descr = $dev->description(); if ( !defined $layers || !defined $descr ) { die "Are you sure you specified a file created with make_snmpdata.pl ?\n"; } print "\nFetching base info...\n\n"; my @base_fns = qw/vendor model os os_ver description contact location layers mac serial/; foreach my $fn (@base_fns) { test_global( $dev, $fn ); } print "\nFetching interface info...\n\n"; my @fns = qw/interfaces i_type i_ignore i_description i_mtu i_speed i_mac i_up i_up_admin i_name i_duplex i_duplex_admin i_stp_state i_vlan i_pvid i_lastchange/; foreach my $fn (@fns) { test_fn( $dev, $fn ); } print "\nFetching VLAN info...\n\n"; my @vlan = qw/v_index v_name/; foreach my $fn (@vlan) { test_fn( $dev, $fn ); } print "\nFetching topology info...\n\n"; my @topo = qw/c_if c_ip c_port c_id c_platform/; foreach my $fn (@topo) { test_fn( $dev, $fn ); } print "\nFetching module info...\n\n"; my @modules = qw/e_descr e_type e_parent e_name e_class e_pos e_hwver e_fwver e_swver e_model e_serial e_fru/; foreach my $fn (@modules) { test_fn( $dev, $fn ); } foreach my $fn (@dump) { if ( !$dumped{$fn} ) { test_fn( $dev, $fn ) } } #-------------------------------- sub load_snmpdata { my $data_file = shift; my @lines = slurp($data_file); my $snmp_data = {}; foreach my $line (@lines) { next if !$line; next if ( $line =~ /^#/ ); if ( $line =~ /^(\S+::\w+)[.]?(\S+)*\s=\s(.*)$/ ) { my ( $leaf, $iid, $val ) = ( $1, $2, $3 ); next if !$leaf; $iid ||= 0; $val =~ s/\"//g; $snmp_data->{$leaf}->{$iid} = $val; } } return $snmp_data; } sub create_mock_session { my $snmp_data = load_snmpdata($file); my $session = SNMP::Session->new( UseEnums => 1, RetryNoSuch => 1, Data => $snmp_data, DestHost => '127.0.0.1', Community => 'public', Version => 2, ); my $mock_session = Test::MockObject::Extends->new($session); mock_get($mock_session); mock_getnext($mock_session); return $mock_session; } sub mock_get { my $mock_session = shift; $mock_session->mock( 'get', sub { my $self = shift; my $vars = shift; my ( $leaf, $iid, $oid, $oid_name ); my $c_data = $self->{Data}; # From SNMP::Info get will only be passed either an OID or # SNMP::Varbind with a fully qualified leaf and potentially # a partial if ( ref($vars) =~ /SNMP::Varbind/ ) { ( $leaf, $iid ) = @{$vars}; } else { $oid = $vars; $oid_name = SNMP::translateObj( $oid, 0, 1 ) || $EMPTY; ( $leaf, $iid ) = $oid_name =~ /^(\S+::\w+)[.]?(\S+)*$/; } $iid ||= 0; my $new_iid = $iid; my $val = $EMPTY; my $data = $c_data->{$leaf} || {}; my $count = scalar keys %{$data} || 0; if ( $count > 1 ) { my $found = 0; foreach my $d_iid ( sort keys %{$data} ) { if ( $d_iid eq $iid ) { $val = $data->{$d_iid}; $found = 1; next; } elsif ( $found == 1 ) { $new_iid = $d_iid; last; } } if ( $found && ( $new_iid eq $iid ) ) { $leaf = 'unknown'; } } else { $val = $data->{$iid}; $leaf = 'unknown'; } if ( ref $vars =~ /SNMP::Varbind/ ) { $vars->[0] = $leaf; $vars->[1] = $new_iid; $vars->[2] = $val; } return ( wantarray() ? $vars : $val ); } ); return; } sub mock_getnext { my $mock_session = shift; $mock_session->mock( 'getnext', sub { my $self = shift; my $vars = shift; my ( $leaf, $iid, $oid, $oid_name ); my $c_data = $self->{Data}; # From SNMP::Info getnext will only be passed a SNMP::Varbind # with a fully qualified leaf and potentially a partial ( $leaf, $iid ) = @{$vars}; unless (defined $iid) { $iid = -1; } my $new_iid = $iid; my $val = $EMPTY; my $data = $c_data->{$leaf}; my $count = scalar keys %{$data} || 0; if ( $count ) { my $found = 0; foreach my $d_iid ( sort keys %{$data} ) { if ( $d_iid gt $iid && !$found ) { $val = $data->{$d_iid}; $new_iid = $d_iid; $found = 1; next; } elsif ( $found == 1 ) { last; } } if ( $found && ( $new_iid eq $iid ) ) { $leaf = 'unknown'; } } else { $val = $data->{$iid}; $leaf = 'unknown'; } $vars->[0] = $leaf; $vars->[1] = $new_iid; $vars->[2] = $val; return ( wantarray() ? $vars : $val ); } ); return; } sub test_global { my $device = shift; my $method = shift; my $value = $device->$method(); if ( !defined $value ) { printf "%-20s Does not exist.\n", $method; return 0; } $value =~ s/[[:cntrl:]]+/ /g; if ( length $value > 60 ) { $value = substr $value, 0, 60; $value .= '...'; } printf "%-20s %s \n", $method, $value; return 1; } sub test_fn { my $device = shift; my $method = shift; my $results = $device->$method(); # If accidentally called on a global, pass it along nicely. if ( defined $results && !ref $results ) { return test_global( $dev, $method ); } if ( !defined $results && !scalar keys %{$results} ) { printf "%-20s Empty Results.\n", $method; return 0; } printf "%-20s %d rows.\n", $method, scalar keys %{$results}; if ( grep {/^$method$/} @dump ) { $dumped{$method} = 1; foreach my $iid ( keys %{$results} ) { print " $iid : "; if ( ref( $results->{$iid} ) eq 'ARRAY' ) { print '[ ', join( ', ', @{ $results->{$iid} } ), ' ]'; } else { print $results->{$iid}; } print "\n"; } } return 1; } __END__ =head1 NAME test_class_mocked.pl - Test a device against an SNMP::Info class using output from make_snmpdata.pl stored in a text file. =head1 AUTHOR Eric Miller =head1 SYNOPSIS test_class_mocked.pl [options] Options: -class SNMP::Info class to use, Layer2::Catalyst -file File containing data gathered using make_snmpdata.pl -print Print values -debug Debugging flag -ignore Ignore Net-SNMP configuration file -mibdir Directory containing MIB Files -help Brief help message =head1 OPTIONS =over 8 =item B<-class> Specific SNMP::Info class to use. Defaults to SNMP::Info if no specific class provided. -class Layer2::Catalyst =item B<-file> File containing data gathered using make_snmpdata.pl. No default and a mandatory option. -file /data/mydevice.txt =item B<-print> Print values of a class method rather than summarizing. May be repeated multiple times. -print i_description -print i_type =item B<-debug> Turns on SNMP::Info debug. -debug =item B<-ignore > Ignore Net-SNMP configuration file snmp.conf. If this used mibdirs must be provided. -ignore =item B<-mibdir> Directory containing MIB Files. Multiple directories should be separated by a colon ':'. -mibdir /usr/local/share/snmp/mibs/rfc:/usr/local/share/snmp/mibs/net-snmp =item B<-help> Print help message and exits. =back =head1 DESCRIPTION B will test a device against an SNMP::Info class using snmpwalk output from the utility B stored in a text file. This allows debugging and testing without requiring network access to the device being tested. =cut SNMP-Info-3.39/lib000755000765000024 013215550564 13456 5ustar00oliverstaff000000000000SNMP-Info-3.39/lib/SNMP000755000765000024 013215550564 14233 5ustar00oliverstaff000000000000SNMP-Info-3.39/lib/SNMP/Info.pm000444000765000024 40130013215550564 15657 0ustar00oliverstaff000000000000# SNMP::Info # # Copyright (c) 2003-2012 Max Baker and SNMP::Info Developers # All rights reserved. # # Portions Copyright (c) 2002-2003, Regents of the University of California # All rights reserved. # # See COPYRIGHT at bottom package SNMP::Info; use warnings; use strict; use Exporter; use SNMP; use Carp; use Math::BigInt; @SNMP::Info::ISA = qw/Exporter/; @SNMP::Info::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG %SPEED_MAP $NOSUCH $BIGINT $REPEATERS/; $VERSION = '3.39'; =head1 NAME SNMP::Info - OO Interface to Network devices and MIBs through SNMP =head1 VERSION SNMP::Info - Version 3.39 =head1 AUTHOR SNMP::Info is maintained by team of Open Source authors headed by Eric Miller, Bill Fenner, Max Baker, Jeroen van Ingen and Oliver Gorwits. Please visit L for most up-to-date list of developers. SNMP::Info was originally created at UCSC for the Netdisco project L by Max Baker. =head1 DEVICES SUPPORTED There are now generic classes for most types of device and so the authors recommend loading SNMP::Info with AutoSpecify, and then reporting to the mail list any missing functionality (such as neighbor discovery tables). =head1 SYNOPSIS use SNMP::Info; my $info = new SNMP::Info( # Auto Discover more specific Device Class AutoSpecify => 1, Debug => 1, # The rest is passed to SNMP::Session DestHost => 'router', Community => 'public', Version => 2 ) or die "Can't connect to device.\n"; my $err = $info->error(); die "SNMP Community or Version probably wrong connecting to device. $err\n" if defined $err; $name = $info->name(); $class = $info->class(); print "SNMP::Info is using this device class : $class\n"; # Find out the Duplex status for the ports my $interfaces = $info->interfaces(); my $i_duplex = $info->i_duplex(); # Get CDP Neighbor info my $c_if = $info->c_if(); my $c_ip = $info->c_ip(); my $c_port = $info->c_port(); # Print out data per port foreach my $iid (keys %$interfaces){ my $duplex = $i_duplex->{$iid}; # Print out physical port name, not snmp iid my $port = $interfaces->{$iid}; print "$port: "; print "$duplex duplex" if defined $duplex; # The CDP Table has table entries different than the interface tables. # So we use c_if to get the map from cdp table to interface table. my %c_map = reverse %$c_if; my $c_key = $c_map{$iid}; unless (defined $c_key) { print "\n\n"; next; } my $neighbor_ip = $c_ip->{$c_key}; my $neighbor_port = $c_port->{$c_key}; print " connected to $neighbor_ip / $neighbor_port\n" if defined $neighbor_ip; print "\n"; } =head1 SUPPORT Please direct all support, help, and bug requests to the snmp-info-users Mailing List at L. =head1 DESCRIPTION SNMP::Info gives an object oriented interface to information obtained through SNMP. This module is geared towards network devices. Subclasses exist for a number of network devices and common MIBs. The idea behind this module is to give a common interface to data from network devices, leaving the device-specific hacks behind the scenes in subclasses. In the SYNOPSIS example we fetch the name of all the ports on the device and the duplex setting for that port with two methods -- interfaces() and i_duplex(). The information may be coming from any number of MIB files and is very vendor specific. SNMP::Info provides you a common method for all supported devices. Adding support for your own device is easy, and takes little SNMP knowledge. The module is not limited to network devices. Any MIB or device can be given an objected oriented front-end by making a module that consists of a couple hashes. See EXTENDING SNMP::INFO. =head1 REQUIREMENTS =over =item 1. Net-SNMP To use this module, you must have Net-SNMP installed on your system. More specifically you need the Perl modules that come with it. DO NOT INSTALL SNMP:: or Net::SNMP from CPAN! The SNMP module is matched to an install of net-snmp, and must be installed from the net-snmp source tree. The Perl module C is found inside the net-snmp distribution. Go to the F directory of the distribution to install it, or run C<./configure --with-perl-modules> from the top directory of the net-snmp distribution. Net-SNMP can be found at http://net-snmp.sourceforge.net Version 5.3.2 or greater is recommended. Versions 5.0.1, 5.0301 and 5.0203 have issues with bulkwalk and are not supported. B: Some versions that come with certain versions of Redhat/Fedora don't have the Perl library installed. Uninstall the RPM and install by hand. =item 2. MIBS SNMP::Info operates on textual descriptors found in MIBs. If you are using SNMP::Info separate from Netdisco, download the Netdisco MIB package at L Make sure that your snmp.conf is updated to point to your MIB directory and that the MIBs are world-readable. =back =head1 DESIGN GOALS =over =item 1. Use of textual MIB leaf identifier and enumerated values =over =item * All values are retrieved via MIB Leaf node names For example SNMP::Info has an entry in its %GLOBALS hash for ``sysName'' instead of 1.3.6.1.2.1.1.5. =item * Data returned is in the enumerated value form. For Example instead of looking up 1.3.6.1.2.1.2.2.1.3 and getting back C<23> SNMP::Info will ask for C and will get back C. =back =item 2. SNMP::Info is easily extended to new devices You can create a new subclass for a device by providing four hashes : %GLOBALS, %MIBS, %FUNCS, and %MUNGE. Or you can override any existing methods from a parent class by making a short subroutine. See the section EXTENDING SNMP::INFO for more details. When you make a new subclass for a device, please be sure to send it back to the developers (via Source Forge or the mailing list) for inclusion in the next version. =back =head1 SUBCLASSES These are the subclasses that implement MIBs and support devices: Required MIBs not included in the install instructions above are noted here. =head2 MIB Subclasses These subclasses implement method to access one or more MIBs. These are not used directly, but rather inherited from device subclasses. For more info run C on any of the following module names. =over =item SNMP::Info::AdslLine SNMP Interface to the ADSL-LINE-MIB for ADSL interfaces. Requires the F, down loadable from Cisco. See documentation in L for details. =item SNMP::Info::Aggregate SNMP Interface to F C Aggregated Links See documentation in L for details. =item SNMP::Info::Airespace F and F. Inherited by devices based on the Airespace wireless platform. See documentation in L for details. =item SNMP::Info::AMAP F. Alcatel Mapping Adjacency Protocol (AMAP) Support. See documentation in L for details. =item SNMP::Info::Bridge F (RFC1286). F. Inherited by devices with Layer2 support. See documentation in L for details. =item SNMP::Info::CiscoAgg SNMP Interface to Cisco Aggregated Links See documentation in L for details. =item SNMP::Info::CDP F. Cisco Discovery Protocol (CDP) Support. Inherited by Cisco, Enterasys, and HP devices. See documentation in L for details. =item SNMP::Info::CiscoConfig F, F, and F. These OIDs facilitate the writing of configuration files. See documentation in L for details. =item SNMP::Info::CiscoPortSecurity F and F. See documentation in L for details. =item SNMP::Info::CiscoPower F. See documentation in L for details. =item SNMP::Info::CiscoQOS F. A collection of OIDs providing information about a Cisco device's QOS config. See documentation in L for details. =item SNMP::Info::CiscoRTT F. A collection of OIDs providing information about a Cisco device's RTT values. See documentation in L for details. =item SNMP::Info::CiscoStack F. See documentation in L for details. =item SNMP::Info::CiscoStpExtensions F See documentation in L for details. =item SNMP::Info::CiscoStats F, F, and F. Provides common interfaces for memory, cpu, and os statistics for Cisco devices. See documentation in L for details. =item SNMP::Info::CiscoVTP F, F, F See documentation in L for details. =item SNMP::Info::EDP Extreme Discovery Protocol. F See documentation in L for details. =item SNMP::Info::Entity F. Used for device info in Cisco and other vendors. See documentation in L for details. =item SNMP::Info::EtherLike F (RFC1398) - Some Layer3 devices implement this MIB, as well as some Aironet Layer 2 devices (non Cisco). See documentation in L for details. =item SNMP::Info::FDP Foundry (Brocade) Discovery Protocol. F See documentation in L for details. =item SNMP::Info::IPv6 SNMP Interface for obtaining configured IPv6 addresses and mapping IPv6 addresses to MAC addresses and interfaces, using information from F, F and/or F. See documentation in L for details. =item SNMP::Info::IEEE802dot11 F. A collection of OIDs providing information about standards based 802.11 wireless devices. See documentation in L for details. =item SNMP::Info::IEEE802dot3ad SNMP Interface to IEEE Aggregated Links. F See documentation in L for details. =item SNMP::Info::LLDP F, F, and F. Link Layer Discovery Protocol (LLDP) Support. See documentation in L for details. =item SNMP::Info::MAU F (RFC2668). Some Layer2 devices use this for extended Ethernet (Media Access Unit) interface information. See documentation in L for details. =item SNMP::Info::MRO Method resolution introspection for SNMP::Info See documentation in L for details. =item SNMP::Info::NortelStack F, F. See documentation in L for details. =item SNMP::Info::PowerEthernet F See documentation in L for details. =item SNMP::Info::RapidCity F. Inherited by Avaya switches for duplex and VLAN information. See documentation in L for details. =item SNMP::Info::SONMP SynOptics Network Management Protocol (SONMP) F, F. Inherited by Avaya/Nortel/Bay/Synoptics switches and hubs. See documentation in L for details. =back =head2 Device Subclasses These subclasses inherit from one or more classes to provide a common interface to data obtainable from network devices. All the required MIB files are included in the netdisco-mib package. (See Above). =over =item SNMP::Info::Layer1 Generic Layer1 Device subclass. See documentation in L for details. =over =item SNMP::Info::Layer1::Allied Subclass for Allied Telesis Repeaters / Hubs. Requires F See documentation in L for details. =item SNMP::Info::Layer1::Asante Subclass for Asante 1012 Hubs. Requires F See documentation in L for details. =item SNMP::Info::Layer1::Bayhub Subclass for Nortel/Bay hubs. This includes System 5000, 100 series, 200 series, and probably more. See documentation in L for details. =item SNMP::Info::Layer1::Cyclades Subclass for Cyclades terminal servers. See documentation in L for details. =item SNMP::Info::Layer1::S3000 Subclass for Bay/Synoptics hubs. This includes System 3000, 281X, and probably more. See documentation in L for details. =back =item SNMP::Info::Layer2 Generic Layer2 Device subclass. See documentation in L for details. =over =item SNMP::Info::Layer2::3Com SNMP::Info::Layer2::3Com - SNMP Interface to L2 3Com Switches See documentation in L for details. =item SNMP::Info::Layer2::Airespace Subclass for Cisco (Airespace) wireless controllers. See documentation in L for details. =item SNMP::Info::Layer2::Aironet Class for Cisco Aironet wireless devices that run IOS. See also Layer3::Aironet for Aironet devices that don't run IOS. See documentation in L for details. =item SNMP::Info::Layer2::Allied Allied Telesis switches. See documentation in L for details. =item SNMP::Info::Layer2::Baystack Subclass for Avaya/Nortel/Bay Ethernet Switch/Baystack switches. This includes 303, 304, 350, 380, 410, 420, 425, 450, 460, 470 series, 2500 series, 4000 series, 5000 series, Business Ethernet Switch (BES), Business Policy Switch (BPS), VSP 7000 series, and probably others. See documentation in L for details. =item SNMP::Info::Layer2::Kentrox Class for Kentrox DataSMART DSU/CSU. See L for details. =item SNMP::Info::Layer2::C1900 Subclass for Cisco Catalyst 1900 and 1900c Devices running CatOS. See documentation in L for details. =item SNMP::Info::Layer2::C2900 Subclass for Cisco Catalyst 2900, 2950, 3500XL, and 3548 devices running IOS. See documentation in L for details. =item SNMP::Info::Layer2::Catalyst Subclass for Cisco Catalyst switches running CatOS. These switches usually report a model number that starts with C. Note that this class does not support everything that has the name Catalyst. See documentation in L for details. =item SNMP::Info::Layer2::Centillion Subclass for Nortel/Bay Centillion and 5000BH ATM switches. See documentation in L for details. =item SNMP::Info::Layer2::Cisco Generic Cisco subclass for layer 2 devices that are not yet supported in more specific subclassesand the base layer 2 Cisco class for other device specific layer 2 Cisco classes. See documentation in L for details. =item SNMP::Info::Layer2::CiscoSB Subclass for Cisco's "Small Business" product line, acquired from Linksys. This currently comprises the Sx300/500 line of switches. See documentation in L for details. =item SNMP::Info::Layer2::HP Subclass for more recent HP Procurve Switches Requires F and F downloaded from HP. See documentation in L for details. =item SNMP::Info::Layer2::HP4000 Subclass for older HP Procurve Switches Requires F and F downloaded from HP. See documentation in L for details. =item SNMP::Info::Layer2::HPVC Subclass for HP Virtual Connect Switches See documentation in L for details. =item SNMP::Info::Layer2::N2270 Subclass for Nortel 2270 wireless switches. See documentation in L for details. =item SNMP::Info::Layer2::NAP222x Subclass for Nortel 222x series wireless access points. See documentation in L for details. =item SNMP::Info::Layer2::Netgear Subclass for Netgear switches See documentation in L for details. =item SNMP::Info::Layer2::NWSS2300 SNMP Interface to Avaya (Trapeze) Wireless Controllers See documentation in L for details. =item SNMP::Info::Layer2::Orinoco Subclass for Orinoco/Proxim wireless access points. See documentation in L for details. =item SNMP::Info::Layer2::Trapeze SNMP Interface to Juniper (Trapeze) Wireless Controllers See documentation in L for details. =item SNMP::Info::Layer2::Ubiquiti SNMP Interface to Ubiquiti Access Points and other devices See documentation in L for details. =item SNMP::Info::Layer2::ZyXEL_DSLAM Zyxel DSLAMs. Need I say more? See documentation in L for details. =back =item SNMP::Info::Layer3 Generic Layer3 and Layer2+3 Device subclass. See documentation in L for details. =over =item SNMP::Info::Layer3::Aironet Subclass for Cisco Aironet wireless access points (AP) not running IOS. These are usually older devices. MIBs for these devices now included in v2.tar.gz available from ftp.cisco.com. Note Layer2::Aironet See documentation in L for details. =item SNMP::Info::Layer3::AlcatelLucent Alcatel-Lucent OmniSwitch Class. See documentation in L for details. =item SNMP::Info::Layer3::AlteonAD Subclass for Radware Alteon Series ADC switches and Nortel BladeCenter Layer2-3 GbE Switch Modules. See documentation in L for details. =item SNMP::Info::Layer3::Altiga See documentation in L for details. =item SNMP::Info::Layer3::Arista See documentation in L for details. =item SNMP::Info::Layer3::Aruba Subclass for Aruba wireless switches. See documentation in L for details. =item SNMP::Info::Layer3::BayRS Subclass for Avaya/Nortel/Bay Multiprotocol/BayRS routers. This includes BCN, BLN, ASN, ARN, AN, 2430, and 5430 routers. See documentation in L for details. =item SNMP::Info::Layer3::BlueCoatSG Subclass for Blue Coat SG series proxy devices. See documentation in L for details. =item SNMP::Info::Layer3::C3550 Subclass for Cisco Catalyst 3550,3540,3560 2/3 switches running IOS. See documentation in L for details. =item SNMP::Info::Layer3::C4000 This class covers Catalyst 4000s and 4500s. See documentation in L for details. =item SNMP::Info::Layer3::C6500 This class covers Catalyst 6500s in native mode, hybrid mode. Catalyst 3750's, 2970's and probably others. See documentation in L for details. =item SNMP::Info::Layer3::Cisco This is a simple wrapper around layer 3 for IOS devices and the base layer 3 Cisco class for other device specific layer 3 Cisco classes. See documentation in L for details. =item SNMP::Info::Layer3::CiscoASA Subclass for Cisco Adaptive Security Appliances. See documentation in L for details. =item SNMP::Info::Layer3::CiscoFWSM Subclass for Cisco Firewall Services Modules. See documentation in L for details. =item SNMP::Info::Layer3::CiscoSwitch Base class for L3 Cisco switches. See documentation in L for details. =item SNMP::Info::Layer3::Contivity Subclass for Avaya/Nortel Contivity/VPN Routers. See documentation in L for details. =item SNMP::Info::Layer3::Dell Subclass for Dell PowerConnect switches. D-Link, the IBM BladeCenter Gigabit Ethernet Switch Module and some Linksys switches also use this module based upon MIB support. See documentation in L for details. =item SNMP::Info::Layer3::Enterasys Subclass for Enterasys devices. See documentation in L for details. =item SNMP::Info::Layer3::Extreme Subclass for Extreme Networks switches. See documentation in L for details. =item SNMP::Info::Layer3::F5 Subclass for F5 devices. See documentation in L for details. =item SNMP::Info::Layer3::Force10 Subclass for Force10 devices. See documentation in L for details. =item SNMP::Info::Layer3::Fortinet Subclass for Fortinet devices. See documentation in L for details. =item SNMP::Info::Layer3::Foundry Subclass for Brocade (Foundry) Network devices. See documentation in L for details. =item SNMP::Info::Layer3::H3C SNMP Interface to Layer 3 Devices, H3C & HP A-series. See documentation in L for details. =item SNMP::Info::Layer3::HP9300 Subclass for HP network devices which Foundry Networks was the Original Equipment Manufacturer (OEM) such as the HP ProCurve 9300 and 6300 series. See documentation in L for details. =item SNMP::Info::Layer3::Huawei SNMP Interface to Huawei Layer 3 switches and routers. See documentation in L for details. =item SNMP::Info::Layer3::IBMGbTor SNMP Interface to IBM Rackswitch (formerly Blade Network Technologies) network devices. See documentation in L for details. =item SNMP::Info::Layer3::Juniper Subclass for Juniper devices See documentation in L for details. =item SNMP::Info::Layer3::Lantronix Subclass for Lantronix devices See documentation in L for details. =item SNMP::Info::Layer3::Microsoft Subclass for Generic Microsoft Routers running Microsoft Windows OS. See documentation in L for details. =item SNMP::Info::Layer3::Mikrotik Subclass for Mikrotik devices running RouterOS. See documentation in L for details. =item SNMP::Info::Layer3::N1600 Subclass for Avaya/Nortel Ethernet Routing Switch 1600 series. See documentation in L for details. =item SNMP::Info::Layer3::NetSNMP Subclass for host systems running Net-SNMP. See documentation in L for details. =item SNMP::Info::Layer3::Netscreen Subclass for Juniper NetScreen. See documentation in L for details. =item SNMP::Info::Layer3::Nexus Subclass for Cisco Nexus devices running NX-OS See documentation in L for details. =item SNMP::Info::Layer3::PacketFront Subclass for PacketFront DRG series CPE. See documentation in L for details. =item SNMP::Info::Layer3::PaloAlto Subclass for Palo Alto firewalls. See documentation in L for details. =item SNMP::Info::Layer3::Passport Subclass for Avaya/Nortel Ethernet Routing Switch/Passport 8000 series, Accelar, and VSP 9000 series switches. See documentation in L for details. =item SNMP::Info::Layer3::Pf Subclass for FreeBSD-Based Firewalls using Pf /Pf Sense See documentation in L for details. =item SNMP::Info::Layer3::Pica8 Subclass for Pica8 devices. See documentation in L for details. =item SNMP::Info::Layer3::SonicWALL Subclass for generic SonicWALL devices. See documentation in L for details. =item SNMP::Info::Layer3::Steelhead Subclass for Riverbed Steelhead WAN optimization appliances. See documentation in L for details. =item SNMP::Info::Layer3::Sun Subclass for Generic Sun Routers running SunOS. See documentation in L for details. =item SNMP::Info::Layer3::Tasman Subclass for Avaya Secure Routers. See documentation in L for details. =item SNMP::Info::Layer3::Timetra Alcatel-Lucent SR Class. See documentation in L for details. =item SNMP::Info::Layer3::VMware Subclass for VMware ESXi hosts. See documentation in L for details. =back =back =over 4 =item SNMP::Info::Layer7 Generic Layer7 Devices. See documentation in L for details. =over 4 =item SNMP::Info::Layer7::APC SNMP Interface to APC UPS devices See documentation in L for details. =item SNMP::Info::Layer7::Netscaler SNMP Interface to Citrix Netscaler appliances See documentation in L for details. =item SNMP::Info::Layer7::Neoteris SNMP Interface to Juniper SSL VPN appliances See documentation in L for details. =back =back =head1 Thanks Thanks for testing and coding help (in no particular order) to : Alexander Barthel, Andy Ford, Alexander Hartmaier, Andrew Herrick, Alex Kramarov, Bernhard Augenstein, Bradley Baetz, Brian Chow, Brian Wilson, Carlos Vicente, Dana Watanabe, David Pinkoski, David Sieborger, Douglas McKeown, Greg King, Ivan Auger, Jean-Philippe Luiggi, Jeroen van Ingen, Justin Hunter, Kent Hamilton, Matthew Tuttle, Michael Robbert, Mike Hunter, Nicolai Petri, Ralf Gross, Robert Kerr and people listed on the Netdisco README! =head1 USAGE =head2 Constructor =over =item new() Creates a new object and connects via SNMP::Session. my $info = new SNMP::Info( 'Debug' => 1, 'AutoSpecify' => 1, 'BigInt' => 1, 'BulkWalk' => 1, 'BulkRepeaters' => 20, 'IgnoreNetSNMPConf' => 1, 'LoopDetect' => 1, 'DestHost' => 'myrouter', 'Community' => 'public', 'Version' => 2, 'MibDirs' => ['dir1','dir2','dir3'], ) or die; SNMP::Info Specific Arguments : =over =item AutoSpecify Returns an object of a more specific device class (default 0, which means "off") =item BigInt Return Math::BigInt objects for 64 bit counters. Sets on a global scope, not object. (default 0, which means "off") =item BulkWalk Set to C<0> to turn off BULKWALK commands for SNMPv2 connections. Note that BULKWALK is turned off for Net-SNMP versions 5.1.x because of a bug. (default 1, which means "on") =item BulkRepeaters Set number of MaxRepeaters for BULKWALK operation. See C -> bulkwalk() for more info. (default 20) =item LoopDetect Detects looping during getnext table column walks by comparing IIDs for each instance. A loop is detected if the same IID is seen more than once and the walk is aborted. Note: This will not detect loops during a bulkwalk operation, Net-SNMP's internal bulkwalk function must detect the loop. Set to C<0> to turn off loop detection. (default 1, which means "on") =item IgnoreNetSNMPConf Net-SNMP version 5.0 and higher read configuration files, snmp.conf or snmp.local.conf, from /etc/snmp, /usr/share/snmp, /usr/lib(64)/snmp, or $HOME/.snmp and uses those settings to automatically parse MIB files, etc. Set to C<1> "on" to ignore Net-SNMP configuration files by overriding the C environmental variable during object initialization. Note: MibDirs must be defined or Net-SNMP will not be able to load MIBs and initialize the object. (default 0, which means "off") =item Debug Prints Lots of debugging messages. Pass 2 to print even more debugging messages. (default 0, which means "off") =item DebugSNMP Set $SNMP::debugging level for Net-SNMP. See F for more details. =item MibDirs Array ref to list of directories in which to look for MIBs. Note this will be in addition to the ones setup in snmp.conf at the system level. (default use net-snmp settings only) =item RetryNoSuch When using SNMP Version 1, try reading values even if they come back as "no such variable in this MIB". Set to false if so desired. This feature lets you read SNMPv2 data from an SNMP version 1 connection, and should probably be left on. (default 1, which means "on") =item Session SNMP::Session object to use instead of connecting on own. (default creates session automatically) =item Offline Causes SNMP::Info to avoid network activity and return data only from its cache. If you ask for something not in the cache, an error is thrown. See also the C and C methods. (default 0, which means "online") =item Cache Pass in a HashRef to prime the cache of retrieved data. Useful for creating an instance in C mode from a previously dumped cache. See also the C method to retrieve a cache after running actial queries. =item OTHER All other arguments are passed to SNMP::Session. See SNMP::Session for a list of other possible arguments. =back A Note about the wrong Community string or wrong SNMP Version: If a connection is using the wrong community string or the wrong SNMP version, the creation of the object will not fail. The device still answers the call on the SNMP port, but will not return information. Check the error() method after you create the device object to see if there was a problem in connecting. A note about SNMP Versions : Some older devices don't support SNMP version 2, and will not return anything when a connection under Version 2 is attempted. Some newer devices will support Version 1, but will not return all the data they might have if you had connected under Version 1 When trying to get info from a new device, you may have to try version 2 and then fallback to version 1. =cut sub new { my $proto = shift; my $class = ref($proto) || $proto; my %args = @_; my %sess_args = %args; my $new_obj = {}; bless $new_obj, $class; $new_obj->{class} = $class; # load references to all the subclass data structures { no strict 'refs'; ## no critic (ProhibitNoStrict ProhibitProlongedStrictureOverride) $new_obj->{init} = \${ $class . '::INIT' }; $new_obj->{mibs} = \%{ $class . '::MIBS' }; $new_obj->{globals} = \%{ $class . '::GLOBALS' }; $new_obj->{funcs} = \%{ $class . '::FUNCS' }; $new_obj->{munge} = \%{ $class . '::MUNGE' }; } # SNMP::Info specific args : if ( defined $args{Debug} ) { $new_obj->debug( $args{Debug} ); delete $sess_args{Debug}; } else { $new_obj->debug( defined $DEBUG ? $DEBUG : 0 ); } if ( defined $args{DebugSNMP} ) { $SNMP::debugging = $args{DebugSNMP}; delete $sess_args{DebugSNMP}; } my $auto_specific = 0; if ( defined $args{AutoSpecify} ) { $auto_specific = $args{AutoSpecify} || 0; delete $sess_args{AutoSpecify}; } if ( defined $args{BulkRepeaters} ) { $new_obj->{BulkRepeaters} = $args{BulkRepeaters}; delete $sess_args{BulkRepeaters}; } if ( defined $args{BulkWalk} ) { $new_obj->{BulkWalk} = $args{BulkWalk}; delete $sess_args{BulkWalk}; } if ( defined $args{LoopDetect} ) { $new_obj->{LoopDetect} = $args{LoopDetect}; delete $sess_args{LoopDetect}; } if ( defined $args{IgnoreNetSNMPConf} ) { $new_obj->{IgnoreNetSNMPConf} = $args{IgnoreNetSNMPConf} || 0; delete $sess_args{IgnoreNetSNMPConf}; } if ( defined $args{Offline} ) { $new_obj->{Offline} = $args{Offline} || 0; delete $sess_args{Offline}; } if ( defined $args{Cache} and ref {} eq ref $args{Cache} ) { $new_obj->{$_} = $args{Cache}->{$_} for keys %{$args{Cache}}; delete $sess_args{Cache}; } my $sess = undef; if ( defined $args{Session} ) { $sess = $args{Session}; delete $sess_args{Session}; } if ( defined $args{BigInt} ) { $BIGINT = $args{BigInt}; delete $sess_args{BigInt}; } if ( defined $args{MibDirs} ) { $new_obj->{mibdirs} = $args{MibDirs}; delete $sess_args{MibDirs}; } $new_obj->{nosuch} = $args{RetryNoSuch} || $NOSUCH; # Initialize mibs if not done my $init_ref = $new_obj->{init}; unless ( defined $$init_ref and $$init_ref ) { $new_obj->init(); $$init_ref = 1; } # Connects to device unless open session is provided. $sess = new SNMP::Session( 'UseEnums' => 1, %sess_args, 'RetryNoSuch' => $new_obj->{nosuch} ) unless defined $sess; # No session object created unless ( defined $sess ) { $new_obj->error_throw("SNMP::Info::new() Failed to Create Session. "); return; } # Session object created but SNMP connection failed. my $sess_err = $sess->{ErrorStr} || ''; if ($sess_err) { $new_obj->error_throw( "SNMP::Info::new() Net-SNMP session creation failed. $sess_err"); return; } # Save Args for later $new_obj->{store} ||= {}; $new_obj->{sess} = $sess; $new_obj->{args} = \%args; $new_obj->{snmp_ver} = $sess->{Version} || $args{Version} || 2; $new_obj->{snmp_comm} = $sess->{Community} || $args{Community} || 'public'; $new_obj->{snmp_user} = $sess->{SecName} || $args{SecName} || 'initial'; return $auto_specific ? $new_obj->specify() : $new_obj; } =item update() Replace the existing session with a new one with updated values, without re-identifying the device. The only supported changes are to Community or Context. Clears the object cache. This is useful, e.g., when a device supports multiple contexts (via changes to the Community string, or via the SNMPv3 Context parameter), but a context that you want to access does not support the objects (e.g., C, C) that we use to identify the device. =cut sub update { my $obj = shift; my %update_args = @_; my %sess_args = ( %{ $obj->{args} }, %update_args ); # silently only update "the right" args delete $sess_args{Debug}; delete $sess_args{DebugSNMP}; delete $sess_args{AutoSpecify}; delete $sess_args{BulkRepeaters}; delete $sess_args{BulkWalk}; delete $sess_args{LoopDetect}; delete $sess_args{IgnoreNetSNMPConf}; delete $sess_args{BigInt}; delete $sess_args{MibDirs}; my $sess = new SNMP::Session( 'UseEnums' => 1, %sess_args, 'RetryNoSuch' => $obj->{nosuch} ); unless ( defined $sess ) { $obj->error_throw( "SNMP::Info::update() Failed to Create new Session. "); return; } # Session object created but SNMP connection failed. my $sess_err = $sess->{ErrorStr} || ''; if ($sess_err) { $obj->error_throw( "SNMP::Info::update() Net-SNMP session creation failed. $sess_err" ); return; } $obj->clear_cache(); return $obj->session($sess); } =back =head2 Data is Cached Methods and subroutines requesting data from a device will only load the data once, and then return cached versions of that data. Run $info->load_METHOD() where method is something like 'i_name' to reload data from a method. Run $info->clear_cache() to clear the cache to allow reload of both globals and table methods. The cache can be retrieved or set using the $info->cache() method. This works together with the C option. =head2 Object Scalar Methods These are for package related data, not directly supplied from SNMP. =over =item $info->clear_cache() Clears the cached data. This includes GLOBALS data and TABLE METHOD data. =cut sub clear_cache { my $self = shift; print "SNMP::Info::clear_cache() - Cache Cleared.\n" if $self->debug(); # Clear cached global values and table method flag for being cached foreach my $key ( keys %$self ) { next unless defined $key; next unless $key =~ /^_/; delete $self->{$key}; } # Clear store for tables return $self->store( {} ); } =item $info->debug(1) Returns current debug status, and optionally toggles debugging info for this object. =cut sub debug { my $self = shift; my $debug = shift; if ( defined $debug ) { $self->{debug} = $debug; } return $self->{debug}; } =item $info->offline([1|0]) Returns if offline mode is currently turned on for this object. Optionally sets the Offline parameter. =cut sub offline { my $self = shift; my $ol = shift; if ( defined $ol ) { $self->{Offline} = $ol; } return $self->{Offline}; } =item $info->cache([new_cache]) Returns a HashRef of all cached data in this object. There will be a C key for table data and then one key for each leaf. Optionally sets the cache parameters if passed a HashRef. =cut sub cache { my $self = shift; my $data = shift; if ( defined $data and ref {} eq ref $data ) { $self->{$_} = $data->{$_} for keys %$data; } my $cache = { store => $self->{store} }; foreach my $key ( keys %$self ) { next unless defined $key; next unless $key =~ /^_/; $cache->{$key} = $self->{$key}; } return $cache; } =item $info->bulkwalk([1|0]) Returns if bulkwalk is currently turned on for this object. Optionally sets the bulkwalk parameter. =cut sub bulkwalk { my $self = shift; my $bw = shift; if ( defined $bw ) { $self->{BulkWalk} = $bw; } return $self->{BulkWalk}; } =item $info->loopdetect([1|0]) Returns if loopdetect is currently turned on for this object. Optionally sets the loopdetect parameter. =cut sub loopdetect { my $self = shift; my $ld = shift; if ( defined $ld ) { $self->{LoopDetect} = $ld; } return $self->{LoopDetect}; } =item $info->device_type() Returns the Subclass name for this device. C is returned if no more specific class is available. First the device is checked for Layer 3 support and a specific subclass, then Layer 2 support and subclasses are checked. This means that Layer 2 / 3 switches and routers will fall under the SNMP::Info::Layer3 subclasses. If the device still can be connected to via SNMP::Info, then SNMP::Info is returned. =cut sub device_type { my $info = shift; my $objtype = "SNMP::Info"; my $layers = $info->layers() || '00000000'; my $desc = $info->description() || 'undef'; $desc =~ s/[\r\n\l]+/ /g; # Some devices don't implement sysServices, but do return a description. # In that case, log a warning and continue. if ( $layers eq '00000000' ) { if ($desc ne 'undef') { carp("Device doesn't implement sysServices but did return sysDescr. Might give unexpected results.\n") if $info->debug(); } else { # No sysServices, no sysDescr return; } } my $id = $info->id() || 'undef'; my $soid = $id; # Hash for generic fallback to a device class if unable to determine using # the sysDescr regex. my %l3sysoidmap = ( 9 => 'SNMP::Info::Layer3::Cisco', 11 => 'SNMP::Info::Layer2::HP', 18 => 'SNMP::Info::Layer3::BayRS', 42 => 'SNMP::Info::Layer3::Sun', 43 => 'SNMP::Info::Layer2::3Com', 45 => 'SNMP::Info::Layer2::Baystack', 171 => 'SNMP::Info::Layer3::DLink', 244 => 'SNMP::Info::Layer3::Lantronix', 311 => 'SNMP::Info::Layer3::Microsoft', 674 => 'SNMP::Info::Layer3::Dell', 1872 => 'SNMP::Info::Layer3::AlteonAD', 1916 => 'SNMP::Info::Layer3::Extreme', 1991 => 'SNMP::Info::Layer3::Foundry', 2011 => 'SNMP::Info::Layer3::Huawei', 2021 => 'SNMP::Info::Layer3::NetSNMP', 2272 => 'SNMP::Info::Layer3::Passport', 2636 => 'SNMP::Info::Layer3::Juniper', 2925 => 'SNMP::Info::Layer1::Cyclades', 3076 => 'SNMP::Info::Layer3::Altiga', 3224 => 'SNMP::Info::Layer3::Netscreen', 3375 => 'SNMP::Info::Layer3::F5', 3417 => 'SNMP::Info::Layer3::BlueCoatSG', 4526 => 'SNMP::Info::Layer2::Netgear', 5624 => 'SNMP::Info::Layer3::Enterasys', 6027 => 'SNMP::Info::Layer3::Force10', 6486 => 'SNMP::Info::Layer3::AlcatelLucent', 6527 => 'SNMP::Info::Layer3::Timetra', 6876 => 'SNMP::Info::Layer3::VMware', 8072 => 'SNMP::Info::Layer3::NetSNMP', 9303 => 'SNMP::Info::Layer3::PacketFront', 10002 => 'SNMP::Info::Layer2::Ubiquiti', 12325 => 'SNMP::Info::Layer3::Pf', 12356 => 'SNMP::Info::Layer3::Fortinet', 14179 => 'SNMP::Info::Layer2::Airespace', 14525 => 'SNMP::Info::Layer2::Trapeze', 14823 => 'SNMP::Info::Layer3::Aruba', 14988 => 'SNMP::Info::Layer3::Mikrotik', 17163 => 'SNMP::Info::Layer3::Steelhead', 25506 => 'SNMP::Info::Layer3::H3C', 25461 => 'SNMP::Info::Layer3::PaloAlto', 26543 => 'SNMP::Info::Layer3::IBMGbTor', 30065 => 'SNMP::Info::Layer3::Arista', 35098 => 'SNMP::Info::Layer3::Pica8', 41112 => 'SNMP::Info::Layer2::Ubiquiti', 4413 => 'SNMP::Info::Layer2::Ubiquiti', ); my %l2sysoidmap = ( 9 => 'SNMP::Info::Layer2::Cisco', 11 => 'SNMP::Info::Layer2::HP', 43 => 'SNMP::Info::Layer2::3Com', 45 => 'SNMP::Info::Layer2::Baystack', 171 => 'SNMP::Info::Layer3::DLink', 207 => 'SNMP::Info::Layer2::Allied', 674 => 'SNMP::Info::Layer3::Dell', 1872 => 'SNMP::Info::Layer3::AlteonAD', 1916 => 'SNMP::Info::Layer3::Extreme', 1991 => 'SNMP::Info::Layer3::Foundry', 2011 => 'SNMP::Info::Layer3::Huawei', 2272 => 'SNMP::Info::Layer3::Passport', 2925 => 'SNMP::Info::Layer1::Cyclades', 3224 => 'SNMP::Info::Layer3::Netscreen', 3375 => 'SNMP::Info::Layer3::F5', 4526 => 'SNMP::Info::Layer2::Netgear', 5624 => 'SNMP::Info::Layer3::Enterasys', 6486 => 'SNMP::Info::Layer3::AlcatelLucent', 9303 => 'SNMP::Info::Layer3::PacketFront', 11898 => 'SNMP::Info::Layer2::Orinoco', 14179 => 'SNMP::Info::Layer2::Airespace', 14525 => 'SNMP::Info::Layer2::Trapeze', 14823 => 'SNMP::Info::Layer3::Aruba', 17163 => 'SNMP::Info::Layer3::Steelhead', 26543 => 'SNMP::Info::Layer3::IBMGbTor', ); my %l1sysoidmap = ( 2925 => 'SNMP::Info::Layer1::Cyclades', ); my %l7sysoidmap = ( 318 => 'SNMP::Info::Layer7::APC', 5951 => 'SNMP::Info::Layer7::Netscaler', 14525 => 'SNMP::Info::Layer2::Trapeze', 12532 => 'SNMP::Info::Layer7::Neoteris', ); # Get just the enterprise number for generic mapping $id = $1 if ( defined($id) && $id =~ /^\.1\.3\.6\.1\.4\.1\.(\d+)/ ); if ($info->debug()) { print "SNMP::Info $VERSION\n"; print "SNMP::Info::device_type() layers:$layers id:$id sysDescr:\"$desc\"\n"; } # Layer 3 Supported # (usually has layer2 as well, so we check for 3 first) if ( $info->has_layer(3) ) { $objtype = 'SNMP::Info::Layer3'; # Device Type Overrides return $objtype unless ( defined $desc and length($desc) ); $objtype = 'SNMP::Info::Layer3::C3550' if $desc =~ /(C3550|C3560)/; $objtype = 'SNMP::Info::Layer3::C4000' if $desc =~ /Catalyst 4[05]00/; $objtype = 'SNMP::Info::Layer3::Foundry' if $desc =~ /foundry/i; # Aironet - older non-IOS $objtype = 'SNMP::Info::Layer3::Aironet' if ($desc =~ /Cisco/ and $desc =~ /\D(CAP340|AP340|CAP350|350|1200)\D/ ); $objtype = 'SNMP::Info::Layer3::Aironet' if ( $desc =~ /Aironet/ and $desc =~ /\D(AP4800)\D/ ); # Override voice gateway device (VG350) showing up as Aironet $objtype = 'SNMP::Info::Layer3::Cisco' if $desc =~ /VG350/; # Cat6k with older SUPs (hybrid CatOS/IOS?) $objtype = 'SNMP::Info::Layer3::C6500' if $desc =~ /(c6sup2|c6sup1)/; # Cat6k with Sup720, Sup720 or Sup2T (and Sup2 running native IOS?) $objtype = 'SNMP::Info::Layer3::C6500' if $desc =~ /(s72033_rp|s3223_rp|s32p3_rp|s222_rp|s2t54)/; # Next one untested. Reported working by DA $objtype = 'SNMP::Info::Layer3::C6500' if ( $desc =~ /cisco/i and $desc =~ /3750/ ); # IOS 15.x on Catalyst 3850 $objtype = 'SNMP::Info::Layer3::C6500' if ( $desc =~ /cisco/i and $desc =~ /CAT3K/ ); # Cisco 2970 $objtype = 'SNMP::Info::Layer3::C6500' if ( $desc =~ /(C2970|C2960)/ ); # Cisco 3400 w/ Layer3 capable image $objtype = 'SNMP::Info::Layer3::C3550' if ( $desc =~ /(ME340x)/ ); # Various Cisco blade switches, CBS30x0 and CBS31x0 models $objtype = 'SNMP::Info::Layer3::C6500' if ( $desc =~ /cisco/i and $desc =~ /CBS3[0-9A-Za-z]{3}/ ); # Cisco Nexus running NX-OS $objtype = 'SNMP::Info::Layer3::Nexus' if ( $desc =~ /^Cisco\s+NX-OS/ ); # HP, older ProCurve models (1600, 2400, 2424m, 4000, 8000) $objtype = 'SNMP::Info::Layer2::HP4000' if $desc =~ /\b(J4093A|J4110A|J4120A|J4121A|J4122A|J4122B)\b/; # HP, Foundry OEM $objtype = 'SNMP::Info::Layer3::HP9300' if $desc =~ /\b(J4874A|J4138A|J4139A|J4840A|J4841A)\b/; # Nortel ERS (Passport) 1600 Series < version 2.1 $objtype = 'SNMP::Info::Layer3::N1600' if $desc =~ /(Passport|Ethernet\s+Routing\s+Switch)-16/i; # ERS - BayStack Numbered $objtype = 'SNMP::Info::Layer2::Baystack' if ( $desc =~ /^(BayStack|Ethernet\s+Routing\s+Switch)\s[2345](\d){2,3}/i ); # Nortel Contivity $objtype = 'SNMP::Info::Layer3::Contivity' if $desc =~ /(\bCES\b|\bNVR\sV\d)/; # SonicWALL $objtype = 'SNMP::Info::Layer3::SonicWALL' if $desc =~ /SonicWALL/i; # Allied Telesis Layer2 managed switches. They report they have L3 support $objtype = 'SNMP::Info::Layer2::Allied' if ( $desc =~ /Allied.*AT-80\d{2}\S*/i ); # Cisco ASA, newer versions which report layer 3 functionality # version >= 8.2 are known to do this $objtype = 'SNMP::Info::Layer3::CiscoASA' if ( $desc =~ /Cisco Adaptive Security Appliance/i ); # Cisco FWSM $objtype = 'SNMP::Info::Layer3::CiscoFWSM' if ( $desc =~ /Cisco Firewall Services Module/i ); # Avaya Secure Router $objtype = 'SNMP::Info::Layer3::Tasman' if ( $desc =~ /^(avaya|nortel)\s+(SR|secure\srouter)\s+\d{4}/i ); # HP Virtual Connect blade switches $objtype = 'SNMP::Info::Layer2::HPVC' if ( $desc =~ /HP\sVC\s/ ); # Aironet - IOS # Starting with IOS 15, Aironet reports sysServices 6, even though # it still is the same layer2 access point. $objtype = 'SNMP::Info::Layer2::Aironet' if ($desc =~ /\b(C1100|C1130|C1140|AP1200|C350|C1200|C1240|C1250|C2700|C3700)\b/ and $desc =~ /\bIOS\b/ ); # Airespace (WLC) Module $objtype = 'SNMP::Info::Layer2::Airespace' if ( $desc =~ /^Cisco Controller$/ ); #Nortel 2270 $objtype = 'SNMP::Info::Layer2::N2270' if ( $desc =~ /Nortel\s+(Networks\s+)??WLAN\s+-\s+Security\s+Switch/ ); # Nortel (Trapeze) WSS 2300 Series $objtype = 'SNMP::Info::Layer2::NWSS2300' if ( $desc =~ /^(Nortel\s)??Wireless\sSecurity\sSwitch\s23[568][012]\b/); # Generic device classification based upon sysObjectID if ( ( $objtype eq 'SNMP::Info::Layer3' ) and ( defined($id) ) and ( exists( $l3sysoidmap{$id} ) ) ) { $objtype = $l3sysoidmap{$id}; } # Layer 2 Supported } elsif ( $info->has_layer(2) ) { $objtype = 'SNMP::Info::Layer2'; return $objtype unless ( defined $desc and $desc !~ /^\s*$/ ); # Device Type Overrides # Bay Hub (Needed here for layers override) $objtype = 'SNMP::Info::Layer1::Bayhub' if ( $desc =~ /\bNMM.*Agent/ ); $objtype = 'SNMP::Info::Layer1::Bayhub' if ( $desc =~ /\bBay\s*Stack.*Hub/i ); # Synoptics Hub (Needed here for layers override) # This will override Bay Hub only for specific devices supported # by this class $objtype = 'SNMP::Info::Layer1::S3000' if ( $desc =~ /\bNMM\s+(281|3000|3030)/i ); # Catalyst 1900 series override $objtype = 'SNMP::Info::Layer2::C1900' if ( $desc =~ /catalyst/i and $desc =~ /\D19\d{2}/ ); # Catalyst 2900 and 3500XL (IOS) series override $objtype = 'SNMP::Info::Layer2::C2900' if ( $desc =~ /(C2900XL|C2950|C3500XL|C2940|CGESM|CIGESM)/i ); # Catalyst WS-C series override 2926,4k,5k,6k in Hybrid $objtype = 'SNMP::Info::Layer2::Catalyst' if ( $desc =~ /WS-C\d{4}/ ); # Catalyst 3550 / 3548 Layer2 only switches # Cisco 3400 w/ MetroBase Image $objtype = 'SNMP::Info::Layer3::C3550' if ( $desc =~ /(C3550|ME340x)/ ); # Cisco blade switches, CBS30x0 and CBS31x0 models with L2 only $objtype = 'SNMP::Info::Layer3::C6500' if ( $desc =~ /cisco/i and $desc =~ /CBS3[0-9A-Za-z]{3}/ ); # Cisco 2970 $objtype = 'SNMP::Info::Layer3::C6500' if ( $desc =~ /(C2970|C2960)/ ); # Cisco Small Business (300 500) series override # This is for enterprises(1).cisco(9).otherEnterprises(6).ciscosb(1) $objtype = 'SNMP::Info::Layer2::CiscoSB' if ( $soid =~ /^\.1\.3\.6\.1\.4\.1\.9\.6\.1/ ); # HP, older ProCurve models (1600, 2400, 2424m, 4000, 8000) $objtype = 'SNMP::Info::Layer2::HP4000' if $desc =~ /\b(J4093A|J4110A|J4120A|J4121A|J4122A|J4122B)\b/; # HP, Foundry OEM $objtype = 'SNMP::Info::Layer3::HP9300' if $desc =~ /\b(J4874A|J4138A|J4139A|J4840A|J4841A)\b/; # IBM BladeCenter 4-Port GB Ethernet Switch Module $objtype = 'SNMP::Info::Layer3::Dell' if ( $desc =~ /^IBM Gigabit Ethernet Switch Module$/ ); # Linksys 2024/2048 $objtype = 'SNMP::Info::Layer3::Dell' if ( $desc =~ /^(24|48)-Port 10\/100\/1000 Gigabit Switch (with |w\/)WebView$/ ); # Centillion ATM $objtype = 'SNMP::Info::Layer2::Centillion' if ( $desc =~ /MCP/ ); # BPS $objtype = 'SNMP::Info::Layer2::Baystack' if ( $desc =~ /Business\sPolicy\sSwitch/i ); # BayStack Numbered $objtype = 'SNMP::Info::Layer2::Baystack' if ( $desc =~ /^(BayStack|Ethernet\s+(Routing\s+)??Switch)\s[2345](\d){2,3}/i ); # Kentrox DataSMART DSU/CSU $objtype = 'SNMP::Info::Layer2::Kentrox' if ( $desc =~ /^DataSMART/i ); # Nortel Business Ethernet Switch $objtype = 'SNMP::Info::Layer2::Baystack' if ( $desc =~ /^Business Ethernet Switch\s[12]\d\d/i ); # Nortel AP 222X $objtype = 'SNMP::Info::Layer2::NAP222x' if ( $desc =~ /Access\s+Point\s+222/ ); # Orinoco $objtype = 'SNMP::Info::Layer2::Orinoco' if ( $desc =~ /(AP-\d{3}|WavePOINT)/ ); # Aironet - IOS $objtype = 'SNMP::Info::Layer2::Aironet' if ($desc =~ /\b(C1100|C1130|C1140|AP1200|C350|C1200|C1240|C1250)\b/ and $desc =~ /\bIOS\b/ ); # Aironet - non IOS $objtype = 'SNMP::Info::Layer3::Aironet' if ( $desc =~ /Cisco/ and $desc =~ /\D(BR500)\D/ ); # Airespace (WLC) Module $objtype = 'SNMP::Info::Layer2::Airespace' if ( $desc =~ /^Cisco Controller$/ ); #Nortel 2270 $objtype = 'SNMP::Info::Layer2::N2270' if ( $desc =~ /Nortel\s+(Networks\s+)??WLAN\s+-\s+Security\s+Switch/ ); # HP Virtual Connect blade switches $objtype = 'SNMP::Info::Layer2::HPVC' if ( $desc =~ /HP\sVC\s/ ); $objtype = 'SNMP::Info::Layer2::ZyXEL_DSLAM' if ( $desc =~ /8-port .DSL Module\(Annex .\)/i ); # Generic device classification based upon sysObjectID if ( ( $objtype eq 'SNMP::Info::Layer2' ) and ( defined($id) ) and ( exists( $l2sysoidmap{$id} ) ) ) { $objtype = $l2sysoidmap{$id}; } } elsif ( $info->has_layer(1) ) { $objtype = 'SNMP::Info::Layer1'; # Allied crap-o-hub $objtype = 'SNMP::Info::Layer1::Allied' if ( $desc =~ /allied/i ); $objtype = 'SNMP::Info::Layer1::Asante' if ( $desc =~ /asante/i ); # Bay Hub $objtype = 'SNMP::Info::Layer1::Bayhub' if ( $desc =~ /\bNMM.*Agent/ ); $objtype = 'SNMP::Info::Layer1::Bayhub' if ( $desc =~ /\bBay\s*Stack.*Hub/i ); # Synoptics Hub # This will override Bay Hub only for specific devices supported # by this class $objtype = 'SNMP::Info::Layer1::S3000' if ( $desc =~ /\bNMM\s+(281|3000|3030)/i ); # Generic device classification based upon sysObjectID if ( ( $objtype eq 'SNMP::Info::Layer1' ) and ( defined($id) ) and ( exists( $l1sysoidmap{$id} ) ) ) { $objtype = $l1sysoidmap{$id}; } } # These devices don't claim to have Layer1-3 but we like em anyways. else { $objtype = 'SNMP::Info::Layer2::ZyXEL_DSLAM' if ( $desc =~ /8-port .DSL Module\(Annex .\)/i ); # Aruba wireless switches $objtype = 'SNMP::Info::Layer3::Aruba' if ( $desc =~ /(ArubaOS|AirOS)/ ); # Alcatel-Lucent branded Aruba $objtype = 'SNMP::Info::Layer3::Aruba' if ( $desc =~ /^AOS-W/ ); # Cisco PIX $objtype = 'SNMP::Info::Layer3::Cisco' if ( $desc =~ /Cisco PIX Security Appliance/i ); # Cisco ASA, older version which doesn't report layer 3 functionality $objtype = 'SNMP::Info::Layer3::CiscoASA' if ( $desc =~ /Cisco Adaptive Security Appliance/i ); # HP Virtual Connect blade switches $objtype = 'SNMP::Info::Layer2::HPVC' if ( $desc =~ /HP\sVC\s/ ); # Nortel (Trapeze) WSS 2300 Series $objtype = 'SNMP::Info::Layer2::NWSS2300' if ( $desc =~ /^(Nortel\s)??Wireless\sSecurity\sSwitch\s23[568][012]\b/); # Cisco IPS, older version which doesn't report layer 3 functionality $objtype = 'SNMP::Info::Layer7::CiscoIPS' if ( $soid =~ /\.1\.3\.6\.1\.4\.1\.9\.1\.1545/i ); # Generic device classification based upon sysObjectID if ( defined($id) and $objtype eq 'SNMP::Info') { if ( defined $l3sysoidmap{$id} ) { $objtype = $l3sysoidmap{$id}; } elsif ( defined $l2sysoidmap{$id}) { $objtype = $l2sysoidmap{$id}; } elsif ( defined $l7sysoidmap{$id}) { $objtype = $l7sysoidmap{$id}; } elsif ($info->has_layer(7)) { $objtype = 'SNMP::Info::Layer7' } } } return $objtype; } =item $info->error(no_clear) Returns Error message if there is an error, or undef if there is not. Reading the error will clear the error unless you set the no_clear flag. =cut sub error { my $self = shift; my $no_clear = shift; my $err = $self->{error}; $self->{error} = undef unless defined $no_clear and $no_clear; return $err; } =item $info->has_layer(3) Returns non-zero if the device has the supplied layer in the OSI Model Returns if the device doesn't support the layers() call. =cut sub has_layer { my $self = shift; my $check_for = shift; my $layers = $self->layers(); return unless defined $layers; return unless length($layers); return substr( $layers, 8 - $check_for, 1 ); } =item $info->snmp_comm() Returns SNMP Community string used in connection. =cut sub snmp_comm { my $self = shift; if ( $self->{snmp_ver} == 3 ) { return $self->{snmp_user}; } else { return $self->{snmp_comm}; } } =item $info->snmp_ver() Returns SNMP Version used for this connection =cut sub snmp_ver { my $self = shift; return $self->{snmp_ver}; } =item $info->specify() Returns an object of a more-specific subclass. my $info = new SNMP::Info(...); # Returns more specific object type $info = $info->specific(); Usually this method is called internally from new(AutoSpecify => 1) See device_type() entry for how a subclass is chosen. =cut sub specify { my $self = shift; my $device_type = $self->device_type(); unless ( defined $device_type ) { $self->error_throw( "SNMP::Info::specify() - Could not get info from device"); return; } return $self if $device_type eq 'SNMP::Info'; # Load Subclass # By evaling a string the contents of device_type now becomes a bareword. eval "require $device_type;"; ## no critic if ($@) { croak "SNMP::Info::specify() Loading $device_type Failed. $@\n"; } my $args = $self->args(); my $session = $self->session(); my $sub_obj = $device_type->new( %$args, 'Session' => $session, 'AutoSpecify' => 0 ); unless ( defined $sub_obj ) { $self->error_throw( "SNMP::Info::specify() - Could not connect with new class ($device_type)" ); return $self; } $self->debug() and print "SNMP::Info::specify() - Changed Class to $device_type.\n"; return $sub_obj; } =item $info->cisco_comm_indexing() Returns 0. Is an overridable method used for vlan indexing for snmp calls on certain Cisco devices. See L =cut sub cisco_comm_indexing { return 0; } =back =head2 Globals (Scalar Methods) These are methods to return scalar data from RFC1213. Some subset of these is probably available for any network device that speaks SNMP. =over =item $info->uptime() Uptime in hundredths of seconds since device became available. (C) =item $info->contact() (C) =item $info->name() (C) =item $info->location() (C) =item $info->layers() This returns a binary encoded string where each digit represents a layer of the OSI model served by the device. eg: 01000010 means layers 2 (physical) and 7 (Application) are served. Note: This string is 8 digits long. See $info->has_layer() (C) =item $info->ports() Number of interfaces available on this device. Not too useful as the number of SNMP interfaces usually does not correspond with the number of physical ports (C) =item $info->ipforwarding() The indication of whether the entity is acting as an IP gateway Returns either forwarding or not-forwarding (C) =back =head2 Table Methods Each of these methods returns a hash_reference to a hash keyed on the interface index in SNMP. Example : $info->interfaces() might return { '1.12' => 'FastEthernet/0', '2.15' => 'FastEthernet/1', '9.99' => 'FastEthernet/2' } The key is what you would see if you were to do an snmpwalk, and in some cases changes between reboots of the network device. =head2 Partial Table Fetches If you want to get only a part of an SNMP table or a single instance from the table and you know the IID for the part of the table that you want, you can specify it in the call: $local_routes = $info->ipr_route('192.168.0'); This will only fetch entries in the table that start with C<192.168.0>, which in this case are routes on the local network. Remember that you must supply the partial IID (a numeric OID). Partial table results are not cached. =head2 Interface Information =over =item $info->interfaces() This methods is overridden in each subclass to provide a mapping between the Interface Table Index (iid) and the physical port name. =item $info->if_ignore() Returns a reference to a hash where key values that exist are interfaces to ignore. Ignored interfaces are ones that are usually not physical ports or Virtual Lans (VLANs) such as the Loopback interface, or the CPU interface. =cut sub if_ignore { my %nothing; return \%nothing; } =item $info->bulkwalk_no() Returns 0. Is an overridable method used for turn off bulkwalk for the device class. =cut sub bulkwalk_no { return 0; } =item $info->i_index() Default SNMP IID to Interface index. (C) =item $info->i_description() Description of the interface. Usually a little longer single word name that is both human and machine friendly. Not always. (C) =item $info->i_type() Interface type, such as Vlan, Ethernet, Serial (C) =item $info->i_mtu() INTEGER. Interface MTU value. (C) =item $info->i_speed() Speed of the link, human format. See munge_speed() later in document for details. (C, C if necessary) =cut sub i_speed { my $info = shift; my $partial = shift; my $i_speed = $info->orig_i_speed($partial); my $i_speed_high = undef; foreach my $i ( keys %$i_speed ) { if ( $i_speed->{$i} eq "4294967295" ) { $i_speed_high = $info->i_speed_high($partial) unless defined($i_speed_high); $i_speed->{$i} = $i_speed_high->{$i} if ( $i_speed_high->{$i} ); } } return $i_speed; } =item $info->i_speed_raw() Speed of the link in bits per second without munging. If i_speed_high is available it will be used and multiplied by 1_000_000. (C, C if necessary) =cut sub i_speed_raw { my $info = shift; my $partial = shift; # remove the speed formating my $munge_i_speed = delete $info->{munge}{i_speed}; # also for highspeed interfaces e.g. TenGigabitEthernet my $munge_i_speed_high = delete $info->{munge}{i_speed_high}; my $i_speed_raw = $info->orig_i_speed($partial); my $i_speed_high = undef; foreach my $i ( keys %$i_speed_raw ) { if ( $i_speed_raw->{$i} eq "4294967295" ) { $i_speed_high = $info->i_speed_high($partial) unless defined($i_speed_high); $i_speed_raw->{$i} = ( $i_speed_high->{$i} * 1_000_000 ) if ( $i_speed_high->{$i} ); } } # restore the speed formating $info->{munge}{i_speed} = $munge_i_speed; $info->{munge}{i_speed_high} = $munge_i_speed_high; return $i_speed_raw; } =item $info->i_speed_high() Speed of a high-speed link, human format. See munge_highspeed() later in document for details. You should not need to call this directly, as i_speed() will call it if it needs to. (C) =item $info->i_mac() MAC address of the interface. Note this is just the MAC of the port, not anything connected to it. (C) =item $info->i_up() Link Status of the interface. Typical values are 'up' and 'down'. (C) =item $info->i_up_admin() Administrative status of the port. Typical values are 'enabled' and 'disabled'. (C) =item $info->i_lastchange() The value of C when this port last changed states (up,down). (C) =item $info->i_name() Interface Name field. Supported by a smaller subset of devices, this fields is often human set. (C) =item $info->i_alias() Interface Name field. For certain devices this is a more human friendly form of i_description(). For others it is a human set field like i_name(). (C) =back =head2 Interface Statistics =over =item $info->i_octet_in(), $info->i_octets_out(), $info->i_octet_in64(), $info->i_octets_out64() Bandwidth. Number of octets sent/received on the interface including framing characters. 64 bit version may not exist on all devices. NOTE: To manipulate 64 bit counters you need to use Math::BigInt, since the values are too large for a normal Perl scalar. Set the global $SNMP::Info::BIGINT to 1 , or pass the BigInt value to new() if you want SNMP::Info to do it for you. (C) (C) (C) (C) =item $info->i_errors_in(), $info->i_errors_out() Number of packets that contained an error preventing delivery. See C for more info. (C) (C) =item $info->i_pkts_ucast_in(), $info->i_pkts_ucast_out(), $info->i_pkts_ucast_in64(), $info->i_pkts_ucast_out64() Number of packets not sent to a multicast or broadcast address. 64 bit version may not exist on all devices. (C) (C) (C) (C) =item $info->i_pkts_nucast_in(), $info->i_pkts_nucast_out(), Number of packets sent to a multicast or broadcast address. These methods are deprecated by i_pkts_multi_in() and i_pkts_bcast_in() according to C. Actual device usage may vary. (C) (C) =item $info->i_pkts_multi_in() $info->i_pkts_multi_out(), $info->i_pkts_multi_in64(), $info->i_pkts_multi_out64() Number of packets sent to a multicast address. 64 bit version may not exist on all devices. (C) (C) (C) (C) =item $info->i_pkts_bcast_in() $info->i_pkts_bcast_out(), $info->i_pkts_bcast_in64() $info->i_pkts_bcast_out64() Number of packets sent to a broadcast address on an interface. 64 bit version may not exist on all devices. (C) (C) (C) (C) =item $info->i_discards_in() $info->i_discards_out() "The number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being deliverable to a higher-layer protocol. One possible reason for discarding such a packet could be to free up buffer space." (C) (C) (C) =item $info->i_bad_proto_in() "For packet-oriented interfaces, the number of packets received via the interface which were discarded because of an unknown or unsupported protocol. For character-oriented or fixed-length interfaces that support protocol multiplexing the number of transmission units received via the interface which were discarded because of an unknown or unsupported protocol. For any interface that does not support protocol multiplexing, this counter will always be 0." (C) =item $info->i_qlen_out() "The length of the output packet queue (in packets)." (C) =item $info->i_specific() See C for full description (C) =back =head2 IP Address Table Each entry in this table is an IP address in use on this device. Usually this is implemented in Layer3 Devices. =over =item $info->ip_index() Maps the IP Table to the IID (C) =item $info->ip_table() Maps the Table to the IP address (C) =item $info->ip_netmask() Gives netmask setting for IP table entry. (C) =item $info->ip_broadcast() Gives broadcast address for IP table entry. (C) =back =head2 IP Routing Table =over =item $info->ipr_route() The route in question. A value of 0.0.0.0 is the default gateway route. (C) =item $info->ipr_if() The interface (IID) that the route is on. Use interfaces() to map. (C) =item $info->ipr_1() Primary routing metric for this route. (C) =item $info->ipr_2() If metrics are not used, they should be set to -1 (C) =item $info->ipr_3() (C) =item $info->ipr_4() (C) =item $info->ipr_5() (C) =item $info->ipr_dest() From RFC1213: "The IP address of the next hop of this route. (In the case of a route bound to an interface which is realized via a broadcast media, the value of this field is the agent's IP address on that interface.)" (C) =item $info->ipr_type() From RFC1213: other(1), -- none of the following invalid(2), -- an invalidated route -- route to directly direct(3), -- connected (sub-)network -- route to a non-local indirect(4) -- host/network/sub-network "The type of route. Note that the values direct(3) and indirect(4) refer to the notion of direct and indirect routing in the IP architecture. Setting this object to the value invalid(2) has the effect of invalidating the corresponding entry in the ipRouteTable object. That is, it effectively disassociates the destination identified with said entry from the route identified with said entry. It is an implementation-specific matter as to whether the agent removes an invalidated entry from the table. Accordingly, management stations must be prepared to receive tabular information from agents that corresponds to entries not currently in use. Proper interpretation of such entries requires examination of the relevant ipRouteType object." (C) =item $info->ipr_proto() From RFC1213: other(1), -- none of the following -- non-protocol information, -- e.g., manually configured local(2), -- entries -- set via a network netmgmt(3), -- management protocol -- obtained via ICMP, icmp(4), -- e.g., Redirect -- the remaining values are -- all gateway routing -- protocols egp(5), ggp(6), hello(7), rip(8), is-is(9), es-is(10), ciscoIgrp(11), bbnSpfIgp(12), ospf(13), bgp(14) (C) =item $info->ipr_age() Seconds since route was last updated or validated. (C) =item $info->ipr_mask() Subnet Mask of route. 0.0.0.0 for default gateway. (C) =item $info->ipr_info() Reference to MIB definition specific to routing protocol. (C) =back =head2 Topology Information Based upon the manufacturer and software version devices may support some combination of Layer 2 topology protocol information. SNMP::Info supports querying Link Layer Discovery Protocol (LLDP), Cisco Discovery Protocol (CDP), SynOptics/Bay/Nortel/Avaya Network Management Protocol (SONMP), Foundry/Brocade Discovery Protocol (FDP), Extreme Discovery Protocol (EDP), and Alcatel Mapping Adjacency Protocol (AMAP). For protocol specific information and implementation: =over =item LLDP: See L for details. =item CDP: See L for details. =item SONMP: See L for details. =item FDP: See L for details. =item EDP: See L for details. =item AMAP: See L for details. =back =head3 Topology Capabilities =over =item $info->has_topo() Reports Layer 2 topology protocols which are supported and running on a device. Returns either a reference to an array of protocols, possible values being: C, C, C, C, C, C or C if no protocols are supported or running. =back =cut sub has_topo { my $self = shift; my @topo_cap; push( @topo_cap, 'lldp' ) if ( $self->can('hasLLDP') && $self->hasLLDP() ); push( @topo_cap, 'cdp' ) if $self->can('hasCDP') && $self->hasCDP(); push( @topo_cap, 'sonmp' ) if $self->can('hasSONMP') && $self->hasSONMP(); push( @topo_cap, 'fdp' ) if $self->can('hasFDP') && $self->hasFDP(); push( @topo_cap, 'edp' ) if $self->can('hasEDP') && $self->hasEDP(); push( @topo_cap, 'amap' ) if $self->can('hasAMAP') && $self->hasAMAP(); if (@topo_cap) { return \@topo_cap; } else { return; } } sub _get_topo_data { my $self = shift; my $partial = shift; my $topo_cap = shift; my $method = shift; return unless $method =~ /(ip|if|port|id|platform|cap)/; my %t_data; foreach my $proto (@$topo_cap) { next unless $proto =~ /(lldp|cdp|sonmp|fdp|edp|amap)/; my $method_name = "$proto" . "_$method"; my $cdp = $self->$method_name($partial) || {}; foreach my $iid ( keys %$cdp ) { my $ip = $cdp->{$iid}; next unless defined $ip; $t_data{$iid} = $ip; } } return \%t_data; } =head3 Common Topology Table Information The common topology table methods below will query the device for information from the specified topology protocols and return a single hash combining all information. As a result, there may be identical topology information returned from the two protocols causing duplicate entries. It is the calling program's responsibility to identify any duplicate entries and remove duplicates if necessary. If it is necessary to understand which protocol provided the information, utilize the protocol specific methods directly rather than the generic methods. The methods support partial table fetches by providing a partial as the first argument. If a reference to an array is provided as the second argument, those protocols will be queried for information. The supported array values are: C, C, C, C, C, C. If nothing is passed in as the second argument, the methods will call has_topo() to determine supported and running topology protocols on the device. =over =item $info->c_ip(partial, topology_protocol_arrayref) Returns reference to hash. Key: iid, Value: remote IPv4 address If multiple entries exist with the same local port, c_if(), with the same IPv4 address, c_ip(), it may be a duplicate entry. If multiple entries exist with the same local port, c_if(), with different IPv4 addresses, c_ip(), there is either a device in between two or more devices utilizing a different topology protocol or multiple devices which are not directly connected. Use the protocol specific methods to dig deeper. =cut sub c_ip { my $self = shift; my $partial = shift; my $topo_cap = shift; # Default to old behavior if not called with topo_cap if ( !$topo_cap ) { my $topo_test = $self->has_topo(); if ($topo_test) { $topo_cap = $topo_test; } else { return; } } return _get_topo_data ($self, $partial, $topo_cap, 'ip'); } =item $info->c_if(partial, topology_protocol_arrayref) Returns reference to hash. Key: iid, Value: local device port (interfaces) =cut sub c_if { my $self = shift; my $partial = shift; my $topo_cap = shift; # Default to old behavior if not called with topo_cap if ( !$topo_cap ) { my $topo_test = $self->has_topo(); if ($topo_test) { $topo_cap = $topo_test; } else { return; } } return _get_topo_data ($self, $partial, $topo_cap, 'if'); } =item $info->c_port(partial, topology_protocol_arrayref) Returns reference to hash. Key: iid, Value: remote port (interfaces) =cut sub c_port { my $self = shift; my $partial = shift; my $topo_cap = shift; # Default to old behavior if not called with topo_cap if ( !$topo_cap ) { my $topo_test = $self->has_topo(); if ($topo_test) { $topo_cap = $topo_test; } else { return; } } return _get_topo_data ($self, $partial, $topo_cap, 'port'); } =item $info->c_id(partial, topology_protocol_arrayref) Returns reference to hash. Key: iid, Value: string value used to identify the chassis component associated with the remote system. Note: SONMP does not return this information. =cut sub c_id { my $self = shift; my $partial = shift; my $topo_cap = shift; # Default to old behavior if not called with topo_cap if ( !$topo_cap ) { my $topo_test = $self->has_topo(); if ($topo_test) { $topo_cap = $topo_test; } else { return; } } return _get_topo_data ($self, $partial, $topo_cap, 'id'); } =item $info->c_platform(partial, topology_protocol_arrayref) Returns reference to hash. Key: iid, Value: Remote Device Type Note: EDP does not provide this information. LLDP uses (C) or C as the closest match. =cut sub c_platform { my $self = shift; my $partial = shift; my $topo_cap = shift; # Default to old behavior if not called with topo_cap if ( !$topo_cap ) { my $topo_test = $self->has_topo(); if ($topo_test) { $topo_cap = $topo_test; } else { return; } } return _get_topo_data ($self, $partial, $topo_cap, 'platform'); } =item $info->c_cap(partial, topology_protocol_arrayref) Returns reference to hash of arrays. Key: iid, Value: Array of capabilities supported by the device. See the specific protocol class for string values which could be elements within the array. Note: Only CDP and LLDP support this method. =cut sub c_cap { my $self = shift; my $partial = shift; my $topo_cap = shift; # Default to old behavior if not called with topo_cap if ( !$topo_cap ) { my $topo_test = $self->has_topo(); if ($topo_test) { $topo_cap = $topo_test; } else { return; } } return _get_topo_data ($self, $partial, $topo_cap, 'cap'); } =back =head1 SETTING DATA VIA SNMP This section explains how to use SNMP::Info to do SNMP Set operations. =over =item $info->set_METHOD($value) Sets the global METHOD to value. Assumes that iid is .0 Returns if failed, or the return value from SNMP::Session::set() (snmp_errno) $info->set_location("Here!"); =item $info->set_METHOD($value,$iid) Table Methods. Set iid of method to value. Returns if failed, or the return value from SNMP::Session::set() (snmp_errno) # Disable a port administratively my %if_map = reverse %{$info->interfaces()} $info->set_i_up_admin('down', $if_map{'FastEthernet0/0'}) or die "Couldn't disable the port. ",$info->error(1); =back NOTE: You must be connected to your device with a C community string in order for set operations to work. NOTE: This will only set data listed in %FUNCS and %GLOBALS. For data acquired from overridden methods (subroutines) specific set_METHOD() subroutines will need to be added if they haven't been already. =head1 Quiet Mode SNMP::Info will not chirp anything to STDOUT unless there is a serious error (in which case it will probably die). To get lots of debug info, set the Debug flag when calling new() or call $info->debug(1); When calling a method check the return value. If the return value is undef then check $info->error() Beware, calling $info->error() clears the error. my $name = $info->name() or die "Couldn't get sysName!" . $name->error(); =head1 EXTENDING SNMP::INFO To support a new class (vendor or platform) of device, add a Perl package with the data structures and methods listed below. If this seems a little scary, then the SNMP::Info developers are usually happy to accept the SNMP data from your device and make an attempt at the class themselves. Usually a "beta" release will go to CPAN for you to verify the implementation. =head2 Gathering MIB data for SNMP::Info Developers The preference is to open a feature request in the SourceForge project. This allows all developers to have visibility into the request. Please include pointers to the applicable platform MIBs. For development we will need an C of the device. There is a tool now included in the SNMP::Info distribution to help with this task, although you'll most likely need to download the distribution from CPAN as it's included in the "C" directory. The utility is named C. Run it with a command line like: ./make_snmpdata.pl -c community -i -d device_ip \ -m /home/netdisco-mibs/rfc:/home/netdisco-mibs/net-snmp:/home/netdisco-mibs/dir3 \ SNMPv2-MIB IF-MIB EtherLike-MIB BRIDGE-MIB Q-BRIDGE-MIB ENTITY-MIB \ POWER-ETHERNET-MIB IPV6-MIB LLDP-MIB DEVICE-SPECIFIC-MIB-NAME(s) > output.txt This will print to the file every MIB entry with data in a format that the developers can use to emulate read operations without needing access to the device. Preference would be to mask any sensitive data in the output, zip the file, and upload as an attachment to the Sourceforge tracker. However, if you do not feel comfortable uploading the output to the tracker you could e-mail it to the developer that has claimed the ticket. =head2 Data Structures required in new Subclass A class inheriting this class must implement these data structures : =over =item $INIT Used to flag if the MIBs have been loaded yet. =cut $INIT = 0; =item %GLOBALS Contains a hash in the form ( method_name => SNMP MIB leaf name ) These are scalar values such as name, uptime, etc. To resolve MIB leaf name conflicts between private MIBs, you may prefix the leaf name with the MIB replacing each - (dash) and : (colon) with an _ (underscore). For example, ALTEON_TIGON_SWITCH_MIB__agSoftwareVersion would be used as the hash value instead of the net-snmp notation ALTEON-TIGON-SWITCH-MIB::agSoftwareVersion. When choosing the name for the methods, be aware that other new Sub Modules might inherit this one to get it's features. Try to choose a prefix for methods that will give it's own name space inside the SNMP::Info methods. =cut %GLOBALS = ( # from SNMPv2-MIB 'id' => 'sysObjectID', 'description' => 'sysDescr', 'uptime' => 'sysUpTime', 'contact' => 'sysContact', 'name' => 'sysName', 'location' => 'sysLocation', 'layers' => 'sysServices', 'ports' => 'ifNumber', 'ipforwarding' => 'ipForwarding', ); =item %FUNCS Contains a hash in the form ( method_name => SNMP MIB leaf name) These are table entries, such as the C To resolve MIB leaf name conflicts between private MIBs, you may prefix the leaf name with the MIB replacing each - (dash) and : (colon) with an _ (underscore). For example, ALTEON_TS_PHYSICAL_MIB__agPortCurCfgPortName would be used as the hash value instead of the net-snmp notation ALTEON-TS-PHYSICAL-MIB::agPortCurCfgPortName. =cut %FUNCS = ( 'interfaces' => 'ifIndex', 'i_name' => 'ifName', # IF-MIB::IfEntry 'i_index' => 'ifIndex', 'i_description' => 'ifDescr', 'i_type' => 'ifType', 'i_mtu' => 'ifMtu', 'i_speed' => 'ifSpeed', 'i_mac' => 'ifPhysAddress', 'i_up_admin' => 'ifAdminStatus', 'i_up' => 'ifOperStatus', 'i_lastchange' => 'ifLastChange', 'i_octet_in' => 'ifInOctets', 'i_pkts_ucast_in' => 'ifInUcastPkts', 'i_pkts_nucast_in' => 'ifInNUcastPkts', 'i_discards_in' => 'ifInDiscards', 'i_errors_in' => 'ifInErrors', 'i_bad_proto_in' => 'ifInUnknownProtos', 'i_octet_out' => 'ifOutOctets', 'i_pkts_ucast_out' => 'ifOutUcastPkts', 'i_pkts_nucast_out' => 'ifOutNUcastPkts', 'i_discards_out' => 'ifOutDiscards', 'i_errors_out' => 'ifOutErrors', 'i_qlen_out' => 'ifOutQLen', 'i_specific' => 'ifSpecific', # IF-MIB::IfStackTable 'i_stack_status' => 'ifStackStatus', # IP Address Table 'ip_index' => 'ipAdEntIfIndex', 'ip_table' => 'ipAdEntAddr', 'ip_netmask' => 'ipAdEntNetMask', 'ip_broadcast' => 'ipAdEntBcastAddr', # ifXTable - Extension Table 'i_speed_high' => 'ifHighSpeed', 'i_pkts_multi_in' => 'ifInMulticastPkts', 'i_pkts_multi_out' => 'ifOutMulticastPkts', 'i_pkts_bcast_in' => 'ifInBroadcastPkts', 'i_pkts_bcast_out' => 'ifOutBroadcastPkts', 'i_octet_in64' => 'ifHCInOctets', 'i_octet_out64' => 'ifHCOutOctets', 'i_pkts_ucast_in64' => 'ifHCInUcastPkts', 'i_pkts_ucast_out64' => 'ifHCOutUcastPkts', 'i_pkts_multi_in64' => 'ifHCInMulticastPkts', 'i_pkts_multi_out64' => 'ifHCOutMulticastPkts', 'i_pkts_bcast_in64' => 'ifHCInBroadcastPkts', 'i_pkts_bcast_out64' => 'ifHCOutBroadcastPkts', 'i_alias' => 'ifAlias', # IP Routing Table 'ipr_route' => 'ipRouteDest', 'ipr_if' => 'ipRouteIfIndex', 'ipr_1' => 'ipRouteMetric1', 'ipr_2' => 'ipRouteMetric2', 'ipr_3' => 'ipRouteMetric3', 'ipr_4' => 'ipRouteMetric4', 'ipr_5' => 'ipRouteMetric5', 'ipr_dest' => 'ipRouteNextHop', 'ipr_type' => 'ipRouteType', 'ipr_proto' => 'ipRouteProto', 'ipr_age' => 'ipRouteAge', 'ipr_mask' => 'ipRouteMask', 'ipr_info' => 'ipRouteInfo', ); =item %MIBS A list of each mib needed. ('MIB-NAME' => 'itemToTestForPresence') The value for each entry should be a MIB object to check for to make sure that the MIB is present and has loaded correctly. $info->init() will throw an exception if a MIB does not load. =cut %MIBS = ( # The "main" MIBs are automagically loaded in Net-SNMP now. ); =item %MUNGE A map between method calls (from %FUNCS or %GLOBALS) and subroutine methods. The subroutine called will be passed the data as it gets it from SNMP and it should return that same data in a more human friendly format. Sample %MUNGE: (my_ip => \&munge_ip, my_mac => \&munge_mac, my_layers => \&munge_dec2bin ) =cut %MUNGE = ( 'ip' => \&munge_ip, 'mac' => \&munge_mac, 'i_mac' => \&munge_mac, 'layers' => \&munge_dec2bin, 'i_speed' => \&munge_speed, 'i_speed_high' => \&munge_highspeed, 'i_octet_in64' => \&munge_counter64, 'i_octet_out64' => \&munge_counter64, 'i_pkts_ucast_in64' => \&munge_counter64, 'i_pkts_ucast_out64' => \&munge_counter64, 'i_pkts_mutli_in64' => \&munge_counter64, 'i_pkts_multi_out64' => \&munge_counter64, 'i_pkts_bcast_in64' => \&munge_counter64, 'i_pkts_bcast_out64' => \&munge_counter64, 'i_up' => \&munge_i_up, ); =back =head2 Sample Subclass Let's make a sample Layer 2 Device subclass. This class will inherit the Cisco Vlan module as an example. ----------------------- snip -------------------------------- # SNMP::Info::Layer2::Sample package SNMP::Info::Layer2::Sample; $VERSION = 0.1; use strict; use Exporter; use SNMP::Info::Layer2; use SNMP::Info::CiscoVTP; @SNMP::Info::Layer2::Sample::ISA = qw/SNMP::Info::Layer2 SNMP::Info::CiscoVTP Exporter/; @SNMP::Info::Layer2::Sample::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/; %MIBS = (%SNMP::Info::Layer2::MIBS, %SNMP::Info::CiscoVTP::MIBS, 'SUPER-DOOPER-MIB' => 'supermibobject' ); %GLOBALS = (%SNMP::Info::Layer2::GLOBALS, %SNMP::Info::CiscoVTP::GLOBALS, 'name' => 'supermib_supername', 'favorite_color' => 'supermib_fav_color_object', 'favorite_movie' => 'supermib_fav_movie_val' ); %FUNCS = (%SNMP::Info::Layer2::FUNCS, %SNMP::Info::CiscoVTP::FUNCS, # Super Dooper MIB - Super Hero Table 'super_hero_index' => 'SuperHeroIfIndex', 'super_hero_name' => 'SuperHeroIfName', 'super_hero_powers' => 'SuperHeroIfPowers' ); %MUNGE = (%SNMP::Info::Layer2::MUNGE, %SNMP::Info::CiscoVTP::MUNGE, 'super_hero_powers' => \&munge_powers ); # OverRide uptime() method from %SNMP::Info::GLOBALS sub uptime { my $sample = shift; my $name = $sample->name(); # this is silly but you get the idea return '600' if defined $name ; } # Create our own munge function sub munge_powers { my $power = shift; # Take the returned obscure value and return something useful. return 'Fire' if $power =~ /reallyhot/i; return 'Ice' if $power =~ /reallycold/i; # Else return $power; } # Copious Documentation here!!! =head1 NAME =head1 AUTHOR =head1 SYNOPSIS =head1 DESCRIPTION =head2 Inherited Classes =head2 Required MIBs =head1 GLOBALS =head2 Overrides =head1 TABLE METHODS =head2 Overrides =cut 1; # don't forget this line ----------------------- snip -------------------------------- Be sure and send the debugged version to snmp-info-users@lists.sourceforge.net to be included in the next version of SNMP::Info. =head1 SNMP::INFO INTERNALS =head2 Object Namespace Internal data is stored with bareword keys. For example $info->{debug} SNMP Data is stored or marked cached with keys starting with an underscore. For example $info->{_name} is the cache for $info->name(). Cached Table data is stored in $info->store() and marked cached per above. =head2 Package Globals These set the default value for an object upon creation. =over =item $DEBUG Default 0. Sends copious debug info to stdout. This global sets the object's debug status in new() unless 'Debug' argument passed in new(). Change objects' debug status with $info->debug(). =cut $DEBUG = 0; =item $BIGINT Default 0. Set to true to have 64 bit counters return Math::BigInt objects instead of scalar string values. See note under Interface Statistics about 64 bit values. =cut $BIGINT = 0; =item $NOSUCH Default 1. Set to false to disable RetryNoSuch option for SNMP::Session. Or see method in new() to do it on an object scope. =cut $NOSUCH = 1; =item $REPEATERS Default 20. MaxRepeaters for BULKWALK operations. See C for more info. Can change by passing L option in new() =cut $REPEATERS = 20; =back =head2 Data Munging Callback Subroutines =over =item munge_speed() Makes human friendly speed ratings using %SPEED_MAP %SPEED_MAP = ( '56000' => '56 kbps', '64000' => '64 kbps', '115000' => '115 kpbs', '1500000' => '1.5 Mbps', '1536000' => 'T1', '1544000' => 'T1', '2000000' => '2.0 Mbps', '2048000' => '2.048 Mbps', '3072000' => 'Dual T1', '3088000' => 'Dual T1', '4000000' => '4.0 Mbps', '10000000' => '10 Mbps', '11000000' => '11 Mbps', '20000000' => '20 Mbps', '16000000' => '16 Mbps', '16777216' => '16 Mbps', '44210000' => 'T3', '44736000' => 'T3', '45000000' => '45 Mbps', '45045000' => 'DS3', '46359642' => 'DS3', '51850000' => 'OC-1', '54000000' => '54 Mbps', '64000000' => '64 Mbps', '100000000' => '100 Mbps', '200000000' => '200 Mbps', '149760000' => 'ATM on OC-3', '155000000' => 'OC-3', '155519000' => 'OC-3', '155520000' => 'OC-3', '400000000' => '400 Mbps', '599040000' => 'ATM on OC-12', '622000000' => 'OC-12', '622080000' => 'OC-12', '1000000000' => '1.0 Gbps', '2000000000' => '2.0 Gbps', '2488000000' => 'OC-48', ) Note: high speed interfaces (usually 1 Gbps or faster) have their link speed in C. i_speed() automatically determines whether to use C or C; if the latter is used, the value is munged by munge_highspeed(). SNMP::Info can return speeds up to terabit levels this way. =cut %SPEED_MAP = ( '56000' => '56 kbps', '64000' => '64 kbps', '115000' => '115 kpbs', '1500000' => '1.5 Mbps', '1536000' => 'T1', '1544000' => 'T1', '2000000' => '2.0 Mbps', '2048000' => '2.048 Mbps', '3072000' => 'Dual T1', '3088000' => 'Dual T1', '4000000' => '4.0 Mbps', '10000000' => '10 Mbps', '11000000' => '11 Mbps', '20000000' => '20 Mbps', '16000000' => '16 Mbps', '16777216' => '16 Mbps', '44210000' => 'T3', '44736000' => 'T3', '45000000' => '45 Mbps', '45045000' => 'DS3', '46359642' => 'DS3', '51850000' => 'OC-1', '54000000' => '54 Mbps', '64000000' => '64 Mbps', '100000000' => '100 Mbps', '200000000' => '200 Mbps', '149760000' => 'ATM on OC-3', '155000000' => 'OC-3', '155519000' => 'OC-3', '155520000' => 'OC-3', '400000000' => '400 Mbps', '599040000' => 'ATM on OC-12', '622000000' => 'OC-12', '622080000' => 'OC-12', '1000000000' => '1.0 Gbps', '2000000000' => '2.0 Gbps', '2488000000' => 'OC-48', ); sub munge_speed { my $speed = shift; my $map = $SPEED_MAP{$speed}; #print " $speed -> $map " if (defined $map); return $map || $speed; } =item munge_highspeed() Makes human friendly speed ratings for C =cut sub munge_highspeed { my $speed = shift; my $fmt = "%d Mbps"; if ( $speed > 9999999 ) { $fmt = "%d Tbps"; $speed /= 1000000; } elsif ( $speed > 999999 ) { $fmt = "%.1f Tbps"; $speed /= 1000000.0; } elsif ( $speed > 9999 ) { $fmt = "%d Gbps"; $speed /= 1000; } elsif ( $speed > 999 ) { $fmt = "%.1f Gbps"; $speed /= 1000.0; } return sprintf( $fmt, $speed ); } =item munge_ip() Takes a binary IP and makes it dotted ASCII =cut sub munge_ip { my $ip = shift; return join( '.', unpack( 'C4', $ip ) ); } =item munge_mac() Takes an octet stream (HEX-STRING) and returns a colon separated ASCII hex string. =cut sub munge_mac { my $mac = shift; return unless defined $mac; return unless length $mac; $mac = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $mac ) ); return $mac if $mac =~ /^([0-9A-F][0-9A-F]:){5}[0-9A-F][0-9A-F]$/i; return; } =item munge_prio_mac() Takes an 2-byte octet stream (HEX-STRING) and returns a colon separated ASCII hex string. =cut sub munge_prio_mac { my $mac = shift; return unless defined $mac; return unless length $mac; $mac = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $mac ) ); return $mac if $mac =~ /^([0-9A-F][0-9A-F]:){7}[0-9A-F][0-9A-F]$/i; return; } =item munge_prio_port() Takes an 8-byte octet stream (HEX-STRING) and returns a colon separated ASCII hex string. =cut sub munge_prio_port { my $mac = shift; return unless defined $mac; return unless length $mac; $mac = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $mac ) ); return $mac if $mac =~ /^([0-9A-F][0-9A-F]:){1}[0-9A-F][0-9A-F]$/i; return; } =item munge_octet2hex() Takes a binary octet stream and returns an ASCII hex string =cut sub munge_octet2hex { my $oct = shift; return join( '', map { sprintf "%x", $_ } unpack( 'C*', $oct ) ); } =item munge_dec2bin() Takes a binary char and returns its ASCII binary representation =cut sub munge_dec2bin { my $num = shift; return unless defined $num; #return unless length($num); $num = unpack( "B32", pack( "N", $num ) ); # return last 8 characters only $num =~ s/.*(.{8})$/$1/; return $num; } =item munge_bits Takes a SNMP2 'BITS' field and returns the ASCII bit string =cut sub munge_bits { my $bits = shift; return unless defined $bits; return unpack( "B*", $bits ); } =item munge_counter64 If $BIGINT is set to true, then a Math::BigInt object is returned. See Math::BigInt for details. =cut sub munge_counter64 { my $counter = shift; return unless defined $counter; return $counter unless $BIGINT; my $bigint = Math::BigInt->new($counter); return $bigint; } =item munge_i_up Net-SNMP tends to load C first, and so ignores the updated enumeration for C in C. This munge handles the "newer" definitions for the enumeration in IF-MIB. TODO: Get the precedence of MIBs and overriding of MIB data in Net-SNMP figured out. Heirarchy/precendence of MIBS in SNMP::Info. =cut sub munge_i_up { my $i_up = shift; return unless defined $i_up; my %ifOperStatusMap = ( '4' => 'unknown', '5' => 'dormant', '6' => 'notPresent', '7' => 'lowerLayerDown' ); return $ifOperStatusMap{$i_up} || $i_up; } =item munge_port_list Takes an octet string representing a set of ports and returns a reference to an array of binary values each array element representing a port. If the element has a value of '1', then that port is included in the set of ports; the port is not included if it has a value of '0'. =cut sub munge_port_list { my $oct = shift; return unless defined $oct; my $list = [ split( //, unpack( "B*", $oct ) ) ]; return $list; } =item munge_null() Removes control characters from a string =cut # munge_null() - removes nulls (\0) and other control characters sub munge_null { my $text = shift || return; $text =~ s/[[:cntrl:]]//g; return $text; } =item munge_e_type() Takes an OID and return the object name if the right MIB is loaded. =cut sub munge_e_type { my $oid = shift; my $name = &SNMP::translateObj($oid); return $name if defined($name); return $oid; } =back =head2 Internally Used Functions =over =item $info->init() Used internally. Loads all entries in %MIBS. =cut sub init { my $self = shift; # Get MibDirs if provided my $mibdirs = $self->{mibdirs} || []; # SNMP::initMib and SNMP::addMibDirs both look for some initial MIBs # so if we are not using Net-SNMP configuration files we need to # specify where the MIBs are before those calls. # Ignore snmp.conf and snmp.local.conf files if IgnoreNetSNMPConf # specified local $ENV{'SNMPCONFPATH'} = '' if $self->{IgnoreNetSNMPConf}; # We need to provide MIBDIRS if we are not getting them from a # configuration file my $mibdir = join (':', @$mibdirs); local $ENV{'MIBDIRS'} = "$mibdir" if $self->{IgnoreNetSNMPConf}; SNMP::initMib; my $version = $SNMP::VERSION; my ( $major, $minor, $rev ) = split( '\.', $version ); if ( $major < 5 ) { # Seems to work under 4.2.0 } elsif ( $major == 5 and $minor == 0 and $rev < 2 ) { carp("Net-SNMP 5.0.1 seems to be rather buggy. Upgrade.\n"); # This is a bug in net-snmp 5.0.1 perl module # see http://groups.google.com/groups?th=47aed6bf7be6a0f5 SNMP::init_snmp("perl"); } foreach my $d (@$mibdirs) { next unless -d $d; print "SNMP::Info::init() - Adding new mibdir:$d\n" if $self->debug() > 1; SNMP::addMibDirs($d); } my $mibs = $self->mibs(); foreach my $mib ( keys %$mibs ) { #print "SNMP::Info::init() - Loading mib:$mib\n" if $self->debug(); SNMP::loadModules("$mib"); unless ( defined $SNMP::MIB{ $mibs->{$mib} } ) { croak "The $mib did not load. See README for $self->{class}\n"; } } return; } =item $info->args() Returns a reference to the argument hash supplied to SNMP::Session =cut sub args { my $self = shift; return $self->{args}; } =item $info->class() Returns the class name of the object. =cut sub class { my $self = shift; return $self->{class}; } =item $info->error_throw(error message) Stores the error message for use by $info->error() If $info->debug() is true, then the error message is carped too. =cut sub error_throw { my $self = shift; my $error = shift; return unless defined $error; $self->{error} = $error; if ( $self->debug() ) { $error =~ s/\n+$//; carp($error); } return; } =item $info->funcs() Returns a reference to the %FUNCS hash. =cut sub funcs { my $self = shift; return $self->{funcs}; } =item $info->globals() Returns a reference to the %GLOBALS hash. =cut sub globals { my $self = shift; return $self->{globals}; } =item $info->mibs() Returns a reference to the %MIBS hash. =cut sub mibs { my $self = shift; return $self->{mibs}; } =item $info->munge() Returns a reference of the %MUNGE hash. =cut sub munge { my $self = shift; return $self->{munge}; } =item $info->nosuch() Returns NoSuch value set or not in new() =cut sub nosuch { my $self = shift; return $self->{nosuch}; } =item $info->session() Gets or Sets the SNMP::Session object. =cut sub session { my $self = shift; $self->{sess} = $_[0] if @_; return $self->{sess}; } =item $info->store(new_store) Returns or sets hash store for Table functions. Store is a hash reference in this format : $info->store = { attribute => { iid => value , iid2 => value2, ... } }; =cut sub store { my $self = shift; $self->{store} = $_[0] if @_; return $self->{store}; } =item $info->_global() Used internally by AUTOLOAD to create dynamic methods from %GLOBALS or a single instance MIB Leaf node name from a loaded MIB. Example: $info->name() on the first call dispatches to AUTOLOAD() which calls $info->_global('name') creating the method name(). These methods return data as a scalar. =cut sub _global { my $method = shift; my $oid = shift; return sub {} if $method eq 'CARP_TRACE'; return sub { my $self = shift; my $sess = $self->session(); return unless defined $sess; my $load = $method =~ /^load/; my $raw = $method =~ /raw$/; my $attr = $method; $attr =~ s/^(load|orig)_//; $attr =~ s/_raw$//; # Return cached data unless loading # We now store in raw format so munge before returning # unless expecting raw data if ( exists $self->{"_$attr"} && !$load ) { my $val = $self->{"_$attr"}; if ( !$raw ) { return $self->_munge($attr, $val); } else{ return $val; } } if ( $self->{Offline} ) { $self->error_throw( "SNMP::Info::_global: Offline but $attr is not in cache\n" ); return; } if ( $self->debug() ) { # Let's get the MIB Module and leaf name along with the OID my $qual_leaf = SNMP::translateObj($oid,0,1) || ''; print "SNMP::Info::_global $method : $qual_leaf : $oid\n"; } my $val = $sess->get($oid); # Mark as gotten. Even if it fails below, we don't want to keep failing. $self->{"_$attr"} = undef; if ( $sess->{ErrorStr} ) { $self->error_throw( "SNMP::Info::_global($method) $sess->{ErrorStr}"); return; } if ( defined $val and $val eq 'NOSUCHOBJECT' ) { $self->error_throw("SNMP::Info::_global($method) NOSUCHOBJECT"); return; } if ( defined $val and $val eq 'NOSUCHINSTANCE' ) { $self->error_throw("SNMP::Info::_global($method) NOSUCHINSTANCE"); return; } # Save Cached Value $self->_cache($attr, $val); # Data Munging if ( !$raw ) { $val = $self->_munge($attr, $val); } return $val; } } =item $info->_set(attr,val,iid,type) Used internally by set_multi() to run an SNMP set command. When run clears attr cache. Attr can be passed as either a scalar or a reference to an array or array of arrays when used with set_multi(). Example: $info->set_name('dog',3) uses autoload to resolve to $info->_set('name','dog',3); =cut sub _set { my ( $self, $attr, $val, $iid, $type ) = @_; my $varbind_list_ref; if ( !ref($attr) ) { $varbind_list_ref = [ [ $attr, $iid, $val, $type ] ]; } elsif ( ref($attr) =~ /ARRAY/ ) { $varbind_list_ref = [$attr]; $varbind_list_ref = $attr if ref( $$attr[0] ) =~ /ARRAY/; } else { $self->error_throw( "SNMP::Info::_set($attr,$val) - Failed. Invalid argument for attr." ); } my $sess = $self->session(); return unless defined $sess; my $funcs = $self->funcs(); my $globals = $self->globals(); foreach my $var_list (@$varbind_list_ref) { my $list_attr = $var_list->[0]; my $list_iid = $var_list->[1]; my $list_val = $var_list->[2]; # Get rid of non-printable chars in $list_val for debug statements $list_val =~ s/\W//; # Instance is 0 for scalars without a supplied instance $var_list->[1] = $list_iid = defined $list_iid ? $list_iid : '0'; # Check if this method is from a sub or from the tables. if ( $self->can($list_attr) ) { $self->error_throw( "SNMP::Info::_set($list_attr,$list_val) - Failed. $list_attr is generated in a sub(). set_$list_attr sub required." ); # if sub set_attr() existed, we wouldn't have gotten this far. return; } # Lookup oid my $oid = undef; $oid = $list_attr if SNMP::translateObj($list_attr); $oid = $globals->{$list_attr} if defined $globals->{$list_attr}; $oid = $funcs->{$list_attr} if defined $funcs->{$list_attr}; unless ( defined $oid ) { $self->error_throw( "SNMP::Info::_set($list_attr,$list_val) - Failed to find $list_attr in \%GLOBALS or \%FUNCS or loaded MIB." ); return; } # Check for fully qualified attr if ( $oid =~ /__/ ) { $oid =~ s/__/::/; $oid =~ s/_/-/g; } $var_list->[0] = $oid; $self->debug() and print "SNMP::Info::_set $list_attr.$list_iid ($oid.$list_iid) = $list_val\n"; delete $self->{"_$list_attr"}; } my $rv = $sess->set($varbind_list_ref); if ( $sess->{ErrorStr} ) { $self->error_throw("SNMP::Info::_set $sess->{ErrorStr}"); return; } return $rv; } =item $info->_make_setter(val,iid) Used internally by AUTOLOAD to create dynamic methods from either %GLOBALS, %FUNCS, or a valid mib leaf from a loaded MIB which runs an SNMP set command. When run clears the attribute cache. Example: $info->set_name('dog',3) dispatches to autoload to resolve to $info->_set('name','dog',3) and _make_setter creates the set_name() method. =cut sub _make_setter { my $method = shift; my $oid = shift; return sub { my $self = shift; my $val = shift; my $iid = shift; my $set_oid = $oid; my $globals = $self->globals(); my $attr = $method; $attr =~ s/^set_//; # The only thing which may give us the iid in $oid should be # a %GLOBALS entry appended with a number. In that case strip it # from the OID and use it as $iid if ( defined $globals->{$attr} && $globals->{$attr} =~ /(\.\d+$)/ ) { $iid = $1; $set_oid =~ s/$iid//; } # If we don't have $iid now we should be a %GLOBALS entry or single # instance MIB leaf so default to zero $iid = defined $iid ? $iid : '.0'; # prepend dot if necessary to $iid $iid = ".$iid" unless $iid =~ /^\./; my $sess = $self->session(); return unless defined $sess; $set_oid .= "$iid"; $self->debug() and print "SNMP::Info::_set $method$iid ($set_oid) = $val\n"; delete $self->{"_$attr"}; my $rv = $sess->set( $set_oid, $val ); if ( $sess->{ErrorStr} ) { $self->error_throw("SNMP::Info::_set $sess->{ErrorStr}"); return; } return $rv; } } =item $info->set_multi(arrayref) Used to run an SNMP set command on several new values in the one request. Returns the result of $info->_set(method). Pass either a reference to a 4 element array [, , , ] or a reference to an array of 4 element arrays to specify multiple values. - One of the following forms: 1) leaf identifier (e.g., C<'sysContact'>) 2) An entry in either %FUNCS, %GLOBALS (e.g., 'contact') - The dotted-decimal, instance identifier. For scalar MIB objects use '0' - The SNMP data value being set (e.g., 'netdisco') - Optional as the MIB should be loaded. If one of the set assignments is invalid, then the request will be rejected without applying any of the new values - regardless of the order they appear in the list. Example: my $vlan_set = [ ['qb_v_untagged',"$old_vlan_id","$old_untagged_portlist"], ['qb_v_egress',"$new_vlan_id","$new_egress_portlist"], ['qb_v_egress',"$old_vlan_id","$old_egress_portlist"], ['qb_v_untagged',"$new_vlan_id","$new_untagged_portlist"], ['qb_i_vlan',"$port","$new_vlan_id"], ]; $info->set_multi($vlan_set); =cut sub set_multi { my $self = shift; return $self->_set(@_); } =item $info->load_all() Debugging routine. This does not include any overridden method or method implemented by subroutine. Runs $info->load_METHOD() for each entry in $info->funcs(); Returns $info->store() -- See store() entry. Note return value has changed since version 0.3 =cut sub load_all { my $self = shift; my $sess = $self->session(); return unless defined $sess; my $funcs = $self->funcs(); foreach my $attrib ( keys %$funcs ) { $attrib = "load_$attrib"; $self->$attrib(); } $self->{_all}++; return unless defined wantarray; return $self->store(); } =item $info->all() Runs $info->load_all() once then returns $info->store(); Use $info->load_all() to reload the data. Note return value has changed since version 0.3 =cut sub all { my $self = shift; my $sess = $self->session(); return unless defined $sess; $self->load_all() unless defined $self->{_all}; return $self->store(); } =item $info->_load_attr() Used internally by AUTOLOAD to create dynamic methods from %FUNCS or a MIB Leaf node name contained within a table of a loaded MIB. Supports partial table fetches and single instance table fetches. See L. These methods return data as a reference to a hash. =cut sub _load_attr { my $method = shift; my $oid = shift; return sub { my $self = shift; my $partial = shift; my $sess = $self->session(); return unless defined $sess; my $ver = $self->snmp_ver(); my $nosuch = $self->nosuch(); my $store = $self->store(); my $load = $method =~ /^load/; my $raw = $method =~ /raw$/; my $attr = $method; $attr =~ s/^(load|orig)_//; $attr =~ s/_raw$//; # Return cached data unless loading or partial # We now store in raw format so munge before returning # unless expecting raw data return $self->_show_attr($attr, $raw) if ( defined $self->{"_${attr}"} && !$load && !defined $partial ); if ( $self->{Offline} ) { $self->error_throw( "SNMP::Info::_load_atrr: Offline but $attr is not in cache\n" ); return; } # We want the qualified leaf name so that we can # specify the Module (MIB) in the case of private leaf naming # conflicts. Example: ALTEON-TIGON-SWITCH-MIB::agSoftwareVersion # and ALTEON-CHEETAH-SWITCH-MIB::agSoftwareVersion # Third argument to translateObj specifies the Module prefix my $qual_leaf = SNMP::translateObj($oid,0,1) || ''; # We still want just the leaf since a SNMP get in the case of a # partial fetch may strip the Module portion upon return. We need # the match to make sure we didn't leave the table during getnext # requests my ($leaf) = $qual_leaf =~ /::(\w+)$/; $self->debug() and print "SNMP::Info::_load_attr $method : $qual_leaf", defined $partial ? "($partial)" : '', " : $oid" , defined $partial ? ".$partial" : '', "\n"; my $var = new SNMP::Varbind( [$qual_leaf, $partial] ); # So devices speaking SNMP v.1 are not supposed to give out # data from SNMP2, but most do. Net-SNMP, being very precise # will tell you that the SNMP OID doesn't exist for the device. # They have a flag RetryNoSuch that is used for get() operations, # but not for getnext(). We set this flag normally, and if we're # using V1, let's try and fetch the data even if we get one of those. my $localstore = undef; my $errornum = 0; my %seen = (); my $vars = []; my $bulkwalk_no = $self->can('bulkwalk_no') ? $self->bulkwalk_no() : 0; my $bulkwalk_on = defined $self->{BulkWalk} ? $self->{BulkWalk} : 1; my $can_bulkwalk = $bulkwalk_on && !$bulkwalk_no; my $repeaters = $self->{BulkRepeaters} || $REPEATERS; my $bulkwalk = $can_bulkwalk && $ver != 1; my $loopdetect = defined $self->{LoopDetect} ? $self->{LoopDetect} : 1; if ( defined $partial ) { # Try a GET, in case the partial is a leaf OID. # Would like to only do this if we know the OID is # long enough; implementing that would require a # lot of MIB mucking. my $try = $sess->get($var); $errornum = $sess->{ErrorNum}; if ( defined($try) && $errornum == 0 && $try !~ /^NOSUCH/ ) { $var->[2] = $try; $vars = [$var]; $bulkwalk = 1; # fake a bulkwalk return } # We want to execute the while loop below for the getnext request. if ( $ver == 1 and $sess->{ErrorNum} and $sess->{ErrorStr} =~ /nosuch/i ) { $errornum = 0; } } # Use BULKWALK if we can because its faster if ( $bulkwalk && @$vars == 0 ) { ($vars) = $sess->bulkwalk( 0, $repeaters, $var ); if ( $sess->{ErrorNum} ) { $self->error_throw( "SNMP::Info::_load_atrr: BULKWALK " . $sess->{ErrorStr}, "\n" ); return; } } while ( !$errornum ) { if ($bulkwalk) { $var = shift @$vars or last; } else { # GETNEXT instead of BULKWALK $sess->getnext($var); $errornum = $sess->{ErrorNum}; } if ( $self->debug() > 1 ) { use Data::Dumper; print "SNMP::Info::_load_attr $method : leaf = $oid , var = ", Dumper($var); } # Check if we've left the requested subtree last if $var->[0] !~ /$leaf$/; my $iid = $var->[1]; my $val = $var->[2]; unless ( defined $iid ) { $self->error_throw( "SNMP::Info::_load_attr: $method not here"); next; } # Check to make sure we are still in partial land if ( defined $partial and $iid !~ /^$partial$/ and $iid !~ /^$partial\./ ) { $self->debug() and print "$iid makes us leave partial land.\n"; last; } # Check if last element, V2 devices may report ENDOFMIBVIEW even if # instance or object doesn't exist. if ( $val eq 'ENDOFMIBVIEW' ) { last; } # Similarly for SNMPv1 - noSuchName return results in both $iid # and $val being empty strings. if ( $val eq '' and $iid eq '' ) { last; } # Another check for SNMPv1 - noSuchName return may results in an $iid # we've already seen and $val an empty string. If we don't catch # this here we erronously report a loop below. if ( defined $seen{$iid} and $seen{$iid} and $val eq '' ) { last; } if ($loopdetect) { # Check to see if we've already seen this IID (looping) if ( defined $seen{$iid} and $seen{$iid} ) { $self->error_throw("Looping on: $method iid:$iid. "); last; } else { $seen{$iid}++; } } if ( $val eq 'NOSUCHOBJECT' ) { $self->error_throw( "SNMP::Info::_load_attr: $method : NOSUCHOBJECT"); next; } if ( $val eq 'NOSUCHINSTANCE' ) { $self->error_throw( "SNMP::Info::_load_attr: $method : NOSUCHINSTANCE"); next; } $localstore->{$iid} = $val; } # Cache data if we are not getting partial data: if ( !defined $partial ) { $self->_cache($attr, $localstore); } # Data Munging if ( !$raw ) { $localstore = $self->_munge($attr, $localstore); } return $localstore; } } =item $info->_show_attr() Used internally by AUTOLOAD to return data called by methods listed in %FUNCS. =cut sub _show_attr { my $self = shift; my $attr = shift; my $raw = shift; my $store = $self->store(); if ( !$raw ) { my $localstore = $store->{$attr}; return $self->_munge($attr, $localstore); } else { return $store->{$attr}; } } =item $info->snmp_connect_ip(ip) Returns true or false based upon snmp connectivity to an IP. =cut sub snmp_connect_ip { my $self = shift; my $ip = shift; my $ver = $self->snmp_ver(); my $comm = $self->snmp_comm(); return if $self->{Offline}; return if ( $ip eq '0.0.0.0' ) or ( $ip =~ /^127\./ ); # Create session object my $snmp_test = new SNMP::Session( 'DestHost' => $ip, 'Community' => $comm, 'Version' => $ver ); # No session object created unless ( defined $snmp_test ) { return; } # Session object created but SNMP connection failed. my $sess_err = $snmp_test->{ErrorStr} || ''; if ($sess_err) { return; } # Try to get some data from IP my $layers = $snmp_test->get('sysServices.0'); $sess_err = $snmp_test->{ErrorStr} || ''; if ($sess_err) { return; } return 1; } =item modify_port_list(portlist,offset,replacement) Replaces the specified bit in a port_list array and returns the packed bitmask =cut sub modify_port_list { my ( $self, $portlist, $offset, $replacement ) = @_; print "Original port list: @$portlist \n" if $self->debug(); @$portlist[$offset] = $replacement; # Some devices do not populate the portlist with all possible ports. # If we have lengthened the list fill all undefined elements with zero. foreach my $item (@$portlist) { $item = '0' unless ( defined($item) ); } print "Modified port list: @$portlist \n" if $self->debug(); return pack( "B*", join( '', @$portlist ) ); } =item $info->_cache(attr, data) Cache retrieved data so that if it's asked for again, we use the cache instead of going back to Net-SNMP. Data is cached inside the blessed hashref C<$self>. Accepts the leaf and value (scalar, or hashref for a table). Does not return anything useful. =cut sub _cache { my $self = shift; my ($attr, $data) = @_; my $store = $self->store(); if (ref {} eq ref $data) { $self->{"_${attr}"}++; $store->{$attr} = $data; } else { $self->{"_$attr"} = $data; } } =item $info->_munge(attr, data) Raw data returned from Net-SNMP might not be formatted correctly or might have platform-specific bugs or mistakes. The MUNGE feature of SNMP::Info allows for fixups to take place. Accepts the leaf and value (scalar, or hashref for a table) and returns the raw or the munged data, as appropriate. That is, you do not need to know whether MUNGE is installed, and it's safe to call this method regardless. =cut sub _munge { my $self = shift; my ($attr, $data) = @_; my $munge = $self->munge(); return $data unless defined $munge->{$attr}; if (ref {} eq ref $data) { my $subref = $munge->{$attr}; my %munged; foreach my $key ( keys %$data ) { my $value = $data->{$key}; next unless defined $value; $munged{$key} = $subref->($value); } return \%munged; } else { return unless $data; my $subref = $munge->{$attr}; return $subref->($data); } } =item _validate_autoload_method(method) Used internally by AUTOLOAD to validate that a dynamic method should be created. Returns the OID of the MIB leaf node the method will get or set. =over =item 1. Returns unless method is listed in %FUNCS, %GLOBALS, or is MIB Leaf node name in a loaded MIB for given class. =item 2. Translates the MIB Leaf node name to an OID. =item 3. Checks to see if the method access type is allowed for the resolved OID. Write access for set_ methods, read access for others. =back =cut sub _validate_autoload_method { my $self = shift; my $method = shift; my $setter = $method =~ /^set/; my $attr = $method; $attr =~ s/^(load|set|orig)_//; $attr =~ s/_raw$//; my $globals = $self->globals(); my $funcs = $self->funcs(); my $leaf_name = $globals->{$attr} || $funcs->{$attr} || $attr; # Check for fully qualified name if ( $leaf_name =~ /__/ ) { $leaf_name =~ s/__/::/; $leaf_name =~ s/_/-/g; } # skip if offline if ( $self->{Offline} ) { return [1,(exists $self->{store}->{$method} ? 1: 0)]; } # Translate MIB leaf node name to OID my $oid = SNMP::translateObj($leaf_name); if ( $leaf_name =~ /^[.]?\d[\.\d]+$/ ) { $oid = $leaf_name; } unless ( defined $oid ) { print "SNMP::Info::_validate_autoload_method($leaf_name) Unable to resolve method.\n" if $self->debug(); return; } # Validate that we have proper access for the operation my $access = $SNMP::MIB{$oid}{'access'} || ''; # If we were given a fully qualified OID because we don't have the MIB # file, it will translate above but we won't be able to check access so # skip the check and return if ($access) { unless ( ( $method =~ /^set/ && $access =~ /Write|Create/ ) || $access =~ /Read|Create/ ) { print "SNMP::Info::_validate_autoload_method($attr : $oid) Not accessable for requested operation.\n" if $self->debug(); return; } } # If the parent of the leaf has indexes it is contained within a table my $indexes = $SNMP::MIB{$oid}{'parent'}{'indexes'}; my $table_leaf = 0; if ( !$globals->{$attr} && ( ( defined $indexes && scalar( @{$indexes} ) > 0 ) || $funcs->{$attr} )) { $table_leaf = 1; } # Tag on .0 for %GLOBALS and single instance MIB leafs unless # the leaf ends in a digit or we are going to use for a set operation if ( $table_leaf == 0 && ( $globals->{$attr} || $leaf_name ne $oid ) ) { unless ( $leaf_name =~ /\d$/ || $setter ) { $oid .= ".0"; } } my $return = [ $oid, $table_leaf ]; return $return; } =item $info->can() Overrides UNIVERSAL::can() so that objects will correctly report their capabilities to include dynamic methods generated at run time via AUTOLOAD. Calls parent can() first to see if method exists, if not validates that a method should be created then dispatches to the appropriate internal method for creation. The newly created method is inserted into the symbol table returning to AUTOLOAD only for the initial method call. Returns undef if the method does not exist and can not be created. =cut sub can { my $self = shift; my $method = shift; # use results of parent can() return $self->SUPER::can($method) if $self->SUPER::can($method); my $validated = $self->_validate_autoload_method($method); return unless $validated; my ($oid, $table) = @$validated; # _validate_autoload_method validates, so we need to check for # set_ , funcs, table leafs, and everything else goes to _global my $funcs = $self->funcs(); # We need to resolve funcs with a prefix or suffix my $f_method = $method; $f_method =~ s/^(load|orig)_//; $f_method =~ s/_raw$//; no strict 'refs'; ## no critic (ProhibitNoStrict ) # Check for set_ ing. if ( $method =~ /^set_/ ) { return *{$AUTOLOAD} = _make_setter( $method, $oid, @_ ); } elsif ( defined $funcs->{$f_method} || $table ) { return *{$AUTOLOAD} = _load_attr( $method, $oid, @_ ); } else { return *{$AUTOLOAD} = _global( $method, $oid ); } } =back =head2 AUTOLOAD Each entry in either %FUNCS, %GLOBALS, or MIB Leaf node names present in loaded MIBs are used by AUTOLOAD() to create dynamic methods. Generated methods are inserted into the symbol table so that subsequent calls can avoid AUTOLOAD() and dispatch directly. =over =item 1. Returns unless method is listed in %FUNCS, %GLOBALS, or is a MIB Leaf node name in a loaded MIB for given class. =item 2. If the method exists in %GLOBALS or is a single instance MIB Leaf node name from a loaded MIB, _global() generates the method. =item 3. If a set_ prefix is present _make_setter() generates the method. =item 4. If the method exists in %FUNCS or is a MIB Leaf node name contained within a table from a loaded MIB, _load_attr() generates the method. =item 5. A load_ prefix forces reloading of data and does not use cached data. =item 6. A _raw suffix returns data ignoring any munge routines. =back Override any dynamic method listed in %GLOBALS, %FUNCS, or MIB Leaf node name a by creating a subroutine with the same name. For example to override $info->name() create `` sub name {...}'' in your subclass. =cut sub AUTOLOAD { my $self = shift; my ($sub_name) = $AUTOLOAD =~ /::(\w+)$/; return if $sub_name =~ /DESTROY$/; # Typos in function calls in SNMP::Info subclasses turn into # AUTOLOAD requests for non-methods. While this is deprecated, # we'll still get called, so report a less confusing error. if ( ref($self) !~ /SNMP::Info/ ) { # croak reports one level too high. die reports here. # I would really like to get the place that's likely to # have the typo, but perl doesn't want me to. croak( "SNMP::Info::AUTOLOAD($AUTOLOAD) called with no class (probably typo of function call to $sub_name)" ); } # This enables us to use SUPER:: for AUTOLOAD methods as well # as the true OO methods. Method needs to be renamed to prevent # namespace collision when we insert into the symbol table later. if ( $AUTOLOAD =~ /SUPER::$sub_name$/ ) { $AUTOLOAD =~ s/SUPER::$sub_name/orig_$sub_name/; $sub_name = "orig_$sub_name"; } return unless my $meth_ref = $self->can($sub_name, @_); return $self->$meth_ref(@_); } 1; =head1 COPYRIGHT AND LICENSE Changes from SNMP::Info Version 0.7 and on are: Copyright (c) 2003-2010 Max Baker and SNMP::Info Developers All rights reserved. Original Code is: Copyright (c) 2002-2003, Regents of the University of California All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of California, Santa Cruz nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =cut SNMP-Info-3.39/lib/SNMP/Info000755000765000024 013215550564 15126 5ustar00oliverstaff000000000000SNMP-Info-3.39/lib/SNMP/Info/AMAP.pm000444000765000024 2251313215550564 16362 0ustar00oliverstaff000000000000# SNMP::Info::AMAP # # Copyright (c) 2013 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::AMAP; use strict; use Exporter; use SNMP::Info; @SNMP::Info::LLDP::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::LLDP::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'ALCATEL-IND1-INTERSWITCH-PROTOCOL-MIB' => 'aipAMAPRemDeviceType', ); %GLOBALS = ( ); %FUNCS = ( # EXTREME-EDP-MIB::extremeEdpTable 'amap_rem_sysname' => 'aipAMAPRemHostname', ); %MUNGE = ( 'amap_rem_sysname' => \&SNMP::Info::munge_null, ); sub hasAMAP { my $amap = shift; my $amap_ip = $amap->aipAMAPIpAddr() || {}; return 1 if ( scalar( keys %$amap_ip ) ); return; } # Break up the aipAMAPhostsTable INDEX into MAC and IP address. sub _hosts_table_index { my $idx = shift; my @oids = split( /\./, $idx ); my $mac = join( '.', splice( @oids, 0, 6 ) ); return ( $mac, join( '.', @oids ) ); } # Break up the aipAMAPportConnectionTable INDEX and return MAC sub _conn_table_mac { my $idx = shift; my @oids = split( /\./, $idx ); my $local_idx = shift @oids; my $mac = join( '.', splice( @oids, 0, 6 ) ); return ($mac); } # Since we need to get IP Addresses from the aipAMAPhostsTable which has # a different index (MAC, IP) than the aipAMAPportConnectionTable which holds # the remote device details we create a combined index and skip any # IPs which have an address of 0.0.0.0. Would like to include only one # address since they should all originate from the same device, but we don't # know if they would all be reachable from the network management application. # # We don't inplement partials since this is private index function sub _amap_index { my $amap = shift; my $amap_ip = $amap->aipAMAPIpAddr() || {}; my $amap_rport = $amap->aipAMAPLocalPort() || {}; my %amap_index; foreach my $key ( keys %$amap_ip ) { my ( $mac, $ip ) = _hosts_table_index($key); next if ( $ip eq '0.0.0.0' ); next unless $ip; foreach my $idx ( keys %$amap_rport ) { my $c_mac = _conn_table_mac($idx); if ( $mac eq $c_mac ) { my $index = "$idx.$ip"; $amap_index{$index} = $index; } } } return \%amap_index; } # Break up _amap_index INDEX into local index, MAC, remote index, and # IP address sub _amap_index_parts { my $idx = shift; my @oids = split( /\./, $idx ); my $local_idx = shift @oids; my $mac = join( '.', splice( @oids, 0, 6 ) ); my $rem_idx = shift @oids; return ( $local_idx, $mac, $rem_idx, join( '.', @oids ) ); } sub amap_if { my $amap = shift; my $index = $amap->_amap_index() || {}; my $if_idx = $amap->aipAMAPLocalIfindex() || {}; my %amap_if; foreach my $key ( keys %$index ) { my ( $local_idx, $mac, $rem_idx, $ip ) = _amap_index_parts($key); my $if_key = "$local_idx.$mac.$rem_idx"; if ( $key =~ /^$if_key/ ) { my $if = $if_idx->{$if_key}; $amap_if{$key} = $if; } } return \%amap_if; } sub amap_ip { my $amap = shift; my $index = $amap->_amap_index() || {}; my %amap_ip; foreach my $key ( keys %$index ) { my ( $local_idx, $mac, $rem_idx, $ip ) = _amap_index_parts($key); # MIB says should only be IPv4 next unless ( $ip =~ /\d+(\.\d+){3}/ ); $amap_ip{$key} = $ip; } return \%amap_ip; } sub amap_port { my $amap = shift; my $index = $amap->_amap_index() || {}; my $amap_rport = $amap->aipAMAPLocalPort() || {}; my $amap_rslot = $amap->aipAMAPLocalSlot() || {}; my %amap_port; foreach my $key ( sort keys %$index ) { my ( $local_idx, $mac, $rem_idx, $ip ) = _amap_index_parts($key); my $p_key = "$local_idx.$mac.$rem_idx"; if ( $key =~ /^$p_key/ ) { my $port = $amap_rport->{$p_key}; my $slot = $amap_rslot->{$p_key} || 0; next unless $port; $amap_port{$key} = defined $slot ? "$slot\/$port" : $port; } } return \%amap_port; } sub amap_id { my $amap = shift; my $index = $amap->_amap_index() || {}; my $amap_name = $amap->amap_rem_sysname() || {}; my %amap_name; foreach my $key ( sort keys %$index ) { my ( $local_idx, $mac, $rem_idx, $ip ) = _amap_index_parts($key); my $id_key = "$local_idx.$mac.$rem_idx"; if ( $key =~ /^$id_key/ ) { my $name = $amap_name->{$id_key} || 0; next unless $name; $amap_name{$key} = $name; } } return \%amap_name; } sub amap_platform { my $amap = shift; my $index = $amap->_amap_index() || {}; my $amap_topo_platform = $amap->aipAMAPRemDeviceType() || {}; my %amap_platform; foreach my $key ( keys %$index ) { my ( $local_idx, $mac, $rem_idx, $ip ) = _amap_index_parts($key); my $pf_key = "$local_idx.$mac.$rem_idx"; if ( $key =~ /^$pf_key/ ) { my $platform = $amap_topo_platform->{$pf_key}; next unless $platform; $amap_platform{$key} = $platform; } } return \%amap_platform; } 1; __END__ =head1 NAME SNMP::Info::AMAP - SNMP Interface to Alcatel Mapping Adjacency Protocol (AMAP) =head1 AUTHOR Eric Miller =head1 SYNOPSIS my $amap = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'router', Community => 'public', Version => 2 ); my $class = $amap->class(); print " Using device sub class : $class\n"; $hasamap = $amap->hasAMAP() ? 'yes' : 'no'; # Print out a map of device ports with LLDP neighbors: my $interfaces = $amap->interfaces(); my $amap_if = $amap->amap_if(); my $amap_ip = $amap->amap_ip(); my $amap_port = $amap->amap_port(); foreach my $amap_key (keys %$amap_ip){ my $iid = $amap_if->{$amap_key}; my $port = $interfaces->{$iid}; my $neighbor = $amap_ip->{$amap_key}; my $neighbor_port = $amap_port->{$amap_key}; print "Port : $port connected to $neighbor / $neighbor_port\n"; } =head1 DESCRIPTION SNMP::Info::AMAP is a subclass of SNMP::Info that provides an object oriented interface to Alcatel Mapping Adjacency Protocol (AMAP) information through SNMP. AMAP is a Layer 2 protocol that allows a network device to advertise its identity and capabilities on the local network providing topology information. Create or use a device subclass that inherits this class. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =back =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $amap->hasAMAP() Is AMAP is active in this device? =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $amap->amap_id() Returns the string value used to identify the remote system. =item $amap->amap_if() Returns the mapping to the SNMP Interface Table. =item $amap->amap_ip() Returns remote IPv4 addresses. Note: AMAP returns all IP addresses associated with the remote device. It would be preferable to include only one address since they should all originate from the same device, but amap_ip() can not determine if all addresses are reachable from the network management application therefore all addresses are returned and the calling application must determine which address to use and if they are in fact from the same device. =item $amap->amap_port() Returns remote port ID =item $amap->amap_platform() Returns remote platform ID =back =cut SNMP-Info-3.39/lib/SNMP/Info/AdslLine.pm000444000765000024 1111513215550564 17333 0ustar00oliverstaff000000000000# SNMP::Info::AdslLine # # Copyright (c) 2009 Alexander Hartmaier # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::AdslLine; use strict; use Exporter; use SNMP::Info; @SNMP::Info::AdslLine::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::AdslLine::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'ADSL-LINE-MIB' => 'adslLineType' ); %GLOBALS = (); %FUNCS = ( # ADSL-LINE-MIB::adslAtucChanTable 'adsl_atuc_interleave_delay' => 'adslAtucChanInterleaveDelay', 'adsl_atuc_curr_tx_rate' => 'adslAtucChanCurrTxRate', 'adsl_atuc_prev_tx_rate' => 'adslAtucChanPrevTxRate', 'adsl_atuc_crc_block_len' => 'adslAtucChanCrcBlockLength', # ADSL-LINE-MIB::adslAturChanTable 'adsl_atur_interleave_delay' => 'adslAturChanInterleaveDelay', 'adsl_atur_curr_tx_rate' => 'adslAturChanCurrTxRate', 'adsl_atur_prev_tx_rate' => 'adslAturChanPrevTxRate', 'adsl_atur_crc_block_len' => 'adslAturChanCrcBlockLength', ); %MUNGE = (); 1; __END__ =head1 NAME SNMP::Info::AdslLine - SNMP Interface to the F =head1 AUTHOR Alexander Hartmaier =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $info = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $info->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::AdslLine is a subclass of SNMP::Info that provides information about the adsl interfaces of a device. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes none. =head2 Required MIBs =over =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBALS =over =item none =back =head1 TABLE METHODS =head2 ATUC channel table (C) This table provides one row for each ATUC channel. ADSL channel interfaces are those C where C is equal to adslInterleave(124) or adslFast(125). =over =item $info->adsl_atuc_interleave_delay() (C) =item $info->adsl_atuc_curr_tx_rate() (C) =item $info->adsl_atuc_prev_tx_rate() (C) =item $info->adsl_atuc_crc_block_len() (C) =back =head2 ATUR channel table (C) This table provides one row for each ATUR channel. ADSL channel interfaces are those C where C is equal to adslInterleave(124) or adslFast(125). =over =item $info->adsl_atur_interleave_delay() (C) =item $info->adsl_atur_curr_tx_rate() (C) =item $info->adsl_atur_prev_tx_rate() (C) =item $info->adsl_atur_crc_block_len() (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/Aggregate.pm000444000765000024 714513215550564 17516 0ustar00oliverstaff000000000000# SNMP::Info::Aggregate # # Copyright (c) 2014 SNMP::Info Developers # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Aggregate; use strict; use Exporter; use SNMP::Info; @SNMP::Info::Aggregate::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::Aggregate::EXPORT_OK = qw/agg_ports_ifstack/; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = (); # IF-MIB %GLOBALS = (); %FUNCS = (); %MUNGE = (); sub agg_ports_ifstack { my $dev = shift; my $partial = shift; my $ifStack = $dev->ifStackStatus(); # TODO: if we want to do partial, we need to use inverse status my $ifType = $dev->ifType(); my $ret = {}; foreach my $idx ( keys %$ifStack ) { my ( $higher, $lower ) = split /\./, $idx; next if ( $higher == 0 or $lower == 0 ); if ( $ifType->{ $higher } eq 'ieee8023adLag' or $ifType->{ $higher } eq 'propMultiplexor') { $ret->{ $lower } = $higher; } } return $ret; } 1; __END__ =head1 NAME SNMP::Info::Aggregate - SNMP Interface to ifStackTable Aggregated Links =head1 AUTHOR SNMP::Info Developers =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $info = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $info->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION This class provides access to Aggregated Links configuration on devices supporting C. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes L =head2 Required MIBs =over =item F =back =head1 METHODS =over 4 =item C Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =back =cut SNMP-Info-3.39/lib/SNMP/Info/Airespace.pm000444000765000024 13533613215550564 17570 0ustar00oliverstaff000000000000# SNMP::Info::Airespace # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Airespace; use strict; use Exporter; use SNMP::Info; @SNMP::Info::Airespace::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::Airespace::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, 'AIRESPACE-WIRELESS-MIB' => 'bsnAPName', 'AIRESPACE-SWITCHING-MIB' => 'agentInventorySerialNumber', ); %GLOBALS = ( %SNMP::Info::GLOBALS, 'airespace_type' => 'agentInventoryMachineType', 'airespace_model' => 'agentInventoryMachineModel', 'airespace_serial' => 'agentInventorySerialNumber', 'airespace_maint_ver' => 'agentInventoryMaintenanceLevel', 'airespace_mac' => 'agentInventoryBurnedInMacAddress', 'airespace_os' => 'agentInventoryOperatingSystem', 'airespace_vendor' => 'agentInventoryManufacturerName', 'airespace_prod_name' => 'agentInventoryProductName', 'os_ver' => 'agentInventoryProductVersion', 'airespace_bssid_mode' => 'agentNetworkBroadcastSsidMode', 'airespace_mc_mode' => 'agentNetworkMulticastMode', 'airespace_lwapp_mode' => 'agentSwitchLwappTransportMode', 'airespace_ul_mode' => 'agentTransferUploadMode', 'airespace_ul_ip' => 'agentTransferUploadServerIP', 'airespace_ul_path' => 'agentTransferUploadPath', 'airespace_ul_file' => 'agentTransferUploadFilename', 'airespace_ul_type' => 'agentTransferUploadDataType', 'airespace_ul_start' => 'agentTransferUploadStart', 'airespace_ul_status' => 'agentTransferUploadStatus', ); %FUNCS = ( %SNMP::Info::FUNCS, # AIRESPACE-WIRELESS-MIB::bsnDot11EssTable 'airespace_ess_idx' => 'bsnDot11EssIndex', 'airespace_ess_ssid' => 'bsnDot11EssSsid', 'airespace_ess_macflt' => 'bsnDot11EssMacFiltering', 'airespace_ess_status' => 'bsnDot11EssAdminStatus', 'airespace_ess_sec_auth' => 'bsnDot11EssSecurityAuthType', 'airespace_ess_radio_pol' => 'bsnDot11EssRadioPolicy', 'airespace_ess_qos' => 'bsnDot11EssQualityOfService', 'airespace_ess_ifname' => 'bsnDot11EssInterfaceName', 'airespace_ess_aclname' => 'bsnDot11EssAclName', 'airespace_ess_bcast' => 'bsnDot11EssBroadcastSsid', # AIRESPACE-WIRELESS-MIB::bsnAPTable 'airespace_ap_mac' => 'bsnAPDot3MacAddress', 'airespace_ap_name' => 'bsnAPName', 'airespace_ap_ip' => 'bsnApIpAddress', 'airespace_ap_loc' => 'bsnAPLocation', 'airespace_ap_sw' => 'bsnAPSoftwareVersion', 'airespace_ap_fw' => 'bsnAPBootVersion', 'airespace_ap_model' => 'bsnAPModel', 'airespace_ap_serial' => 'bsnAPSerialNumber', 'airespace_ap_type' => 'bsnAPType', 'airespace_ap_status' => 'bsnAPAdminStatus', 'airespace_ap_ethermac' => 'bsnAPEthernetMacAddress', # AIRESPACE-WIRELESS-MIB::bsnAPIfTable 'airespace_apif_slot' => 'bsnAPIfSlotId', 'airespace_apif_type' => 'bsnAPIfType', 'airespace_apif_ch_num' => 'bsnAPIfPhyChannelNumber', 'airespace_apif_power' => 'bsnAPIfPhyTxPowerLevel', 'airespace_apif' => 'bsnAPIfOperStatus', 'airespace_apif_oride' => 'bsnAPIfWlanOverride', 'airespace_apif_admin' => 'bsnAPIfAdminStatus', 'airespace_apif_a_pwr' => 'bsnAPIfAbsolutePowerList', # AIRESPACE-WIRELESS-MIB::bsnMobileStationTable 'airespace_sta_mac' => 'bsnMobileStationAPMacAddr', 'fw_mac' => 'bsnMobileStationMacAddress', 'airespace_sta_slot' => 'bsnMobileStationAPIfSlotId', 'airespace_sta_ess_idx' => 'bsnMobileStationEssIndex', 'airespace_sta_ssid' => 'bsnMobileStationSsid', 'airespace_sta_delete' => 'bsnMobileStationDeleteAction', 'airespace_sta_ip' => 'bsnMobileStationIpAddress', # AIRESPACE-WIRELESS-MIB::bsnUsersTable 'airespace_user_name' => 'bsnUserName', 'airespace_user_pw' => 'bsnUserPassword', 'airespace_user_ess_idx' => 'bsnUserEssIndex', 'airespace_user_access' => 'bsnUserAccessMode', 'airespace_user_type' => 'bsnUserType', 'airespace_user_ifname' => 'bsnUserInterfaceName', 'airespace_user_rstat' => 'bsnUserRowStatus', # AIRESPACE-WIRELESS-MIB::bsnBlackListClientTable 'airespace_bl_mac' => 'bsnBlackListClientMacAddress', 'airespace_bl_descr' => 'bsnBlackListClientDescription', 'airespace_bl_rstat' => 'bsnBlackListClientRowStatus', # AIRESPACE-WIRELESS-MIB::bsnAPIfWlanOverrideTable 'airespace_oride_id' => 'bsnAPIfWlanOverrideId', 'airespace_oride_ssid' => 'bsnAPIfWlanOverrideSsid', # AIRESPACE-SWITCHING-MIB::agentInterfaceConfigTable 'airespace_if_name' => 'agentInterfaceName', 'airespace_if_vlan' => 'agentInterfaceVlanId', 'airespace_if_type' => 'agentInterfaceType', 'airespace_if_mac' => 'agentInterfaceMacAddress', 'airespace_if_ip' => 'agentInterfaceIPAddress', 'airespace_if_mask' => 'agentInterfaceIPNetmask', 'airespace_if_acl' => 'agentInterfaceAclName', 'airespace_if_rstat' => 'agentInterfaceRowStatus', # AIRESPACE-SWITCHING-MIB::agentPortConfigTable 'airespace_duplex_admin' => 'agentPortPhysicalMode', 'airespace_duplex' => 'agentPortPhysicalStatus', # This needs to be cleaned up, but for now we pretend to # have the CISCO-DOT11-MIB for signal strengths, etc. 'cd11_sigstrength' => 'bsnMobileStationRSSI', # kinda 'cd11_sigqual' => 'bsnMobileStationSnr', # kinda 'cd11_rxbyte' => 'bsnMobileStationBytesReceived', 'cd11_txbyte' => 'bsnMobileStationBytesSent', 'cd11_rxpkt' => 'bsnMobileStationPacketsReceived', 'cd11_txpkt' => 'bsnMobileStationPacketsSent', 'cd11_ssid' => 'bsnMobileStationSsid', ); %MUNGE = ( %SNMP::Info::MUNGE, 'airespace_ap_mac' => \&SNMP::Info::munge_mac, 'airespace_ap_ethermac' => \&SNMP::Info::munge_mac, 'fw_port' => \&SNMP::Info::munge_mac, 'airespace_bl_mac' => \&SNMP::Info::munge_mac, 'airespace_if_mac' => \&SNMP::Info::munge_mac, 'airespace_sta_mac' => \&SNMP::Info::munge_mac, 'cd11_rxpkt' => \&munge_64bits, 'cd11_txpkt' => \&munge_64bits, ); sub layers { return '00000111'; } sub serial { my $airespace = shift; my $sn = $airespace->airespace_serial(); return unless defined $sn; return $sn; } # Wirless switches do not support ifMIB requirements to get MAC # and port status sub i_index { my $airespace = shift; my $partial = shift; my $i_index = $airespace->orig_i_index($partial) || {}; my $ap_index = $airespace->airespace_apif_slot($partial) || {}; my $if_index = $airespace->airespace_if_name($partial) || {}; my %if_index; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; $if_index{$iid} = $index; } # Get Attached APs as Interfaces foreach my $ap_id ( keys %$ap_index ) { if ( $ap_id =~ /(\d+\.\d+\.\d+\.\d+\.\d+\.\d+)\.(\d+)/ ) { my $mac = join( ':', map { sprintf( "%02x", $_ ) } split( /\./, $1 ) ); my $slot = $2; next unless ( ( defined $mac ) and ( defined $slot ) ); $if_index{$ap_id} = "$mac.$slot"; } } # Get Switch Interfaces from Interface Config Table foreach my $if_id ( keys %$if_index ) { my $name = $if_index->{$if_id}; next unless defined $name; $if_index{$if_id} = $name; } return \%if_index; } sub interfaces { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my %if; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { $if{$iid} = "1.$index"; } else { $if{$iid} = $index; } } return \%if; } sub i_name { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my $i_name = $airespace->orig_i_name($partial) || {}; my $ap_name = $airespace->airespace_ap_name($partial) || {}; my %i_name; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $name = $i_name->{$iid}; next unless defined $name; $i_name{$iid} = $name; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $idx = $iid; $idx =~ s/\.\d+$//; my $name = $ap_name->{$idx}; next unless defined $name; $i_name{$iid} = $name; } else { $i_name{$iid} = $index; } } return \%i_name; } sub i_description { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my $i_descr = $airespace->orig_i_description($partial) || {}; my $ap_loc = $airespace->airespace_ap_loc($partial) || {}; my %descr; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $descr = $i_descr->{$iid}; next unless defined $descr; $descr{$iid} = $descr; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $idx = $iid; $idx =~ s/\.\d+$//; my $name = $ap_loc->{$idx}; next unless defined $name; $descr{$iid} = $name; } else { $descr{$iid} = $index; } } return \%descr; } sub i_type { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my $i_descr = $airespace->orig_i_type($partial) || {}; my $apif_type = $airespace->airespace_apif_type($partial) || {}; my $if_type = $airespace->airespace_if_type($partial) || {}; my %i_type; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $descr = $i_descr->{$iid}; next unless defined $descr; $i_type{$iid} = $descr; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $type = $apif_type->{$iid}; next unless defined $type; $i_type{$iid} = $type; } else { my $type = $if_type->{$iid}; $i_type{$iid} = $type; } } return \%i_type; } sub i_up { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my $i_up = $airespace->orig_i_up($partial) || {}; my $apif_up = $airespace->airespace_apif($partial) || {}; my %i_up; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $stat = $i_up->{$iid}; next unless defined $stat; $i_up{$iid} = $stat; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $stat = $apif_up->{$iid}; next unless defined $stat; $i_up{$iid} = $stat; } else { next; } } return \%i_up; } sub i_up_admin { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my $i_up = $airespace->orig_i_up($partial) || {}; my $apif_up = $airespace->airespace_apif_admin($partial) || {}; my %i_up_admin; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $stat = $i_up->{$iid}; next unless defined $stat; $i_up_admin{$iid} = $stat; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $stat = $apif_up->{$iid}; next unless defined $stat; $i_up_admin{$iid} = $stat; } else { next; } } return \%i_up_admin; } sub i_mac { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my $i_mac = $airespace->orig_i_mac($partial) || {}; my $if_mac = $airespace->airespace_if_mac($partial) || {}; my %i_mac; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $mac = $i_mac->{$iid}; next unless defined $mac; $i_mac{$iid} = $mac; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { $index =~ s/\.\d+$//; next unless defined $index; $i_mac{$iid} = $index; } # Some switch interfaces have MACs, virtuals report 00:00:00:00:00:00 else { my $mac = $if_mac->{$iid}; next unless defined $mac; next if $mac =~ /00:00:00:00:00:00/; $i_mac{$iid} = $mac; } } return \%i_mac; } sub i_vlan { my $airespace = shift; my $partial = shift; my $if_vlan = $airespace->airespace_if_vlan($partial) || {}; my %i_vlan; foreach my $iid ( keys %$if_vlan ) { my $vlan = $if_vlan->{$iid}; next unless defined $vlan; $i_vlan{$iid} = $vlan; } return \%i_vlan; } sub i_duplex { my $airespace = shift; my $partial = shift; my $ap_duplex = $airespace->airespace_duplex($partial) || {}; my %i_duplex; foreach my $if ( keys %$ap_duplex ) { my $duplex = $ap_duplex->{$if}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $duplex = 'auto' if $duplex =~ /auto/i; $i_duplex{$if} = $duplex; } return \%i_duplex; } sub i_duplex_admin { my $airespace = shift; my $partial = shift; my $ap_duplex_admin = $airespace->airespace_duplex_admin($partial) || {}; my %i_duplex_admin; foreach my $if ( keys %$ap_duplex_admin ) { my $duplex = $ap_duplex_admin->{$if}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $duplex = 'auto' if $duplex =~ /auto/i; $i_duplex_admin{$if} = $duplex; } return \%i_duplex_admin; } sub ip_index { my $airespace = shift; my $partial = shift; my $ip_index = $airespace->orig_ip_index($partial) || {}; my $if_ip = $airespace->airespace_if_ip() || {}; my %ip_index; foreach my $ip ( keys %$ip_index ) { my $iid = $ip_index->{$ip}; next unless defined $iid; $ip_index{$ip} = $iid; } foreach my $iid ( keys %$if_ip ) { my $ip = $if_ip->{$iid}; next unless defined $ip; next if ( defined $partial and $partial !~ /$ip/ ); $ip_index{$ip} = $iid; } return \%ip_index; } sub ip_netmask { my $airespace = shift; my $partial = shift; my $ip_mask = $airespace->orig_ip_netmask($partial) || {}; my $if_ip = $airespace->airespace_if_ip() || {}; my $if_mask = $airespace->airespace_if_mask() || {}; my %ip_netmask; foreach my $ip ( keys %$ip_mask ) { my $mask = $ip_mask->{$ip}; next unless defined $mask; $ip_netmask{$ip} = $mask; } foreach my $iid ( keys %$if_mask ) { my $ip = $if_ip->{$iid}; next unless defined $ip; next if ( defined $partial and $partial !~ /$ip/ ); my $mask = $if_mask->{$iid}; next unless defined $mask; $ip_netmask{$ip} = $mask; } return \%ip_netmask; } # Wireless switches do not support the standard Bridge MIB sub bp_index { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my %bp_index; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; $bp_index{$index} = $iid; } return \%bp_index; } sub fw_mac { my $airespace = shift; my $partial = shift; return $airespace->SUPER::fw_mac($partial); } sub fw_port { my $airespace = shift; my $partial = shift; my $sta_mac = $airespace->airespace_sta_mac($partial) || {}; my $sta_slot = $airespace->airespace_sta_slot($partial) || {}; my %fw_port; foreach my $iid ( keys %$sta_mac ) { my $mac = $sta_mac->{$iid}; next unless defined $mac; my $slot = $sta_slot->{$iid}; next unless defined $slot; $fw_port{$iid} = "$mac.$slot"; } return \%fw_port; } sub i_ssidlist { my $airespace = shift; my $partial = shift; my $apif_override = $airespace->airespace_apif_oride($partial) || {}; my $apif_type = $airespace->airespace_apif_type($partial) || {}; my $ssids = $airespace->airespace_ess_ssid() || {}; my $ssid_policy = $airespace->airespace_ess_radio_pol() || {}; my $ssid_status = $airespace->airespace_ess_status() || {}; my $ovride_ssids = $airespace->airespace_oride_ssid($partial) || {}; my %i_ssidlist; foreach my $iid ( keys %$apif_override ) { my $override = $apif_override->{$iid}; next unless defined $override; next unless $override =~ /disable/i; my $ap_type = $apif_type->{$iid}; next unless defined $ap_type; $ap_type =~ s/dot11//; foreach my $idx ( keys %$ssids ) { my $ssid = $ssids->{$idx}; next unless defined $ssid; my $status = $ssid_status->{$idx}; next unless defined $status; next if ( $status =~ /disable/ ); my $policy = $ssid_policy->{$idx}; next unless $policy =~ /$ap_type/ or $policy =~ /all/; $i_ssidlist{"$iid.$idx"} = $ssid; } next; } foreach my $iid ( keys %$ovride_ssids ) { my $ssid = $ovride_ssids->{$iid}; next unless $ssid; $i_ssidlist{$iid} = $ssid; } return \%i_ssidlist; } sub i_ssidbcast { my $airespace = shift; my $partial = shift; my $ssidlist = $airespace->i_ssidlist($partial) || {}; my $bc_mode = $airespace->airespace_bssid_mode() || 'enable'; my $ess_bc_mode = $airespace->airespace_ess_bcast() || {}; my $ssids = $airespace->airespace_ess_ssid() || {}; my %ssid_index = reverse %$ssids; my %bcmap = qw/enable 1 disable 0/; my $broadcast = $bcmap{$bc_mode}; my %i_ssidbcast; foreach my $iid ( keys %$ssidlist ) { if (!$broadcast) { $i_ssidbcast{$iid} = $broadcast; next; } else { my $ssid = $ssidlist->{$iid}; my $ssid_idx = $ssid_index{$ssid}; my $bc = $ess_bc_mode->{$ssid_idx}; $i_ssidbcast{$iid} = $bcmap{$bc}; } } return \%i_ssidbcast; } # Secret decoder ring for BSSID: https://supportforums.cisco.com/docs/DOC-2935 # We need radio base MAC, SSID index, radio band, and whether AP is # VxWorks or IOS based then we can do the arithmetic sub i_ssidmac { my $airespace = shift; my $partial = shift; my $ssidlist = $airespace->i_ssidlist($partial) || {}; my $apif_type = $airespace->airespace_apif_type() || {}; my $ap_ios = $airespace->bsnAPIOSVersion() || {}; my %i_ssidmac; foreach my $oid ( keys %$ssidlist ) { my @parts = split( /\./, $oid ); my $ssid_idx = pop(@parts); my $slot = pop(@parts); my $last = pop(@parts); my $iid = $oid; # Get radio band $iid =~ s/\.\d+$//; my $ap_type = $apif_type->{$iid}; # Determine if IOS based $iid =~ s/\.\d+$//; my $ios = $ap_ios->{$iid} || ''; # 17 can be used as index for 3rd Party AP's. We only have one # hexadecimal digit to work with so skip if outside the range if ( $ssid_idx > 0 and $ssid_idx < 17 ) { # Four cases: # IOS and 2.4Ghz count up, starts at zero if ( $ios and $ap_type =~ /b$/ ) { $last = $last + ( $ssid_idx - 1 ); } # IOS and 5Ghz - count down from maximum of 16 elsif ( $ios and $ap_type =~ /a$/ ) { $last = $last + ( 16 - $ssid_idx ); } # VxWorks and 5Ghz - count up, starts at zero elsif ( $ios and $ap_type =~ /a$/ ) { $last = $last + ( $ssid_idx - 1 ); } # VxWorks and 2.4Ghz - count down from maximum of 16 else { $last = $last + ( 16 - $ssid_idx ); } } push( @parts, $last ); my $bssid = join( ':', map { sprintf( "%02x", $_ ) } @parts ); $i_ssidmac{$oid} = $bssid; } return \%i_ssidmac; } sub i_80211channel { my $airespace = shift; my $partial = shift; my $ch_list = $airespace->airespace_apif_ch_num($partial) || {}; my %i_80211channel; foreach my $iid ( keys %$ch_list ) { my $ch = $ch_list->{$iid}; $ch =~ s/ch//; $i_80211channel{$iid} = $ch; } return \%i_80211channel; } sub dot11_cur_tx_pwr_mw { my $airespace = shift; my $partial = shift; my $cur = $airespace->airespace_apif_power($partial); my $pwr_abs = $airespace->airespace_apif_a_pwr($partial); my $dot11_cur_tx_pwr_mw = {}; foreach my $idx ( keys %$cur ) { my $pwr = $cur->{$idx}; if ( $pwr >= 1 && $pwr <= 8 ) { my @pwr_list = split(/,/, $pwr_abs->{$idx} ); $dot11_cur_tx_pwr_mw->{$idx} = $pwr_list[$pwr-1]; } else { next; } } return $dot11_cur_tx_pwr_mw; } # Pseudo ENTITY-MIB methods sub e_index { my $airespace = shift; my $ap_model = $airespace->airespace_ap_model() || {}; my %e_index; # Chassis $e_index{1} = 1; # We're going to hack an index to capture APs foreach my $idx ( keys %$ap_model ) { # Create the integer index by joining the last three octets of the MAC. # Hopefully, this will be unique since the manufacturer should be # limited to Airespace and Cisco. We can't use the entire MAC since # we would exceed the intger size limit. if ( $idx =~ /(\d+\.\d+\.\d+)$/ ) { my $index = int( join( '', map { sprintf "%03d", $_ } split /\./, $1 ) ); $e_index{$idx} = $index; } } return \%e_index; } sub e_class { my $airespace = shift; my $e_idx = $airespace->e_index() || {}; my %e_class; foreach my $iid ( keys %$e_idx ) { if ( $iid eq 1 ) { $e_class{$iid} = 'chassis'; } # This isn't a valid PhysicalClass, but we're hacking this anyway else { $e_class{$iid} = 'ap'; } } return \%e_class; } sub e_name { my $airespace = shift; my $ap_name = $airespace->airespace_ap_name() || {}; my %e_name; # Chassis $e_name{1} = 'WLAN Controller'; # APs foreach my $iid ( keys %$ap_name ) { $e_name{$iid} = 'AP'; } return \%e_name; } sub e_descr { my $airespace = shift; my $ap_model = $airespace->airespace_ap_model() || {}; my $ap_name = $airespace->airespace_ap_name() || {}; my $ap_loc = $airespace->airespace_ap_loc() || {}; my %e_descr; # Chassis $e_descr{1} = $airespace->airespace_prod_name(); # APs foreach my $iid ( keys %$ap_name ) { my $name = $ap_name->{$iid}; next unless defined $name; my $model = $ap_model->{$iid} || 'AP'; my $loc = $ap_loc->{$iid} || 'unknown'; $e_descr{$iid} = "$model: $name ($loc)"; } return \%e_descr; } sub e_model { my $airespace = shift; my $ap_model = $airespace->airespace_ap_model() || {}; my %e_model; # Chassis $e_model{1} = $airespace->airespace_model(); # APs foreach my $iid ( keys %$ap_model ) { my $model = $ap_model->{$iid}; next unless defined $model; $e_model{$iid} = $model; } return \%e_model; } sub e_type { my $airespace = shift; my $ap_type = $airespace->airespace_ap_type() || {}; my %e_type; # Chassis $e_type{1} = $airespace->airespace_type(); # APs foreach my $iid ( keys %$ap_type ) { my $type = $ap_type->{$iid}; next unless defined $type; $e_type{$iid} = $type; } return \%e_type; } sub e_fwver { my $airespace = shift; my $ap_fw = $airespace->airespace_ap_fw() || {}; my %e_fwver; # Chassis $e_fwver{1} = $airespace->airespace_maint_ver(); # APs foreach my $iid ( keys %$ap_fw ) { my $fw = $ap_fw->{$iid}; next unless defined $fw; $e_fwver{$iid} = $fw; } return \%e_fwver; } sub e_vendor { my $airespace = shift; my $e_idx = $airespace->e_index() || {}; my %e_vendor; foreach my $iid ( keys %$e_idx ) { $e_vendor{$iid} = 'cisco'; } return \%e_vendor; } sub e_serial { my $airespace = shift; my $ap_serial = $airespace->airespace_ap_serial() || {}; my %e_serial; # Chassis $e_serial{1} = $airespace->airespace_serial(); # APs foreach my $iid ( keys %$ap_serial ) { my $serial = $ap_serial->{$iid}; next unless defined $serial; $e_serial{$iid} = $serial; } return \%e_serial; } sub e_pos { my $airespace = shift; my $e_idx = $airespace->e_index() || {}; my %e_pos; my $pos = 0; foreach my $iid ( sort keys %$e_idx ) { if ( $iid eq 1 ) { $e_pos{$iid} = -1; next; } else { $pos++; $e_pos{$iid} = $pos; } } return \%e_pos; } sub e_swver { my $airespace = shift; my $ap_sw = $airespace->airespace_ap_sw() || {}; my %e_swver; # Chassis $e_swver{1} = $airespace->airespace_os(); # APs foreach my $iid ( keys %$ap_sw ) { my $sw = $ap_sw->{$iid}; next unless defined $sw; $e_swver{$iid} = $sw; } return \%e_swver; } sub e_parent { my $airespace = shift; my $e_idx = $airespace->e_index() || {}; my %e_parent; foreach my $iid ( sort keys %$e_idx ) { if ( $iid eq 1 ) { $e_parent{$iid} = 0; next; } else { $e_parent{$iid} = 1; } } return \%e_parent; } # arpnip: # # This is the controller snooping on the MAC->IP mappings. # Pretending this is arpnip data allows us to get MAC->IP # mappings even for stations that only communicate locally. # Also use the controller's knowledge of the APs' MAC and # IP addresses to augment the data. sub at_paddr { my $airespace = shift; my $mac2ip = $airespace->airespace_sta_ip(); my $apethermac = $airespace->airespace_ap_ethermac(); my $ret = {}; foreach my $idx ( keys %$mac2ip ) { next if ( $mac2ip->{ $idx } eq '0.0.0.0' ); my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); $ret->{$idx} = $mac; } foreach my $idx ( keys %$apethermac ) { $ret->{$idx} = $apethermac->{$idx}; } return $ret; } sub at_netaddr { my $airespace = shift; my $mac2ip = $airespace->airespace_sta_ip(); my $ap2ip = $airespace->airespace_ap_ip(); my $ret = {}; foreach my $idx ( keys %$mac2ip ) { next if ( $mac2ip->{ $idx } eq '0.0.0.0' ); $ret->{$idx} = $mac2ip->{ $idx }; } foreach my $idx ( keys %$ap2ip ) { $ret->{$idx} = $ap2ip->{ $idx }; } return $ret; } sub munge_64bits { # The controller sometimes hands off a ridiculous value for packets. # Just truncate it to 32 bits. my $value = shift; return $value & 0xffffffff; } 1; __END__ =head1 NAME SNMP::Info::Airespace - SNMP Interface to data from F and F =head1 AUTHOR Eric Miller =head1 SYNOPSIS my $airespace = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $airespace->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION SNMP::Info::Airespace is a subclass of SNMP::Info that provides an interface to F and F. These MIBs are used in Airespace wireless switches, as well as, products from Cisco, Nortel, and Alcatel which are based upon the Airespace platform. The Airespace platform utilizes intelligent wireless switches which control thin access points. The thin access points themselves are unable to be polled for end station information. This class emulates bridge functionality for the wireless switch. This enables end station MAC addresses collection and correlation to the thin access point the end station is using for communication. Use or create a subclass of SNMP::Info that inherits this one. Do not use directly. =head2 Inherited Classes =over =item None. =back =head2 Required MIBs =over =item F =item F =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $airespace->airespace_type() (C) =item $airespace->airespace_model() (C) =item $airespace->airespace_serial() (C) =item $airespace->airespace_maint_ver() (C) =item $airespace->airespace_mac() (C) =item $airespace->airespace_os() (C) =item $airespace->airespace_vendor() (C) =item $airespace->airespace_prod_name() (C) =item $airespace->os_ver() (C) =item $airespace->airespace_bssid_mode() (C) =item $airespace->airespace_mc_mode() (C) =item $airespace->airespace_lwapp_mode() The LWAPP transport mode decides if the switch is operating in the Layer2 or Layer3 mode. (C) =item $airespace->airespace_ul_mode() Transfer upload mode configures the mode to use when uploading from the switch. Normal usage tftp. (C) =item $airespace->airespace_ul_ip() Transfer upload tftp server ip configures the IP address of the server. It is valid only when the Transfer Mode is tftp. (C) =item $airespace->airespace_ul_path() Transfer upload tftp path configures the directory path where the file is to be uploaded to. The switch remembers the last file path used. (C) =item $airespace->airespace_ul_file() (C) =item $airespace->airespace_ul_type() Transfer upload datatype configures the type of file to upload from the switch. The types for upload are: config(2) errorlog(3) systemtrace(4) traplog(5) crashfile(6) (C) =item $airespace->airespace_ul_start() (C) =item $airespace->airespace_ul_status() (C) =back =head2 Overrides =over =item $airespace->layers() Returns 00000111. Class emulates Layer 2 functionality for Thin APs through proprietary MIBs. =item $airespace->serial() (C) =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $airespace->i_ssidlist() Returns reference to hash. SSID's recognized by the radio interface. =item $airespace->i_ssidbcast() Returns reference to hash. Indicates whether the SSID is broadcast. =item $airespace->i_80211channel() Returns reference to hash. Current operating frequency channel of the radio interface. =item $airespace->dot11_cur_tx_pwr_mw() Returns reference to hash. Current transmit power, in milliwatts, of the radio interface. =item $airespace->i_ssidmac() With the same keys as i_ssidlist, returns the Basic service set identification (BSSID), MAC address, the AP is using for the SSID. =back =head2 Dot11 Ess Table (C) Ess(WLAN) Configuration Table. Maximum of 17 WLANs can be created on Airespace Switch. Index of 17 is reserved for WLAN for Third Party APs(non-Airespace APs). =over =item $airespace->airespace_ess_idx() (C) =item $airespace->airespace_ess_ssid() SSID assigned to ESS(WLAN) (C) =item $airespace->airespace_ess_macflt() Select to filter clients by MAC address. By selecting this Security, you need to create MAC Filters in C or have MAC Filters configured on Radius Servers specified in C (C) =item $airespace->airespace_ess_status() Administrative Status of ESS(WLAN). (C) =item $airespace->airespace_ess_sec_auth() Type of 802.11 Authentication. (C) =item $airespace->airespace_ess_radio_pol() Radio Policy for a WLAN. It can either be All where it will be applicable to ALL types of protocols or it can be set to apply to combinations of 802.11a, 802.11b, 802.11g. (C) =item $airespace->airespace_ess_qos() Quality of Service for a WLAN. (C) =item $airespace->airespace_ess_ifname() Name of the interface used by this WLAN. (C) =item $airespace->airespace_ess_aclname() Name of ACL for the WLAN. This is applicable only when Web Authentication is enabled. (C) =item $airespace->airespace_ess_bcast() This attribute when enabled allows the switch to broadcast this SSID. (C) =back =head2 AP Table (C) Table of Airespace APs managed by this Airespace Switch. =over =item $airespace->airespace_ap_mac() The MAC address of the 802.3 interface of the AP. (C) =item $airespace->airespace_ap_name() Name assigned to this AP. If an AP is not configured its factory default name will be ap:. e.g. ap:af:12:be (C) =item $airespace->airespace_ap_ip() Ip address of the AP. This will not be available when the switch is operating in the Layer2 mode. In this case, the attribute will return 0 as value. (C) =item $airespace->airespace_ap_loc() User specified location of this AP. (C) =item $airespace->airespace_ap_sw() (C) =item $airespace->airespace_ap_fw() (C) =item $airespace->airespace_ap_model() (C) =item $airespace->airespace_ap_serial() (C) =item $airespace->airespace_ap_type() (C) =item $airespace->airespace_ap_status() (C) =back =head2 AP Interface Table (C) Table of 802.11 interfaces in an Airespace APs. =over =item $airespace->airespace_apif_slot() The slot Id of this interface. Value will be 0 for a 802.11a (5Ghz) interface and will be 1 for 802.11b/g (2.4Ghz) interface. (C) =item $airespace->airespace_apif_type() (C) =item $airespace->airespace_apif_ch_num() (C) =item $airespace->airespace_apif_power() The transmit power level N currently being used to transmit data. (C) =item $airespace->airespace_apif() (C) =item $airespace->airespace_apif_oride() This flag when disabled implies that all WLANs are available from this radio. However, if this is enabled, then only those WLANs that appear in the (C) will be available from this radio. (C) =item $airespace->airespace_apif_admin() (C) =item $airespace->airespace_apif_a_pwr() List of comma separated absolute power levels supported by the radio. (C) =back =head2 Mobile Station Table (C) =over =item $airespace->airespace_sta_mac() Mac Address of the AP on which Mobile Station is associated. (C) =item $airespace->airespace_sta_slot() Slot Id of AP If on which mobile station is associated. (C) =item $airespace->airespace_sta_ess_idx() Ess Index of the Wlan(SSID) that is being used by Mobile Station to connect to the AP. (C) =item $airespace->airespace_sta_ssid() The SSID Advertised by the Mobile Station. (C) =item $airespace->airespace_sta_delete() Action to Deauthenticate the Mobile Station. Set the State to delete. (C) =back =head2 Users Table (C) The (conceptual) table listing Wlan Users. =over =item $airespace->airespace_user_name() User name. For MAC filters, this will be the MAC address (e.g. 000123456789). (C) =item $airespace->airespace_user_pw() User Password. For MAC filters, this will be "nopassword". (C) =item $airespace->airespace_user_ess_idx() User WLAN ID. Value 0 implies that this applies to any WLAN ID. (C) =item $airespace->airespace_user_access() For MAC filters, this will be "readOnly". (C) =item $airespace->airespace_user_type() User Access Mode. For MAC filters, this will be "macFilter". (C) =item $airespace->airespace_user_ifname() ACL for MAC Filters. An interface name from C (C) =item $airespace->airespace_user_rstat() (C) =back =head2 Black List Client Table (C) The table listing Wlan Black Listed Clients =over =item $airespace->airespace_bl_mac() (C) =item $airespace->airespace_bl_descr() (C) =item $airespace->airespace_bl_rstat() (C) =back =head2 AP Interface WLAN Override Table (C) Each entry represents an SSID added to the AP when the attribute C on the radio is enabled. This means only those WLANs on the switch that are added to this table will be available on such a radio. =over =item $airespace->airespace_oride_id() Index of the WLAN (C) added to the radio. (C) =item $airespace->airespace_oride_ssid() SSID assigned to the override WLAN. (C) =back =head2 Interface Config Table (C) A table of the switch's Interface Config entries. Typically, it will contain entries for Service Port Interface, DS Port Interface and Virtual Gateway Interface apart from other entries. =over =item $airespace->airespace_if_name() Interface Name. This values is 'management' for DS port, 'service-port' for service port and 'virtual' for virtual gateway. For other interfaces, the name can be anything. These interfaces are already created by default. (C) =item $airespace->airespace_if_vlan() VLAN Id configured for the Interface. (C) =item $airespace->airespace_if_type() The interface's type. The static type is set for the interfaces that are created by default on the switch and these cannot be deleted. Any other interface that is created is of type dynamic which can be deleted. (C) =item $airespace->airespace_if_mac() Interface MAC Address. This is only applicable in case of management and service-port interfaces. (C) =item $airespace->airespace_if_ip() (C) =item $airespace->airespace_if_mask() (C) =item $airespace->airespace_if_acl() Name of the Access Control List applied to the interface. This attribute is applicable only to the management interface and other dynamic interfaces. If it is required to remove the ACL name for an interface, it should be set to an empty string. (C) =item $airespace->airespace_if_rstat() (C) =back =head2 Port Config Table (C) =over =item $airespace->airespace_duplex_admin() (C) =item $airespace->airespace_duplex() (C) =back =head2 Overrides =over =item $airespace->i_index() Returns reference to map of IIDs to Interface index. Extends C to support thin APs and WLAN virtual interfaces as device interfaces. =item $airespace->interfaces() Returns reference to map of IIDs to ports. Thin APs are implemented as device interfaces. The thin AP MAC address airespace_ap_mac() and Slot ID airespace_apif_slot() are used as the port identifier. Virtual interfaces use airespace_if_name() as the port identifier. =item $airespace->i_name() Returns reference to map of IIDs to interface names. Returns C for Ethernet interfaces, airespace_ap_name() for thin AP interfaces, and airespace_if_name() for virtual interfaces. =item $airespace->i_description() Returns reference to map of IIDs to interface descriptions. Returns C for Ethernet interfaces, airespace_ap_loc() for thin AP interfaces, and airespace_if_name() for virtual interfaces. =item $airespace->i_type() Returns reference to map of IIDs to interface types. Returns C for Ethernet interfaces, airespace_apif_type() for thin AP interfaces, and airespace_if_type() for virtual interfaces. =item $airespace->i_up() Returns reference to map of IIDs to link status of the interface. Returns C for Ethernet interfaces and airespace_apif() for thin AP interfaces. =item $airespace->i_up_admin() Returns reference to map of IIDs to administrative status of the interface. Returns C for Ethernet interfaces and airespace_apif_admin() for thin AP interfaces. =item $airespace->i_mac() Returns reference to map of IIDs to MAC address of the interface. Returns C for Ethernet interfaces and airespace_if_mac() for virtual interfaces. =item $airespace->i_vlan() Returns reference to map of IIDs to VLAN ID of the interface. Returns airespace_if_vlan() for virtual interfaces. =item $airespace->i_duplex() Returns reference to map of IIDs to current link duplex. Ethernet interfaces only. =item $airespace->i_duplex_admin() Returns reference to hash of IIDs to admin duplex setting. Ethernet interfaces only. =item $airespace->ip_index() Extends table by mapping airespace_if_ip() to the interface IID. =item $airespace->ip_netmask() Extends IP table by mapping airespace_if_mask() to airespace_if_ip() =item $airespace->bp_index() Simulates bridge MIB by returning reference to a hash mapping i_index() to the interface iid. =item $airespace->fw_port() Returns reference to a hash, value being airespace_sta_mac() and airespace_sta_slot() combined to match the interface iid. =item $airespace->fw_mac() (C) =back =head2 Pseudo F information These methods emulate F Physical Table methods using F and F. Thin APs are included as subcomponents of the wireless controller. =over =item $airespace->e_index() Returns reference to hash. Key: IID and Value: Integer. The index for APs is created with an integer representation of the last three octets of the AP MAC address. =item $airespace->e_class() Returns reference to hash. Key: IID, Value: General hardware type. Return ap for wireless access points. =item $airespace->e_descr() Returns reference to hash. Key: IID, Value: Human friendly name. =item $airespace->e_model() Returns reference to hash. Key: IID, Value: Model name. =item $airespace->e_name() More computer friendly name of entity. Name is either 'WLAN Controller' or 'AP'. =item $airespace->e_vendor() Returns reference to hash. Key: IID, Value: cisco. =item $airespace->e_serial() Returns reference to hash. Key: IID, Value: Serial number. =item $airespace->e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. =item $airespace->e_type() Returns reference to hash. Key: IID, Value: Type of component. =item $airespace->e_fwver() Returns reference to hash. Key: IID, Value: Firmware revision. =item $airespace->e_swver() Returns reference to hash. Key: IID, Value: Software revision. =item $airespace->e_parent() Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. =back =head2 Arp Cache Table Augmentation The controller has knowledge of MAC->IP mappings for wireless clients. Augmenting the arp cache data with these MAC->IP mappings enables visibility for stations that only communicate locally. =over =item $airespace->at_paddr() Adds MAC addresses extracted from the index of C. =item $airespace->at_netaddr() Adds IP addresses from C. =back =head1 Data Munging Callback Subroutines =over =item munge_64bits() Truncate packet values to 32 bits. =back =cut SNMP-Info-3.39/lib/SNMP/Info/Bridge.pm000444000765000024 6454113215550564 17047 0ustar00oliverstaff000000000000# SNMP::Info::Bridge # $Id$ # # Changes since Version 0.7 Copyright (c) 2004 Max Baker # All rights reserved. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Bridge; use strict; use Exporter; use SNMP::Info; @SNMP::Info::Bridge::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::Bridge::EXPORT_OK = qw//; use vars qw/$VERSION $DEBUG %MIBS %FUNCS %GLOBALS %MUNGE $INIT/; $VERSION = '3.39'; %MIBS = ( 'BRIDGE-MIB' => 'dot1dBaseBridgeAddress', 'Q-BRIDGE-MIB' => 'dot1qPvid', ); %GLOBALS = ( 'b_mac' => 'dot1dBaseBridgeAddress', 'b_ports' => 'dot1dBaseNumPorts', 'b_type' => 'dot1dBaseType', # Spanning Tree Protocol 'stp_ver' => 'dot1dStpProtocolSpecification', 'stp_time' => 'dot1dStpTimeSinceTopologyChange', 'stp_root' => 'dot1dStpDesignatedRoot', 'stp_root_port' => 'dot1dStpRootPort', 'stp_priority' => 'dot1dStpPriority', # Q-BRIDGE-MIB 'qb_vlans_max' => 'dot1qMaxSupportedVlans', 'qb_vlans' => 'dot1qNumVlans', 'qb_next_vlan_index' => 'dot1qNextFreeLocalVlanIndex', ); %FUNCS = ( # Forwarding Table: Dot1dTpFdbEntry 'fw_mac' => 'dot1dTpFdbAddress', 'fw_port' => 'dot1dTpFdbPort', 'fw_status' => 'dot1dTpFdbStatus', # Bridge Port Table: Dot1dBasePortEntry 'bp_index' => 'dot1dBasePortIfIndex', 'bp_port' => 'dot1dBasePortCircuit', # Bridge Static (Destination-Address Filtering) Database 'bs_mac' => 'dot1dStaticAddress', 'bs_port' => 'dot1dStaticReceivePort', 'bs_to' => 'dot1dStaticAllowedToGoTo', 'bs_status' => 'dot1dStaticStatus', # These leafs are not part of a table, but placed here # to return a hash reference to ease API compatibility with # MST and PVST implementations indexed by a spanning tree # instance id 'stp_i_mac' => 'dot1dBaseBridgeAddress', 'stp_i_time' => 'dot1dStpTimeSinceTopologyChange', 'stp_i_ntop' => 'dot1dStpTopChanges', 'stp_i_root' => 'dot1dStpDesignatedRoot', 'stp_i_root_port' => 'dot1dStpRootPort', 'stp_i_priority' => 'dot1dStpPriority', # Spanning Tree Protocol Table : dot1dStpPortTable 'stp_p_id' => 'dot1dStpPort', 'stp_p_priority' => 'dot1dStpPortPriority', 'stp_p_state' => 'dot1dStpPortState', 'stp_p_cost' => 'dot1dStpPortPathCost', 'stp_p_root' => 'dot1dStpPortDesignatedRoot', 'stp_p_bridge' => 'dot1dStpPortDesignatedBridge', 'stp_p_port' => 'dot1dStpPortDesignatedPort', # Q-BRIDGE-MIB : dot1qPortVlanTable 'qb_i_vlan' => 'dot1qPvid', 'qb_i_vlan_type' => 'dot1qPortAcceptableFrameTypes', 'qb_i_vlan_in_flt' => 'dot1qPortIngressFiltering', # Q-BRIDGE-MIB : dot1qVlanCurrentTable 'qb_cv_egress' => 'dot1qVlanCurrentEgressPorts', 'qb_cv_untagged' => 'dot1qVlanCurrentUntaggedPorts', 'qb_cv_stat' => 'dot1qVlanStatus', # Q-BRIDGE-MIB : dot1qVlanStaticTable 'v_name' => 'dot1qVlanStaticName', 'qb_v_name' => 'dot1qVlanStaticName', 'qb_v_egress' => 'dot1qVlanStaticEgressPorts', 'qb_v_fbdn_egress' => 'dot1qVlanForbiddenEgressPorts', 'qb_v_untagged' => 'dot1qVlanStaticUntaggedPorts', 'qb_v_stat' => 'dot1qVlanStaticRowStatus', # VLAN Forwarding Table: Dot1qTpFdbEntry 'qb_fw_port' => 'dot1qTpFdbPort', 'qb_fw_status' => 'dot1qTpFdbStatus', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::MUNGE, # Add ones for our class 'b_mac' => \&SNMP::Info::munge_mac, 'fw_mac' => \&SNMP::Info::munge_mac, 'bs_mac' => \&SNMP::Info::munge_mac, 'stp_root' => \&SNMP::Info::munge_prio_mac, 'stp_i_mac' => \&SNMP::Info::munge_mac, 'stp_i_root' => \&SNMP::Info::munge_prio_mac, 'stp_p_root' => \&SNMP::Info::munge_prio_mac, 'stp_p_bridge' => \&SNMP::Info::munge_prio_mac, 'stp_p_port' => \&SNMP::Info::munge_prio_port, 'qb_cv_egress' => \&SNMP::Info::munge_port_list, 'qb_cv_untagged' => \&SNMP::Info::munge_port_list, 'qb_v_egress' => \&SNMP::Info::munge_port_list, 'qb_v_fbdn_egress' => \&SNMP::Info::munge_port_list, 'qb_v_untagged' => \&SNMP::Info::munge_port_list, 'qb_cv_untagged' => \&SNMP::Info::munge_port_list, ); # break up the Dot1qTpFdbEntry INDEX into FDB ID and MAC Address. sub _qb_fdbtable_index { my $idx = shift; my @values = split( /\./, $idx ); my $fdb_id = shift(@values); return ( $fdb_id, join( ':', map { sprintf "%02x", $_ } @values ) ); } sub qb_fw_mac { my $bridge = shift; my $partial = shift; my $qb_fw_port = $bridge->qb_fw_port($partial); my $qb_fw_mac = {}; foreach my $idx ( keys %$qb_fw_port ) { my ( $fdb_id, $mac ) = _qb_fdbtable_index($idx); $qb_fw_mac->{$idx} = $mac; } return $qb_fw_mac; } sub qb_fw_vlan { my $bridge = shift; my $partial = shift; my $qb_fw_port = $bridge->qb_fw_port($partial); my $qb_fdb_ids = $bridge->qb_fdb_index() || {}; my $qb_fw_vlan = {}; foreach my $idx ( keys %$qb_fw_port ) { my ( $fdb_id, $mac ) = _qb_fdbtable_index($idx); # Many devices do not populate the dot1qVlanCurrentTable, so default # to FDB ID = VID, but if we have a mapping use it. my $vlan = $fdb_id; # defined as test since some devices have a vlan 0 if (defined $qb_fdb_ids->{$fdb_id}) { $vlan = $qb_fdb_ids->{$fdb_id}; } $qb_fw_vlan->{$idx} = $vlan; } return $qb_fw_vlan; } sub qb_i_vlan_t { my $bridge = shift; my $partial = shift; my $qb_i_vlan = $bridge->qb_i_vlan($partial); my $qb_i_vlan_type = $bridge->qb_i_vlan_type($partial); my $i_vlan = {}; foreach my $if ( keys %$qb_i_vlan ) { my $vlan = $qb_i_vlan->{$if}; my $tagged = $qb_i_vlan_type->{$if} || ''; next unless defined $vlan; $i_vlan->{$if} = $tagged eq 'admitOnlyVlanTagged' ? 'trunk' : $vlan; } return $i_vlan; } sub qb_fdb_index { my $bridge = shift; my $partial = shift; # Some devices may not implement TimeFilter in a standard manner # appearing to loop on this request. Override in the device class, # see Enterasys for example. my $qb_fdb_ids = $bridge->dot1qVlanFdbId() || {}; # Strip the TimeFilter my $vl_fdb_index = {}; for my $fdb_entry (keys(%$qb_fdb_ids)) { (my $vlan = $fdb_entry) =~ s/^\d+\.//; $vl_fdb_index->{$qb_fdb_ids->{$fdb_entry}} = $vlan; } return $vl_fdb_index; } # Most devices now support Q-BRIDGE-MIB, fall back to # BRIDGE-MIB for those that don't. sub fw_mac { my $bridge = shift; my $qb = $bridge->qb_fw_mac(); return $qb if (ref {} eq ref $qb and scalar keys %$qb); return $bridge->SUPER::fw_mac(); } sub fw_port { my $bridge = shift; my $qb = $bridge->qb_fw_port(); return $qb if (ref {} eq ref $qb and scalar keys %$qb); return $bridge->SUPER::fw_port(); } sub fw_status { my $bridge = shift; my $qb = $bridge->qb_fw_status(); return $qb if (ref {} eq ref $qb and scalar keys %$qb); return $bridge->SUPER::fw_status(); } sub i_stp_state { my $bridge = shift; my $partial = shift; my $bp_index = $bridge->bp_index($partial); my $stp_p_state = $bridge->stp_p_state($partial); my %i_stp_state; foreach my $index ( keys %$stp_p_state ) { my $state = $stp_p_state->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $state; $i_stp_state{$iid} = $state; } return \%i_stp_state; } sub i_stp_port { my $bridge = shift; my $partial = shift; my $bp_index = $bridge->bp_index($partial); my $stp_p_port = $bridge->stp_p_port($partial); my %i_stp_port; foreach my $index ( keys %$stp_p_port ) { my $bridge = $stp_p_port->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $bridge; $i_stp_port{$iid} = $bridge; } return \%i_stp_port; } sub i_stp_id { my $bridge = shift; my $partial = shift; my $bp_index = $bridge->bp_index($partial); my $stp_p_id = $bridge->stp_p_id($partial); my %i_stp_id; foreach my $index ( keys %$stp_p_id ) { my $bridge = $stp_p_id->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $bridge; $i_stp_id{$iid} = $bridge; } return \%i_stp_id; } sub i_stp_bridge { my $bridge = shift; my $partial = shift; my $bp_index = $bridge->bp_index($partial); my $stp_p_bridge = $bridge->stp_p_bridge($partial); my %i_stp_bridge; foreach my $index ( keys %$stp_p_bridge ) { my $bridge = $stp_p_bridge->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $bridge; $i_stp_bridge{$iid} = $bridge; } return \%i_stp_bridge; } # Non-accessible, but needed for consistency with other classes sub v_index { my $bridge = shift; my $partial = shift; my $v_name = $bridge->v_name($partial); my %v_index; foreach my $idx ( keys %$v_name ) { $v_index{$idx} = $idx; } return \%v_index; } sub i_vlan { my $bridge = shift; my $partial = shift; my $index = $bridge->bp_index(); # If given a partial it will be an ifIndex, we need to use dot1dBasePort if ($partial) { my %r_index = reverse %$index; $partial = $r_index{$partial}; } my $i_pvid = $bridge->qb_i_vlan($partial) || {}; my $i_vlan = {}; foreach my $bport ( keys %$i_pvid ) { my $vlan = $i_pvid->{$bport}; my $ifindex = $index->{$bport}; unless ( defined $ifindex ) { print " Port $bport has no bp_index mapping. Skipping.\n" if $DEBUG; next; } $i_vlan->{$ifindex} = $vlan; } return $i_vlan; } sub i_untagged { goto &i_vlan } sub i_vlan_membership { my $bridge = shift; my $partial = shift; # Use VlanCurrentTable if available since it will include dynamic # VLANs. However, some devices do not populate the table. my $v_ports = $bridge->qb_cv_egress() || $bridge->qb_v_egress(); return $bridge->_vlan_hoa($v_ports, $partial); } sub i_vlan_membership_untagged { my $bridge = shift; my $partial = shift; # Use VlanCurrentTable if available since it will include dynamic # VLANs. However, some devices do not populate the table. my $v_ports = $bridge->qb_cv_untagged() || $bridge->qb_v_untagged(); return $bridge->_vlan_hoa($v_ports, $partial); } sub _vlan_hoa { my $bridge = shift; my ( $v_ports, $partial ) = @_; my $index = $bridge->bp_index(); my $vlan_hoa = {}; foreach my $idx ( keys %$v_ports ) { next unless ( defined $v_ports->{$idx} ); my $portlist = $v_ports->{$idx}; my $ret = []; my $vlan; # Strip TimeFilter if we're using VlanCurrentTable ( $vlan = $idx ) =~ s/^\d+\.//; # Convert portlist bit array to bp_index array for ( my $i = 0; $i <= $#$portlist; $i++ ) { push( @{$ret}, $i + 1 ) if ( @$portlist[$i] ); } #Create HoA ifIndex -> VLAN array foreach my $port ( @{$ret} ) { my $ifindex = $index->{$port}; next unless ( defined($ifindex) ); # shouldn't happen next if ( defined $partial and $ifindex !~ /^$partial$/ ); push( @{ $vlan_hoa->{$ifindex} }, $vlan ); } } return $vlan_hoa; } sub set_i_pvid { my $bridge = shift; $bridge->error_throw("VLAN set not supported."); return; } sub set_i_vlan { my $bridge = shift; $bridge->error_throw("VLAN set not supported."); return; } sub set_i_untagged { goto &set_i_vlan } sub set_add_i_vlan_tagged { my $bridge = shift; $bridge->error_throw("VLAN set not supported."); return; } sub set_remove_i_vlan_tagged { my $bridge = shift; $bridge->error_throw("VLAN set not supported."); return; } # # These are internal methods and are not documented. Do not use directly. # sub _check_forbidden_ports { my $bridge = shift; my ( $vlan_id, $index ) = @_; return unless ( $vlan_id =~ /\d+/ and $index =~ /\d+/ ); my $iv_forbidden = $bridge->qb_v_fbdn_egress($vlan_id); my $forbidden_ports = $iv_forbidden->{$vlan_id}; print "Forbidden ports: @$forbidden_ports\n" if $bridge->debug(); if ( defined( @$forbidden_ports[ $index - 1 ] ) and ( @$forbidden_ports[ $index - 1 ] eq "1" ) ) { print "Error: Index: $index in forbidden list for VLAN: $vlan_id unable to add.\n" if $bridge->debug(); return; } return 1; } sub _validate_vlan_param { my $bridge = shift; my ( $vlan_id, $ifindex ) = @_; # VID and ifIndex should both be numeric unless (defined $vlan_id and defined $ifindex and $vlan_id =~ /^\d+$/ and $ifindex =~ /^\d+$/ ) { $bridge->error_throw("Invalid parameter."); return; } # Check that ifIndex exists on device my $index = $bridge->interfaces($ifindex); unless ( exists $index->{$ifindex} ) { $bridge->error_throw("ifIndex $ifindex does not exist."); return; } #Check that VLAN exists on device my $vtp_vlans = $bridge->load_qb_cv_stat() || $bridge->load_qb_v_stat(); my $vlan_exists = 0; foreach my $iid ( keys %$vtp_vlans ) { my $vlan = 0; my $state = $vtp_vlans->{$iid}; next unless defined $state; if ( $iid =~ /(\d+)$/ ) { $vlan = $1; } $vlan_exists = 1 if ( $vlan_id eq $vlan ); } unless ($vlan_exists) { $bridge->error_throw( "VLAN $vlan_id does not exist or is not operational."); return; } return 1; } 1; __END__ =head1 NAME SNMP::Info::Bridge - SNMP Interface to SNMP data available through the F (RFC1493) =head1 AUTHOR Max Baker =head1 SYNOPSIS my $bridge = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'switch', Community => 'public', Version => 2 ); my $class = $bridge->class(); print " Using device sub class : $class\n"; # Grab Forwarding Tables my $interfaces = $bridge->interfaces(); my $fw_mac = $bridge->fw_mac(); my $fw_port = $bridge->fw_port(); my $bp_index = $bridge->bp_index(); foreach my $fw_index (keys %$fw_mac){ my $mac = $fw_mac->{$fw_index}; my $bp_id = $fw_port->{$fw_index}; my $iid = $bp_index->{$bp_id}; my $port = $interfaces->{$iid}; print "Port:$port forwarding to $mac\n"; } =head1 DESCRIPTION F is used by most Layer 2 devices, and holds information like the MAC Forwarding Table and Spanning Tree Protocol info. F holds 802.1q information -- VLANs and Trunking. Cisco tends not to use this MIB, but some proprietary ones. HP and some nicer vendors use this. This is from C. Create or use a subclass of SNMP::Info that inherits this class. Do not use directly. For debugging you can call new() directly as you would in SNMP::Info my $bridge = new SNMP::Info::Bridge(...); =head2 Inherited Classes None. =head2 Required MIBs =over =item F =item F =back F needs to be extracted from ftp://ftp.cisco.com/pub/mibs/v1/v1.tar.gz =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $bridge->b_mac() Returns the MAC Address of the root bridge port (C) =item $bridge->b_ports() Returns the number of ports in device (C) =item $bridge->b_type() Returns the type of bridging this bridge can perform, transparent and/or source route. (C) =item $bridge->stp_ver() Returns what version of STP the device is running. (C) =item $bridge->stp_time() Returns time since last topology change detected. (100ths/second) (C) =item $bridge->stp_root() Returns root of STP. (C) =item $bridge->qb_vlans_max() Maximum number of VLANS supported on this device. (C) =item $bridge->qb_vlans() Current number of VLANs that are configured in this device. (C) =item $bridge->qb_next_vlan_index() The next available value for C of a local VLAN entry in C (C) =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $bridge->i_vlan() Returns a mapping between C and the PVID or default VLAN. =item $vtp->i_untagged() An alias for C. =item $bridge->i_vlan_membership() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the egress list for the port. Example: my $interfaces = $bridge->interfaces(); my $vlans = $bridge->i_vlan_membership(); foreach my $iid (sort keys %$interfaces) { my $port = $interfaces->{$iid}; my $vlan = join(',', sort(@{$vlans->{$iid}})); print "Port: $port VLAN: $vlan\n"; } =item $bridge->i_vlan_membership_untagged() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port. =item $bridge->qb_i_vlan_t() Returns reference to hash: key = C, value = either 'trunk' for tagged ports or the VLAN ID. =item $bridge->qb_fdb_index() Returns reference to hash: key = VLAN ID, value = FDB ID. =item $bridge->v_index() Returns VLAN IDs =back =head2 Forwarding Table (C) =over =item $bridge->fw_mac() Returns reference to hash of forwarding table MAC Addresses (C) =item $bridge->fw_port() Returns reference to hash of forwarding table entries port interface identifier (iid) (C) =item $bridge->fw_status() Returns reference to hash of forwarding table entries status (C) =back =head2 Bridge Port Table (C) =over =item $bridge->bp_index() Returns reference to hash of bridge port table entries map back to interface identifier (iid) (C) =item $bridge->bp_port() Returns reference to hash of bridge port table entries for a port which (potentially) has the same value of C as another port on the same bridge, this object contains the name of an object instance unique to this port. (C) =back =head2 Spanning Tree Instance Globals These are not part of a table, but return a hash reference to ease API compatibility with MST and PVST implementations indexed by a spanning tree instance id. =over =item $bridge->stp_i_time() Returns time since last topology change detected. (100ths/second) (C) =item $bridge->stp_i_time() Returns the total number of topology changes detected. (C) =item $bridge->stp_i_root() Returns root of STP. (C) =item $bridge->stp_i_root_port() Returns the port number of the port that offers the lowest cost path to the root bridge. (C) =item $bridge->stp_i_priority() Returns the port number of the port that offers the lowest cost path to the root bridge. (C) =back =head2 Spanning Tree Protocol Table (C) Descriptions are straight from F =over =item $bridge->stp_p_id() "The port number of the port for which this entry contains Spanning Tree Protocol management information." (C) =item $bridge->stp_p_priority() "The value of the priority field which is contained in the first (in network byte order) octet of the (2 octet long) Port ID. The other octet of the Port ID is given by the value of C." (C) =item $bridge->stp_p_state() "The port's current state as defined by application of the Spanning Tree Protocol. This state controls what action a port takes on reception of a frame. If the bridge has detected a port that is malfunctioning it will place that port into the broken(6) state. For ports which are disabled (see C), this object will have a value of disabled(1)." disabled(1) blocking(2) listening(3) learning(4) forwarding(5) broken(6) (C) =item $bridge->stp_p_cost() "The contribution of this port to the path cost of paths towards the spanning tree root which include this port. 802.1D-1990 recommends that the default value of this parameter be in inverse proportion to the speed of the attached LAN." (C) =item $bridge->stp_p_root() "The unique Bridge Identifier of the Bridge recorded as the Root in the Configuration BPDUs transmitted by the Designated Bridge for the segment to which the port is attached." (C) =item $bridge->stp_p_bridge() "The Bridge Identifier of the bridge which this port considers to be the Designated Bridge for this port's segment." (C) =item $bridge->stp_p_port() (C) "The Port Identifier of the port on the Designated Bridge for this port's segment." =item $bridge->i_stp_port() Returns the mapping of (C) to the interface index (iid). =item $bridge->i_stp_state() Returns the mapping of (C) to the interface index (iid). =item $bridge->i_stp_id() Returns the mapping of (C) to the interface index (iid). =item $bridge->i_stp_bridge() Returns the mapping of (C) to the interface index (iid). =back =head2 Q-BRIDGE Port VLAN Table (C) =over =item $bridge->qb_i_vlan() The PVID, the VLAN ID assigned to untagged frames or Priority-Tagged frames received on this port. (C) =item $bridge->qb_i_vlan_type() Either C or C. This is a good spot to find trunk ports. (C) =item $bridge->qb_i_vlan_in_flt() When this is C the device will discard incoming frames for VLANs which do not include this Port in its Member set. When C, the port will accept all incoming frames. (C) =back =head2 Q-BRIDGE VLAN Current Table (C) =over =item $bridge->qb_cv_egress() The set of ports which are assigned to the egress list for this VLAN. (C) =item $bridge->qb_cv_untagged() The set of ports which should transmit egress packets for this VLAN as untagged. (C) =item $bridge->qb_cv_stat() Status of the VLAN, other, permanent, or dynamicGvrp. (C) =back =head2 Q-BRIDGE VLAN Static Table (C) =over =item $bridge->qb_v_name() Human-entered name for vlans. (C) =item $bridge->qb_v_egress() The set of ports which are assigned to the egress list for this VLAN. (C) =item $bridge->qb_v_fbdn_egress() The set of ports which are prohibited from being included in the egress list for this VLAN. (C) =item $bridge->qb_v_untagged() The set of ports which should transmit egress packets for this VLAN as untagged. (C) =item $bridge->qb_v_stat() C ! (C) =back =head2 Q-BRIDGE Filtering Database Table (C) =over =item $bridge->qb_fw_mac() Returns reference to hash of forwarding table MAC Addresses (C) =item $bridge->qb_fw_port() Returns reference to hash of forwarding table entries port interface identifier (iid) (C) =item $bridge->qb_fw_vlan() Returns reference to hash of forwarding table entries VLAN ID =item $bridge->qb_fw_status() Returns reference to hash of forwarding table entries status (C) =back =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item $bridge->set_i_vlan(vlan, ifIndex) Currently unsupported. Throws an error and returns. =item $bridge->set_i_untagged(vlan, ifIndex) An alias for C. =item $bridge->set_i_pvid(pvid, ifIndex) Currently unsupported. Throws an error and returns. =item $bridge->set_add_i_vlan_tagged(vlan, ifIndex) Currently unsupported. Throws an error and returns. =item $bridge->set_remove_i_vlan_tagged(vlan, ifIndex) Currently unsupported. Throws an error and returns. =back =cut SNMP-Info-3.39/lib/SNMP/Info/CDP.pm000444000765000024 3346013215550564 16255 0ustar00oliverstaff000000000000# SNMP::Info::CDP # $Id$ # # Changes since Version 0.7 Copyright (c) 2004 Max Baker # All rights reserved. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CDP; use strict; use Exporter; use SNMP::Info; @SNMP::Info::CDP::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::CDP::EXPORT_OK = qw//; use vars qw/$VERSION $DEBUG %FUNCS %GLOBALS %MIBS %MUNGE $INIT %CDP_CAPABILITIES/; $VERSION = '3.39'; # Five data structures required by SNMP::Info %MIBS = ( 'CISCO-CDP-MIB' => 'cdpGlobalRun' ); # Notice we dont inherit the default GLOBALS and FUNCS # only the default MUNGE. %GLOBALS = ( 'cdp_run' => 'cdpGlobalRun', 'cdp_interval' => 'cdpGlobalMessageInterval', 'cdp_holdtime' => 'cdpGlobalHoldTime', 'cdp_gid' => 'cdpGlobalDeviceId', ); %FUNCS = ( 'cdp_index' => 'cdpCacheIfIndex', 'cdp_proto' => 'cdpCacheAddressType', 'cdp_addr' => 'cdpCacheAddress', 'cdp_ver' => 'cdpCacheVersion', 'cdp_dev_id' => 'cdpCacheDeviceId', 'cdp_port' => 'cdpCacheDevicePort', 'cdp_platform' => 'cdpCachePlatform', 'cdp_capabilities' => 'cdpCacheCapabilities', 'cdp_domain' => 'cdpCacheVTPMgmtDomain', 'cdp_vlan' => 'cdpCacheNativeVLAN', 'cdp_duplex' => 'cdpCacheDuplex', 'cdp_power' => 'cdpCachePowerConsumption', 'cdp_pri_mgmt_type'=> 'cdpCachePrimaryMgmtAddrType', 'cdp_pri_mgmt_addr'=> 'cdpCachePrimaryMgmtAddr', 'cdp_sec_mgmt_type'=> 'cdpCacheSecondaryMgmtAddrType', 'cdp_sec_mgmt_addr'=> 'cdpCacheSecondaryMgmtAddr', ); %MUNGE = ( 'cdp_capabilities' => \&SNMP::Info::munge_bits, 'cdp_platform' => \&SNMP::Info::munge_null, 'cdp_domain' => \&SNMP::Info::munge_null, 'cdp_port' => \&SNMP::Info::munge_null, 'cdp_ver' => \&SNMP::Info::munge_null, 'cdp_ip' => \&SNMP::Info::munge_ip, 'cdp_power' => \&munge_power, ); %CDP_CAPABILITIES = ( 'Router' => 0x001, 'Trans-Bridge' => 0x002, 'Source-Route-Bridge' => 0x004, 'Switch' => 0x008, 'Host' => 0x010, 'IGMP' => 0x020, 'Repeater' => 0x040, 'VoIP-Phone' => 0x080, 'Remotely-Managed-Device' => 0x100, 'Supports-STP-Dispute' => 0x200, 'Two-port Mac Relay' => 0x400, ); sub munge_power { my $power = shift; my $decimal = substr( $power, -3 ); $power =~ s/$decimal$/\.$decimal/; return $power; } sub hasCDP { my $cdp = shift; my $ver = $cdp->{_version}; # SNMP v1 clients dont have the globals if ( defined $ver and $ver == 1 ) { my $cdp_ip = $cdp->cdp_ip(); # See if anything in cdp cache, if so we have cdp return 1 if ( defined $cdp_ip and scalar( keys %$cdp_ip ) ); return; } return $cdp->cdp_run(); } sub cdp_if { my $cdp = shift; # See if by some miracle Cisco implemented the cdpCacheIfIndex entry my $cdp_index = $cdp->cdp_index(); return $cdp_index if defined $cdp_index; # Nope, didn't think so. Now we fake it. my $cdp_ip = $cdp->cdp_ip(); unless ( defined $cdp_ip ) { $cdp->error_throw( "SNMP::Info::CDP:cdp_if() - Device doesn't have cdp_ip() data. Can't fake cdp_index()" ); return; } my %cdp_if; foreach my $key ( keys %$cdp_ip ) { next unless defined $key; my $iid = $key; # Truncate .1 from cdp cache entry $iid =~ s/\.\d+$//; $cdp_if{$key} = $iid; } return \%cdp_if; } sub cdp_ip { my $cdp = shift; my $partial = shift; my $cdp_addr = $cdp->cdp_addr($partial) || {}; my $cdp_proto = $cdp->cdp_proto($partial) || {}; my %cdp_ip; foreach my $key ( keys %$cdp_addr ) { my $addr = $cdp_addr->{$key}; my $proto = $cdp_proto->{$key}; next unless defined $addr; next if ( defined $proto and $proto ne 'ip' ); my $ip = join( '.', unpack( 'C4', $addr ) ); $cdp_ip{$key} = $ip; } return \%cdp_ip; } sub cdp_cap { my $cdp = shift; my $partial = shift; # Some devices return a hex-string, others return a space separated # string, we need the raw data to determine return value and # take appropriate action my $cdp_caps = $cdp->cdp_capabilities_raw($partial) || {}; my %cdp_cap; foreach my $key ( keys %$cdp_caps ) { my $cap_raw = $cdp_caps->{$key}; next unless $cap_raw; # Simple check, smallest single string is either Host or IGMP with a # space added on the end for a length of 5, hex string is normally # 4 bytes, but since only one byte was traditionally needed process # as hex for a length of 4 or less if ( length $cap_raw < 5 ) { my $cap_hex = join( '', map { sprintf "%x", $_ } unpack( 'C*', $cap_raw ) ); foreach my $capability ( keys %CDP_CAPABILITIES ) { if ( ( hex $cap_hex ) & $CDP_CAPABILITIES{$capability} ) { push( @{ $cdp_cap{$key} }, $capability ); } } } else { my @caps = split /\s/, $cap_raw; push( @{ $cdp_cap{$key} }, @caps ); } } return \%cdp_cap; } sub cdp_id { my $cdp = shift; my $partial = shift; my $ch = $cdp->cdp_dev_id($partial) || {}; my %cdp_id; foreach my $key ( sort keys %$ch ) { my $id = $ch->{$key}; next unless $id; $id = SNMP::Info::munge_mac($id) || SNMP::Info::munge_null($id); $cdp_id{$key} = $id; } return \%cdp_id; } 1; __END__ =head1 NAME SNMP::Info::CDP - SNMP Interface to Cisco Discovery Protocol (CDP) using SNMP =head1 AUTHOR Max Baker =head1 SYNOPSIS my $cdp = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'router', Community => 'public', Version => 2 ); my $class = $cdp->class(); print " Using device sub class : $class\n"; $hascdp = $cdp->hasCDP() ? 'yes' : 'no'; # Print out a map of device ports with CDP neighbors: my $interfaces = $cdp->interfaces(); my $cdp_if = $cdp->cdp_if(); my $cdp_ip = $cdp->cdp_ip(); my $cdp_port = $cdp->cdp_port(); foreach my $cdp_key (keys %$cdp_ip){ my $iid = $cdp_if->{$cdp_key}; my $port = $interfaces->{$iid}; my $neighbor = $cdp_ip->{$cdp_key}; my $neighbor_port = $cdp_port->{$cdp_key}; print "Port : $port connected to $neighbor / $neighbor_port\n"; } =head1 DESCRIPTION SNMP::Info::CDP is a subclass of SNMP::Info that provides an object oriented interface to CDP information through SNMP. CDP is a Layer 2 protocol that supplies topology information of devices that also speak CDP, mostly switches and routers. CDP is implemented in Cisco and some HP devices. Create or use a device subclass that inherits this class. Do not use directly. Each device implements a subset of the global and cache entries. Check the return value to see if that data is held by the device. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $cdp->hasCDP() Is CDP is active in this device? Accounts for SNMP version 1 devices which may have CDP but not cdp_run() =item $cdp->cdp_run() Is CDP enabled on this device? Note that a lot of Cisco devices that implement CDP don't implement this value. @#%$! (C) =item $cdp->cdp_interval() Interval in seconds at which CDP messages are generated. (C) =item $cdp->cdp_holdtime() Time in seconds that CDP messages are kept. (C) =item $cdp->cdp_gid() Returns CDP device ID. This is the device id broadcast via CDP to other devices, and is what is retrieved from remote devices with $cdp->id(). (C) =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 CDP CACHE ENTRIES =over =item $cdp->cdp_capabilities() Returns Device Functional Capabilities. Results are munged into an ascii binary string, MSB. Each digit represents a bit from the table below from the CDP Capabilities Mapping to Smartport Type table within the Cisco Small Business 200 Series Smart Switch Administration Guide, L: (Bit) - Description =over =item (0x400) - Two-Port MAC Relay. =item (0x200) - CAST Phone Port / CVTA / Supports-STP-Dispute depending upon platform. =item (0x100) - Remotely-Managed Device. =item (0x80) - VoIP Phone. =item (0x40) - Provides level 1 functionality. =item (0x20) - The bridge or switch does not forward IGMP Report packets on non router ports. =item (0x10) - Sends and receives packets for at least one network layer protocol. If the device is routing the protocol, this bit should not be set. =item (0x08) - Performs level 2 switching. The difference between this bit and bit 0x02 is that a switch does not run the Spanning-Tree Protocol. This device is assumed to be deployed in a physical loop-free topology. =item (0x04) - Performs level 2 source-route bridging. A source-route bridge would set both this bit and bit 0x02. =item (0x02) - Performs level 2 transparent bridging. =item (0x01) - Performs level 3 routing for at least one network layer protocol. =back Thanks to Martin Lorensen for a pointer to the original information and CPAN user Alex for updates. (C) =item $cdp->cdp_domain() Returns remote VTP Management Domain as defined in C (C) =item $cdp->cdp_duplex() Returns the port duplex status from remote devices. (C) =item $cdp->cdp_id() Returns remote device id string (C) =item $cdp->cdp_if() Returns the mapping to the SNMP Interface Table. Note that a lot devices don't implement $cdp->cdp_index(), So if it isn't around, we fake it. In order to map the cdp table entry back to the interfaces() entry, we truncate the last number off of it : # it exists, yay. my $cdp_index = $device->cdp_index(); return $cdp_index if defined $cdp_index; # if not, let's fake it my $cdp_ip = $device->cdp_ip(); my %cdp_if foreach my $key (keys %$cdp_ip){ $iid = $key; ## Truncate off .1 from cdp response $iid =~ s/\.\d+$//; $cdp_if{$key} = $iid; } return \%cdp_if; =item $cdp->cdp_index() Returns the mapping to the SNMP2 Interface table for CDP Cache Entries. Most devices don't implement this, so you probably want to use $cdp->cdp_if() instead. See cdp_if() entry. (C) =item $cdp->cdp_ip() If $cdp->cdp_proto() is supported, returns remote IPV4 address only. Otherwise it will return all addresses. (C) =item $cdp->cdp_addr() Returns remote address (C) =item $cdp->cdp_platform() Returns remote platform id (C) =item $cdp->cdp_port() Returns remote port ID (C) =item $cdp->cdp_proto() Returns remote address type received. Usually IP. (C) =item $cdp->cdp_ver() Returns remote hardware version (C) =item $cdp->cdp_vlan() Returns the remote interface native VLAN. (C) =item $cdp->cdp_power() Returns the amount of power consumed by remote device in milliwatts munged for decimal placement. (C) =item $cdp->cdp_cap() Returns hash of arrays with each array containing the system capabilities supported by the remote system. Possible elements in the array are C, C, C, C, C, C, C, C, C, C, and C. =back =head1 Data Munging Callback Subroutines =over =item $cdp->munge_power() Inserts a decimal at the proper location. =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoAgg.pm000444000765000024 1014413215550564 17320 0ustar00oliverstaff000000000000# SNMP::Info::CiscoAgg # # Copyright (c) 2014 SNMP::Info Developers # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoAgg; use strict; use Exporter; use SNMP::Info::IEEE802dot3ad 'agg_ports_lag'; @SNMP::Info::CiscoAgg::ISA = qw/ SNMP::Info::IEEE802dot3ad Exporter /; @SNMP::Info::CiscoAgg::EXPORT_OK = qw/ agg_ports /; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::IEEE802dot3ad::MIBS, 'CISCO-PAGP-MIB' => 'pagpGroupIfIndex', ); %GLOBALS = (); %FUNCS = (); %MUNGE = (); sub agg_ports_pagp { my $dev = shift; # Note that this mapping will miss any interfaces that are down during # polling. If one of the members is up, we could use # pagpAdminGroupCapability to figure things out, but if they're all # down, we're hosed. Since we could be hosed anyway, we skip the fancy # stuff. my $mapping = {}; my $group = $dev->pagpGroupIfIndex; for my $slave (keys %$group) { my $master = $group->{$slave}; next if($master == 0 || $slave == $master); $mapping->{$slave} = $master; } return $mapping; } # until we have PAgP data and need to combine with LAG data sub agg_ports { my $ret = {%{agg_ports_pagp(@_)}, %{agg_ports_lag(@_)}}; return $ret; } 1; __END__ =head1 NAME SNMP::Info::CiscoAgg - SNMP Interface to Cisco Aggregated Links =head1 AUTHOR SNMP::Info Developers =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $info = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $info->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION This class provides access to Aggregated Links configuration on Cisco devices. It combines Cisco PAgP and IEEE 802.3ad information. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes L =head2 Required MIBs =over =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 METHODS =over 4 =item C Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =item C Implements the PAgP LAG info retrieval. Merged into C data automatically. =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoConfig.pm000444000765000024 3366713215550564 20046 0ustar00oliverstaff000000000000# SNMP::Info::CiscoConfig # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoConfig; use strict; use Exporter; use SNMP::Info; @SNMP::Info::CiscoConfig::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::CiscoConfig::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'CISCO-CONFIG-COPY-MIB' => 'ccCopyTable', 'CISCO-FLASH-MIB' => 'ciscoFlashCopyTable', 'OLD-CISCO-SYS-MIB' => 'writeMem', ); %GLOBALS = ( # OLD-CISCO-SYS-MIB 'old_write_mem' => 'writeMem', 'old_write_net' => 'writeNet', ); %FUNCS = ( # CISCO-COPY-CONFIG-MIB::ccCopyTable 'config_protocol' => 'ccCopyProtocol', 'config_source_type' => 'ccCopySourceFileType', 'config_dest_type' => 'ccCopyDestFileType', 'config_server_addr' => 'ccCopyServerAddress', 'config_filename' => 'ccCopyFileName', 'config_username' => 'ccCopyUserName', 'config_password' => 'ccCopyUserPassword', 'config_notify_complete' => 'ccCopyNotificationOnCompletion', 'config_copy_state' => 'ccCopyState', 'config_copy_start_time' => 'ccCopyTimeStarted', 'config_copy_complete_time' => 'ccCopyTimeCompleted', 'config_fail_cause' => 'ccCopyFailCause', 'config_row_status' => 'ccCopyEntryRowStatus', # CISCO-FLASH-MIB::ciscoFlashCopyTable 'flash_copy_cmd' => 'ciscoFlashCopyCommand', 'flash_copy_protocol' => 'ciscoFlashCopyProtocol', 'flash_copy_address' => 'ciscoFlashCopyServerAddress', 'flash_copy_source' => 'ciscoFlashCopySourceName', 'flash_copy_dest' => 'ciscoFlashCopyDestinationName', 'flash_copy_row_status' => 'ciscoFlashCopyEntryStatus', ); %MUNGE = (); sub copy_run_tftp { my $ciscoconfig = shift; my ( $tftphost, $tftpfile ) = @_; srand( time() ^ ( $$ + ( $$ << 15 ) ) ); my $rand = int( rand( 1 << 24 ) ); print "Saving running config to $tftphost as $tftpfile\n" if $ciscoconfig->debug(); #Try new method first fall back to old method if ( $ciscoconfig->set_config_protocol( 1, $rand ) ) { print "Using new method, row iid: $rand\n" if $ciscoconfig->debug(); #Check each set, delete created row if any fail unless ( $ciscoconfig->set_config_row_status( 5, $rand ) ) { $ciscoconfig->error_throw("Initializing config copy instruction failed"); return; } unless ( $ciscoconfig->set_config_source_type( 4, $rand ) ) { $ciscoconfig->error_throw("Setting source type failed"); unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { $ciscoconfig->error_throw( "Setting source type failed and failed to delete row $rand" ); } return; } unless ( $ciscoconfig->set_config_dest_type( 1, $rand ) ) { $ciscoconfig->error_throw("Setting destination type failed"); unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { $ciscoconfig->error_throw( "Setting dest type failed and failed to delete row $rand" ); } return; } unless ( $ciscoconfig->set_config_server_addr( $tftphost, $rand ) ) { $ciscoconfig->error_throw("Setting tftp server failed"); unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { $ciscoconfig->error_throw( "Setting tftp server failed and failed to delete row $rand" ); } return; } unless ( $ciscoconfig->set_config_filename( $tftpfile, $rand ) ) { $ciscoconfig->error_throw("Setting file name failed"); unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { $ciscoconfig->error_throw( "Setting file name failed and failed to delete row $rand" ); } return; } unless ( $ciscoconfig->set_config_row_status( 1, $rand ) ) { $ciscoconfig->error_throw("Initiating transfer failed"); unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { $ciscoconfig->error_throw( "Initiating transfer failed and failed to delete row $rand" ); } return; } my $status = 0; my $timer = 0; # Hard-coded timeout of approximately 5 minutes, we can wrap this in an # option later if needed my $timeout = 300; while ( $status !~ /successful|failed/ ) { my $t = $ciscoconfig->config_copy_state($rand); $status = $t->{$rand}; last if $status =~ /successful|failed/; $timer += 1; if ( $timer >= $timeout ) { $status = 'failed'; last; } sleep 1; } unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { print "Failed deleting row, iid $rand\n" if $ciscoconfig->debug(); } if ( $status eq 'successful' ) { print "Save operation successful\n" if $ciscoconfig->debug(); return 1; } if ( $status eq 'failed' ) { $ciscoconfig->error_throw("Save operation failed"); return; } } print "Using old method\n" if $ciscoconfig->debug(); unless ( $ciscoconfig->set_old_write_net( $tftpfile, $tftphost ) ) { $ciscoconfig->error_throw("Save operation failed"); return; } return 1; } sub copy_run_start { my $ciscoconfig = shift; srand( time() ^ ( $$ + ( $$ << 15 ) ) ); my $rand = int( rand( 1 << 24 ) ); print "Saving running config to memory\n" if $ciscoconfig->debug(); if ( $ciscoconfig->set_config_source_type( 4, $rand ) ) { print "Using new method, row iid: $rand\n" if $ciscoconfig->debug(); #Check each set, delete created row if any fail unless ( $ciscoconfig->set_config_dest_type( 3, $rand ) ) { $ciscoconfig->error_throw("Setting dest type failed"); unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { $ciscoconfig->error_throw( "Setting dest type failed and failed to delete row $rand" ); } return; } unless ( $ciscoconfig->set_config_row_status( 1, $rand ) ) { $ciscoconfig->error_throw("Initiating save failed"); unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { $ciscoconfig->error_throw( "Initiating save failed and failed to delete row $rand"); } return; } my $status = 0; my $timer = 0; # Hard-coded timeout of approximately 5 minutes, we can wrap this in an # option later if needed my $timeout = 300; while ( $status !~ /successful|failed/ ) { my $t = $ciscoconfig->config_copy_state($rand); $status = $t->{$rand}; last if $status =~ /successful|failed/; $timer += 1; if ( $timer >= $timeout ) { $status = 'failed'; last; } sleep 1; } unless ( $ciscoconfig->set_config_row_status( 6, $rand ) ) { print "Failed deleting row, iid $rand\n" if $ciscoconfig->debug(); } if ( $status eq 'successful' ) { print "Save operation successful\n" if $ciscoconfig->debug(); return 1; } if ( $status eq 'failed' ) { $ciscoconfig->error_throw("Save operation failed"); return; } } print "Using old method\n" if $ciscoconfig->debug(); unless ( $ciscoconfig->set_old_write_mem(1) ) { $ciscoconfig->error_throw("Save operation failed"); return; } return 1; } 1; __END__ =head1 NAME SNMP::Info::CiscoConfig - SNMP Interface to Cisco Configuration Files =head1 AUTHOR Justin Hunter, Eric Miller =head1 SYNOPSIS my $ciscoconfig = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $ciscoconfig->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION SNMP::Info::CiscoConfig is a subclass of SNMP::Info that provides an interface to F, F, and F. These MIBs facilitate the writing of configuration files. Use or create a subclass of SNMP::Info that inherits this one. Do not use directly. =head2 Inherited Classes =over None. =back =head2 Required MIBs =over =item F =item F =item F =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $ciscoconfig->old_write_mem() (C) =item $ciscoconfig->old_write_net() (C) =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =back =head2 Config Copy Request Table (C) =over =item $ciscoconfig->config_protocol() (C) =item $ciscoconfig->config_source_type() (C) =item $ciscoconfig->config_dest_type() (C) =item $ciscoconfig->config_server_addr() (C) =item $ciscoconfig->config_filename() (C) =item $ciscoconfig->config_username() (C) =item $ciscoconfig->config_password() (C) =item $ciscoconfig->config_notify_complete() (C) =item $ciscoconfig->config_copy_state() (C) =item $ciscoconfig->config_copy_start_time() (C) =item $ciscoconfig->config_copy_complete_time() (C) =item $ciscoconfig->config_fail_cause() (C) =item $ciscoconfig->config_row_status() (C) =back =head2 Flash Copy Table (C) Table of Flash copy operation entries. =over =item $ciscoconfig->flash_copy_cmd() (C) =item $ciscoconfig->flash_copy_protocol() (C) =item $ciscoconfig->flash_copy_address() (C) =item $ciscoconfig->flash_copy_source() (C) =item $ciscoconfig->flash_copy_dest() (C) =item $ciscoconfig->flash_copy_row_status() (C) =back =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item $ciscoconfig->copy_run_tftp (tftpserver, tftpfilename ) Store the running configuration on a TFTP server. Equivalent to the CLI commands "copy running-config tftp" or "write net". This method attempts to use newer "copy running-config tftp" procedure first and then the older "write net" procedure if that fails. The newer procedure is supported Cisco devices with the F available, Cisco IOS software release 12.0 or on some devices as early as release 11.2P. The older procedure has been depreciated by Cisco and is utilized only to support devices running older code revisions. Example: $ciscoconfig->copy_run_tftp('1.2.3.4', 'myconfig') or die "Couldn't save config. ",$ciscoconfig->error(1); =item $ciscoconfig->copy_run_start() Copy the running configuration to the start up configuration. Equivalent to the CLI command C<"copy running-config startup-config"> or C<"write mem">. This method attempts to use newer C<"copy running-config startup-config"> procedure first and then the older C<"write mem"> procedure if that fails. The newer procedure is supported Cisco devices with the F available, Cisco IOS software release 12.0 or on some devices as early as release 11.2P. The older procedure has been depreciated by Cisco and is utilized only to support devices running older code revisions. Example: $ciscoconfig->copy_run_start() or die "Couldn't save config. ",$ciscoconfig->error(1); =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoPortSecurity.pm000444000765000024 2233213215550564 21300 0ustar00oliverstaff000000000000# SNMP::Info::CiscoPortSecurity # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoPortSecurity; use strict; use Exporter; @SNMP::Info::CiscoPortSecurity::ISA = qw/Exporter/; @SNMP::Info::CiscoPortSecurity::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE %PAECAPABILITIES/; $VERSION = '3.39'; %MIBS = ( 'CISCO-PORT-SECURITY-MIB' => 'ciscoPortSecurityMIB', 'CISCO-PAE-MIB' => 'ciscoPaeMIB', 'IEEE8021-PAE-MIB' => 'dot1xAuthLastEapolFrameSource', ); %GLOBALS = ( # CISCO-PORT-SECURITY-MIB 'cps_clear' => 'cpsGlobalClearSecureMacAddresses', 'cps_notify' => 'cpsGlobalSNMPNotifControl', 'cps_rate' => 'cpsGlobalSNMPNotifRate', 'cps_enable' => 'cpsGlobalPortSecurityEnable', 'cps_mac_count' => 'cpsGlobalTotalSecureAddress', 'cps_mac_max' => 'cpsGlobalMaxSecureAddress', ); %FUNCS = ( # CISCO-PORT-SECURITY-MIB::cpsIfConfigTable 'cps_i_limit_val' => 'cpsIfInvalidSrcRateLimitValue', 'cps_i_limit' => 'cpsIfInvalidSrcRateLimitEnable', 'cps_i_sticky' => 'cpsIfStickyEnable', 'cps_i_clear_type' => 'cpsIfClearSecureMacAddresses', 'cps_i_shutdown' => 'cpsIfShutdownTimeout', 'cps_i_flood' => 'cpsIfUnicastFloodingEnable', 'cps_i_clear' => 'cpsIfClearSecureAddresses', 'cps_i_mac' => 'cpsIfSecureLastMacAddress', 'cps_i_count' => 'cpsIfViolationCount', 'cps_i_action' => 'cpsIfViolationAction', 'cps_i_mac_static' => 'cpsIfStaticMacAddrAgingEnable', 'cps_i_mac_type' => 'cpsIfSecureMacAddrAgingType', 'cps_i_mac_age' => 'cpsIfSecureMacAddrAgingTime', 'cps_i_mac_count' => 'cpsIfCurrentSecureMacAddrCount', 'cps_i_mac_max' => 'cpsIfMaxSecureMacAddr', 'cps_i_status' => 'cpsIfPortSecurityStatus', 'cps_i_enable' => 'cpsIfPortSecurityEnable', # CISCO-PORT-SECURITY-MIB::cpsIfVlanTable 'cps_i_v_mac_count' => 'cpsIfVlanCurSecureMacAddrCount', 'cps_i_v_mac_max' => 'cpsIfVlanMaxSecureMacAddr', 'cps_i_v' => 'cpsIfVlanIndex', # CISCO-PORT-SECURITY-MIB::cpsIfVlanSecureMacAddrTable 'cps_i_v_mac_status' => 'cpsIfVlanSecureMacAddrRowStatus', 'cps_i_v_mac_age' => 'cpsIfVlanSecureMacAddrRemainAge', 'cps_i_v_mac_type' => 'cpsIfVlanSecureMacAddrType', 'cps_i_v_vlan' => 'cpsIfVlanSecureVlanIndex', 'cps_i_v_mac' => 'cpsIfVlanSecureMacAddress', # CISCO-PORT-SECURITY-MIB::cpsSecureMacAddressTable 'cps_m_status' => 'cpsSecureMacAddrRowStatus', 'cps_m_age' => 'cpsSecureMacAddrRemainingAge', 'cps_m_type' => 'cpsSecureMacAddrType', 'cps_m_mac' => 'cpsSecureMacAddress', # IEEE8021-PAE-MIB::dot1xPaePortEntry 'pae_i_capabilities' => 'dot1xPaePortCapabilities', 'pae_i_last_eapol_frame_source' => 'dot1xAuthLastEapolFrameSource', ); %MUNGE = ( 'cps_i_mac' => \&SNMP::Info::munge_mac, 'cps_m_mac' => \&SNMP::Info::munge_mac, 'cps_i_v_mac' => \&SNMP::Info::munge_mac, 'pae_i_last_eapol_frame_source' => \&SNMP::Info::munge_mac, 'pae_i_capabilities' => \&munge_pae_capabilities, ); %PAECAPABILITIES = ( 0 => 'dot1xPaePortAuthCapable', 1 => 'dot1xPaePortSuppCapable' ); sub munge_pae_capabilities { my $bits = shift; return unless defined $bits; my @vals = map( $PAECAPABILITIES{$_}, sprintf( "%x", unpack( 'b*', $bits ) ) ); return join( ' ', @vals ); } 1; __END__ =head1 NAME SNMP::Info::CiscoPortSecurity - SNMP Interface to data from F and F =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $cps = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $cps->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::CiscoPortSecurity is a subclass of SNMP::Info that provides an interface to the F and F. These MIBs are used across the Catalyst family under CatOS and IOS. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =item F =item F =back =head1 GLOBALS These are methods that return scalar values from SNMP =over =back =head2 F globals =over =item $cps->cps_clear() (C) =item $cps->cps_notify() (C) =item $cps->cps_rate() (C) =item $cps->cps_enable() (C) =item $cps->cps_mac_count() (C) =item $cps->cps_mac_max() (C) =back =head1 TABLE METHODS =head2 C - Interface Config Table =over =item $cps->cps_i_limit_val() (C) =item $cps->cps_i_limit() (C) =item $cps->cps_i_sticky() (C) =item $cps->cps_i_clear_type() (C) =item $cps->cps_i_shutdown() (C) =item $cps->cps_i_flood() (C) =item $cps->cps_i_clear() (C) =item $cps->cps_i_mac() (C) =item $cps->cps_i_count() (C) =item $cps->cps_i_action() (C) =item $cps->cps_i_mac_static() (C) =item $cps->cps_i_mac_type() (C) =item $cps->cps_i_mac_age() (C) =item $cps->cps_i_mac_count() (C) =item $cps->cps_i_mac_max() (C) =item $cps->cps_i_status() (C) =item $cps->cps_i_enable() (C) =back =head2 C =over =item $cps->cps_i_v_mac_count() (C) =item $cps->cps_i_v_mac_max() (C) =item $cps->cps_i_v() (C) =back =head2 C =over =item $cps->cps_i_v_mac_status() (C) =item $cps->cps_i_v_mac_age() (C) =item $cps->cps_i_v_mac_type() (C) =item $cps->cps_i_v_vlan() (C) =item $cps->cps_i_v_mac() (C) =back =head2 C =over =item $cps->cps_m_status() (C) =item $cps->cps_m_age() (C) =item $cps->cps_m_type() (C) =item $cps->cps_m_mac() (C) =back =head2 C =over =item $cps->pae_i_capabilities() C Indicates the PAE functionality that this Port supports and that may be managed through this MIB munged to return either C<'dot1xPaePortAuthCapable'> or C<'dot1xPaePortSuppCapable'>. =item $cps->pae_i_last_eapol_frame_source() C The source MAC address carried in the most recently received EAPOL frame. =back =head1 Data Munging Callback Subroutines =over =item $cps->munge_pae_capabilities() Return either C<'dot1xPaePortAuthCapable'> or C<'dot1xPaePortSuppCapable'> based upon bit value. =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoPower.pm000444000765000024 1272313215550564 17723 0ustar00oliverstaff000000000000# SNMP::Info::CiscoPower # $Id$ # # Copyright (c) 2008 Bill Fenner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoPower; use strict; use Exporter; use SNMP::Info; @SNMP::Info::CiscoPower::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::CiscoPower::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'CISCO-POWER-ETHERNET-EXT-MIB' => 'cpeExtPsePortEntPhyIndex', 'CISCO-CDP-MIB' => 'cdpCachePowerConsumption' ); %GLOBALS = (); %FUNCS = ( 'cpeth_ent_phy' => 'cpeExtPsePortEntPhyIndex', 'peth_port_power' => 'cpeExtPsePortPwrConsumption', ); %MUNGE = (); # Cisco overcame the limitation of the module.port index of the # pethPsePortTable by adding another mapping table, which maps # a pethPsePortTable row to an entPhysicalTable index, which can # then be mapped to ifIndex. sub peth_port_ifindex { my $cpeth = shift; my $partial = shift; my $ent_phy = $cpeth->cpeth_ent_phy($partial); my $e_port = $cpeth->e_port(); my $peth_port_ifindex = {}; foreach my $i ( keys %$ent_phy ) { if ( $e_port->{ $ent_phy->{$i} } ) { $peth_port_ifindex->{$i} = $e_port->{ $ent_phy->{$i} }; } } return $peth_port_ifindex; } # peth_port_neg_power uses the same index as the other peth_port_* tables. # However, cdpCachePowerConsumption uses .. # Therefore, we have to invert peth_port_ifindex, to get to # the index that is expected and the rest of the code can re-invert it. sub peth_port_neg_power { my $cpeth = shift; my $partial = shift; # Ignoring partial, since it's not easy to implement properly. my $index = $cpeth->peth_port_ifindex(); my %inverse_index; foreach my $i ( keys %$index ) { $inverse_index{ $index->{$i} } = $i; } my $neg_power = $cpeth->cdpCachePowerConsumption(); my $peth_port_neg_power = {}; foreach my $i ( keys %$neg_power ) { my( $ifIndex, $nbrIndex ) = split( /\./, $i ); if ( defined( $inverse_index{ $ifIndex } ) ) { $peth_port_neg_power->{ $inverse_index{ $ifIndex } } = $neg_power->{ $i }; } } return $peth_port_neg_power; } 1; __END__ =head1 NAME SNMP::Info::CiscoPower - SNMP Interface to data stored in F. =head1 AUTHOR Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $poe = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $poe->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION The Info::PowerEthernet class needs a per-device helper function to properly map the C to C values. This class provides that helper, using F. It does not define any helpers for the extra values that this MIB contains. Create or use a device subclass that inherit this class. Do not use directly. For debugging purposes you can call this class directly as you would SNMP::Info my $poe = new SNMP::Info::CiscoPower (...); =head2 Inherited Classes none. Note that it requires that the device inherits from Info::Entity. =head2 Required MIBs =over =item F =back =head1 GLOBALS none. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Power Port Table =over =item $poe->peth_port_ifindex() Maps the C to C by way of the F. =item $poe->peth_port_power() Power supplied by PoE ports, in milliwatts (C) =back =head2 CDP Port table =over =item $poe->peth_port_neg_power() Power negotiated using CDP, in milliwatts (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoQOS.pm000444000765000024 1177713215550564 17301 0ustar00oliverstaff000000000000# SNMP::Info::CiscoQOS # $Id$ # # Copyright (c) 2005 Alexander Hartmaier # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoQOS; use strict; use Exporter; use SNMP::Info; @SNMP::Info::CiscoQOS::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::CiscoQOS::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'CISCO-CLASS-BASED-QOS-MIB' => 'cbQosIfIndex', ); %GLOBALS = (); %FUNCS = ( # CISCO-CLASS-BASED-QOS-MIB::cbQosServicePolicyTable 'qos_i_index' => 'cbQosIfIndex', 'qos_i_type' => 'cbQosIfType', 'qos_pol_direction' => 'cbQosPolicyDirection', # CISCO-CLASS-BASED-QOS-MIB::cbQosObjectsTable 'qos_obj_conf_index' => 'cbQosConfigIndex', 'qos_obj_type' => 'cbQosObjectsType', 'qos_obj_parent' => 'cbQosParentObjectsIndex', # CISCO-CLASS-BASED-QOS-MIB::cbQosCMCfgTable 'qos_cm_name' => 'cbQosCMName', 'qos_cm_desc' => 'cbQosCMDesc', 'qos_cm_info' => 'cbQosCMInfo', # CISCO-CLASS-BASED-QOS-MIB::cbQosCMStatsTable 'qos_octet_pre' => 'cbQosCMPrePolicyByte', 'qos_octet_post' => 'cbQosCMPostPolicyByte', # CISCO-CLASS-BASED-QOS-MIB::cbQosQueueingCfgTable 'qos_queueingcfg_bw' => 'cbQosQueueingCfgBandwidth', 'qos_queueingcfg_bw_units' => 'cbQosQueueingCfgBandwidthUnits', ); %MUNGE = (); 1; __END__ =head1 NAME SNMP::Info::CiscoQOS - SNMP Interface to Cisco's Quality of Service MIBs =head1 AUTHOR Alexander Hartmaier =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $qos = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $qos->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::CiscoQOS is a subclass of SNMP::Info that provides information about a cisco device's QoS config. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes none. =head2 Required MIBs =over =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBALS =over =item none =back =head1 TABLE METHODS =head2 Service Policy Table (C) This table describes the interfaces/media types and the policy map that are attached to it. =over =item $qos->qos_i_index() (C) =item $qos->qos_i_type() (C) =item $qos->qos_pol_direction() (C) =back =head2 Class Map Objects Table (C) =over =item $qos->qos_obj_index() (C) =item $qos->qos_obj_type() (C) =item $qos->qos_obj_parent() (C) =back =head2 Class Map Configuration Table (C) =over =item $qos->qos_cm_name() (C) =item $qos->qos_cm_desc() (C) =item $qos->qos_cm_info() (C) =back =head2 Class Map Stats Table (C) =over =item $qos->qos_octet_pre() (C) =item $qos->qos_octet_post() (C) =back =head2 Queueing Configuration Table (C) =over =item $qos->qos_queueingcfg_bw() (C) =item $qos->qos_queueingcfg_bw_units() (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoRTT.pm000444000765000024 665613215550564 17270 0ustar00oliverstaff000000000000# SNMP::Info::CiscoRTT # $Id$ # # Copyright (c) 2005 Alexander Hartmaier # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoRTT; use strict; use Exporter; use SNMP::Info; @SNMP::Info::CiscoRTT::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::CiscoRTT::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'CISCO-RTTMON-MIB' => 'rttMonCtrlAdminOwner', ); %GLOBALS = (); %FUNCS = ( # CISCO-RTTMON-MIB 'rtt_desc' => 'rttMonCtrlAdminOwner', 'rtt_last' => 'rttMonLatestRttOperCompletionTime', ); %MUNGE = (); 1; __END__ =head1 NAME SNMP::Info::CiscoRTT - SNMP Interface to Cisco's Round Trip Time MIBs =head1 AUTHOR Alexander Hartmaier =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $rtt = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $rtt->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::CiscoRTT is a subclass of SNMP::Info that provides information about a cisco device's RTT values. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes none. =head2 Required MIBs =over =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBALS =over None =back =head1 TABLE METHODS =head2 Overall Control Group Table This table is from C =over =item $rtt->rtt_desc() (C) =back =head2 Overall Control Group Table This table is from C =over =item $rtt->rtt_last() (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoStack.pm000444000765000024 3713113215550564 17674 0ustar00oliverstaff000000000000# SNMP::Info::CiscoStack # $Id$ # # Copyright (c) 2008 Max Baker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoStack; use strict; use Exporter; @SNMP::Info::CiscoStack::ISA = qw/Exporter/; @SNMP::Info::CiscoStack::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE %PORTSTAT/; $VERSION = '3.39'; %MIBS = ( 'CISCO-STACK-MIB' => 'ciscoStackMIB', ); %GLOBALS = ( 'sysip' => 'sysIpAddr', 'netmask' => 'sysNetMask', 'broadcast' => 'sysBroadcast', 'serial1' => 'chassisSerialNumber', 'serial2' => 'chassisSerialNumberString', 'model1' => 'chassisModel', 'ps1_type' => 'chassisPs1Type', 'ps1_status' => 'chassisPs1Status', 'ps2_type' => 'chassisPs2Type', 'ps2_status' => 'chassisPs2Status', 'slots' => 'chassisNumSlots', 'fan' => 'chassisFanStatus', ); %FUNCS = ( # CISCO-STACK-MIB::moduleEntry # These are blades in a catalyst device 'm_type' => 'moduleType', 'm_model' => 'moduleModel', 'm_serial' => 'moduleSerialNumber', 'm_serial_string' => 'moduleSerialNumberString', 'm_status' => 'moduleStatus', 'm_name' => 'moduleName', 'm_ports' => 'moduleNumPorts', 'm_ports_status' => 'modulePortStatus', 'm_hwver' => 'moduleHwVersion', 'm_fwver' => 'moduleFwVersion', 'm_swver' => 'moduleSwVersion', # Router Blades : 'm_ip' => 'moduleIPAddress', 'm_sub1' => 'moduleSubType', 'm_sub2' => 'moduleSubType2', # CISCO-STACK-MIB::portEntry 'p_name' => 'portName', 'p_type' => 'portType', 'p_status' => 'portOperStatus', 'p_status2' => 'portAdditionalStatus', 'p_speed' => 'portAdminSpeed', 'p_duplex' => 'portDuplex', 'p_port' => 'portIfIndex', 'p_rx_flow_control' => 'portOperRxFlowControl', 'p_tx_flow_control' => 'portOperTxFlowControl', 'p_rx_flow_control_admin' => 'portAdminRxFlowControl', 'p_tx_flow_control_admin' => 'portAdminTxFlowControl', 'p_oidx' => 'portCrossIndex', # CISCO-STACK-MIB::PortCpbEntry 'p_speed_admin' => 'portCpbSpeed', 'p_duplex_admin' => 'portCpbDuplex', ); %MUNGE = ( 'm_ports_status' => \&munge_port_status, 'p_duplex_admin' => \&SNMP::Info::munge_bits, ); %PORTSTAT = ( 1 => 'other', 2 => 'ok', 3 => 'minorFault', 4 => 'majorFault' ); # Changes binary byte describing each port into ascii, and returns # an ascii list separated by spaces. sub munge_port_status { my $status = shift; my @vals = map( $PORTSTAT{$_}, unpack( 'C*', $status ) ); return join( ' ', @vals ); } sub serial { my $stack = shift; my $serial1 = $stack->serial1(); my $serial2 = $stack->serial2(); return $serial1 if defined $serial1; return $serial2 if defined $serial2; return; } # Rules for older CatOS devices using CiscoStack # # You can configure Ethernet and Fast Ethernet interfaces to either full # duplex or half duplex. # # You cannot configure the duplex mode on Gigabit Ethernet ports (they are # always in full-duplex mode). # # If you set the port speed to auto, duplex mode is automatically set to auto. # # For operational duplex if portCpbDuplex is all zeros the port is a gigabit # port and duplex is always full. If the port is not operational and auto # return value will be undef since we don't know the operational status. # # Newer devices use ETHERLIKE-MIB to report operational duplex, this will be # checked in the device class. sub i_duplex { my $stack = shift; my $partial = shift; my $p_port = $stack->p_port() || {}; my $p_duplex = $stack->p_duplex() || {}; my $p_duplex_cap = $stack->p_duplex_admin() || {}; my $i_duplex = {}; foreach my $port ( keys %$p_duplex ) { my $iid = $p_port->{$port}; next unless defined $iid; next if ( defined $partial and $iid !~ /^$partial$/ ); # Test for gigabit if ( defined $p_duplex_cap->{$port} and $p_duplex_cap->{$port} == 0 ) { $i_duplex->{$iid} = 'full'; } # Auto is not a valid operational state elsif ( $p_duplex->{$port} eq 'auto' ) { next; } else { $i_duplex->{$iid} = $p_duplex->{$port}; } } return $i_duplex; } # For administrative duplex if portCpbDuplex is all zeros the port is a gigabit # port and duplex is always full. If portAdminSpeed is set to auto then the # duplex will be auto, otherwise use portDuplex. sub i_duplex_admin { my $stack = shift; my $partial = shift; my $p_port = $stack->p_port() || {}; my $p_duplex = $stack->p_duplex() || {}; my $p_duplex_cap = $stack->p_duplex_admin() || {}; my $p_speed = $stack->p_speed() || {}; my $i_duplex_admin = {}; foreach my $port ( keys %$p_duplex ) { my $iid = $p_port->{$port}; next unless defined $iid; next if ( defined $partial and $iid !~ /^$partial$/ ); # Test for gigabit if ( defined $p_duplex_cap->{$port} and $p_duplex_cap->{$port} == 1 ) { $i_duplex_admin->{$iid} = 'full'; } # Check admin speed for auto elsif ( $p_speed->{$port} =~ /auto/ ) { $i_duplex_admin->{$iid} = 'auto'; } else { $i_duplex_admin->{$iid} = $p_duplex->{$port}; } } return $i_duplex_admin; } sub i_speed_admin { my $stack = shift; my $partial = shift; my %i_speed_admin; my $p_port = $stack->p_port() || {}; my $p_speed = $stack->p_speed() || {}; my %speeds = ( 'autoDetect' => 'auto', 'autoDetect10100' => 'auto', 's10000000' => '10 Mbps', 's100000000' => '100 Mbps', 's1000000000' => '1.0 Gbps', 's10G' => '10 Gbps', ); %i_speed_admin = map { $p_port->{$_} => $speeds{ $p_speed->{$_} } } keys %$p_port; return \%i_speed_admin; } sub set_i_speed_admin { # map speeds to those the switch will understand my %speeds = qw/auto 1 10 10000000 100 100000000 1000 1000000000/; my $stack = shift; my ( $speed, $iid ) = @_; my $p_port = $stack->p_port() || {}; my %reverse_p_port = reverse %$p_port; $speed = lc($speed); return 0 unless defined $speeds{$speed}; $iid = $reverse_p_port{$iid}; return $stack->set_p_speed( $speeds{$speed}, $iid ); } sub set_i_duplex_admin { # map a textual duplex to an integer one the switch understands my %duplexes = qw/half 1 full 2 auto 4/; my $stack = shift; my ( $duplex, $iid ) = @_; if ( $duplex eq 'auto' ) { $stack->error_throw( "Software doesn't support setting auto duplex with set_i_duplex_admin() you must use set_i_speed_admin() and set both speed and duplex to auto" ); return 0; } my $p_port = $stack->p_port() || {}; my %reverse_p_port = reverse %$p_port; $duplex = lc($duplex); return 0 unless defined $duplexes{$duplex}; $iid = $reverse_p_port{$iid}; return $stack->set_p_duplex( $duplexes{$duplex}, $iid ); } 1; __END__ =head1 NAME SNMP::Info::CiscoStack - SNMP Interface to data from F and F =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $ciscostats = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $ciscostats->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::CiscoStack is a subclass of SNMP::Info that provides an interface to the C. This MIB is used across the Catalyst family under CatOS and IOS. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes none. =head2 Required MIBs =over =item F =back =head1 GLOBALS =over =item $stack->broadcast() (C) =item $stack->fan() (C) =item $stack->model() (C) =item $stack->netmask() (C) =item $stack->ps1_type() (C) =item $stack->ps2_type() (C) =item $stack->ps1_status() (C) =item $stack->ps2_status() (C) =item $stack->serial() (C) or (C) =item $stack->slots() (C) =back =head1 TABLE METHODS =head2 Interface Tables =over =item $stack->i_physical() Returns a map to IID for ports that are physical ports, not vlans, etc. =item $stack->i_type() Crosses p_port() with p_type() and returns the results. Overrides with C if p_type() isn't available. =item $stack->i_duplex() Returns reference to hash of iid to current link duplex setting. First checks for fixed gigabit ports which are always full duplex. Next, if the port is not operational and reported port duplex (C) is auto then the operational duplex can not be determined. Otherwise it uses the reported port duplex (C). =item $stack->i_duplex_admin() Returns reference to hash of iid to administrative duplex setting. First checks for fixed gigabit ports which are always full duplex. Next checks the port administrative speed (C) which if set to autonegotiate then the duplex will also autonegotiate, otherwise it uses the reported port duplex (C). =item $stack->i_speed_admin() Returns reference to hash of iid to administrative speed setting. C =item $stack->set_i_speed_admin(speed, ifIndex) Sets port speed, must be supplied with speed and port C Speed choices are 'auto', '10', '100', '1000' Crosses $stack->p_port() with $stack->p_duplex() to utilize port C. Example: my %if_map = reverse %{$stack->interfaces()}; $stack->set_i_speed_admin('auto', $if_map{'FastEthernet0/1'}) or die "Couldn't change port speed. ",$stack->error(1); =item $stack->set_i_duplex_admin(duplex, ifIndex) Sets port duplex, must be supplied with duplex and port C Speed choices are 'auto', 'half', 'full' Crosses $stack->p_port() with $stack->p_duplex() to utilize port C. Example: my %if_map = reverse %{$stack->interfaces()}; $stack->set_i_duplex_admin('auto', $if_map{'FastEthernet0/1'}) or die "Couldn't change port duplex. ",$stack->error(1); =back =head2 Module table This table holds configuration information for each of the blades installed in the Catalyst device. =over =item $stack->m_type() (C) =item $stack->m_model() (C) =item $stack->m_serial() (C) =item $stack->m_status() (C) =item $stack->m_name() (C) =item $stack->m_ports() (C) =item $stack->m_ports_status() Returns a list of space separated status strings for the ports. To see the status of port 4 : @ports_status = split(' ', $stack->m_ports_status() ); $port4 = $ports_status[3]; (C) =item $stack->m_ports_hwver() (C) =item $stack->m_ports_fwver() (C) =item $stack->m_ports_swver() (C) =item $stack->m_ports_ip() (C) =item $stack->m_ports_sub1() (C) =item $stack->m_ports_sub2() (C) =back =head2 Modules - Router Blades =over =item $stack->m_ip() (C) =item $stack->m_sub1() (C) =item $stack->m_sub2() (C) =back =head2 Port Entry Table (C) =over =item $stack->p_name() (C) =item $stack->p_type() (C) =item $stack->p_status() (C) =item $stack->p_status2() (C) =item $stack->p_speed() (C) =item $stack->p_duplex() (C) =item $stack->p_port() (C) =item $stack->p_rx_flow_control() Can be either C C or C "Indicates the receive flow control operational status of the port. If the port could not agree with the far end on a link protocol, its operational status will be disagree(3)." C =item $stack->p_tx_flow_control() Can be either C C or C "Indicates the transmit flow control operational status of the port. If the port could not agree with the far end on a link protocol, its operational status will be disagree(3)." C =item $stack->p_rx_flow_control_admin() Can be either C C or C "Indicates the receive flow control administrative status set on the port. If the status is set to on(1), the port will require the far end to send flow control. If the status is set to off(2), the port will not allow far end to send flow control. If the status is set to desired(3), the port will allow the far end to send the flow control." C =item $stack->p_tx_flow_control_admin() Can be either C C or C "Indicates the transmit flow control administrative status set on the port. If the status is set to on(1), the port will send flow control to the far end. If the status is set to off(2), the port will not send flow control to the far end. If the status is set to desired(3), the port will send flow control to the far end if the far end supports it." C =back =head2 Port Capability Table (C) =over =item $stack->p_speed_admin() (C) =item $stack->p_duplex_admin() (C) =back =head1 Data Munging Callback Subroutines =over =item $stack->munge_port_status() Munges binary byte describing each port into ascii, and returns an ascii list separated by spaces. =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoStats.pm000444000765000024 3321513215550564 17724 0ustar00oliverstaff000000000000# SNMP::Info::CiscoStats # $Id$ # # Changes since Version 0.7 Copyright (c) 2008-2009 Max Baker and SNMP::Info Developers # All rights reserved. # # Copyright (c) 2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoStats; use strict; use Exporter; use SNMP::Info; @SNMP::Info::CiscoStats::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::CiscoStats::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'SNMPv2-MIB' => 'sysDescr', 'CISCO-PROCESS-MIB' => 'cpmCPUTotal5sec', 'CISCO-MEMORY-POOL-MIB' => 'ciscoMemoryPoolUsed', 'OLD-CISCO-SYSTEM-MIB' => 'writeMem', 'CISCO-PRODUCTS-MIB' => 'sysName', 'ENTITY-MIB' => 'entPhysicalSoftwareRev', 'CISCO-IMAGE-MIB' => 'ciscoImageString', # some older catalysts live here 'CISCO-STACK-MIB' => 'wsc1900sysID', 'CISCO-ENTITY-VENDORTYPE-OID-MIB' => 'cevChassis', 'CISCO-FLASH-MIB' => 'ciscoFlashDeviceSize', ); %GLOBALS = ( 'description' => 'sysDescr', 'ent_physical_software_rev' => 'entPhysicalSoftwareRev.1', # We will use the numeric OID's so that we don't require people # to install v1 MIBs, which can conflict. # OLD-CISCO-CPU-MIB:avgBusyPer 'ios_cpu' => '1.3.6.1.4.1.9.2.1.56.0', 'ios_cpu_1min' => '1.3.6.1.4.1.9.2.1.57.0', 'ios_cpu_5min' => '1.3.6.1.4.1.9.2.1.58.0', # CISCO-PROCESS-MIB 'cat_cpu' => 'cpmCPUTotal5sec.9', 'cat_cpu_1min' => 'cpmCPUTotal1min.9', 'cat_cpu_5min' => 'cpmCPUTotal5min.9', # OLD-CISCO-SYSTEM-MIB 'write_mem' => 'writeMem', 'rom_id' => 'romId', ); %FUNCS = ( # CISCO-MEMORY-POOL-MIB::ciscoMemoryPoolTable 'cisco_mem_free' => 'ciscoMemoryPoolFree', 'cisco_mem_used' => 'ciscoMemoryPoolUsed', # CISCO-FLASH-MIB::ciscoFlashDeviceTable 'cisco_flash_size' => 'ciscoFlashDeviceSize', # CISCO-IMAGE-MIB 'ci_images' => 'ciscoImageString', ); %MUNGE = (); sub vendor { return 'cisco'; } sub os { my $l2 = shift; my $descr = $l2->description() || ''; # order here matters - there are Catalysts that run IOS and have catalyst # in their description field, as well as Catalysts that run IOS-XE. return 'ios-xe' if ( $descr =~ /IOS-XE/ ); return 'ios-xr' if ( $descr =~ /IOS XR/ ); return 'ios' if ( $descr =~ /IOS/ ); return 'catalyst' if ( $descr =~ /catalyst/i ); return 'css' if ( $descr =~ /Content Switch SW/ ); return 'css-sca' if ( $descr =~ /Cisco Systems Inc CSS-SCA-/ ); return 'pix' if ( $descr =~ /Cisco PIX Security Appliance/ ); return 'asa' if ( $descr =~ /Cisco Adaptive Security Appliance/ ); return 'san-os' if ( $descr =~ /Cisco SAN-OS/ ); if ( $descr =~ /Application Control Engine Service Module/ ) { # Only the admin context implements the entity MIB return 'ace-admin' if defined $l2->ent_physical_software_rev(); return 'ace-context'; } # Pre-version 3 FWSMs return 'fwsm' if ( $descr =~ /Cisco Secure FWSM Firewall/ ); # Version 3+ FWSMs (currently untested against version 4) if ( $descr =~ /Firewall Services Module/ ) { my $model = $l2->model(); if ( defined $model && $model eq "WsSvcFwm1sc" ) { # Only the admin context implements the entity MIB return 'fwsm-admin' if defined $l2->ent_physical_software_rev(); return 'fwsm-context'; } # Non context mode FWSM return 'fwsm'; } return; } sub os_ver { my $l2 = shift; my $os = $l2->os(); my $descr = $l2->description(); # Older Catalysts if ( defined $os and $os eq 'catalyst' and defined $descr and $descr =~ m/V(\d{1}\.\d{2}\.\d{2})/ ) { return $1; } if ( defined $os and $os eq 'css' and defined $descr and $descr =~ m/Content Switch SW Version ([0-9\.\(\)]+) with SNMPv1\/v2c Agent/ ) { return $1; } if ( defined $os and $os eq 'css-sca' and defined $descr and $descr =~ m/Cisco Systems Inc CSS-SCA-2FE-K9, ([0-9\.\(\)]+) Release / ) { return $1; } if ( defined $os and $os eq 'pix' and defined $descr and $descr =~ m/Cisco PIX Security Appliance Version ([0-9\.\(\)]+)/ ) { return $1; } if ( defined $os and $os eq 'asa' and defined $descr and $descr =~ m/Cisco Adaptive Security Appliance Version ([0-9\.\(\)]+)/ ) { return $1; } if ( defined $os and $os =~ /^ace/ ) { return $l2->ent_physical_software_rev(); } if ( defined $os and $os =~ /^fwsm/ and defined $descr and $descr =~ m/Version (\d+\.\d+(\(\d+\)){0,1})/ ) { return $1; } if ( defined $os and $os eq 'ios-xr' and defined $descr and $descr =~ m/Version (\d+[\.\d]+)/ ) { return $1; } # Newer Catalysts and IOS devices if ( defined $descr and $descr =~ m/Version (\d+\.\d+\([^)]+\)[^,\s]*)(,|\s)+/ ) { return $1; } # Generic fallback: try to determine running image from CISCO-IMAGE-MIB my $image_info = $l2->ciscoImageString() || {}; foreach my $row (keys %$image_info) { my $info_string = $image_info->{$row}; if ($info_string =~ /CW_VERSION\$([^\$]+)\$/) { return $1; } } return; } sub os_bin { my $self = shift; my $rom_id = $self->rom_id(); if ($rom_id =~ m/Version ([^,]+),/) { return $1; } return; } sub cpu { my $self = shift; my $ios_cpu = $self->ios_cpu(); return $ios_cpu if defined $ios_cpu; my $cat_cpu = $self->cat_cpu(); return $cat_cpu; } sub cpu_1min { my $self = shift; my $ios_cpu_1min = $self->ios_cpu_1min(); return $ios_cpu_1min if defined $ios_cpu_1min; my $cat_cpu_1min = $self->cat_cpu_1min(); return $cat_cpu_1min; } sub cpu_5min { my $self = shift; my $ios_cpu_5min = $self->ios_cpu_5min(); return $ios_cpu_5min if defined $ios_cpu_5min; my $cat_cpu_5min = $self->cat_cpu_5min(); return $cat_cpu_5min; } sub mem_free { my $self = shift; my $mem_free; my $cisco_mem_free = $self->cisco_mem_free() || {}; foreach my $mem_free_val ( values %$cisco_mem_free ) { $mem_free += $mem_free_val; } return $mem_free; } sub mem_used { my $self = shift; my $mem_used; my $cisco_mem_used = $self->cisco_mem_used() || {}; foreach my $mem_used_val ( values %$cisco_mem_used ) { $mem_used += $mem_used_val; } return $mem_used; } sub mem_total { my $self = shift; my $mem_total; my $cisco_mem_free = $self->cisco_mem_free() || {}; my $cisco_mem_used = $self->cisco_mem_used() || {}; foreach my $mem_entry ( keys %$cisco_mem_free ) { my $mem_free = $cisco_mem_free->{$mem_entry} || 0; my $mem_used = $cisco_mem_used->{$mem_entry} || 0; $mem_total += ( $mem_free + $mem_used ); } return $mem_total; } sub flashmem_total { my $self = shift; my $flashmem_total; my $flash_sizes = $self->cisco_flash_size; foreach my $flash_index ( keys %$flash_sizes ) { $flashmem_total += $flash_sizes->{$flash_index}; } return $flashmem_total; } 1; __END__ =head1 NAME SNMP::Info::CiscoStats - Perl5 Interface to CPU and Memory stats for Cisco Devices =head1 AUTHOR Eric Miller, Max Baker, Sam Stickland =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $ciscostats = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly on to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $ciscostats->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::CiscoStats is a subclass of SNMP::Info that provides cpu, memory, os and version information about Cisco Devices. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =item F =item F =item F =item F =item F =item F =item F =item F =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBALS =over =item $ciscostats->cpu() Returns ios_cpu() or cat_cpu(), whichever is available. =item $ciscostats->cpu_1min() Returns ios_cpu_1min() or cat_cpu1min(), whichever is available. =item $ciscostats->cpu_5min() Returns ios_cpu_5min() or cat_cpu5min(), whichever is available. =item $ciscostats->mem_total() Returns mem_free() + mem_used() =item $ciscostats->vendor() 'cisco' =item $ciscostats->os() Tries to parse if device is running 'IOS', 'CatOS', 'IOS-XE' or something else from description() Available values: 'ios' for Cisco IOS 'ios-xe' for Cisco IOS XE 'ios-xr' for Cisco IOS XR 'pix' for Cisco PIX 'asa' for Cisco ASA 'fwsm' for Single-mode FWSM 'fwsm-admin' for Admin context of multi-context FWSM 'fwsm-context' for Standard context of multi-context FWSM 'ace-admin' for Admin context of ACE module 'ace-context' for Standard context of ACE module (NB: No OS version detection is available, but will be the same as it's 'ace admin') 'css' for Cisco Content Switch 'css-sca' for Cisco Content Switch Secure Content Acceleration 'san-os' for Cisco SAN-OS =item $ciscostats->os_ver() Tries to parse device operating system version from description(), falls back to parsing C if needed =item $ciscostats->os_bin() Tries to parse C version from rom_id() string =item $ciscostats->ios_cpu() Current CPU usage in percent. C<1.3.6.1.4.1.9.2.1.56.0> = C =item $ciscostats->ios_cpu_1min() Average CPU Usage in percent over the last minute. C<1.3.6.1.4.1.9.2.1.57.0> =item $ciscostats->ios_cpu_5min() Average CPU Usage in percent over the last 5 minutes. C<1.3.6.1.4.1.9.2.1.58.0> =item $ciscostats->cat_cpu() Current CPU usage in percent. C =item $ciscostats->cat_cpu_1min() Average CPU Usage in percent over the last minute. C =item $ciscostats->cat_cpu_5min() Average CPU Usage in percent over the last 5 minutes. C =item $ciscostats->mem_free() Main DRAM free of the device in bytes. C =item $ciscostats->mem_used() Main DRAM used of the device in bytes. C =item $ciscostats->mem_total() Main DRAM of the device in bytes. C + C =item $ciscostats->flashmem_total() Flash memory of the device in bytes. C =back =head1 TABLE METHODS =head2 Cisco Memory Pool Table (C) =over =item $ciscostats->cisco_mem_free() The number of bytes from the memory pool that are currently unused on the managed device. (C) =item $ciscostats->cisco_mem_used() The number of bytes from the memory pool that are currently in use by applications on the managed device. (C) =back =head2 Cisco Flash Device Table (C) =over =item $ciscostats->cisco_flash_size() Total size of the Flash device. For a removable device, the size will be zero if the device has been removed. (C) =back =head2 Cisco Image Table (C) =over =item $ci->ci_images() Returns the table of image strings. C =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoStpExtensions.pm000444000765000024 2306413215550564 21455 0ustar00oliverstaff000000000000# SNMP::Info::CiscoStpExtensions # # Copyright (c)2009 Carlos Vicente # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * Neither the name of the author nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoStpExtensions; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Bridge; use vars qw/$VERSION $DEBUG %MIBS %FUNCS %GLOBALS %MUNGE %PORTSTAT $INIT/; $VERSION = '3.39'; @SNMP::Info::CiscoStpExtensions::ISA = qw/SNMP::Info::Bridge SNMP::Info Exporter/; @SNMP::Info::CiscoStpExtensions::EXPORT_OK = qw//; %MIBS = ( %SNMP::Info::Bridge::MIBS, 'CISCO-STP-EXTENSIONS-MIB' => 'stpxSpanningTreeType', ); %GLOBALS = ( %SNMP::Info::Bridge::GLOBALS, 'stpx_mst_config_digest' => 'stpxSMSTConfigDigest', 'stpx_mst_region_name' => 'stpxMSTRegionName', 'stpx_mst_region_rev' => 'stpxSMSTRegionRevision', 'stpx_stp_type' => 'stpxSpanningTreeType', 'stpx_bpduguard_enable' => 'stpxFastStartBpduGuardEnable', 'stpx_bpdufilter_enable' => 'stpxFastStartBpduFilterEnable', ); %FUNCS = ( %SNMP::Info::Bridge::FUNCS, 'stpx_rootguard_enabled' => 'stpxRootGuardConfigEnabled', 'stpx_loopguard_enabled' => 'stpxLoopGuardConfigEnabled', 'stpx_port_bpduguard_mode' => 'stpxFastStartPortBpduGuardMode', 'stpx_port_bpdufilter_mode' => 'stpxFastStartPortBpduFilterMode', 'stpx_smst_root' => 'stpxSMSTInstanceCISTRegionalRoot', 'stpx_smst_vlans_mapped_1k2k' => 'stpxSMSTInstanceVlansMapped1k2k', 'stpx_smst_vlans_mapped_3k4k' => 'stpxSMSTInstanceVlansMapped3k4k', ); %MUNGE = ( %SNMP::Info::Bridge::MUNGE, 'stpx_mst_config_digest' => \&SNMP::Info::CiscoStpExtensions::oct2str, ); # Report version of STP via standard method sub stp_ver { my $self = shift; my $stp_ver = $self->SUPER::stp_ver(); if ( !defined($stp_ver) || $stp_ver eq 'unknown' ){ if ( defined $self->stpx_stp_type() ){ $stp_ver = $self->stpx_stp_type(); } } return $stp_ver; } sub mst_config_digest { my $self = shift; return $self->stpx_mst_config_digest; } sub mst_region_name { my $self = shift; return $self->stpx_mst_region_name; } sub mst_region_rev { my $self = shift; return $self->stpx_mst_region_rev; } sub mst_vlan2instance { my $self = shift; # Get MST vlan-to-instance mapping my $m1k2k = $self->stpx_smst_vlans_mapped_1k2k; my $m3k4k = $self->stpx_smst_vlans_mapped_3k4k; # Get list of VLANs my $vlan_membership = $self->i_vlan_membership; my @vlans; foreach my $iid ( keys %$vlan_membership ){ if ( my $vm = $vlan_membership->{$iid} ){ foreach my $vid ( @$vm ){ push @vlans, $vid; } } } my %res; foreach my $vlan ( @vlans ){ if ( $vlan < 2048 ){ foreach my $inst ( keys %$m1k2k ){ my $list = $m1k2k->{$inst}; my $vlanlist = [split(//, unpack("B*", $list))]; if ( @$vlanlist[$vlan] ){ $res{$vlan} = $inst; last; } } }else{ foreach my $inst ( keys %$m3k4k ){ my $list = $m3k4k->{$inst}; my $vlanlist = [split(//, unpack("B*", $list))]; if ( @$vlanlist[$vlan-2048] ){ $res{$vlan} = $inst; last; } } } } return \%res; } sub i_rootguard_enabled { my $self = shift; my $partial = shift; my $rg_enabled = $self->stpx_rootguard_enabled(); my $bp_index = $self->bp_index($partial); my %res; foreach my $index ( keys %$rg_enabled ){ my $enabled = $rg_enabled->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $enabled; $res{$iid} = $enabled; } return \%res; } sub i_loopguard_enabled { my $self = shift; my $partial = shift; my $lg_enabled = $self->stpx_loopguard_enabled(); my $bp_index = $self->bp_index($partial); my %res; foreach my $index ( keys %$lg_enabled ){ my $enabled = $lg_enabled->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $enabled; $res{$iid} = $enabled; } return \%res; } sub i_bpduguard_enabled { my $self = shift; my $partial = shift; my $bpdugm_default = $self->stpx_bpduguard_enable(); my $bp_index = $self->bp_index($partial); my $bpdugm = $self->stpx_port_bpduguard_mode(); my %res; foreach my $index ( keys %$bpdugm ){ my $mode = $bpdugm->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $mode; if ( $mode eq 'default' ){ $res{$iid} = $bpdugm_default; }else{ $res{$iid} = $mode; } } return \%res; } sub i_bpdufilter_enabled { my $self = shift; my $partial = shift; my $bpdufm_default = $self->stpx_bpdufilter_enable(); my $bp_index = $self->bp_index($partial); my $bpdufm = $self->stpx_port_bpdufilter_mode(); my %res; foreach my $index ( keys %$bpdufm ){ my $mode = $bpdufm->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $mode; if ( $mode eq 'default' ){ $res{$iid} = $bpdufm_default; }else{ $res{$iid} = $mode; } } return \%res; } sub oct2str { my ($v) = @_; return sprintf('%s', unpack('H*', $v)); } 1; __END__ =head1 NAME SNMP::Info::CiscoStpExtensions - SNMP Interface to C =head1 AUTHOR Carlos Vicente =head1 SYNOPSIS =head1 DESCRIPTION Create or use a subclass of SNMP::Info that inherits this class. Do not use directly. For debugging you can call new() directly as you would in SNMP::Info my $stpx = new SNMP::Info::CiscoStpExtensions(...); =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Bridge =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $stpx->stp_ver() Returns the particular STP version running on this device. Meant to override SNMP::Info::Brigde::stp_ver() Values: C, C, C, C, C (C) =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $stpx->mst_config_digest() Returns the Multiple Spanning Tree (MST) configuration digest (C) =item $stpx->mst_region_name() Returns the Multiple Spanning Tree (MST) region name (C) =item $stpx->mst_region_rev() Returns the Multiple Spanning Tree (MST) region name (C) =item $stpx->mst_vlan2instance() Returns the mapping of vlan to MST instance in the form of a hash reference with key = VLAN id, value = STP instance =item $stpx->i_rootguard_enabled() Returns 1 or 0 depending on whether C is enabled on a given port. Format is a hash reference with key = C, value = [1|0] (C) =item $stpx->i_loopguard_enabled() Returns 1 or 0 depending on whether C is enabled on a given port. Format is a hash reference with key = C, value = [1|0] (C) =item $stpx->i_bpduguard_enabled() Returns 1 or 0 depending on whether C is enabled on a given port. Format is a hash reference with key = C, value = [1|0] (C) =item $stpx->i_bpdufilter_enabled() Returns 1 or 0 depending on whether C is enabled on a given port. Format is a hash reference with key = C, value = [1|0] (C) =back =head1 MUNGES =over =item oct2str() Unpacks H* into a string =back =cut SNMP-Info-3.39/lib/SNMP/Info/CiscoVTP.pm000444000765000024 6050013215550564 17274 0ustar00oliverstaff000000000000# SNMP::Info::CiscoVTP # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::CiscoVTP; use strict; use Exporter; use SNMP::Info; @SNMP::Info::CiscoVTP::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::CiscoVTP::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'CISCO-VTP-MIB' => 'vtpVlanName', 'CISCO-VLAN-MEMBERSHIP-MIB' => 'vmMembershipEntry', 'CISCO-VLAN-IFTABLE-RELATIONSHIP-MIB' => 'cviRoutedVlanIfIndex', ); %GLOBALS = ( 'vtp_version' => 'vtpVersion', 'vtp_maxstore' => 'vtpMaxVlanStorage', 'vtp_notify' => 'vtpNotificationsEnabled', 'vtp_notify_create' => 'vtpVlanCreatedNotifEnabled', 'vtp_notify_delete' => 'vtpVlanDeletedNotifEnabled', 'vtp_trunk_set_serial' => 'vlanTrunkPortSetSerialNo', ); %FUNCS = ( # CISCO-VTP-MIB::managementDomainTable 'vtp_d_index' => 'managementDomainIndex', 'vtp_d_name' => 'managementDomainName', 'vtp_d_mode' => 'managementDomainLocalMode', 'vtp_d_rev' => 'managementDomainConfigRevNumber', 'vtp_d_updater' => 'managementDomainLastUpdater', 'vtp_d_last' => 'managementDomainLastChange', 'vtp_d_status' => 'managementDomainRowStatus', 'vtp_d_tftp' => 'managementDomainTftpServer', 'vtp_d_tftp_path' => 'managementDomainTftpPathname', 'vtp_d_pruning' => 'managementDomainPruningState', 'vtp_d_ver' => 'managementDomainVersionInUse', # CISCO-VTP-MIB::vtpVlanTable 'v_state' => 'vtpVlanState', 'v_type' => 'vtpVlanType', 'v_name' => 'vtpVlanName', 'v_mtu' => 'vtpVlanMtu', 'v_said' => 'vtpVlanDot10Said', 'v_ring' => 'vtpVlanRingNumber', 'v_bridge' => 'vtpVlanBridgeNumber', 'v_stp' => 'vtpVlanStpType', 'v_parent' => 'vtpVlanParentVlan', 'v_trans1' => 'vtpVlanTranslationalVlan1', 'v_trans2' => 'vtpVlanTranslationalVlan2', 'v_btype' => 'vtpVlanBridgeType', 'v_hop_are' => 'vtpVlanAreHopCount', 'v_hop_ste' => 'vtpVlanSteHopCount', 'v_crf' => 'vtpVlanIsCRFBackup', 'v_type_ext' => 'vtpVlanTypeExt', 'v_if' => 'vtpVlanIfIndex', # CISCO-VLAN-MEMBERSHIP-MIB::vmMembershipTable 'i_vlan_type' => 'vmVlanType', 'i_vlan2' => 'vmVlan', 'i_vlan_stat' => 'vmPortStatus', 'i_vlan_1' => 'vmVlans', 'i_vlan_2' => 'vmVlans2k', 'i_vlan_3' => 'vmVlans3k', 'i_vlan_4' => 'vmVlans4k', # CISCO-VLAN-MEMBERSHIP-MIB::vmVoiceVlanTable 'i_voice_vlan' => 'vmVoiceVlanId', # CISCO-VLAN-IFTABLE-RELATIONSHIP-MIB 'v_cvi_if' => 'cviRoutedVlanIfIndex', # CISCO-VTP-MIB::vlanTrunkPortTable 'vtp_trunk_mgmt_dom' => 'vlanTrunkPortManagementDomain', 'vtp_trunk_encaps_t' => 'vlanTrunkPortEncapsulationType', 'vtp_trunk_vlans' => 'vlanTrunkPortVlansEnabled', 'vtp_trunk_vlans_2k' => 'vlanTrunkPortVlansEnabled2k', 'vtp_trunk_vlans_3k' => 'vlanTrunkPortVlansEnabled3k', 'vtp_trunk_vlans_4k' => 'vlanTrunkPortVlansEnabled4k', 'vtp_trunk_native' => 'vlanTrunkPortNativeVlan', 'i_pvid' => 'vlanTrunkPortNativeVlan', 'vtp_trunk_rstat' => 'vlanTrunkPortRowStatus', 'vtp_trunk_dyn' => 'vlanTrunkPortDynamicState', 'vtp_trunk_dyn_stat' => 'vlanTrunkPortDynamicStatus', 'vtp_trunk_vtp' => 'vlanTrunkPortVtpEnabled', 'vtp_trunk_encaps' => 'vlanTrunkPortEncapsulationOperType', # TODO Add these tables if someone wants them.. # vtpEditControlTable # vtpVlanEditTable # vtpStatsTable ); %MUNGE = (); sub v_index { my $vtp = shift; my $partial = shift; my $v_name = $vtp->v_name($partial); my %v_index; foreach my $idx ( keys %$v_name ) { my ( $mgmtdomain, $vlan ) = split( /\./, $idx ); $v_index{$idx} = $vlan; } return \%v_index; } sub i_vlan { my $vtp = shift; my $partial = shift; my $port_vlan = $vtp->vtp_trunk_native($partial) || {}; my $i_vlan = $vtp->i_vlan2($partial) || {}; my $trunk_dyn = $vtp->vtp_trunk_dyn($partial) || {}; my $trunk_dyn_stat = $vtp->vtp_trunk_dyn_stat($partial) || {}; my %i_vlans; # Get access ports foreach my $port ( keys %$i_vlan ) { my $vlan = $i_vlan->{$port}; next unless defined $vlan; $i_vlans{$port} = $vlan; } # Get trunk ports foreach my $port ( keys %$port_vlan ) { my $vlan = $port_vlan->{$port}; next unless defined $vlan; # ports up and trunking should have a trunking status my $stat = $trunk_dyn_stat->{$port}; # vtp_trunk_dyn_stat is not useful for down ports # so we use vtp_trunk_dyn to see if trunking is set my $dyn = $trunk_dyn->{$port}; if (($stat and $stat =~ /^trunking/ ) or ($dyn and (($dyn eq 'on') or ($dyn eq 'onNoNegotiate')))) { $i_vlans{$port} = $vlan; } } # Check in CISCO-VLAN-IFTABLE-RELATION-MIB # Used for traditional Cisco Routers and Aironet my $v_cvi_if = $vtp->v_cvi_if(); if ( defined $v_cvi_if ) { # Translate vlan.physical_interface -> iid # to iid -> vlan foreach my $i ( keys %$v_cvi_if ) { my ( $vlan, $phys ) = split( /\./, $i ); my $iid = $v_cvi_if->{$i}; $i_vlans{$iid} = $vlan; } } return \%i_vlans; } sub i_untagged { my $vtp = shift; my ( $ifindex ) = @_; # cannot defer to i_vlan - vtp_trunk_dyn_stat is not useful for down ports # so we use vtp_trunk_dyn as a hint to use i_pvid my $trunking = eval { $vtp->vtp_trunk_dyn($ifindex)->{$ifindex} }; if ($trunking and (($trunking eq 'on') or ($trunking eq 'onNoNegotiate'))) { return $vtp->i_pvid(@_); } else { return $vtp->i_vlan(@_); } } sub i_vlan_membership { my $vtp = shift; my $partial = shift; my $ports_vlans = $vtp->vtp_trunk_vlans($partial) || {}; my $ports_vlans_2k = $vtp->vtp_trunk_vlans_2k($partial) || {}; my $ports_vlans_3k = $vtp->vtp_trunk_vlans_3k($partial) || {}; my $ports_vlans_4k = $vtp->vtp_trunk_vlans_4k($partial) || {}; my $vtp_vlans = $vtp->v_state(); my $i_vlan = $vtp->i_vlan2($partial) || {}; my $trunk_dyn_stat = $vtp->vtp_trunk_dyn_stat($partial) || {}; my $trunk_dyn = $vtp->vtp_trunk_dyn($partial) || {}; my $i_voice_vlan = $vtp->i_voice_vlan($partial) || {}; my $i_vlan_membership = {}; # Get access ports foreach my $port ( keys %$i_vlan ) { my $vlan = $i_vlan->{$port}; next unless defined $vlan; my $dyn = $trunk_dyn->{$port}; unless ($dyn and (($dyn eq 'on') or ($dyn eq 'onNoNegotiate'))) { push( @{ $i_vlan_membership->{$port} }, $vlan ); } } # Get voice VLANs foreach my $port ( keys %$i_voice_vlan ) { my $vlan = $i_voice_vlan->{$port}; next unless defined $vlan; next unless ($vlan =~ m/[[:digit:]]+/ and $vlan < 4095); my $dyn = $trunk_dyn->{$port}; unless ($dyn and (($dyn eq 'on') or ($dyn eq 'onNoNegotiate'))) { push( @{ $i_vlan_membership->{$port} }, $vlan ); } } # Get trunk ports my %oper_vlans; foreach my $iid ( keys %$vtp_vlans ) { my $vlan = 0; my $vtp_dom = 0; my $state = $vtp_vlans->{$iid}; next unless defined $state; next if $state !~ /operational/; if ( $iid =~ /(\d+)\.(\d+)/ ) { $vtp_dom = $1; $vlan = $2; } $oper_vlans{$vlan}++; } foreach my $port ( keys %$ports_vlans ) { my $stat = $trunk_dyn_stat->{$port}; my $dyn = $trunk_dyn->{$port}; if (($stat and $stat =~ /^trunking/ ) or ($dyn and (($dyn eq 'on') or ($dyn eq 'onNoNegotiate')))) { my $k = 0; my $list1 = $ports_vlans->{$port} || '0'; my $list2 = $ports_vlans_2k->{$port} || '0'; my $list3 = $ports_vlans_3k->{$port} || '0'; my $list4 = $ports_vlans_4k->{$port} || '0'; foreach my $list ( "$list1", "$list2", "$list3", "$list4" ) { my $offset = 1024 * $k++; next unless $list; my $vlanlist = [ split( //, unpack( "B*", $list ) ) ]; foreach my $vlan ( keys %oper_vlans ) { next if (($vlan < $offset) or ($vlan - $offset > 1024)); push( @{ $i_vlan_membership->{$port} }, $vlan ) if ( @$vlanlist[ $vlan - $offset ] ); } } } } return $i_vlan_membership; } sub i_vlan_membership_untagged { my $vtp = shift; my $partial = shift; my $vlans = $vtp->i_vlan($partial); my $i_vlan_membership = {}; foreach my $port (keys %$vlans) { my $vlan = $vlans->{$port}; push( @{ $i_vlan_membership->{$port} }, $vlan ); } return $i_vlan_membership; } sub set_i_pvid { my $vtp = shift; my ( $vlan_id, $ifindex ) = @_; return unless ( $vtp->_validate_vlan_param( $vlan_id, $ifindex ) ); my $native_vlan = $vtp->vtp_trunk_native($ifindex); if ( defined $native_vlan ) { print "Changing native VLAN from $native_vlan->{$ifindex} to $vlan_id on IfIndex: $ifindex\n" if $vtp->debug(); my $rv = $vtp->set_vtp_trunk_native( $vlan_id, $ifindex ); unless ($rv) { $vtp->error_throw( "Unable to change native VLAN to $vlan_id on IfIndex: $ifindex" ); return; } return $rv; } $vtp->error_throw("Can't find ifIndex: $ifindex - Is it a trunk port?"); return; } sub set_i_vlan { my $vtp = shift; my ( $vlan_id, $ifindex ) = @_; return unless ( $vtp->_validate_vlan_param( $vlan_id, $ifindex ) ); my $i_vlan = $vtp->i_vlan2($ifindex); if ( defined $i_vlan ) { print "Changing VLAN from $i_vlan->{$ifindex} to $vlan_id on IfIndex: $ifindex\n" if $vtp->debug(); my $rv = $vtp->set_i_vlan2( $vlan_id, $ifindex ); unless ($rv) { $vtp->error_throw( "Unable to change VLAN to $vlan_id on IfIndex: $ifindex"); return; } return $rv; } $vtp->error_throw("Can't find ifIndex: $ifindex - Is it an access port?"); return; } sub set_i_untagged { my $vtp = shift; my ( $vlan_id, $ifindex ) = @_; # cannot defer to i_vlan - vtp_trunk_dyn_stat is not useful for down ports # so we use vtp_trunk_dyn as a hint to use i_pvid my $trunking = eval { $vtp->vtp_trunk_dyn($ifindex)->{$ifindex} }; if ($trunking and (($trunking eq 'on') or ($trunking eq 'onNoNegotiate'))) { return $vtp->set_i_pvid(@_); } else { return $vtp->set_i_vlan(@_); } } sub set_add_i_vlan_tagged { my $vtp = shift; my ( $vlan_id, $ifindex ) = @_; return unless ( $vtp->_validate_vlan_param( $vlan_id, $ifindex ) ); print "Adding VLAN: $vlan_id to ifIndex: $ifindex\n" if $vtp->debug(); my $trunk_serial = $vtp->load_vtp_trunk_set_serial(); my $trunk_members = $vtp->vtp_trunk_vlans($ifindex); unless ( defined $trunk_members ) { $vtp->error_throw( "Can't find ifIndex: $ifindex - Is it a trunk port?"); return; } my @member_list = split( //, unpack( "B*", $trunk_members->{$ifindex} ) ); print "Original vlan list for ifIndex: $ifindex: @member_list \n" if $vtp->debug(); $member_list[$vlan_id] = '1'; print "Modified vlan list for ifIndex: $ifindex: @member_list \n" if $vtp->debug(); my $new_list = pack( "B*", join( '', @member_list ) ); #Add VLAN to member list my $list_rv = $vtp->set_vtp_trunk_vlans( $new_list, $ifindex ); unless ($list_rv) { $vtp->error_throw( "Unable to add VLAN: $vlan_id to ifIndex: $ifindex member list"); return; } #Make sure no other SNMP manager was making modifications at the same time. my $serial_rv = $vtp->set_vtp_trunk_set_serial($trunk_serial); unless ($serial_rv) { $vtp->error_throw( "Unable to increment trunk set serial number - check configuration!" ); return; } return 1; } sub set_remove_i_vlan_tagged { my $vtp = shift; my ( $vlan_id, $ifindex ) = @_; return unless ( $vtp->_validate_vlan_param( $vlan_id, $ifindex ) ); print "Removing VLAN: $vlan_id from ifIndex: $ifindex\n" if $vtp->debug(); my $trunk_serial = $vtp->load_vtp_trunk_set_serial(); my $trunk_members = $vtp->vtp_trunk_vlans($ifindex); unless ( defined $trunk_members ) { $vtp->error_throw( "Can't find ifIndex: $ifindex - Is it a trunk port?"); return; } my @member_list = split( //, unpack( "B*", $trunk_members->{$ifindex} ) ); print "Original vlan list for ifIndex: $ifindex: @member_list \n" if $vtp->debug(); $member_list[$vlan_id] = '0'; print "Modified vlan list for ifIndex: $ifindex: @member_list \n" if $vtp->debug(); my $new_list = pack( "B*", join( '', @member_list ) ); #Remove VLAN to member list my $list_rv = $vtp->set_vtp_trunk_vlans( $new_list, $ifindex ); unless ($list_rv) { $vtp->error_throw( "Error: Unable to remove VLAN: $vlan_id from ifIndex: $ifindex member list" ); return; } #Make sure no other manager was making modifications at the same time. my $serial_rv = $vtp->set_vtp_trunk_set_serial($trunk_serial); unless ($serial_rv) { $vtp->error_throw( "Error: Unable to increment trunk set serial number - check configuration!" ); return; } return 1; } # # These are internal methods and are not documented. Do not use directly. # sub _validate_vlan_param { my $vtp = shift; my ( $vlan_id, $ifindex ) = @_; # VID and ifIndex should both be numeric unless (defined $vlan_id and defined $ifindex and $vlan_id =~ /^\d+$/ and $ifindex =~ /^\d+$/ ) { $vtp->error_throw("Invalid parameter"); return; } # Check that ifIndex exists on device my $index = $vtp->interfaces($ifindex); unless ( exists $index->{$ifindex} ) { $vtp->error_throw("ifIndex $ifindex does not exist"); return; } #Check that VLAN exists on device my $vtp_vlans = $vtp->v_state(); my $vlan_exists = 0; foreach my $iid ( keys %$vtp_vlans ) { my $vlan = 0; my $vtp_dom = 0; my $state = $vtp_vlans->{$iid}; next unless defined $state; next if $state !~ /operational/; if ( $iid =~ /(\d+)\.(\d+)/ ) { $vtp_dom = $1; $vlan = $2; } $vlan_exists = 1 if ( $vlan_id eq $vlan ); } unless ($vlan_exists) { $vtp->error_throw( "VLAN $vlan_id does not exist or is not operational"); return; } return 1; } 1; __END__ =head1 NAME SNMP::Info::CiscoVTP - SNMP Interface to Cisco's VLAN Management MIBs =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $vtp = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $vtp->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::CiscoVTP is a subclass of SNMP::Info that provides information about a Cisco device's VLAN and VTP Domain membership. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =item F =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBALS =over =item $vtp->vtp_version() (C) =item $vtp->vtp_maxstore() (C) =item $vtp->vtp_notify() (C) =item $vtp->vtp_notify_create() (C) =item $vtp->vtp_notify_delete() (C) =item $vtp->vtp_trunk_set_serial() (C) =back =head1 TABLE METHODS Your device will only implement a subset of these methods. =over =item $vtp->i_vlan() Returns a mapping between C and assigned VLAN ID for access ports and the default VLAN ID for trunk ports. =item $vtp->i_untagged() An alias for C. =item $vtp->i_vlan_membership() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of enabled VLAN list for the port. Example: my $interfaces = $vtp->interfaces(); my $vlans = $vtp->i_vlan_membership(); foreach my $iid (sort keys %$interfaces) { my $port = $interfaces->{$iid}; my $vlan = join(',', sort(@{$vlans->{$iid}})); print "Port: $port VLAN: $vlan\n"; } =item $vtp->i_vlan_membership_untagged() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port. =back =head2 VLAN Table (C) See L for a good treaty of how to connect to the VLANs =over =item $vtp->v_index() (C) =item $vtp->v_state() (C) =item $vtp->v_type() (C) =item $vtp->v_name() (C) =item $vtp->v_mtu() (C) =item $vtp->v_said() (C) =item $vtp->v_ring() (C) =item $vtp->v_bridge() (C) =item $vtp->v_stp() (C) =item $vtp->v_parent() (C) =item $vtp->v_trans1() (C) =item $vtp->v_trans2() (C) =item $vtp->v_btype() (C) =item $vtp->v_hop_are() (C) =item $vtp->v_hop_ste() (C) =item $vtp->v_crf() (C) =item $vtp->v_type_ext() (C) =item $vtp->v_if() (C) =back =head2 VLAN Membership Table (C) =over =item $vtp->i_vlan_type() Static, Dynamic, or multiVlan. (C) =item $vtp->i_vlan2() The VLAN that an access port is assigned to. (C) =item $vtp->i_vlan_stat() Inactive, active, shutdown. (C) =item $vtp->i_vlan_1() Each bit represents a VLAN. This is 0 through 1023 (C) =item $vtp->i_vlan_2() Each bit represents a VLAN. This is 1024 through 2047 (C) =item $vtp->i_vlan_3() Each bit represents a VLAN. This is 2048 through 3071 (C) =item $vtp->i_vlan_4() Each bit represents a VLAN. This is 3072 through 4095 (C) =back =head2 VLAN Membership Voice VLAN Table (C) =over =item $vtp->i_voice_vlan() (C) =back =head2 Management Domain Table (C) =over =item $vtp->vtp_d_index() (C) =item $vtp->vtp_d_name() (C) =item $vtp->vtp_d_mode() (C) =item $vtp->vtp_d_rev() (C) =item $vtp->vtp_d_updater() (C) =item $vtp->vtp_d_last() (C) =item $vtp->vtp_d_status() (C) =item $vtp->vtp_d_tftp() (C) =item $vtp->vtp_d_tftp_path() (C) =item $vtp->vtp_d_pruning() (C) =item $vtp->vtp_d_ver() (C) =back =head2 VLAN Trunk Port Table (C) =over =item $vtp->vtp_trunk_mgmt_dom() (C) =item $vtp->vtp_trunk_encaps_t() (C) =item $vtp->vtp_trunk_vlans() (C) =item $vtp->vtp_trunk_vlans_2k() (C) =item $vtp->vtp_trunk_vlans_3k() (C) =item $vtp->vtp_trunk_vlans_4k() (C) =item $vtp->vtp_trunk_native() (C) =item $vtp->i_pvid() (C) =item $vtp->vtp_trunk_rstat() (C) =item $vtp->vtp_trunk_dyn() (C) =item $vtp->vtp_trunk_dyn_stat() (C) =item $vtp->vtp_trunk_vtp() (C) =item $vtp->vtp_trunk_encaps() (C) =back =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item $vtp->set_i_vlan ( vlan, ifIndex ) Changes an access (untagged) port VLAN, must be supplied with the numeric VLAN ID and port C. This method should only be used on end station (non-trunk) ports. Example: my %if_map = reverse %{$vtp->interfaces()}; $vtp->set_i_vlan('2', $if_map{'FastEthernet0/1'}) or die "Couldn't change port VLAN. ",$vtp->error(1); =item $vtp->set_i_pvid ( pvid, ifIndex ) Sets port default VLAN, must be supplied with the numeric VLAN ID and port C. This method should only be used on trunk ports. Example: my %if_map = reverse %{$vtp->interfaces()}; $vtp->set_i_pvid('2', $if_map{'FastEthernet0/1'}) or die "Couldn't change port default VLAN. ",$vtp->error(1); =item $vtp->set_i_untagged ( vlan, ifIndex ) This method attempts to work out whether the port referenced by ifIndex is trunking, and if so will return the value of C. Otherwise, the value of C is returned. =item $vtp->set_add_i_vlan_tagged ( vlan, ifIndex ) Adds the VLAN to the enabled VLANs list of the port, must be supplied with the numeric VLAN ID and port C. Example: my %if_map = reverse %{$vtp->interfaces()}; $vtp->set_add_i_vlan_tagged('2', $if_map{'FastEthernet0/1'}) or die "Couldn't add port to egress list. ",$vtp->error(1); =item $vtp->set_remove_i_vlan_tagged ( vlan, ifIndex ) Removes the VLAN from the enabled VLANs list of the port, must be supplied with the numeric VLAN ID and port C. Example: my %if_map = reverse %{$vtp->interfaces()}; $vtp->set_remove_i_vlan_tagged('2', $if_map{'FastEthernet0/1'}) or die "Couldn't add port to egress list. ",$vtp->error(1); =back =cut SNMP-Info-3.39/lib/SNMP/Info/EDP.pm000444000765000024 1661213215550564 16257 0ustar00oliverstaff000000000000# SNMP::Info::EDP # # Copyright (c) 2012 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::EDP; use strict; use Exporter; use SNMP::Info; @SNMP::Info::LLDP::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::LLDP::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'EXTREME-EDP-MIB' => 'extremeEdpPortIfIndex', ); %GLOBALS = ( ); %FUNCS = ( # EXTREME-EDP-MIB::extremeEdpTable 'edp_rem_sysname' => 'extremeEdpNeighborName', ); %MUNGE = ( 'edp_rem_sysname' => \&SNMP::Info::munge_null, ); sub hasEDP { my $edp = shift; my $edp_ip = $edp->extremeEdpNeighborVlanIpAddress() || {}; return 1 if ( scalar( keys %$edp_ip ) ); return; } # Since we need to get IP Addresses from the extremeEdpNeighborTable which has # a different index (adds VLAN name) than the extremeEdpTable which holds # the remote device details use the index from extremeEdpNeighborTable but skip # indexes which have an address of 0.0.0.0. Would like to include only one # address since they should all originate from the same device, but we don't # know if they would all be reachable from the network management application. # # We don't inplement partials since this is private index function sub _edp_index { my $edp = shift; my $edp_ip = $edp->extremeEdpNeighborVlanIpAddress() || {}; my %edp_index; foreach my $key ( keys %$edp_ip ) { my $ip = $edp_ip->{$key}; next if ($ip eq '0.0.0.0'); next unless $ip; $edp_index{$key} = $key; } return \%edp_index; } sub edp_if { my $edp = shift; my $index = $edp->_edp_index() || {}; my %edp_if; foreach my $key (keys %$index) { my $iid = $key; # ifIndex is first part of the iid $iid = $1 if $iid =~ /^(\d+)\./; $edp_if{$key} = $iid; } return \%edp_if; } sub edp_ip { my $edp = shift; my $index = $edp->_edp_index() || {}; my $edp_ip = $edp->extremeEdpNeighborVlanIpAddress() || {}; my %edp_ip; foreach my $key ( keys %$index ) { my $ip = $edp_ip->{$key}; # MIB says should only be IPv4 next unless ($ip =~ /\d+(\.\d+){3}/); $edp_ip{$key} = $ip; } return \%edp_ip; } sub edp_port { my $edp = shift; my $index = $edp->_edp_index() || {}; my $edp_rport = $edp->extremeEdpNeighborPort() || {}; my $edp_rslot = $edp->extremeEdpNeighborSlot() || {}; my %edp_port; foreach my $key ( sort keys %$edp_rport ) { my $port = $edp_rport->{$key}; my $slot = $edp_rslot->{$key} || 0; next unless $port; my $slotport = defined $slot ? "$slot\/$port" : $port; foreach my $iid ( sort keys %$index ) { $edp_port{$iid} = $slotport if ($iid =~ /^$key/); } } return \%edp_port; } sub edp_id { my $edp = shift; my $index = $edp->_edp_index() || {}; my $edp_name = $edp->edp_rem_sysname() || {}; my %edp_name; foreach my $key ( sort keys %$edp_name ) { my $name = $edp_name->{$key} || 0; next unless $name; foreach my $iid ( sort keys %$index ) { $edp_name{$iid} = $name if ($iid =~ /^$key/); } } return \%edp_name; } sub edp_ver { my $edp = shift; my $index = $edp->_edp_index() || {}; my $edp_ver = $edp->extremeEdpNeighborSoftwareVersion() || {}; my %edp_ver; foreach my $key ( sort keys %$edp_ver ) { my $ver = $edp_ver->{$key} || 0; next unless $ver; foreach my $iid ( sort keys %$index ) { $edp_ver{$iid} = $ver if ($iid =~ /^$key/); } } return \%edp_ver; } 1; __END__ =head1 NAME SNMP::Info::EDP - SNMP Interface to the Extreme Discovery Protocol (EDP) =head1 AUTHOR Eric Miller =head1 SYNOPSIS my $edp = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'router', Community => 'public', Version => 2 ); my $class = $edp->class(); print " Using device sub class : $class\n"; $haslldp = $edp->hasLLDP() ? 'yes' : 'no'; # Print out a map of device ports with LLDP neighbors: my $interfaces = $edp->interfaces(); my $edp_if = $edp->edp_if(); my $edp_ip = $edp->edp_ip(); my $edp_port = $edp->edp_port(); foreach my $edp_key (keys %$edp_ip){ my $iid = $edp_if->{$edp_key}; my $port = $interfaces->{$iid}; my $neighbor = $edp_ip->{$edp_key}; my $neighbor_port = $edp_port->{$edp_key}; print "Port : $port connected to $neighbor / $neighbor_port\n"; } =head1 DESCRIPTION SNMP::Info::EDP is a subclass of SNMP::Info that provides an object oriented interface to EDP information through SNMP. EDP is a Layer 2 protocol that allows a network device to advertise its identity and capabilities on the local network providing topology information. Create or use a device subclass that inherits this class. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =back =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $edp->hasEDP() Is EDP is active in this device? =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $edp->edp_id() Returns the string value used to identify the chassis component associated with the remote system. (C) =item $edp->edp_if() Returns the mapping to the SNMP Interface Table. =item $edp->edp_ip() Returns remote IPv4 address. =item $edp->edp_port() Returns remote port ID =item $edp->edp_ver() Returns the operating system version of the remote system. Nulls are removed before the value is returned. (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/Entity.pm000444000765000024 1423513215550564 17122 0ustar00oliverstaff000000000000# SNMP::Info::Entity # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Entity; use strict; use Exporter; use SNMP::Info; @SNMP::Info::Entity::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::Entity::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'ENTITY-MIB' => 'entPhysicalSerialNum' ); %GLOBALS = (); %FUNCS = ( 'e_alias' => 'entPhysicalAlias', 'e_class' => 'entPhysicalClass', 'e_descr' => 'entPhysicalDescr', 'e_fwver' => 'entPhysicalFirmwareRev', 'e_fru' => 'entPhysicalIsFRU', 'e_hwver' => 'entPhysicalHardwareRev', 'e_id' => 'entPhysicalAssetID', 'e_map' => 'entAliasMappingIdentifier', 'e_model' => 'entPhysicalModelName', 'e_name' => 'entPhysicalName', 'e_parent' => 'entPhysicalContainedIn', 'e_pos' => 'entPhysicalParentRelPos', 'e_serial' => 'entPhysicalSerialNum', 'e_swver' => 'entPhysicalSoftwareRev', 'e_type' => 'entPhysicalVendorType', 'e_vendor' => 'entPhysicalMfgName', ); %MUNGE = ( 'e_type' => \&SNMP::Info::munge_e_type, ); # entPhysicalIndex is not-accessible. Create to facilitate emulation methods # in other classes sub e_index { my $entity = shift; my $partial = shift; # Force use of MIB leaf to avoid inheritance issues in psuedo classes my $e_descr = $entity->entPhysicalDescr($partial); return unless ($e_descr); my %e_index; foreach my $iid ( keys %$e_descr ) { $e_index{$iid} = $iid; } return \%e_index; } sub e_port { my $entity = shift; my $partial = shift; my $e_map = $entity->e_map($partial); my %e_port; foreach my $e_id ( keys %$e_map ) { my $id = $e_id; $id =~ s/\.0$//; my $iid = $e_map->{$e_id}; $iid =~ s/.*\.//; $e_port{$id} = $iid; } return \%e_port; } 1; __END__ =head1 NAME SNMP::Info::Entity - SNMP Interface to data stored in F. RFC 2737 =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $entity = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $entity->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION F is used by Layer 2 devices from Brocade, Cisco, HP, and more. See RFC 2737 for full details. Create or use a device subclass that inherit this class. Do not use directly. For debugging purposes you can call this class directly as you would SNMP::Info my $entity = new SNMP::Info::Entity (...); =head2 Inherited Classes none. =head2 Required MIBs =over =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBALS none. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Entity Table =over =item $entity->e_index() Index (C) =item $entity->e_alias() Human entered, not usually used. (C) =item $entity->e_class() Stack, Module, Container, Port ... (C) =item $entity->e_descr() Human Friendly (C) =item $entity->e_fwver() (C) =item $entity->e_fru() BOOLEAN. Is a Field Replaceable unit? (C) =item $entity->e_hwver() (C) =item $entity->e_id() This is human entered and not normally used. (C) =item $entity->e_map() See MIB. (C) =item $entity->e_model() Model Name of Entity. (C) =item $entity->e_name() More computer friendly name of entity. Parse me. (C) =item $entity->e_parent() 0 if root. (C) =item $entity->e_port() Maps Entity Table entries to the Interface Table (C) using $entity->e_map() =item $entity->e_pos() The relative position among all entities sharing the same parent. (C) =item $entity->e_serial() (C) =item $entity->e_swver() (C) =item $entity->e_type() This is an OID, which gets munged into the object name if the right MIB is loaded. (C) =item $entity->e_vendor() Vendor of Module. (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/EtherLike.pm000444000765000024 1426713215550564 17527 0ustar00oliverstaff000000000000# SNMP::Info::EtherLike # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::EtherLike; use strict; use Exporter; use SNMP::Info; @SNMP::Info::EtherLike::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::EtherLike::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'EtherLike-MIB' => 'etherMIB' ); %GLOBALS = (); %FUNCS = ( # EtherLike StatsTable 'el_chipset' => 'dot3StatsEtherChipSet', 'el_coll_excess' => 'dot3StatsExcessiveCollisions', 'el_coll_late' => 'dot3StatsLateCollisions', 'el_coll_mult' => 'dot3StatsMultipleCollisionFrames', 'el_coll_single' => 'dot3StatsSingleCollisionFrames', 'el_duplex' => 'dot3StatsDuplexStatus', 'el_error_alignment' => 'dot3StatsAlignmentErrors', 'el_error_fcs' => 'dot3StatsFCSErrors', 'el_error_cs' => 'dot3StatsCarrierSenseErrors', 'el_error_frame' => 'dot3StatsFrameTooLongs', 'el_error_mac_rec' => 'dot3StatsInternalMacReceiveErrors', 'el_error_mac_xmit' => 'dot3StatsInternalMacTransmitErrors', 'el_error_sqe' => 'dot3StatsSQETestErrors', 'el_error_symbol' => 'dot3StatsSymbolErrors', 'el_index' => 'dot3StatsIndex', 'el_xmit_defer' => 'dot3StatsDeferredTransmissions', # Ethernet-like Collision Statistics Group 'el_coll_count' => 'dot3CollCount', 'el_coll_freq' => 'dot3CollFrequencies' ); %MUNGE = ( %SNMP::Info::MUNGE, 'el_duplex' => \&munge_el_duplex, ); sub munge_el_duplex { my $duplex = shift; return unless defined $duplex; $duplex =~ s/Duplex$//; return $duplex; } 1; __END__ =head1 NAME SNMP::Info::EtherLike - SNMP Interface to SNMP F RFC 1398 =head1 AUTHOR Max Baker =head1 SYNOPSIS my $el = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'router', Community => 'public', Version => 2 ); my $class = $cdp->class(); print " Using device sub class : $class\n"; # Find the duplex setting for a port on a device that implements # ETHERLIKE-MIB my $interfaces = $el->interfaces(); my $el_index = $el->el_index(); my $el_duplex = $el->el_duplex(); foreach my $el_port (keys %$el_duplex){ my $duplex = $el_duplex->{$el_port}; my $iid = $el_index->{$el_port}; my $port = $interfaces->{$iid}; print "PORT:$port set to duplex:$duplex\n"; } =head1 DESCRIPTION SNMP::Info::EtherLike is a subclass of SNMP::Info that supplies access to the F used by some Layer 3 Devices such as Cisco routers. See RFC 1398 for more details. Use or create a subclass of SNMP::Info that inherits this one. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =back MIBs can be found at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz =head1 GLOBALS These are methods that return scalar values from SNMP =over =item None =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 ETHERLIKE STATS TABLE (C) =over =item $el->el_index() Returns reference to hash. Indexes Stats Table to the interface index (iid). (C) =item $el->el_duplex() Returns reference to hash. Indexes Stats Table to Duplex Status of port. (C) =item $el->el_chipset() (C) =item $el->el_coll_excess() (C) =item $el->el_coll_late() (C) =item $el->el_coll_mult() (C) =item $el->el_coll_single() (C) =item $el->el_error_alignment() (C) =item $el->el_error_fcs() (C) =item $el->el_error_cs() (C) =item $el->el_error_frame() (C) =item $el->el_error_mac_rec() (C) =item $el->el_error_mac_xmit() (C) =item $el->el_error_sqe() (C) =item $el->el_error_symbol() (C) =item $el->el_xmit_defer() (C) =item $el->el_coll_count() (C) =item $el->el_coll_freq() (C) =back =head1 Data Munging Callback Subroutines =over =item $el->munge_el_duplex() Removes 'Duplex' from the end of a string. =back =cut SNMP-Info-3.39/lib/SNMP/Info/FDP.pm000444000765000024 2421713215550564 16260 0ustar00oliverstaff000000000000# SNMP::Info::FDP # $Id$ # # Copyright (c) 2008 Bruce Rodger, Max Baker # All rights reserved. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::FDP; use strict; use Exporter; use SNMP::Info; @SNMP::Info::FDP::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::FDP::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'FOUNDRY-SN-SWITCH-GROUP-MIB' => 'snFdpGlobalRun' ); %GLOBALS = ( 'fdp_run' => 'snFdpGlobalRun', 'fdp_interval' => 'snFdpGlobalMessageInterval', 'fdp_holdtime' => 'snFdpGlobalHoldTime', 'fdp_gid' => 'snFdpGlobalDeviceId', ); %FUNCS = ( 'fdp_index' => 'snFdpCacheIfIndex', 'fdp_proto' => 'snFdpCacheAddressType', 'fdp_ip' => 'snFdpCacheAddress', 'fdp_ver' => 'snFdpCacheVersion', 'fdp_id' => 'snFdpCacheDeviceId', 'fdp_port' => 'snFdpCacheDevicePort', 'fdp_platform' => 'snFdpCachePlatform', 'fdp_capabilities' => 'snFdpCacheCapabilities', 'fdp_domain' => 'snFdpCacheVTPMgmtDomain', 'fdp_vlan' => 'snFdpCacheNativeVLAN', 'fdp_duplex' => 'snFdpCacheDuplex', ); %MUNGE = ( 'fdp_capabilities' => \&SNMP::Info::munge_bits, 'fdp_ip' => \&SNMP::Info::munge_ip ); sub fdp_run { my $fdp = shift; my $fdp_run = $fdp->orig_fdp_run(); # if fdp_run isn't implemented on device, assume FDP is on return $fdp_run if defined $fdp_run; return 1; } sub hasFDP { my $fdp = shift; my $ver = $fdp->{_version}; #my $ver = $fdp->fdp_ver; # SNMP v1 clients dont have the globals if ( defined $ver and $ver == 1 ) { my $fdp_ip = $fdp->fdp_ip(); # See if anything in fdp cache, if so we have fdp return 1 if ( defined $fdp_ip and scalar( keys %$fdp_ip ) ); return; } return $fdp->fdp_run(); } sub fdp_if { my $fdp = shift; # See if by some miracle Cisco implemented the fdpCacheIfIndex entry my $fdp_index = $fdp->fdp_index(); return $fdp_index if defined $fdp_index; # Nope, didn't think so. Now we fake it. my $fdp_ip = $fdp->fdp_ip(); unless ( defined $fdp_ip ) { $fdp->error_throw( "SNMP::Info::FDP:fdp_if() - Device doesn't have fdp_ip() data. Can't fake fdp_index()" ); return; } my %fdp_if; foreach my $key ( keys %$fdp_ip ) { next unless defined $key; my $iid = $key; # Truncate .1 from fdp cache entry $iid =~ s/\.\d+$//; $fdp_if{$key} = $iid; } return \%fdp_if; } 1; __END__ =head1 NAME SNMP::Info::FDP - SNMP Interface to Foundry Discovery Protocol (FDP) using SNMP =head1 AUTHOR Bruce Rodger, Max Baker =head1 SYNOPSIS my $fdp = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'router', Community => 'public', Version => 2 ); my $class = $fdp->class(); print " Using device sub class : $class\n"; $hasfdp = $fdp->hasFDP() ? 'yes' : 'no'; # Print out a map of device ports with FDP neighbors: my $interfaces = $fdp->interfaces(); my $fdp_if = $fdp->fdp_if(); my $fdp_ip = $fdp->fdp_ip(); my $fdp_port = $fdp->fdp_port(); foreach my $fdp_key (keys %$fdp_ip){ my $iid = $fdp_if->{$fdp_key}; my $port = $interfaces->{$iid}; my $neighbor = $fdp_ip->{$fdp_key}; my $neighbor_port = $fdp_port->{$fdp_key}; print "Port : $port connected to $neighbor / $neighbor_port\n"; } =head1 DESCRIPTION SNMP::Info::FDP is a subclass of SNMP::Info that provides an object oriented interface to FDP information through SNMP. FDP is a Layer 2 protocol that supplies topology information of devices that also speak FDP, mostly switches and routers. It has similar functionality to Cisco's CDP, and the SNMP interface is virtually identical. FDP is implemented in Brocade (Foundry) devices. Create or use a device subclass that inherits this class. Do not use directly. Each device implements a subset of the global and cache entries. Check the return value to see if that data is held by the device. =head2 Inherited Classes None. =head2 Required MIBs =over =item F Needs a reasonably recent MIB. Works OK with B2R07604A.mib, but doesn't work with B2R07600C. =back =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $fdp->hasFDP() Is FDP is active in this device? Accounts for SNMP version 1 devices which may have FDP but not fdp_run() =item $fdp->fdp_run() Is FDP enabled on this device? (C) =item $fdp->fdp_interval() Interval in seconds at which FDP messages are generated. (C) =item $fdp->fdp_holdtime() Time in seconds that FDP messages are kept. (C) =item $fdp->fdp_gid() Returns FDP device ID. This is the device id broadcast via FDP to other devices, and is what is retrieved from remote devices with $fdp->id(). (C) =back =head2 Overrides CDP compatibility =over =item $fdp->fdp_interval() Interval in seconds at which FDP messages are generated. (C) =item $fdp->fdp_holdtime() Time in seconds that FDP messages are kept. (C) =item $fdp->fdp_id() Returns FDP device ID. This is the device id broadcast via FDP to other devices, and is what is retrieved from remote devices with $fdp->id(). (C) =item $fdp->fdp_run() Is FDP enabled on this device? =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides CDP compatibility =over =item $fdp->fdp_capabilities() Returns Device Functional Capabilities. Results are munged into an ascii binary string, MSB. Each digit represents a bit from the table below. From L: (Bit) - Description =over =item (0x40) - Provides level 1 functionality. =item (0x20) - The bridge or switch does not forward IGMP Report packets on non router ports. =item (0x10) - Sends and receives packets for at least one network layer protocol. If the device is routing the protocol, this bit should not be set. =item (0x08) - Performs level 2 switching. The difference between this bit and bit 0x02 is that a switch does not run the Spanning-Tree Protocol. This device is assumed to be deployed in a physical loop-free topology. =item (0x04) - Performs level 2 source-route bridging. A source-route bridge would set both this bit and bit 0x02. =item (0x02) - Performs level 2 transparent bridging. =item (0x01) - Performs level 3 routing for at least one network layer protocol. =back Thanks to Martin Lorensen for a pointer to this information. (C) =item $fdp->fdp_domain() The CDP version of this returns remote VTP Management Domain as defined in C (C) =item $fdp->fdp_duplex() Returns the port duplex status from remote devices. (C) =item $fdp->fdp_id() Returns remote device id string (C) =item $fdp->fdp_if() Returns the mapping to the SNMP Interface Table. Note that a lot devices don't implement $fdp->fdp_index(), So if it isn't around, we fake it. In order to map the fdp table entry back to the interfaces() entry, we truncate the last number off of it : # it exists, yay. my $fdp_index = $device->fdp_index(); return $fdp_index if defined $fdp_index; # if not, let's fake it my $fdp_ip = $device->fdp_ip(); my %fdp_if foreach my $key (keys %$fdp_ip){ $iid = $key; ## Truncate off .1 from fdp response $iid =~ s/\.\d+$//; $fdp_if{$key} = $iid; } return \%fdp_if; =item $fdp->fdp_index() Returns the mapping to the SNMP2 Interface table for FDP Cache Entries. Most devices don't implement this, so you probably want to use $fdp->fdp_if() instead. See fdp_if() entry. (C) =item $fdp->fdp_ip() Returns remote IP address (C) =item $fdp->fdp_platform() Returns remote platform id (C) =item $fdp->fdp_port() Returns remote port ID (C) =item $fdp->fdp_proto() Returns remote address type received. Usually IP. (C) =item $fdp->fdp_ver() Returns remote hardware version (C) =item $fdp->fdp_vlan() Returns the remote interface native VLAN. (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/IEEE802dot11.pm000444000765000024 2172213215550564 17457 0ustar00oliverstaff000000000000# SNMP::Info::IEEE802dot11 # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::IEEE802dot11; use strict; use Exporter; @SNMP::Info::IEEE802dot11::ISA = qw/Exporter/; @SNMP::Info::IEEE802dot11::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'IEEE802dot11-MIB' => 'dot11DesiredSSID', ); %GLOBALS = (); %FUNCS = ( # dot11PhyOFDMTable 'dot11_cur_freq' => 'dot11CurrentFrequency', # dot11PhyDSSSTable 'dot11_cur_ch' => 'dot11CurrentChannel', # dot11PhyOperationTable 'dot11_phy_type' => 'dot11PHYType', 'dot11_reg_dom' => 'dot11CurrentRegDomain', # dot11ResourceInfoTable 'dot11_prod_ver' => 'dot11manufacturerProductVersion', 'dot11_prod_name' => 'dot11manufacturerProductName', 'dot11_man_name' => 'dot11manufacturerName', # dot11OperationTable 'dot11_mac' => 'dot11MACAddress', # dot11StationConfigTable 'dot11_bss_type' => 'dot11DesiredBSSType', 'i_ssidlist' => 'dot11DesiredSSID', 'dot11_pwr_mode' => 'dot11PowerManagementMode', 'dot11_sta_id' => 'dot11StationID', # dot11PhyTxPowerTable 'dot11_cur_tx_pwr' => 'dot11CurrentTxPowerLevel', 'dot11_tx_pwr_level_1' => 'dot11TxPowerLevel1', 'dot11_tx_pwr_level_2' => 'dot11TxPowerLevel2', 'dot11_tx_pwr_level_3' => 'dot11TxPowerLevel3', 'dot11_tx_pwr_level_4' => 'dot11TxPowerLevel4', 'dot11_tx_pwr_level_5' => 'dot11TxPowerLevel5', 'dot11_tx_pwr_level_6' => 'dot11TxPowerLevel6', 'dot11_tx_pwr_level_7' => 'dot11TxPowerLevel7', 'dot11_tx_pwr_level_8' => 'dot11TxPowerLevel8', ); %MUNGE = ( 'dot11_mac' => \&SNMP::Info::munge_mac, 'dot11_sta_id' => \&SNMP::Info::munge_mac, ); sub vendor { my $dot11 = shift; my $names = $dot11->dot11_man_name(); foreach my $iid ( keys %$names ) { my $vendor = $names->{$iid}; next unless defined $vendor; if ( $vendor =~ /^(\S+)/ ) { return lc($1); } } return; } sub model { my $dot11 = shift; my $names = $dot11->dot11_prod_name(); foreach my $iid ( keys %$names ) { my $prod = $names->{$iid}; next unless defined $prod; return lc($prod); } return; } sub os_ver { my $dot11 = shift; my $versions = $dot11->dot11_prod_ver(); foreach my $iid ( keys %$versions ) { my $ver = $versions->{$iid}; next unless defined $ver; if ( $ver =~ /([\d\.]+)/ ) { return $1; } } return; } sub i_80211channel { my $dot11 = shift; my $phy_type = $dot11->dot11_phy_type() || {}; my $cur_freq = $dot11->dot11_cur_freq() || {}; my $cur_ch = $dot11->dot11_cur_ch() || {}; my %i_80211channel; foreach my $iid ( keys %$phy_type ) { my $type = $phy_type->{$iid}; next unless defined $type; if ( $type =~ /dsss/ ) { my $ch = $cur_ch->{$iid}; next unless defined $ch; $i_80211channel{$iid} = $ch; } elsif ( $type =~ /ofdm/ ) { my $ch = $cur_freq->{$iid}; next unless defined $ch; $i_80211channel{$iid} = $ch; } else { next; } } return \%i_80211channel; } sub dot11_cur_tx_pwr_mw { my $dot11 = shift; my $partial = shift; my $cur = $dot11->dot11_cur_tx_pwr($partial); my $dot11_cur_tx_pwr_mw = {}; foreach my $idx ( keys %$cur ) { my $pwr = $cur->{$idx}; if ( $pwr >= 1 && $pwr <= 8 ) { # ToDo - Look at string eval my $mw = eval "\$dot11->dot11_tx_pwr_level_$pwr(\$idx)"; ## no critic $dot11_cur_tx_pwr_mw->{$idx} = $mw->{$idx}; } else { next; } } return $dot11_cur_tx_pwr_mw; } 1; __END__ =head1 NAME SNMP::Info::IEEE802dot11 - SNMP Interface to data from F =head1 AUTHOR Eric Miller =head1 SYNOPSIS my $dot11 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $dot11->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION SNMP::Info::IEEE802dot11 is a subclass of SNMP::Info that provides an interface to F. This MIB is used in standards based 802.11 wireless devices. Use or create a subclass of SNMP::Info that inherits this one. Do not use directly. =head2 Inherited Classes =over None. =back =head2 Required MIBs =over =item F =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $dot11->vendor() Tries to discover the vendor from dot11_man_name() - returns lower case of the first word in the first instance found. =item $dot11->model() Tries to discover the model from dot11_prod_name() - returns lower case of the first instance found. =item $dot11->os_ver() Tries to discover the operating system version from dot11_prod_ver() - returns string of numeric and decimals in the first instance found. =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $dot11->i_ssidlist() Returns reference to hash. SSID's recognized by the radio interface. (C) =item $dot11->i_80211channel() Returns reference to hash. Current operating frequency channel of the radio interface. =item $dot11->dot11_cur_tx_pwr_mw() Returns reference to hash. Current transmit power, in milliwatts, of the radio interface. =back =head2 Dot11 Phy OFDM Table (C) =over =item $dot11->dot11_cur_freq() (C) =back =head2 Dot11 Phy DSSS Table (C) =over =item $dot11->dot11_cur_ch() (C) =back =head2 Dot11 Phy Operation Table (C) =over =item $dot11->dot11_phy_type() (C) =item $dot11->dot11_reg_dom() (C) =back =head2 Dot11 Resource Information Table (C) =over =item $dot11->dot11_prod_ver() (C) =item $dot11->dot11_prod_name() (C) =item $dot11->dot11_man_name() (C) =back =head2 Dot11 Operation Table (C) =over =item $dot11->dot11_mac() (C) =back =head2 Dot11 Station Configuration Table (C) =over =item $dot11->dot11_bss_type() (C) =item $dot11->dot11_pwr_mode() (C) =item $dot11->dot11_sta_id() (C) =back =head2 Dot11 Transmission Power Table (C) =over =item $dot11->dot11_cur_tx_pwr() (C) =item $dot11->dot11_tx_pwr_level_1() (C) =item $dot11->dot11_tx_pwr_level_2() (C) =item $dot11->dot11_tx_pwr_level_3() (C) =item $dot11->dot11_tx_pwr_level_4() (C) =item $dot11->dot11_tx_pwr_level_5() (C) =item $dot11->dot11_tx_pwr_level_6() (C) =item $dot11->dot11_tx_pwr_level_7() (C) =item $dot11->dot11_tx_pwr_level_8() (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/IEEE802dot3ad.pm000444000765000024 737713215550564 17677 0ustar00oliverstaff000000000000# SNMP::Info::IEEE802dot3ad # # Copyright (c) 2014 SNMP::Info Developers # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::IEEE802dot3ad; use strict; use Exporter; use SNMP::Info::Aggregate; @SNMP::Info::IEEE802dot3ad::ISA = qw/ SNMP::Info::Aggregate Exporter /; @SNMP::Info::IEEE802dot3ad::EXPORT_OK = qw/ agg_ports_lag /; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Aggregate::MIBS, 'IEEE8023-LAG-MIB' => 'dot3adAggPortSelectedAggID', ); %GLOBALS = (); %FUNCS = (); %MUNGE = (); sub agg_ports_lag { my $dev = shift; # TODO: implement partial my $masters = $dev->dot3adAggActorOperKey; my $slaves = $dev->dot3adAggPortActorOperKey; return {} unless ref {} eq ref $masters and scalar keys %$masters and ref {} eq ref $slaves and scalar keys %$slaves; my $ret = {}; foreach my $s (keys %$slaves) { next if $slaves->{$s} == 0; foreach my $m (keys %$masters) { next unless $masters->{$m} == $slaves->{$s}; $ret->{$s} = $m; last; } } return $ret; } 1; __END__ =head1 NAME SNMP::Info::IEEE802dot3ad - SNMP Interface to IEEE Aggregated Links =head1 AUTHOR SNMP::Info Developers =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $info = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $info->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION This class provides access to Aggregated Links configuration on devices implementing C. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes L =head2 Required MIBs =over =item F =back =head1 METHODS =over 4 =item C Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =back =cut SNMP-Info-3.39/lib/SNMP/Info/IPv6.pm000444000765000024 4054513215550564 16435 0ustar00oliverstaff000000000000# SNMP::Info::IPv6 # # Copyright (c) 2010 Jeroen van Ingen and Carlos Vicente # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::IPv6; use strict; use Exporter; use SNMP::Info; @SNMP::Info::IPv6::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::IPv6::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE $METHOD/; use constant { IPMIB => 1, CISCO => 2, IPV6MIB => 3, }; $VERSION = '3.39'; %MIBS = ( 'IP-MIB' => 'ipv6InterfaceTableLastChange', 'IPV6-MIB' => 'ipv6IfTableLastChange', 'CISCO-IETF-IP-MIB' => 'cInetNetToMediaNetAddress', ); %GLOBALS = (); %FUNCS = ( 'ip_n2p_phys_addr' => 'ipNetToPhysicalPhysAddress', # IP-MIB 'c_inet_phys_addr' => 'cInetNetToMediaPhysAddress', # CISCO-IETF-IP-MIB 'i6_n2p_phys_addr' => 'ipv6NetToMediaPhysAddress', # IPV6-MIB 'ip_n2p_phys_type' => 'ipNetToPhysicalType', # IP-MIB 'c_inet_phys_type' => 'cInetNetToMediaType', # CISCO-IETF-IP-MIB 'i6_n2p_phys_type' => 'ipv6NetToMediaType', # IPV6-MIB 'ip_n2p_phys_state' => 'ipNetToPhysicalState', # IP-MIB 'c_inet_phys_state' => 'cInetNetToMediaState', # CISCO-IETF-IP-MIB 'i6_n2p_phys_state' => 'ipv6NetToMediaState', # IPV6-MIB 'ip_pfx_origin' => 'ipAddressPrefixOrigin', # IP-MIB 'c_pfx_origin' => 'cIpAddressPfxOrigin', # CISCO-IETF-IP-MIB 'ip_addr6_pfx' => 'ipAddressPrefix', # IP-MIB 'c_addr6_pfx' => 'cIpAddressPrefix', # CISCO-IETF-IP-MIB 'ip_addr6_index' => 'ipAddressIfIndex', # IP-MIB 'c_addr6_index' => 'cIpAddressIfIndex', # CISCO-IETF-IP-MIB 'ip_addr6_type' => 'ipAddressType', # IP-MIB 'c_addr6_type' => 'cIpAddressType', # CISCO-IETF-IP-MIB ); %MUNGE = ( 'ip_n2p_phys_addr' => \&SNMP::Info::munge_mac, 'c_inet_phys_addr' => \&munge_physaddr, 'i6_n2p_phys_addr' => \&SNMP::Info::munge_mac, ); sub ipv6_n2p_mac { my $info = shift; my $return; my $phys_addr = &_test_methods( $info, { ip_n2p_phys_addr => IPMIB, c_inet_phys_addr => CISCO, i6_n2p_phys_addr => IPV6MIB, }); return unless defined $phys_addr; foreach my $row (keys %$phys_addr) { if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) { my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4; if ($info::METHOD == IPV6MIB) { # IPV6-MIB doesn't include the addrtype in the index; # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes) $v6addr = join('.', $addrtype, $addrsize, $v6addr); $addrtype = 2; } if (($addrtype == 2) && (defined $phys_addr->{$row})) { # IPv6 $return->{$row} = substr($phys_addr->{$row}, 0, 17); } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_n2p_addr { my $info = shift; my $return; my $net_addr = &_test_methods( $info, { ip_n2p_phys_addr => IPMIB, c_inet_phys_addr => CISCO, i6_n2p_phys_addr => IPV6MIB, }); return unless defined $net_addr; foreach my $row (keys %$net_addr) { if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) { my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4; if ($info::METHOD == IPV6MIB) { # IPV6-MIB doesn't include the addrtype in the index; # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes) $v6addr = join('.', $addrtype, $addrsize, $v6addr); $addrtype = 2; } if ($addrtype == 2) { # IPv6 my $v6_packed = pack("C*", split(/\./, $v6addr)); if (length($v6_packed) == 15) { # Workaround for some some IP-MIB implementations, eg on Cisco Nexus: no explicit addrsize, # so what we've collected in that variable is actually the first byte of the address. $v6_packed = pack('C', $addrsize) . $v6_packed; } if (length($v6_packed) == 17) { # Workaround for IPV6-MIB on Windows 2012: if the address is one byte too long, the SNMP agent probably has an incorrect # implementation where a length field precedes the actual IPv6 address. # In that case, the first character should be chr(16), ie 0x10; strip it if that's the case. $v6_packed =~ s/^\x10//; } if (length($v6_packed) == 16) { $v6addr = join(':', map { sprintf("%04x", $_) } unpack("n*", $v6_packed) ); $return->{$row} = $v6addr; } else { printf("Invalid size for IPv6 address: expected 16 bytes, got %d (%s = %s)\n", length($v6_packed), $row, $net_addr->{$row}); } } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_n2p_if { my $info = shift; my $return; my $phys_addr = &_test_methods( $info, { ip_n2p_phys_addr => IPMIB, c_inet_phys_addr => CISCO, i6_n2p_phys_addr => IPV6MIB, }); return unless defined $phys_addr; foreach my $row (keys %$phys_addr) { if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) { my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4; if ($info::METHOD == IPV6MIB) { # IPV6-MIB doesn't include the addrtype in the index; # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes) $v6addr = join('.', $addrtype, $addrsize, $v6addr); $addrtype = 2; } if ($addrtype == 2) { # IPv6 $return->{$row} = $ifindex; } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_n2p_type { my $info = shift; my $return; my $phys_type = &_test_methods( $info, { ip_n2p_phys_type => IPMIB, c_inet_phys_type => CISCO, i6_n2p_phys_type => IPV6MIB, }); return unless defined $phys_type; foreach my $row (keys %$phys_type) { if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) { my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4; if ($info::METHOD == IPV6MIB) { # IPV6-MIB doesn't include the addrtype in the index; # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes) $v6addr = join('.', $addrtype, $addrsize, $v6addr); $addrtype = 2; } if ($addrtype == 2) { # IPv6 $return->{$row} = $phys_type->{$row}; } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_n2p_state { my $info = shift; my $return; my $phys_state = &_test_methods( $info, { ip_n2p_phys_state => IPMIB, c_inet_phys_state => CISCO, i6_n2p_phys_state => IPV6MIB, }); return unless defined $phys_state; foreach my $row (keys %$phys_state) { if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) { my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4; if ($info::METHOD == IPV6MIB) { # IPV6-MIB doesn't include the addrtype in the index; # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes) $v6addr = join('.', $addrtype, $addrsize, $v6addr); $addrtype = 2; } if ($addrtype == 2) { # IPv6 $return->{$row} = $phys_state->{$row}; } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_index { my $info = shift; my $return; my $ipv6_index = &_test_methods( $info, { ip_addr6_index => IPMIB, c_addr6_index => CISCO, }); return unless defined $ipv6_index; foreach my $row (keys %$ipv6_index){ if ($row =~ /^(\d+)\.([\d\.]+)$/) { my $addrtype = $1; my $v6addr = $2; if ($addrtype == 2) { # IPv6 $return->{$row} = $ipv6_index->{$row}; } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_type { my $info = shift; my $return; my $ipv6_type = &_test_methods( $info, { ip_addr6_type => IPMIB, c_addr6_type => CISCO, }); return unless defined $ipv6_type; foreach my $row (keys %$ipv6_type){ if ($row =~ /^(\d+)\.([\d\.]+)$/) { my $addrtype = $1; my $v6addr = $2; if ($addrtype == 2) { # IPv6 $return->{$row} = $ipv6_type->{$row}; } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_pfx_origin { my $info = shift; my $return; my $ipv6_pfx_origin = &_test_methods( $info, { ip_pfx_origin => IPMIB, c_pfx_origin => CISCO, }); return unless defined $ipv6_pfx_origin; foreach my $row (keys %$ipv6_pfx_origin){ if ($row =~ /^(\d+)\.(\d+)\.([\d\.]+)\.(\d+)$/) { my $ifindex = $1; my $type = $2; my $pfx = $3; my $len = $4; if ($type == 2) { # IPv6 $return->{$row} = $ipv6_pfx_origin->{$row}; } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_addr_prefix { my $info = shift; my $return; my $ipv6_addr_prefix = &_test_methods( $info, { ip_addr6_pfx => IPMIB, c_addr6_pfx => CISCO, }); return unless defined $ipv6_addr_prefix; foreach my $row (keys %$ipv6_addr_prefix){ if ($row =~ /^(\d+)\.[\d\.]+$/) { my $type = $1; if (($type == 2) or ($type == 4)) { # IPv6 # Remove interface specific part from vrf interfaces if ($row =~ /^((\d+\.){17}\d+)/) { $row = $1 } # Remove the OID part from the value my $val = $ipv6_addr_prefix->{$row}; if ( $val =~ /^.+?((?:\d+\.){19}\d+)$/ ){ $val = $1; $return->{$row} = $val; } } } } printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug(); return $return; } sub ipv6_addr { my $info = shift; my $return; my $indexes = $info->ipv6_index(); foreach my $row (keys %$indexes) { my @parts = split(/\./, $row); my $is_valid = 0; if (scalar @parts == 18) { my $addrtype = shift @parts; $is_valid = 1; } elsif (scalar @parts == 17) { $is_valid = 1; } my $addrsize = shift @parts; # First element now is addrsize, should be 16 if ($is_valid && $addrsize == 16) { $return->{$row} = join(':', unpack('(H4)*', pack('C*', @parts))); } else { warn sprintf("%s: unable to decode table index to IPv6 address. Raw data is [%s].\n", &_my_sub_name, $row); } } return $return; } sub _method_used { my $info = shift; my $return = 'none of the MIBs'; if (defined $info::METHOD) { if ($info::METHOD eq IPMIB) { $return = 'IP-MIB'; } elsif ($info::METHOD eq IPV6MIB) { $return = 'IPV6-MIB'; } elsif ($info::METHOD eq CISCO) { $return = 'CISCO-IETF-IP-MIB'; } } return $return; } sub _test_methods { my $info = shift; my $test = shift; my $return = {}; foreach my $method (sort {$test->{$a} <=> $test->{$b}} keys %$test) { $return = $info->$method || {}; if (scalar keys %$return) { $info::METHOD = $test->{$method}; last; } } return $return; } sub _my_sub_name { my @callinfo = caller(1); return $callinfo[3]; } sub munge_physaddr { my $addr = shift; return unless defined $addr; return unless length $addr; $addr = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $addr ) ); return $addr; } 1; __END__ =head1 NAME SNMP::Info::IPv6 - SNMP Interface for obtaining IPv6 addresses and IPv6 address mappings =head1 AUTHOR Jeroen van Ingen and Carlos Vicente =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $info = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $info->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION The SNMP::Info::IPv6 class implements functions to for mapping IPv6 addresses to MAC addresses, interfaces and more. It will use data from the F, F, or the F, whichever is supported by the device. This class is inherited by Info::Layer3 to provide IPv6 node tracking across device classes. For debugging purposes you can call this class directly as you would SNMP::Info my $info = new SNMP::Info::IPv6 (...); =head2 Inherited Classes none. =head2 Required MIBs =over =item F =item F =item F =back =head1 GLOBALS none. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Internet Address Table =over =item $info->ipv6_n2p_addr() =item $info->ipv6_n2p_if() =item $info->ipv6_n2p_mac() =item $info->ipv6_n2p_state() =item $info->ipv6_n2p_type() =item $info->ipv6_index() Maps an IPv6 address to an interface C =item $info->ipv6_type() Maps an IPv6 address to its type (unicast, anycast, etc.) =item $info->ipv6_pfx_origin() Maps an IPv6 prefix with its origin (manual, well-known, dhcp, etc.) =item $info->ipv6_addr_prefix() Maps IPv6 addresses with their prefixes =item $info->ipv6_addr() Maps a table instance to an IPv6 address =back =head2 Internet Address Translation Table =over =item $info->c_inet_phys_address() Maps an address of type C on interface C to a physical address. =back =head1 MUNGES =over =item munge_physaddr() Takes an octet stream (HEX-STRING) and returns a colon separated ASCII hex string. =back =cut SNMP-Info-3.39/lib/SNMP/Info/LLDP.pm000444000765000024 4517613215550564 16411 0ustar00oliverstaff000000000000# SNMP::Info::LLDP # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::LLDP; use strict; use Exporter; use SNMP::Info; @SNMP::Info::LLDP::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::LLDP::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'LLDP-MIB' => 'lldpLocSysCapEnabled', 'LLDP-EXT-MED-MIB' => 'lldpXMedMIB', 'LLDP-EXT-DOT1-MIB' => 'lldpXdot1MIB', 'LLDP-EXT-DOT3-MIB' => 'lldpXdot3MIB', ); %GLOBALS = ( 'lldp_sysname' => 'lldpLocSysName', 'lldp_sysdesc' => 'lldpLocSysDesc', 'lldp_sys_cap' => 'lldpLocSysCapEnabled', ); %FUNCS = ( # LLDP-MIB::lldpLocManAddrTable 'lldp_lman_addr' => 'lldpLocManAddrIfId', # LLDP-MIB::lldpRemTable 'lldp_rem_id_type' => 'lldpRemChassisIdSubtype', 'lldp_rem_id' => 'lldpRemChassisId', 'lldp_rem_pid_type' => 'lldpRemPortIdSubtype', 'lldp_rem_pid' => 'lldpRemPortId', 'lldp_rem_desc' => 'lldpRemPortDesc', 'lldp_rem_sysname' => 'lldpRemSysName', 'lldp_rem_sysdesc' => 'lldpRemSysDesc', 'lldp_rem_sys_cap' => 'lldpRemSysCapEnabled', 'lldp_rem_cap_spt' => 'lldpRemSysCapSupported', # LLDP-MIB::lldpRemManAddrTable 'lldp_rman_addr' => 'lldpRemManAddrIfSubtype', ); %MUNGE = ( 'lldp_sysdesc' => \&SNMP::Info::munge_null, 'lldp_sysname' => \&SNMP::Info::munge_null, 'lldp_rem_sysname' => \&SNMP::Info::munge_null, 'lldp_rem_sysdesc' => \&SNMP::Info::munge_null, 'lldp_rem_port_desc' => \&SNMP::Info::munge_null, 'lldp_sys_cap' => \&SNMP::Info::munge_bits, 'lldp_rem_sys_cap' => \&SNMP::Info::munge_bits, 'lldp_rem_cap_spt' => \&SNMP::Info::munge_bits, ); sub hasLLDP { my $lldp = shift; # We may be have LLDP, but nothing in lldpRemoteSystemsData Tables # so we could be running LLDP but not return any useful information my $lldp_cap = $lldp->lldp_sys_cap(); return 1 if defined $lldp_cap; # If the device doesn't return local system capabilities, fallback by checking if it would report neighbors my $lldp_rem = $lldp->lldp_rem_id() || {}; return 1 if scalar keys %$lldp_rem; return; } sub lldp_if { my $lldp = shift; my $partial = shift; my $addr = $lldp->lldp_rem_pid($partial) || {}; my $i_descr = $lldp->i_description() || {}; my $i_alias = $lldp->i_alias() || {}; my %r_i_descr = reverse %$i_descr; my %r_i_alias = reverse %$i_alias; my %lldp_if; foreach my $key ( keys %$addr ) { my @aOID = split( '\.', $key ); my $port = $aOID[1]; next unless $port; # Local LLDP port may not equate to ifIndex, see LldpPortNumber TEXTUAL-CONVENTION in LLDP-MIB. # Cross reference lldpLocPortDesc with ifDescr and ifAlias to get ifIndex, # prefer ifDescr over ifAlias because using cross ref with description is correct behavior # according to the LLDP-MIB. Some devices (eg H3C gear) seem to use ifAlias though. my $lldp_desc = $lldp->lldpLocPortDesc($port); my $desc = $lldp_desc->{$port}; # If cross reference is successful use it, otherwise stick with lldpRemLocalPortNum if ( $desc && exists $r_i_descr{$desc} ) { $port = $r_i_descr{$desc}; } elsif ( $desc && exists $r_i_alias{$desc} ) { $port = $r_i_alias{$desc}; } $lldp_if{$key} = $port; } return \%lldp_if; } sub lldp_ip { my $lldp = shift; my $partial = shift; my $rman_addr = $lldp->lldp_rman_addr($partial) || {}; my %lldp_ip; foreach my $key ( keys %$rman_addr ) { my ( $index, $proto, $addr ) = _lldp_addr_index($key); next unless defined $index; next unless $proto == 1; $lldp_ip{$index} = $addr; } return \%lldp_ip; } sub lldp_ipv6 { my $lldp = shift; my $partial = shift; my $rman_addr = $lldp->lldp_rman_addr($partial) || {}; my %lldp_ipv6; foreach my $key ( keys %$rman_addr ) { my ( $index, $proto, $addr ) = _lldp_addr_index($key); next unless defined $index; next unless $proto == 2; $lldp_ipv6{$index} = $addr; } return \%lldp_ipv6; } sub lldp_mac { my $lldp = shift; my $partial = shift; my $rman_addr = $lldp->lldp_rman_addr($partial) || {}; my %lldp_ipv6; foreach my $key ( keys %$rman_addr ) { my ( $index, $proto, $addr ) = _lldp_addr_index($key); next unless defined $index; next unless $proto == 6; $lldp_ipv6{$index} = $addr; } return \%lldp_ipv6; } sub lldp_addr { my $lldp = shift; my $partial = shift; my $rman_addr = $lldp->lldp_rman_addr($partial) || {}; my %lldp_ip; foreach my $key ( keys %$rman_addr ) { my ( $index, $proto, $addr ) = _lldp_addr_index($key); next unless defined $index; $lldp_ip{$index} = $addr; } return \%lldp_ip; } sub lldp_port { my $lldp = shift; my $partial = shift; my $pdesc = $lldp->lldp_rem_desc($partial) || {}; my $pid = $lldp->lldp_rem_pid($partial) || {}; my $ptype = $lldp->lldp_rem_pid_type($partial) || {}; my $desc = $lldp->lldp_rem_sysdesc($partial) || {}; my %lldp_port; foreach my $key ( sort keys %$pid ) { my $port = $pdesc->{$key}; my $type = $ptype->{$key}; if ( $type and $type eq 'interfaceName' ) { # If the pid claims to be an interface name, # believe it. $port = $pid->{$key}; } unless ($port) { $port = $pid->{$key}; next unless $port; next unless $type; # May need to format other types in the future, i.e. Network address if ( $type =~ /mac/ ) { $port = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $port ) ); } } # Avaya/Nortel lldpRemPortDesc doesn't match ifDescr, but we can still # figure out slot.port based upon lldpRemPortDesc if ( defined $desc->{$key} && $desc->{$key} =~ /^Ethernet\s(?:Routing\s)?Switch\s\d|^Virtual\sServices\sPlatform\s\d/ && $port =~ /^(Unit\s+(\d+)\s+)?Port\s+(\d+)$/ ) { $port = defined $1 ? "$2.$3" : "1.$3"; } $lldp_port{$key} = $port; } return \%lldp_port; } sub lldp_id { my $lldp = shift; my $partial = shift; my $ch_type = $lldp->lldp_rem_id_type($partial) || {}; my $ch = $lldp->lldp_rem_id($partial) || {}; my %lldp_id; foreach my $key ( keys %$ch ) { my $id = $ch->{$key}; next unless $id; my $type = $ch_type->{$key}; next unless $type; # May need to format other types in the future if ( $type =~ /mac/ ) { $id = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $id ) ); } elsif ( $type eq 'networkAddress' ) { if ( length( unpack( 'H*', $id ) ) == 10 ) { # IP address (first octet is sign, I guess) my @octets = ( map { sprintf "%02x", $_ } unpack( 'C*', $id ) ) [ 1 .. 4 ]; $id = join '.', map { hex($_) } @octets; } } $lldp_id{$key} = $id; } return \%lldp_id; } sub lldp_platform { my $lldp = shift; my $partial = shift; my $rid = $lldp->lldp_rem_id($partial) || {}; my $desc = $lldp->lldp_rem_sysdesc($partial) || {}; my $name = $lldp->lldp_rem_sysname($partial) || {}; my %lldp_platform; foreach my $key ( keys %$rid ) { $lldp_platform{$key} = $desc->{$key} || $name->{$key}; } return \%lldp_platform; } sub lldp_cap { my $lldp = shift; my $partial = shift; my $lldp_caps = $lldp->lldp_rem_cap_spt($partial) || {}; # Encoded as BITS which Perl Net-SNMP implementation doesn't seem to # be able to enumerate for us, so we have to get it from the MIB # and enumerate ourselves my $oid = SNMP::translateObj( 'lldpRemSysCapEnabled', 0, 1 ) || ''; my $enums = ( ( ref {} eq ref $SNMP::MIB{$oid}{'enums'} ) ? $SNMP::MIB{$oid}{'enums'} : {} ); my %r_enums = reverse %$enums; my %lldp_cap; foreach my $key ( keys %$lldp_caps ) { my $cap_bits = $lldp_caps->{$key}; next unless $cap_bits; my $count = 0; foreach my $bit ( split //, $cap_bits ) { if ($bit) { push( @{ $lldp_cap{$key} }, $r_enums{$count} ); } $count++; } } return \%lldp_cap; } #sub root_ip { # my $lldp = shift; # # my $man_addr = $lldp->lldp_lman_addr() || {}; # # foreach my $key (keys %$man_addr) { # my @oids = split(/\./, $key); # my $proto = shift(@oids); # my $length = shift(@oids); # # IPv4 # if ($proto == 1) { # my $addr = join('.',@oids); # return $addr if (defined $addr and $lldp->snmp_connect_ip($addr)); # } # } # return; #} # Break up the lldpRemManAddrTable INDEX into common index, protocol, # and address. sub _lldp_addr_index { my $idx = shift; my @oids = split( /\./, $idx ); my $index = join( '.', splice( @oids, 0, 3 ) ); my $proto = shift(@oids); shift(@oids) if scalar @oids > 4; # $length # IPv4 if ( $proto == 1 ) { return ( $index, $proto, join( '.', @oids ) ); } # IPv6 elsif ( $proto == 2 ) { return ( $index, $proto, join(':', unpack('(H4)*', pack('C*', @oids)) ) ); } # MAC elsif ( $proto == 6 ) { return ( $index, $proto, join( ':', map { sprintf "%02x", $_ } @oids ) ); } # TODO - Other protocols may be used as well; implement when needed? else { return; } } 1; __END__ =head1 NAME SNMP::Info::LLDP - SNMP Interface to the Link Layer Discovery Protocol (LLDP) =head1 AUTHOR Eric Miller =head1 SYNOPSIS my $lldp = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'router', Community => 'public', Version => 2 ); my $class = $lldp->class(); print " Using device sub class : $class\n"; $haslldp = $lldp->hasLLDP() ? 'yes' : 'no'; # Print out a map of device ports with LLDP neighbors: my $interfaces = $lldp->interfaces(); my $lldp_if = $lldp->lldp_if(); my $lldp_ip = $lldp->lldp_ip(); my $lldp_port = $lldp->lldp_port(); foreach my $lldp_key (keys %$lldp_ip){ my $iid = $lldp_if->{$lldp_key}; my $port = $interfaces->{$iid}; my $neighbor = $lldp_ip->{$lldp_key}; my $neighbor_port = $lldp_port->{$lldp_key}; print "Port : $port connected to $neighbor / $neighbor_port\n"; } =head1 DESCRIPTION SNMP::Info::LLDP is a subclass of SNMP::Info that provides an object oriented interface to LLDP information through SNMP. LLDP is a Layer 2 protocol that allows a network device to advertise its identity and capabilities on the local network providing topology information. The protocol is defined in the IEEE standard 802.1AB. Create or use a device subclass that inherits this class. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =item F =item F =item F =back =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $lldp->hasLLDP() Is LLDP is active in this device? Note: LLDP may be active, but nothing in C Tables so the device would not return any useful topology information. =item $lldp->lldp_sysname() The string value used to identify the system name of the local system. If the local agent supports IETF RFC 3418, C object should have the same value of C object. Nulls are removed before the value is returned. (C) =item $lldp->lldp_sysdesc() The string value used to identify the system description of the local system. If the local agent supports IETF RFC 3418, C object should have the same value of C object. Nulls are removed before the value is returned. (C) =item $lldp->lldp_sys_cap() Returns which system capabilities are enabled on the local system. Results are munged into an ascii binary string, LSB. Each digit represents a bit from the table below: =over =item Bit 'other(0)' indicates that the system has capabilities other than those listed below. =item Bit 'repeater(1)' indicates that the system has repeater capability. =item Bit 'bridge(2)' indicates that the system has bridge capability. =item Bit 'wlanAccessPoint(3)' indicates that the system has WLAN access point capability. =item Bit 'router(4)' indicates that the system has router capability. =item Bit 'telephone(5)' indicates that the system has telephone capability. =item Bit 'docsisCableDevice(6)' indicates that the system has DOCSIS Cable Device capability (IETF RFC 2669 & 2670). =item Bit 'stationOnly(7)' indicates that the system has only station capability and nothing else." =back (C) =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $lldp->lldp_id() Returns the string value used to identify the chassis component associated with the remote system. (C) =item $lldp->lldp_if() Returns the mapping to the SNMP Interface Table. Tries to cross reference (C) with (C) and (C) to get (C), if unable defaults to (C). =item $lldp->lldp_ip() Returns remote IPv4 address. Returns for all other address types, use lldp_addr if you want any return address type. =item $lldp->lldp_ipv6() Returns remote IPv6 address, if known. Returns for all other address types, use lldp_addr if you don't care about return address type. =item $lldp->lldp_mac() Returns remote (management) MAC address, if known. Returns for all other address types, use lldp_addr if you don't care about return address type. =item $lldp->lldp_addr() Returns remote address. Type may be any IANA Address Family Number. Currently only returns IPv4, IPv6 or MAC addresses. If the remote device returns more than one address type, this method will give only one. Which one is returned is decided by chance, phase of the moon and Perl hash ordering. Use lldp_mac, lldp_ip or lldp_ipv6 if you want a specific address type. =item $lldp->lldp_port() Returns remote port ID =item $lldp->lldp_platform() Tries to return something useful from C or C. =item $lldp->lldp_cap() Returns hash of arrays with each array containing the system capabilities supported by the remote system. Possible elements in the array are enumerated from C. =back =head2 LLDP Remote Table (C) =over =item $lldp->lldp_rem_id_type() Returns the type of encoding used to identify the chassis associated with the remote system. (C) =item $lldp->lldp_rem_id() Returns the string value used to identify the chassis component associated with the remote system. (C) =item $lldp->lldp_rem_pid_type() Returns the type of port identifier encoding used in the associated C object. (C) =item $lldp->lldp_rem_pid() Returns the string value used to identify the port component associated with the remote system. (C) =item $lldp->lldp_rem_desc() Returns the string value used to identify the description of the given port associated with the remote system. Nulls are removed before the value is returned. (C) =item $lldp->lldp_rem_sysname() Returns the string value used to identify the system name of the remote system. Nulls are removed before the value is returned. (C) =item $lldp->lldp_rem_sysdesc() Returns the string value used to identify the system description of the remote system. Nulls are removed before the value is returned. (C) =item $lldp->lldp_rem_sys_cap() Returns which system capabilities are enabled on the remote system. Results are munged into an ascii binary string, LSB. Each digit represents a bit from the table below: =over =item Bit 'other(0)' indicates that the system has capabilities other than those listed below. =item Bit 'repeater(1)' indicates that the system has repeater capability. =item Bit 'bridge(2)' indicates that the system has bridge capability. =item Bit 'wlanAccessPoint(3)' indicates that the system has WLAN access point capability. =item Bit 'router(4)' indicates that the system has router capability. =item Bit 'telephone(5)' indicates that the system has telephone capability. =item Bit 'docsisCableDevice(6)' indicates that the system has DOCSIS Cable Device capability (IETF RFC 2669 & 2670). =item Bit 'stationOnly(7)' indicates that the system has only station capability and nothing else." =back (C) =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer1.pm000444000765000024 2003613215550564 16777 0ustar00oliverstaff000000000000# SNMP::Info::Layer1 - SNMP Interface to Layer1 Devices # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer1; use strict; use Exporter; use SNMP::Info; @SNMP::Info::Layer1::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::Layer1::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, 'SNMP-REPEATER-MIB' => 'rptrPortGroupIndex' ); %GLOBALS = ( %SNMP::Info::GLOBALS, 'ports_managed' => 'ifNumber', 'rptr_slots' => 'rptrGroupCapacity', 'slots' => 'rptrGroupCapacity' ); %FUNCS = ( %SNMP::Info::FUNCS, 'rptr_ports' => 'rptrGroupPortCapacity', 'rptr_port' => 'rptrPortIndex', 'rptr_slot' => 'rptrPortGroupIndex', 'rptr_up_admin' => 'rptrPortAdminStatus', 'rptr_up' => 'rptrPortOperStatus', 'rptr_last_src' => 'rptrAddrTrackNewLastSrcAddress', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::MUNGE, 'rptr_last_src' => \&SNMP::Info::munge_mac, ); # Method OverRides # assuming managed ports aren't in repeater ports? sub ports { my $l1 = shift; my $ports = $l1->ports_managed(); my $rptr_ports = $l1->rptr_ports(); foreach my $group ( keys %$rptr_ports ) { $ports += $rptr_ports->{$group}; } return $ports; } # $l1->model() - Looks at sysObjectID which gives the oid of the system # name, contained in a propriatry MIB. sub model { my $l1 = shift; my $id = $l1->id(); my $model = &SNMP::translateObj($id); # HP $model =~ s/^hpswitch//i; # Cisco $model =~ s/sysid$//i; return $model; } sub vendor { my $l1 = shift; my $descr = $l1->description(); return 'hp' if ( $descr =~ /hp/i ); return 'cisco' if ( $descr =~ /(catalyst|cisco|ios)/i ); return 'allied' if ( $descr =~ /allied/i ); return 'asante' if ( $descr =~ /asante/i ); return 'unknown'; } # By Default we'll use the description field sub interfaces { my $l1 = shift; my $partial = shift; my $interfaces = $l1->i_index($partial) || {}; my $rptr_port = $l1->rptr_port($partial) || {}; foreach my $port ( keys %$rptr_port ) { $interfaces->{$port} = $port; } return $interfaces; } sub i_up_admin { my $l1 = shift; my $partial = shift; my $i_up_admin = $l1->SUPER::i_up_admin($partial) || {}; my $rptr_up_admin = $l1->rptr_up_admin($partial) || {}; foreach my $key ( keys %$rptr_up_admin ) { my $up = $rptr_up_admin->{$key}; $i_up_admin->{$key} = 'up' if $up =~ /enabled/; $i_up_admin->{$key} = 'down' if $up =~ /disabled/; } return $i_up_admin; } sub i_up { my $l1 = shift; my $partial = shift; my $i_up = $l1->SUPER::i_up($partial) || {}; my $rptr_up = $l1->rptr_up($partial) || {}; foreach my $key ( keys %$rptr_up ) { my $up = $rptr_up->{$key}; $i_up->{$key} = 'up' if $up =~ /operational/; } return $i_up; } 1; __END__ =head1 NAME SNMP::Info::Layer1 - SNMP Interface to network devices serving Layer1 only. =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $l1 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $l1->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; # Let's get some basic Port information my $interfaces = $l1->interfaces(); my $i_up = $l1->i_up(); my $i_speed = $l1->i_speed(); foreach my $iid (keys %$interfaces) { my $port = $interfaces->{$iid}; my $up = $i_up->{$iid}; my $speed = $i_speed->{$iid} print "Port $port is $up. Port runs at $speed.\n"; } =head1 DESCRIPTION This class is usually used as a superclass for more specific device classes listed under SNMP::Info::Layer1::* Please read all docs under SNMP::Info first. Provides abstraction to the configuration information obtainable from a Layer1 device through SNMP. Information is stored in a number of MIBs. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $l1 = new SNMP::Info::Layer1(...); =head2 Inherited Classes =over =item SNMP::Info =back =head2 Required MIBs =over =item F =back MIBs required for L See L for its MIB requirements. F needs to be extracted from ftp://ftp.cisco.com/pub/mibs/v1/v1.tar.gz =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $l1->ports_managed() Gets the number of ports under the interface mib (C) =back =head2 Overrides =over =item $l1->model() Cross references $l1->id() with product IDs. For HP devices, removes C<'hpswitch'> from the name For Cisco devices, removes C<'sysid'> from the name =item $l1->vendor() Tries to discover the vendor from $l1->model() and $l1->vendor() =item $l1->ports() Adds the values from rptr_ports() and ports_managed() =item $l1->slots() Number of 'groups' in the Repeater MIB (C) =back =head2 Global Methods imported from SNMP::Info See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $l1->interfaces() Returns reference to the map between IID and physical Port. =item $l1->i_up() Returns reference to map of IIDs to link status. =item $l1->i_up_admin() Returns reference to map of IIDs to administrative link status. =back =head2 Repeater MIB =over =item $l1->rptr_ports() Number of ports in each group. (C) =item $l1->rptr_port() Port number in Group (C) =item $l1->rptr_slot() Group (slot) Number for given port. (C) =item $l1->rptr_up_admin() (C) =item $l1->rptr_up() (C) =item $l1->rptr_last_src() (C) =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2.pm000444000765000024 2037313215550564 17004 0ustar00oliverstaff000000000000# SNMP::Info::Layer2 - SNMP Interface to Layer2 Devices # $Id$ # # Copyright (c) 2008 Max Baker -- All changes from Version 0.7 on # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Bridge; use SNMP::Info::Entity; use SNMP::Info::PowerEthernet; use SNMP::Info::LLDP; @SNMP::Info::Layer2::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::Entity SNMP::Info::PowerEthernet SNMP::Info::LLDP Exporter/; @SNMP::Info::Layer2::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::Bridge::MIBS, %SNMP::Info::Entity::MIBS, %SNMP::Info::PowerEthernet::MIBS, %SNMP::Info::LLDP::MIBS, ); %GLOBALS = ( %SNMP::Info::GLOBALS, %SNMP::Info::Bridge::GLOBALS, %SNMP::Info::Entity::GLOBALS, %SNMP::Info::PowerEthernet::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'serial1' => '.1.3.6.1.4.1.9.3.6.3.0', # OLD-CISCO-CHASSIS-MIB::chassisId.0 ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::Bridge::FUNCS, %SNMP::Info::Entity::FUNCS, %SNMP::Info::PowerEthernet::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::MUNGE, %SNMP::Info::Bridge::MUNGE, %SNMP::Info::Entity::MUNGE, %SNMP::Info::PowerEthernet::MUNGE, %SNMP::Info::LLDP::MUNGE, ); # Method OverRides # $l2->model() - Looks at sysObjectID which gives the oid of the system # name, contained in a propriatry MIB. sub model { my $l2 = shift; my $id = $l2->id(); my $model = &SNMP::translateObj($id) || $id || ''; # HP $model =~ s/^hpswitch//i; # Cisco $model =~ s/sysid$//i; $model =~ s/^(cisco|catalyst)//i; $model =~ s/^cat//i; return $model; } sub vendor { my $l2 = shift; my $model = $l2->model(); my $descr = $l2->description(); if ( $model =~ /hp/i or $descr =~ /\bhp\b/i ) { return 'hp'; } if ( $model =~ /catalyst/i or $descr =~ /(catalyst|cisco)/i ) { return 'cisco'; } } sub serial { my $l2 = shift; my $serial1 = $l2->serial1(); my $e_descr = $l2->e_descr() || {}; my $e_serial = $l2->e_serial() || {}; my $serial2 = $e_serial->{1} || undef; my $chassis = $e_descr->{1} || undef; # precedence # serial2,chassis parse,serial1 return $serial2 if ( defined $serial2 and $serial2 !~ /^\s*$/ ); if ( defined $chassis and $chassis =~ /serial#?:\s*([a-z0-9]+)/i ) { return $1; } return $serial1 if ( defined $serial1 and $serial1 !~ /^\s*$/ ); return; } sub interfaces { my $l2 = shift; my $partial = shift; my $interfaces = $l2->i_index($partial) || {}; my $i_descr = $l2->i_description($partial) || {}; # Replace the Index with the ifDescr field. # Check for duplicates in ifDescr, if so uniquely identify by adding # ifIndex to repeated values my %seen; foreach my $iid ( keys %$i_descr ) { my $port = $i_descr->{$iid}; next unless defined $port; if ( $seen{$port}++ ) { $interfaces->{$iid} = sprintf( "%s (%d)", $port, $iid ); } else { $interfaces->{$iid} = $port; } } return $interfaces; } 1; __END__ =head1 NAME SNMP::Info::Layer2 - SNMP Interface to network devices serving Layer2 only. =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $l2 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $l2->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; # Let's get some basic Port information my $interfaces = $l2->interfaces(); my $i_up = $l2->i_up(); my $i_speed = $l2->i_speed(); foreach my $iid (keys %$interfaces) { my $port = $interfaces->{$iid}; my $up = $i_up->{$iid}; my $speed = $i_speed->{$iid} print "Port $port is $up. Port runs at $speed.\n"; } =head1 DESCRIPTION This class is usually used as a superclass for more specific device classes listed under SNMP::Info::Layer2::* Please read all docs under SNMP::Info first. Provides abstraction to the configuration information obtainable from a Layer2 device through SNMP. Information is stored in a number of MIBs. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $l2 = new SNMP::Info::Layer2(...); =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Bridge =item SNMP::Info::Entity =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item Inherited Classes MIBs required by the inherited classes listed above. =back MIBs can be found in netdisco-mibs package. =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $l2->model() Cross references $l2->id() with product IDs in the Cisco MIBs. For HP devices, removes C<'hpswitch'> from the name For Cisco devices, removes c<'sysid'> from the name =item $l2->vendor() Tries to discover the vendor from $l2->model() and $l2->description() =item $l2->serial() Returns serial number if available through SNMP =back =head2 Globals imported from SNMP::Info See documentation in L for details. =head2 Globals imported from SNMP::Info::Bridge See documentation in L for details. =head2 Globals imported from SNMP::Info::Entity See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $l2->interfaces() Creates a map between the interface identifier (iid) and the physical port name. Defaults to C but checks and overrides with C =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Bridge See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Entity See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3.pm000444000765000024 4777413215550564 17023 0ustar00oliverstaff000000000000# SNMP::Info::Layer3 - SNMP Interface to Layer3 devices # $Id$ # # Copyright (c) 2008 Max Baker -- All changes from Version 0.7 on # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Bridge; use SNMP::Info::EtherLike; use SNMP::Info::Entity; use SNMP::Info::PowerEthernet; use SNMP::Info::IPv6; use SNMP::Info::AdslLine; use SNMP::Info::LLDP; @SNMP::Info::Layer3::ISA = qw/ SNMP::Info::PowerEthernet SNMP::Info::IPv6 SNMP::Info::Entity SNMP::Info::EtherLike SNMP::Info::Bridge SNMP::Info::AdslLine SNMP::Info::LLDP SNMP::Info Exporter/; @SNMP::Info::Layer3::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::AdslLine::MIBS, %SNMP::Info::Bridge::MIBS, %SNMP::Info::EtherLike::MIBS, %SNMP::Info::Entity::MIBS, %SNMP::Info::PowerEthernet::MIBS, %SNMP::Info::IPv6::MIBS, %SNMP::Info::LLDP::MIBS, 'IP-MIB' => 'ipNetToMediaIfIndex', 'OSPF-MIB' => 'ospfRouterId', 'BGP4-MIB' => 'bgpIdentifier', ); %GLOBALS = ( # Inherit the super class ones %SNMP::Info::GLOBALS, %SNMP::Info::AdslLine::GLOBALS, %SNMP::Info::Bridge::GLOBALS, %SNMP::Info::EtherLike::GLOBALS, %SNMP::Info::Entity::GLOBALS, %SNMP::Info::PowerEthernet::GLOBALS, %SNMP::Info::IPv6::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'mac' => 'ifPhysAddress.1', 'serial1' => '.1.3.6.1.4.1.9.3.6.3.0', # OLD-CISCO-CHASSIS-MIB::chassisId.0 'router_ip' => 'ospfRouterId.0', 'bgp_id' => 'bgpIdentifier.0', 'bgp_local_as' => 'bgpLocalAs.0', ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::AdslLine::FUNCS, %SNMP::Info::Bridge::FUNCS, %SNMP::Info::EtherLike::FUNCS, %SNMP::Info::Entity::FUNCS, %SNMP::Info::PowerEthernet::FUNCS, %SNMP::Info::IPv6::FUNCS, %SNMP::Info::LLDP::FUNCS, # Obsolete Address Translation Table (ARP Cache) 'old_at_index' => 'atIfIndex', 'old_at_paddr' => 'atPhysAddress', 'old_at_netaddr' => 'atNetAddress', # IP-MIB IP Net to Media Table (ARP Cache) 'at_index' => 'ipNetToMediaIfIndex', 'at_paddr' => 'ipNetToMediaPhysAddress', 'at_netaddr' => 'ipNetToMediaNetAddress', # OSPF-MIB::ospfIfTable 'ospf_if_ip' => 'ospfIfIpAddress', 'ospf_if_area' => 'ospfIfAreaId', 'ospf_if_type' => 'ospfIfType', 'ospf_if_hello' => 'ospfIfHelloInterval', 'ospf_if_dead' => 'ospfIfRtrDeadInterval', 'ospf_if_admin' => 'ospfIfAdminStat', 'ospf_if_state' => 'ospfIfState', # OSPF-MIB::ospfNbrTable 'ospf_ip' => 'ospfHostIpAddress', 'ospf_peers' => 'ospfNbrIpAddr', 'ospf_peer_id' => 'ospfNbrRtrId', 'ospf_peer_state' => 'ospfNbrState', # BGP4-MIB::bgpPeerTable 'bgp_peers' => 'bgpPeerLocalAddr', 'bgp_peer_id' => 'bgpPeerIdentifier', 'bgp_peer_state' => 'bgpPeerState', 'bgp_peer_as' => 'bgpPeerRemoteAs', 'bgp_peer_addr' => 'bgpPeerRemoteAddr', 'bgp_peer_fsm_est_trans' => 'bgpPeerFsmEstablishedTransitions', 'bgp_peer_in_tot_msgs' => 'bgpPeerInTotalMessages', 'bgp_peer_in_upd_el_time' => 'bgpPeerInUpdateElapsedTime', 'bgp_peer_in_upd' => 'bgpPeerInUpdates', 'bgp_peer_out_tot_msgs' => 'bgpPeerOutTotalMessages', 'bgp_peer_out_upd' => 'bgpPeerOutUpdates', # IP-MIB Net to Physical Table (ARP Cache) 'n2p_paddr' => 'ipNetToPhysicalPhysAddress', 'n2p_lastupdate' => 'ipNetToPhysicalLastUpdated', 'n2p_ptype' => 'ipNetToPhysicalType', 'n2p_pstate' => 'ipNetToPhysicalState', 'n2p_pstatus' => 'ipNetToPhysicalRowStatus', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::MUNGE, %SNMP::Info::AdslLine::MUNGE, %SNMP::Info::Bridge::MUNGE, %SNMP::Info::EtherLike::MUNGE, %SNMP::Info::Entity::MUNGE, %SNMP::Info::PowerEthernet::MUNGE, %SNMP::Info::IPv6::MUNGE, %SNMP::Info::LLDP::MUNGE, 'old_at_paddr' => \&SNMP::Info::munge_mac, 'at_paddr' => \&SNMP::Info::munge_mac, 'n2p_paddr' => \&SNMP::Info::munge_mac, ); # Method OverRides sub root_ip { my $l3 = shift; my $router_ip = $l3->router_ip(); my $ospf_ip = $l3->ospf_ip(); # if the router ip exists and is a route advertised by the device we prefer # it over the others return $router_ip if (( defined $router_ip ) and ( $router_ip ne '0.0.0.0' ) and ( grep { $ospf_ip->{$_} eq $router_ip } ( keys %$ospf_ip ) ) and ( $l3->snmp_connect_ip($router_ip) ) ); # return the first one found here (should be only one) if ( defined $ospf_ip and scalar( keys %$ospf_ip ) ) { foreach my $key ( keys %$ospf_ip ) { my $ip = $ospf_ip->{$key}; next if $ip eq '0.0.0.0'; next unless $l3->snmp_connect_ip($ip); print " SNMP::Layer3::root_ip() using $ip\n" if $l3->debug(); return $ip; } } return; } sub serial { my $l3 = shift; my $serial1 = $l3->serial1(); my $e_parent = $l3->e_parent() || {}; my $e_class = $l3->e_class() || {}; foreach my $iid ( keys %$e_parent ) { my $parent = $e_parent->{$iid}; my $class = $e_class->{$iid} || ''; # Only consider serial numbers for entries without a parent, or if they are of type "chassis" if ( $parent eq '0' or $class eq 'chassis') { my $serial = $l3->e_serial($iid); if ( $serial && $serial->{$iid} ) { return $serial->{$iid}; } else { my $descr = $l3->e_descr($iid); if ( $descr and $descr =~ /serial#?:\s*([a-z0-9]+)/i ) { return $1; } } } } return $serial1 if ( defined $serial1 and $serial1 !~ /^\s*$/ ); return; } # $l3->model() - the sysObjectID returns an IID to an entry in # the CISCO-PRODUCT-MIB. Look it up and return it. sub model { my $l3 = shift; my $id = $l3->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::model() - Device does not support sysObjectID\n" if $l3->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^cisco//i; $model =~ s/^catalyst//; $model =~ s/^cat//; return $model; } sub i_name { my $l3 = shift; my $partial = shift; my $i_index = $l3->i_index($partial); my $i_alias = $l3->i_alias($partial); my $i_name2 = $l3->orig_i_name($partial); my %i_name; foreach my $iid ( keys %$i_name2 ) { my $name = $i_name2->{$iid}; my $alias = $i_alias->{$iid}; $i_name{$iid} = ( defined $alias and $alias !~ /^\s*$/ ) ? $alias : $name; } return \%i_name; } sub i_duplex { my $l3 = shift; my $partial = shift; my $el_index = $l3->el_index($partial); my $el_duplex = $l3->el_duplex($partial); my %i_index; foreach my $el_port ( keys %$el_duplex ) { my $iid = $el_index->{$el_port}; next unless defined $iid; my $duplex = $el_duplex->{$el_port}; next unless defined $duplex; $i_index{$iid} = 'half' if $duplex =~ /half/i; $i_index{$iid} = 'full' if $duplex =~ /full/i; $i_index{$iid} = 'auto' if $duplex =~ /auto/i; } return \%i_index; } # $l3->interfaces() - Map the Interfaces to their physical names sub interfaces { my $l3 = shift; my $partial = shift; my $interfaces = $l3->i_index($partial); my $i_descr = $l3->i_description($partial); # Check for duplicates in ifDescr, if so uniquely identify by adding # ifIndex to repeated values my %seen; foreach my $iid ( keys %$i_descr ) { my $port = $i_descr->{$iid}; next unless defined $port; if ( $seen{$port}++ ) { $interfaces->{$iid} = sprintf( "%s (%d)", $port, $iid ); } else { $interfaces->{$iid} = $port; } } return $interfaces; } sub vendor { my $l3 = shift; my $descr = $l3->description(); my $id = $l3->id(); # .1.3.6.1.4.1.9.1 is the CISCO-PRODUCTS-MIB # .1.3.6.1.4.1.9.9.368.4 is an old tree that Cisco CSSs were numbered from return 'cisco' if $id =~ /^\Q.1.3.6.1.4.1.9.1.\E\d+$/; return 'cisco' if $id =~ /^\Q.1.3.6.1.4.1.9.9.368.4.\E\d+/; return 'cisco' if ( $descr =~ /(cisco|\bios\b)/i ); return 'brocade' if ( $descr =~ /foundry/i ); return 'unknown'; } sub at_index { my $l3 = shift; my $partial = shift; return $l3->orig_at_index($partial) || $l3->old_at_index($partial); } sub at_paddr { my $l3 = shift; my $partial = shift; return $l3->orig_at_paddr($partial) || $l3->old_at_paddr($partial); } sub at_netaddr { my $l3 = shift; my $partial = shift; return $l3->orig_at_netaddr($partial) || $l3->old_at_netaddr($partial); } 1; __END__ =head1 NAME SNMP::Info::Layer3 - SNMP Interface to network devices serving Layer3 or Layers 2 & 3 =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $l3 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $l3->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; # Let's get some basic Port information my $interfaces = $l3->interfaces(); my $i_up = $l3->i_up(); my $i_speed = $l3->i_speed(); foreach my $iid (keys %$interfaces) { my $port = $interfaces->{$iid}; my $up = $i_up->{$iid}; my $speed = $i_speed->{$iid} print "Port $port is $up. Port runs at $speed.\n"; } =head1 DESCRIPTION This class is usually used as a superclass for more specific device classes listed under SNMP::Info::Layer3::* Please read all docs under SNMP::Info first. Provides generic methods for accessing SNMP data for Layer 3 network devices. Includes support for Layer2+3 devices. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $l3 = new SNMP::Info::Layer3(...); =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Bridge (For L2/L3 devices) =item SNMP::Info::EtherLike =item SNMP::Info::Entity =item SNMP::Info::PowerEthernet =item SNMP::Info::IPv6 =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item F =item F =item F =back =head2 Inherited MIBs See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $l3->mac() Returns root port mac address (C) =item $l3->router_ip() (C) =item $l3->bgp_id() (C) Returns the BGP identifier of the local system =item $l3->bgp_local_as() Returns the local autonomous system number (C) =back =head2 Overrides =over =item $l3->model() Tries to reference $l3->id() to one of the product MIBs listed above Removes 'cisco' from cisco devices for readability. =item $l3->serial() Tries to cull a serial number from F, description, and F... MIB. =item $l3->vendor() Tries to cull a Vendor name from C =item $l3->root_ip() Returns the primary IP used to communicate with the device. Returns the first found: OSPF Router ID (C) or any OSPF Host IP Address (C). =back =head2 Globals imported from SNMP::Info See L for details. =head2 Global Methods imported from SNMP::Info::Bridge See L for details. =head2 Global Methods imported from SNMP::Info::EtherLike See L for details. =head2 Global Methods imported from SNMP::Info::Entity See L for details. =head2 Global Methods imported from SNMP::Info:PowerEthernet See L for details. =head2 Global Methods imported from SNMP::Info::IPv6 See L for details. =head2 Global Methods imported from SNMP::Info::LLDP See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $l3->interfaces() Returns the map between SNMP Interface Identifier (iid) and physical port name. Only returns those iids that have a description listed in $l3->i_description() =item $l3->i_name() Returns reference to hash of iid to human set name. Defaults to C, but checks for an C =item $l3->i_duplex() Returns reference to hash of iid to current link duplex setting. Maps $l3->el_index() to $l3->el_duplex, then culls out full,half, or auto and sets the map to that value. See L for the el_index() and el_duplex() methods. =back =head2 F Arp Cache Table (C) =over =item $l3->at_index() Returns reference to hash. Maps ARP table entries to Interface IIDs (C) If the device doesn't support C, this will try the deprecated C. =item $l3->at_paddr() Returns reference to hash. Maps ARP table entries to MAC addresses. (C) If the device doesn't support C, this will try the deprecated C. =item $l3->at_netaddr() Returns reference to hash. Maps ARP table entries to IP addresses. (C) If the device doesn't support C, this will try the deprecated C. =back =head2 ARP Cache Entries The C has been deprecated since 1991. You should never need to use these methods. See C above. =over =item $l3->old_at_index() Returns reference to map of IID to Arp Cache Entry (C) =item $l3->old_at_paddr() Returns reference to hash of Arp Cache Entries to MAC address (C) =item $l3->old_at_netaddr() Returns reference to hash of Arp Cache Entries to IP Address (C) =back =head2 BGP Peer Table (C) =over =item $l3->bgp_peers() Returns reference to hash of BGP peer to local IP address (C) =item $l3->bgp_peer_id() Returns reference to hash of BGP peer to BGP peer identifier (C) =item $l3->bgp_peer_state() Returns reference to hash of BGP peer to BGP peer state (C) =item $l3->bgp_peer_as() Returns reference to hash of BGP peer to BGP peer autonomous system number (C) =item $l3->bgp_peer_addr() Returns reference to hash of BGP peer to BGP peer IP address (C) =item $l3->bgp_peer_fsm_est_trans() Returns reference to hash of BGP peer to the total number of times the BGP FSM transitioned into the established state (C) =item $l3->bgp_peer_in_tot_msgs() Returns reference to hash of BGP peer to the total number of messages received from the remote peer on this connection (C) =item $l3->bgp_peer_in_upd_el_time() Returns reference to hash of BGP peer to the elapsed time in seconds since the last BGP UPDATE message was received from the peer. (C) =item $l3->bgp_peer_in_upd() Returns reference to hash of BGP peer to the number of BGP UPDATE messages received on this connection (C) =item $l3->bgp_peer_out_tot_msgs() Returns reference to hash of BGP peer to the total number of messages transmitted to the remote peer on this connection (C) =item $l3->bgp_peer_out_upd() Returns reference to hash of BGP peer to the number of BGP UPDATE messages transmitted on this connection (C) =back =head2 OSPF Interface Table (C) =over =item $l3->ospf_if_ip() Returns reference to hash of OSPF interface IP addresses (C) =item $l3->ospf_if_area() Returns reference to hash of the OSPF area to which the interfaces connect (C) =item $l3->ospf_if_type() Returns reference to hash of the OSPF interfaces' type (C) =item $l3->ospf_if_hello() Returns reference to hash of the OSPF interfaces' hello interval (C) =item $l3->ospf_if_dead() Returns reference to hash of the OSPF interfaces' dead interval (C) =item $l3->ospf_if_admin() Returns reference to hash of the OSPF interfaces' administrative status (C) =item $l3->ospf_if_state() Returns reference to hash of the OSPF interfaces' state (C) =back =head2 OSPF Neighbor Table (C) =over =item $l3->ospf_peers() Returns reference to hash of IP addresses the neighbor is using in its IP Source Addresses (C) =item $l3->ospf_peer_id() Returns reference to hash of neighbor Router IDs (C) =item $l3->ospf_peer_state() Returns reference to hash of state of the relationship with the neighbor routers (C) =back =head2 Table Methods imported from SNMP::Info See L for details. =head2 Table Methods imported from SNMP::Info::Bridge See L for details. =head2 Table Methods imported from SNMP::Info::EtherLike See L for details. =head2 Table Methods imported from SNMP::Info::Entity See L for details. =head2 Table Methods imported from SNMP::Info::PowerEthernet See L for details. =head2 Table Methods imported from SNMP::Info::IPv6 See L for details. =head2 Table Methods imported from SNMP::Info::LLDP See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer7.pm000444000765000024 1275013215550564 17011 0ustar00oliverstaff000000000000# SNMP::Info::Layer7 - SNMP Interface to Layer7 Devices # # Copyright (c) 2011 Jeroen van Ingen # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer7; use strict; use Exporter; use SNMP::Info; @SNMP::Info::Layer7::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::Layer7::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, ); %GLOBALS = ( %SNMP::Info::GLOBALS, ); %FUNCS = ( %SNMP::Info::FUNCS, ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::MUNGE, ); # $l7->model() - Looks at sysObjectID which gives the oid of the system # name, contained in a proprietary MIB. sub model { my $l7 = shift; my $id = $l7->id(); my $model = &SNMP::translateObj($id); # Neoteris (Juniper IVE) $model =~ s/^ive//i; return $model; } sub vendor { my $l7 = shift; my $id = $l7->id(); my $vendor = 'unknown'; if ( defined($id) && $id =~ /^(\.1\.3\.6\.1\.4\.1\.\d+)/ ) { my $enterprise = &SNMP::translateObj($1); $vendor = $enterprise if defined $enterprise; } return $vendor; } # By Default we'll use the description field sub interfaces { my $l7 = shift; my $partial = shift; my $interfaces = $l7->i_index($partial) || {}; my $i_descr = $l7->i_description($partial) || {}; # Replace the Index with the ifDescr field. foreach my $iid ( keys %$i_descr ) { my $port = $i_descr->{$iid}; next unless defined $port; $interfaces->{$iid} = $port; } return $interfaces; } 1; __END__ =head1 NAME SNMP::Info::Layer7 - SNMP Interface to network devices serving Layer7 only. =head1 AUTHOR Jeroen van Ingen =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $l7 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $l7->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; # Let's get some basic Port information my $interfaces = $l7->interfaces(); my $i_up = $l7->i_up(); my $i_speed = $l7->i_speed(); foreach my $iid (keys %$interfaces) { my $port = $interfaces->{$iid}; my $up = $i_up->{$iid}; my $speed = $i_speed->{$iid} print "Port $port is $up. Port runs at $speed.\n"; } =head1 DESCRIPTION This class is usually used as a superclass for more specific device classes listed under SNMP::Info::Layer7::* Please read all docs under SNMP::Info first. Provides abstraction to the configuration information obtainable from a Layer7 device through SNMP. Information is stored in a number of MIBs. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $l7 = new SNMP::Info::Layer7(...); =head2 Inherited Classes =over =item SNMP::Info =back =head2 Required MIBs =over =item None =back MIBs required for L See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =back =head2 Overrides =over =item $l7->model() Cross references $l7->id() with product IDs. =item $l7->vendor() Tries to discover the vendor by looking up the enterprise number in C. =back =head2 Global Methods imported from SNMP::Info See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $l7->interfaces() Returns reference to the map between IID and physical Port. =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/MAU.pm000444000765000024 4414013215550564 16266 0ustar00oliverstaff000000000000# SNMP::Info::MAU - Media Access Unit - RFC 2668 # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::MAU; use strict; use Exporter; use SNMP::Info; @SNMP::Info::MAU::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::MAU::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'MAU-MIB' => 'mauMod', 'IANA-MAU-MIB' => 'dot3MauType' ); %GLOBALS = (); %FUNCS = ( # Interface MAU Table 'mau_index' => 'ifMauIfIndex', 'mau_link' => 'ifMauType', 'mau_status' => 'ifMauStatus', 'mau_up' => 'ifMauMediaAvailable', 'mau_type' => 'ifMauTypeList', 'mau_type_admin' => 'ifMauDefaultType', # Interface Auto-Negotiation Table 'mau_auto' => 'ifMauAutoNegSupported', 'mau_autostat' => 'ifMauAutoNegAdminStatus', 'mau_autosent' => 'ifMauAutoNegCapAdvertised', 'mau_autorec' => 'ifMauAutoNegCapReceived', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::MUNGE, # Add ones for our class 'mau_type' => \&munge_int2bin, 'mau_autosent' => \&munge_int2bin, 'mau_autorec' => \&munge_int2bin, ); sub munge_int2bin { my $int = shift; return unless defined $int; return unpack( "B32", pack( "N", $int ) ); } sub _isfullduplex { my $mau = shift; my $mautype = shift; my @full_types = qw/11 13 16 18 20/; foreach my $type (@full_types) { return 1 if ( substr( $mautype, 32 - $type, 1 ) eq '1' ); } return 0; } sub _ishalfduplex { my $mau = shift; my $mautype = shift; my @half_types = qw/10 12 15 17 19/; foreach my $type (@half_types) { return 1 if ( substr( $mautype, 32 - $type, 1 ) eq '1' ); } return 0; } my %_mau_i_speed_map = ( '10' => '10 Mbps', '100' => '100 Mbps', '1000' => '1.0 Gbps', '10Gig' => '10 Gbps', ); sub mau_i_speed_admin { my $mau = shift; my $mau_index = $mau->mau_index(); my $mau_type_admin = $mau->mau_type_admin(); my %i_speed_admin; foreach my $mau_port ( keys %$mau_type_admin ) { my $iid = $mau_index->{$mau_port}; next unless defined $iid; my $type_adminoid = $mau_type_admin->{$mau_port}; my $type_admin = &SNMP::translateObj($type_adminoid); next unless defined $type_admin; if ( $type_adminoid eq '.0.0' ) { $i_speed_admin{$iid} = 'auto'; } elsif ($type_admin =~ /^dot3MauType(.*)Base/ && $_mau_i_speed_map{$1} ) { $i_speed_admin{$iid} = $_mau_i_speed_map{$1}; } } return \%i_speed_admin; } sub mau_i_duplex { my $mau = shift; my $mau_index = $mau->mau_index(); my $mau_link = $mau->mau_link(); my %i_duplex; foreach my $mau_port ( keys %$mau_link ) { my $iid = $mau_index->{$mau_port}; next unless defined $iid; my $linkoid = $mau_link->{$mau_port}; my $link = &SNMP::translateObj($linkoid); next unless defined $link; my $duplex = undef; if ( $link =~ /fd$/i ) { $duplex = 'full'; } elsif ( $link =~ /hd$/i ) { $duplex = 'half'; } $i_duplex{$iid} = $duplex if defined $duplex; } return \%i_duplex; } sub mau_i_duplex_admin { my $mau = shift; my $partial = shift; my $mau_index = $mau->mau_index() || {}; if ($partial) { my %rev_mau_index = reverse %$mau_index; $partial = $rev_mau_index{$partial}; } my $mau_autostat = $mau->mau_autostat($partial) || {}; my $mau_type_admin = $mau->mau_type_admin($partial) || {}; # Older HP4000's don't implement ifMauDefaultType, but we can # figure out from ifMauAutoNegCapAdvertised what we'd like. if ( !defined($mau_type_admin) ) { if ( defined($mau_index) ) { return mau_i_duplex_admin_old( $mau, $mau_index, $mau_autostat ); } else { return; } } my %i_duplex_admin; foreach my $mau_port ( keys %$mau_type_admin ) { my $iid = $mau_index->{$mau_port}; next unless defined $iid; my $autostat = $mau_autostat->{$mau_port}; if ( defined $autostat and $autostat =~ /enabled/i ) { $i_duplex_admin{$iid} = 'auto'; next; } my $type_adminoid = $mau_type_admin->{$mau_port}; my $type_admin = &SNMP::translateObj($type_adminoid); next unless defined $type_admin; my $duplex = undef; if ( $type_admin =~ /fd$/i ) { $duplex = 'full'; } elsif ( $type_admin =~ /hd$/i ) { $duplex = 'half'; } elsif ( $type_admin eq 'zeroDotZero' ) { $duplex = 'auto'; } $i_duplex_admin{$iid} = $duplex if defined $duplex; } return \%i_duplex_admin; } sub mau_i_duplex_admin_old { my $mau = shift; my $mau_index = shift; my $mau_autostat = shift; my $interfaces = $mau->interfaces(); my $mau_autosent = $mau->mau_autosent(); my %mau_reverse = reverse %$mau_index; my %i_duplex_admin; foreach my $iid ( keys %$interfaces ) { my $mau_idx = $mau_reverse{$iid}; next unless defined $mau_idx; my $autostat = $mau_autostat->{$mau_idx}; # HP25xx has this value if ( defined $autostat and $autostat =~ /enabled/i ) { $i_duplex_admin{$iid} = 'auto'; next; } my $type = $mau_autosent->{$mau_idx}; next unless defined $type; if ( $type == 0 ) { $i_duplex_admin{$iid} = 'none'; next; } my $full = $mau->_isfullduplex($type); my $half = $mau->_ishalfduplex($type); if ( $full && !$half ) { $i_duplex_admin{$iid} = 'full'; } elsif ($half) { $i_duplex_admin{$iid} = 'half'; } } return \%i_duplex_admin; } sub mau_set_i_speed_admin { my $mau = shift; my $speed = shift; my $iid = shift; my $rv; $speed = lc($speed); if ( !( $speed =~ /(10|100|1000|auto)/io and $iid =~ /\d+/o ) ) { return; } # map a speed value to an integer the switch understands based on duplex my %speeds; # 10 = dot3MauType10BaseTHD, 15 = dot3MauType100BaseTXHD # 29 = dot3MauType1000BaseTHD from IANA-MAU-MIB %{ $speeds{'HD'} } = qw/10 10 100 15 1000 29/; # half duplex settings # 11 = dot3MauType10BaseTFD, 16 = dot3MauType100BaseTXFD # 30 = dot3MauType1000BaseTFD from IANA-MAU-MIB %{ $speeds{'FD'} } = qw/10 11 100 16 1000 30/; # full duplex settings my $myhash = $mau->mau_autostat; my $key = $iid . '.1'; my $i_autoneg = $myhash->{$key}; my $myduplex; my $i_mau_def_type = &SNMP::translateObj( $mau->mau_type_admin($iid)->{ $iid . '.1' } ); if ( $i_mau_def_type =~ /^dot3MauType.*Base.*(..)$/ && ( $1 eq "HD" or $1 eq "FD" ) ) { $myduplex = $1; } else { # this is not a valid speed known, assuming auto $myduplex = "auto"; } if ( $speed eq "auto" && $i_autoneg eq "enabled" ) { return (1); } elsif ( $speed eq "auto" ) { $rv = $mau->set_mau_autostat( 'enabled', $iid . '.1' ); return ($rv); } else { if ( $i_autoneg eq "enabled" ) { $mau->set_mau_autostat( 'disabled', $iid . '.1' ); } $rv = $mau->set_mau_type_admin( '.1.3.6.1.2.1.26.4.' . $speeds{$myduplex}{$speed}, $iid . '.1' ); return ($rv); } } sub mau_set_i_duplex_admin { my $mau = shift; my $duplex = shift; my $iid = shift; my $rv; $duplex = lc($duplex); if ( !( $duplex =~ /(full|half|auto)/i and $iid =~ /\d+/ ) ) { return; } # map a textual duplex setting to an integer value the switch will understand my %duplexes; %{ $duplexes{'10'} } = qw/full 11 half 10/; %{ $duplexes{'100'} } = qw/full 16 half 15/; %{ $duplexes{'1000'} } = qw/full 30 half 29/; # current port values: my $myhash = $mau->mau_autostat; my $key = $iid . '.1'; my $i_autoneg = $myhash->{$key}; my $i_speed = &SNMP::translateObj( $mau->mau_type_admin($iid)->{ $iid . '.1' } ); if ( $i_speed =~ /^dot3MauType(.*)Base/ && $_mau_i_speed_map{$1} ) { $i_speed = $1; } else { # this is not a valid speed setting, assuming auto $duplex = "auto"; } if ( $duplex eq "auto" && $i_autoneg eq "enabled" ) { return (1); } elsif ( $duplex eq "auto" ) { $rv = $mau->set_mau_autostat( 'enabled', $iid . '.1' ); return ($rv); } else { # Can't always do it here, if not... if ( $i_autoneg eq "enabled" && defined( $duplexes{$i_speed}{$duplex} ) ) { $mau->set_mau_autostat( 'disabled', $iid . '.1' ); } $rv = $mau->set_mau_type_admin( '.1.3.6.1.2.1.26.4.' . $duplexes{$i_speed}{$duplex}, $iid . '.1' ); return ($rv); } } # # mau_set_i_speed_duplex_admin() accepts the following values for speed/duplex # # auto/auto (special case) # 10/half # 10/full # 100/half # 100/full # 1000/half # 1000/full sub mau_set_i_speed_duplex_admin { my $mau = shift; my $speed = shift; my $duplex = shift; my $iid = shift; my $rv; $speed = lc($speed); $duplex = lc($duplex); if ( ( $speed !~ m/auto|10|100|1000/io ) or ( $duplex !~ m/full|half|auto/io ) or ( $iid !~ /\d+/ ) ) { return ("bad arguments"); } # map input speed and duplex paramters to 'mau_type_admin' settings # From IANA-MAU-MIB # 11 = dot3MauType10BaseTFD, 10 = dot3MauType10BaseTHD, # 16 = dot3MauType100BaseTXFD, 15 = dot3MauType100BaseTXHD # 30 = dot3MauType1000BaseTFD, 29 = dot3MauType1000BaseTHD my %params; %{ $params{'10'} } = qw/full 11 half 10/; %{ $params{'100'} } = qw/full 16 half 15/; %{ $params{'1000'} } = qw/full 30 half 29/; # if given "auto/auto", set 'mau_autostat' to "enable" and exit if ( ( $speed eq "auto" ) or ( $duplex eq "auto" ) ) { $rv = $mau->set_mau_autostat( 'enabled', $iid . '.1' ); return ($rv); } $rv = $mau->set_mau_type_admin( '.1.3.6.1.2.1.26.4.' . $params{$speed}{$duplex}, $iid . '.1' ); $rv = $mau->set_mau_autostat( 'disabled', $iid . '.1' ); return ($rv); } 1; __END__ =head1 NAME SNMP::Info::MAU - SNMP Interface to Medium Access Unit (MAU) MIB (RFC 2668) via SNMP =head1 AUTHOR Max Baker =head1 SYNOPSIS my $mau = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'hpswitch', Community => 'public', Version => 2 ); my $class = $mau->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION SNMP::Info::MAU is a subclass of SNMP::Info that supplies access to the F (RFC 2668). This MIB is sometimes implemented on Layer 2 network devices like HP Switches. MAU = Media Access Unit. The MAU table contains link and duplex info for the port itself and the device connected to that port. Normally you use or create a subclass of SNMP::Info that inherits this one. Do not use directly. For debugging purposes call the class directly as you would SNMP::Info my $mau = new SNMP::Info::MAU(...); =head2 Inherited Classes None. =head2 Required MIBs =over =item F =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item None =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $mau->mau_i_duplex() Parses mau_index and mau_link to return the duplex information for interfaces. =item $mau->mau_i_duplex_admin() Parses C,C,C in order to find the admin duplex setting for all the interfaces. Returns either (auto,full,half). =item $mau->mau_i_duplex_admin_old() Called by mau_i_duplex_admin() if C is empty. Parses C,C,C in order to find the admin duplex setting for all the interfaces. Returns either (auto,none,full,half). =item $mau->mau_i_speed_admin() Returns admin speed setting for all the interfaces. =back =head2 MAU Interface Table Methods =over =item $mau->mau_index() - Returns a list of interfaces and their index in the MAU IF Table. (C) =item $mau->mau_link() - Returns the type of Media Access used. This is essentially the type of link in use. eg. dot3MauType100BaseTXFD - 100BaseT at Full Duplex (C) =item $mau->mau_status() - Returns the admin link condition as 1 - other 2 - unknown 3 - operational 4 - standby 5 - shutdown 6 - reset Use 5 and !5 to see if the link is up or down on the admin side. (C) =item $mau->mau_up() - Returns the current link condition (C) =item $mau->mau_type() - Returns a 32bit string reporting the capabilities of the port from a MAU POV. Directly from F : Bit Capability 0 other or unknown 1 AUI 2 10BASE-5 3 FOIRL 4 10BASE-2 5 10BASE-T duplex mode unknown 6 10BASE-FP 7 10BASE-FB 8 10BASE-FL duplex mode unknown 9 10BROAD36 10 10BASE-T half duplex mode 11 10BASE-T full duplex mode 12 10BASE-FL half duplex mode 13 10BASE-FL full duplex mode 14 100BASE-T4 15 100BASE-TX half duplex mode 16 100BASE-TX full duplex mode 17 100BASE-FX half duplex mode 18 100BASE-FX full duplex mode 19 100BASE-T2 half duplex mode 20 100BASE-T2 full duplex mode (C) =item $mau->mau_type_admin() (C) =item $mau->mau_auto() - Indicates whether or not auto-negotiation is supported. (C) =item $mau->mau_autostat() - Returns status of auto-negotiation mode for ports. (C) =item $mau->mau_autosent() - Returns a 32 bit bit-string representing the capabilities we are broadcasting on that port Uses the same decoder as $mau->mau_type(). (C) =item $mau->mau_autorec() - Returns a 32 bit bit-string representing the capabilities of the device on the other end. Uses the same decoder as $mau->mau_type(). (C) =back =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item $mau->mau_set_i_speed_admin(speed, ifIndex) Sets port speed, must be supplied with speed and port C. Note that this method has some limitations since there is no way to reliably set the port speed independently of the port duplex setting on certain devices, notably the Cisco Cat4k series. Speed choices are '10', '100', '1000', 'auto'. =item $mau->mau_set_i_duplex_admin(duplex, ifIndex) Sets port duplex, must be supplied with duplex and port C. Note that this method has some limitations since there is no way to reliably set the port duplex independently of the port speed setting on certain devices, notably the Cisco Cat4k series. Duplex choices are 'auto', 'half', 'full'. =item $mau->mau_set_i_speed_duplex_admin(speed, duplex, ifIndex) Sets port speed and duplex settings, must be supplied with speed, duplex and port C. Accepts the following values for speed and duplex: Speed/Duplex ------------ auto/auto (this is a special case) 10/half 10/full 100/half 100/full 1000/half 1000/full =back =head1 Utility Functions =over =item munge_int2bin() - Unpacks an integer into a 32bit bit string. =item $mau->_isfullduplex(bitstring) Boolean. Checks to see if any of the full_duplex types from mau_type() are high. Currently bits 11,13,16,18,20. =item $mau->_ishalfduplex(bitstring) Boolean. Checks to see if any of the half_duplex types from mau_type() are high. Currently bits 10,12,15,17,19. =back =cut SNMP-Info-3.39/lib/SNMP/Info/MRO.pm000444000765000024 2437613215550564 16312 0ustar00oliverstaff000000000000package SNMP::Info::MRO; use warnings; use strict; use vars qw/$VERSION/; $VERSION = '3.39'; use PPI; use Class::ISA; use Module::Info; use Module::Load (); # use Data::Printer; sub _walk_global_data { my $self = shift; my $class = (ref $self ? ref $self : $self); my $ppi = PPI::Document->new( file($class) ); my $name = shift or die "name (e.g. GLOBALS) required"; my $results = shift || {}; my $subref = \&_walk_global_data; # get the hash declaration my $declaration = $ppi->find_first(sub { my ($doc, $tok) = @_; return ($tok->isa('PPI::Token::Symbol') and $tok->symbol eq "\%$name"); }); # get the hash content my $content = $declaration->snext_sibling->snext_sibling; # get relevant tokens in the hash content my @tokens = $content->find(sub { my ($doc, $tok) = @_; return ($tok->isa('PPI::Token::Symbol') or $tok->isa('PPI::Token::Quote')); }); return $results unless scalar @tokens and ref $tokens[0] eq ref []; @tokens = @{ $tokens[0] }; # walk tokens and build final result while (my $tok = splice(@tokens, 0, 1)) { if ($tok->isa('PPI::Token::Quote')) { my $token = $tok->string; my $leaf = splice(@tokens, 0, 1); my $extract = (($leaf =~ m/^&/) ? 'symbol' : 'string'); unshift @{ $results->{$token} }, [ $class => $leaf->$extract ] # we can sometimes see the same package twice unless scalar grep { $_ eq $class } map { $_->[0] } @{ $results->{$token} }; } elsif ($tok->isa('PPI::Token::Symbol')) { # recurse to get the results of the mentioned package (my $otherpkg = $tok->symbol) =~ s/^\%(.+)::$name$/$1/; $results = $subref->($otherpkg, $name, $results); } } return $results; } sub _print_global_data { my $results = _walk_global_data(@_); foreach my $key (sort keys %$results) { print $key, "\n"; my @defs = @{ $results->{$key} }; my $first = 0; while (my $classdef = splice(@defs, 0, 1)) { my $class = $classdef->[0]; my $meth = $classdef->[1]; if ($first) { printf " %s ( %s )\n", $meth, $class; } else { printf " `-- %s ( %s )\n", $meth, $class; $first = 1; } } } } =head1 NAME SNMP::Info::MRO - Method resolution introspection for SNMP::Info =head1 SYNOPSIS use SNMP::Info::MRO; use Data::Printer; p SNMP::Info::MRO::all_methods('SNMP::Info::Layer3::Juniper'); =head1 DESCRIPTION This is a set of helpers to show where a given method in SNMP::Info has been implemented, and which implementation is being used at runtime. The following distributions are I to run this code: =over 4 =item * PPI =item * Class::ISA =item * Module::Info =item * Module::Load =back =head1 FUNCTIONS None of the functions are exported. For all helper functions, you can pass either the name of a Perl module, or an object instance of SNMP::Info. =over 4 =item all_methods( $module ) Returns the location of methods defined in C<$module> and all its ancestor classes (superclasses), either as Perl subroutines or via C<%GLOBALS> or C<%FUNCS> configuration. The data structure looks like: { method_name => { globals => [ [ Package::Name => 'mib_leaf.0' ], [ Other::Package::Name => '1.3.6.1.4.1.9.2.1.58.0' ], ], }, other_method_name => [ subs => [ 'Package::Name', ], funcs => [ [ Package::Name => 'mib_leaf_name' ], ], ], } It should be noted that the order of method resolution in SNMP::Info is to first look for a defined subroutine (this is done by Perl), then the AUTOLOAD sequence will search for a definition in C<%GLOBALS> followed by C<%FUNCS>. The defining class or module at runtime is always the first entry in the list, if it exists: $data->{method_name}->{subs}->[0] if exists $data->{method_name}->{subs}; =cut sub all_methods { my $self = shift; my $class = (ref $self ? ref $self : $self); my $results = subroutines( $class ); $results = { map { $_ => { subs => $results->{$_} } } keys %$results }; my $globals = globals( $class ); foreach my $key (keys %$globals) { $results->{$key}->{globals} = $globals->{$key}; } my $funcs = funcs( $class ); foreach my $key (keys %$funcs) { $results->{$key}->{funcs} = $funcs->{$key}; } #foreach my $key (keys %$results) { # $results->{$key}->{subs} ||= []; # $results->{$key}->{globals} ||= []; # $results->{$key}->{funcs} ||= []; #} return $results; } =item subroutines( $module ) Returns the set of subroutines defined in C<$module> and all its ancestor classes (superclasses). The data structure looks like: { method_name => [ 'Package::Name', 'Other::Package::Name', ], other_method_name => [ 'Package::Name', ], } Should a subroutine have been defined more than once, the defining classes are listed in reverse order, such that the definition used at runtime is always: $data->{method_name}->[0]; =cut sub subroutines { my $self = shift; my $class = (ref $self ? ref $self : $self); my $results = {}; my @super = superclasses($class); foreach my $parent (reverse @super) { my %sh = Module::Info->new_from_module( $parent )->subroutines; my @subs = grep { $_ !~ m/^_/ } map { $_ =~ s/^.+:://; $_ } keys %sh; foreach my $sub (@subs) { unshift @{ $results->{$sub} }, $parent; } } return $results; } =item globals( $module || $object ) Returns a data structure showing how L will resolve MIB Leaf Nodes configured through the C<%GLOBALS> hashes in C<$module>. The data structure looks like: { method_name => [ [ Package::Name => 'mib_leaf_name' ], [ Other::Package::Name => '1.3.6.1.4.1.9.2.1.58.0' ], ], other_method_name => [ [ Package::Name => 'mib_leaf.0' ], ], } Where a method has been defined in different packages, then they are listed in reverse order, such that the mapping used by SNMP::Info is always: $data->{method_name}->[0]; =cut sub globals { _walk_global_data(shift, 'GLOBALS') } =item funcs( $module || $object ) Returns a data structure showing how L will resolve MIB Tables configured through the C<%FUNCS> hashes in C<$module>. See L for further detail. =cut sub funcs { _walk_global_data(shift, 'FUNCS') } =item munge( $module || $object ) Returns a data structure showing the subroutines used for munging returned values for any method defined in C<%FUNCS> or C<%GLOBALS>. The data structure looks like: { method_name => [ [ Package::Name => '&subroutine' ], [ Other::Package::Name => '&Other::Package::subroutine' ], ], other_method_name => [ [ Package::Name => '&subroutine' ], ], } Where a mapping has been defined in different packages, then they are listed in reverse order, such that the munge subroutine used by SNMP::Info is always: $data->{method_name}->[0]; =cut sub munge { _walk_global_data(shift, 'MUNGE') } =item file( $module ) Returns the filename from which Perl will load the given module. =cut sub file { my $self = shift; my $class = (ref $self ? ref $self : $self); return Module::Info->new_from_module( $class )->file; } =item superclasses( $class || $object ) Returns the list (in order) of the names of classes Perl will search to find methods for this SNMP::Info class or object instance. Note this B the L distribution to be installed. =cut sub superclasses { my $self = shift; my $class = (ref $self ? ref $self : $self); Module::Load::load( $class ); return Class::ISA::self_and_super_path( $class ); } =item print_globals( $module || $object ) Pretty print the output of C. =cut sub print_globals { _print_global_data(shift, 'GLOBALS') } =item print_funcs( $module || $object ) Pretty print the output of C. =cut sub print_funcs { _print_global_data(shift, 'FUNCS') } =item print_munge( $module || $object ) Pretty print the output of C. =cut sub print_munge { _print_global_data(shift, 'MUNGE') } =item print_superclasses( $class || $object ) Pretty print the output of C. =cut sub print_superclasses { print join ("\n", superclasses(@_)), "\n"; } =back =head1 AUTHOR Oliver Gorwits =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2014 by The SNMP::Info Project. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. =cut 1; SNMP-Info-3.39/lib/SNMP/Info/NortelStack.pm000444000765000024 5636613215550564 20112 0ustar00oliverstaff000000000000# SNMP::Info::NortelStack # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::NortelStack; use strict; use Exporter; use SNMP::Info; @SNMP::Info::NortelStack::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::NortelStack::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( # S5-ROOT-MIB and S5-TCS-MIB required by the MIBs below 'S5-AGENT-MIB' => 's5AgMyGrpIndx', 'S5-CHASSIS-MIB' => 's5ChasType', 'S5-REG-MIB' => 's5ChasTypeVal', ); %GLOBALS = ( # From S5-AGENT-MIB 'ns_ag_ver' => 's5AgInfoVer', 'ns_op_mode' => 's5AgSysCurrentOperationalMode', 'ns_auto_pvid' => 's5AgSysAutoPvid', 'tftp_host' => 's5AgSysTftpServerAddress', 'tftp_file' => 's5AgSysBinaryConfigFilename', 'tftp_action' => 's5AgInfoFileAction', 'tftp_result' => 's5AgInfoFileStatus', 'vlan' => 's5AgSysManagementVlanId', # From S5-CHASSIS-MIB 'ns_serial' => 's5ChasSerNum', 'ns_ch_type' => 's5ChasType', 'ns_cfg_chg' => 's5ChasGblConfChngs', 'ns_cfg_time' => 's5ChasGblConfLstChng', ); %FUNCS = ( # From S5-AGENT-MIB::s5AgMyIfTable 'i_cfg_file' => 's5AgMyIfCfgFname', 'i_cfg_host' => 's5AgMyIfLdSvrAddr', # From S5-CHASSIS-MIB::s5ChasGrpTable 'ns_grp_type' => 's5ChasGrpType', # From S5-CHASSIS-MIB::s5ChasComTable 'ns_com_grp_idx' => 's5ChasComGrpIndx', 'ns_com_idx' => 's5ChasComIndx', 'ns_com_sub_idx' => 's5ChasComSubIndx', 'ns_com_type' => 's5ChasComType', 'ns_com_descr' => 's5ChasComDescr', 'ns_com_ver' => 's5ChasComVer', 'ns_com_serial' => 's5ChasComSerNum', # From S5-CHASSIS-MIB::s5ChasStoreTable 'ns_store_grp_idx' => 's5ChasStoreGrpIndx', 'ns_store_com_idx' => 's5ChasStoreComIndx', 'ns_store_sub_idx' => 's5ChasStoreSubIndx', 'ns_store_idx' => 's5ChasStoreIndx', 'ns_store_type' => 's5ChasStoreType', 'ns_store_size' => 's5ChasStoreCurSize', 'ns_store_ver' => 's5ChasStoreCntntVer', ); %MUNGE = ( 'ns_ch_type' => \&SNMP::Info::munge_e_type, 'ns_grp_type' => \&munge_ns_grp_type, 'ns_com_type' => \&SNMP::Info::munge_e_type, 'ns_store_type' => \&SNMP::Info::munge_e_type, ); sub os_ver { my $stack = shift; my $ver = $stack->ns_ag_ver(); return unless defined $ver; if ( $ver =~ m/(\d+\.\d+\.\d+\.\d+)/ ) { return $1; } if ( $ver =~ m/V(\d+\.\d+\.\d+)/i ) { return $1; } return; } sub os_bin { my $stack = shift; my $ver = $stack->ns_ag_ver(); return unless defined $ver; if ( $ver =~ m/(\d+\.\d+\.\d+\.\d+)/i ) { return $1; } if ( $ver =~ m/V(\d+\.\d+.\d+)/i ) { return $1; } return; } # Need to override here since overridden in Layer2 and Layer3 classes sub serial { my $stack = shift; my $ver = $stack->ns_serial(); return $ver unless !defined $ver; return; } # Pseudo ENTITY-MIB methods for older switches with don't support ENTITY-MIB # This class supports both stackable and chassis based switches, identify if # we have a stackable so that we return appropriate entPhysicalClass sub _ns_e_is_virtual { my $stack = shift; # We really only need one value, but we want this cached since most # methods call it at least via ns_e_index() my $v_test = $stack->s5ChasComRelPos() || {}; return $v_test->{'8.1.0'}; } # Identify is the stackable is actually a stack vs. single switch sub _ns_e_is_stack { my $stack = shift; my $s_test = $stack->ns_e_class() || {}; foreach my $iid ( keys %$s_test ) { my $class = $s_test->{$iid}; next unless defined $class; return 1 if ( $class eq 'stack' ); } return 0; } sub ns_e_index { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_com_grp_idx($partial) || {}; my $is_virtual = $stack->_ns_e_is_virtual(); my %ns_e_index; foreach my $iid ( keys %$ns_e_idx ) { # Skip backplane, power, sensor, fan, clock - these aren't in the # newer devices ENTITY-MIB we're emulating next if ( $iid =~ /^[24567]/ ); next if ( ($is_virtual) and ( $iid =~ /^8/ or $iid eq '1.0.0' ) ); # Format into consistent integer format so that numeric sorting works my $index = join( '', map { sprintf "%02d", $_ } split /\./, $iid ); $ns_e_index{$iid} = $index; } return \%ns_e_index; } sub ns_e_class { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $classes = $stack->ns_grp_type(); my $ns_grp_enc = $stack->s5ChasGrpEncodeFactor($partial) || {}; my $is_virtual = $stack->_ns_e_is_virtual(); my %ns_e_class; foreach my $iid ( keys %$ns_e_idx ) { my ( $grp, $idx, $sub ) = split( /\./, $iid ); next unless defined $grp; my $class = $classes->{$grp}; next unless defined $class; my $enc = $ns_grp_enc->{$grp}; # Handle quirks of dealing with both stacks and chassis if ( ( !$is_virtual ) and ( $grp == 1 ) ) { $class = 'module'; } if ( ($is_virtual) and ( $grp == 3 ) and !( $idx % $enc ) ) { $class = 'chassis'; } $ns_e_class{$iid} = $class; } return \%ns_e_class; } sub ns_e_descr { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $ns_e_descr = $stack->ns_com_descr($partial) || {}; my %ns_e_descr; foreach my $iid ( keys %$ns_e_idx ) { my $descr = $ns_e_descr->{$iid}; next unless defined $descr; $ns_e_descr{$iid} = $descr; } return \%ns_e_descr; } sub ns_e_name { my $stack = shift; my $partial = shift; my $ns_class = $stack->ns_e_class() || {}; my $ns_e_idx = $stack->ns_e_index() || {}; my $ns_grp_enc = $stack->s5ChasGrpEncodeFactor($partial) || {}; my $is_virtual = $stack->_ns_e_is_virtual(); my %ns_e_name; foreach my $iid ( keys %$ns_e_idx ) { my ( $grp, $idx, $sub ) = split( /\./, $iid ); my $class = $ns_class->{$iid}; next unless defined $class; my $enc = $ns_grp_enc->{$grp}; if ( ( !$is_virtual ) and ( $grp == 1 ) ) { $ns_e_name{$iid} = 'Supervisory Module'; } elsif ( $class eq 'stack' ) { $ns_e_name{$iid} = 'Stack Master Unit'; } elsif ( $class eq 'chassis' ) { if ($is_virtual) { my $unit = $idx / $enc; $ns_e_name{$iid} = "Switch Unit $unit"; } else { $ns_e_name{$iid} = "Chassis"; } } elsif ( $class eq 'module' ) { if ($is_virtual) { my $unit = int( $idx / $enc ); my $mda = $idx % $enc; $ns_e_name{$iid} = "Switch Unit $unit, MDA $mda"; } elsif ( $sub != 0 ) { $ns_e_name{$iid} = "Module Slot $idx, Subcomponent $sub"; } else { $ns_e_name{$iid} = "Module Slot $idx"; } } } return \%ns_e_name; } sub ns_e_hwver { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $ns_e_ver = $stack->ns_com_ver($partial) || {}; my %ns_e_hwver; foreach my $iid ( keys %$ns_e_idx ) { my $ver = $ns_e_ver->{$iid}; next unless defined $ver; $ns_e_hwver{$iid} = $ver; } return \%ns_e_hwver; } sub ns_e_vendor { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my %ns_e_vendor; foreach my $iid ( keys %$ns_e_idx ) { my $vendor = 'avaya'; $ns_e_vendor{$iid} = $vendor; } return \%ns_e_vendor; } sub ns_e_serial { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $ns_e_serial = $stack->ns_com_serial($partial) || {}; my %ns_e_serial; foreach my $iid ( keys %$ns_e_idx ) { my $serial = $ns_e_serial->{$iid}; next unless defined $serial; $ns_e_serial{$iid} = $serial; } return \%ns_e_serial; } sub ns_e_type { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $ns_e_type = $stack->ns_com_type($partial) || {}; my $is_stack = $stack->_ns_e_is_stack(); my $ch_type = $stack->ns_ch_type(); my %ns_e_type; foreach my $iid ( keys %$ns_e_idx ) { my $type = $ns_e_type->{$iid}; next unless defined $type; if ( $is_stack and $iid =~ /^1/ ) { $type = $ch_type; } $ns_e_type{$iid} = $type; } return \%ns_e_type; } sub ns_e_pos { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $ns_grp_enc = $stack->s5ChasGrpEncodeFactor($partial) || {}; my $is_stack = $stack->_ns_e_is_stack(); my $is_virtual = $stack->_ns_e_is_virtual(); my %ns_e_pos; foreach my $iid ( keys %$ns_e_idx ) { my ( $grp, $pos, $idx ) = split( /\./, $iid ); next unless defined $grp; next unless defined $pos; if ( $grp == 1 ) { if ($is_stack) { $pos = -1; } else { $pos = 99; } } elsif ( $grp == 3 and $idx == 0 ) { my $enc = $ns_grp_enc->{$grp}; if ( $is_virtual and ( $pos % $enc ) ) { $pos = int( $pos % $enc ); } elsif ( $is_virtual and !$is_stack and !( $pos % $enc ) ) { $pos = -1; } elsif ( $is_virtual and !( $pos % $enc ) ) { $pos = ( $pos / $enc ); } } elsif ( !$is_stack and $grp == 3 ) { $pos = $idx; } elsif ( $grp == 8 ) { $pos = -1; } $ns_e_pos{$iid} = $pos; } return \%ns_e_pos; } sub ns_e_fwver { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $ns_e_ver = $stack->ns_store_ver($partial) || {}; my $ns_e_type = $stack->ns_store_type($partial) || {}; my $ns_grp_enc = $stack->s5ChasGrpEncodeFactor($partial) || {}; my $is_virt = $stack->_ns_e_is_virtual(); my %ns_e_fwver; foreach my $iid ( keys %$ns_e_type ) { my $type = $ns_e_type->{$iid}; next unless defined $type; next unless $type =~ /(rom|boot|fw)/i; my $ver = $ns_e_ver->{$iid}; next unless defined $ver; $iid =~ s/\.\d+$//; if ($is_virt) { my ( $grp, $idx, $pos ) = split( /\./, $iid ); my $enc = $ns_grp_enc->{$grp}; $idx = $idx * $enc; $iid = "3.$idx.$pos"; } $ns_e_fwver{$iid} = $ver; } return \%ns_e_fwver; } sub ns_e_swver { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $ns_e_ver = $stack->ns_store_ver($partial) || {}; my $ns_e_type = $stack->ns_store_type($partial) || {}; my $ns_grp_enc = $stack->s5ChasGrpEncodeFactor($partial) || {}; my $is_virt = $stack->_ns_e_is_virtual(); my %ns_e_swver; foreach my $iid ( keys %$ns_e_type ) { my $type = $ns_e_type->{$iid}; next unless defined $type; next unless $type =~ /(flash)/i; my $ver = $ns_e_ver->{$iid}; next unless defined $ver; $iid =~ s/\.\d+$//; if ($is_virt) { my ( $grp, $idx, $pos ) = split( /\./, $iid ); my $enc = $ns_grp_enc->{$grp}; $idx = $idx * $enc; $iid = "3.$idx.$pos"; } $ns_e_swver{$iid} = $ver; } return \%ns_e_swver; } sub ns_e_parent { my $stack = shift; my $partial = shift; my $ns_e_idx = $stack->ns_e_index($partial) || {}; my $ns_grp_enc = $stack->s5ChasGrpEncodeFactor($partial) || {}; my $is_stack = $stack->_ns_e_is_stack(); my $is_virtual = $stack->_ns_e_is_virtual(); my %ns_e_parent; foreach my $iid ( keys %$ns_e_idx ) { my $index = $ns_e_idx->{$iid}; my ( $grp, $idx, $pos ) = split( /\./, $iid ); next unless defined $grp; if ( $grp == 8 ) { $ns_e_parent{$iid} = '0'; } if ( $grp == 1 ) { if ($is_stack) { $ns_e_parent{$iid} = '0'; } else { $ns_e_parent{$iid} = '080100'; } } if ( $grp == 3 ) { my $enc = $ns_grp_enc->{$grp}; if ( $idx % $enc ) { my $npos = ( $idx % $enc ) * $enc; my @parent = ( $grp, $npos, $pos ); my $parent = join( '', map { sprintf "%02d", $_ } @parent ); $ns_e_parent{$iid} = $parent; } elsif ($is_stack) { $ns_e_parent{$iid} = '010100'; } elsif ( $is_virtual and !$is_stack ) { $ns_e_parent{$iid} = 0; } elsif ( $pos == 0 ) { $ns_e_parent{$iid} = '080100'; } else { my $parent = $iid; $parent =~ s/\.\d+$/\.00/; $parent = join( '', map { sprintf "%02d", $_ } split /\./, $parent ); $ns_e_parent{$iid} = $parent; } } next; } return \%ns_e_parent; } sub munge_ns_grp_type { my $oid = shift; my %e_class = ( Sup => 'stack', Bkpl => 'backplane', Brd => 'module', Pwr => 'powerSupply', TmpSnr => 'sensor', Fan => 'fan', Clk => 'other', Unit => 'chassis', ); my $name = &SNMP::translateObj($oid); $name =~ s/s5ChasGrp//; if ( ( defined($name) ) and ( exists( $e_class{$name} ) ) ) { $name = $e_class{$name}; } return $name if defined($name); return $oid; } 1; __END__ =head1 NAME SNMP::Info::NortelStack - SNMP Interface to the Avaya/Nortel F and F =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $stack = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly on to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $stack->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::NortelStack is a subclass of SNMP::Info that provides an interface to F and F. These MIBs are used across the Avaya/Nortel Stackable Ethernet Switches (BayStack), as well as, older Nortel devices such as the Centillion family of ATM switches. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =item F =item F and F are required by the other MIBs. =back =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $stack->os_ver() Returns the software version extracted from (C) =item $stack->os_bin() Returns the firmware version extracted from (C) =item $stack->serial() Returns serial number of the chassis (C) =item $stack->ns_ag_ver() Returns the version of the agent in the form 'major.minor.maintenance[letters]'. (C) =item $stack->ns_op_mode() Returns the stacking mode. (C) =item $stack->tftp_action() This object is used to download or upload a config file or an image file. (C) =item $stack->tftp_result() Returns the status of the latest action as shown by $stack->tftp_action(). (C) =item $stack->ns_auto_pvid() Returns the value indicating whether adding a port as a member of a VLAN automatically results in its PVID being set to be the same as that VLAN ID. (C) =item $stack->tftp_file() Name of the binary configuration file that will be downloaded/uploaded when the $stack->tftp_action() object is set. (C) =item $stack->tftp_host() The IP address of the TFTP server for all TFTP operations. (C) =item $stack->vlan() Returns the VLAN ID of the system's management VLAN. (C) =item $stack->ch_ser() Returns the serial number of the chassis. (C) =item $stack->ns_cfg_chg() Returns the total number of configuration changes (other than attachment changes, or physical additions or removals) in the chassis that have been detected since cold/warm start. (C) =item $stack->ns_cfg_time() Returns the value of C when the last configuration change (other than attachment changes, or physical additions or removals) in the chassis was detected. (C) =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Agent Interface Table (C) =over =item $stack->i_cfg_file() Returns reference to hash. Key: Table entry, Value: Name of the file (C) =item $stack->i_cfg_host() Returns reference to hash. Key: Table entry, Value: IP address of the load server (C) =back =head2 Chassis Components Table (C) =over =item $stack->ns_com_grp_idx() Returns reference to hash. Key: Table entry, Value: Index of the chassis level group which contains this component. (C) =item $stack->ns_com_idx() Returns reference to hash. Key: Table entry, Value: Index of the component in the group. For modules in the 'board' group, this is the slot number. (C) =item $stack->ns_com_sub_idx() Returns reference to hash. Key: Table entry, Value: Index of the sub-component in the component. (C) =item $stack->ns_com_type() Returns reference to hash. Key: Table entry, Value: Type (C) =item $stack->ns_com_descr() Returns reference to hash. Key: Table entry, Value: Description (C) =item $stack->ns_com_ver() Returns reference to hash. Key: Table entry, Value: Version (C) =item $stack->ns_com_serial() Returns reference to hash. Key: Table entry, Value: Serial Number (C) =back =head2 Storage Area Table (C) =over =item $stack->ns_store_grp_idx() Returns reference to hash. Key: Table entry, Value: Index of the chassis level group. (C) =item $stack->ns_store_idx() Returns reference to hash. Key: Table entry, Value: Index of the group. (C) =item $stack->ns_store_sub_idx() Returns reference to hash. Key: Table entry, Value: Index of the sub-component. (C) =item $stack->ns_store_idx() Returns reference to hash. Key: Table entry, Value: Index of the storage area. (C) =item $stack->ns_store_type() Returns reference to hash. Key: Table entry, Value: Type (C) =item $stack->ns_store_size() Returns reference to hash. Key: Table entry, Value: Size (C) =item $stack->ns_store_ver() Returns reference to hash. Key: Table entry, Value: Version (C) =back =head2 Pseudo F information These methods emulate F Physical Table methods using F. =over =item $stack->ns_e_index() Returns reference to hash. Key: IID, Value: Integer, Indices are combined into a six digit integer, each index is two digits padded with leading zero if required. =item $stack->ns_e_class() Returns reference to hash. Key: IID, Value: General hardware type (C). Group is stripped from the string. Values may be Supervisory Module, Back Plane, Board, Power Supply, Sensor, Fan, Clock, Unit. =item $stack->ns_e_descr() Returns reference to hash. Key: IID, Value: Human friendly name (C) =item $stack->ns_e_name() Returns reference to hash. Key: IID, Value: Human friendly name =item $stack->ns_e_hwver() Returns reference to hash. Key: IID, Value: Hardware version (C) =item $stack->ns_e_vendor() Returns reference to hash. Key: IID, Value: avaya =item $stack->ns_e_serial() Returns reference to hash. Key: IID, Value: Serial number (C) =item $stack->ns_e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. (C) =item $stack->ns_e_type() Returns reference to hash. Key: IID, Value: Type of component/sub-component as defined under C in F. =item $stack->ns_e_fwver() Returns reference to hash. Key: IID, Value: Firmware revision. Value of C for entries with rom, boot, or firmware in C. =item $stack->ns_e_swver() Returns reference to hash. Key: IID, Value: Software revision. Value of C for entries with "flash" in C. =item $stack->ns_e_parent() Returns reference to hash. Key: IID, Value: The value of ns_e_index() for the entity which 'contains' this entity. A value of zero indicates this entity is not contained in any other entity. =back =head1 Data Munging Callback Subroutines =over =item $stack->munge_ns_grp_type() Munges C into an C equivalent. =back =cut SNMP-Info-3.39/lib/SNMP/Info/PowerEthernet.pm000444000765000024 1621213215550564 20436 0ustar00oliverstaff000000000000# SNMP::Info::PowerEthernet # $Id$ # # Copyright (c) 2008 Bill Fenner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::PowerEthernet; use strict; use Exporter; use SNMP::Info; @SNMP::Info::PowerEthernet::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::PowerEthernet::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'POWER-ETHERNET-MIB' => 'pethPsePortDetectionStatus' ); %GLOBALS = (); %FUNCS = ( # parts of pethPsePortTable 'peth_port_admin' => 'pethPsePortAdminEnable', 'peth_port_status' => 'pethPsePortDetectionStatus', 'peth_port_class' => 'pethPsePortPowerClassifications', # pethMainPseTable 'peth_power_watts' => 'pethMainPsePower', 'peth_power_status' => 'pethMainPseOperStatus', 'peth_power_consumption' => 'pethMainPseConsumptionPower', 'peth_power_threshold' => 'pethMainPseUsageThreshold', ); %MUNGE = (); # POWER-ETHERNET-MIB doesn't define a mapping of its # "module"/"port" index to ifIndex. Different vendors # do this in different ways. This is a poor fallback: # if all of the module values = 1, return the port number # on the assumption that port number = ifindex. # If there is a module != 1, this heuristic doesn't work # so returns undef. sub peth_port_ifindex { my $peth = shift; my $partial = shift; my $peth_port_status = $peth->peth_port_status($partial); my $peth_port_ifindex; foreach my $i ( keys %$peth_port_status ) { my ( $module, $port ) = split( /\./, $i ); if ( $module != 1 ) { # This heuristic won't work, so say that we got nothing. # If you have this case, you have to write a device-specific # version of this function. return; } $peth_port_ifindex->{$i} = $port; } return $peth_port_ifindex; } # Subclasses are encouraged to override this method to report # what has actually been negotiated with the device, if a # protocol with more values (e.g., CDP) has been used. sub peth_port_neg_power { my $peth = shift; my $partial = shift; my $peth_port_status = $peth->peth_port_status($partial); my $peth_port_class = $peth->peth_port_class($partial); my $poemax = { 'class0' => 12950, 'class1' => 3840, 'class2' => 6490, 'class3' => 12950, 'class4' => 25500 }; my $peth_port_neg_power = {}; foreach my $i ( keys %$peth_port_status ) { if ($peth_port_status->{$i} eq 'deliveringPower') { $peth_port_neg_power->{$i} = $poemax->{ $peth_port_class->{$i} }; } } return $peth_port_neg_power; } 1; __END__ =head1 NAME SNMP::Info::PowerEthernet - SNMP Interface to data stored in F. =head1 AUTHOR Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $poe = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $poe->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION F is used to describe PoE (IEEE 802.3af) Create or use a device subclass that inherit this class. Do not use directly. For debugging purposes you can call this class directly as you would SNMP::Info my $poe = new SNMP::Info::PowerEthernet (...); =head2 Inherited Classes none. =head2 Required MIBs =over =item F =back =head1 GLOBALS none. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Power Port Table Selected values from the C =over =item $poe->peth_port_admin() Administrative status: is this port permitted to deliver power? C =item $poe->peth_port_status() Current status: is this port delivering power, searching, disabled, etc? C =item $poe->peth_port_class() Device class: if status is delivering power, this represents the 802.3af class of the device being powered. C =item $poe->peth_port_ifindex() A mapping function from the C INDEX of module.port to an C. The default mapping ignores the module (returning undef if there are any module values greater than 1) and returns the port number, assuming that there is a 1:1 mapping. This mapping is more or less left up to the device vendor to implement; the MIB gives only very weak guidance. A given device class may implement its own version of this function (e.g., see Info::CiscoPower). =item $poe->peth_port_neg_power() The power, in milliwatts, that has been committed to this port. This value is derived from the 802.3af class of the device being powered, but may be overridden by a subclass that has information from another source (e.g., if a different protocol, such as CDP, was used to negotiate the power level.) =back =head2 Power Supply Table =over =item $poe->peth_power_watts() The power supply's capacity, in watts. C =item $poe->peth_power_status() The power supply's operational status. C =item $poe->peth_power_consumption() How much power, in watts, this power supply has been committed to deliver. (Note: certain devices seem to supply this value in milliwatts, so be cautious interpreting it.) C =item $poe->peth_power_threshold() The threshold (in percent) of consumption required to raise an alarm. C =back =cut SNMP-Info-3.39/lib/SNMP/Info/RapidCity.pm000444000765000024 12171313215550564 17556 0ustar00oliverstaff000000000000# SNMP::Info::RapidCity # $Id$ # # Copyright (c) 2014 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::RapidCity; use strict; use Exporter; use SNMP::Info; @SNMP::Info::RapidCity::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::RapidCity::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'RAPID-CITY' => 'rapidCity', # These are distinct from RAPID-CITY but are potentially used by # classes which inherit the RAPID-CITY class 'NORTEL-NETWORKS-RAPID-SPANNING-TREE-MIB' => 'nnRstDot1dStpVersion', 'NORTEL-NETWORKS-MULTIPLE-SPANNING-TREE-MIB' => 'nnMstBrgAddress', ); %GLOBALS = ( 'rc_serial' => 'rcChasSerialNumber', 'chassis' => 'rcChasType', 'slots' => 'rcChasNumSlots', 'tftp_host' => 'rcTftpHost', 'tftp_file' => 'rcTftpFile', 'tftp_action' => 'rcTftpAction', 'tftp_result' => 'rcTftpResult', 'rc_ch_rev' => 'rcChasHardwareRevision', 'rc_base_mac' => 'rc2kChassisBaseMacAddr', 'rc_virt_ip' => 'rcSysVirtualIpAddr', 'rc_virt_mask' => 'rcSysVirtualNetMask', ); %FUNCS = ( # From RAPID-CITY::rcPortTable 'rc_index' => 'rcPortIndex', 'rc_duplex' => 'rcPortOperDuplex', 'rc_duplex_admin' => 'rcPortAdminDuplex', 'rc_speed_admin' => 'rcPortAdminSpeed', 'rc_auto' => 'rcPortAutoNegotiate', 'rc_alias' => 'rcPortName', # From RAPID-CITY::rc2kCpuEthernetPortTable 'rc_cpu_ifindex' => 'rc2kCpuEthernetPortIfIndex', 'rc_cpu_admin' => 'rc2kCpuEthernetPortAdminStatus', 'rc_cpu_oper' => 'rc2kCpuEthernetPortOperStatus', 'rc_cpu_ip' => 'rc2kCpuEthernetPortAddr', 'rc_cpu_mask' => 'rc2kCpuEthernetPortMask', 'rc_cpu_auto' => 'rc2kCpuEthernetPortAutoNegotiate', 'rc_cpu_duplex_admin' => 'rc2kCpuEthernetPortAdminDuplex', 'rc_cpu_duplex' => 'rc2kCpuEthernetPortOperDuplex', 'rc_cpu_speed_admin' => 'rc2kCpuEthernetPortAdminSpeed', 'rc_cpu_speed_oper' => 'rc2kCpuEthernetPortOperSpeed', 'rc_cpu_mac' => 'rc2kCpuEthernetPortMgmtMacAddr', # From RAPID-CITY::rcVlanPortTable 'rc_i_vlan_if' => 'rcVlanPortIndex', 'rc_i_vlan_num' => 'rcVlanPortNumVlanIds', 'rc_i_vlan' => 'rcVlanPortVlanIds', 'rc_i_vlan_type' => 'rcVlanPortType', 'rc_i_vlan_pvid' => 'rcVlanPortDefaultVlanId', 'rc_i_vlan_tag' => 'rcVlanPortPerformTagging', # From RAPID-CITY::rcVlanTable 'rc_vlan_id' => 'rcVlanId', 'v_name' => 'rcVlanName', 'rc_vlan_color' => 'rcVlanColor', 'rc_vlan_if' => 'rcVlanIfIndex', 'rc_vlan_stg' => 'rcVlanStgId', 'rc_vlan_type' => 'rcVlanType', 'rc_vlan_members' => 'rcVlanPortMembers', 'rc_vlan_no_join' => 'rcVlanNotAllowToJoin', 'rc_vlan_mac' => 'rcVlanMacAddress', 'rc_vlan_rstatus' => 'rcVlanRowStatus', # From RAPID-CITY::rcIpAddrTable 'rc_ip_index' => 'rcIpAdEntIfIndex', 'rc_ip_addr' => 'rcIpAdEntAddr', 'rc_ip_type' => 'rcIpAdEntIfType', # From RAPID-CITY::rcChasFanTable 'rc_fan_op' => 'rcChasFanOperStatus', # From RAPID-CITY::rcChasPowerSupplyTable 'rc_ps_op' => 'rcChasPowerSupplyOperStatus', # From RAPID-CITY::rcChasPowerSupplyDetailTable 'rc_ps_type' => 'rcChasPowerSupplyDetailType', 'rc_ps_serial' => 'rcChasPowerSupplyDetailSerialNumber', 'rc_ps_rev' => 'rcChasPowerSupplyDetailHardwareRevision', 'rc_ps_part' => 'rcChasPowerSupplyDetailPartNumber', 'rc_ps_detail' => 'rcChasPowerSupplyDetailDescription', # From RAPID-CITY::rcCardTable 'rc_c_type' => 'rcCardType', 'rc_c_serial' => 'rcCardSerialNumber', 'rc_c_rev' => 'rcCardHardwareRevision', 'rc_c_part' => 'rcCardPartNumber', # From RAPID-CITY::rc2kCardTable 'rc2k_c_ftype' => 'rc2kCardFrontType', 'rc2k_c_fdesc' => 'rc2kCardFrontDescription', 'rc2k_c_fserial' => 'rc2kCardFrontSerialNum', 'rc2k_c_frev' => 'rc2kCardFrontHwVersion', 'rc2k_c_fpart' => 'rc2kCardFrontPartNumber', 'rc2k_c_fdate' => 'rc2kCardFrontDateCode', 'rc2k_c_fdev' => 'rc2kCardFrontDeviations', 'rc2k_c_btype' => 'rc2kCardBackType', 'rc2k_c_bdesc' => 'rc2kCardBackDescription', 'rc2k_c_bserial' => 'rc2kCardBackSerialNum', 'rc2k_c_brev' => 'rc2kCardBackHwVersion', 'rc2k_c_bpart' => 'rc2kCardBackPartNumber', 'rc2k_c_bdate' => 'rc2kCardBackDateCode', 'rc2k_c_bdev' => 'rc2kCardBackDeviations', # From RAPID-CITY::rc2kMdaCardTable 'rc2k_mda_type' => 'rc2kMdaCardType', 'rc2k_mda_desc' => 'rc2kMdaCardDescription', 'rc2k_mda_serial' => 'rc2kMdaCardSerialNum', 'rc2k_mda_rev' => 'rc2kMdaCardHwVersion', 'rc2k_mda_part' => 'rc2kMdaCardPartNumber', 'rc2k_mda_date' => 'rc2kMdaCardDateCode', 'rc2k_mda_dev' => 'rc2kMdaCardDeviations', # From RAPID-CITY::rcMltTable 'rc_mlt_ports' => 'rcMltPortMembers', 'rc_mlt_index' => 'rcMltIfIndex', 'rc_mlt_dp' => 'rcMltDesignatedPort', # From RAPID-CITY::rcBridgeSpbmMacTable 'rc_spbm_fw_port' => 'rcBridgeSpbmMacCPort', 'rc_spbm_fw_status' => 'rcBridgeSpbmMacStatus', 'rc_spbm_fw_vlan' => 'rcBridgeSpbmMacCVlanId', # From RAPID-CITY::rcStgTable 'stp_i_id' => 'rcStgId', 'rc_stp_i_mac' => 'rcStgBridgeAddress', 'rc_stp_i_time' => 'rcStgTimeSinceTopologyChange', 'rc_stp_i_ntop' => 'rcStgTopChanges', 'rc_stp_i_root' => 'rcStgDesignatedRoot', 'rc_stp_i_root_port' => 'rcStgRootPort', 'rc_stp_i_priority' => 'rcStgPriority', # From RAPID-CITY::rcStgPortTable 'rc_stp_p_id' => 'rcStgPort', 'stp_p_stg_id' => 'rcStgPortStgId', 'rc_stp_p_priority' => 'rcStgPortPriority', 'rc_stp_p_state' => 'rcStgPortState', 'rc_stp_p_cost' => 'rcStgPortPathCost', 'rc_stp_p_root' => 'rcStgPortDesignatedRoot', 'rc_stp_p_bridge' => 'rcStgPortDesignatedBridge', 'rc_stp_p_port' => 'rcStgPortDesignatedPort', ); %MUNGE = ( 'rc_base_mac' => \&SNMP::Info::munge_mac, 'rc_vlan_mac' => \&SNMP::Info::munge_mac, 'rc_cpu_mac' => \&SNMP::Info::munge_mac, 'rc_vlan_members' => \&SNMP::Info::munge_port_list, 'rc_vlan_no_join' => \&SNMP::Info::munge_port_list, 'rc_mlt_ports' => \&SNMP::Info::munge_port_list, 'rc_stp_i_mac' => \&SNMP::Info::munge_mac, 'rc_stp_i_root' => \&SNMP::Info::munge_prio_mac, 'rc_stp_p_root' => \&SNMP::Info::munge_prio_mac, 'rc_stp_p_bridge' => \&SNMP::Info::munge_prio_mac, 'rc_stp_p_port' => \&SNMP::Info::munge_prio_port, ); # Need to override here since overridden in Layer2 and Layer3 classes sub serial { my $rapidcity = shift; my $ver = $rapidcity->rc_serial(); return $ver unless !defined $ver; return; } sub i_duplex { my $rapidcity = shift; my $partial = shift; my $rc_duplex = $rapidcity->rc_duplex($partial) || {}; my $rc_cpu_duplex = $rapidcity->rc_cpu_duplex($partial) || {}; my %i_duplex; foreach my $if ( keys %$rc_duplex ) { my $duplex = $rc_duplex->{$if}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $i_duplex{$if} = $duplex; } # Get CPU Ethernet Interfaces for 8600 Series foreach my $iid ( keys %$rc_cpu_duplex ) { my $c_duplex = $rc_cpu_duplex->{$iid}; next unless defined $c_duplex; $i_duplex{$iid} = $c_duplex; } return \%i_duplex; } sub i_duplex_admin { my $rapidcity = shift; my $partial = shift; my $rc_duplex_admin = $rapidcity->rc_duplex_admin() || {}; my $rc_auto = $rapidcity->rc_auto($partial) || {}; my $rc_cpu_auto = $rapidcity->rc_cpu_auto($partial) || {}; my $rc_cpu_duplex_admin = $rapidcity->rc_cpu_duplex_admin($partial) || {}; my %i_duplex_admin; foreach my $if ( keys %$rc_duplex_admin ) { my $duplex = $rc_duplex_admin->{$if}; next unless defined $duplex; my $auto = $rc_auto->{$if} || 'false'; my $string = 'other'; $string = 'half' if ( $duplex =~ /half/i and $auto =~ /false/i ); $string = 'full' if ( $duplex =~ /full/i and $auto =~ /false/i ); $string = 'auto' if $auto =~ /true/i; $i_duplex_admin{$if} = $string; } # Get CPU Ethernet Interfaces for 8600 Series foreach my $iid ( keys %$rc_cpu_duplex_admin ) { my $c_duplex = $rc_cpu_duplex_admin->{$iid}; next unless defined $c_duplex; my $c_auto = $rc_cpu_auto->{$iid}; my $string = 'other'; $string = 'half' if ( $c_duplex =~ /half/i and $c_auto =~ /false/i ); $string = 'full' if ( $c_duplex =~ /full/i and $c_auto =~ /false/i ); $string = 'auto' if $c_auto =~ /true/i; $i_duplex_admin{$iid} = $string; } return \%i_duplex_admin; } sub set_i_duplex_admin { my $rapidcity = shift; my ( $duplex, $iid ) = @_; $duplex = lc($duplex); return unless ( $duplex =~ /(half|full|auto)/ and $iid =~ /\d+/ ); # map a textual duplex to an integer one the switch understands my %duplexes = qw/full 2 half 1/; my $i_auto = $rapidcity->rc_auto($iid); if ( $duplex eq "auto" ) { return $rapidcity->set_rc_auto( '1', $iid ); } elsif ( ( $duplex ne "auto" ) and ( $i_auto->{$iid} eq "1" ) ) { return unless ( $rapidcity->set_rc_auto( '2', $iid ) ); return $rapidcity->set_rc_duplex_admin( $duplexes{$duplex}, $iid ); } else { return $rapidcity->set_rc_duplex_admin( $duplexes{$duplex}, $iid ); } return; } sub set_i_speed_admin { my $rapidcity = shift; my ( $speed, $iid ) = @_; return unless ( $speed =~ /(10|100|1000|auto)/i and $iid =~ /\d+/ ); # map a textual duplex to an integer one the switch understands my %speeds = qw/10 1 100 2 1000 3/; my $i_auto = $rapidcity->rc_auto($iid); if ( $speed eq "auto" ) { return $rapidcity->set_rc_auto( '1', $iid ); } elsif ( ( $speed ne "auto" ) and ( $i_auto->{$iid} eq "1" ) ) { return unless ( $rapidcity->set_rc_auto( '2', $iid ) ); return $rapidcity->set_rc_speed_admin( $speeds{$speed}, $iid ); } else { return $rapidcity->set_rc_speed_admin( $speeds{$speed}, $iid ); } return; } sub v_index { my $rapidcity = shift; my $partial = shift; return $rapidcity->rc_vlan_id($partial); } sub i_vlan { my $rapidcity = shift; my $partial = shift; my $i_pvid = $rapidcity->rc_i_vlan_pvid($partial) || {}; return $i_pvid; } sub i_vlan_membership { my $rapidcity = shift; my $rc_v_ports = $rapidcity->rc_vlan_members(); my $i_vlan_membership = {}; foreach my $vlan ( keys %$rc_v_ports ) { my $portlist = $rc_v_ports->{$vlan}; my $ret = []; # Convert portlist bit array to ifIndex array for ( my $i = 0; $i <= scalar(@$portlist); $i++ ) { push( @{$ret}, $i ) if ( @$portlist[$i] ); } #Create HoA ifIndex -> VLAN array foreach my $port ( @{$ret} ) { push( @{ $i_vlan_membership->{$port} }, $vlan ); } } return $i_vlan_membership; } sub i_vlan_membership_untagged { my $rapidcity = shift; # Traditionally access ports have one VLAN untagged and trunk ports have # one or more VLANs all tagged # Newer VOSS device trunks have PerformTagging true or false and also can # UntagDefaultVlan # Newer BOSS device trunks have four PerformTagging options true, false, # tagPvidOnly, and untagPvidOnly my $p_members = $rapidcity->i_vlan_membership(); my $i_vlan = $rapidcity->i_vlan(); my $p_tag_opt = $rapidcity->rcVlanPortPerformTagging() || {}; my $p_untag_def = $rapidcity->rcVlanPortUntagDefaultVlan() || {}; my $p_type = $rapidcity->rcVlanPortType() || {}; my $members_untagged = {}; foreach my $port ( keys %$p_type ) { my $type = $p_type->{$port}; next unless $type; # Easiest case first access ports if ($type eq 'access') { # Access ports should only have one VLAN and it should be # untagged $members_untagged->{$port} = $p_members->{$port}; } else { # If PerformTagging has a value do all checks otherwise we're # just a trunk and everything is tagged if ($p_tag_opt->{$port}) { if ($p_tag_opt->{$port} eq 'untagPvidOnly') { my $vlan = $i_vlan->{$port}; push( @{ $members_untagged->{$port} }, $vlan ); } elsif (($p_tag_opt->{$port} eq 'true') and ($p_untag_def->{$port} and $p_untag_def->{$port} eq 'true')) { my $vlan = $i_vlan->{$port}; push( @{ $members_untagged->{$port} }, $vlan ); } elsif ($p_tag_opt->{$port} eq 'tagPvidOnly') { my $vlan = $i_vlan->{$port}; my @arr = $p_members->{$port}; my $index = 0; my $count = scalar @arr; $index++ until $arr[$index] eq $vlan or $index==$count; splice(@arr, $index, 1); $members_untagged->{$port} = @arr; } # Don't know if this is a legal configuration, but included # for completeness elsif ($p_tag_opt->{$port} eq 'false') { $members_untagged->{$port} = $p_members->{$port}; } else { next; } } } } return $members_untagged; } sub set_i_pvid { my $rapidcity = shift; my ( $vlan_id, $ifindex ) = @_; return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) ); unless ( $rapidcity->set_rc_i_vlan_pvid( $vlan_id, $ifindex ) ) { $rapidcity->error_throw( "Unable to change PVID to $vlan_id on IfIndex: $ifindex"); return; } return 1; } sub set_i_vlan { my $rapidcity = shift; my ( $new_vlan_id, $ifindex ) = @_; return unless ( $rapidcity->_validate_vlan_param( $new_vlan_id, $ifindex ) ); my $vlan_p_type = $rapidcity->rc_i_vlan_type($ifindex); unless ( $vlan_p_type->{$ifindex} =~ /access/ ) { $rapidcity->error_throw("Not an access port"); return; } my $i_pvid = $rapidcity->rc_i_vlan_pvid($ifindex); # Store current untagged VLAN to remove it from the port list later my $old_vlan_id = $i_pvid->{$ifindex}; # Check that haven't been given the same VLAN we are currently using if ( $old_vlan_id eq $new_vlan_id ) { $rapidcity->error_throw( "Current PVID: $old_vlan_id and New VLAN: $new_vlan_id the same, no change." ); return; } print "Changing VLAN: $old_vlan_id to $new_vlan_id on IfIndex: $ifindex\n" if $rapidcity->debug(); # Check if port in forbidden list for the VLAN, haven't seen this used, # but we'll check anyway return unless ( $rapidcity->_check_forbidden_ports( $new_vlan_id, $ifindex ) ); my $old_vlan_members = $rapidcity->rc_vlan_members($old_vlan_id); my $new_vlan_members = $rapidcity->rc_vlan_members($new_vlan_id); print "Modifying egress list for VLAN: $new_vlan_id \n" if $rapidcity->debug(); my $new_egress = $rapidcity->modify_port_list( $new_vlan_members->{$new_vlan_id}, $ifindex, '1' ); print "Modifying egress list for VLAN: $old_vlan_id \n" if $rapidcity->debug(); my $old_egress = $rapidcity->modify_port_list( $old_vlan_members->{$old_vlan_id}, $ifindex, '0' ); my $vlan_set = [ [ 'rc_vlan_members', "$new_vlan_id", "$new_egress" ], # ['rc_vlan_members',"$old_vlan_id","$old_egress"], ]; return unless ( $rapidcity->set_multi($vlan_set) ); my $vlan_set2 = [ [ 'rc_vlan_members', "$old_vlan_id", "$old_egress" ], ]; return unless ( $rapidcity->set_multi($vlan_set2) ); # Set new untagged / native VLAN # Some models/versions do this for us also, so check to see if we need to set $i_pvid = $rapidcity->rc_i_vlan_pvid($ifindex); my $cur_i_pvid = $i_pvid->{$ifindex}; print "Current PVID: $cur_i_pvid\n" if $rapidcity->debug(); unless ( $cur_i_pvid eq $new_vlan_id ) { return unless ( $rapidcity->set_i_pvid( $new_vlan_id, $ifindex ) ); } print "Successfully changed VLAN: $old_vlan_id to $new_vlan_id on IfIndex: $ifindex\n" if $rapidcity->debug(); return 1; } sub set_add_i_vlan_tagged { my $rapidcity = shift; my ( $vlan_id, $ifindex ) = @_; return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) ); print "Adding VLAN: $vlan_id to IfIndex: $ifindex\n" if $rapidcity->debug(); # Check if port in forbidden list for the VLAN, haven't seen this used, but we'll check anyway return unless ( $rapidcity->_check_forbidden_ports( $vlan_id, $ifindex ) ); my $iv_members = $rapidcity->rc_vlan_members($vlan_id); print "Modifying egress list for VLAN: $vlan_id \n" if $rapidcity->debug(); my $new_egress = $rapidcity->modify_port_list( $iv_members->{$vlan_id}, $ifindex, '1' ); unless ( $rapidcity->set_qb_v_egress( $new_egress, $vlan_id ) ) { print "Error: Unable to add VLAN: $vlan_id to Index: $ifindex egress list.\n" if $rapidcity->debug(); return; } print "Successfully added IfIndex: $ifindex to VLAN: $vlan_id egress list\n" if $rapidcity->debug(); return 1; } sub set_remove_i_vlan_tagged { my $rapidcity = shift; my ( $vlan_id, $ifindex ) = @_; return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) ); print "Removing VLAN: $vlan_id from IfIndex: $ifindex\n" if $rapidcity->debug(); my $iv_members = $rapidcity->rc_vlan_members($vlan_id); print "Modifying egress list for VLAN: $vlan_id \n" if $rapidcity->debug(); my $new_egress = $rapidcity->modify_port_list( $iv_members->{$vlan_id}, $ifindex, '0' ); unless ( $rapidcity->set_qb_v_egress( $new_egress, $vlan_id ) ) { print "Error: Unable to add VLAN: $vlan_id to Index: $ifindex egress list.\n" if $rapidcity->debug(); return; } print "Successfully removed IfIndex: $ifindex from VLAN: $vlan_id egress list\n" if $rapidcity->debug(); return 1; } sub set_create_vlan { my $rapidcity = shift; my ( $name, $vlan_id ) = @_; return unless ( $vlan_id =~ /\d+/ ); my $vlan_set = [ [ 'v_name', "$vlan_id", "$name" ], [ 'rc_vlan_rstatus', "$vlan_id", 4 ], ]; unless ( $rapidcity->set_multi($vlan_set) ) { print "Error: Unable to create VLAN: $vlan_id\n" if $rapidcity->debug(); return; } return 1; } sub set_delete_vlan { my $rapidcity = shift; my ($vlan_id) = shift; return unless ( $vlan_id =~ /^\d+$/ ); unless ( $rapidcity->set_rc_vlan_rstatus( '6', $vlan_id ) ) { $rapidcity->error_throw("Unable to delete VLAN: $vlan_id"); return; } return 1; } # # These are internal methods and are not documented. Do not use directly. # sub _check_forbidden_ports { my $rapidcity = shift; my ( $vlan_id, $ifindex ) = @_; my $iv_forbidden = $rapidcity->rc_vlan_no_join($vlan_id); my @forbidden_ports = split( //, unpack( "B*", $iv_forbidden->{$vlan_id} ) ); print "Forbidden ports: @forbidden_ports\n" if $rapidcity->debug(); if ( defined( $forbidden_ports[$ifindex] ) and ( $forbidden_ports[$ifindex] eq "1" ) ) { $rapidcity->error_throw( "IfIndex: $ifindex in forbidden list for VLAN: $vlan_id unable to add" ); return; } return 1; } sub _validate_vlan_param { my $rapidcity = shift; my ( $vlan_id, $ifindex ) = @_; # VID and ifIndex should both be numeric unless (defined $vlan_id and defined $ifindex and $vlan_id =~ /^\d+$/ and $ifindex =~ /^\d+$/ ) { $rapidcity->error_throw("Invalid parameter"); return; } # Check that ifIndex exists on device my $index = $rapidcity->interfaces($ifindex); unless ( exists $index->{$ifindex} ) { $rapidcity->error_throw("ifIndex $ifindex does not exist"); return; } #Check that VLAN exists on device unless ( $rapidcity->rc_vlan_id($vlan_id) ) { $rapidcity->error_throw( "VLAN $vlan_id does not exist or is not operational"); return; } return 1; } sub agg_ports { my $rapidcity = shift; # TODO: implement partial my $ports = $rapidcity->rc_mlt_ports; my $trunks = $rapidcity->rc_mlt_index; my $dps = $rapidcity->rc_mlt_dp || {}; return {} unless ref {} eq ref $trunks and scalar keys %$trunks and ref {} eq ref $ports and scalar keys %$ports; my $ret = {}; foreach my $m ( keys %$trunks ) { my $idx = $trunks->{$m}; next unless $idx; $idx = $dps->{$m} ? $dps->{$m} : $idx; my $portlist = $ports->{$m}; next unless $portlist; for ( my $i = 0; $i <= scalar(@$portlist); $i++ ) { $ret->{$i} = $idx if ( @$portlist[$i] ); } } return $ret; } # break up the rcBridgeSpbmMacEntry INDEX into ISID and MAC Address. sub _spbm_fdbtable_index { my $idx = shift; my @values = split( /\./, $idx ); my $isid = shift(@values); return ( $isid, join( ':', map { sprintf "%02x", $_ } @values ) ); } sub rc_spbm_fw_mac { my $rapidcity = shift; my $partial = shift; my $spbm_fw_ports = $rapidcity->rc_spbm_fw_port($partial); my $spbm_fw_mac = {}; foreach my $idx ( keys %$spbm_fw_ports ) { my ( $isid, $mac ) = _spbm_fdbtable_index($idx); $spbm_fw_mac->{$idx} = $mac; } return $spbm_fw_mac; } sub rc_spbm_fw_isid { my $rapidcity = shift; my $partial = shift; my $spbm_fw_ports = $rapidcity->rc_spbm_fw_port($partial); my $spbm_fw_isid = {}; foreach my $idx ( keys %$spbm_fw_ports ) { my ( $isid, $mac ) = _spbm_fdbtable_index($idx); $spbm_fw_isid->{$idx} = $isid; } return $spbm_fw_isid; } sub stp_ver { my $rapidcity = shift; return $rapidcity->rcSysSpanningTreeOperMode() || $rapidcity->SUPER::stp_ver(); } # RSTP and ieee8021d operating modes do not populate RAPID-CITY::rcStgTable # or RAPID-CITY::rcStgPortTable but do populate BRIDGE-MIB so check both sub stp_i_mac { my $rapidcity = shift; return $rapidcity->rc_stp_i_mac() || $rapidcity->SUPER::stp_i_mac(); } sub stp_i_time { my $rapidcity = shift; return $rapidcity->rc_stp_i_time() || $rapidcity->SUPER::stp_i_time(); } sub stp_i_ntop { my $rapidcity = shift; return $rapidcity->rc_stp_i_ntop() || $rapidcity->SUPER::stp_i_ntop(); } sub stp_i_root { my $rapidcity = shift; return $rapidcity->rc_stp_i_root() || $rapidcity->SUPER::stp_i_root(); } sub stp_i_root_port { my $rapidcity = shift; return $rapidcity->rc_stp_i_root_port() || $rapidcity->SUPER::stp_i_root_port(); } sub stp_i_priority { my $rapidcity = shift; return $rapidcity->rc_stp_i_priority() || $rapidcity->SUPER::stp_i_priority(); } sub stp_p_id { my $rapidcity = shift; return $rapidcity->rc_stp_p_id() || $rapidcity->SUPER::stp_p_id(); } sub stp_p_priority { my $rapidcity = shift; return $rapidcity->rc_stp_p_priority() || $rapidcity->SUPER::stp_p_priority(); } sub stp_p_state { my $rapidcity = shift; return $rapidcity->rc_stp_p_state() || $rapidcity->SUPER::stp_p_state(); } sub stp_p_cost { my $rapidcity = shift; return $rapidcity->rc_stp_p_cost() || $rapidcity->SUPER::stp_p_cost(); } sub stp_p_root { my $rapidcity = shift; return $rapidcity->rc_stp_p_root() || $rapidcity->SUPER::stp_p_root(); } sub stp_p_bridge { my $rapidcity = shift; return $rapidcity->rc_stp_p_bridge() || $rapidcity->SUPER::stp_p_bridge(); } sub stp_p_port { my $rapidcity = shift; return $rapidcity->rc_stp_p_port() || $rapidcity->SUPER::stp_p_port(); } sub mst_vlan2instance { my $rapidcity = shift; my $partial = shift; return $rapidcity->rcVlanStgId($partial); } sub i_bpduguard_enabled { my $rapidcity = shift; my $partial = shift; return $rapidcity->rcPortBpduFilteringOperEnabled(); } sub i_stp_state { my $rapidcity = shift; my $partial = shift; my $bp_index = $rapidcity->bp_index($partial); my $stp_p_state = $rapidcity->dot1dStpPortState($partial); my %i_stp_state; foreach my $index ( keys %$stp_p_state ) { my $state = $stp_p_state->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $state; $i_stp_state{$iid} = $state; } return \%i_stp_state; } 1; __END__ =head1 NAME SNMP::Info::RapidCity - SNMP Interface to the Avaya/Nortel RapidCity MIB =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $rapidcity = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $rapidcity->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info::RapidCity is a subclass of SNMP::Info that provides an interface to the C MIB. This MIB is used across the Avaya/Nortel Ethernet Routing Switch and Ethernet Switch product lines (Formerly known as Passport, BayStack, and Accelar), as well as, the VSP 9000 and 7000 series. Use or create in a subclass of SNMP::Info. Do not use directly. =head2 Inherited Classes None. =head2 Required MIBs =over =item RAPID-CITY =back =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $rapidcity->rc_base_mac() (C) =item $rapidcity->rc_serial() (C) =item $rapidcity->rc_ch_rev() (C) =item $rapidcity->chassis() (C) =item $rapidcity->slots() (C) =item $rapidcity->rc_virt_ip() (C) =item $rapidcity->rc_virt_mask() (C) =item $rapidcity->tftp_host() (C) =item $rapidcity->tftp_file() (C) =item $rapidcity->tftp_action() (C) =item $rapidcity->tftp_result() (C) =back =head2 Overrides =over =item $rapidcity->serial() Returns serial number of the chassis =item $rapidcity->stp_ver() Returns the particular STP version running on this device. Values: C, C, C, C, C (C) =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $rapidcity->i_duplex() Returns reference to map of IIDs to current link duplex. =item $rapidcity->i_duplex_admin() Returns reference to hash of IIDs to admin duplex setting. =item $rapidcity->i_vlan() Returns a mapping between C and the PVID or default VLAN. =item $rapidcity->i_vlan_membership() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the egress list for the port. Example: my $interfaces = $rapidcity->interfaces(); my $vlans = $rapidcity->i_vlan_membership(); foreach my $iid (sort keys %$interfaces) { my $port = $interfaces->{$iid}; my $vlan = join(',', sort(@{$vlans->{$iid}})); print "Port: $port VLAN: $vlan\n"; } =item $rapidcity->i_vlan_membership_untagged() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port. =item $rapidcity->v_index() Returns VLAN IDs (C) =item $rapidcity->agg_ports() Returns a HASH reference mapping from slave to master port for each member of a port bundle (MLT) on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =item $rapidcity->i_stp_state() Returns the mapping of (C) to the interface index (iid). =item $rapidcity->mst_vlan2instance() Returns the mapping of VLAN to Spanning Tree Group (STG) instance in the form of a hash reference with key = VLAN id, value = STG instance (C) =item $rapidcity->i_bpduguard_enabled() Returns true or false depending on whether C is enabled on a given port. Format is a hash reference with key = C, value = [true|false] (C) =back =head2 RAPID-CITY Port Table (C) =over =item $rapidcity->rc_index() (C) =item $rapidcity->rc_duplex() (C) =item $rapidcity->rc_duplex_admin() (C) =item $rapidcity->rc_speed_admin() (C) =item $rapidcity->rc_auto() (C) =item $rapidcity->rc_alias() (C) =back =head2 RAPID-CITY CPU Ethernet Port Table (C) =over =item $rapidcity->rc_cpu_ifindex() (C) =item $rapidcity->rc_cpu_admin() (C) =item $rapidcity->rc_cpu_oper() (C) =item $rapidcity->rc_cpu_ip() (C) =item $rapidcity->rc_cpu_mask() (C) =item $rapidcity->rc_cpu_auto() (C) =item $rapidcity->rc_cpu_duplex_admin() (C) =item $rapidcity->rc_cpu_duplex() (C) =item $rapidcity->rc_cpu_speed_admin() (C) =item $rapidcity->rc_cpu_speed_oper() (C) =item $rapidcity->rc_cpu_mac() (C) =back =head2 RAPID-CITY VLAN Port Table (C) =over =item $rapidcity->rc_i_vlan_if() (C) =item $rapidcity->rc_i_vlan_num() (C) =item $rapidcity->rc_i_vlan() (C) =item $rapidcity->rc_i_vlan_type() (C) =item $rapidcity->rc_i_vlan_pvid() (C) =item $rapidcity->rc_i_vlan_tag() (C) =back =head2 RAPID-CITY VLAN Table (C) =over =item $rapidcity->rc_vlan_id() (C) =item $rapidcity->v_name() (C) =item $rapidcity->rc_vlan_color() (C) =item $rapidcity->rc_vlan_if() (C) =item $rapidcity->rc_vlan_stg() (C) =item $rapidcity->rc_vlan_type() (C) =item $rapidcity->rc_vlan_members() (C) =item $rapidcity->rc_vlan_mac() (C) =back =head2 RAPID-CITY IP Address Table (C) =over =item $rapidcity->rc_ip_index() (C) =item $rapidcity->rc_ip_addr() (C) =item $rapidcity->rc_ip_type() (C) =back =head2 RAPID-CITY Chassis Fan Table (C) =over =item $rapidcity->rc_fan_op() (C) =back =head2 RAPID-CITY Power Supply Table (C) =over =item $rapidcity->rc_ps_op() (C) =back =head2 RAPID-CITY Power Supply Detail Table (C) =over =item $rapidcity->rc_ps_type() (C) =item $rapidcity->rc_ps_serial() (C) =item $rapidcity->rc_ps_rev() (C) =item $rapidcity->rc_ps_part() (C) =item $rapidcity->rc_ps_detail() (C) =back =head2 RAPID-CITY Card Table (C) =over =item $rapidcity->rc_c_type() (C) =item $rapidcity->rc_c_serial() (C) =item $rapidcity->rc_c_rev() (C) =item $rapidcity->rc_c_part() (C) =back =head2 RAPID-CITY 2k Card Table (C) =over =item $rapidcity->rc2k_c_ftype() (C) =item $rapidcity->rc2k_c_fdesc() (C) =item $rapidcity->rc2k_c_fserial() (C) =item $rapidcity->rc2k_c_frev() (C) =item $rapidcity->rc2k_c_fpart() (C) =item $rapidcity->rc2k_c_fdate() (C) =item $rapidcity->rc2k_c_fdev() (C) =item $rapidcity->rc2k_c_btype() (C) =item $rapidcity->rc2k_c_bdesc() (C) =item $rapidcity->rc2k_c_bserial() (C) =item $rapidcity->rc2k_c_brev() (C) =item $rapidcity->rc2k_c_bpart() (C) =item $rapidcity->rc2k_c_bdate() (C) =item $rapidcity->rc2k_c_bdev() (C) =back =head2 RAPID-CITY MDA Card Table (C) =over =item $rapidcity->rc2k_mda_type() (C) =item $rapidcity->rc2k_mda_desc() (C) =item $rapidcity->rc2k_mda_serial() (C) =item $rapidcity->rc2k_mda_rev() (C) =item $rapidcity->rc2k_mda_part() (C) =item $rapidcity->rc2k_mda_date() (C) =item $rapidcity->rc2k_mda_dev() (C) =back =head2 RAPID-CITY Bridge SPBM MAC Table (C) =over =item $rapidcity->rc_spbm_fw_mac() Returns reference to hash of forwarding table MAC Addresses (C) =item $rapidcity->rc_spbm_fw_port() Returns reference to hash of forwarding table entries port interface identifier (iid) (C) =item $rapidcity->rc_spbm_fw_status() Returns reference to hash of forwarding table entries status (C) =item $rapidcity->rc_spbm_fw_vlan() Returns reference to hash of forwarding table entries Customer VLAN ID (C) =item $rapidcity->rc_spbm_fw_isid() Returns reference to hash of forwarding table entries ISID (C) =back =head2 Spanning Tree Instance Globals C and C operating modes do not populate the C but do populate F. These methods check F first and fall back to F. =over =item $rapidcity->stp_i_mac() Returns the bridge address =item $rapidcity->stp_i_time() Returns time since last topology change detected. (100ths/second) =item $rapidcity->stp_i_ntop() Returns the total number of topology changes detected. =item $rapidcity->stp_i_root() Returns root of STP. =item $rapidcity->stp_i_root_port() Returns the port number of the port that offers the lowest cost path to the root bridge. =item $rapidcity->stp_i_priority() Returns the port number of the port that offers the lowest cost path to the root bridge. =back =head2 Spanning Tree Protocol Port Table C and C operating modes do not populate the C but do populate F. These methods check F first and fall back to F. =over =item $rapidcity->stp_p_id() "The port number of the port for which this entry contains Spanning Tree Protocol management information." =item $rapidcity->stp_p_priority() "The value of the priority field which is contained in the first (in network byte order) octet of the (2 octet long) Port ID. The other octet of the Port ID is given by the value of C." =item $rapidcity->stp_p_state() "The port's current state as defined by application of the Spanning Tree Protocol." =item $rapidcity->stp_p_cost() "The contribution of this port to the path cost of paths towards the spanning tree root which include this port." =item $rapidcity->stp_p_root() "The unique Bridge Identifier of the Bridge recorded as the Root in the Configuration BPDUs transmitted by the Designated Bridge for the segment to which the port is attached." =item $rapidcity->stp_p_bridge() "The Bridge Identifier of the bridge which this port considers to be the Designated Bridge for this port's segment." =item $rapidcity->stp_p_port() "The Port Identifier of the port on the Designated Bridge for this port's segment." =back =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item $rapidcity->set_i_speed_admin(speed, ifIndex) Sets port speed, must be supplied with speed and port C. Speed choices are 'auto', '10', '100', '1000'. Example: my %if_map = reverse %{$rapidcity->interfaces()}; $rapidcity->set_i_speed_admin('auto', $if_map{'1.1'}) or die "Couldn't change port speed. ",$rapidcity->error(1); =item $rapidcity->set_i_duplex_admin(duplex, ifIndex) Sets port duplex, must be supplied with duplex and port C. Speed choices are 'auto', 'half', 'full'. Example: my %if_map = reverse %{$rapidcity->interfaces()}; $rapidcity->set_i_duplex_admin('auto', $if_map{'1.1'}) or die "Couldn't change port duplex. ",$rapidcity->error(1); =item $rapidcity->set_i_vlan(vlan, ifIndex) Changes an access (untagged) port VLAN, must be supplied with the numeric VLAN ID and port C. This method will modify the port's VLAN membership and PVID (default VLAN). This method should only be used on end station (non-trunk) ports. Example: my %if_map = reverse %{$rapidcity->interfaces()}; $rapidcity->set_i_vlan('2', $if_map{'1.1'}) or die "Couldn't change port VLAN. ",$rapidcity->error(1); =item $rapidcity->set_i_pvid(pvid, ifIndex) Sets port PVID or default VLAN, must be supplied with the numeric VLAN ID and port C. This method only changes the PVID, to modify an access (untagged) port use set_i_vlan() instead. Example: my %if_map = reverse %{$rapidcity->interfaces()}; $rapidcity->set_i_pvid('2', $if_map{'1.1'}) or die "Couldn't change port PVID. ",$rapidcity->error(1); =item $rapidcity->set_add_i_vlan_tagged(vlan, ifIndex) Adds the port to the egress list of the VLAN, must be supplied with the numeric VLAN ID and port C. Example: my %if_map = reverse %{$rapidcity->interfaces()}; $rapidcity->set_add_i_vlan_tagged('2', $if_map{'1.1'}) or die "Couldn't add port to egress list. ",$rapidcity->error(1); =item $rapidcity->set_remove_i_vlan_tagged(vlan, ifIndex) Removes the port from the egress list of the VLAN, must be supplied with the numeric VLAN ID and port C. Example: my %if_map = reverse %{$rapidcity->interfaces()}; $rapidcity->set_remove_i_vlan_tagged('2', $if_map{'1.1'}) or die "Couldn't add port to egress list. ",$rapidcity->error(1); =item $rapidcity->set_delete_vlan(vlan) Deletes the specified VLAN from the device. =item $rapidcity->set_create_vlan(name, vlan) Creates the specified VLAN on the device. Note: This method only allows creation of Port type VLANs and does not allow for the setting of the Spanning Tree Group (STG) which defaults to 1. =back =cut SNMP-Info-3.39/lib/SNMP/Info/SONMP.pm000444000765000024 3206413215550564 16542 0ustar00oliverstaff000000000000# SNMP::Info::SONMP # # Copyright (c) 2016 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::SONMP; use warnings; use strict; use Exporter; use SNMP::Info; @SNMP::Info::SONMP::ISA = qw/SNMP::Info Exporter/; @SNMP::Info::SONMP::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( 'SYNOPTICS-ROOT-MIB' => 'synoptics', 'S5-ETH-MULTISEG-TOPOLOGY-MIB' => 's5EnMsTop', ); %GLOBALS = ( 'sonmp_gid' => 's5EnMsTopIpAddr', 'sonmp_run' => 's5EnMsTopStatus', ); %FUNCS = ( # From S5-ETH-MULTISEG-TOPOLOGY-MIB::s5EnMsTopNmmTable 'sonmp_topo_slot' => 's5EnMsTopNmmSlot', 'sonmp_topo_port' => 's5EnMsTopNmmPort', 'sonmp_topo_ip' => 's5EnMsTopNmmIpAddr', 'sonmp_topo_seg' => 's5EnMsTopNmmSegId', 'sonmp_topo_mac' => 's5EnMsTopNmmMacAddr', 'sonmp_topo_platform' => 's5EnMsTopNmmChassisType', 'sonmp_topo_localseg' => 's5EnMsTopNmmLocalSeg', # From S5-ETH-MULTISEG-TOPOLOGY-MIB::s5EnMsTopNmmEnhancedTable # Note: indexes are not-accessible in enhanced table 'sonmp_topo_e_mac' => 's5EnMsTopNmmEnhancedMacAddr', 'sonmp_topo_e_platform' => 's5EnMsTopNmmEnhancedChassisType', ); %MUNGE = ( 'sonmp_topo_mac' => \&SNMP::Info::munge_mac, 'sonmp_topo_e_mac' => \&SNMP::Info::munge_mac ); sub index_factor { return 32; } sub slot_offset { return 1; } sub port_offset { return 0; } sub hasSONMP { my $sonmp = shift; return 1 if defined $sonmp->sonmp_run(); return; } # Break up the s5EnMsTopNmmEntry or s5EnMsTopNmmEnhancedEntry INDEX # into Port, SubPort, IP, and Segment Id. sub _sonmp_topnmm_index { my @values = split( /\./, shift ); my $seg = pop(@values); my $s = shift(@values); my $p = shift(@values); my $sp = 0; if ( scalar @values > 4 ) { $sp = shift(@values); } return ( $s, $p, $sp, join( '.', @values ), $seg ); } # Note: Using platform to get the index because it's commonly accessible and # will be cached after first method call, we now extract the other values # from the index. sub sonmp_if { my $sonmp = shift; my $partial = shift; my $sonmp_topo_idx = $sonmp->sonmp_topo_platform($partial) || $sonmp->sonmp_topo_e_platform($partial) || {}; my $interfaces = $sonmp->interfaces() || {}; my %r_interfaces = reverse %$interfaces; my $index_factor = $sonmp->index_factor(); my $slot_offset = $sonmp->slot_offset(); my $port_offset = $sonmp->port_offset(); my $model = $sonmp->model(); my %sonmp_if; foreach my $idx ( keys %$sonmp_topo_idx ) { my ( $slot, $port, $sub_port, $ip, $seg_id ) = _sonmp_topnmm_index($idx); next unless defined $port; next if $port == 0; if ( $model eq 'Baystack Hub' ) { my $comidx = $slot; if ( !( $comidx % 5 ) ) { $slot = ( $slot / 5 ); } elsif ( $comidx =~ /[16]$/ ) { $slot = int( $slot / 5 ); $port = 25; } elsif ( $comidx =~ /[27]$/ ) { $slot = int( $slot / 5 ); $port = 26; } } my $index; my $int = $sub_port ? "$slot.$port.$sub_port" : "$slot.$port"; if ( exists $r_interfaces{$int} ) { $index = $r_interfaces{$int}; } else { $index = ( ( $slot - $slot_offset ) * $index_factor ) + ( $port - $port_offset ); } $sonmp_if{$idx} = $index; } return \%sonmp_if; } sub sonmp_ip { my $sonmp = shift; my $partial = shift; my $sonmp_topo_idx = $sonmp->sonmp_topo_platform($partial) || $sonmp->sonmp_topo_e_platform($partial) || {}; my %sonmp_ip; foreach my $idx ( keys %$sonmp_topo_idx ) { my ( $slot, $port, $sub_port, $ip, $seg_id ) = _sonmp_topnmm_index($idx); next unless defined $port; next if $port == 0; $sonmp_ip{$idx} = $ip; } return \%sonmp_ip; } sub sonmp_port { my $sonmp = shift; my $partial = shift; my $sonmp_topo_idx = $sonmp->sonmp_topo_platform($partial) || $sonmp->sonmp_topo_e_platform($partial) || {}; my $sonmp_topo_port = $sonmp->sonmp_topo_port($partial) || {}; my $sonmp_topo_seg = $sonmp->sonmp_topo_seg($partial) || {}; my $sonmp_topo_platform = $sonmp->sonmp_topo_platform($partial) || {}; my %sonmp_port; foreach my $idx ( keys %$sonmp_topo_idx ) { my ( $slot, $port, $sub_port, $ip, $seg_id ) = _sonmp_topnmm_index($idx); next unless defined $port; next if $port == 0; my $platform = $sonmp_topo_idx->{$idx}; # AP-222x Series does not adhere to port numbering if ( $platform =~ /AccessPoint/i ) { $sonmp_port{$idx} = 'dp0'; } # BayHubs send the lower three bytes of the MAC not the slot/port elsif ( $platform =~ /BayStack[E12]/ ) { $sonmp_port{$idx} = 'unknown'; } else { # Segment id is (256 * remote slot_num) + (remote_port) # Enhanced is subport +((256 * slot) + port) my $subport = 0; if ( $seg_id > 65535 ) { $subport = int( $seg_id / 65536 ); $seg_id = $seg_id % 65536; } my $port = $seg_id % 256; my $slot = int( $seg_id / 256 ); $sonmp_port{$idx} = $subport ? "$slot.$port.$subport" : "$slot.$port"; } } return \%sonmp_port; } sub sonmp_platform { my $sonmp = shift; my $partial = shift; my $sonmp_topo_idx = $sonmp->sonmp_topo_platform($partial) || $sonmp->sonmp_topo_e_platform($partial) || {}; my %sonmp_platform; foreach my $idx ( keys %$sonmp_topo_idx ) { my ( $slot, $port, $sub_port, $ip, $seg_id ) = _sonmp_topnmm_index($idx); next unless defined $port; next if $port == 0; my $platform = $sonmp_topo_idx->{$idx}; $sonmp_platform{$idx} = $platform; } return \%sonmp_platform; } sub mac { my $sonmp = shift; my $sonmp_topo_idx = $sonmp->sonmp_topo_mac() || $sonmp->sonmp_topo_e_mac() || {}; foreach my $idx ( keys %$sonmp_topo_idx ) { my ( $slot, $port, $sub_port, $ip, $seg_id ) = _sonmp_topnmm_index($idx); next unless $port == 0; my $mac = $sonmp_topo_idx->{$idx}; return $mac; } # Topology turned off, not supported. return; } 1; __END__ =head1 NAME SNMP::Info::SONMP - SNMP Interface to SynOptics Network Management Protocol (SONMP) =head1 AUTHOR Eric Miller =head1 SYNOPSIS my $sonmp = new SNMP::Info ( AutoSpecify => 1, Debug => 1, DestHost => 'router', Community => 'public', Version => 2 ); my $class = $sonmp->class(); print " Using device sub class : $class\n"; $hassonmp = $sonmp->hasSONMP() ? 'yes' : 'no'; # Print out a map of device ports with CDP neighbors: my $interfaces = $sonmp->interfaces(); my $sonmp_if = $sonmp->sonmp_if(); my $sonmp_ip = $sonmp->sonmp_ip(); my $sonmp_port = $sonmp->sonmp_port(); foreach my $sonmp_key (keys %$sonmp_ip){ my $iid = $sonmp_if->{$sonmp_key}; my $port = $interfaces->{$iid}; my $neighbor = $sonmp_ip->{$sonmp_key}; my $neighbor_port = $sonmp_port->{$sonmp_key}; print "Port : $port connected to $neighbor / $neighbor_port\n"; } =head1 DESCRIPTION SNMP::Info::SONMP is a subclass of SNMP::Info that provides an object oriented interface to the SynOptics Network Management Protocol (SONMP) information through SNMP. SONMP is a Layer 2 protocol that supplies topology information of devices that also speak SONMP, mostly switches and hubs. SONMP is implemented in SynOptics, Bay, Nortel, and Avaya devices. SONMP has been rebranded by Bay then Nortel and may be referred to by several different names, including Nortel Discovery Protocol (NDP). Create or use a device subclass that inherits this class. Do not use directly. Each device implements a subset of the global and cache entries. Check the return value to see if that data is held by the device. =head2 Inherited Classes None. =head2 Required MIBs =over =item F =item F =back =head1 GLOBAL METHODS These are methods that return scalar values from SNMP =over =item $sonmp->index_factor() Returns a number representing the number of ports reserved per slot or switch within the device MIB. Defaults to 32. =item $sonmp->slot_offset() Returns the offset if slot numbering does not start at 0. Defaults to 1. =item $sonmp->port_offset() Returns the offset if port numbering does not start at 0. Defaults to 0. =item $sonmp->hasSONMP() Is SONMP is active in this device? =item $sonmp->sonmp_gid() Returns the IP that the device is sending out for its Nmm topology info. (C) =item $sonmp->sonmp_run() Returns true if SONMP is on for this device. (C) =item $sonmp->mac() Returns MAC of the advertised IP address of this device. =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Layer2 Topology info (C) =over =item $sonmp->sonmp_topo_slot() Returns reference to hash. Key: Table entry, Value:slot number (C) =item $sonmp->sonmp_topo_port() Returns reference to hash. Key: Table entry, Value:Port Number (interface iid) (C) =item $sonmp->sonmp_topo_ip() Returns reference to hash. Key: Table entry, Value:Remote IP address of entry (C) =item $sonmp->sonmp_topo_seg() Returns reference to hash. Key: Table entry, Value:Remote Segment ID (C) =item $sonmp->sonmp_topo_mac() (C) Returns reference to hash. Key: Table entry, Value:Remote MAC address =item $sonmp->sonmp_topo_platform Returns reference to hash. Key: Table entry, Value:Remote Device Type (C) =item $sonmp->sonmp_topo_localseg Returns reference to hash. Key: Table entry, Value: Boolean, if bay_topo_seg() is local. (C) =back =head2 Layer2 Topology info (C) =over =item $sonmp->sonmp_topo_e_mac() (C) Returns reference to hash. Key: Table entry, Value:Remote MAC address =item $sonmp->sonmp_topo_e_platform Returns reference to hash. Key: Table entry, Value:Remote Device Type (C) =back =head2 Common topology information All entries with port=0 are local and ignored. =over =item $sonmp->sonmp_if() Returns reference to hash. Key: IID, Value: Local port (interfaces) =item $sonmp->sonmp_ip() Returns reference to hash. Key: IID, Value: Remote IP address If multiple entries exist with the same local port, sonmp_if(), with different IPv4 addresses, sonmp_ip(), there is either a non SONMP device in between two or more devices or multiple devices which are not directly connected. Use the data from the Layer2 Topology Table below to dig deeper. =item $sonmp->sonmp_port() Returns reference to hash. Key: IID, Value: Remote port (interfaces) =item $sonmp->sonmp_platform() Returns reference to hash. Key: IID, Value: Remote device type =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer1000755000765000024 013215550564 16263 5ustar00oliverstaff000000000000SNMP-Info-3.39/lib/SNMP/Info/Layer1/Allied.pm000444000765000024 1263713215550564 20201 0ustar00oliverstaff000000000000# SNMP::Info::Layer1::Allied # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer1::Allied; use strict; use Exporter; use SNMP::Info::Layer1; @SNMP::Info::Layer1::Allied::ISA = qw/SNMP::Info::Layer1 Exporter/; @SNMP::Info::Layer1::Allied::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; # Set for No CDP %GLOBALS = ( %SNMP::Info::Layer1::GLOBALS, 'root_ip' => 'actualIPAddr', ); %FUNCS = ( %SNMP::Info::Layer1::FUNCS, 'ati_p_name' => 'portName', 'ati_up' => 'linkTestLED', ); %MIBS = ( %SNMP::Info::Layer1::MIBS, 'ATI-MIB' => 'atiPortGroupIndex' ); %MUNGE = ( %SNMP::Info::Layer1::MUNGE, ); sub vendor { return 'allied'; } sub os { return 'allied'; } sub os_ver { my $allied = shift; my $descr = $allied->description(); if ( $descr =~ m/version (\d+\.\d+)/ ) { return $1; } } sub model { my $allied = shift; my $desc = $allied->description(); if ( $desc =~ /(AT-\d{4}\S{1})/ ) { return $1; } return; } sub i_name { my $allied = shift; my $partial = shift; my $i_name = $allied->orig_i_name($partial) || {}; my $ati_p_name = $allied->ati_p_name($partial) || {}; foreach my $port ( keys %$ati_p_name ) { my $name = $ati_p_name->{$port}; $i_name->{$port} = $name if ( defined $name and $name !~ /^\s*$/ ); } return $i_name; } sub i_up { my $allied = shift; my $partial = shift; my $i_up = SNMP::Info::Layer1::i_up( $allied, $partial ); my $ati_up = $allied->ati_up($partial) || {}; foreach my $port ( keys %$ati_up ) { my $up = $ati_up->{$port}; $i_up->{$port} = 'down' if $up eq 'linktesterror'; $i_up->{$port} = 'up' if $up eq 'nolinktesterror'; } return $i_up; } 1; __END__ =head1 NAME SNMP::Info::Layer1::Allied - SNMP Interface to old Allied Hubs =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $allied = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myhub', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $allied->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Allied device through SNMP. See inherited classes' documentation for inherited methods. =head2 Inherited Classes =over =item SNMP::Info::Layer1 =back =head2 Required MIBs =over =item F =back =head2 Inherited MIBs See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $allied->vendor() Returns 'allied' :) =item $allied->os() Returns 'allied' =item $allied->os_ver() Culls Version from description() =item $allied->root_ip() Returns IP Address of Managed Hub. (C) =item $allied->model() Tries to cull out C out of the description field. =back =head2 Global Methods imported from SNMP::Info::Layer1 See L for details. =head1 TABLE METHODS =head2 Overrides =over =item $allied->i_name() Returns reference to map of IIDs to human-set port name. =item $allied->i_up() Returns reference to map of IIDs to link status. Changes the values of ati_up() to 'up' and 'down'. =back =head2 Allied MIB =over =item $allied->ati_p_name() (C) =item $allied->ati_up() (C) =back =head2 Table Methods imported from SNMP::Info::Layer1 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer1/Asante.pm000444000765000024 1413013215550564 20210 0ustar00oliverstaff000000000000# SNMP::Info::Layer1::Asante # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer1::Asante; use strict; use Exporter; use SNMP::Info::Layer1; @SNMP::Info::Layer1::Asante::ISA = qw/SNMP::Info::Layer1 Exporter/; @SNMP::Info::Layer1::Asante::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; # Set for No CDP %GLOBALS = ( %SNMP::Info::Layer1::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer1::FUNCS, 'asante_port' => 'ePortIndex', 'asante_group' => 'ePortGrpIndex', 'i_type' => 'ePortGrpIndex', 'asante_up' => 'ePortStateLinkStatus', ); %MIBS = ( %SNMP::Info::Layer1::MIBS, 'ASANTE-AH1012-MIB' => 'asante' ); %MUNGE = ( %SNMP::Info::Layer1::MUNGE, ); sub interfaces { my $asante = shift; my $partial = shift; my $rptr_port = $asante->rptr_port($partial) || {}; my %interfaces; foreach my $port ( keys %$rptr_port ) { $interfaces{$port} = $port; } return \%interfaces; } sub os { return 'asante'; } sub os_ver { my $asante = shift; my $descr = $asante->description(); if ( $descr =~ /software v(\d+\.\d+)/ ) { return $1; } } sub vendor { return 'asante'; } sub model { my $asante = shift; my $id = $asante->id(); my $model = &SNMP::translateObj($id); return $model; } sub i_up { my $asante = shift; my $partial = shift; my $asante_up = $asante->asante_up($partial) || {}; my $i_up = {}; foreach my $port ( keys %$asante_up ) { my $up = $asante_up->{$port}; $i_up->{$port} = 'down' if $up =~ /on/; $i_up->{$port} = 'up' if $up =~ /off/; } return $i_up; } sub i_speed { my $asante = shift; my $partial = shift; my $i_speed = $asante->orig_i_speed($partial) || {}; my %i_speed; $i_speed{"1.2"} = $i_speed->{1}; return \%i_speed; } sub i_mac { my $asante = shift; my $partial = shift; my $i_mac = $asante->orig_i_mac($partial) || {}; my %i_mac; $i_mac{"1.2"} = $i_mac->{1}; return \%i_mac; } sub i_description { return; } sub i_name { my $asante = shift; my $partial = shift; my $i_name = $asante->orig_i_descr($partial) || {}; my %i_name; $i_name{"1.2"} = $i_name->{1}; return \%i_name; } 1; __END__ =head1 NAME SNMP::Info::Layer1::Asante - SNMP Interface to old Asante 1012 Hubs =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $asante = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $asante->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Asante device through SNMP. =head2 Inherited Classes =over =item SNMP::Info::Layer1 =back =head2 Required MIBs =over =item F =back =head2 Inherited MIBs See L for its MIB requirements. =head1 GLOBALS =head2 Overrides =over =item $asante->os() Returns 'asante' =item $asante->os_ver() Culls software version from description() =item $asante->vendor() Returns 'asante' :) =item $asante->model() Cross references $asante->id() to the F and returns the results. =back =head2 Global Methods imported from SNMP::Info::Layer1 See L for details. =head1 TABLE METHODS =head2 Overrides =over =item $asante->interfaces() Returns reference to the map between IID and physical Port. =item $asante->i_description() Description of the interface. =item $asante->i_mac() MAC address of the interface. Note this is just the MAC of the port, not anything connected to it. =item $asante->i_name() Returns reference to map of IIDs to human-set port name. =item $asante->i_up() Returns reference to map of IIDs to link status. Changes the values of asante_up() to 'up' and 'down'. =item $asante->i_speed() Speed of the link, human format. =back =head2 Asante MIB =over =item $asante->ati_p_name() (C) =item $asante->ati_up() (C) =back =head2 Table Methods imported from SNMP::Info::Layer1 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer1/Bayhub.pm000444000765000024 4145413215550564 20220 0ustar00oliverstaff000000000000# SNMP::Info::Layer1::Bayhub # $Id$ # # Copyright (c) 2008 Eric Miller, Max Baker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer1::Bayhub; use strict; use Exporter; use SNMP::Info::SONMP; use SNMP::Info::NortelStack; use SNMP::Info::Layer2; @SNMP::Info::Layer1::Bayhub::ISA = qw/SNMP::Info::SONMP SNMP::Info::NortelStack SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer1::Bayhub::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::NortelStack::MIBS, %SNMP::Info::SONMP::MIBS, 'S5-ETHERNET-COMMON-MIB' => 's5EnPortTable', 'S5-COMMON-STATS-MIB' => 's5CmStat', ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::NortelStack::GLOBALS, %SNMP::Info::SONMP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::NortelStack::FUNCS, %SNMP::Info::SONMP::FUNCS, # S5-ETHERNET-COMMON-MIB::s5EnPortTable 'bayhub_pb_index' => 's5EnPortBrdIndx', 'bayhub_pp_index' => 's5EnPortIndx', 'bayhub_up_admin' => 's5EnPortPartStatus', 'bayhub_up' => 's5EnPortLinkStatus', # S5-ETHERNET-COMMON-MIB::s5EnPortExtTable 'bayhub_p_speed' => 's5EnPortExtActiveSpeed', 'bayhub_p_cap' => 's5EnPortExtHwCapability', 'bayhub_p_adv' => 's5EnPortExtAutoNegAdv', # S5-COMMON-STATS-MIB::s5CmSNodeTable 'bayhub_nb_index' => 's5CmSNodeBrdIndx', 'bayhub_np_index' => 's5CmSNodePortIndx', 'fw_mac' => 's5CmSNodeMacAddr', ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::NortelStack::MUNGE, %SNMP::Info::SONMP::MUNGE, ); sub layers { return '00000011'; } sub os { return 'bay_hub'; } sub vendor { return 'avaya'; } sub model { my $bayhub = shift; my $id = $bayhub->id(); return unless defined $id; my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^sreg-//i; return 'Baystack Hub' if ( $model =~ /BayStack/ ); return '5000' if ( $model =~ /5000/ ); return '5005' if ( $model =~ /5005/ ); return $model; } # Hubs do not support ifMIB requirements for get MAC # and port status sub i_index { my $bayhub = shift; my $partial = shift; my $b_index = $bayhub->bayhub_pb_index($partial) || {}; my $p_index = $bayhub->bayhub_pp_index($partial) || {}; my $model = $bayhub->model() || 'Baystack Hub'; my %i_index; foreach my $iid ( keys %$b_index ) { my $board = $b_index->{$iid}; next unless defined $board; my $port = $p_index->{$iid} || 0; if ( $model eq 'Baystack Hub' ) { my $comidx = $board; if ( !( $comidx % 5 ) ) { $board = ( $board / 5 ); } elsif ( $comidx =~ /[16]$/ ) { $board = int( $board / 5 ); $port = 25; } elsif ( $comidx =~ /[27]$/ ) { $board = int( $board / 5 ); $port = 26; } } my $index = ( $board * 256 ) + $port; $i_index{$iid} = $index; } return \%i_index; } # Partials don't really help in this class, but implemented # for consistency sub interfaces { my $bayhub = shift; my $partial = shift; my $i_index = $bayhub->i_index() || {}; my %if; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); # Index numbers are deterministic slot * 256 + port my $port = $index % 256; my $slot = int( $index / 256 ); my $slotport = "$slot.$port"; $if{$index} = $slotport; } return \%if; } sub i_duplex { my $bayhub = shift; my $partial = shift; my $port_index = $bayhub->i_index() || {}; my %i_duplex; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $duplex = 'half'; $i_duplex{$index} = $duplex; } return \%i_duplex; } sub i_duplex_admin { my $bayhub = shift; my $partial = shift; my $port_index = $bayhub->i_index() || {}; my %i_duplex_admin; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $duplex = 'half'; $i_duplex_admin{$index} = $duplex; } return \%i_duplex_admin; } sub i_speed { my $bayhub = shift; my $partial = shift; my $port_index = $bayhub->i_index() || {}; my $port_speed = $bayhub->bayhub_p_speed() || {}; my %i_speed; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $speed = $port_speed->{$iid} || '10 Mbps'; $speed = '10 Mbps' if $speed =~ /bps10M/i; $speed = '100 Mbps' if $speed =~ /bps100M/i; $i_speed{$index} = $speed; } return \%i_speed; } sub i_up { my $bayhub = shift; my $partial = shift; my $port_index = $bayhub->i_index() || {}; my $link_stat = $bayhub->bayhub_up() || {}; my %i_up; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $link_stat = $link_stat->{$iid}; next unless defined $link_stat; $link_stat = 'up' if $link_stat =~ /on/i; $link_stat = 'down' if $link_stat =~ /off/i; $i_up{$index} = $link_stat; } return \%i_up; } sub i_up_admin { my $bayhub = shift; my $partial = shift; my $i_index = $bayhub->i_index() || {}; my $link_stat = $bayhub->bayhub_up_admin() || {}; my %i_up_admin; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $link_stat = $link_stat->{$iid}; next unless defined $link_stat; $i_up_admin{$index} = $link_stat; } return \%i_up_admin; } sub set_i_up_admin { # map setting to those the hub will understand my %setting = qw/up 2 down 3/; my $bayhub = shift; my ( $setting, $iid ) = @_; my $i_index = $bayhub->i_index() || {}; my %reverse_i_index = reverse %$i_index; $setting = lc($setting); return 0 unless defined $setting{$setting}; $iid = $reverse_i_index{$iid}; return $bayhub->set_bayhub_up_admin( $setting{$setting}, $iid ); } # Hubs do not support the standard Bridge MIB sub bp_index { my $bayhub = shift; my $partial = shift; my $b_index = $bayhub->bayhub_nb_index() || {}; my $p_index = $bayhub->bayhub_np_index() || {}; my $model = $bayhub->model() || 'Baystack Hub'; my %bp_index; foreach my $iid ( keys %$b_index ) { my $board = $b_index->{$iid}; next unless defined $board; my $port = $p_index->{$iid} || 0; if ( $model eq 'Baystack Hub' ) { my $comidx = $board; if ( !( $comidx % 5 ) ) { $board = ( $board / 5 ); } elsif ( $comidx =~ /[16]$/ ) { $board = int( $board / 5 ); $port = 25; } elsif ( $comidx =~ /[27]$/ ) { $board = int( $board / 5 ); $port = 26; } } my $index = ( $board * 256 ) + $port; next if ( defined $partial and $index !~ /^$partial$/ ); $bp_index{$index} = $index; } return \%bp_index; } sub fw_mac { my $bayhub = shift; my $partial = shift; return $bayhub->SUPER::fw_mac($partial); } sub fw_port { my $bayhub = shift; my $partial = shift; my $b_index = $bayhub->bayhub_nb_index($partial) || {}; my $p_index = $bayhub->bayhub_np_index($partial) || {}; my $model = $bayhub->model() || 'Baystack Hub'; my %fw_port; foreach my $iid ( keys %$b_index ) { my $board = $b_index->{$iid}; next unless defined $board; my $port = $p_index->{$iid} || 0; if ( $model eq 'Baystack Hub' ) { my $comidx = $board; if ( !( $comidx % 5 ) ) { $board = ( $board / 5 ); } elsif ( $comidx =~ /[16]$/ ) { $board = int( $board / 5 ); $port = 25; } elsif ( $comidx =~ /[27]$/ ) { $board = int( $board / 5 ); $port = 26; } } my $index = ( $board * 256 ) + $port; $fw_port{$iid} = $index; } return \%fw_port; } sub index_factor { return 256; } sub slot_offset { return 0; } # Devices do not support ENTITY-MIB use proprietary methods. sub e_index { my $stack = shift; my $partial = shift; return $stack->ns_e_index($partial); } sub e_class { my $stack = shift; my $partial = shift; return $stack->ns_e_class($partial); } sub e_descr { my $stack = shift; my $partial = shift; return $stack->ns_e_descr($partial); } sub e_name { my $stack = shift; my $partial = shift; return $stack->ns_e_name($partial); } sub e_fwver { my $stack = shift; my $partial = shift; return $stack->ns_e_fwver($partial); } sub e_hwver { my $stack = shift; my $partial = shift; return $stack->ns_e_hwver($partial); } sub e_parent { my $stack = shift; my $partial = shift; return $stack->ns_e_parent($partial); } sub e_pos { my $stack = shift; my $partial = shift; return $stack->ns_e_pos($partial); } sub e_serial { my $stack = shift; my $partial = shift; return $stack->ns_e_serial($partial); } sub e_swver { my $stack = shift; my $partial = shift; return $stack->ns_e_swver($partial); } sub e_type { my $stack = shift; my $partial = shift; return $stack->ns_e_type($partial); } sub e_vendor { my $stack = shift; my $partial = shift; return $stack->ns_e_vendor($partial); } 1; __END__ =head1 NAME SNMP::Info::Layer1::Bayhub - SNMP Interface to Bay/Nortel/Avaya Hubs =head1 AUTHOR Eric Miller =head1 SYNOPSIS #Let SNMP::Info determine the correct subclass for you. my $bayhub = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $bayhub->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Bay hub device through SNMP. Also provides device MAC to port mapping through the proprietary MIB. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $bayhub = new SNMP::Info::Layer1::Bayhub(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2 =item SNMP::Info::NortelStack =item SNMP::Info::SONMP =back =head2 Required MIBs =over =item F =item F =back =head2 Inherited MIBs See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $bayhub->vendor() Returns 'avaya' =item $bayhub->os() Returns 'bay_hub' =item $bayhub->model() Cross references $bayhub->id() to the F and returns the results. Removes either Baystack Hub, 5000, or 5005 depending on the model. =back =head2 Overrides =over =item $bayhub->layers() Returns 00000011. Class emulates Layer 2 functionality through proprietary MIBs. =item $bayhub->index_factor() Required by SNMP::Info::SONMP. Number representing the number of ports reserved per slot within the device MIB. Returns 256. =item $bayhub->slot_offset() Required by SNMP::Info::SONMP. Offset if slot numbering does not start at 0. Returns 0. =back =head2 Globals imported from SNMP::Info::Layer2 See L for details. =head2 Global Methods imported from SNMP::Info::NortelStack See L for details. =head2 Global Methods imported from SNMP::Info::SONMP See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $bayhub->i_index() Returns reference to map of IIDs to Interface index. Since hubs do not support C, the interface index is created using the formula (board * 256 + port). =item $bayhub->interfaces() Returns reference to map of IIDs to physical ports. =item $bayhub->i_duplex() Returns half, hubs do not support full duplex. =item $bayhub->i_duplex_admin() Returns half, hubs do not support full duplex. =item $bayhub->i_speed() Returns interface speed. =item $bayhub->i_up() Returns (C) for each port. Translates on/off to up/down. =item $bayhub->i_up_admin() Returns (C) for each port. =item $bayhub->set_i_up_admin(state, ifIndex) Sets port state, must be supplied with state and port C State choices are 'up' or 'down' Example: my %if_map = reverse %{$bayhub->interfaces()}; $bayhub->set_i_up_admin('down', $if_map{'1.1'}) or die "Couldn't change port state. ",$bayhub->error(1); =item $bayhub->bp_index() Simulates bridge MIB by returning reference to a hash containing the index for both the keys and values. =item $bayhub->fw_port() Returns reference to map of IIDs of the C to the Interface index. =item $bayhub->fw_mac() (C) =back =head2 Pseudo F Information These devices do not support F. These methods emulate Physical Table methods using F. See L for details. =over =item $bayhub->e_index() Returns ns_e_index(). =item $bayhub->e_class() Returns ns_e_class(). =item $bayhub->e_descr() Returns ns_e_descr(). =item $bayhub->e_name() Returns ns_e_name(). =item $bayhub->e_fwver() Returns ns_e_fwver(). =item $bayhub->e_hwver() Returns ns_e_hwver(). =item $bayhub->e_parent() Returns ns_e_parent(). =item $bayhub->e_pos() Returns ns_e_pos(). =item $bayhub->e_serial() Returns ns_e_serial(). =item $bayhub->e_swver() Returns ns_e_swver(). =item $bayhub->e_type() Returns ns_e_type(). =item $bayhub->e_vendor() Returns ns_e_vendor(). =back =head2 Table Methods imported from SNMP::Info::Layer2 See L for details. =head2 Table Methods imported from SNMP::Info::NortelStack See L for details. =head2 Table Methods imported from SNMP::Info::SONMP See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer1/Cyclades.pm000444000765000024 2530713215550564 20534 0ustar00oliverstaff000000000000# SNMP::Info::Layer1::Cyclades # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer1::Cyclades; use strict; use Exporter; use SNMP::Info::Layer1; @SNMP::Info::Layer1::Cyclades::ISA = qw/SNMP::Info::Layer1 Exporter/; @SNMP::Info::Layer1::Cyclades::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer1::MIBS, 'CYCLADES-ACS-SYS-MIB' => 'cyACSversion', 'CYCLADES-ACS-CONF-MIB' => 'cyEthIPaddr', 'CYCLADES-ACS-INFO-MIB' => 'cyISPortTty', ); %GLOBALS = ( # CYCLADES-ACS-SYS-MIB %SNMP::Info::Layer1::GLOBALS, 'os_ver' => 'cyACSversion', 'cy_model' => 'cyACSpname', 'serial' => 'cyACSDevId', 'root_ip' => 'cyEthIPaddr', 'ps1_status' => 'cyACSPw1', 'ps2_status' => 'cyACSPw2', ); %FUNCS = ( %SNMP::Info::Layer1::FUNCS, # CYCLADES-ACS-INFO-MIB::cyInfoSerialTable 'cy_port_tty' => 'cyISPortTty', 'cy_port_name' => 'cyISPortName', 'cy_port_speed' => 'cyISPortSpeed', 'cy_port_cd' => 'cyISPortSigCD', # CYCLADES-ACS-CONF-MIB::cySerialPortTable 'cy_port_socket' => 'cySPortSocketPort', ); %MUNGE = ( %SNMP::Info::Layer1::MUNGE, ); # These devices don't have a FDB and we probably don't want to poll for ARP # cache so turn off reported L2/L3. sub layers { return '01000001'; } sub os { return 'cyclades'; } sub vendor { return 'cyclades'; } sub model { my $cyclades = shift; my $model = $cyclades->cy_model(); return unless defined $model; return lc($model); } # Extend interface methods to include serial ports # # Partials don't really help in this class, but implemented # for consistency sub i_index { my $cyclades = shift; my $partial = shift; my $orig_index = $cyclades->orig_i_index($partial) || {}; my $cy_index = $cyclades->cy_port_socket() || {}; my %i_index; foreach my $iid ( keys %$orig_index ) { my $index = $orig_index->{$iid}; next unless defined $index; $i_index{$iid} = $index; } # Use alternative labeling system for the serial port, listening socket # to avoid conflicts with ifIndex. foreach my $iid ( keys %$cy_index ) { my $index = $cy_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); $i_index{$index} = $index; } return \%i_index; } sub interfaces { my $cyclades = shift; my $partial = shift; my $i_descr = $cyclades->orig_i_description($partial) || {}; my $cy_index = $cyclades->cy_port_socket() || {}; my $cy_p_tty = $cyclades->cy_port_tty() || {}; my %if; foreach my $iid ( keys %$i_descr ) { my $descr = $i_descr->{$iid}; next unless defined $descr; $if{$iid} = $descr; } foreach my $iid ( keys %$cy_p_tty ) { my $index = $cy_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $name = $cy_p_tty->{$iid}; next unless defined $name; $if{$index} = $name; } return \%if; } sub i_speed { my $cyclades = shift; my $partial = shift; my $i_speed = $cyclades->orig_i_speed($partial) || {}; my $cy_index = $cyclades->cy_port_socket() || {}; my $cy_p_speed = $cyclades->cy_port_speed() || {}; my %i_speed; foreach my $iid ( keys %$i_speed ) { my $speed = $i_speed->{$iid}; next unless defined $speed; $i_speed{$iid} = $speed; } foreach my $iid ( keys %$cy_p_speed ) { my $index = $cy_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $speed = $cy_p_speed->{$iid}; next unless defined $speed; $i_speed{$index} = $speed; } return \%i_speed; } sub i_up { my $cyclades = shift; my $partial = shift; my $i_up = $cyclades->orig_i_up($partial) || {}; my $cy_index = $cyclades->cy_port_socket() || {}; my $cy_p_up = $cyclades->cy_port_cd() || {}; my %i_up; foreach my $iid ( keys %$i_up ) { my $up = $i_up->{$iid}; next unless defined $up; $i_up{$iid} = $up; } foreach my $iid ( keys %$cy_p_up ) { my $index = $cy_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $up = $cy_p_up->{$iid}; next unless defined $up; $i_up{$index} = $up; } return \%i_up; } sub i_description { my $cyclades = shift; my $partial = shift; my $i_desc = $cyclades->orig_i_description($partial) || {}; my $cy_index = $cyclades->cy_port_socket() || {}; my $cy_p_desc = $cyclades->cy_port_name() || {}; my %descr; foreach my $iid ( keys %$i_desc ) { my $desc = $i_desc->{$iid}; next unless defined $desc; $descr{$iid} = $desc; } foreach my $iid ( keys %$cy_p_desc ) { my $index = $cy_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $desc = $cy_p_desc->{$iid}; next unless defined $desc; $descr{$index} = $desc; } return \%descr; } sub i_name { my $cyclades = shift; my $partial = shift; my $i_name = $cyclades->orig_i_name($partial) || {}; my $cy_index = $cyclades->cy_port_socket() || {}; my $cy_p_desc = $cyclades->cy_port_name() || {}; my %i_name; foreach my $iid ( keys %$i_name ) { my $name = $i_name->{$iid}; next unless defined $name; $i_name{$iid} = $name; } foreach my $iid ( keys %$cy_p_desc ) { my $index = $cy_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $name = $cy_p_desc->{$iid}; next unless defined $name; $i_name{$index} = $name; } return \%i_name; } 1; __END__ =head1 NAME SNMP::Info::Layer1::Cyclades - SNMP Interface to Cyclades terminal servers =head1 AUTHOR Eric Miller =head1 SYNOPSIS #Let SNMP::Info determine the correct subclass for you. my $cyclades = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $cyclades->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Cyclades device through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $cyclades = new SNMP::Info::Layer1::Cyclades(...); =head2 Inherited Classes =over =item SNMP::Info::Layer1 =back =head2 Required MIBs =over =item F =item F =item F =back =head2 Inherited MIBs See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $cyclades->os_ver() (C) =item $cyclades->serial() (C) =item $cyclades->root_ip() (C) =item $cyclades->ps1_status() (C) =item $cyclades->ps2_status() (C) =back =head2 Overrides =over =item $cyclades->layers() Returns 01000001. These devices don't have a FDB and we probably don't want to poll for an ARP cache so turn off reported Layer 2 and Layer 3. =item $cyclades->vendor() Returns 'cyclades' =item $cyclades->os() Returns 'cyclades' =item $cyclades->model() Returns lower case (C) =back =head2 Globals imported from SNMP::Info::Layer1 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $cyclades->i_index() Returns reference to map of IIDs to Interface index. Extended to include serial ports. Serial ports are indexed with the alternative labeling system for the serial port, the listening socket port C to avoid conflicts with C. =item $cyclades->interfaces() Returns reference to map of IIDs to physical ports. Extended to include serial ports, C. =item $cyclades->i_speed() Returns interface speed. Extended to include serial ports, C. =item $cyclades->i_up() Returns link status for each port. Extended to include serial ports, C. =item $cyclades->i_description() Returns description of each port. Extended to include serial ports, C. =item $cyclades->i_name() Returns name of each port. Extended to include serial ports, C. =back =head2 Table Methods imported from SNMP::Info::Layer1 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer1/S3000.pm000444000765000024 3247313215550564 17514 0ustar00oliverstaff000000000000# SNMP::Info::Layer1::S3000 # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer1::S3000; use strict; use Exporter; use SNMP::Info::Layer2; @SNMP::Info::Layer1::S3000::ISA = qw/SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer1::S3000::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, 'SYNOPTICS-ETHERNET-MIB' => 's3EnetPortTable', 'SYNOPTICS-COMMON-MIB' => 's3AgentType', ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, # From SYNOPTICS-COMMON-MIB 'os_bin' => 's3AgentFwVer', 's3000_major_ver' => 's3AgentSwMajorVer', 's3000_minor_ver' => 's3AgentSwMinorVer', 's3000_maint_ver' => 's3AgentSwMaintVer', ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, # SYNOPTICS-ETHERNET-MIB::s3EnetPortTable 's3000_pb_index' => 's3EnetPortBoardIndex', 's3000_pp_index' => 's3EnetPortIndex', 's3000_up_admin' => 's3EnetPortPartStatus', 's3000_up' => 's3EnetPortLinkStatus', # SYNOPTICS-ETHERNET-MIB::s3EnetShowNodesTable 's3000_nb_index' => 's3EnetShowNodesSlotIndex', 's3000_np_index' => 's3EnetShowNodesPortIndex', 'fw_mac' => 's3EnetShowNodesMacAddress', # SYNOPTICS-ETHERNET-MIB::s3EnetTopNmmTable 's3000_topo_port' => 's3EnetTopNmmPort', 's3000_topo_mac' => 's3EnetTopNmmMacAddr', ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, 's3000_topo_mac' => \&SNMP::Info::munge_mac ); sub layers { return '00000011'; } sub os { return 'synoptics'; } sub vendor { return 'nortel'; } sub model { my $s3000 = shift; my $id = $s3000->id(); return unless defined $id; my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^s3reg-//i; return $1 if ( $model =~ /((\d+){3}[\dX])/ ); return $model; } sub os_ver { my $s3000 = shift; my $major_ver = $s3000->s3000_major_ver() || 0; my $minor_ver = $s3000->s3000_minor_ver() || 0; my $maint_ver = $s3000->s3000_maint_ver() || 0; my $ver = "$major_ver.$minor_ver.$maint_ver"; return $ver; } sub mac { my $s3000 = shift; my $topo_port = $s3000->s3000_topo_port(); my $topo_mac = $s3000->s3000_topo_mac(); foreach my $entry ( keys %$topo_port ) { my $port = $topo_port->{$entry}; next unless $port == 0; my $mac = $topo_mac->{$entry}; return $mac; } # Topology turned off, not supported. return; } # Hubs do not support ifMIB requirements for get MAC # and port status sub i_index { my $s3000 = shift; my $partial = shift; my $b_index = $s3000->s3000_pb_index($partial) || {}; my $p_index = $s3000->s3000_pp_index($partial) || {}; my %i_index; foreach my $iid ( keys %$b_index ) { my $board = $b_index->{$iid}; next unless defined $board; my $port = $p_index->{$iid} || 0; # We need to make up an index for multiple board instances. my $index = ( $board * 256 ) + $port; $i_index{$iid} = $index; } return \%i_index; } # Partials don't really help in this class, but implemented # for consistency sub interfaces { my $s3000 = shift; my $partial = shift; my $i_index = $s3000->i_index() || {}; my %if; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); # Index numbers are deterministic slot * 256 + port - see i_index() my $port = $index % 256; my $slot = int( $index / 256 ); my $slotport = "$slot.$port"; $if{$index} = $slotport; } return \%if; } sub i_duplex { my $s3000 = shift; my $partial = shift; my $port_index = $s3000->i_index() || {}; my %i_duplex; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); # Hubs only function half duplex my $duplex = 'half'; $i_duplex{$index} = $duplex; } return \%i_duplex; } sub i_duplex_admin { my $s3000 = shift; my $partial = shift; my $port_index = $s3000->i_index() || {}; my %i_duplex_admin; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); # Hubs only function half duplex my $duplex = 'half'; $i_duplex_admin{$index} = $duplex; } return \%i_duplex_admin; } sub i_speed { my $s3000 = shift; my $partial = shift; my $port_index = $s3000->i_index() || {}; my %i_speed; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); # These hubs only support 10 Mbs my $speed = '10000000'; $i_speed{$index} = $speed; } return \%i_speed; } sub i_up { my $s3000 = shift; my $partial = shift; my $port_index = $s3000->i_index() || {}; my $link_stat = $s3000->s3000_up() || {}; my %i_up; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $link_stat = $link_stat->{$iid}; next unless defined $link_stat; $link_stat = 'up' if $link_stat =~ /on/i; $link_stat = 'down' if $link_stat =~ /off/i; $i_up{$index} = $link_stat; } return \%i_up; } sub i_up_admin { my $s3000 = shift; my $partial = shift; my $i_index = $s3000->i_index() || {}; my $link_stat = $s3000->s3000_up_admin() || {}; my %i_up_admin; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; next if ( defined $partial and $index !~ /^$partial$/ ); my $link_stat = $link_stat->{$iid}; next unless defined $link_stat; $i_up_admin{$index} = $link_stat; } return \%i_up_admin; } sub set_i_up_admin { # map setting to those the hub will understand my %setting = qw/up 2 down 3/; my $s3000 = shift; my ( $setting, $iid ) = @_; my $i_index = $s3000->i_index() || {}; my %reverse_i_index = reverse %$i_index; $setting = lc($setting); return 0 unless defined $setting{$setting}; $iid = $reverse_i_index{$iid}; return $s3000->set_s3000_up_admin( $setting{$setting}, $iid ); } # Hubs do not support the standard Bridge MIB sub bp_index { my $s3000 = shift; my $partial = shift; my $b_index = $s3000->s3000_nb_index() || {}; my $p_index = $s3000->s3000_np_index() || {}; my $model = $s3000->model(); my %bp_index; foreach my $iid ( keys %$b_index ) { my $board = $b_index->{$iid}; next unless defined $board; my $port = $p_index->{$iid} || 0; my $index = ( $board * 256 ) + $port; next if ( defined $partial and $index !~ /^$partial$/ ); $bp_index{$index} = $index; } return \%bp_index; } sub fw_mac { my $s3000 = shift; my $partial = shift; return $s3000->SUPER::fw_mac($partial); } sub fw_port { my $s3000 = shift; my $partial = shift; my $b_index = $s3000->s3000_nb_index($partial) || {}; my $p_index = $s3000->s3000_np_index($partial) || {}; my $model = $s3000->model(); my %fw_port; foreach my $iid ( keys %$b_index ) { my $board = $b_index->{$iid}; next unless defined $board; my $port = $p_index->{$iid} || 0; my $index = ( $board * 256 ) + $port; $fw_port{$iid} = $index; } return \%fw_port; } 1; __END__ =head1 NAME SNMP::Info::Layer1::S3000 - SNMP Interface to Synoptics / Nortel Hubs =head1 AUTHOR Eric Miller =head1 SYNOPSIS #Let SNMP::Info determine the correct subclass for you. my $s3000 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $s3000->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Bay hub device through SNMP. Also provides device MAC to port mapping through the proprietary MIB. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $s3000 = new SNMP::Info::Layer1::S3000(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item F =item F =back =head2 Inherited MIBs See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $s3000->vendor() Returns 'nortel' =item $s3000->os() Returns 'synoptics' =item $s3000->model() Cross references $s3000->id() to the F and returns the results. Removes C from the model name and returns only the numeric model identifier. =item $stack->os_ver() Returns the software version specified as major.minor.maint. (C).(C).(C) =item $stack->os_bin() Returns the firmware version. (C) =item $s3000->mac() Returns MAC of the advertised IP address of the device. =back =head2 Overrides =over =item $s3000->layers() Returns 00000011. Class emulates Layer 2 functionality through proprietary MIBs. =back =head2 Globals imported from SNMP::Info::Layer2 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $s3000->i_index() Returns reference to map of IIDs to Interface index. Since hubs do not support C, the interface index is created using the formula (board * 256 + port). This is required to support devices with more than one module. =item $s3000->interfaces() Returns reference to map of IIDs to physical ports. =item $s3000->i_duplex() Returns half, hubs do not support full duplex. =item $s3000->i_duplex_admin() Returns half, hubs do not support full duplex. =item $s3000->i_speed() Returns 10000000. The hubs only support 10 Mbs Ethernet. =item $s3000->i_up() Returns (C) for each port. Translates on/off to up/down. =item $s3000->i_up_admin() Returns (C) for each port. =item $s3000->set_i_up_admin(state, ifIndex) Sets port state, must be supplied with state and port C State choices are 'up' or 'down' Example: my %if_map = reverse %{$s3000->interfaces()}; $s3000->set_i_up_admin('down', $if_map{'1.1'}) or die "Couldn't change port state. ",$s3000->error(1); =item $s3000->bp_index() Simulates bridge MIB by returning reference to a hash containing the index for both the keys and values. =item $s3000->fw_port() Returns reference to map of IIDs of the C to the Interface index. =item $s3000->fw_mac() (C) =item $s3000->s3000_topo_port() Returns reference to hash. Key: Table entry, Value:Port Number (interface iid) (C) =item $s3000->s3000_topo_mac() (C) Returns reference to hash. Key: Table entry, Value:Remote MAC address =back =head2 Table Methods imported from SNMP::Info::Layer2 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2000755000765000024 013215550564 16264 5ustar00oliverstaff000000000000SNMP-Info-3.39/lib/SNMP/Info/Layer2/3Com.pm000444000765000024 606013215550564 17562 0ustar00oliverstaff000000000000package SNMP::Info::Layer2::3Com; use strict; use Exporter; use SNMP::Info::Layer2; use SNMP::Info::LLDP; use SNMP::Info::CDP; @SNMP::Info::Layer2::3Com::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::3Com::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::LLDP::MIBS, %SNMP::Info::Layer2::MIBS, 'A3Com-products-MIB' => 'wlanAP7760', ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::LLDP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub os { return '3Com'; } sub serial { my $dev = shift; my $e_serial = $dev->e_serial(); # Find entity table entry for this unit foreach my $e ( sort keys %$e_serial ) { if (defined $e_serial->{$e} and $e_serial->{$e} !~ /^\s*$/) { return $e_serial->{$e}; } } } sub os_ver { my $dev = shift; my $e_swver = $dev->e_swver(); # Find entity table entry for this unit foreach my $e ( sort keys %$e_swver ) { if (defined $e_swver->{$e} and $e_swver->{$e} !~ /^\s*$/) { return $e_swver->{$e}; } } } sub vendor { return '3Com'; } sub model { my $dsmodel = shift; my $descr = $dsmodel->description(); if ( $descr =~ /^([\S ]+) Software.*/){ return $1; } } 1; __END__ =head1 NAME SNMP::Info::Layer2::3Com - SNMP Interface to L2 3Com Switches =head1 AUTHOR Max Kosmach =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $router = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $router->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for 3Com L2 devices =head2 Inherited Classes =over =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $device->vendor() Returns '3Com' =item $device->os() Returns '3Com' =item $device->os_ver() Return os version =item $device->model() Returns device model extracted from description =item $device->serial() Returns serial number =back =head2 Globals imported from SNMP::Info::Layer2 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Airespace.pm000444000765000024 2270313215550564 20677 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Airespace # # Copyright (c) 2008 Eric Miller # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Airespace; use strict; use Exporter; use SNMP::Info::Bridge; use SNMP::Info::CDP; use SNMP::Info::Airespace; @SNMP::Info::Layer2::Airespace::ISA = qw/SNMP::Info::Airespace SNMP::Info::CDP SNMP::Info::Bridge Exporter/; @SNMP::Info::Layer2::Airespace::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::Bridge::MIBS, %SNMP::Info::CDP::MIBS, %SNMP::Info::Airespace::MIBS, 'CISCO-LWAPP-DOT11-CLIENT-MIB' => 'cldcClientCurrentTxRateSet', 'CISCO-LWAPP-DOT11-MIB' => 'cldHtDot11nChannelBandwidth', 'CISCO-LWAPP-AP-MIB' => 'cLApIfMacAddress', ); %GLOBALS = ( %SNMP::Info::GLOBALS, %SNMP::Info::Bridge::GLOBALS, %SNMP::Info::CDP::GLOBALS, %SNMP::Info::Airespace::GLOBALS, ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::Bridge::FUNCS, %SNMP::Info::CDP::FUNCS, %SNMP::Info::Airespace::FUNCS, # CISCO-LWAPP-AP-MIB::cLApTable 'ap_if_mac' => 'cLApIfMacAddress', # CISCO-LWAPP-DOT11-CLIENT-MIB::cldcClientTable 'client_txrate' => 'cldcClientCurrentTxRateSet', 'cd11_proto' => 'cldcClientProtocol', 'cd11_rateset' => 'cldcClientDataRateSet', # CISCO-LWAPP-DOT11-MIB::cldHtMacOperationsTable 'cd11n_ch_bw' => 'cldHtDot11nChannelBandwidth', ); %MUNGE = ( %SNMP::Info::MUNGE, %SNMP::Info::Bridge::MUNGE, %SNMP::Info::CDP::MUNGE, %SNMP::Info::Airespace::MUNGE, 'ap_if_mac' => \&SNMP::Info::munge_mac, 'cd11n_ch_bw' => \&munge_cd11n_ch_bw, 'cd11_rateset' => \&munge_cd11_rateset, 'cd11_proto' => \&munge_cd11_proto, ); # 802.11n Modulation and Coding Scheme (MCS) my $mcs_index = { 20 => { m0 => '6.5', m1 => '13', m2 => '19.5', m3 => '26', m4 => '39', m5 => '52', m6 => '58.5', m7 => '65', m8 => '13', m9 => '26', m10 => '39', m11 => '52', m12 => '78', m13 => '104', m14 => '117', m15 => '130', m16 => '19.5', m17 => '39', m18 => '58.5', m19 => '78', m20 => '117', m21 => '156', m22 => '175.5', m23 => '195', # This is a cheat for 802.11a bonded m108 => '108', }, 40 => { m0 => '15', m1 => '30', m2 => '45', m3 => '60', m4 => '90', m5 => '120', m6 => '135', m7 => '157.5', m8 => '30', m9 => '60', m10 => '90', m11 => '120', m12 => '180', m13 => '240', m14 => '270', m15 => '300', m16 => '45', m17 => '90', m18 => '135', m19 => '180', m20 => '270', m21 => '360', m22 => '405', m23 => '450', } }; sub os { return 'cisco'; } sub vendor { return 'cisco'; } sub model { my $airespace = shift; my $model = $airespace->airespace_model(); return unless defined $model; return $model; } sub cd11_mac { my $airespace = shift; my $cd11_sigstrength = $airespace->cd11_sigstrength(); my $ret = {}; foreach my $idx ( keys %$cd11_sigstrength ) { my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); $ret->{$idx} = $mac } return $ret; } sub cd11_txrate { my $airespace = shift; my $rates = $airespace->client_txrate() || {}; my $protos = $airespace->cd11_proto() || {}; my $bws = $airespace->cd11n_ch_bw() || {}; my $cd11_txrate = {}; foreach my $idx ( keys %$rates ) { my $rate = $rates->{$idx} || '0.0'; if ( $rate =~ /^\d+/ ) { $cd11_txrate->{$idx} = [ $rate * 1.0 ]; } elsif ( $rate =~ /^m/ ) { my $band = $protos->{$idx}; my $bw = $bws->{$band}; # FIXME throw some kind of error if we get an index/rate that we haven't implemented yet? Now we simply return "0.0"... $cd11_txrate->{$idx} = [ $mcs_index->{$bw}->{$rate} || '0.0' ]; } else { $cd11_txrate->{$idx} = [ $rate ]; } } return $cd11_txrate; } sub munge_cd11n_ch_bw { my $bw = shift; if ( $bw =~ /forty/ ) { return 40; } return 20; } sub munge_cd11_proto { my $bw = shift; return 2 if ( $bw eq 'dot11n5' ); return 1; } sub munge_cd11_rateset { my $rates = shift; return [ map { $_ * 1.0 } split /,/, $rates ]; } # Cisco provides the AP's Ethernet MAC via # CISCO-LWAPP-AP-MIB::cLApIfMacAddress this was not available pre-Cisco sub i_mac { my $airespace = shift; my $partial = shift; my $i_index = $airespace->i_index($partial) || {}; my $ap_mac = $airespace->ap_if_mac() || {}; my $i_mac = $airespace->SUPER::i_mac() || {}; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { $index =~ s/\.\d+$//; next unless defined $index; my $sys_mac = join( '.', map { hex($_) } split( ':', $index ) ); my $mac = $ap_mac->{$sys_mac}; $i_mac->{$iid} = $mac; } } return $i_mac; } 1; __END__ =head1 NAME SNMP::Info::Layer2::Airespace - SNMP Interface to Cisco (Airespace) Wireless Controllers =head1 AUTHOR Eric Miller =head1 SYNOPSIS #Let SNMP::Info determine the correct subclass for you. my $airespace = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $airespace->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from Cisco (Airespace) Wireless Controllers through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $airespace = new SNMP::Info::Layer2::Airespace(...); =head2 Inherited Classes =over =item SNMP::Info::Airespace =item SNMP::Info::CDP =item SNMP::Info::Bridge =back =head2 Required MIBs =over =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $airespace->vendor() Returns 'cisco' =item $airespace->os() Returns 'cisco' =item $airespace->model() (C) =back =head2 Global Methods imported from SNMP::Info::Airespace See documentation in L for details. =head2 Global Methods imported from SNMP::Info::CDP See documentation in L for details. =head2 Globals imported from SNMP::Info::Bridge See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item cd11_mac() Returns client radio interface MAC addresses. =item cd11_txrate() Returns client transmission speed in Mbs. =back =head2 Overrides =over =item i_mac() Adds AP Ethernet MAC as port mac on radio ports from C. =back =head2 Table Methods imported from SNMP::Info::Airespace See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Bridge See documentation in L for details. =head1 Data Munging Callback Subroutines =over =item munge_cd11n_ch_bw() Converts 802.11n channel bandwidth to either 20 or 40. =item munge_cd11_proto() Converts 802.11n 2.4Ghz to 1 and 5Ghz to 2 to correspond to the (C) index. =item munge_cd11_rateset() Converts rate set to array. =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Aironet.pm000444000765000024 4502513215550564 20406 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Aironet # $Id$ # # Copyright (c) 2008-2009 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Aironet; use strict; use Exporter; use SNMP::Info::Layer2; use SNMP::Info::Entity; use SNMP::Info::EtherLike; use SNMP::Info::CiscoStats; use SNMP::Info::CiscoConfig; use SNMP::Info::CDP; use SNMP::Info::IEEE802dot11; @SNMP::Info::Layer2::Aironet::ISA = qw/SNMP::Info::Layer2 SNMP::Info::Entity SNMP::Info::EtherLike SNMP::Info::CiscoStats SNMP::Info::CiscoConfig SNMP::Info::CDP Exporter/; @SNMP::Info::Layer2::Aironet::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %GLOBALS = ( %SNMP::Info::IEEE802dot11::GLOBALS, %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::Entity::GLOBALS, %SNMP::Info::EtherLike::GLOBALS, %SNMP::Info::CiscoStats::GLOBALS, %SNMP::Info::CiscoConfig::GLOBALS, %SNMP::Info::CDP::GLOBALS, 'serial' => 'entPhysicalSerialNum.1', 'descr' => 'sysDescr', 'ps1_type' => 'cpoePdCurrentPowerSource' ); %FUNCS = ( %SNMP::Info::IEEE802dot11::FUNCS, %SNMP::Info::Layer2::FUNCS, %SNMP::Info::Entity::FUNCS, %SNMP::Info::EtherLike::FUNCS, %SNMP::Info::CiscoStats::FUNCS, %SNMP::Info::CiscoConfig::FUNCS, %SNMP::Info::CDP::FUNCS, 'i_80211channel' => 'cd11IfPhyDsssCurrentChannel', 'c_dot11subif' => 'cDot11ClientSubIfIndex', 'cd11_rateset' => 'cDot11ClientDataRateSet', 'cd11_txrate' => 'cDot11ClientCurrentTxRateSet', 'cd11_uptime' => 'cDot11ClientUpTime', 'cd11_sigstrength' => 'cDot11ClientSignalStrength', 'cd11_sigqual' => 'cDot11ClientSigQuality', 'cd11_rxpkt' => 'cDot11ClientPacketsReceived', 'cd11_txpkt' => 'cDot11ClientPacketsSent', 'cd11_rxbyte' => 'cDot11ClientBytesReceived', 'cd11_txbyte' => 'cDot11ClientBytesSent', 'mbss_mac_addr' => 'cdot11MbssidIfMacAddress', ); %MIBS = ( %SNMP::Info::IEEE802dot11::MIBS, %SNMP::Info::Layer2::MIBS, %SNMP::Info::Entity::MIBS, %SNMP::Info::EtherLike::MIBS, %SNMP::Info::CiscoStats::MIBS, %SNMP::Info::CiscoConfig::MIBS, %SNMP::Info::CDP::MIBS, 'CISCO-DOT11-IF-MIB' => 'cd11IfAuxSsid', 'CISCO-DOT11-ASSOCIATION-MIB' => 'cDot11ClientSubIfIndex', 'CISCO-DOT11-SSID-SECURITY-MIB' => 'cdot11SecVlanNameId', 'CISCO-VLAN-IFTABLE-RELATIONSHIP-MIB' => 'cviRoutedVlanIfIndex', 'CISCO-POE-PD-MIB' => 'cpoePdCurrentPowerSource', ); %MUNGE = ( %SNMP::Info::IEEE802dot11::MUNGE, %SNMP::Info::Layer2::MUNGE, %SNMP::Info::Entity::MUNGE, %SNMP::Info::EtherLike::MUNGE, %SNMP::Info::CiscoStats::MUNGE, %SNMP::Info::CiscoConfig::MUNGE, %SNMP::Info::CDP::MUNGE, 'cd11_txrate' => \&munge_cd11_txrate, 'cd11_rateset' => \&munge_cd11_txrate, 'mbss_mac_addr' => \&SNMP::Info::munge_mac, ); # Use 802.11 power level without putting IEEE802dot11 in @ISA *SNMP::Info::Layer2::Aironet::dot11_cur_tx_pwr_mw = \&SNMP::Info::IEEE802dot11::dot11_cur_tx_pwr_mw; sub vendor { # Sorry, but it's true. return 'cisco'; } sub interfaces { my $aironet = shift; my $partial = shift; my $i_description = $aironet->i_description($partial); return $i_description; } # Tag on e_descr.1 sub description { my $aironet = shift; my $descr = $aironet->descr(); my $e_descr = $aironet->e_descr(); $descr = "$e_descr->{1} $descr" if defined $e_descr->{1}; return $descr; } # Fetch duplex from EtherLike sub i_duplex { my $aironet = shift; my $partial = shift; my $el_duplex = $aironet->el_duplex($partial); my %i_duplex; foreach my $d ( keys %$el_duplex ) { my $val = $el_duplex->{$d}; next unless defined $val; $i_duplex{$d} = 'full' if $val =~ /full/i; $i_duplex{$d} = 'half' if $val =~ /half/i; } return \%i_duplex; } # # IOS 12.3 introduces the cDot11ClientSubIfIndex in the # cDot11ClientConfigInfoTable, which supplies the ifIndex # of the VLAN Subinterface if one exists, or of the primary # interface if there are not subinterfaces. 12.2 used the # Q-BRIDGE-MIB dot1qTpFdbTable but that was removed in 12.3. sub _aironet_special { my $aironet = shift; my $os_ver = $aironet->os_ver(); if ( defined($os_ver) && $os_ver =~ /^(\d+)\.(\d+)(\D|$)/ && ( ( $1 == 12 && $2 >= 3 ) || $1 > 12 ) ) { return 1; } } # # INDEX { ifIndex, cd11IfAuxSsid, cDot11ClientAddress } sub _aironet_breakout_dot11idx { my $oid = shift; my @parts = split( /\./, $oid ); my $ifindex = shift(@parts); my $ssidlen = shift(@parts); my $ssid = pack( "C*", splice( @parts, 0, $ssidlen ) ); my $mac = join( ":", map { sprintf "%02x", $_ } @parts ); return ( $ifindex, $ssid, $mac ); } sub fw_mac { my $aironet = shift; return $aironet->qb_fw_mac() unless _aironet_special($aironet); my $c_dot11subif = $aironet->c_dot11subif(); my $fw_mac = {}; foreach my $i ( keys %$c_dot11subif ) { my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($i); $fw_mac->{$i} = $mac; } return $fw_mac; } sub fw_port { my $aironet = shift; return $aironet->qb_fw_port() unless _aironet_special($aironet); my $c_dot11subif = $aironet->c_dot11subif(); my $fw_port = {}; foreach my $i ( keys %$c_dot11subif ) { my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($i); $fw_port->{$i} = $c_dot11subif->{$i} || $ifindex; } return $fw_port; } sub bp_index { my $aironet = shift; return $aironet->orig_bp_index() unless _aironet_special($aironet); my $c_dot11subif = $aironet->c_dot11subif(); my $bp_index = {}; foreach my $i ( keys %$c_dot11subif ) { my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($i); my ($i) = $c_dot11subif->{$i} || $ifindex; $bp_index->{$i} = $i; } return $bp_index; } ### # # VLAN support # sub v_name { my $aironet = shift; my $v_name = {}; my $vlan_nameid = $aironet->cdot11SecVlanNameId(); foreach my $i ( keys %$vlan_nameid ) { my @parts = split( /\./, $i ); my $namelen = shift(@parts); my $name = pack( "C*", @parts ); $v_name->{$i} = $name; } return $v_name; } sub v_index { my $aironet = shift; return $aironet->cdot11SecVlanNameId(); } sub i_vlan { my $aironet = shift; my $i_vlan = {}; my $idxmap = $aironet->cviRoutedVlanIfIndex(); foreach my $i ( keys %$idxmap ) { my @parts = split( /\./, $i ); $i_vlan->{ $idxmap->{$i} } = $parts[0]; } return $i_vlan; } # The MIB reports in units of half a megabit, e.g., # 5.5Mbps is reported as 11. sub munge_cd11_txrate { my $txrates = shift; my @units = unpack( "C*", $txrates ); my @rates = map { my $unit = $_; $unit *= 0.5; } @units; return \@rates; } # cd11 INDEX sub cd11_port { my $aironet = shift; my $cd11_sigstrength = $aironet->cd11_sigstrength(); my $interfaces = $aironet->interfaces(); my %ret; foreach ( keys %$cd11_sigstrength ) { my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($_); $ret{$_} = $interfaces->{$ifindex}; } return \%ret; } sub cd11_ssid { my $aironet = shift; my $cd11_sigstrength = $aironet->cd11_sigstrength(); my %ret; foreach ( keys %$cd11_sigstrength ) { my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($_); $ret{$_} = $ssid; } return \%ret; } sub cd11_mac { my $aironet = shift; my $cd11_sigstrength = $aironet->cd11_sigstrength(); my %ret; foreach ( keys %$cd11_sigstrength ) { my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($_); $ret{$_} = $mac; } return \%ret; } # Map VLAN N on interface I to its actual ifIndex. sub _vlan_map_n_stack { my $aironet = shift; my $vlan_idx = $aironet->cviRoutedVlanIfIndex(); my $vlan_map = {}; foreach my $idx ( keys %$vlan_idx ) { my ( $vlan, $num ) = split( /\./, $idx ); $vlan_map->{$vlan}->{$num} = $vlan_idx->{$idx}; } return $vlan_map; } # When using MBSS, the ifTable reports the # base MAC address, but the actual association is # with a different MAC address for MBSS. # This convoluted path seems to be necessary # to get the right overrides. sub i_mac { my $aironet = shift; # no partial is possible due to the levels # of indirection. # Start with the ifPhysAddress, and override my $mbss_mac = $aironet->orig_i_mac(); my $mbss_mac_addr = $aironet->mbss_mac_addr(); my $ssid_vlan = $aironet->cdot11SecAuxSsidVlan(); my $vlan_map = $aironet->cviRoutedVlanIfIndex(); my $ifstack = $aironet->ifStackStatus(); my $vlan_list = {}; foreach my $idx ( keys %$vlan_map ) { my ( $vlan, $num ) = split( /\./, $idx ); push( @{ $vlan_list->{$vlan} }, $vlan_map->{$idx} ); } my $stack = {}; foreach my $idx ( keys %$ifstack ) { my ( $upper, $lower ) = split( /\./, $idx ); $stack->{$upper}->{$lower} = $ifstack->{$idx}; } # mbss_mac_addr index is (radio, ssid). # ssid_vlan maps ssid->vlan. # vlan_map maps vlan->[list of interfaces] # ifstack allows us to pick the right interface foreach my $idx ( keys %$mbss_mac_addr ) { my ( $interface, @ssid ) = split( /\./, $idx ); my $vlan = $ssid_vlan->{ join( ".", scalar(@ssid), @ssid ) }; next unless defined($vlan); foreach my $vlanif ( @{ $vlan_list->{$vlan} } ) { if ( defined( $stack->{$vlanif}->{$interface} ) ) { $mbss_mac->{$vlanif} = $mbss_mac_addr->{$idx}; } } } return $mbss_mac; } sub i_ssidlist { my $aironet = shift; # no partial is possible due to the levels # of indirection. my $ssid_row = $aironet->cdot11SecInterfSsidRowStatus(); my $ssid_vlan = $aironet->cdot11SecAuxSsidVlan(); if ( !defined($ssid_row) || !defined($ssid_vlan) ) { return $aironet->cd11IfAuxSsid(); } my $ssidlist = {}; my $if_ssidcount = {}; my $vlan_map = $aironet->_vlan_map_n_stack(); foreach my $idx ( keys %$ssid_row ) { next unless $ssid_row->{$idx} eq 'active'; # ssid_row index is radio.ssid my ( $interface, $ssid ) = split( /\./, $idx, 2 ); my ( $len, @ssidt ) = split( /\./, $ssid ); my $mappedintf = $vlan_map->{ $ssid_vlan->{$ssid} }->{$interface}; next unless $mappedintf; if ( !$if_ssidcount->{$mappedintf} ) { $if_ssidcount->{$mappedintf} = 1; } my $ssidlist_idx = sprintf( "%s.%d", $mappedintf, $if_ssidcount->{$mappedintf} ); $ssidlist->{$ssidlist_idx} = pack( "C*", @ssidt ); $if_ssidcount->{$mappedintf}++; } return $ssidlist; } sub i_ssidbcast { my $aironet = shift; my $partial = shift; my $mbss_bcast = $aironet->cdot11SecAuxSsidMbssidBroadcast(); if ( !defined($mbss_bcast) ) { return $aironet->cd11IfAuxSsidBroadcastSsid($partial); } my $map = {}; foreach my $key ( keys %$mbss_bcast ) { my (@idx) = split( /\./, $key ); my $len = shift(@idx); $map->{ pack( "C*", @idx ) } = $mbss_bcast->{$key}; } # This needs to return the same indexes as i_ssidlist. # mbss_bcast maps ssid -> broadcasting # so we just replace the i_ssidlist values with the mbss_bcast ones. my $i_ssidlist = $aironet->i_ssidlist(); my $i_ssidbcast = {}; foreach my $key ( keys %$i_ssidlist ) { $i_ssidbcast->{$key} = $map->{ $i_ssidlist->{$key} }; } return $i_ssidbcast; } sub i_ssidmac { my $aironet = shift; my $partial = shift; my $mbss_mac_addr = $aironet->mbss_mac_addr(); # Same logic as i_ssidbcast to return same indexes as i_ssidlist my $map = {}; foreach my $key ( keys %$mbss_mac_addr ) { my ( $interface, @idx ) = split( /\./, $key ); $map->{ pack( "C*", @idx ) } = $mbss_mac_addr->{$key}; } my $i_ssidlist = $aironet->i_ssidlist(); my $i_ssidmac = {}; foreach my $key ( keys %$i_ssidlist ) { $i_ssidmac->{$key} = $map->{ $i_ssidlist->{$key} }; } return $i_ssidmac; } ### # PoE status. The ps1_type is the PoE injector type, which is just # a scalar; the status is a little more complex. sub ps1_status { my $aironet = shift; my $idx = $aironet->cpoePdCurrentPowerLevel(); my $mw = $aironet->cpoePdSupportedPower( $idx ); my $descr = $aironet->cpoePdSupportedPowerMode( $idx ); return sprintf( "%.2fW (%s)", $mw->{$idx} * 0.001, $descr->{$idx} ); } 1; __END__ =head1 NAME SNMP::Info::Layer2::Aironet - SNMP Interface to Cisco Aironet devices running IOS. =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $aironet = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $aironet->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides interface to SNMP Data available on newer Aironet devices running Cisco IOS. Note there are two classes for Aironet devices : =over =item SNMP::Info::Layer3::Aironet This class is for devices running Aironet software (older) =item SNMP::Info::Layer2::Aironet This class is for devices running Cisco IOS software (newer) =back For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $aironet = new SNMP::Info::Layer2::Aironet(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2 =item SNMP::Info::Entity =item SNMP::Info::EtherLike =item SNMP::Info::CiscoStats =item SNMP::Info::CiscoConfig =back =head2 Required MIBs =over =item Inherited Classes MIBs required by the inherited classes listed above. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $aironet->vendor() Returns 'cisco' =item $aironet->description() System description. Adds info from method e_descr() from SNMP::Info::Entity =back =head2 Globals imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Globals imported from SNMP::Info::Entity See documentation in L for details. =head2 Globals imported from SNMP::Info::EtherLike See documentation in L for details. =head1 TABLE METHODS =over =item $aironet->cd11_port() Returns radio interfaces. =item $aironet->cd11_mac() Returns client radio interface MAC addresses. =item $aironet->cd11_ssid() Returns radio interface ssid. =item $aironet->dot11_cur_tx_pwr_mw() Current transmit power, in milliwatts, of the radio interface. =back =head2 Overrides =over =item $aironet->interfaces() Uses the i_description() field. =item $aironet->i_mac() MAC address of the interface. Note this is just the MAC of the port, not anything connected to it. =item $aironet->i_duplex() Crosses information from SNMP::Info::EtherLike to get duplex info for interfaces. =item $aironet->bp_index() Returns reference to hash of bridge port table entries map back to interface identifier (iid) =item $aironet->fw_mac() Returns reference to hash of forwarding table MAC Addresses =item $aironet->fw_port() Returns reference to hash of forwarding table entries port interface identifier (iid) =item $aironet->i_vlan() Returns a mapping between C and the PVID or default VLAN. =item $aironet->v_index() Returns VLAN IDs =item $aironet->v_name() Returns VLAN names =item $aironet->i_ssidlist() Returns a list of SSIDs associated with interfaces. This function is C aware, so when using C can map SSIDs to the sub-interface to which they belong. =item $aironet->i_ssidbcast() With the same keys as i_ssidlist, returns whether the given SSID is being broadcast. =item $aironet->i_ssidmac() With the same keys as i_ssidlist, returns the Basic service set identification (BSSID), MAC address, the AP is using for the SSID. =item $aironet ps1_status() Returns the PoE injector status based on C and C. =back =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Entity See documentation in L for details. =head2 Table Methods imported from SNMP::Info::EtherLike See documentation in L for details. =head1 Data Munging Callback Subroutines =over =item $aironet->munge_cd11_txrate() Converts units of half a megabit to human readable string. =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Allied.pm000444000765000024 1276013215550564 20177 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Allied # $Id$ # # Copyright (c) 2008 Max Baker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Allied; use strict; use Exporter; use SNMP::Info::Layer2; use SNMP::Info::Layer1; @SNMP::Info::Layer2::Allied::ISA = qw/SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::Allied::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, 'ip_adresses' => 'atNetAddress', 'ip_mac' => 'atPhysAddress', ); %MIBS = ( %SNMP::Info::Layer2::MIBS, 'AtiSwitch-MIB' => 'atiswitchProductType', 'AtiStackInfo-MIB' => 'atiswitchEnhancedStacking', ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, ); sub vendor { return 'allied'; } sub os { return 'allied'; } sub os_ver { my $allied = shift; my $descr = $allied->description(); if ( $descr =~ m/version (\d+\.\d+)/ ) { return $1; } } sub model { my $allied = shift; my $desc = $allied->description(); if ( $desc =~ /(AT-80\d{2}\S*)/ ) { return $1; } return; } sub root_ip { my $allied = shift; my $ip_hash = $allied->ip_addresses(); my $found_ip; foreach my $ip ( values %{$ip_hash} ) { $found_ip = SNMP::Info::munge_ip($ip) if ( defined $ip ); last; # this is only one IP address } return $found_ip; } sub mac { my $allied = shift; my $mac_hash = $allied->ip_mac(); my $found_mac; foreach my $mac ( values %{$mac_hash} ) { $found_mac = SNMP::Info::munge_mac($mac); last; # this is only one MAC address } return $found_mac; } sub i_up { my $allied = shift; my $partial = shift; my $i_up = SNMP::Info::Layer1::i_up( $allied, $partial ); foreach my $port ( keys %$i_up ) { my $up = $i_up->{$port}; $i_up->{$port} = 'down' if $up eq 'linktesterror'; $i_up->{$port} = 'up' if $up eq 'nolinktesterror'; } return $i_up; } 1; __END__ =head1 NAME SNMP::Info::Layer2::Allied - SNMP Interface to Allied Telesis switches =head1 AUTHOR Max Baker, Dmitry Sergienko =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $allied = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myhub', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $allied->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Allied device through SNMP. See inherited classes' documentation for inherited methods. =head2 Inherited Classes =over =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item F =item F Download for your device from ftp://ftp.allied-telesyn.com/pub/switches/mibs/ =back =head2 Inherited MIBs See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $allied->vendor() Returns 'allied' :) =item $allied->os() Returns 'allied' =item $allied->os_ver() Culls Version from description() =item $allied->root_ip() Returns IP Address of Managed Device. (C) =item $allied->model() Tries to cull out C out of the description field. =item $allied->mac() Returns device MAC. =back =head2 Globals imported from SNMP::Info::Layer2 See L for details. =head1 TABLE METHODS =head2 Overrides =over =item $allied->i_up() Returns reference to map of IIDs to link status. Changes the values of ati_up() to 'up' and 'down'. =back =head2 Table Methods imported from SNMP::Info::Layer2 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Baystack.pm000444000765000024 4307513215550564 20551 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Baystack # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Baystack; use strict; use Exporter; use SNMP::Info::SONMP; use SNMP::Info::NortelStack; use SNMP::Info::RapidCity; use SNMP::Info::LLDP; use SNMP::Info::Layer3; @SNMP::Info::Layer2::Baystack::ISA = qw/SNMP::Info::SONMP SNMP::Info::NortelStack SNMP::Info::RapidCity SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer2::Baystack::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::RapidCity::MIBS, %SNMP::Info::NortelStack::MIBS, %SNMP::Info::SONMP::MIBS, 'BAY-STACK-PETH-EXT-MIB' => 'bspePethPsePortExtMeasuredPower', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, %SNMP::Info::RapidCity::GLOBALS, %SNMP::Info::NortelStack::GLOBALS, %SNMP::Info::SONMP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, %SNMP::Info::RapidCity::FUNCS, %SNMP::Info::NortelStack::FUNCS, %SNMP::Info::SONMP::FUNCS, 'peth_port_power' => 'bspePethPsePortExtMeasuredPower', ); # 450's report full duplex as speed = 20mbps?! $SNMP::Info::SPEED_MAP{20_000_000} = '10 Mbps'; $SNMP::Info::SPEED_MAP{200_000_000} = '100 Mbps'; $SNMP::Info::SPEED_MAP{2_000_000_000} = '1.0 Gbps'; %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, %SNMP::Info::RapidCity::MUNGE, %SNMP::Info::NortelStack::MUNGE, %SNMP::Info::SONMP::MUNGE, ); sub os { my $baystack = shift; my $descr = $baystack->description() || ""; my $model = $baystack->model() || ""; if ( $descr =~ /Business Ethernet Switch.*SW:v/i ) { return 'bes'; } if ( ( ( $model =~ /(420|425|BPS)/ ) and ( $descr =~ m/SW:v[1-2]/i ) ) or ( ( $model =~ /(410|450|380)/ ) ) ) { return 'baystack'; } if ( $model =~ /VSP/ ) { return 'vsp'; } return 'boss'; } sub os_bin { my $baystack = shift; my $descr = $baystack->description(); return unless defined $descr; # 303 / 304 if ( $descr =~ m/Rev: \d+\.(\d+\.\d+\.\d+)-\d+\.\d+\.\d+\.\d+/ ) { return $1; } # 450 if ( $descr =~ m/FW:V(\d+\.\d+)/ ) { return $1; } if ( $descr =~ m/FW:(\d+\.\d+\.\d+\.\d+)/i ) { return $1; } return; } sub vendor { return 'avaya'; } sub model { my $baystack = shift; my $id = $baystack->id(); return unless defined $id; my $model = &SNMP::translateObj($id); return $id unless defined $model; my $descr = $baystack->description(); return '303' if ( defined $descr and $descr =~ /\D303\D/ ); return '304' if ( defined $descr and $descr =~ /\D304\D/ ); return 'BPS' if ( $model =~ /BPS2000/i ); # Pull sreg- from all $model =~ s/^sreg-//; # Strip ES/ERS/BayStack etc. from those families $model =~ s/^(E(R)?S|BayStack|Ethernet(Routing)?Switch)-?//; $model =~ s/-ethSwitchNMM//; return $model; } sub interfaces { my $baystack = shift; my $partial = shift; my $i_index = $baystack->i_index($partial) || {}; my $index_factor = $baystack->index_factor(); my $slot_offset = $baystack->slot_offset(); my %if; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; # Ignore cascade ports next if $index > $index_factor * 8; my $port = ( $index % $index_factor ); my $slot = ( int( $index / $index_factor ) ) + $slot_offset; my $slotport = "$slot.$port"; $if{$iid} = $slotport; } return \%if; } sub i_mac { my $baystack = shift; my $partial = shift; my $i_mac = $baystack->orig_i_mac($partial) || {}; my %i_mac; # Baystack 303's with a hw rev < 2.11.4.5 report the mac as all zeros foreach my $iid ( keys %$i_mac ) { my $mac = $i_mac->{$iid}; next unless defined $mac; next if $mac eq '00:00:00:00:00:00'; $i_mac{$iid} = $mac; } return \%i_mac; } sub i_name { my $baystack = shift; my $partial = shift; my $i_index = $baystack->i_index($partial) || {}; my $i_alias = $baystack->i_alias($partial) || {}; my $i_name2 = $baystack->orig_i_name($partial) || {}; my %i_name; foreach my $iid ( keys %$i_name2 ) { my $name = $i_name2->{$iid}; my $alias = $i_alias->{$iid}; $i_name{$iid} = ( defined $alias and $alias !~ /^\s*$/ ) ? $alias : $name; } return \%i_name; } sub index_factor { my $baystack = shift; my $model = $baystack->model() || ""; my $os = $baystack->os(); my $os_ver = $baystack->os_ver(); my $op_mode = $baystack->ns_op_mode(); $op_mode = 'pure' unless defined $op_mode; if ( $os_ver =~ m/^(\d+)\./ ) { $os_ver = $1; } else { $os_ver = 1; } my $index_factor = 32; $index_factor = 64 if ( ( $model =~ /(470)/ ) or ( $os =~ m/(boss|bes)/ ) and ( $op_mode eq 'pure' ) ); $index_factor = 128 if ( ( $model =~ /(5[56]\d\d)|VSP/ ) and ( $os_ver >= 6 ) ); return $index_factor; } # Newer devices support ENTITY-MIB, use if available otherwise use proprietary # methods. sub e_index { my $stack = shift; my $partial = shift; return $stack->SUPER::e_index($partial) || $stack->ns_e_index($partial); } sub e_class { my $stack = shift; my $partial = shift; return $stack->SUPER::e_class($partial) || $stack->ns_e_class($partial); } sub e_descr { my $stack = shift; my $partial = shift; return $stack->SUPER::e_descr($partial) || $stack->ns_e_descr($partial); } sub e_name { my $stack = shift; my $partial = shift; return $stack->SUPER::e_name($partial) || $stack->ns_e_name($partial); } sub e_fwver { my $stack = shift; my $partial = shift; return $stack->SUPER::e_fwver($partial) || $stack->ns_e_fwver($partial); } sub e_hwver { my $stack = shift; my $partial = shift; return $stack->SUPER::e_hwver($partial) || $stack->ns_e_hwver($partial); } sub e_parent { my $stack = shift; my $partial = shift; return $stack->SUPER::e_parent($partial) || $stack->ns_e_parent($partial); } sub e_pos { my $stack = shift; my $partial = shift; return $stack->SUPER::e_pos($partial) || $stack->ns_e_pos($partial); } sub e_serial { my $stack = shift; my $partial = shift; return $stack->SUPER::e_serial($partial) || $stack->ns_e_serial($partial); } sub e_swver { my $stack = shift; my $partial = shift; return $stack->SUPER::e_swver($partial) || $stack->ns_e_swver($partial); } sub e_type { my $stack = shift; my $partial = shift; return $stack->SUPER::e_type($partial) || $stack->ns_e_type($partial); } sub e_vendor { my $stack = shift; my $partial = shift; return $stack->SUPER::e_vendor($partial) || $stack->ns_e_vendor($partial); } # fix for stack of switches without POE on module 1 # https://sourceforge.net/tracker/?func=detail&aid=3317739&group_id=70362&atid=527529 sub peth_port_ifindex { my $stack = shift; my $partial = shift; my %peth_port_ifindex = (); my $poe_port_st = $stack->peth_port_status($partial); my $if_index = $stack->interfaces($partial); foreach my $i (keys %$if_index) { next unless defined $poe_port_st->{$if_index->{$i}}; $peth_port_ifindex{$if_index->{$i}} = $i; } return \%peth_port_ifindex; } # Currently only ERS 4800 v5.8+ support the rcBridgeSpbmMacTable # which holds the FDB for a SPBM edge deployment. # # Q-BRIDGE still holds some entries when the rcBridgeSpbmMacTable is in use # so we merge hash entries. sub fw_mac { my $rapidcity = shift; my $qb = $rapidcity->SUPER::fw_mac() || {}; my $spbm = $rapidcity->rc_spbm_fw_mac() || {}; my $fw_mac = { %$qb, %$spbm }; return $fw_mac; } sub fw_port { my $rapidcity = shift; my $qb = $rapidcity->SUPER::fw_port() || {}; my $spbm = $rapidcity->rc_spbm_fw_port() || {}; my $fw_port = { %$qb, %$spbm }; return $fw_port; } sub fw_status { my $rapidcity = shift; my $qb = $rapidcity->SUPER::fw_status() || {}; my $spbm = $rapidcity->rc_spbm_fw_status() || {}; my $fw_status = { %$qb, %$spbm }; return $fw_status; } sub qb_fw_vlan { my $rapidcity = shift; my $qb = $rapidcity->SUPER::qb_fw_vlan() || {}; my $spbm = $rapidcity->rc_spbm_fw_vlan() || {}; my $qb_fw_vlan = { %$qb, %$spbm }; return $qb_fw_vlan; } # Baystack uses S5-AGENT-MIB (loaded in NortelStack) versus RAPID-CITY sub stp_ver { my $rapidcity = shift; return $rapidcity->s5AgSysSpanningTreeOperMode() || $rapidcity->SUPER::stp_ver(); } 1; __END__ =head1 NAME SNMP::Info::Layer2::Baystack - SNMP Interface to Avaya Ethernet Switch (Baystack) and VSP 7000 series switches =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $baystack = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $baystack->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from an Avaya Ethernet Switch (formerly Nortel/Bay Baystack) and VSP 7000 series through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $baystack = new SNMP::Info::Layer2::Baystack(...); =head2 Inherited Classes =over =item SNMP::Info::SONMP =item SNMP::Info::NortelStack =item SNMP::Info::RapidCity =item SNMP::Info::LLDP =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =back =head2 Inherited MIBs See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $baystack->vendor() Returns 'avaya' =item $baystack->model() Cross references $baystack->id() to the F and returns the results. 303s and 304s have the same ID, so we have a hack to return depending on which it is. Returns BPS for Business Policy Switch For others extracts and returns the switch numeric designation. =item $baystack->os() Returns 'baystack' or 'boss' depending on software version. =item $baystack->os_bin() Returns the firmware version extracted from C. =item $baystack->stp_ver() Returns the particular STP version running on this device. Values: C, C, C, C, C (C) =back =head2 Overrides =over =item $baystack->index_factor() Required by SNMP::Info::SONMP. Number representing the number of ports reserved per slot within the device MIB. Index factor on the Baystack switches are determined by the formula: Index Factor = 64 if (model = 470 or (os eq 'boss' and operating in pure mode)) or else Index factor = 32. Returns either 32 or 64 based upon the formula. =back =head2 Global Methods imported from SNMP::Info::SONMP See L for details. =head2 Globals imported from SNMP::Info::NortelStack See L for details. =head2 Global Methods imported from SNMP::Info::RapidCity See L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $baystack->interfaces() Returns reference to the map between IID and physical Port. Slot and port numbers on the Baystack switches are determined by the formula: port = (Interface index % Index factor) slot = (int(Interface index / Index factor)) + Slot offset The physical port name is returned as slot.port. =item $baystack->i_ignore() Returns reference to hash of IIDs to ignore. =item $baystack->i_mac() Returns the C table entries. Removes all entries matching '00:00:00:00:00:00' -- Certain revisions of Baystack firmware report all zeros for each port mac. =item $baystack->i_name() Crosses C with C and returns the human set port name if exists. =item $baystack->peth_port_ifindex() Maps the C to C by way of the F. =item $baystack->peth_port_power() Power supplied by PoE ports, in milliwatts (C) =back =head2 F Information For older devices which do not support F, these methods emulate Physical Table methods using F. See L for details on ns_e_* methods. =over =item $baystack->e_index() If the device doesn't support C, this will try ns_e_index(). Note that this is based on C due to implementation details of SNMP::Info::Entity::e_index(). =item $baystack->e_class() If the device doesn't support C, this will try ns_e_class(). =item $baystack->e_descr() If the device doesn't support C, this will try ns_e_descr(). =item $baystack->e_name() If the device doesn't support C, this will try ns_e_name(). =item $baystack->e_fwver() If the device doesn't support C, this will try ns_e_fwver(). =item $baystack->e_hwver() If the device doesn't support C, this will try ns_e_hwver(). =item $baystack->e_parent() If the device doesn't support C, this will try ns_e_parent(). =item $baystack->e_pos() If the device doesn't support C, this will try ns_e_pos(). =item $baystack->e_serial() If the device doesn't support C, this will try ns_e_serial(). =item $baystack->e_swver() If the device doesn't support C, this will try ns_e_swver(). =item $baystack->e_type() If the device doesn't support C, this will try ns_e_type(). =item $baystack->e_vendor() If the device doesn't support C, this will try ns_e_vendor(). =back =head2 Layer 2 Forwarding Database These methods try to obtain the layer 2 forwarding database entries via the normal bridge methods as well as SPBM entries via rapid city methods. =over =item $baystack->fw_mac() Returns reference to hash of forwarding table MAC Addresses =item $baystack->fw_port() Returns reference to hash of forwarding table entries port interface identifier (iid) =item $baystack->qb_fw_vlan() Returns reference to hash of forwarding table entries VLAN ID =item $baystack->fw_status() Returns reference to hash of forwarding table entries status =back =head2 Table Methods imported from SNMP::Info::SONMP See L for details. =head2 Table Methods imported from SNMP::Info::NortelStack See L for details. =head2 Table Methods imported from SNMP::Info::RapidCity See L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/C1900.pm000444000765000024 3513313215550564 17500 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::C1900 # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::C1900; use strict; use Exporter; use SNMP::Info::CDP; use SNMP::Info::CiscoStats; use SNMP::Info::CiscoConfig; use SNMP::Info::CiscoStpExtensions; use SNMP::Info::CiscoAgg; use SNMP::Info::Layer2; @SNMP::Info::Layer2::C1900::ISA = qw/SNMP::Info::CDP SNMP::Info::CiscoStats SNMP::Info::CiscoConfig SNMP::Info::CiscoStpExtensions SNMP::Info::CiscoAgg SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::C1900::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::CiscoAgg::GLOBALS, %SNMP::Info::CiscoStpExtensions::GLOBALS, %SNMP::Info::CiscoConfig::GLOBALS, %SNMP::Info::CiscoStats::GLOBALS, %SNMP::Info::CDP::GLOBALS, 'c1900_flash_status' => 'upgradeFlashBankStatus', ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::CiscoAgg::FUNCS, %SNMP::Info::CiscoStpExtensions::FUNCS, %SNMP::Info::CiscoConfig::FUNCS, %SNMP::Info::CiscoStats::FUNCS, %SNMP::Info::CDP::FUNCS, # ESSWITCH-MIB 'c1900_p_index' => 'swPortIndex', 'c1900_p_ifindex' => 'swPortIfIndex', 'c1900_p_duplex' => 'swPortDuplexStatus', 'c1900_p_duplex_admin' => 'swPortFullDuplex', 'c1900_p_name' => 'swPortName', 'c1900_p_up_admin' => 'swPortAdminStatus', 'c1900_p_type' => 'swPortMediaCapability', 'c1900_p_media' => 'swPortConnectorType', ); %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::CiscoAgg::MIBS, %SNMP::Info::CiscoStpExtensions::MIBS, %SNMP::Info::CiscoConfig::MIBS, %SNMP::Info::CiscoStats::MIBS, %SNMP::Info::CDP::MIBS, # Also known as the ESSWITCH-MIB 'STAND-ALONE-ETHERNET-SWITCH-MIB' => 'series2000' ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::CiscoAgg::MUNGE, %SNMP::Info::CiscoStpExtensions::MUNGE, %SNMP::Info::CiscoConfig::MUNGE, %SNMP::Info::CiscoStats::MUNGE, %SNMP::Info::CDP::MUNGE, ); sub bulkwalk_no { return 1; } sub cisco_comm_indexing { return 1; } sub vendor { return 'cisco'; } sub os { return 'catalyst'; } sub os_ver { my $c1900 = shift; # Check for superclass one my $os_ver = $c1900->SUPER::os_ver(); return $os_ver if defined $os_ver; my $c1900_flash_status = $c1900->c1900_flash_status(); return unless defined $c1900_flash_status; if ( $c1900_flash_status =~ m/V(\d+\.\d+(\.\d+)?)/ ) { return $1; } return; } sub interfaces { my $c1900 = shift; my $partial = shift; my $i_descr = $c1900->i_description($partial) || {}; foreach my $iid ( keys %$i_descr ) { $i_descr->{$iid} =~ s/\s*$//; } return $i_descr; } sub i_duplex { my $c1900 = shift; my $partial = shift; my $c1900_p_duplex = $c1900->c1900_p_duplex($partial) || {}; my %i_duplex; foreach my $if ( keys %$c1900_p_duplex ) { my $duplex = $c1900_p_duplex->{$if}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $i_duplex{$if} = $duplex; } return \%i_duplex; } sub i_duplex_admin { my $c1900 = shift; my $partial = shift; my $c1900_p_admin = $c1900->c1900_p_duplex_admin($partial) || {}; my %i_duplex_admin; foreach my $if ( keys %$c1900_p_admin ) { my $duplex = $c1900_p_admin->{$if}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /disabled/i; $duplex = 'full' if $duplex =~ /flow control/i; $duplex = 'full' if $duplex =~ /enabled/i; $duplex = 'auto' if $duplex =~ /auto/i; $i_duplex_admin{$if} = $duplex; } return \%i_duplex_admin; } sub i_name { my $c1900 = shift; my $partial = shift; my $i_name = $c1900->orig_i_name($partial) || {}; my $c1900_p_name = $c1900->c1900_p_name($partial) || {}; foreach my $port ( keys %$c1900_p_name ) { my $name = $c1900_p_name->{$port}; next unless defined $name; next unless $name !~ /^\s*$/; $i_name->{$port} = $name; } return $i_name; } sub set_i_duplex_admin { my $c1900 = shift; my ( $duplex, $port ) = @_; # map a textual duplex to an integer one the switch understands my %duplexes = qw/full 1 half 2 auto 3/; my $iid = $c1900->c1900_p_ifindex($port); $duplex = lc($duplex); return 0 unless defined $duplexes{$duplex}; return $c1900->set_c1900_p_duplex_admin( $duplexes{$duplex}, $iid ); } sub i_vlan { my $c1900 = shift; my $partial = shift; # Overlap allows more than one VLAN per port. Unable to determine default my $overlap = $c1900->bridgeGroupAllowMembershipOverlap() || $c1900->vlanAllowMembershipOverlap() || 'disabled'; if ( $overlap eq 'enabled' ) { return; } my $member_of = $c1900->bridgeGroupMemberPortOfBridgeGroup() || $c1900->vlanMemberPortOfVlan(); my $i_pvid = {}; foreach my $idx ( keys %$member_of ) { my @values = split( /\./, $idx ); my ( $vlan, $port ) = @values; next unless $vlan; next unless $port; next if ( defined $partial and $port !~ /^$partial$/ ); my $value = $member_of->{$idx}; next if ( $value eq 'false' ); $i_pvid->{$port} = $vlan; } return $i_pvid; } sub i_vlan_membership { my $c1900 = shift; my $partial = shift; my $member_of = $c1900->bridgeGroupMemberPortOfBridgeGroup() || $c1900->vlanMemberPortOfVlan(); my $i_vlan_membership = {}; foreach my $idx ( keys %$member_of ) { my @values = split( /\./, $idx ); my ( $vlan, $port ) = @values; next unless $vlan; next unless $port; next if ( defined $partial and $port !~ /^$partial$/ ); my $value = $member_of->{$idx}; next if ( $value eq 'false' ); push( @{ $i_vlan_membership->{$port} }, $vlan ); } return $i_vlan_membership; } sub i_vlan_membership_untagged { return; } sub bp_index { my $c1900 = shift; my $partial = shift; my $if_index = $c1900->i_index($partial); my $index = $c1900->orig_bp_index($partial) || {}; foreach my $iid ( keys %$if_index ) { $index->{$iid} = $iid if ( !defined $index->{$iid} ); } return $index; } 1; __END__ =head1 NAME SNMP::Info::Layer2::C1900 - SNMP Interface to data from Cisco Catalyst 1900 Network Switches running CatOS =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $c1900 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $c1900->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Catalyst 1900 device through SNMP. See SNMP::Info for full documentation Note that most of these devices only talk SNMP version 1, but not all. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $c1900 = new SNMP::Info::Layer2::C1900(...); =head2 Inherited classes =over =item SNMP::Info::CDP =item SNMP::Info::CiscoStats =item SNMP::Info::CiscoConfig =item SNMP::Info::CiscoStpExtensions =item SNMP::Info::CiscoAgg =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item F F is included in the Version 1 MIBs from Cisco. They can be found at ftp://ftp.cisco.com/pub/mibs/v1/v1.tar.gz =back =head2 Inherited MIBs See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $c1900->c1900_flash_status() Usually contains the version of the software loaded in flash. Used by os_ver() C =item $c1900->os() Returns 'catalyst' =item $c1900->os_ver() Returns CatOS version if obtainable. First tries to use SNMP::Info::CiscoStats->os_ver() . If that fails then it checks for the presence of $c1900->c1900_flash_status() and culls the version from there. =item $c1900->vendor() Returns 'cisco' :) =back =head2 Overrides =over =item $c1900->cisco_comm_indexing() Returns 1. Use vlan indexing. =item $c1900->bulkwalk_no Return C<1>. Bulkwalk is turned off for this class. =back =head2 Globals imported from SNMP::Info::CDP See L for details. =head2 Globals imported from SNMP::Info::CiscoStats See L for details. =head2 Globals imported from SNMP::Info::CiscoConfig See L for details. =head2 Globals imported from SNMP::Info::CiscoStpExtensions See L for details. =head2 Globals imported from SNMP::Info::CiscoAgg See L for details. =head2 Globals imported from SNMP::Info::Layer2 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $c1900->interfaces() Returns reference to the map between IID and physical Port. =item $c1900->i_duplex() Returns reference to map of IIDs to current link duplex =item $c1900->i_duplex_admin() Returns reference to hash of IIDs to admin duplex setting =item $c1900->i_name() Crosses C with $c1900->c1900_p_name() and returns the human set port name if exists. =item $c1900->i_vlan() Returns a mapping between the interface and the VLAN / bridge group if overlap is not enabled. =item $c1900->i_vlan_membership() Returns reference to hash of arrays: key = interface, value = array of VLAN / bridge group IDs. Example: my $interfaces = $c1900->interfaces(); my $vlans = $c1900->i_vlan_membership(); foreach my $iid (sort keys %$interfaces) { my $port = $interfaces->{$iid}; my $vlan = join(',', sort(@{$vlans->{$iid}})); print "Port: $port VLAN: $vlan\n"; } =item $c1900->i_vlan_membership_untagged() Unsupported, returns nothing. =item $c1900->bp_index() Returns a bp_index that contains the original bp_index entries and extra entries for those interfaces listed in if_index, as some C1900 devices do not return complete bp_indexes. =back =head2 F Switch Port Table Entries: =over =item $c1900->c1900_p_index() Maps the Switch Port Table to the IID C =item $c1900->c1900_p_duplex() Gives Port Duplex Info (C) =item $c1900->c1900_p_duplex_admin() Gives admin setting for Duplex Info (C) =item $c1900->c1900_p_name() Gives human set name for port (C) =item $c1900->c1900_p_up_admin() Gives Admin status of port enabled. (C) =item $c1900->c1900_p_type() Gives Type of port, i.e. C<"general-ethernet"> (C) =item $c1900->c1900_p_media() Gives the media of the port , i.e. "C" (C) =back =head2 Table Methods imported from SNMP::Info::CDP See L for details. =head2 Table Methods imported from SNMP::Info::CiscoStats See L for details. =head2 Table Methods imported from SNMP::Info::CiscoConfig See L for details. =head2 Table Methods imported from SNMP::Info::CiscoStpExtensions See L for details. =head2 Table Methods imported from SNMP::Info::CiscoAgg See L for details. =head2 Table Methods imported from SNMP::Info::Layer2 See L for details. =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item $c1900->set_i_duplex_admin(duplex, ifIndex) Sets port duplex, must be supplied with duplex and port C. Speed choices are 'auto', 'half', 'full'. Example: my %if_map = reverse %{$c1900->interfaces()}; $c1900->set_i_duplex_admin('auto', $if_map{'1'}) or die "Couldn't change port duplex. ",$c1900->error(1); =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/C2900.pm000444000765000024 2451013215550564 17476 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::C2900 # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::C2900; use strict; use Exporter; use SNMP::Info::Layer2::Cisco; @SNMP::Info::Layer2::C2900::ISA = qw/SNMP::Info::Layer2::Cisco Exporter/; @SNMP::Info::Layer2::C2900::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %GLOBALS = ( %SNMP::Info::Layer2::Cisco::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer2::Cisco::FUNCS, 'i_name' => 'ifAlias', # C2900PortEntry 'c2900_p_index' => 'c2900PortIfIndex', 'c2900_p_duplex' => 'c2900PortDuplexStatus', 'c2900_p_duplex_admin' => 'c2900PortDuplexState', 'c2900_p_speed_admin' => 'c2900PortAdminSpeed', ); %MIBS = ( %SNMP::Info::Layer2::Cisco::MIBS, 'CISCO-C2900-MIB' => 'ciscoC2900MIB', ); %MUNGE = ( %SNMP::Info::Layer2::Cisco::MUNGE, ); sub vendor { return 'cisco'; } sub cisco_comm_indexing { return 1; } sub i_duplex { my $c2900 = shift; my $partial = shift; my $interfaces = $c2900->interfaces($partial); my $c2900_p_index = $c2900->c2900_p_index() || {}; my $c2900_p_duplex = $c2900->c2900_p_duplex(); my %reverse_2900 = reverse %$c2900_p_index; my %i_duplex; foreach my $if ( keys %$interfaces ) { my $port_2900 = $reverse_2900{$if}; next unless defined $port_2900; my $duplex = $c2900_p_duplex->{$port_2900}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $i_duplex{$if} = $duplex; } return \%i_duplex; } sub i_duplex_admin { my $c2900 = shift; my $partial = shift; my $interfaces = $c2900->interfaces($partial); my $c2900_p_index = $c2900->c2900_p_index() || {}; my $c2900_p_admin = $c2900->c2900_p_duplex_admin(); my %reverse_2900 = reverse %$c2900_p_index; my %i_duplex_admin; foreach my $if ( keys %$interfaces ) { my $port_2900 = $reverse_2900{$if}; next unless defined $port_2900; my $duplex = $c2900_p_admin->{$port_2900}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $duplex = 'auto' if $duplex =~ /auto/i; $i_duplex_admin{$if} = $duplex; } return \%i_duplex_admin; } sub i_speed_admin { my $c2900 = shift; my $partial = shift; my %i_speed_admin; my $p_port = $c2900->p_port() || {}; my $interfaces = $c2900->interfaces($partial); my $c2900_p_index = $c2900->c2900_p_index() || {}; my %reverse_2900 = reverse %$c2900_p_index; my $c2900_p_speed = $c2900->c2900_p_speed_admin( $reverse_2900{$partial} ); my %speeds = ( 'autoDetect' => 'auto', 's10000000' => '10 Mbps', 's100000000' => '100 Mbps', ); %i_speed_admin = map { $c2900_p_index->{$_} => $speeds{ $c2900_p_speed->{$_} } } keys %$c2900_p_index; return \%i_speed_admin; } sub set_i_speed_admin { my $c2900 = shift; my ( $speed, $iid ) = @_; # map speeds to those the switch will understand my %speeds = qw/auto 1 10 10000000 100 100000000/; my $c2900_p_index = $c2900->c2900_p_index() || {}; my %reverse_2900 = reverse %$c2900_p_index; $speed = lc($speed); return unless defined $speeds{$speed}; # account for weirdness of c2900 mib $iid = $reverse_2900{$iid}; return $c2900->set_c2900_p_speed_admin( $speeds{$speed}, $iid ); } sub set_i_duplex_admin { my $c2900 = shift; my ( $duplex, $iid ) = @_; # map a textual duplex to an integer one the switch understands my %duplexes = qw/full 1 half 2 auto 3/; my $c2900_p_index = $c2900->c2900_p_index() || {}; my %reverse_2900 = reverse %$c2900_p_index; $duplex = lc($duplex); return unless defined $duplexes{$duplex}; # account for weirdness of c2900 mib $iid = $reverse_2900{$iid}; return $c2900->set_c2900_p_duplex_admin( $duplexes{$duplex}, $iid ); } # Use i_descritption for port key, cuz i_name can be manually entered. sub interfaces { my $c2900 = shift; my $partial = shift; my $interfaces = $c2900->i_index($partial) || {}; my $i_descr = $c2900->i_description($partial) || {}; my %if; foreach my $iid ( keys %$interfaces ) { my $port = $i_descr->{$iid}; next unless defined $port; $port =~ s/\./\//g if ( $port =~ /\d+\.\d+$/ ); $port =~ s/[^\d\/,()\w]+//gi; $if{$iid} = $port; } return \%if; } 1; __END__ =head1 NAME SNMP::Info::Layer2::C2900 - SNMP Interface to Cisco Catalyst 2900 Switches running IOS =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $c2900 = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $c2900->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a C2900 device through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $c2900 = new SNMP::Info::Layer2::C2900(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2::Cisco =back =head2 Required MIBs =over =item F Part of the v2 MIBs from Cisco. =back =head2 Inherited MIBs See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $c2900->vendor() Returns 'cisco' :) =item $c2900->cisco_comm_indexing() Returns 1. Use vlan indexing. =back =head2 Globals imported from SNMP::Info::Layer2::Cisco See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $c2900->interfaces() Returns reference to the map between IID and physical Port. On the 2900 devices i_name isn't reliable, so we override to just the description. Next all dots are changed for forward slashes so that the physical port name is the same as the broad-casted CDP port name. (Ethernet0.1 -> Ethernet0/1) Also, any weird characters are removed, as I saw a few pop up. =item $c2900->i_duplex() Returns reference to map of IIDs to current link duplex Crosses $c2900->c2900_p_index() with $c2900->c2900_p_duplex() =item $c2900->i_duplex_admin() Returns reference to hash of IIDs to admin duplex setting Crosses $c2900->c2900_p_index() with $c2900->c2900_p_duplex_admin() =item $c2900->i_speed_admin() Returns reference to hash of IIDs to admin speed setting. =back =head2 F Port Entry Table =over =item $c2900->c2900_p_index() Maps the Switch Port Table to the IID (C) =item $c2900->c2900_p_duplex() Gives Port Duplex Info (C) =item $c2900->c2900_p_duplex_admin() Gives admin setting for Duplex Info (C) =item $c2900->c2900_p_speed_admin() Gives Admin speed of port (C) =back =head2 Table Methods imported from SNMP::Info::Layer2::Cisco See L for details. =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item $c2900->set_i_speed_admin(speed, ifIndex) Sets port speed, must be supplied with speed and port C Speed choices are 'auto', '10', '100' Crosses $c2900->c2900_p_index() with $c2900->c2900_p_speed_admin() to utilize port C. Example: my %if_map = reverse %{$c2900->interfaces()}; $c2900->set_i_speed_admin('auto', $if_map{'FastEthernet0/1'}) or die "Couldn't change port speed. ",$c2900->error(1); =item $c2900->set_i_duplex_admin(duplex, ifIndex) Sets port duplex, must be supplied with duplex and port C Speed choices are 'auto', 'half', 'full' Crosses $c2900->c2900_p_index() with $c2900->c2900_p_duplex_admin() to utilize port C. Example: my %if_map = reverse %{$c2900->interfaces()}; $c2900->set_i_duplex_admin('auto', $if_map{'FastEthernet0/1'}) or die "Couldn't change port duplex. ",$c2900->error(1); =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Catalyst.pm000444000765000024 1760213215550564 20571 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Catalyst # $Id$ # # Copyright (c) 2002,2003 Regents of the University of California # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Catalyst; use strict; use Exporter; use SNMP::Info::CiscoStack; use SNMP::Info::Layer2::Cisco; @SNMP::Info::Layer2::Catalyst::ISA = qw/SNMP::Info::CiscoStack SNMP::Info::Layer2::Cisco Exporter/; @SNMP::Info::Layer2::Catalyst::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::Cisco::MIBS, %SNMP::Info::CiscoStack::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer2::Cisco::GLOBALS, %SNMP::Info::CiscoStack::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer2::Cisco::FUNCS, %SNMP::Info::CiscoStack::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer2::Cisco::MUNGE, %SNMP::Info::CiscoStack::MUNGE, ); # Overidden Methods # i_physical sets a hash entry as true if the iid is a physical port sub i_physical { my $cat = shift; my $p_port = $cat->p_port(); my %i_physical; foreach my $port ( keys %$p_port ) { my $iid = $p_port->{$port}; $i_physical{$iid} = 1; } return \%i_physical; } sub vendor { return 'cisco'; } sub os { return 'catalyst'; } sub os_ver { my $cat = shift; my $os_ver = $cat->SUPER::os_ver(); return $os_ver if defined $os_ver; my $m_swver = $cat->m_swver(); return unless defined $m_swver; # assume .1 entry is the chassis and the sw version we want. return $m_swver->{1} if defined $m_swver->{1}; return; } # Workaround for incomplete bp_index sub bp_index { my $cat = shift; my $p_index = $cat->p_port(); my $b_index = $cat->p_oidx(); my %bp_index; foreach my $iid ( keys %$p_index ) { my $ifidx = $p_index->{$iid}; next unless defined $ifidx; my $bpidx = $b_index->{$iid} || 0; $bp_index{$bpidx} = $ifidx; } return \%bp_index; } sub cisco_comm_indexing { return 1; } sub interfaces { my $cat = shift; my $partial = shift; my $i_index = $cat->i_index($partial); my $portnames = $cat->p_port() || {}; my %portmap = reverse %$portnames; my %interfaces = (); foreach my $iid ( keys %$i_index ) { next unless defined $iid; my $if = $i_index->{$iid}; $if =~ s/\./\// if $if; my $port = $portmap{$iid}; $port =~ s/\./\// if $port; $interfaces{$iid} = $port || $if; } return \%interfaces; } sub i_name { my $cat = shift; my $partial = shift; my $p_port = $cat->p_port() || {}; my $p_name = $cat->p_name() || {}; my %i_name; foreach my $port ( keys %$p_name ) { my $iid = $p_port->{$port}; next unless defined $iid; next if ( defined $partial and $iid !~ /^$partial$/ ); $i_name{$iid} = $p_name->{$port}; } return \%i_name; } 1; __END__ =head1 NAME SNMP::Info::Layer2::Catalyst - SNMP Interface to Cisco Catalyst devices running Catalyst OS. =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $cat = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $cat->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info subclass to provide information for Cisco Catalyst series switches running CatOS. This class includes the Catalyst 2920, 4000, 5000, 6000 (hybrid mode) families. This subclass is not for all devices that have the name Catalyst. Note that some Catalyst switches run IOS, like the 2900 and 3550 families. Cisco Catalyst 1900 switches use their own MIB and have a separate subclass. Use the method above to have SNMP::Info determine the appropriate subclass before using this class directly. See SNMP::Info::device_type() for specifics. Note: Some older Catalyst switches will only talk SNMP version 1. Some newer ones will not return all their data if connected via Version 1. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $cat = new SNMP::Info::Layer2::Catalyst(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2::Cisco =item SNMP::Info::CiscoStack =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back These MIBs are found in the standard v2 MIBs from Cisco. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $cat->os() Returns 'catalyst' =item $cat->os_ver() Tries to use the value from SNMP::Info::CiscoStats->os_ver() and if it fails it grabs $cat->m_swver()->{1} and uses that. =item $cat->vendor() Returns 'cisco' =item $cat->cisco_comm_indexing() Returns 1. Use vlan indexing. =back =head2 Global Methods imported from SNMP::Info::Layer2::Cisco See documentation in L for details. =head2 Global Methods imported from SNMP::Info::CiscoStack See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $cat->interfaces() Returns the map between SNMP Interface Identifier (iid) and physical port name. =item $cat->i_name() Returns reference to hash of iid to human set name. C =item $cat->i_physical() Returns a map to IID for ports that are physical ports, not vlans, etc. =item $cat->bp_index() Returns reference to hash of bridge port table entries map back to interface identifier (iid) Crosses (C) to (C) since some devices seem to have problems with F =back =head2 Table Methods imported from SNMP::Info::Layer2::Cisco See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoStack See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Centillion.pm000444000765000024 3143613215550564 21106 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Centillion # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Centillion; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Bridge; use SNMP::Info::NortelStack; use SNMP::Info::SONMP; @SNMP::Info::Layer2::Centillion::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::NortelStack SNMP::Info::SONMP Exporter/; @SNMP::Info::Layer2::Centillion::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::Bridge::MIBS, %SNMP::Info::NortelStack::MIBS, %SNMP::Info::SONMP::MIBS, 'CENTILLION-DOT3-EXTENSIONS-MIB' => 'cnDot3ExtnTable', 'S5-COMMON-STATS-MIB' => 's5CmStat', 'CENTILLION-VLAN-MIB' => 'cnVlanENETMgt', 'CENTILLION-CONFIG-MIB' => 'sysTFTPStart', ); %GLOBALS = ( %SNMP::Info::GLOBALS, %SNMP::Info::Bridge::GLOBALS, %SNMP::Info::NortelStack::GLOBALS, %SNMP::Info::SONMP::GLOBALS, 'tftp_action' => 'sysTFTPStart', 'tftp_host' => 'sysTFTPIpAddress', 'tftp_file' => 'sysTFTPFileName', 'tftp_type' => 'sysTFTPFileType', 'tftp_result' => 'sysTFTPResult', ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::Bridge::FUNCS, %SNMP::Info::NortelStack::FUNCS, %SNMP::Info::SONMP::FUNCS, # CENTILLION-DOT3-EXTENSIONS-MIB::cnDot3ExtnTable 'centillion_p_index' => 'cnDot3ExtnIfIndex', 'centillion_p_duplex' => 'cnDot3ExtnIfOperConnectionType', 'centillion_p_duplex_admin' => 'cnDot3ExtnIfAdminConnectionType', # S5-COMMON-STATS-MIB::s5CmSNodeTable 'fw_mac' => 's5CmSNodeMacAddr', 'fw_port' => 's5CmSNodeIfIndx', # CENTILLION-VLAN-MIB::cnVlanPortMemberTable 'centillion_i_vlan_index' => 'cnVlanPortMemberIfIndex', 'centillion_i_vlan' => 'cnVlanPortMemberVID', 'centillion_i_vlan_type' => 'cnVlanPortMemberIngressType', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::MUNGE, %SNMP::Info::Bridge::MUNGE, %SNMP::Info::NortelStack::MUNGE, %SNMP::Info::SONMP::MUNGE, ); sub os { return 'centillion'; } sub vendor { return 'nortel'; } sub i_ignore { my $centillion = shift; my $descr = $centillion->i_description(); my %i_ignore; foreach my $if ( keys %$descr ) { my $type = $descr->{$if}; # Skip virtual interfaces $i_ignore{$if}++ if $type =~ /(VE|VID|vc|lp)/i; } return \%i_ignore; } sub interfaces { my $centillion = shift; my $i_index = $centillion->i_index(); my $i_descr = $centillion->i_description(); my %if; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; my $descr = $i_descr->{$iid}; # Skip ATM and virtual interfaces next if $descr =~ /(VE|VID|vc|lp)/i; # Index numbers are deterministic slot * 256 + port my $port = $index % 256; my $slot = int( $index / 256 ); my $slotport = "$slot.$port"; $slotport = "$descr" if $descr =~ /(mcp)/i; $if{$index} = $slotport; } return \%if; } sub i_duplex { my $centillion = shift; my $port_index = $centillion->centillion_p_index(); my $port_duplex = $centillion->centillion_p_duplex(); my %i_duplex; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; my $duplex = $port_duplex->{$iid}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $i_duplex{$index} = $duplex; } return \%i_duplex; } sub i_duplex_admin { my $centillion = shift; my $port_index = $centillion->centillion_p_index(); my $port_admin = $centillion->centillion_p_duplex_admin(); my %i_duplex_admin; foreach my $iid ( keys %$port_index ) { my $index = $port_index->{$iid}; next unless defined $index; my $duplex = $port_admin->{$iid}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $duplex = 'auto' if $duplex =~ /auto/i; $i_duplex_admin{$index} = $duplex; } return \%i_duplex_admin; } sub i_vlan { my $centillion = shift; my $cn_vlan_index = $centillion->centillion_i_vlan_index(); my $cn_vlan = $centillion->centillion_i_vlan(); my %i_vlan; foreach my $iid ( keys %$cn_vlan_index ) { my $index = $cn_vlan_index->{$iid}; next unless defined $index; my $vlan = $cn_vlan->{$iid}; next unless defined $vlan; $i_vlan{$index} = $vlan; } return \%i_vlan; } sub model { my $centillion = shift; my $id = $centillion->id(); return unless defined $id; my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^sreg-//i; return '5000BH' if ( $model =~ /5000BH/ ); return '5005BH' if ( $model =~ /5005BH/ ); return 'C100' if ( $model =~ /Centillion100/ ); return 'C50N' if ( $model =~ /Centillion50N/ ); return 'C50T' if ( $model =~ /Centillion50T/ ); return $model; } sub bp_index { my $centillion = shift; my $index = $centillion->fw_port(); my %bp_index; foreach my $iid ( keys %$index ) { my $b_index = $index->{$iid}; next unless defined $b_index; #Index value is the same as ifIndex $bp_index{$b_index} = $b_index; } return \%bp_index; } sub index_factor { return 256; } sub slot_offset { return 0; } sub fw_mac { my $centillion = shift; my $partial = shift; return $centillion->SUPER::fw_mac($partial); } sub fw_port { my $centillion = shift; my $partial = shift; return $centillion->SUPER::fw_port($partial); } 1; __END__ =head1 NAME SNMP::Info::Layer2::Centillion - SNMP Interface to Nortel Centillion based ATM Switches =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $centillion = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $centillion->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Centillion device through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $centillion = new SNMP::Info::Layer2::centillion(...); Note: This class supports version 4.X and 5.X which are VLAN based rather than bridge group based. =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Bridge =item SNMP::Info::NortelStack =item SNMP::Info::SONMP =back =head2 Required MIBs =over =item F =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $centillion->vendor() Returns 'Nortel' =item $centillion->model() Cross references $centillion->id() to the F and returns the results. Removes C from the model name =item $centillion->os() Returns 'Centillion' =item $centillion->tftp_action() (C) =item $centillion->tftp_host() (C) =item $centillion->tftp_file() (C) =item $centillion->tftp_type() (C) =item $centillion->tftp_result() (C) =back =head2 Overrides =over =item $centillion->index_factor() Required by SNMP::Info::SONMP. Number representing the number of ports reserved per slot within the device MIB. Returns 256. =item $centillion->slot_offset() Required by SNMP::Info::SONMP. Offset if slot numbering does not start at 0. Returns 0. =back =head2 Globals imported from SNMP::Info See documentation in L for details. =head2 Globals imported from SNMP::Info::Bridge See documentation in L for details. =head2 Globals imported from SNMP::Info::NortelStack See documentation in L for details. =head2 Global Methods imported from SNMP::Info::SONMP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $centillion->interfaces() Returns reference to the map between IID and physical Port. Slot and port numbers on the Passport switches are determined by the formula: port = index % 256 slot = int(index / 256) The physical port name is returned as slot.port. =item $centillion->i_duplex() Returns reference to map of IIDs to current link duplex =item $centillion->i_duplex_admin() Returns reference to hash of IIDs to admin duplex setting =item $centillion->i_ignore() Returns reference to hash of IIDs to ignore. =item $centillion->fw_mac() (C) =item $centillion->fw_port() (C) =item $centillion->bp_index() Returns a mapping between C and the Bridge Table. =item $centillion->i_vlan() Returns a mapping between C and the VLAN. =back =head2 Centillion 802.3 Extension Table (C) =over =item $centillion->centillion_p_index() Returns reference to hash. Maps table IIDs to Interface IIDs (C) =item $centillion->centillion_p_duplex() Returns reference to hash. Maps port operational duplexes to IIDs (C) =item $centillion->rc_centillion_p_duplex_admin() Returns reference to hash. Maps port admin duplexes to IIDs (C) =back =head2 Centillion VLAN Table (C) =over =item $centillion->centillion_i_vlan_index() Returns reference to hash. Key: Table entry, Value: Index (C) =item $centillion->centillion_i_vlan() Returns reference to hash. Key: Table entry, Value: VLAN ID (C) =item $centillion->centillion_i_vlan_type() Returns reference to hash. Key: Table entry, Value: VLAN Type (C) =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Bridge See documentation in L for details. =head2 Table Methods imported from SNMP::Info::NortelStack See documentation in L for details. =head2 Table Methods imported from SNMP::Info::SONMP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Cisco.pm000444000765000024 2016313215550564 20041 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Cisco # $Id$ # # Copyright (c) 2008 Max Baker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Cisco; use strict; use Exporter; use SNMP::Info::CiscoVTP; use SNMP::Info::CDP; use SNMP::Info::CiscoStats; use SNMP::Info::CiscoRTT; use SNMP::Info::CiscoConfig; use SNMP::Info::CiscoPortSecurity; use SNMP::Info::CiscoStpExtensions; use SNMP::Info::CiscoAgg; use SNMP::Info::Layer2; @SNMP::Info::Layer2::Cisco::ISA = qw/SNMP::Info::CiscoVTP SNMP::Info::CDP SNMP::Info::CiscoStats SNMP::Info::CiscoRTT SNMP::Info::CiscoConfig SNMP::Info::CiscoPortSecurity SNMP::Info::CiscoStpExtensions SNMP::Info::CiscoAgg SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::Cisco::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::CiscoAgg::MIBS, %SNMP::Info::CiscoStpExtensions::MIBS, %SNMP::Info::CiscoPortSecurity::MIBS, %SNMP::Info::CiscoConfig::MIBS, %SNMP::Info::CiscoRTT::MIBS, %SNMP::Info::CiscoStats::MIBS, %SNMP::Info::CDP::MIBS, %SNMP::Info::CiscoVTP::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::CiscoAgg::GLOBALS, %SNMP::Info::CiscoStpExtensions::GLOBALS, %SNMP::Info::CiscoPortSecurity::GLOBALS, %SNMP::Info::CiscoConfig::GLOBALS, %SNMP::Info::CiscoRTT::GLOBALS, %SNMP::Info::CiscoStats::GLOBALS, %SNMP::Info::CDP::GLOBALS, %SNMP::Info::CiscoVTP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::CiscoAgg::FUNCS, %SNMP::Info::CiscoStpExtensions::FUNCS, %SNMP::Info::CiscoPortSecurity::FUNCS, %SNMP::Info::CiscoConfig::FUNCS, %SNMP::Info::CiscoRTT::FUNCS, %SNMP::Info::CiscoStats::FUNCS, %SNMP::Info::CDP::FUNCS, %SNMP::Info::CiscoVTP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::CiscoAgg::MUNGE, %SNMP::Info::CiscoStpExtensions::MUNGE, %SNMP::Info::CiscoPortSecurity::MUNGE, %SNMP::Info::CiscoConfig::MUNGE, %SNMP::Info::CiscoRTT::MUNGE, %SNMP::Info::CiscoStats::MUNGE, %SNMP::Info::CDP::MUNGE, %SNMP::Info::CiscoVTP::MUNGE, ); 1; __END__ =head1 NAME SNMP::Info::Layer2::Cisco - SNMP Interface to L2 Cisco devices that are not covered in other classes and the base L2 Cisco class for other device specific L2 Cisco classes. =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $cisco = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $cisco->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Generic Layer 2 Cisco devices and the base L2 Cisco class for other device specific L2 Cisco classes. =head2 Inherited Classes =over =item SNMP::Info::CiscoVTP =item SNMP::Info::CDP =item SNMP::Info::CiscoStats =item SNMP::Info::CiscoRTT =item SNMP::Info::CiscoConfig =item SNMP::Info::CiscoPortSecurity =item SNMP::Info::CiscoStpExtensions =item SNMP::Info::CiscoAgg =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $cisco->vendor() Returns 'cisco' =back =head2 Global Methods imported from SNMP::Info::CiscoVTP See documentation in L for details. =head2 Globals imported from SNMP::Info::CDP See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoStats See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoRTT See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoConfig See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoPortSecurity See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoStpExtensions See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoAgg See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer2 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::CiscoVTP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoStats See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoRTT See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoConfig See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoPortSecurity See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoStpExtensions See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoAgg See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/CiscoSB.pm000444000765000024 1560713215550564 20275 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::CiscoSB # $Id$ # # Copyright (c) 2013 Nic Bernstein # # Copyright (c) 2008-2009 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::CiscoSB; use strict; use Exporter; use SNMP::Info::Layer2; use SNMP::Info::Entity; use SNMP::Info::EtherLike; use SNMP::Info::CiscoStats; use SNMP::Info::CiscoConfig; use SNMP::Info::CDP; @SNMP::Info::Layer2::CiscoSB::ISA = qw/SNMP::Info::Layer2 SNMP::Info::Entity SNMP::Info::EtherLike SNMP::Info::CiscoStats SNMP::Info::CiscoConfig SNMP::Info::CDP Exporter/; @SNMP::Info::Layer2::CiscoSB::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::Entity::GLOBALS, %SNMP::Info::EtherLike::GLOBALS, %SNMP::Info::CiscoStats::GLOBALS, %SNMP::Info::CiscoConfig::GLOBALS, %SNMP::Info::CDP::GLOBALS, 'descr' => 'sysDescr' ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::Entity::FUNCS, %SNMP::Info::EtherLike::FUNCS, %SNMP::Info::CiscoStats::FUNCS, %SNMP::Info::CiscoConfig::FUNCS, %SNMP::Info::CDP::FUNCS, ); %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::Entity::MIBS, %SNMP::Info::EtherLike::MIBS, %SNMP::Info::CiscoStats::MIBS, %SNMP::Info::CiscoConfig::MIBS, %SNMP::Info::CDP::MIBS, ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::Entity::MUNGE, %SNMP::Info::EtherLike::MUNGE, %SNMP::Info::CiscoStats::MUNGE, %SNMP::Info::CiscoConfig::MUNGE, %SNMP::Info::CDP::MUNGE, ); sub vendor { return 'cisco'; } sub os { return 'ros'; } # Walk the entPhysicalSerialNum table and return the first serial found sub serial { my $ciscosb = shift; my $e_serial = $ciscosb->e_serial(); # Find entity table entry for this unit foreach my $e ( sort keys %$e_serial ) { if (defined $e_serial->{$e} and $e_serial->{$e} !~ /^\s*$/) { return $e_serial->{$e}; } } } sub os_ver { my $ciscosb = shift; my $e_swver = $ciscosb->e_swver(); foreach my $e ( sort keys %$e_swver ) { if (defined $e_swver->{$e} and $e_swver->{$e} !~ /^\s*$/) { return $e_swver->{$e}; } } } # Grab e_model from Entity and tag on e_hwver sub model { my $ciscosb = shift; my $e_model = $ciscosb->e_model(); my $e_hwver = $ciscosb->e_hwver(); foreach my $e ( sort keys %$e_model ) { if (defined $e_model->{$e} and $e_model->{$e} !~ /^\s*$/) { my $model = "$e_model->{$e} $e_hwver->{$e}"; return $model; } } return $ciscosb->description(); } # ifDescr is the same for all interfaces in a class, but the ifName is # unique, so let's use that for port name. sub interfaces { my $ciscosb = shift; my $partial = shift; my $interfaces = $ciscosb->i_name($partial); return $interfaces; } 1; __END__ =head1 NAME SNMP::Info::Layer2::CiscoSB - SNMP Interface to Cisco Small Business series =head1 AUTHOR Nic Bernstein (shamelessly stolen from Max Baker's Aironet code) =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $ciscosb = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $ciscosb->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides interface to SNMP Data available on Cisco Small Business (nee LinkSys) managed switches. [i.e. those matching enterprises(1).cisco(9).otherEnterprises(6).ciscosb(1)] =head2 Inherited Classes =over =item SNMP::Info::Layer2 =item SNMP::Info::Entity =item SNMP::Info::EtherLike =item SNMP::Info::CiscoStats =item SNMP::Info::CiscoConfig =back =head2 Required MIBs =over =item Inherited Classes MIBs required by the inherited classes listed above. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $ciscosb->vendor() Returns 'cisco' =item $ciscosb->os() Returns 'ros' =item $ciscosb->os_ver() Returns software version (C) =item $ciscosb->serial() Returns serial number of unit (C) =item $ciscosb->model() Returns model and hardware revision of unit (C) =back =head2 Globals imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Globals imported from SNMP::Info::Entity See documentation in L for details. =head2 Globals imported from SNMP::Info::EtherLike See documentation in L for details. =head1 TABLE METHODS =head2 Overrides =over =item $ciscosb->interfaces() Uses the i_name() field. =back =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Entity See documentation in L for details. =head2 Table Methods imported from SNMP::Info::EtherLike See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/HP.pm000444000765000024 5672013215550564 17320 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::HP - SNMP Interface to HP ProCurve Switches # $Id$ # # Copyright (c) 2008-2009 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::HP; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::MAU; use SNMP::Info::CDP; use SNMP::Info::Aggregate 'agg_ports_ifstack'; @SNMP::Info::Layer2::HP::ISA = qw/ SNMP::Info::Aggregate SNMP::Info::Layer3 SNMP::Info::MAU SNMP::Info::CDP Exporter /; @SNMP::Info::Layer2::HP::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MODEL_MAP %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::MAU::MIBS, %SNMP::Info::CDP::MIBS, %SNMP::Info::Aggregate::MIBS, 'RFC1271-MIB' => 'logDescription', 'HP-ICF-OID' => 'hpSwitch4000', 'STATISTICS-MIB' => 'hpSwitchCpuStat', 'NETSWITCH-MIB' => 'hpMsgBufFree', 'CONFIG-MIB' => 'hpSwitchConfig', 'HP-ICF-CHASSIS' => 'hpicfSensorObjectId', 'HP-ICF-BRIDGE' => 'hpicfBridgeRstpForceVersion', 'HP-ICF-POE-MIB' => 'hpicfPoePethPsePortCurrent', 'SEMI-MIB' => 'hpHttpMgSerialNumber', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::MAU::GLOBALS, %SNMP::Info::CDP::GLOBALS, %SNMP::Info::Aggregate::GLOBALS, 'serial1' => 'entPhysicalSerialNum.1', 'serial2' => 'hpHttpMgSerialNumber.0', 'hp_cpu' => 'hpSwitchCpuStat.0', 'hp_mem_total' => 'hpGlobalMemTotalBytes.1', 'mem_free' => 'hpGlobalMemFreeBytes.1', 'mem_used' => 'hpGlobalMemAllocBytes.1', 'os_version' => 'hpSwitchOsVersion.0', 'os_version2' => 'hpHttpMgVersion.0', 'os_bin' => 'hpSwitchRomVersion.0', 'mac' => 'hpSwitchBaseMACAddress.0', 'rstp_ver' => 'hpicfBridgeRstpForceVersion', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::MAU::FUNCS, %SNMP::Info::CDP::FUNCS, %SNMP::Info::Aggregate::FUNCS, 'i_type2' => 'ifType', # RFC1271 'l_descr' => 'logDescription', # CONFIG-MIB::hpSwitchPortTable 'hp_duplex' => 'hpSwitchPortEtherMode', 'hp_duplex_admin' => 'hpSwitchPortFastEtherMode', 'vendor_i_type' => 'hpSwitchPortType', # HP-ICF-CHASSIS 'hp_s_oid' => 'hpicfSensorObjectId', 'hp_s_name' => 'hpicfSensorDescr', 'hp_s_status' => 'hpicfSensorStatus', # HP-ICF-POE-MIB 'peth_port_power' => 'hpicfPoePethPsePortPower', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::Layer3::MUNGE, %SNMP::Info::MAU::MUNGE, %SNMP::Info::CDP::MUNGE, %SNMP::Info::Aggregate::MUNGE, 'c_id' => \&munge_hp_c_id, ); # Model map, reverse sorted by common model name (sort -k2 -r) # Potential sources for model information: http://www.hp.com/rnd/software/switches.htm or HP-ICF-OID MIB %MODEL_MAP = ( 'J8131A' => 'WAP-420-WW', 'J8130A' => 'WAP-420-NA', 'J9833A' => 'PS1810-8G', 'J9834A' => 'PS1810-24G', 'J8133A' => 'AP520WL', 'J8680A' => '9408sl', 'J9091A' => '8212zl', 'J9475A' => '8206zl', 'J9265A' => '6600ml-24XG', 'J9264A' => '6600ml-24G-4XG', 'J9263A' => '6600ml-24G', 'J9452A' => '6600-48G-4XG', 'J9451A' => '6600-48G', 'J8474A' => '6410cl-6XG', 'J8433A' => '6400cl-6XG', 'J8992A' => '6200yl-24G', 'J4902A' => '6108', 'J8698A' => '5412zl', 'J9851A' => '5412R-zl2', 'J8719A' => '5408yl', 'J8697A' => '5406zl', 'J9850A' => '5406R-zl2', 'J8718A' => '5404yl', 'J4819A' => '5308XL', 'J4850A' => '5304XL', 'J8773A' => '4208vl', 'J8770A' => '4204vl', 'J8772A' => '4202vl-72', 'J9032A' => '4202vl-68G', 'J9031A' => '4202vl-68', 'J8771A' => '4202vl-48G', 'J4865A' => '4108GL', 'J4887A' => '4104GL', 'J9588A' => '3800-48G-PoE+-4XG', 'J9574A' => '3800-48G-PoE+-4SFP+', 'J9586A' => '3800-48G-4XG', 'J9576A' => '3800-48G-4SFP+', 'J9584A' => '3800-24SFP-2SFP+', 'J9587A' => '3800-24G-PoE+-2XG', 'J9573A' => '3800-24G-PoE+-2SFP+', 'J9585A' => '3800-24G-2XG', 'J9575A' => '3800-24G-2SFP+', 'J8693A' => '3500yl-48G-PWR', 'J8692A' => '3500yl-24G-PWR', 'J9473A' => '3500-48-PoE', 'J9472A' => '3500-48', 'J9471A' => '3500-24-PoE', 'J9470A' => '3500-24', 'J4906A' => '3400cl-48G', 'J4905A' => '3400cl-24G', 'J4815A' => '3324XL', 'J4851A' => '3124', 'J9729A' => '2920-48G-PoE+', 'J9729A' => '2920-48G-PoE+', 'J9728A' => '2920-48G', 'J9728A' => '2920-48G', 'J9727A' => '2920-24G-PoE+', 'J9727A' => '2920-24G-PoE+', 'J9726A' => '2920-24G', 'J9726A' => '2920-24G', 'J9562A' => '2915-8G-PoE', 'J9148A' => '2910al-48G-PoE+', 'J9147A' => '2910al-48G', 'J9146A' => '2910al-24G-PoE+', 'J9145A' => '2910al-24G', 'J9050A' => '2900-48G', 'J9049A' => '2900-24G', 'J4904A' => '2848', 'J4903A' => '2824', 'J9022A' => '2810-48G', 'J9021A' => '2810-24G', 'J8165A' => '2650-PWR', 'J4899B' => '2650-CR', 'J4899C' => '2650C', 'J4899A' => '2650', 'J8164A' => '2626-PWR', 'J4900B' => '2626-CR', 'J4900C' => '2626C', 'J4900A' => '2626', 'J9627A' => '2620-48-PoE+', 'J9626A' => '2620-48', 'J9624A' => '2620-24-PPoE+', 'J9625A' => '2620-24-PoE+', 'J9623A' => '2620-24', 'J9565A' => '2615-8-PoE', 'J9089A' => '2610-48-PWR', 'J9088A' => '2610-48', 'J9087A' => '2610-24-PWR', 'J9086A' => '2610-24/12PWR', 'J9085A' => '2610-24', 'J8762A' => '2600-8-PWR', 'J9780A' => '2530-8-PoE+', 'J9774A' => '2530-8G-PoEP', 'J9777A' => '2530-8G', 'J9783A' => '2530-8', 'J9778A' => '2530-48-PoE+', 'J9853A' => '2530-48G-PoE+-2SFP+', 'J9772A' => '2530-48G-PoE+', 'J9855A' => '2530-48G-2SFP+', 'J9775A' => '2530-48G', 'J9781A' => '2530-48', 'J9779A' => '2530-24-PoE+', 'J9854A' => '2530-24G-PoE+-2SFP+', 'J9773A' => '2530-24G-PoE+', 'J9856A' => '2530-24G-2SFP+', 'J9776A' => '2530-24G', 'J9782A' => '2530-24', 'J4813A' => '2524', 'J9298A' => '2520G-8-PoE', 'J9299A' => '2520G-24-PoE', 'J9137A' => '2520-8-PoE', 'J9138A' => '2520-24-PoE', 'J4812A' => '2512', 'J9280A' => '2510G-48', 'J9279A' => '2510G-24', 'J9020A' => '2510-48A', 'J9019B' => '2510-24B', 'J9019A' => '2510-24A', 'J4818A' => '2324', 'J4817A' => '2312', 'J9449A' => '1810G-8', 'J9450A' => '1810G-24', 'J9802A' => '1810-8G', 'J9803A' => '1810-24G', 'J9029A' => '1800-8G', 'J9028A' => '1800-24G', ); # Method Overrides sub stp_ver { my $hp = shift; return $hp->rstp_ver() || $hp->SUPER::stp_ver(); } sub cpu { my $hp = shift; return $hp->hp_cpu(); } sub mem_total { my $hp = shift; return $hp->hp_mem_total(); } sub os { return 'hp'; } sub os_ver { my $hp = shift; my $os_version = $hp->os_version() || $hp->os_version2(); return $os_version if defined $os_version; # Some older ones don't have this value,so we cull it from the description my $descr = $hp->description(); if ( $descr =~ m/revision ([A-Z]{1}\.\d{2}\.\d{2})/ ) { return $1; } return; } # Regular managed ProCurve switches have the serial num in entity mib, # the web-managed models in the semi mib (hphttpmanageable). sub serial { my $hp = shift; my $serial = $hp->serial1() || $hp->serial2() || undef;; return $serial; } # Lookup model number, and translate the part number to the common number sub model { my $hp = shift; my $id = $hp->id(); return unless defined $id; my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^hpswitch//i; return defined $MODEL_MAP{$model} ? $MODEL_MAP{$model} : $model; } sub interfaces { my $hp = shift; my $interfaces = $hp->i_index(); my $i_descr = $hp->i_description(); my %if; foreach my $iid ( keys %$interfaces ) { my $descr = $i_descr->{$iid}; next unless defined $descr; $if{$iid} = $descr if ( defined $descr and length $descr ); } return \%if } sub i_name { my $hp = shift; my $i_alias = $hp->i_alias(); my $e_name = $hp->e_name(); my $e_port = $hp->e_port(); my %i_name; foreach my $port ( keys %$e_name ) { my $iid = $e_port->{$port}; next unless defined $iid; my $alias = $i_alias->{$iid}; next unless defined $iid; $i_name{$iid} = $e_name->{$port}; # Check for alias $i_name{$iid} = $alias if ( defined $alias and length($alias) ); } return \%i_name; } sub i_duplex { my $hp = shift; return $hp->mau_i_duplex(); } sub i_duplex_admin { my $hp = shift; my $partial = shift; # Try HP MIB first my $hp_duplex = $hp->hp_duplex_admin($partial); if ( defined $hp_duplex and scalar( keys %$hp_duplex ) ) { my %i_duplex; foreach my $if ( keys %$hp_duplex ) { my $duplex = $hp_duplex->{$if}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $duplex = 'auto' if $duplex =~ /auto/i; $i_duplex{$if} = $duplex; } return \%i_duplex; } else { return $hp->mau_i_duplex_admin(); } } sub vendor { return 'hp'; } sub log { my $hp = shift; my $log = $hp->l_descr(); my $logstring = undef; foreach my $val ( values %$log ) { next if $val =~ /^Link\s+(Up|Down)/; $logstring .= "$val\n"; } return $logstring; } sub slots { my $hp = shift; my $e_name = $hp->e_name(); return unless defined $e_name; my $slots; foreach my $slot ( keys %$e_name ) { $slots++ if $e_name->{$slot} =~ /slot/i; } return $slots; } sub fan { my $hp = shift; return &_sensor( $hp, 'fan' ); } sub ps1_status { my $hp = shift; return &_sensor( $hp, 'power', '^power supply 1' ) || &_sensor( $hp, 'power', '^power supply sensor' ); } sub ps2_status { my $hp = shift; return &_sensor( $hp, 'power', '^power supply 2' ) || &_sensor( $hp, 'power', '^redundant' ); } sub _sensor { my $hp = shift; my $search_type = shift || 'fan'; my $search_name = shift || ''; my $hp_s_oid = $hp->hp_s_oid(); my $result; foreach my $sensor ( keys %$hp_s_oid ) { my $sensortype = &SNMP::translateObj( $hp_s_oid->{$sensor} ); if ( $sensortype =~ /$search_type/i ) { my $sensorname = $hp->hp_s_name()->{$sensor}; my $sensorstatus = $hp->hp_s_status()->{$sensor}; if ( $sensorname =~ /$search_name/i ) { $result = $sensorstatus; } } } return $result; } sub munge_hp_c_id { my ($v) = @_; if ( length(unpack('H*', $v)) == 12 ){ return join(':',map { sprintf "%02x", $_ } unpack('C*', $v)); }if ( length(unpack('H*', $v)) == 10 ){ # IP address (first octet is sign, I guess) my @octets = (map { sprintf "%02x",$_ } unpack('C*', $v))[1..4]; return join '.', map { hex($_) } @octets; }else{ return $v; } } # POWER-ETHERNET-MIB doesn't define a mapping of its # "module"/"port" index to ifIndex. Different vendors # do this in different ways. # HP switches use the ifIndex as port index, so we can # ignore the module information and map the index directly # onto an ifIndex. sub peth_port_ifindex { my $peth = shift; my $partial = shift; my $peth_port_status = $peth->peth_port_status($partial); my $peth_port_ifindex; foreach my $i ( keys %$peth_port_status ) { my ( $module, $port ) = split( /\./, $i ); $peth_port_ifindex->{$i} = $port; } return $peth_port_ifindex; } sub set_i_vlan { my $hp = shift; my $rv; my $qb_i_vlan = $hp->qb_i_vlan_t(); if (defined $qb_i_vlan and scalar(keys %$qb_i_vlan)){ my $vlan = shift; my $iid = shift; my $qb_v_egress = $hp->qb_v_egress(); if (defined $qb_v_egress and scalar($qb_v_egress->{$vlan})) { # store current untagged VLAN to remove it from the port list later my $old_untagged = $qb_i_vlan->{$iid}; # set new untagged / native VLAN $rv = $hp->set_qb_i_vlan($vlan, $iid); # If change is successful, the old native VLAN will now be a tagged VLAN on the port. This is generally not what we want. # We'll have to remove this VLAN from the "egress list" on the port. if (defined $rv and $old_untagged != $vlan) { if (defined $old_untagged and defined $qb_v_egress and scalar($qb_v_egress->{$vlan})){ # First, get the egress list of the old native VLAN (arrayref structure) my $egressports = $qb_v_egress->{$old_untagged}; # Since arrays are zero-based, we have to change the element at Index - 1 $egressports->[$iid-1] = "0"; # After changing, pack the array into a binary structure (expected by set_qb_v_egress) and set the new value on the device. my $new_egresslist = pack("B*", join('', @$egressports)); $rv = $hp->set_qb_v_egress($new_egresslist, $old_untagged); } } } else { $hp->error_throw(sprintf("Requested VLAN %s doesn't seem to exist on device...", $vlan)); } } return $rv; } sub set_i_vlan_tagged { my $hp = shift; my $rv; my $qb_i_vlan = $hp->qb_i_vlan_t(); if (defined $qb_i_vlan and scalar(keys %$qb_i_vlan)){ my $vlan = shift; my $iid = shift; my $qb_v_egress = $hp->qb_v_egress(); if (defined $qb_v_egress and scalar($qb_v_egress->{$vlan})) { # First, get the egress list of the VLAN we want to add to the port. my $egressports = $qb_v_egress->{$vlan}; # Since arrays are zero-based, we have to change the element at Index - 1 $egressports->[$iid-1] = "1"; # After changing, pack the array into a binary structure (expected by set_qb_v_egress) and set the new value on the device. my $new_egresslist = pack("B*", join('', @$egressports)); $rv = $hp->set_qb_v_egress($new_egresslist, $vlan); return $rv; } else { $hp->error_throw(sprintf("Requested VLAN %s doesn't seem to exist on device...", $vlan)); } } return; } sub agg_ports { return agg_ports_ifstack(@_) } 1; __END__ =head1 NAME SNMP::Info::Layer2::HP - SNMP Interface to HP Procurve Switches =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $hp = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $hp->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a HP ProCurve Switch via SNMP. Note: Some HP Switches will connect via SNMP version 1, but a lot of config data will not be available. Make sure you try and connect with Version 2 first, and then fail back to version 1. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $hp = new SNMP::Info::Layer2::HP(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2 =item SNMP::Info::MAU =back =head2 Required MIBs =over =item F Included in V2 mibs from Cisco =item F (this MIB new with SNMP::Info 0.8) =item F =item F =item F =item F =item F =back The last four MIBs listed are from HP and can be found at L or L =head1 Change Log Version 0.4 - Removed F e_*() methods to separate sub-class - SNMP::Info::Entity =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $hp->cpu() Returns CPU Utilization in percentage. =item $hp->log() Returns all the log entries from the switch's log that are not Link up or down messages. =item $hp->mem_free() Returns bytes of free memory =item $hp->mem_total() Return bytes of total memory =item $hp->mem_used() Returns bytes of used memory =item $hp->model() Returns the model number of the HP Switch. Will translate between the HP Part number and the common model number with this map : %MODEL_MAP = ( 'J8131A' => 'WAP-420-WW', 'J8130A' => 'WAP-420-NA', 'J8133A' => 'AP520WL', 'J8680A' => '9408sl', 'J9091A' => '8212zl', 'J9475A' => '8206zl', 'J9265A' => '6600ml-24XG', 'J9264A' => '6600ml-24G-4XG', 'J9263A' => '6600ml-24G', 'J9452A' => '6600-48G-4XG', 'J9451A' => '6600-48G', 'J8474A' => '6410cl-6XG', 'J8433A' => '6400cl-6XG', 'J8992A' => '6200yl-24G', 'J4902A' => '6108', 'J8698A' => '5412zl', 'J8719A' => '5408yl', 'J8697A' => '5406zl', 'J8718A' => '5404yl', 'J4819A' => '5308XL', 'J4850A' => '5304XL', 'J8773A' => '4208vl', 'J8770A' => '4204vl', 'J8772A' => '4202vl-72', 'J9032A' => '4202vl-68G', 'J9031A' => '4202vl-68', 'J8771A' => '4202vl-48G', 'J4865A' => '4108GL', 'J4887A' => '4104GL', 'J9588A' => '3800-48G-PoE+-4XG', 'J9574A' => '3800-48G-PoE+-4SFP+', 'J9586A' => '3800-48G-4XG', 'J9576A' => '3800-48G-4SFP+', 'J9584A' => '3800-24SFP-2SFP+', 'J9587A' => '3800-24G-PoE+-2XG', 'J9573A' => '3800-24G-PoE+-2SFP+', 'J9585A' => '3800-24G-2XG', 'J9575A' => '3800-24G-2SFP+', 'J8693A' => '3500yl-48G-PWR', 'J8692A' => '3500yl-24G-PWR', 'J9473A' => '3500-48-PoE', 'J9472A' => '3500-48', 'J9471A' => '3500-24-PoE', 'J9470A' => '3500-24', 'J4906A' => '3400cl-48G', 'J4905A' => '3400cl-24G', 'J4815A' => '3324XL', 'J4851A' => '3124', 'J9562A' => '2915-8G-PoE', 'J9148A' => '2910al-48G-PoE+', 'J9147A' => '2910al-48G', 'J9146A' => '2910al-24G-PoE+', 'J9145A' => '2910al-24G', 'J9050A' => '2900-48G', 'J9049A' => '2900-24G', 'J4904A' => '2848', 'J4903A' => '2824', 'J9022A' => '2810-48G', 'J9021A' => '2810-24G', 'J8165A' => '2650-PWR', 'J4899B' => '2650-CR', 'J4899C' => '2650C', 'J4899A' => '2650', 'J8164A' => '2626-PWR', 'J4900B' => '2626-CR', 'J4900C' => '2626C', 'J4900A' => '2626', 'J9627A' => '2620-48-PoE+', 'J9626A' => '2620-48', 'J9624A' => '2620-24-PPoE+', 'J9625A' => '2620-24-PoE+', 'J9623A' => '2620-24', 'J9565A' => '2615-8-PoE', 'J9089A' => '2610-48-PWR', 'J9088A' => '2610-48', 'J9087A' => '2610-24-PWR', 'J9086A' => '2610-24/12PWR', 'J9085A' => '2610-24', 'J8762A' => '2600-8-PWR', 'J4813A' => '2524', 'J9298A' => '2520G-8-PoE', 'J9299A' => '2520G-24-PoE', 'J9137A' => '2520-8-PoE', 'J9138A' => '2520-24-PoE', 'J4812A' => '2512', 'J9280A' => '2510G-48', 'J9279A' => '2510G-24', 'J9020A' => '2510-48A', 'J9019B' => '2510-24B', 'J9019A' => '2510-24A', 'J4818A' => '2324', 'J4817A' => '2312', 'J9449A' => '1810G-8', 'J9450A' => '1810G-24', 'J9029A' => '1800-8G', 'J9028A' => '1800-24G', ); =item $hp->os() Returns hp =item $hp->os_bin() C =item $hp->os_ver() Tries to use os_version() and if that fails will try and cull the version from the description field. =item $hp->os_version() C =item $hp->serial() Returns serial number if available through SNMP =item $hp->slots() Returns number of entries in $hp->e_name that have 'slot' in them. =item $hp->vendor() hp =item $hp->fan() Returns fan status =item $hp->ps1_status() Power supply 1 status =item $hp->ps2_status() Power supply 2 status =item $hp->peth_port_power() Power supplied by PoE ports, in milliwatts (C) =item $hp->stp_ver() Returns what version of STP the device is running. (C with fallback to inherited stp_ver()) =back =head2 Globals imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Globals imported from SNMP::Info::MAU See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over 4 =item $hp->interfaces() Uses $hp->i_description() =item $hp->i_duplex() Returns reference to map of IIDs to current link duplex. =item $hp->i_duplex_admin() Returns reference to hash of IIDs to admin duplex setting. =item $hp->vendor_i_type() Returns reference to hash of IIDs to HP specific port type (C). =item $hp->i_name() Crosses i_name() with $hp->e_name() using $hp->e_port() and i_alias() =item $hp->peth_port_ifindex() Returns reference to hash of power Ethernet port table entries map back to interface index (c) =item C Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =back =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =head1 MUNGES =over =item munge_hp_c_id() Munge for c_id which handles CDP and LLDP. =back =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item set_i_vlan() =item set_i_vlan_tagged() =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/HP4000.pm000444000765000024 4556613215550564 17632 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::HP4000 - SNMP Interface to older HP ProCurve Switches (1600, 2400, 2424M, 4000 and 8000) # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::HP4000; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::MAU; use SNMP::Info::CDP; @SNMP::Info::Layer2::HP4000::ISA = qw/SNMP::Info::Layer3 SNMP::Info::MAU SNMP::Info::CDP Exporter/; @SNMP::Info::Layer2::HP4000::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MODEL_MAP %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::MAU::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::CDP::MIBS, 'RFC1271-MIB' => 'logDescription', 'HP-ICF-OID' => 'hpSwitch4000', 'HP-VLAN' => 'hpVlanMemberIndex', 'STATISTICS-MIB' => 'hpSwitchCpuStat', 'NETSWITCH-MIB' => 'hpMsgBufFree', 'CONFIG-MIB' => 'hpSwitchConfig', 'SEMI-MIB' => 'hpHttpMgSerialNumber', 'HP-ICF-CHASSIS' => 'hpicfSensorObjectId', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::MAU::GLOBALS, %SNMP::Info::CDP::GLOBALS, 'serial1' => 'hpHttpMgSerialNumber.0', 'hp_cpu' => 'hpSwitchCpuStat.0', 'hp_mem_total' => 'hpGlobalMemTotalBytes.1', 'mem_free' => 'hpGlobalMemFreeBytes.1', 'mem_used' => 'hpGlobalMemAllocBytes.1', 'os_version' => 'hpSwitchOsVersion.0', 'os_bin' => 'hpSwitchRomVersion.0', 'mac' => 'hpSwitchBaseMACAddress.0', 'hp_vlans' => 'hpVlanNumber', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::MAU::FUNCS, %SNMP::Info::CDP::FUNCS, 'bp_index2' => 'dot1dBasePortIfIndex', 'i_type2' => 'ifType', # RFC1271 'l_descr' => 'logDescription', # HP-VLAN-MIB 'hp_v_index' => 'hpVlanDot1QID', 'hp_v_name' => 'hpVlanIdentName', 'hp_v_state' => 'hpVlanIdentState', 'hp_v_type' => 'hpVlanIdentType', 'hp_v_status' => 'hpVlanIdentStatus', 'hp_v_mac' => 'hpVlanAddrPhysAddress', 'hp_v_if_index' => 'hpVlanMemberIndex', 'hp_v_if_tag' => 'hpVlanMemberTagged2', # CONFIG-MIB::hpSwitchPortTable 'hp_duplex' => 'hpSwitchPortEtherMode', 'hp_duplex_admin' => 'hpSwitchPortFastEtherMode', 'vendor_i_type' => 'hpSwitchPortType', # HP-ICF-CHASSIS 'hp_s_oid' => 'hpicfSensorObjectId', 'hp_s_name' => 'hpicfSensorDescr', 'hp_s_status' => 'hpicfSensorStatus', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::Layer3::MUNGE, %SNMP::Info::MAU::MUNGE, %SNMP::Info::CDP::MUNGE ); %MODEL_MAP = ( 'J4093A' => '2424M', 'J4110A' => '8000M', 'J4120A' => '1600M', 'J4121A' => '4000M', 'J4122A' => '2400M', 'J4122B' => '2424M', ); # Method Overrides sub cpu { my $hp = shift; return $hp->hp_cpu(); } sub mem_total { my $hp = shift; return $hp->hp_mem_total(); } sub os { return 'hp'; } sub os_ver { my $hp = shift; my $os_version = $hp->os_version(); return $os_version if defined $os_version; # Some older ones don't have this value,so we cull it from the description my $descr = $hp->description(); if ( $descr =~ m/revision ([A-Z]{1}\.\d{2}\.\d{2})/ ) { return $1; } return; } # Lookup model number, and translate the part number to the common number sub model { my $hp = shift; my $id = $hp->id(); return unless defined $id; my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^hpswitch//i; return defined $MODEL_MAP{$model} ? $MODEL_MAP{$model} : $model; } sub interfaces { my $hp = shift; my $interfaces = $hp->i_index(); my $i_descr = $hp->i_description(); my %if; foreach my $iid ( keys %$interfaces ) { my $descr = $i_descr->{$iid}; next unless defined $descr; $if{$iid} = $descr if ( defined $descr and length $descr ); } return \%if } sub i_name { my $hp = shift; my $i_alias = $hp->i_alias(); my $e_name = $hp->e_name(); my $e_port = $hp->e_port(); my %i_name; foreach my $port ( keys %$e_name ) { my $iid = $e_port->{$port}; next unless defined $iid; my $alias = $i_alias->{$iid}; next unless defined $iid; $i_name{$iid} = $e_name->{$port}; # Check for alias $i_name{$iid} = $alias if ( defined $alias and length($alias) ); } return \%i_name; } sub i_duplex { my $hp = shift; return $hp->mau_i_duplex(); } sub i_duplex_admin { my $hp = shift; my $partial = shift; # Try HP MIB first my $hp_duplex = $hp->hp_duplex_admin($partial); if ( defined $hp_duplex and scalar( keys %$hp_duplex ) ) { my %i_duplex; foreach my $if ( keys %$hp_duplex ) { my $duplex = $hp_duplex->{$if}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $duplex = 'auto' if $duplex =~ /auto/i; $i_duplex{$if} = $duplex; } return \%i_duplex; } else { return $hp->mau_i_duplex_admin(); } } sub vendor { return 'hp'; } sub log { my $hp = shift; my $log = $hp->l_descr(); my $logstring = undef; foreach my $val ( values %$log ) { next if $val =~ /^Link\s+(Up|Down)/; $logstring .= "$val\n"; } return $logstring; } sub slots { my $hp = shift; my $e_name = $hp->e_name(); return unless defined $e_name; my $slots; foreach my $slot ( keys %$e_name ) { $slots++ if $e_name->{$slot} =~ /slot/i; } return $slots; } sub fan { my $hp = shift; return &_sensor( $hp, 'fan' ); } sub ps1_status { my $hp = shift; return &_sensor( $hp, 'power', '^power supply 1' ) || &_sensor( $hp, 'power', '^power supply sensor' ); } sub ps2_status { my $hp = shift; return &_sensor( $hp, 'power', '^power supply 2' ) || &_sensor( $hp, 'power', '^redundant' ); } sub _sensor { my $hp = shift; my $search_type = shift || 'fan'; my $search_name = shift || ''; my $hp_s_oid = $hp->hp_s_oid(); my $result; foreach my $sensor ( keys %$hp_s_oid ) { my $sensortype = &SNMP::translateObj( $hp_s_oid->{$sensor} ); if ( $sensortype =~ /$search_type/i ) { my $sensorname = $hp->hp_s_name()->{$sensor}; my $sensorstatus = $hp->hp_s_status()->{$sensor}; if ( $sensorname =~ /$search_name/i ) { $result = $sensorstatus; } } } return $result; } # Bridge MIB does not map Bridge Port to ifIndex correctly on older models, but Bridge Port equals ifIndex in these devices sub bp_index { my $hp = shift; my $partial = shift; my $if_index = $hp->i_index($partial); my %mod_bp_index; foreach my $iid ( keys %$if_index ) { $mod_bp_index{$iid} = $iid; } return \%mod_bp_index; } # VLAN methods. Devices in this class use the proprietary HP-VLAN-MIB. sub v_index { my $hp = shift; my $partial = shift; return $hp->hp_v_index($partial); } sub v_name { my $hp = shift; my $partial = shift; return $hp->hp_v_name($partial); } sub i_vlan { my $hp = shift; # the hpvlanmembertagged2 table has an entry in the form of # vlan.interface = /untagged/no/tagged/auto my $i_vlan = {}; my $hp_v_index = $hp->hp_v_index(); my $hp_v_if_tag = $hp->hp_v_if_tag(); foreach my $row ( keys %$hp_v_if_tag ) { my ( $index, $if ) = split( /\./, $row ); my $tag = $hp_v_if_tag->{$row}; my $vlan = $hp_v_index->{$index}; next unless ( defined $tag and $tag =~ /untagged/ ); $i_vlan->{$if} = $vlan if defined $vlan; } return $i_vlan; } sub i_vlan_membership { my $hp = shift; my $i_vlan_membership = {}; my $hp_v_index = $hp->hp_v_index(); my $hp_v_if_tag = $hp->hp_v_if_tag(); foreach my $row ( keys %$hp_v_if_tag ) { my ( $index, $if ) = split( /\./, $row ); my $tag = $hp_v_if_tag->{$row}; my $vlan = $hp_v_index->{$index}; next unless ( defined $tag ); next if ( $tag eq 'no' ); push( @{ $i_vlan_membership->{$if} }, $vlan ); } return $i_vlan_membership; } sub i_vlan_membership_untagged { my $hp = shift; my $partial = shift; my $vlans = $hp->i_vlan($partial); my $i_vlan_membership = {}; foreach my $port (keys %$vlans) { my $vlan = $vlans->{$port}; push( @{ $i_vlan_membership->{$port} }, $vlan ); } return $i_vlan_membership; } sub set_i_vlan { my $hp = shift; my $rv; my $hp_v_index = $hp->hp_v_index(); my $hp_v_if_tag = $hp->hp_v_if_tag(); if (defined $hp_v_index and scalar(keys %$hp_v_index)){ my $vlan = shift; my $iid = shift; my $old_untagged; # Hash to lookup VLAN index of the VID (dot1q tag) my %vl_trans = reverse %$hp_v_index; # Translate the VLAN identifier (tag) value to the index used by the HP-VLAN MIB my $vlan_index = $vl_trans{$vlan}; if (defined $vlan_index) { # First, loop through table to determine current untagged vlan for the port we're about to change foreach my $row (keys %$hp_v_if_tag){ my ($index,$if) = split(/\./,$row); if ($if == $iid and $hp_v_if_tag->{$row} =~ /untagged/) { # Store the row information of the current untagged VLAN and temporarily set it to tagged $old_untagged = $row; $rv = $hp->set_hp_v_if_tag(1, $row); last; } } # Then set our port untagged in the desired VLAN my $rv = $hp->set_hp_v_if_tag(2, "$vlan_index.$iid"); if (defined $rv) { # If vlan change is successful, remove VLAN that used to be untagged from the port if (defined $old_untagged) { $rv = $hp->set_hp_v_if_tag(3, $old_untagged); $hp->error_throw("Error removing previous untagged vlan from port, should never happen...\n") unless defined $rv; } } else { # If vlan change was not succesful, try to revert to the old situation. if (defined $old_untagged) { $rv = $hp->set_hp_v_if_tag(2, $old_untagged) if defined $old_untagged; if (defined $rv) { $hp->error_throw("VLAN change failed, restored port to previous configuration.\n"); } else { $hp->error_throw("VLAN change failed, unable to restore old configuration. Check device.\n"); } } } } else { $hp->error_throw("Requested VLAN (VLAN ID: $vlan) not available on device.\n"); } } else { $hp->error_throw("Error retrieving VLAN information from device.\n"); } return $rv; } sub set_i_vlan_tagged { my $hp = shift; my $vlan = shift; my $iid = shift; my $rv; my $hp_v_index = $hp->hp_v_index(); if (defined $hp_v_index and scalar(keys %$hp_v_index)){ # Hash to lookup VLAN index of the VID (dot1q tag) my %vl_trans = reverse %$hp_v_index; # Translate the VLAN identifier (tag) value to the index used by the HP-VLAN MIB my $vlan_index = $vl_trans{$vlan}; if (defined $vlan_index) { # Set our port tagged in the desired VLAN $rv = $hp->set_hp_v_if_tag(1, "$vlan_index.$iid"); } else { $hp->error_throw("Requested VLAN (VLAN ID: $vlan) not available on device.\n"); } } return $rv; } 1; __END__ =head1 NAME SNMP::Info::Layer2::HP4000 - SNMP Interface to older HP ProCurve Switches (1600, 2400, 2424M, 4000 and 8000) =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $hp = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $hp->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a HP ProCurve Switch via SNMP. Note: Some HP Switches will connect via SNMP version 1, but a lot of config data will not be available. Make sure you try and connect with Version 2 first, and then fail back to version 1. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $hp = new SNMP::Info::Layer2::HP4000(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2 =item SNMP::Info::MAU =back =head2 Required MIBs =over =item F Included in V2 mibs from Cisco =item F =item F (this MIB new with SNMP::Info 0.8) =item F =item F =item F =back The last five MIBs listed are from HP and can be found at L or L =head1 Change Log Version 0.4 - Removed F e_*() methods to separate sub-class - SNMP::Info::Entity =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $hp->cpu() Returns CPU Utilization in percentage. =item $hp->log() Returns all the log entries from the switch's log that are not Link up or down messages. =item $hp->mem_free() Returns bytes of free memory =item $hp->mem_total() Return bytes of total memory =item $hp->mem_used() Returns bytes of used memory =item $hp->model() Returns the model number of the HP Switch. Will translate between the HP Part number and the common model number with this map : %MODEL_MAP = ( 'J4093A' => '2424M', 'J4110A' => '8000M', 'J4120A' => '1600M', 'J4121A' => '4000M', 'J4122A' => '2400M', 'J4122B' => '2424M', ); =item $hp->os() Returns hp =item $hp->os_bin() C =item $hp->os_ver() Tries to use os_version() and if that fails will try and cull the version from the description field. =item $hp->os_version() C =item $hp->serial() Returns serial number if available through SNMP =item $hp->slots() Returns number of entries in $hp->e_name that have 'slot' in them. =item $hp->vendor() hp =item $hp->fan() Returns fan status =item $hp->ps1_status() Power supply 1 status =item $hp->ps2_status() Power supply 2 status =back =head2 Globals imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Globals imported from SNMP::Info::MAU See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $hp->interfaces() Uses $hp->i_description() =item $hp->i_duplex() Returns reference to map of IIDs to current link duplex. =item $hp->i_duplex_admin() Returns reference to hash of IIDs to admin duplex setting. =item $hp->vendor_i_type() Returns reference to hash of IIDs to HP specific port type (C). =item $hp->i_name() Crosses i_name() with $hp->e_name() using $hp->e_port() and i_alias() =item $hp->i_vlan() Returns a mapping between C and the PVID (default VLAN) or untagged port when using F. =item $hp->i_vlan_membership() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the egress list for the port. It is the union of tagged, untagged, and auto ports. Example: my $interfaces = $hp->interfaces(); my $vlans = $hp->i_vlan_membership(); foreach my $iid (sort keys %$interfaces) { my $port = $interfaces->{$iid}; my $vlan = join(',', sort(@{$vlans->{$iid}})); print "Port: $port VLAN: $vlan\n"; } =item $hp->i_vlan_membership_untagged() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port. =item $hp->v_index() Returns VLAN IDs =item $hp->v_name() Returns VLAN names =item $hp->bp_index() Returns reference to hash of bridge port table entries map back to interface identifier (iid) Returns (C) for both key and value for 1600, 2424, 4000, and 8000 models since they seem to have problems with F =back =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item set_i_vlan() =item set_i_vlan_tagged() =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/HPVC.pm000444000765000024 1161113215550564 17537 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::HPVC - SNMP Interface to HP VirtualConnect Switches # # Copyright (c) 2011 Jeroen van Ingen # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::HPVC; use strict; use Exporter; use SNMP::Info::Layer2; use SNMP::Info::LLDP; @SNMP::Info::Layer2::HPVC::ISA = qw/SNMP::Info::Layer2 SNMP::Info::LLDP Exporter/; @SNMP::Info::Layer2::HPVC::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::LLDP::MIBS, 'HPVC-MIB' => 'vcDomainName', 'CPQSINFO-MIB' => 'cpqSiSysSerialNum', 'HPVCMODULE-MIB' => 'vcModuleDomainName', ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'serial1' => 'cpqSiSysSerialNum.0', 'os_ver' => 'cpqHoSWRunningVersion.1', 'os_bin' => 'cpqHoFwVerVersion.1', 'productname' => 'cpqSiProductName.0', ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::Layer2::MUNGE, %SNMP::Info::LLDP::MUNGE, ); # Method Overrides sub os { return 'hpvc'; } sub vendor { return 'hp'; } sub model { my $hp = shift; return $hp->productname(); } 1; __END__ =head1 NAME SNMP::Info::Layer2::HPVC - SNMP Interface to HP Virtual Connect Switches =head1 AUTHOR Jeroen van Ingen =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $hp = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $hp->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a HP Virtual Connect Switch via SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $hp = new SNMP::Info::Layer2::HPVC(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item F =item F =item F =back All required MIBs can be found in the netdisco-mibs package. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $hp->os() Returns C<'hpvc'> =item $hp->os_bin() C =item $hp->os_ver() C =item $hp->serial() C =item $hp->vendor() hp =item $hp->model() C =back =head2 Globals imported from SNMP::Info::Layer2 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =back =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =head1 MUNGES =over =back =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Kentrox.pm000444000765000024 1042313215550564 20431 0ustar00oliverstaff000000000000package SNMP::Info::Layer2::Kentrox; # Copyright (c) 2011 Netdisco Project # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. use strict; use Exporter; use SNMP::Info::Layer2; @SNMP::Info::Layer2::Kentrox::ISA = qw/SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::Kentrox::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, #from DATASMART-MIB # MIB isn't yet in netdisco-mibs (not clear permission) # ... when it is, this can change to dsScWyv 'ds_sysinfo' => '.1.3.6.1.4.1.181.2.2.12.15.0', ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, ); sub os { return 'Kentrox'; } sub os_ver { my $dsver = shift; my $descr = $dsver->description(); if ( $descr =~ /^\S+\s\S+\s\S+\s(\S+)/){ return $1; } } sub serial { my $dsserial = shift; my $serial = $dsserial->ds_sysinfo(); if ( $serial =~ /SERIAL\s(\S+)/){ my $str = substr($1,8,10); return $str; } } sub vendor { return 'Kentrox'; } sub model { my $dsmodel = shift; my $descr = $dsmodel->description(); if ( $descr =~ /^(\S+\s\S+)/){ return $1; } } 1; __END__ =head1 NAME SNMP::Info::Layer2::Kentrox - SNMP Interface to L2 Kentrox DataSMART DSU/CSU =head1 AUTHOR phishphreek@gmail.com =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $router = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $router->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Kentrox DataSMART DSU/CSU =head2 Inherited Classes =over =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $router->vendor() =item $router->os() =item $router->os_ver() =item $router->model() =item $router->serial() =back =head2 Globals imported from SNMP::Info::Layer2 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =back =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/N2270.pm000444000765000024 1410113215550564 17504 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::N2270 # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::N2270; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Bridge; use SNMP::Info::SONMP; use SNMP::Info::Airespace; @SNMP::Info::Layer2::N2270::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::SONMP SNMP::Info::Airespace Exporter/; @SNMP::Info::Layer2::N2270::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::Bridge::MIBS, %SNMP::Info::SONMP::MIBS, %SNMP::Info::Airespace::MIBS, ); %GLOBALS = ( %SNMP::Info::GLOBALS, %SNMP::Info::Bridge::GLOBALS, %SNMP::Info::SONMP::GLOBALS, %SNMP::Info::Airespace::GLOBALS, ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::Bridge::FUNCS, %SNMP::Info::SONMP::FUNCS, %SNMP::Info::Airespace::FUNCS, ); %MUNGE = ( %SNMP::Info::MUNGE, %SNMP::Info::Bridge::MUNGE, %SNMP::Info::SONMP::MUNGE, %SNMP::Info::Airespace::MUNGE, ); sub os { return 'nortel'; } sub vendor { return 'nortel'; } sub model { my $n2270 = shift; my $id = $n2270->id(); return unless defined $id; my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^sreg-WLANSecuritySwitch//i; return $model; } sub index_factor { return 256; } sub slot_offset { return 0; } 1; __END__ =head1 NAME SNMP::Info::Layer2::N2270 - SNMP Interface to Nortel 2270 Series Wireless Switch =head1 AUTHOR Eric Miller =head1 SYNOPSIS #Let SNMP::Info determine the correct subclass for you. my $n2270 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $n2270->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Nortel 2270 Series Wireless Switch through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $n2270 = new SNMP::Info::Layer2::N2270(...); =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Bridge =item SNMP::Info::SONMP =item SNMP::Info::Airespace =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $n2270->vendor() Returns 'nortel' =item $n2270->os() Returns 'nortel' =item $n2270->model() Cross references $bayhub->id() to the F and returns the results. Removes C from the model name =back =head2 Overrides =over =item $bayhub->index_factor() Required by SNMP::Info::SONMP. Number representing the number of ports reserved per slot within the device MIB. Returns 256. =item $bayhub->slot_offset() Required by SNMP::Info::SONMP. Offset if slot numbering does not start at 0. Returns 0. =back =head2 Globals imported from SNMP::Info See documentation in L for details. =head2 Globals imported from SNMP::Info::Bridge See documentation in L for details. =head2 Global Methods imported from SNMP::Info::SONMP See documentation in L for details. =head2 Global Methods imported from SNMP::Info::Airespace See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item None =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Bridge See documentation in L for details. =head2 Table Methods imported from SNMP::Info::SONMP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Airespace See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/NAP222x.pm000444000765000024 3427713215550564 20050 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::NAP222x # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::NAP222x; use strict; use Exporter; use SNMP::Info::SONMP; use SNMP::Info::IEEE802dot11; use SNMP::Info::Layer2; @SNMP::Info::Layer2::NAP222x::ISA = qw/SNMP::Info::SONMP SNMP::Info::IEEE802dot11 SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::NAP222x::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::IEEE802dot11::MIBS, %SNMP::Info::SONMP::MIBS, 'NORTEL-WLAN-AP-MIB' => 'ntWlanSwHardwareVer', ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::IEEE802dot11::GLOBALS, %SNMP::Info::SONMP::GLOBALS, 'nt_hw_ver' => 'ntWlanSwHardwareVer', 'nt_fw_ver' => 'ntWlanSwBootRomVer', 'nt_sw_ver' => 'ntWlanSwOpCodeVer', 'nt_cc' => 'ntWlanSwCountryCode', 'tftp_action' => 'ntWlanTransferStart', 'tftp_host' => 'ntWlanFileServer', 'tftp_file' => 'ntWlanDestFile', 'tftp_type' => 'ntWlanFileType', 'tftp_result' => 'ntWlanFileTransferStatus', 'tftp_xtype' => 'ntWlanTransferType', 'tftp_src_file' => 'ntWlanSrcFile', 'ftp_user' => 'ntWlanUserName', 'ftp_pass' => 'ntWlanPassword', ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::IEEE802dot11::FUNCS, %SNMP::Info::SONMP::FUNCS, # From ntWlanPortTable 'nt_prt_name' => 'ntWlanPortName', 'nt_dpx_admin' => 'ntWlanPortCapabilities', 'nt_auto' => 'ntWlanPortAutonegotiation', 'nt_dpx' => 'ntWlanPortSpeedDpxStatus', # From ntWlanDot11PhyOperationTable 'nt_i_broadcast' => 'ntWlanDot11ClosedSystem', # From ntWlanApVlanTable 'nt_i_vlan' => 'ntWlanApVlanDefaultVid', ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::IEEE802dot11::MUNGE, %SNMP::Info::SONMP::MUNGE, ); sub os { return 'nortel'; } sub os_bin { my $nap222x = shift; my $bin = $nap222x->nt_fw_ver(); return unless defined $bin; if ( $bin =~ m/(\d+\.\d+\.\d+)/ ) { return $1; } return; } sub model { my $nap222x = shift; my $descr = $nap222x->description(); return unless defined $descr; return 'AP-2220' if ( $descr =~ /2220/ ); return 'AP-2221' if ( $descr =~ /2221/ ); return; } sub mac { my $nap222x = shift; my $i_mac = $nap222x->i_mac(); # Return Interface MAC foreach my $entry ( keys %$i_mac ) { my $sn = $i_mac->{$entry}; next unless $sn; return $sn; } return; } sub serial { my $nap222x = shift; my $i_mac = $nap222x->i_mac(); # Return Interface MAC foreach my $entry ( keys %$i_mac ) { my $sn = $i_mac->{$entry}; next unless $sn; return $sn; } return; } sub interfaces { my $nap222x = shift; my $partial = shift; my $interfaces = $nap222x->i_index($partial) || {}; my $description = $nap222x->i_description($partial) || {}; my %interfaces = (); foreach my $iid ( keys %$interfaces ) { my $desc = $description->{$iid}; next unless defined $desc; next if $desc =~ /lo/i; $interfaces{$iid} = $desc; } return \%interfaces; } sub i_duplex { my $nap222x = shift; my $partial = shift; my $mode = $nap222x->nt_dpx($partial) || {}; my $port_name = $nap222x->nt_prt_name($partial) || {}; my $interfaces = $nap222x->interfaces($partial) || {}; my %i_duplex; foreach my $if ( keys %$interfaces ) { my $port = $interfaces->{$if}; next unless $port =~ /dp/i; foreach my $idx ( keys %$mode ) { my $name = $port_name->{$idx} || 'unknown'; next unless $name eq $port; my $duplex = $mode->{$idx}; $duplex = 'other' unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $i_duplex{$if} = $duplex; } } return \%i_duplex; } sub i_duplex_admin { my $nap222x = shift; my $partial = shift; my $dpx_admin = $nap222x->nt_dpx_admin($partial) || {}; my $nt_auto = $nap222x->nt_auto($partial) || {}; my $interfaces = $nap222x->interfaces($partial) || {}; my $port_name = $nap222x->nt_prt_name($partial) || {}; my %i_duplex_admin; foreach my $if ( keys %$interfaces ) { my $port = $interfaces->{$if}; next unless $port =~ /dp/i; foreach my $idx ( keys %$dpx_admin ) { my $name = $port_name->{$idx} || 'unknown'; next unless $name eq $port; my $duplex = $dpx_admin->{$idx}; my $auto = $nt_auto->{$idx}; $duplex = 'other' unless defined $duplex; $duplex = 'half' if ( $duplex =~ /half/i and $auto =~ /disabled/i ); $duplex = 'full' if ( $duplex =~ /full/i and $auto =~ /disabled/i ); $duplex = 'auto' if $auto =~ /enabled/i; $i_duplex_admin{$if} = $duplex; } } return \%i_duplex_admin; } sub i_name { my $nap222x = shift; my $partial = shift; my $interfaces = $nap222x->interfaces($partial) || {}; my %i_name; foreach my $if ( keys %$interfaces ) { my $desc = $interfaces->{$if}; next unless defined $desc; my $name = 'unknown'; $name = 'Ethernet Interface' if $desc =~ /dp/i; $name = 'Wireless Interface B' if $desc =~ /ndc/i; $name = 'Wireless Interface A' if $desc =~ /ar/i; $i_name{$if} = $name; } return \%i_name; } # dot1dBasePortTable does not exist and dot1dTpFdbPort does not map to ifIndex sub bp_index { my $nap222x = shift; my $partial = shift; my $interfaces = $nap222x->interfaces($partial) || {}; my %bp_index; foreach my $iid ( keys %$interfaces ) { my $desc = $interfaces->{$iid}; next unless defined $desc; next unless $desc =~ /(ndc|ar)/i; my $port = 1; $port = 2 if $desc =~ /ndc/i; $bp_index{$port} = $iid; } return \%bp_index; } # Indicies don't match anywhere in these devices! Need to override to match # IfIndex. sub i_ssidlist { my $nap222x = shift; my $partial = shift; # modify partial to match index if ( defined $partial ) { $partial = $partial - 2; } my $ssids = $nap222x->orig_i_ssidlist($partial) || {}; my %i_ssidlist; foreach my $iid ( keys %$ssids ) { my $port = $iid + 2; my $ssid = $ssids->{$iid}; next unless defined $ssid; $i_ssidlist{$port} = $ssid; } return \%i_ssidlist; } sub i_ssidbcast { my $nap222x = shift; my $partial = shift; # modify partial to match index if ( defined $partial ) { $partial = $partial - 2; } my $bcast = $nap222x->nt_i_broadcast($partial) || {}; my %i_ssidbcast; foreach my $iid ( keys %$bcast ) { my $port = $iid + 2; my $bc = $bcast->{$iid}; next unless defined $bc; $i_ssidbcast{$port} = $bc; } return \%i_ssidbcast; } sub i_80211channel { my $nap222x = shift; my $partial = shift; # modify partial to match index if ( defined $partial ) { $partial = $partial - 2; } my $phy_type = $nap222x->dot11_phy_type($partial) || {}; my $cur_freq = $nap222x->dot11_cur_freq() || {}; my $cur_ch = $nap222x->dot11_cur_ch() || {}; my %i_80211channel; foreach my $iid ( keys %$phy_type ) { my $port = $iid + 2; my $type = $phy_type->{$iid}; next unless defined $type; if ( $type =~ /dsss/ ) { my $ch = $cur_ch->{1}; next unless defined $ch; $i_80211channel{$port} = $ch; } elsif ( $type =~ /ofdm/ ) { my $ch = $cur_freq->{0}; next unless defined $ch; $i_80211channel{$port} = $ch; } else { next; } } return \%i_80211channel; } sub i_vlan { my $nap222x = shift; my $partial = shift; # modify partial to match index if ( defined $partial ) { $partial = $partial - 2; } my $vlans = $nap222x->nt_i_vlan($partial) || {}; my %i_vlan; foreach my $iid ( keys %$vlans ) { my $port = $iid + 2; my $vlan = $vlans->{$iid}; next unless defined $vlan; $i_vlan{$port} = $vlan; } return \%i_vlan; } 1; __END__ =head1 NAME SNMP::Info::Layer2::NAP222x - SNMP Interface to Nortel 2220 Series Access Points =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $nap222x = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $nap222x->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Nortel 2220 series wireless Access Points through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $nap222x = new SNMP::Info::Layer2::NAP222x(...); =head2 Inherited Classes =over =item SNMP::Info::SONMP =item SNMP::Info::IEEE802dot11 =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item F =back =head2 Inherited MIBs See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $nap222x->model() Returns the model extracted from C. =item $nap222x->os() Returns 'nortel' =item $nap222x->os_bin() Returns the firmware version extracted from C. =item $nap222x->mac() Returns the MAC address of the first Ethernet Interface. =item $nap222x->serial() Returns the MAC address of the first Ethernet Interface. =item $nap222x->nt_hw_ver() Returns the hardware version. (C) =item $nap222x->nt_cc() Returns the country code of the AP. (C) =item $nap222x->tftp_action() (C) =item $nap222x->tftp_host() (C) =item $nap222x->tftp_file() (C) =item $nap222x->tftp_type() (C) =item $nap222x->tftp_result() (C) =item $nap222x->tftp_xtype() (C) =item $nap222x->tftp_src_file() (C) =item $nap222x->ftp_user() (C) =item $nap222x->ftp_pass() (C) =back =head2 Globals imported from SNMP::Info::SONMP See L for details. =head2 Global Methods imported from SNMP::Info::IEEE802dot11 See L for details. =head2 Global Methods imported from SNMP::Info::Layer2 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $nap222x->interfaces() Returns reference to map of IIDs to physical ports. =item $nap222x->i_duplex() Returns reference to hash. Maps port operational duplexes to IIDs. (C) =item $nap222x->i_duplex_admin() Returns reference to hash. Maps port admin duplexes to IIDs. (C) =item $nap222x->i_name() Returns a human name based upon port description. =item $nap222x->bp_index() Returns a mapping between C and the Bridge Table. This does not exist in the MIB and bridge port index is not the same as C so it is created. =item $nap222x->i_ssidlist() Returns reference to hash. SSID's recognized by the radio interface. =item $nap222x->i_ssidbcast() Returns reference to hash. Indicates whether the SSID is broadcast. =item $nap222x->i_80211channel() Returns reference to hash. Current operating frequency channel of the radio interface. =item $nap222x->i_vlan() The default Vlan ID of the radio interfaces. (C) =back =head2 Table Methods imported from SNMP::Info::SONMP See L for details. =head2 Table Methods imported from SNMP::Info::IEEE802dot11 See L for details. =head2 Table Methods imported from SNMP::Info::Layer2 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/NWSS2300.pm000444000765000024 7342013215550564 20104 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::NWSS2300 # # Copyright (c) 2012 Eric Miller # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::NWSS2300; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Bridge; @SNMP::Info::Layer2::NWSS2300::ISA = qw/SNMP::Info SNMP::Info::Bridge Exporter/; @SNMP::Info::Layer2::NWSS2300::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::Bridge::MIBS, 'NTWS-REGISTRATION-DEVICES-MIB' => 'ntwsSwitch2380', 'NTWS-AP-STATUS-MIB' => 'ntwsApStatNumAps', 'NTWS-CLIENT-SESSION-MIB' => 'ntwsClSessTotalSessions', 'NTWS-SYSTEM-MIB' => 'ntwsSysCpuAverageLoad', 'NTWS-BASIC-MIB' => 'ntwsVersionString', ); %GLOBALS = ( %SNMP::Info::GLOBALS, %SNMP::Info::Bridge::GLOBALS, 'os_ver' => 'ntwsVersionString', 'serial' => 'ntwsSerialNumber', 'mac' => 'dot1dBaseBridgeAddress', ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::Bridge::FUNCS, # NTWS-AP-STATUS-MIB::ntwsApStatApStatusTable 'nwss2300_ap_mac' => 'ntwsApStatApStatusBaseMac', 'nwss2300_ap_name' => 'ntwsApStatApStatusApName', 'nwss2300_ap_ip' => 'ntwsApStatApStatusIpAddress', #'nwss2300_ap_loc' => 'bsnAPLocation', 'nwss2300_ap_sw' => 'ntwsApStatApStatusSoftwareVer', 'nwss2300_ap_fw' => 'ntwsApStatApStatusBootVer', 'nwss2300_ap_model' => 'ntwsApStatApStatusModel', 'nwss2300_ap_type' => 'ntwsApStatApStatusModel', 'nwss2300_ap_status' => 'ntwsApStatApStatusApState', 'nwss2300_ap_vendor' => 'ntwsApStatApStatusManufacturerId', 'nwss2300_ap_num' => 'ntwsApStatApStatusApNum', 'nwss2300_ap_dapnum' => 'ntwsApStatApStatusPortOrDapNum', # NTWS-AP-STATUS-MIB::ntwsApStatRadioStatusTable 'nwss2300_apif_mac' => 'ntwsApStatRadioStatusBaseMac', 'nwss2300_apif_type' => 'ntwsApStatRadioStatusRadioPhyType', 'nwss2300_apif_ch_num' => 'ntwsApStatRadioStatusCurrentChannelNum', 'nwss2300_apif_power' => 'ntwsApStatRadioStatusCurrentPowerLevel', 'nwss2300_apif_admin' => 'ntwsApStatRadioStatusRadioMode', # NTWS-AP-STATUS-MIB::ntwsApStatRadioServiceTable 'nwss2300_apif_prof' => 'ntwsApStatRadioServServiceProfileName', # NTWS-AP-CONFIG-MIB::ntwsApConfServiceProfileTable 'nwss2300_ess_bcast' => 'ntwsApConfServProfBeaconEnabled', # NTWS-AP-CONFIG-MIB::ntwsApConfRadioConfigTable 'nwss2300_apcr_txpwr' => 'ntwsApConfRadioConfigTxPower', 'nwss2300_apcr_ch' => 'ntwsApConfRadioConfigChannel', 'nwss2300_apcr_mode' => 'ntwsApConfRadioConfigRadioMode', # NTWS-AP-CONFIG-MIB::ntwsApConfApConfigTable 'nwss2300_apc_descr' => 'ntwsApConfApConfigDescription', 'nwss2300_apc_loc' => 'ntwsApConfApConfigLocation', 'nwss2300_apc_name' => 'ntwsApConfApConfigApName', 'nwss2300_apc_model' => 'ntwsApConfApConfigApModelName', 'nwss2300_apc_serial' => 'ntwsApConfApConfigApSerialNum', # NTWS-CLIENT-SESSION-MIB::ntwsClSessClientSessionTable 'nwss2300_sta_slot' => 'ntwsClSessClientSessRadioNum', 'nwss2300_sta_serial' => 'ntwsClSessClientSessApSerialNum', 'nwss2300_sta_ssid' => 'ntwsClSessClientSessSsid', 'nwss2300_sta_ip' => 'ntwsClSessClientSessIpAddress', # NTWS-AP-STATUS-MIB::ntwsApStatRadioServiceTable 'nwss2300_apif_bssid' => 'ntwsApStatRadioServBssid', # NTWS-CLIENT-SESSION-MIB::ntwsClSessClientSessionStatisticsTable # Pretend to have the CISCO-DOT11-MIB for signal strengths, etc. 'cd11_sigstrength' => 'ntwsClSessClientSessStatsLastRssi', 'cd11_sigqual' => 'ntwsClSessClientSessStatsLastSNR', 'cd11_txrate' => 'ntwsClSessClientSessStatsLastRate', # These are supposed to be there... 'cd11_rxbyte' => 'ntwsClSessClientSessStatsUniOctetIn', 'cd11_txbyte' => 'ntwsClSessClientSessStatsUniOctetOut', 'cd11_rxpkt' => 'ntwsClSessClientSessStatsUniPktIn', 'cd11_txpkt' => 'ntwsClSessClientSessStatsUniPktOut', ); %MUNGE = ( %SNMP::Info::MUNGE, %SNMP::Info::Bridge::MUNGE, 'nwss2300_apif_mac' => \&SNMP::Info::munge_mac, 'nwss2300_apif_bssid' => \&SNMP::Info::munge_mac, ); sub layers { return '00000111'; } sub os { return 'trapeze'; } sub vendor { return 'avaya'; } sub model { my $nwss2300 = shift; my $id = $nwss2300->id(); unless ( defined $id ) { print " SNMP::Info::Layer2::NWSS2300::model() - Device does not support sysObjectID\n" if $nwss2300->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^ntwsSwitch//i; return $model; } sub _ap_serial { my $nwss2300 = shift; my $partial = shift; my $names = $nwss2300->nwss2300_ap_name($partial) || {}; my %ap_serial; foreach my $iid ( keys %$names ) { next unless $iid; my $serial = join( '', map { sprintf "%c", $_ } split /\./, $iid ); # Remove any control characters to include nulls $serial =~ s/[\c@-\c_]//g; $ap_serial{$iid} = "$serial"; } return \%ap_serial; } # Wireless switches do not support ifMIB requirements to get MAC # and port status sub i_index { my $nwss2300 = shift; my $partial = shift; my $i_index = $nwss2300->orig_i_index($partial) || {}; my $ap_index = $nwss2300->nwss2300_apif_mac($partial) || {}; my %if_index; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; $if_index{$iid} = $index; } # Get Attached APs as Interfaces foreach my $ap_id ( keys %$ap_index ) { my $mac = $ap_index->{$ap_id}; next unless ($mac); $if_index{$ap_id} = $mac; } return \%if_index; } sub interfaces { my $nwss2300 = shift; my $partial = shift; my $i_index = $nwss2300->i_index($partial) || {}; my $descriptions = $nwss2300->SUPER::i_description($partial) || {}; my %if; foreach my $iid ( keys %$i_index ) { my $desc = $descriptions->{$iid} || $i_index->{$iid}; next unless defined $desc; $if{$iid} = $desc; } return \%if; } sub i_description { my $nwss2300 = shift; my $partial = shift; my $i_index = $nwss2300->i_index($partial) || {}; my $i_desc = $nwss2300->orig_i_description($partial) || {}; my $ap_name = $nwss2300->nwss2300_ap_name($partial) || {}; my %i_name; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $name = $i_desc->{$iid}; next unless defined $name; $i_name{$iid} = $name; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $idx = $iid; $idx =~ s/\.(\d+)$//; my $radio = $1; $radio--; my $name = $ap_name->{$idx}; next unless defined $name; $i_name{$iid} = "Radio-$radio: $name"; } else { $i_name{$iid} = $index; } } return \%i_name; } sub i_name { my $nwss2300 = shift; my $partial = shift; return $nwss2300->i_description($partial); } sub i_type { my $nwss2300 = shift; my $partial = shift; my $i_index = $nwss2300->i_index($partial) || {}; my $i_type = $nwss2300->orig_i_type($partial) || {}; my %i_type; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $type = $i_type->{$iid}; next unless defined $type; $i_type{$iid} = $type; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { # Match to an ifType $i_type{$iid} = 'capwapWtpVirtualRadio'; } else { next; } } return \%i_type; } sub i_up { my $nwss2300 = shift; my $partial = shift; return $nwss2300->i_up_admin($partial); } sub i_up_admin { my $nwss2300 = shift; my $partial = shift; my $i_index = $nwss2300->i_index($partial) || {}; my $i_up = $nwss2300->orig_i_up($partial) || {}; my $apif_up = $nwss2300->nwss2300_apif_admin($partial) || {}; my %i_up_admin; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $stat = $i_up->{$iid}; next unless defined $stat; $i_up_admin{$iid} = $stat; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $stat = $apif_up->{$iid}; next unless defined $stat; $i_up_admin{$iid} = $stat; } else { next; } } return \%i_up_admin; } sub i_mac { my $nwss2300 = shift; my $partial = shift; my $i_index = $nwss2300->i_index($partial) || {}; my $i_mac = $nwss2300->orig_i_mac($partial) || {}; my %i_mac; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $mac = $i_mac->{$iid}; next unless defined $mac; $i_mac{$iid} = $mac; } # Don't grab AP MACs - we want the AP to show up on edge switch # ports else { next; } } return \%i_mac; } # Wireless switches do not support the standard Bridge MIB for client devices sub bp_index { my $nwss2300 = shift; my $partial = shift; my $i_index = $nwss2300->i_index($partial) || {}; my %bp_index; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; $bp_index{$index} = $iid; } return \%bp_index; } sub fw_mac { my $nwss2300 = shift; my $partial = shift; my $serials = $nwss2300->nwss2300_sta_serial($partial) || {}; my %fw_mac; foreach my $iid ( keys %$serials ) { next unless $iid; my $mac = join( ':', map { sprintf "%02x", $_ } split /\./, $iid ); next unless $mac =~ /^([0-9A-F][0-9A-F]:){5}[0-9A-F][0-9A-F]$/i; $fw_mac{$iid} = $mac; } return \%fw_mac; } sub fw_port { my $nwss2300 = shift; my $partial = shift; my $slots = $nwss2300->nwss2300_sta_slot($partial) || {}; my $serials = $nwss2300->nwss2300_sta_serial($partial) || {}; my $ap_serials = $nwss2300->_ap_serial($partial) || {}; my %serial_iid = reverse %$ap_serials; my %fw_port; foreach my $iid ( keys %$slots ) { my $slot = $slots->{$iid}; next unless defined $slot; $slot =~ s/radio-//i; my $serial = $serials->{$iid}; next unless defined $serial; my $index = $serial_iid{$serial}; next unless defined $index; $fw_port{$iid} = "$index.$slot"; } return \%fw_port; } sub i_ssidlist { my $nwss2300 = shift; my $partial = shift; my $apif_bssid = $nwss2300->nwss2300_apif_bssid($partial) || {}; my $i_index = $nwss2300->i_index($partial) || {}; my %i_ssidlist; foreach my $iid ( keys %$i_index ) { # Skip non-radio interfaces next if $iid =~ /^\d+$/; foreach my $idx ( keys %$apif_bssid ) { next unless ( $idx =~ /^$iid\./ ); my $bssid_mac = $apif_bssid->{$idx}; next unless $bssid_mac; # Give the SSID a numeric value based upon tail of BSSID my $id; if ( $bssid_mac =~ /:([0-9A-F]{1,2})$/i ) { $id = hex $1; } next unless ( defined $id and $id =~ /\d+/ ); my $ssid_oid = $idx; $ssid_oid =~ s/^$iid\.//; my $ssid = join( '', map { sprintf "%c", $_ } split /\./, $ssid_oid ); # Remove any control characters including nulls $ssid =~ s/[\c@-\c_]//g; $i_ssidlist{"$iid.$id"} = $ssid; } } return \%i_ssidlist; } # Can't find in MIB # #sub i_ssidbcast { # #} sub i_80211channel { my $nwss2300 = shift; my $partial = shift; my $ch_list = $nwss2300->nwss2300_apif_ch_num($partial) || {}; my %i_80211channel; foreach my $iid ( keys %$ch_list ) { my $ch = $ch_list->{$iid}; next unless $ch =~ /\d+/; $i_80211channel{$iid} = $ch; } return \%i_80211channel; } sub dot11_cur_tx_pwr_mw { my $nwss2300 = shift; my $partial = shift; my $cur = $nwss2300->nwss2300_apif_power($partial); my $dot11_cur_tx_pwr_mw = {}; foreach my $idx ( keys %$cur ) { my $pwr_dbm = $cur->{$idx}; next unless $pwr_dbm; #Convert to milliWatts = 10(dBm/10) my $pwr = int (10 ** ($pwr_dbm / 10)); $dot11_cur_tx_pwr_mw->{$idx} = $pwr; } return $dot11_cur_tx_pwr_mw; } # Pseudo ENTITY-MIB methods sub e_index { my $nwss2300 = shift; # Try new first, fall back to depreciated my $ap_num = $nwss2300->nwss2300_ap_num() || $nwss2300->nwss2300_ap_dapnum() || {}; my %e_index; # Chassis $e_index{1} = 1; # We're going to hack an index to capture APs foreach my $idx ( keys %$ap_num ) { my $number = $ap_num->{$idx}; next unless $number =~ /\d+/; $e_index{$idx} = $number; } return \%e_index; } sub e_class { my $nwss2300 = shift; my $e_idx = $nwss2300->e_index() || {}; my %e_class; foreach my $iid ( keys %$e_idx ) { if ( $iid eq "1" ) { $e_class{$iid} = 'chassis'; } # This isn't a valid PhysicalClass, but we're hacking this anyway else { $e_class{$iid} = 'ap'; } } return \%e_class; } sub e_name { my $nwss2300 = shift; my $ap_name = $nwss2300->nwss2300_ap_name() || {}; my %e_name; # Chassis $e_name{1} = 'WLAN Controller'; # APs foreach my $iid ( keys %$ap_name ) { $e_name{$iid} = 'AP'; } return \%e_name; } sub e_descr { my $nwss2300 = shift; my $ap_model = $nwss2300->nwss2300_ap_model() || {}; my $ap_name = $nwss2300->nwss2300_ap_name() || {}; my %e_descr; # Chassis $e_descr{1} = $nwss2300->model(); # APs foreach my $iid ( keys %$ap_name ) { my $name = $ap_name->{$iid}; next unless defined $name; my $model = $ap_model->{$iid} || 'AP'; $e_descr{$iid} = "$model: $name"; } return \%e_descr; } sub e_model { my $nwss2300 = shift; my $ap_model = $nwss2300->nwss2300_ap_model() || {}; my %e_model; # Chassis $e_model{1} = $nwss2300->model(); # APs foreach my $iid ( keys %$ap_model ) { my $model = $ap_model->{$iid}; next unless defined $model; $e_model{$iid} = $model; } return \%e_model; } sub e_type { my $nwss2300 = shift; return $nwss2300->e_model(); } sub e_fwver { my $nwss2300 = shift; my $ap_fw = $nwss2300->nwss2300_ap_fw() || {}; my %e_fwver; # APs foreach my $iid ( keys %$ap_fw ) { my $fw = $ap_fw->{$iid}; next unless defined $fw; $e_fwver{$iid} = $fw; } return \%e_fwver; } sub e_vendor { my $nwss2300 = shift; my $vendors = $nwss2300->nwss2300_ap_vendor() || {}; my %e_vendor; # Chassis $e_vendor{1} = 'avaya'; # APs foreach my $iid ( keys %$vendors ) { my $vendor = $vendors->{$iid}; next unless defined $vendor; $e_vendor{$iid} = $vendor; } return \%e_vendor; } sub e_serial { my $nwss2300 = shift; my $ap_serial = $nwss2300->_ap_serial() || {}; my %e_serial; # Chassis $e_serial{1} = $nwss2300->serial(); # APs foreach my $iid ( keys %$ap_serial ) { my $serial = $ap_serial->{$iid}; next unless defined $serial; $e_serial{$iid} = $serial; } return \%e_serial; } sub e_pos { my $nwss2300 = shift; my $e_idx = $nwss2300->e_index() || {}; my %e_pos; my $pos = 0; foreach my $iid ( sort keys %$e_idx ) { if ( $iid eq "1" ) { $e_pos{$iid} = -1; next; } else { $pos++; $e_pos{$iid} = $pos; } } return \%e_pos; } sub e_swver { my $nwss2300 = shift; my $ap_sw = $nwss2300->nwss2300_ap_sw() || {}; my %e_swver; # Chassis $e_swver{1} = $nwss2300->os_ver(); # APs foreach my $iid ( keys %$ap_sw ) { my $sw = $ap_sw->{$iid}; next unless defined $sw; $e_swver{$iid} = $sw; } return \%e_swver; } sub e_parent { my $nwss2300 = shift; my $e_idx = $nwss2300->e_index() || {}; my %e_parent; foreach my $iid ( sort keys %$e_idx ) { if ( $iid eq "1" ) { $e_parent{$iid} = 0; next; } else { $e_parent{$iid} = 1; } } return \%e_parent; } # arpnip: # # This is the controller snooping on the MAC->IP mappings. # Pretending this is arpnip data allows us to get MAC->IP # mappings even for stations that only communicate locally. sub at_paddr { my $nwss2300 = shift; my $mac2ip = $nwss2300->nwss2300_sta_ip(); my $ret = {}; foreach my $idx ( keys %$mac2ip ) { next if ( $mac2ip->{ $idx } eq '0.0.0.0' ); my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); $ret->{$idx} = $mac; } return $ret; } sub at_netaddr { my $nwss2300 = shift; my $mac2ip = $nwss2300->nwss2300_sta_ip(); my $ret = {}; foreach my $idx ( keys %$mac2ip ) { next if ( $mac2ip->{ $idx } eq '0.0.0.0' ); $ret->{$idx} = $mac2ip->{ $idx }; } return $ret; } # Client MAC sub cd11_mac { my $nwss2300 = shift; my $cd11_sigstrength = $nwss2300->cd11_sigstrength(); my $ret = {}; foreach my $idx ( keys %$cd11_sigstrength ) { my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); $ret->{$idx} = $mac } return $ret; } 1; __END__ =head1 NAME SNMP::Info::Layer2::NWSS2300 - SNMP Interface to Avaya (Trapeze) Wireless Controllers =head1 AUTHOR Eric Miller =head1 SYNOPSIS #Let SNMP::Info determine the correct subclass for you. my $nwss2300 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $nwss2300->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from Avaya (Trapeze) Wireless Controllers through SNMP. This class emulates bridge functionality for the wireless switch. This enables end station MAC addresses collection and correlation to the thin access point the end station is using for communication. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $nwss2300 = new SNMP::Info::Layer2::NWSS2300(...); =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Bridge =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =back =head2 Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $nwss2300->vendor() Returns 'avaya' =item $nwss2300->os() Returns 'trapeze' =item $nwss2300->os_ver() (C) =item $nwss2300->model() Tries to reference $nwss2300->id() to F Removes C<'ntwsSwitch'> for readability. =item $nwss2300->serial() (C) =item $nwss2300->mac() (C) =back =head2 Overrides =over =item $nwss2300->layers() Returns 00000011. Class emulates Layer 2 functionality for Thin APs through proprietary MIBs. =back =head2 Global Methods imported from SNMP::Info See documentation in L for details. =head2 Globals imported from SNMP::Info::Bridge See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $nwss2300->i_ssidlist() Returns reference to hash. SSID's recognized by the radio interface. =item $nwss2300->i_80211channel() Returns reference to hash. Current operating frequency channel of the radio interface. =item $nwss2300->dot11_cur_tx_pwr_mw() Returns reference to hash. Current transmit power, in milliwatts, of the radio interface. =item cd11_mac() Client MAC address. =back =head2 AP Status Table (C) A table describing all the APs currently present and managed by the controller. =over =item $nwss2300->nwss2300_ap_mac() (C) =item $nwss2300->nwss2300_ap_name() (C) =item $nws2300->nwss2300_ap_ip() (C) =item $nws2300->nwss2300_ap_sw() (C) =item $nws2300->nwss2300_ap_fw() (C) =item $nws2300->nwss2300_ap_model() (C) =item $nws2300->nwss2300_ap_type() (C) =item $nws2300->nwss2300_ap_status() (C) =item $nws2300->nwss2300_ap_vendor() (C) =item $nws2300->nwss2300_ap_num() (C) =item $nws2300->nwss2300_ap_dapnum() (C) =back =head2 AP Radio Status Table (C) A table describing all radios on all the APs currently present and managed by the controller. =over =item $nws2300->nwss2300_apif_mac() (C) =item $nws2300->nwss2300_apif_type() (C) =item $nws2300->nwss2300_apif_ch_num() (C) =item $nws2300->nwss2300_apif_power() (C) =item $nws2300->nwss2300_apif_admin() (C) =back =head2 AP Radio Status Service Table (C) A table describing radio services associated with APs currently present and managed by the controller. =over =item $nws2300->nwss2300_apif_bssid() (C) =item $nws2300->nwss2300_apif_prof() (C) =back =head2 AP Service Profile Config Table (C) =over =item $nws2300->nwss2300_ess_bcast() (C) =back =head2 AP Radio Config Table (C) =over =item $nws2300->nwss2300_apcr_txpwr() (C) =item $nws2300->nwss2300_apcr_ch() (C) =item $nws2300->nwss2300_apcr_mode() (C) =back =head2 AP Config Table (C) =over =item $nws2300->nwss2300_apc_descr() (C) =item $nws2300->nwss2300_apc_loc() (C) =item $nws2300->nwss2300_apc_name() (C) =item $nws2300->nwss2300_apc_model() (C) =item $nws2300->nwss2300_apc_serial() (C) =back =head2 Client Session Table (C) =over =item $nws2300->nwss2300_sta_slot() (C) =item $nws2300->nwss2300_sta_serial() (C) =item $nws2300->nwss2300_sta_ssid() (C) =item $nws2300->nwss2300_sta_ip() (C) =back =head2 Client Session Statistics Table (C) These emulate the F =over =item $nws2300->cd11_sigstrength() (C) =item $nws2300->cd11_sigqual() (C) =item $nws2300->cd11_txrate() (C) =item $nws2300->cd11_rxbyte() (C) =item $nws2300->cd11_txbyte() (C) =item $nws2300->cd11_rxpkt() (C) =item $nws2300->cd11_txpkt() (C) =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Bridge See documentation in L for details. =head2 Overrides =over =item $nwss2300->i_index() Returns reference to map of IIDs to Interface index. Extends C to support thin APs and WLAN virtual interfaces as device interfaces. =item $nwss2300->interfaces() Returns reference to map of IIDs to ports. Thin APs are implemented as device interfaces. The thin AP MAC address and Slot ID nwss2300_apif_slot() are used as the port identifier. =item $nwss2300->i_name() Returns reference to map of IIDs to interface names. Returns C for Ethernet interfaces and nwss2300_ap_name() for thin AP interfaces. =item $nwss2300->i_description() Returns reference to map of IIDs to interface types. Returns C for Ethernet interfaces, nwss2300_ap_name() for thin AP interfaces. =item $nwss2300->i_type() Returns reference to map of IIDs to interface descriptions. Returns C for Ethernet interfaces and C<'capwapWtpVirtualRadio'> for thin AP interfaces. =item $nwss2300->i_up() Returns reference to map of IIDs to link status of the interface. Returns C for Ethernet interfaces and nwss2300_apif_admin() for thin AP interfaces. =item $nwss2300->i_up_admin() Returns reference to map of IIDs to administrative status of the interface. Returns C for Ethernet interfaces and nwss2300_apif_admin() for thin AP interfaces. =item $nwss2300->i_mac() Returns reference to map of IIDs to MAC address of the interface. Returns C for Ethernet interfaces. =item $nwss2300->bp_index() Simulates bridge MIB by returning reference to a hash mapping i_index() to the interface iid. =item $nwss2300->fw_port() Returns reference to a hash, value being mac and nwss2300_sta_slot() combined to match the interface iid. =item $nwss2300->fw_mac() Extracts the MAC from the nwss2300_sta_serial() index. =back =head2 Pseudo ARP Cache Entries The controller snoops on the MAC->IP mappings. Using this as ARP cache data allows us to get MAC->IP mappings even for stations that only communicate locally. The data is gathered from nwss2300_sta_ip(). =over =item $nwss2300->at_paddr() Returns reference to hash of Pseudo Arp Cache Entries to MAC address =item $nwss2300->at_netaddr() Returns reference to hash of Pseudo Arp Cache Entries to IP Address =back =head2 Pseudo F information These methods emulate F Physical Table methods using F. Thin APs are included as subcomponents of the wireless controller. =over =item $nwss2300->e_index() Returns reference to hash. Key: IID and Value: Integer. The index for APs is created with an integer representation of the last three octets of the AP MAC address. =item $nwss2300->e_class() Returns reference to hash. Key: IID, Value: General hardware type. Return ap for wireless access points. =item $nwss2300->e_descr() Returns reference to hash. Key: IID, Value: Human friendly name. =item $nwss2300->e_model() Returns reference to hash. Key: IID, Value: Model name. =item $nwss2300->e_name() More computer friendly name of entity. Name is either 'WLAN Controller' or 'AP'. =item $nwss2300->e_vendor() Returns reference to hash. Key: IID, Value: avaya. =item $nwss2300->e_serial() Returns reference to hash. Key: IID, Value: Serial number. =item $nwss2300->e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. =item $nwss2300->e_type() Returns reference to hash. Key: IID, Value: Type of component. =item $nwss2300->e_fwver() Returns reference to hash. Key: IID, Value: Firmware revision. =item $nwss2300->e_swver() Returns reference to hash. Key: IID, Value: Software revision. =item $nwss2300->e_parent() Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Netgear.pm000444000765000024 2036613215550564 20373 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Netgear # $Id$ # # Copyright (c) 2008 Bill Fenner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Netgear; use strict; use Exporter; use SNMP::Info::Layer2; use SNMP::Info::LLDP; @SNMP::Info::Layer2::Netgear::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::Netgear::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; # This will be filled in with the device's index into the EntPhysicalEntry # table by the serial() function. our $index = undef; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::LLDP::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::LLDP::GLOBALS, ng_fsosver => '.1.3.6.1.4.1.4526.11.11.1.0', ng_gsmserial => '.1.3.6.1.4.1.4526.10.1.1.1.4.0', ng_gsmosver => '.1.3.6.1.4.1.4526.10.1.1.1.13.0', ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub vendor { return 'netgear'; } sub os { return 'netgear'; } # We will attempt to use Entity-MIB if present. In that case, we will # also set the shared variable $index, which is used by other functions # to index within Entity-MIB tables. This assumes, of course, that there # is only one serial number (entPhysicalSerialNum) present in the table. sub serial { my $netgear = shift; my $serial = undef; my $e_serial = $netgear->e_serial(); if (defined($e_serial)) { # This unit sports the Entity-MIB # Find entity table entry for this unit foreach my $e ( keys %$e_serial ) { if (defined ($e_serial->{$e}) and $e_serial->{$e} !~ /^\s*$/) { $index = $e; last; } } return $e_serial->{$index} if defined $index; } # Without Enitity-MIB, we've got to work our way through a bunch of # different locales... return $netgear->ng_gsmserial() if defined $netgear->model and $netgear->model =~ m/GSM\d/i;; return 'none'; } # If device supports Entity-MIB, index into that to divine model and # hardware version, otherwise default to sysDescr. sub model { my $netgear = shift; if (defined($index)) { my $model = $netgear->e_descr(); my $e_hwver = $netgear->e_hwver(); $model = "$model->{$index} $e_hwver->{$index}"; return $model; } return $netgear->description(); } # ifDescr is the same for all interfaces in a class, but the ifName is # unique, so let's use that for port name. If all else fails, # concatentate ifDesc and ifIndex. sub interfaces { my $netgear = shift; my $partial = shift; my $interfaces = $netgear->i_index($partial) || {}; my $i_descr = $netgear->i_description($partial) || {}; my $i_name = $netgear->i_name($partial); my $i_isset = (); # Replace the description with the ifName field, if set foreach my $iid ( keys %$i_name ) { my $name = $i_name->{$iid}; next unless defined $name; if (defined $name and $name !~ /^\s*$/) { $interfaces->{$iid} = $name; $i_isset->{$iid} = 1; } } # Replace the Index with the ifDescr field, appended with index # number, to deal with devices with non-unique ifDescr. foreach my $iid ( keys %$i_descr ) { my $port = $i_descr->{$iid} . '-' . $iid; next unless defined $port; next if (defined $i_isset->{$iid} and $i_isset->{$iid} == 1); $interfaces->{$iid} = $port; } return $interfaces; } # these seem to work for GSM models but not GS # https://sourceforge.net/tracker/?func=detail&aid=3085413&group_id=70362&atid=527529 sub os_ver { my $netgear = shift; my $serial = $netgear->serial(); # Make sure that index gets primed if (defined($index)) { my $os_ver = $netgear->e_swver(); return $os_ver->{$index} if defined $os_ver; } return $netgear->ng_gsmosver() if defined $netgear->model and $netgear->model =~ m/GSM\d/i; return $netgear->ng_fsosver() if defined $netgear->model and $netgear->model =~ m/FS\d/i; } 1; __END__ =head1 NAME SNMP::Info::Layer2::Netgear - SNMP Interface to Netgear switches =head1 AUTHOR Bill Fenner and Zoltan Erszenyi, Hacked in LLDP support from Baystack.pm by Nic Bernstein =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $netgear = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $netgear->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Netgear device through SNMP. See inherited classes' documentation for inherited methods. =head2 Inherited Classes =over =item SNMP::Info::Layer2 =item SNMP::Info::Entity =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item Inherited Classes' MIBs MIBs listed in L and its inherited classes. See L for its MIB requirements. See L for its MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $netgear->vendor() Returns 'netgear' =item $netgear->os() Returns 'netgear' =item $netgear->model() Returns concatenation of $e_model and $e_hwver if Entity MIB present, otherwise returns description() =item $netgear->os_ver() Returns OS Version. =item $netgear->serial() Returns Serial Number if available (older FS switches have no accessible serial number). =back =head2 Global Methods imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Globals imported from SNMP::Info::Entity See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $netgear->interfaces() Uses the i_name() field. =back =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Entity See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Orinoco.pm000444000765000024 1644313215550564 20417 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Orinoco # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Orinoco; use strict; use Exporter; use SNMP::Info::IEEE802dot11; use SNMP::Info::Layer2; @SNMP::Info::Layer2::Orinoco::ISA = qw/SNMP::Info::IEEE802dot11 SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::Orinoco::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::IEEE802dot11::MIBS, #'ORiNOCO-MIB' => 'orinoco', ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::IEEE802dot11::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::IEEE802dot11::FUNCS, # ORiNOCO-MIB:oriWirelessIfPropertiesTable #'ori_ssid' => 'oriWirelessIfNetworkName', #'ori_channel' => 'oriWirelessIfChannel', #'ori_closed_sys' => 'oriWirelessIfClosedSystem', # ORiNOCO-MIB:oriSystemInvMgmtComponentTable ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::IEEE802dot11::MUNGE, ); sub os { return 'orinoco'; } sub os_ver { my $orinoco = shift; my $descr = $orinoco->description(); return unless defined $descr; if ( $descr =~ m/V(\d+\.\d+)/ ) { return $1; } if ( $descr =~ m/v(\d+\.\d+\.\d+)/ ) { return $1; } return; } sub os_bin { my $orinoco = shift; my $descr = $orinoco->description(); return unless defined $descr; if ( $descr =~ m/V(\d+\.\d+)$/ ) { return $1; } if ( $descr =~ m/v(\d+\.\d+\.\d+)$/ ) { return $1; } return; } sub vendor { return 'proxim'; } sub model { my $orinoco = shift; my $descr = $orinoco->description(); return unless defined $descr; return $1 if ( $descr =~ /(AP-\d+)/ ); return 'WavePOINT-II' if ( $descr =~ /WavePOINT-II/ ); return 'Outdoor Router' if ( $descr =~ /Wireless Router/ ); return; } sub serial { my $orinoco = shift; my $descr = $orinoco->description(); return unless defined $descr; $descr = $1 if $descr =~ /SN-(\S+)/; return $descr; } sub i_ignore { my $orinoco = shift; my $partial = shift; my $descr = $orinoco->i_description($partial) || {}; my %i_ignore; foreach my $if ( keys %$descr ) { my $type = $descr->{$if}; # Skip virtual interfaces $i_ignore{$if}++ if $type =~ /(lo|empty|PCMCIA)/i; } return \%i_ignore; } sub interfaces { my $orinoco = shift; my $partial = shift; my $interfaces = $orinoco->i_index($partial) || {}; my $descriptions = $orinoco->i_description($partial) || {}; my %interfaces = (); foreach my $iid ( keys %$interfaces ) { my $desc = $descriptions->{$iid}; next unless defined $desc; next if $desc =~ /(lo|empty|PCMCIA)/i; $desc = 'AMD' if $desc =~ /AMD/; $interfaces{$iid} = $desc; } return \%interfaces; } #sub i_ssidbcast { # my $orinoco = shift; # my $partial = shift; # # my $bcast = $orinoco->ori_closed_sys($partial) || {}; # # my %i_ssidbcast; # foreach my $iid (keys %$bcast){ # my $bc = $bcast->{$iid}; # next unless defined $bc; # # $i_ssidbcast{$iid} = $bc; # } # return \%i_ssidbcast; #} 1; __END__ =head1 NAME SNMP::Info::Layer2::Orinoco - SNMP Interface to Orinoco Series Access Points =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $orinoco = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $orinoco->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from Orinoco Access Point through SNMP. Orinoco devices have been manufactured by Proxim, Agere, and Lucent. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $orinoco = new SNMP::Info::Layer2::Orinoco(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2 =item SNMP::Info::IEEE802dot11 =back =head2 Required MIBs =over None. =back =head2 Inherited MIBs See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $orinoco->vendor() Returns 'proxim' =item $orinoco->model() Returns the model extracted from C. =item $orinoco->os() Returns 'Orinoco' =item $orinoco->os_ver() Returns the software version extracted from C. =item $orinoco->os_bin() Returns the firmware version extracted from C. =item $orinoco->serial() Returns the serial number extracted from C. =back =head2 Global Methods imported from SNMP::Info::Layer2 See L for details. =head2 Global Methods imported from SNMP::Info::IEEE802dot11 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $orinoco->interfaces() Returns reference to map of IIDs to physical ports. =item $orinoco->i_ignore() Returns reference to hash of IIDs to ignore. =back =head2 Table Methods imported from SNMP::Info::Layer2 See L for details. =head2 Table Methods imported from SNMP::Info::IEEE802dot11 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Trapeze.pm000444000765000024 7376113215550564 20427 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Trapeze # # Copyright (c) 2012 Eric Miller # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::Trapeze; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Bridge; use SNMP::Info::LLDP; @SNMP::Info::Layer2::Trapeze::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::LLDP Exporter/; @SNMP::Info::Layer2::Trapeze::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::Bridge::MIBS, %SNMP::Info::LLDP::MIBS, 'TRAPEZE-NETWORKS-REGISTRATION-DEVICES-MIB' => 'wirelessLANController', 'TRAPEZE-NETWORKS-AP-STATUS-MIB' => 'trpzApStatNumAps', 'TRAPEZE-NETWORKS-CLIENT-SESSION-MIB' => 'trpzClSessTotalSessions', 'TRAPEZE-NETWORKS-SYSTEM-MIB' => 'trpzSysCpuAverageLoad', 'TRAPEZE-NETWORKS-BASIC-MIB' => 'trpzVersionString', ); %GLOBALS = ( %SNMP::Info::GLOBALS, %SNMP::Info::Bridge::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'os_ver' => 'trpzVersionString', 'serial' => 'trpzSerialNumber', 'mac' => 'dot1dBaseBridgeAddress', ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::Bridge::FUNCS, %SNMP::Info::LLDP::FUNCS, # TRAPEZE-NETWORKS-AP-STATUS-MIB::trpzApStatApStatusTable 'trapeze_ap_mac' => 'trpzApStatApStatusBaseMac', 'trapeze_ap_name' => 'trpzApStatApStatusApName', 'trapeze_ap_ip' => 'trpzApStatApStatusIpAddress', #'trapeze_ap_loc' => 'bsnAPLocation', 'trapeze_ap_sw' => 'trpzApStatApStatusSoftwareVer', 'trapeze_ap_fw' => 'trpzApStatApStatusBootVer', 'trapeze_ap_model' => 'trpzApStatApStatusModel', 'trapeze_ap_type' => 'trpzApStatApStatusModel', 'trapeze_ap_status' => 'trpzApStatApStatusApState', 'trapeze_ap_vendor' => 'trpzApStatApStatusManufacturerId', 'trapeze_ap_num' => 'trpzApStatApStatusApNum', 'trapeze_ap_dapnum' => 'trpzApStatApStatusPortOrDapNum', # TRAPEZE-NETWORKS-AP-STATUS-MIB::trpzApStatRadioStatusTable 'trapeze_apif_mac' => 'trpzApStatRadioStatusBaseMac', 'trapeze_apif_type' => 'trpzApStatRadioStatusRadioPhyType', 'trapeze_apif_ch_num' => 'trpzApStatRadioStatusCurrentChannelNum', 'trapeze_apif_power' => 'trpzApStatRadioStatusCurrentPowerLevel', 'trapeze_apif_admin' => 'trpzApStatRadioStatusRadioMode', # TRAPEZE-NETWORKS-AP-STATUS-MIB::trpzApStatRadioServiceTable 'trapeze_apif_prof' => 'trpzApStatRadioServServiceProfileName', # TRAPEZE-NETWORKS-AP-CONFIG-MIB::trpzApConfServiceProfileTable 'trapeze_ess_bcast' => 'trpzApConfServProfBeaconEnabled', # TRAPEZE-NETWORKS-AP-CONFIG-MIB::trpzApConfRadioConfigTable 'trapeze_apcr_txpwr' => 'trpzApConfRadioConfigTxPower', 'trapeze_apcr_ch' => 'trpzApConfRadioConfigChannel', 'trapeze_apcr_mode' => 'trpzApConfRadioConfigRadioMode', # TRAPEZE-NETWORKS-AP-CONFIG-MIB::trpzApConfApConfigTable 'trapeze_apc_descr' => 'trpzApConfApConfigDescription', 'trapeze_apc_loc' => 'trpzApConfApConfigLocation', 'trapeze_apc_name' => 'trpzApConfApConfigApName', 'trapeze_apc_model' => 'trpzApConfApConfigApModelName', 'trapeze_apc_serial' => 'trpzApConfApConfigApSerialNum', # TRAPEZE-NETWORKS-CLIENT-SESSION-MIB::trpzClSessClientSessionTable 'trapeze_sta_slot' => 'trpzClSessClientSessRadioNum', 'trapeze_sta_serial' => 'trpzClSessClientSessApSerialNum', 'trapeze_sta_ssid' => 'trpzClSessClientSessSsid', 'trapeze_sta_ip' => 'trpzClSessClientSessIpAddress', # TRAPEZE-NETWORKS-AP-STATUS-MIB::trpzApStatRadioServiceTable 'trapeze_apif_bssid' => 'trpzApStatRadioServBssid', # TRAPEZE-NETWORKS-CLIENT-SESSION-MIB::trpzClSessClientSessionStatisticsTable # Pretend to have the CISCO-DOT11-MIB for signal strengths, etc. 'cd11_sigstrength' => 'trpzClSessClientSessStatsLastRssi', 'cd11_sigqual' => 'trpzClSessClientSessStatsLastSNR', 'cd11_txrate' => 'trpzClSessClientSessStatsLastRate', # These are supposed to be there... 'cd11_rxbyte' => 'trpzClSessClientSessStatsUniOctetIn', 'cd11_txbyte' => 'trpzClSessClientSessStatsUniOctetOut', 'cd11_rxpkt' => 'trpzClSessClientSessStatsUniPktIn', 'cd11_txpkt' => 'trpzClSessClientSessStatsUniPktOut', ); %MUNGE = ( %SNMP::Info::MUNGE, %SNMP::Info::Bridge::MUNGE, %SNMP::Info::LLDP::MUNGE, 'trapeze_apif_mac' => \&SNMP::Info::munge_mac, 'trapeze_apif_bssid' => \&SNMP::Info::munge_mac, ); sub layers { return '00000111'; } sub os { return 'trapeze'; } sub vendor { return 'juniper'; } sub model { my $trapeze = shift; my $id = $trapeze->id(); unless ( defined $id ) { print "SNMP::Info::Layer2::Trapeze::model() - Device does not support sysObjectID\n" if $trapeze->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^wirelessLANController//i; return $model; } sub _ap_serial { my $trapeze = shift; my $partial = shift; my $names = $trapeze->trapeze_ap_name($partial) || {}; my %ap_serial; foreach my $iid ( keys %$names ) { next unless $iid; my $serial = join( '', map { sprintf "%c", $_ } split /\./, $iid ); # Remove any control characters to include nulls $serial =~ s/[\c@-\c_]//g; $ap_serial{$iid} = "$serial"; } return \%ap_serial; } # Wireless switches do not support ifMIB requirements to get MAC # and port status sub i_index { my $trapeze = shift; my $partial = shift; my $i_index = $trapeze->orig_i_index($partial) || {}; my $ap_index = $trapeze->trapeze_apif_mac($partial) || {}; my %if_index; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; $if_index{$iid} = $index; } # Get Attached APs as Interfaces foreach my $ap_id ( keys %$ap_index ) { my $mac = $ap_index->{$ap_id}; next unless ($mac); $if_index{$ap_id} = $mac; } return \%if_index; } sub interfaces { my $trapeze = shift; my $partial = shift; my $i_index = $trapeze->i_index($partial) || {}; my $descriptions = $trapeze->SUPER::i_description($partial) || {}; my %if; foreach my $iid ( keys %$i_index ) { my $desc = $descriptions->{$iid} || $i_index->{$iid}; next unless defined $desc; $if{$iid} = $desc; } return \%if; } sub i_description { my $trapeze = shift; my $partial = shift; my $i_index = $trapeze->i_index($partial) || {}; my $i_desc = $trapeze->orig_i_description($partial) || {}; my $ap_name = $trapeze->trapeze_ap_name($partial) || {}; my %i_name; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $name = $i_desc->{$iid}; next unless defined $name; $i_name{$iid} = $name; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $idx = $iid; $idx =~ s/\.(\d+)$//; my $radio = $1; $radio--; my $name = $ap_name->{$idx}; next unless defined $name; $i_name{$iid} = "Radio-$radio: $name"; } else { $i_name{$iid} = $index; } } return \%i_name; } sub i_name { my $trapeze = shift; my $partial = shift; return $trapeze->i_description($partial); } sub i_type { my $trapeze = shift; my $partial = shift; my $i_index = $trapeze->i_index($partial) || {}; my $i_type = $trapeze->orig_i_type($partial) || {}; my %i_type; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $type = $i_type->{$iid}; next unless defined $type; $i_type{$iid} = $type; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { # Match to an ifType $i_type{$iid} = 'capwapWtpVirtualRadio'; } else { next; } } return \%i_type; } sub i_up { my $trapeze = shift; my $partial = shift; return $trapeze->i_up_admin($partial); } sub i_up_admin { my $trapeze = shift; my $partial = shift; my $i_index = $trapeze->i_index($partial) || {}; my $i_up = $trapeze->orig_i_up($partial) || {}; my $apif_up = $trapeze->trapeze_apif_admin($partial) || {}; my %i_up_admin; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $stat = $i_up->{$iid}; next unless defined $stat; $i_up_admin{$iid} = $stat; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $stat = $apif_up->{$iid}; next unless defined $stat; $i_up_admin{$iid} = $stat; } else { next; } } return \%i_up_admin; } sub i_mac { my $trapeze = shift; my $partial = shift; my $i_index = $trapeze->i_index($partial) || {}; my $i_mac = $trapeze->orig_i_mac($partial) || {}; my %i_mac; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $mac = $i_mac->{$iid}; next unless defined $mac; $i_mac{$iid} = $mac; } # Don't grab AP MACs - we want the AP to show up on edge switch # ports else { next; } } return \%i_mac; } # Wireless switches do not support the standard Bridge MIB for client devices sub bp_index { my $trapeze = shift; my $partial = shift; my $i_index = $trapeze->i_index($partial) || {}; my %bp_index; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; $bp_index{$index} = $iid; } return \%bp_index; } sub fw_mac { my $trapeze = shift; my $partial = shift; my $serials = $trapeze->trapeze_sta_serial($partial) || {}; my %fw_mac; foreach my $iid ( keys %$serials ) { next unless $iid; my $mac = join( ':', map { sprintf "%02x", $_ } split /\./, $iid ); next unless $mac =~ /^([0-9A-F][0-9A-F]:){5}[0-9A-F][0-9A-F]$/i; $fw_mac{$iid} = $mac; } return \%fw_mac; } sub fw_port { my $trapeze = shift; my $partial = shift; my $slots = $trapeze->trapeze_sta_slot($partial) || {}; my $serials = $trapeze->trapeze_sta_serial($partial) || {}; my $ap_serials = $trapeze->_ap_serial($partial) || {}; my %serial_iid = reverse %$ap_serials; my %fw_port; foreach my $iid ( keys %$slots ) { my $slot = $slots->{$iid}; next unless defined $slot; $slot =~ s/radio-//i; my $serial = $serials->{$iid}; next unless defined $serial; my $index = $serial_iid{$serial}; next unless defined $index; $fw_port{$iid} = "$index.$slot"; } return \%fw_port; } sub i_ssidlist { my $trapeze = shift; my $partial = shift; my $apif_bssid = $trapeze->trapeze_apif_bssid($partial) || {}; my $i_index = $trapeze->i_index($partial) || {}; my %i_ssidlist; foreach my $iid ( keys %$i_index ) { # Skip non-radio interfaces next if $iid =~ /^\d+$/; foreach my $idx ( keys %$apif_bssid ) { next unless ( $idx =~ /^$iid\./ ); my $bssid_mac = $apif_bssid->{$idx}; next unless $bssid_mac; # Give the SSID a numeric value based upon tail of BSSID my $id; if ( $bssid_mac =~ /:([0-9A-F]{1,2})$/i ) { $id = hex $1; } next unless ( defined $id and $id =~ /\d+/ ); my $ssid_oid = $idx; $ssid_oid =~ s/^$iid\.//; my $ssid = join( '', map { sprintf "%c", $_ } split /\./, $ssid_oid ); # Remove any control characters including nulls $ssid =~ s/[\c@-\c_]//g; $i_ssidlist{"$iid.$id"} = $ssid; } } return \%i_ssidlist; } # Can't find in MIB # #sub i_ssidbcast { # #} sub i_80211channel { my $trapeze = shift; my $partial = shift; my $ch_list = $trapeze->trapeze_apif_ch_num($partial) || {}; my %i_80211channel; foreach my $iid ( keys %$ch_list ) { my $ch = $ch_list->{$iid}; next unless $ch =~ /\d+/; $i_80211channel{$iid} = $ch; } return \%i_80211channel; } sub dot11_cur_tx_pwr_mw { my $trapeze = shift; my $partial = shift; my $cur = $trapeze->trapeze_apif_power($partial); my $dot11_cur_tx_pwr_mw = {}; foreach my $idx ( keys %$cur ) { my $pwr_dbm = $cur->{$idx}; next unless $pwr_dbm; #Convert to milliWatts = 10(dBm/10) my $pwr = int (10 ** ($pwr_dbm / 10)); $dot11_cur_tx_pwr_mw->{$idx} = $pwr; } return $dot11_cur_tx_pwr_mw; } # Pseudo ENTITY-MIB methods sub e_index { my $trapeze = shift; # Try new first, fall back to depreciated my $ap_num = $trapeze->trapeze_ap_num() || $trapeze->trapeze_ap_dapnum() || {}; my %e_index; # Chassis $e_index{1} = 1; # We're going to hack an index to capture APs foreach my $idx ( keys %$ap_num ) { my $number = $ap_num->{$idx}; next unless $number =~ /\d+/; $e_index{$idx} = $number; } return \%e_index; } sub e_class { my $trapeze = shift; my $e_idx = $trapeze->e_index() || {}; my %e_class; foreach my $iid ( keys %$e_idx ) { if ( $iid eq "1" ) { $e_class{$iid} = 'chassis'; } # This isn't a valid PhysicalClass, but we're hacking this anyway else { $e_class{$iid} = 'ap'; } } return \%e_class; } sub e_name { my $trapeze = shift; my $ap_name = $trapeze->trapeze_ap_name() || {}; my %e_name; # Chassis $e_name{1} = 'WLAN Controller'; # APs foreach my $iid ( keys %$ap_name ) { $e_name{$iid} = 'AP'; } return \%e_name; } sub e_descr { my $trapeze = shift; my $ap_model = $trapeze->trapeze_ap_model() || {}; my $ap_name = $trapeze->trapeze_ap_name() || {}; my %e_descr; # Chassis $e_descr{1} = $trapeze->model(); # APs foreach my $iid ( keys %$ap_name ) { my $name = $ap_name->{$iid}; next unless defined $name; my $model = $ap_model->{$iid} || 'AP'; $e_descr{$iid} = "$model: $name"; } return \%e_descr; } sub e_model { my $trapeze = shift; my $ap_model = $trapeze->trapeze_ap_model() || {}; my %e_model; # Chassis $e_model{1} = $trapeze->model(); # APs foreach my $iid ( keys %$ap_model ) { my $model = $ap_model->{$iid}; next unless defined $model; $e_model{$iid} = $model; } return \%e_model; } sub e_type { my $trapeze = shift; return $trapeze->e_model(); } sub e_fwver { my $trapeze = shift; my $ap_fw = $trapeze->trapeze_ap_fw() || {}; my %e_fwver; # APs foreach my $iid ( keys %$ap_fw ) { my $fw = $ap_fw->{$iid}; next unless defined $fw; $e_fwver{$iid} = $fw; } return \%e_fwver; } sub e_vendor { my $trapeze = shift; my $vendors = $trapeze->trapeze_ap_vendor() || {}; my %e_vendor; # Chassis $e_vendor{1} = 'avaya'; # APs foreach my $iid ( keys %$vendors ) { my $vendor = $vendors->{$iid}; next unless defined $vendor; $e_vendor{$iid} = $vendor; } return \%e_vendor; } sub e_serial { my $trapeze = shift; my $ap_serial = $trapeze->_ap_serial() || {}; my %e_serial; # Chassis $e_serial{1} = $trapeze->serial(); # APs foreach my $iid ( keys %$ap_serial ) { my $serial = $ap_serial->{$iid}; next unless defined $serial; $e_serial{$iid} = $serial; } return \%e_serial; } sub e_pos { my $trapeze = shift; my $e_idx = $trapeze->e_index() || {}; my %e_pos; my $pos = 0; foreach my $iid ( sort keys %$e_idx ) { if ( $iid eq "1" ) { $e_pos{$iid} = -1; next; } else { $pos++; $e_pos{$iid} = $pos; } } return \%e_pos; } sub e_swver { my $trapeze = shift; my $ap_sw = $trapeze->trapeze_ap_sw() || {}; my %e_swver; # Chassis $e_swver{1} = $trapeze->os_ver(); # APs foreach my $iid ( keys %$ap_sw ) { my $sw = $ap_sw->{$iid}; next unless defined $sw; $e_swver{$iid} = $sw; } return \%e_swver; } sub e_parent { my $trapeze = shift; my $e_idx = $trapeze->e_index() || {}; my %e_parent; foreach my $iid ( sort keys %$e_idx ) { if ( $iid eq "1" ) { $e_parent{$iid} = 0; next; } else { $e_parent{$iid} = 1; } } return \%e_parent; } # arpnip: # # This is the controller snooping on the MAC->IP mappings. # Pretending this is arpnip data allows us to get MAC->IP # mappings even for stations that only communicate locally. sub at_paddr { my $trapeze = shift; my $mac2ip = $trapeze->trapeze_sta_ip(); my $ret = {}; foreach my $idx ( keys %$mac2ip ) { next if ( $mac2ip->{ $idx } eq '0.0.0.0' ); my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); $ret->{$idx} = $mac; } return $ret; } sub at_netaddr { my $trapeze = shift; my $mac2ip = $trapeze->trapeze_sta_ip(); my $ret = {}; foreach my $idx ( keys %$mac2ip ) { next if ( $mac2ip->{ $idx } eq '0.0.0.0' ); $ret->{$idx} = $mac2ip->{ $idx }; } return $ret; } # Client MAC sub cd11_mac { my $trapeze = shift; my $cd11_sigstrength = $trapeze->cd11_sigstrength(); my $ret = {}; foreach my $idx ( keys %$cd11_sigstrength ) { my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); $ret->{$idx} = $mac } return $ret; } 1; __END__ =head1 NAME SNMP::Info::Layer2::Trapeze - SNMP Interface to Juniper (Trapeze) Wireless Controllers =head1 AUTHOR Eric Miller =head1 SYNOPSIS #Let SNMP::Info determine the correct subclass for you. my $trapeze = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $trapeze->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from Juniper (Trapeze) Wireless Controllers through SNMP. This class emulates bridge functionality for the wireless switch. This enables end station MAC addresses collection and correlation to the thin access point the end station is using for communication. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $trapeze = new SNMP::Info::Layer2::Trapeze(...); =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Bridge =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =back =head2 Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $trapeze->vendor() Returns 'juniper' =item $trapeze->os() Returns 'trapeze' =item $trapeze->os_ver() (C) =item $trapeze->model() Tries to reference $trapeze->id() to F Removes C<'wirelessLANController'> for readability. =item $trapeze->serial() (C) =item $trapeze->mac() (C) =back =head2 Overrides =over =item $trapeze->layers() Returns 00000011. Class emulates Layer 2 functionality for Thin APs through proprietary MIBs. =back =head2 Global Methods imported from SNMP::Info See documentation in L for details. =head2 Globals imported from SNMP::Info::Bridge See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $trapeze->i_ssidlist() Returns reference to hash. SSID's recognized by the radio interface. =item $trapeze->i_80211channel() Returns reference to hash. Current operating frequency channel of the radio interface. =item $trapeze->dot11_cur_tx_pwr_mw() Returns reference to hash. Current transmit power, in milliwatts, of the radio interface. =item cd11_mac() Client MAC address. =back =head2 AP Status Table (C) A table describing all the APs currently present and managed by the controller. =over =item $trapeze->trapeze_ap_mac() (C) =item $trapeze->trapeze_ap_name() (C) =item $nws2300->trapeze_ap_ip() (C) =item $nws2300->trapeze_ap_sw() (C) =item $nws2300->trapeze_ap_fw() (C) =item $nws2300->trapeze_ap_model() (C) =item $nws2300->trapeze_ap_type() (C) =item $nws2300->trapeze_ap_status() (C) =item $nws2300->trapeze_ap_vendor() (C) =item $nws2300->trapeze_ap_num() (C) =item $nws2300->trapeze_ap_dapnum() (C) =back =head2 AP Radio Status Table (C) A table describing all radios on all the APs currently present and managed by the controller. =over =item $nws2300->trapeze_apif_mac() (C) =item $nws2300->trapeze_apif_type() (C) =item $nws2300->trapeze_apif_ch_num() (C) =item $nws2300->trapeze_apif_power() (C) =item $nws2300->trapeze_apif_admin() (C) =back =head2 AP Radio Status Service Table (C) A table describing radio services associated with APs currently present and managed by the controller. =over =item $nws2300->trapeze_apif_bssid() (C) =item $nws2300->trapeze_apif_prof() (C) =back =head2 AP Service Profile Config Table (C) =over =item $nws2300->trapeze_ess_bcast() (C) =back =head2 AP Radio Config Table (C) =over =item $nws2300->trapeze_apcr_txpwr() (C) =item $nws2300->trapeze_apcr_ch() (C) =item $nws2300->trapeze_apcr_mode() (C) =back =head2 AP Config Table (C) =over =item $nws2300->trapeze_apc_descr() (C) =item $nws2300->trapeze_apc_loc() (C) =item $nws2300->trapeze_apc_name() (C) =item $nws2300->trapeze_apc_model() (C) =item $nws2300->trapeze_apc_serial() (C) =back =head2 Client Session Table (C) =over =item $nws2300->trapeze_sta_slot() (C) =item $nws2300->trapeze_sta_serial() (C) =item $nws2300->trapeze_sta_ssid() (C) =item $nws2300->trapeze_sta_ip() (C) =back =head2 Client Session Statistics Table (C) These emulate the F =over =item $nws2300->cd11_sigstrength() (C) =item $nws2300->cd11_sigqual() (C) =item $nws2300->cd11_txrate() (C) =item $nws2300->cd11_rxbyte() (C) =item $nws2300->cd11_txbyte() (C) =item $nws2300->cd11_rxpkt() (C) =item $nws2300->cd11_txpkt() (C) =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Bridge See documentation in L for details. =head2 Overrides =over =item $trapeze->i_index() Returns reference to map of IIDs to Interface index. Extends C to support thin APs and WLAN virtual interfaces as device interfaces. =item $trapeze->interfaces() Returns reference to map of IIDs to ports. Thin APs are implemented as device interfaces. The thin AP MAC address and Slot ID trapeze_apif_slot() are used as the port identifier. =item $trapeze->i_name() Returns reference to map of IIDs to interface names. Returns C for Ethernet interfaces and trapeze_ap_name() for thin AP interfaces. =item $trapeze->i_description() Returns reference to map of IIDs to interface types. Returns C for Ethernet interfaces, trapeze_ap_name() for thin AP interfaces. =item $trapeze->i_type() Returns reference to map of IIDs to interface descriptions. Returns C for Ethernet interfaces and C<'capwapWtpVirtualRadio'> for thin AP interfaces. =item $trapeze->i_up() Returns reference to map of IIDs to link status of the interface. Returns C for Ethernet interfaces and trapeze_apif_admin() for thin AP interfaces. =item $trapeze->i_up_admin() Returns reference to map of IIDs to administrative status of the interface. Returns C for Ethernet interfaces and trapeze_apif_admin() for thin AP interfaces. =item $trapeze->i_mac() Returns reference to map of IIDs to MAC address of the interface. Returns C for Ethernet interfaces. =item $trapeze->bp_index() Simulates bridge MIB by returning reference to a hash mapping i_index() to the interface iid. =item $trapeze->fw_port() Returns reference to a hash, value being mac and trapeze_sta_slot() combined to match the interface iid. =item $trapeze->fw_mac() Extracts the MAC from the trapeze_sta_serial() index. =back =head2 Pseudo ARP Cache Entries The controller snoops on the MAC->IP mappings. Using this as ARP cache data allows us to get MAC->IP mappings even for stations that only communicate locally. The data is gathered from trapeze_sta_ip(). =over =item $trapeze->at_paddr() Returns reference to hash of Pseudo Arp Cache Entries to MAC address =item $trapeze->at_netaddr() Returns reference to hash of Pseudo Arp Cache Entries to IP Address =back =head2 Pseudo F information These methods emulate F Physical Table methods using F. Thin APs are included as subcomponents of the wireless controller. =over =item $trapeze->e_index() Returns reference to hash. Key: IID and Value: Integer. The index for APs is created with an integer representation of the last three octets of the AP MAC address. =item $trapeze->e_class() Returns reference to hash. Key: IID, Value: General hardware type. Return ap for wireless access points. =item $trapeze->e_descr() Returns reference to hash. Key: IID, Value: Human friendly name. =item $trapeze->e_model() Returns reference to hash. Key: IID, Value: Model name. =item $trapeze->e_name() More computer friendly name of entity. Name is either 'WLAN Controller' or 'AP'. =item $trapeze->e_vendor() Returns reference to hash. Key: IID, Value: avaya. =item $trapeze->e_serial() Returns reference to hash. Key: IID, Value: Serial number. =item $trapeze->e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. =item $trapeze->e_type() Returns reference to hash. Key: IID, Value: Type of component. =item $trapeze->e_fwver() Returns reference to hash. Key: IID, Value: Firmware revision. =item $trapeze->e_swver() Returns reference to hash. Key: IID, Value: Software revision. =item $trapeze->e_parent() Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/Ubiquiti.pm000444000765000024 2013213215550564 20570 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::Ubiquiti # $Id$ # package SNMP::Info::Layer2::Ubiquiti; use strict; use Exporter; use SNMP::Info::IEEE802dot11; use SNMP::Info::Layer2; use SNMP::Info::Layer3; # only used in sub mac() @SNMP::Info::Layer2::Ubiquiti::ISA = qw/SNMP::Info::IEEE802dot11 SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::Ubiquiti::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::IEEE802dot11::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::IEEE802dot11::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::IEEE802dot11::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::IEEE802dot11::MUNGE, ); sub os { my $ubnt = shift; my $names = $ubnt->dot11_prod_name(); foreach my $iid ( keys %$names ) { my $prod = $names->{$iid}; next unless defined $prod; # Product names that match AirOS products if((lc $prod) =~ /station/ or (lc $prod) =~ /beam/ or (lc $prod) =~ /grid/){ return 'AirOS'; # Product names that match UAP }elsif((lc $prod) =~ /uap/){ return 'UniFi'; }else{ # Continue below to find OS name } } ## EdgeMAX OS (EdgeSwitch and EdgeRouter) name is first field split by space my $ver = $ubnt->description() || ''; my @myver = split(/ /, $ver); return $myver[0]; } sub os_ver { my $dot11 = shift; my $versions = $dot11->dot11_prod_ver(); foreach my $iid ( keys %$versions ) { my $ver = $versions->{$iid}; next unless defined $ver; return $ver; ## Not sure what this function does, it seems to be extraneous being in the same code block after a return statement? if ( $ver =~ /([\d\.]+)/ ) { return $1; } } my $ver = $dot11->description() || ''; if($ver =~ /^edgeswitch/){ ## EdgeSwitch OS version is second field split by comma my @myver = split(/, /, $ver); return $myver[1]; } ## EdgeRouter OS version is second field split by space my @myver = split(/ /, $ver); return $myver[1]; } sub vendor { return 'Ubiquiti Networks, Inc.'; } sub model { my $ubnt = shift; my $names = $ubnt->dot11_prod_name(); foreach my $iid ( keys %$names ) { my $prod = $names->{$iid}; next unless defined $prod; return $prod; } my $desc = $ubnt->description() || ''; ## Pull Model from beginning of description, separated by comma (EdgeSwitch) if((lc $desc) =~ /^edgeswitch/){ my @mydesc = split(/, /, $desc); return $mydesc[0]; } if(!((lc $desc) =~ /edgeos/)){ # Not sure what type of device this is to get Model # Wireless devices report dot11_prod_name # EdgeSwitch includes mode directly and edgeos logic is in else statement return ; }else{ ## do some logic to determine ER model based on tech specs from ubnt: ## https://help.ubnt.com/hc/en-us/articles/219652227--EdgeRouter-Which-EdgeRouter-Should-I-Use-#tech%20specs ## Would be nice if UBNT simply adds the model string to their SNMP daemon directly my $ethCount = 0; my $switchCount = 0; #my $sfpCount = 0; #my $poeCount = 0; my $memTotalReal = $ubnt->memTotalReal; my $cpuLoad = $ubnt->hrProcessorLoad; my $cpuCount = 0; ## My perl is lacking. Not sure if there's a more efficient way to find the cpu count foreach my $iid ( keys %$cpuLoad ) { $cpuCount++; } my $ifDescs = $ubnt->ifDescr; foreach my $iid ( keys %$ifDescs ) { my $ifDesc = $ifDescs->{$iid}; next unless defined $ifDesc; if((lc $ifDesc) =~ /^eth\d+$/){ # exclude vlan interfaces. Ex: eth1.5 $ethCount++; }elsif((lc $ifDesc) =~ /^switch/){ $switchCount++; } } ## If people have other models to further fine-tune this logic that would be great. if($ethCount eq 9){ ## Should be ER Infinity return "EdgeRouter Infinity" }if($ethCount eq 8){ ## Could be ER-8 Pro, ER-8, or EP-R8 return "EdgeRouter 8-Port" }elsif($ethCount eq 5 and $cpuCount eq 4){ ## Could be ER-X or ER-X-SFP return "EdgeRouter X 5-Port" }elsif($ethCount eq 5){ return "EdgeRouter PoE 5-Port" }elsif($ethCount eq 3 and $cpuCount eq 2){ return "EdgeRouter LITE 3-Port" }else{ ## failback string return "EdgeRouter eth-$ethCount switch-$switchCount mem-$memTotalReal cpuNum-$cpuCount"; } } } ## simply take the MAC and clean it up sub serial { my $ubnt = shift; my $serial = $ubnt->mac(); if($serial){ $serial =~ s/://g; return uc $serial; } return ; } ## UBNT doesn't put the primary-mac interface at index 1 sub mac { my $ubnt = shift; my $ifDescs = $ubnt->ifDescr; foreach my $iid ( keys %$ifDescs ) { my $ifDesc = $ifDescs->{$iid}; next unless defined $ifDesc; ## CPU Interface will have the primary MAC for EdgeSwitch ## eth0 will have primary MAC for linux-based UBNT devices if($ifDesc =~ /CPU/ or $ifDesc eq 'eth0'){ my $mac = $ubnt->ifPhysAddress->{$iid}; # syntax stolen from sub munge_mac in SNMP::Info $mac = lc join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $mac ) ); return $mac if $mac =~ /^([0-9A-F][0-9A-F]:){5}[0-9A-F][0-9A-F]$/i; } } # MAC malformed or missing return; } 1; __END__ =head1 NAME SNMP::Info::Layer2::Ubiquiti - SNMP Interface to Ubiquiti Access Points =head1 AUTHOR Max Kosmach =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $ubnt = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $ubnt->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from Ubiquiti Access Point through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $ubnt = new SNMP::Info::Layer2::Ubiquiti(...); =head2 Inherited Classes =over =item SNMP::Info::Layer2 =item SNMP::Info::IEEE802dot11 =back =head2 Required MIBs None. =head2 Inherited MIBs See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $ubnt->vendor() Returns 'Ubiquiti Networks, Inc.' =item $ubnt->model() Returns the model extracted from C, with failback to some complex logic for EdgeMax devices =item $ubnt->os() Returns 'Ubiquiti Networks, Inc.' =item $ubnt->os_ver() Returns the software version extracted from C, with failback to description splitting for EdgeMax devices =back =head2 Global Methods imported from SNMP::Info::Layer2 See L for details. =head2 Global Methods imported from SNMP::Info::IEEE802dot11 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer2 See L for details. =head2 Table Methods imported from SNMP::Info::IEEE802dot11 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer2/ZyXEL_DSLAM.pm000444000765000024 1225213215550564 20674 0ustar00oliverstaff000000000000# SNMP::Info::Layer2::ZyXEL_DSLAM # $Id$ # # Copyright (c) 2008 Max Baker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer2::ZyXEL_DSLAM; use strict; use Exporter; use SNMP::Info::Layer2; @SNMP::Info::Layer2::ZyXEL_DSLAM::ISA = qw/SNMP::Info::Layer2 Exporter/; @SNMP::Info::Layer2::ZyXEL_DSLAM::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; # Set for No CDP %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, 'ip_adresses' => 'ipAdEntAddr', 'i_name' => 'ifDescr', 'i_description' => 'adslLineConfProfile', ); %MIBS = ( %SNMP::Info::Layer2::MIBS, 'ADSL-LINE-MIB' => 'adslLineConfProfile' ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE ); sub layers { my $zyxel = shift; my $layers = $zyxel->layers(); return $layers if defined $layers; # If these don't claim to have any layers, so we'll give them 1+2 return '00000011'; } sub vendor { return 'zyxel'; } sub os { return 'zyxel'; } sub os_ver { my $zyxel = shift; my $descr = $zyxel->description(); if ( $descr =~ m/version (\S+) / ) { return $1; } return; } sub model { my $zyxel = shift; my $desc = $zyxel->description(); if ( $desc =~ /8-port ADSL Module\(Annex A\)/ ) { return "AAM1008-61"; } elsif ( $desc =~ /8-port ADSL Module\(Annex B\)/ ) { return "AAM1008-63"; } return; } sub ip { my $zyxel = shift; my $ip_hash = $zyxel->ip_addresses(); my $found_ip; foreach my $ip ( keys %{$ip_hash} ) { $found_ip = $ip if ( defined $ip and $ip =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ ); } return $found_ip; } 1; __END__ =head1 NAME SNMP::Info::Layer2::ZyXEL_DSLAM - SNMP Interface to ZyXEL DSLAM =head1 AUTHOR Dmitry Sergienko (C) =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $zyxel = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myhub', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $l2->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a ZyXEL device through SNMP. See inherited classes' documentation for inherited methods. =head2 Inherited Classes =over =item SNMP::Info::Layer2 =back =head2 Required MIBs =over =item F =item Inherited Classes MIBs listed in L and their inherited classes. =back =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $zyxel->vendor() Returns 'ZyXEL' :) =item $zyxel->os() Returns 'ZyXEL' =item $zyxel->os_ver() Culls Version from description() =item $zyxel->ip() Returns IP Address of DSLAM. (C) =item $zyxel->model() Tries to cull out model out of the description field. =item $zyxel->layers() Returns 00000011. =back =head2 Global Methods imported from SNMP::Info::Layer2 See documentation in L for details. =head1 TABLE METHODS =head2 Overrides =over =item $zyxel->i_name() Returns reference to map of IIDs to port name (C). =item $zyxel->i_description() Returns reference to map of IIDs to human-set port description (profile name). =back =head2 Table Methods imported from SNMP::Info::Layer2 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3000755000765000024 013215550564 16265 5ustar00oliverstaff000000000000SNMP-Info-3.39/lib/SNMP/Info/Layer3/Aironet.pm000444000765000024 2214513215550564 20405 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Aironet # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Aironet; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Aironet::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Aironet::EXPORT_OK = qw//; use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'AWCVX-MIB' => 'awcIfTable', 'IEEE802dot11-MIB' => 'dot11StationID', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, 'mac' => 'dot11StationID.2', # AWC Ethernet Table 'awc_duplex' => 'awcEtherDuplex.0', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, 'i_mac2' => 'ifPhysAddress', 'i_mtu2' => 'ifMtu', 'i_ssid' => 'dot11DesiredSSID', # Bridge-mib overrides 'fw_mac2' => 'dot1dTpFdbAddress', 'fw_port2' => 'dot1dTpFdbPort', 'bp_index2' => 'dot1dBasePortIfIndex', # AWC Interface Table (awcIfTable) 'awc_default_mac' => 'awcIfDefaultPhyAddress', 'awc_mac' => 'awcIfPhyAddress', 'awc_ip' => 'awcIfIpAddress', 'awc_netmask' => 'awcIfIpNetMask', 'awc_msdu' => 'awcIfMSDUMaxLength', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::Layer3::MUNGE, 'i_mac2' => \&SNMP::Info::munge_mac, 'awc_mac' => \&SNMP::Info::munge_mac, 'fw_mac2' => \&SNMP::Info::munge_mac, ); sub os { return 'aironet'; } sub os_ver { my $aironet = shift; my $descr = $aironet->description() || ''; # CAP340 11.21, AP4800-E 11.21 if ( $descr =~ /AP\d{3,4}(-\D+)?\s+(\d{2}\.\d{2})/ ) { return $2; } if ( $descr =~ /Series\s*AP\s+(\d{2}\.\d{2})/ ) { return $1; } return; } # Override wireless port with static info sub bp_index { my $aironet = shift; my $interfaces = $aironet->interfaces(); my $bp_index = $aironet->bp_index2(); foreach my $iid ( keys %$interfaces ) { my $port = $interfaces->{$iid}; # Hardwire the wireless port to the transparent bridge port if ( $port =~ /awc/ ) { $bp_index->{0} = $iid; } } return $bp_index; } # Add the static table to the forwarding table sub fw_mac { my $aironet = shift; my $fw_mac = $aironet->fw_mac2(); my $fw_port = $aironet->fw_port2(); my $bs_mac = $aironet->bs_mac(); # remove port 0 forwarding table entries, only port 0 static entries foreach my $fw ( keys %$fw_mac ) { my $port = $fw_port->{$fw}; next unless defined $port; delete $fw_mac->{$fw} if $port == 0; } foreach my $bs ( keys %$bs_mac ) { my $entry = $bs; $entry =~ s/\.0$//; $fw_mac->{$entry} = $bs_mac->{$bs}; } return $fw_mac; } # Add the static table to the forwarding table sub fw_port { my $aironet = shift; my $fw_port = $aironet->fw_port2(); my $bs_port = $aironet->bs_port(); foreach my $bs ( keys %$bs_port ) { my $entry = $bs; $entry =~ s/\.0$//; $fw_port->{$entry} = $bs_port->{$bs}; } return $fw_port; } sub i_duplex { my $aironet = shift; my $interfaces = $aironet->interfaces(); my $awc_duplex = $aironet->awc_duplex(); my %i_duplex; foreach my $iid ( keys %$interfaces ) { my $name = $interfaces->{$iid}; if ( $name =~ /fec/ ) { $i_duplex{$iid} = $awc_duplex; } } return \%i_duplex; } sub i_mac { my $aironet = shift; my $i_mac = $aironet->i_mac2(); my $awc_mac = $aironet->awc_mac(); foreach my $iid ( keys %$awc_mac ) { next unless defined $i_mac->{$iid}; $i_mac->{$iid} = $awc_mac->{$iid}; } return $i_mac; } sub i_ignore { my $aironet = shift; my $interfaces = $aironet->interfaces(); my %i_ignore; foreach my $if ( keys %$interfaces ) { $i_ignore{$if}++ if ( $interfaces->{$if} =~ /(rptr|lo)/ ); } return \%i_ignore; } sub vendor { return 'cisco'; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Aironet - Perl5 Interface to Cisco Aironet Wireless Devices running Aironet software, not IOS =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $aironet = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $aironet->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION SNMP::Info subclass to provide access to SNMP data for an Aironet device running Aironet software, not cisco IOS. Note there are two classes for Aironet devices : =over =item SNMP::Info::Layer3::Aironet This class is for devices running Aironet software (older) =item SNMP::Info::Layer2::Aironet This class is for devices running Cisco IOS software (newer) =back For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $aironet = new SNMP::Info::Layer3::Aironet(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =back These MIBs are now included in the v2.tar.gz archive available from ftp.cisco.com. Make sure you have a current version. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $aironet->awc_duplex() Gives the admin duplex setting for the Ethernet Port. C =item $aironet->mac() Gives the MAC Address of the wireless side C =item $aironet->os() 'aironet' =item $aironet->os_ver Tries to cull the version from the description field. =item $aironet->vendor() Returns 'cisco'. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $aironet->bp_index() Takes the bp_index() value from SNMP::Info::Bridge and overrides the wireless port to be assigned to the transparent bridge port (port 0) =item $aironet->fw_mac() Adds static table entries from bs_mac() to port 0 so that wireless MAC addresses will be reported. Forwarding table entries for port 0 are removed. =item $aironet->fw_port() Adds the static table port mappings to the forwarding table port mappings by adding bs_port() to fw_port() =item $aironet->i_duplex() Adds the value of awc_duplex() to each Ethernet port seen. =item $aironet->i_mac() Overrides the values for i_mac with the value from awc_mac() if they are set. =item $aironet->i_ignore() Ignores ports that are of type ``rptr'' and ``lo''. =back =head2 Aironet specific items =over =item $aironet->awc_default_mac() Gives the default MAC address of each interface. C =item $aironet->awc_mac() Gives the actual MAC address of each interface. C =item $aironet->awc_ip() Gives the IP Address assigned to each interface. C =item $aironet->awc_netmask() Gives the NetMask for each interface. C =item $aironet->awc_msdu() C =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/AlcatelLucent.pm000444000765000024 3066613215550564 21533 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::AlcatelLucent # $Id$ # # Copyright (c) 2008 Bill Fenner # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::AlcatelLucent; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::MAU; use SNMP::Info::AMAP; # Use LLDP # (or at least try. The versions I've seen have two problems: # 1. they report ifIndex values as 'local'; we don't support ifIndex # but *could* # 2. They report 0.0.0.0 as the management address # ) use SNMP::Info::LLDP; @SNMP::Info::Layer3::AlcatelLucent::ISA = qw/SNMP::Info::AMAP SNMP::Info::LLDP SNMP::Info::MAU SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::AlcatelLucent::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::MAU::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::AMAP::MIBS, 'ALCATEL-IND1-DEVICES' => 'familyOmniSwitch7000', 'ALCATEL-IND1-CHASSIS-MIB' => 'chasEntPhysOperStatus', 'ALU-POWER-ETHERNET-MIB' => 'pethPsePortDetectionStatus', ); # Alcatel provides their own version of the POWER-ETHERNET-MIB, # off in vendor-space, without renaming any of the objects. # This means we have to *not* load the POWER-ETHERNET-MIB # but can then still use the standard PowerEthernet module, # but cannot try both so we hope Alcatel doesn't stop supporting # their private version even if they get around to supporting the # standard. delete $MIBS{'POWER-ETHERNET-MIB'}; %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::MAU::GLOBALS, %SNMP::Info::LLDP::GLOBALS, %SNMP::Info::AMAP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::MAU::FUNCS, %SNMP::Info::LLDP::FUNCS, %SNMP::Info::AMAP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::MAU::MUNGE, %SNMP::Info::LLDP::MUNGE, %SNMP::Info::AMAP::MUNGE, ); # use MAU-MIB for admin. duplex and admin. speed *SNMP::Info::Layer3::AlcatelLucent::i_duplex_admin = \&SNMP::Info::MAU::mau_i_duplex_admin; *SNMP::Info::Layer3::AlcatelLucent::i_speed_admin = \&SNMP::Info::MAU::mau_i_speed_admin; sub model { my $alu = shift; my $id = $alu->id(); my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^device//; return $model; } sub os { return 'AOS'; } sub vendor { return 'alcatel-lucent'; } sub os_ver { my $alu = shift; my $descr = $alu->description(); if ( $descr =~ m/^(\S+)/ ) { return $1; } # No clue what this will try but hey return $alu->SUPER::os_ver(); } # ps1_type, ps1_status, ps2_type, ps2_status: # Find the list of power supplies in the ENTITY-MIB # e_class = powerSupply # e_descr = ps_type # chasEntPhysOperStatus = ps_status sub _power_supplies { my $alu = shift; my $e_class = $alu->e_class(); my @supplies = (); foreach my $key ( sort { int($a) cmp int($b) } keys %$e_class ) { if ( $e_class->{$key} eq 'powerSupply' ) { push( @supplies, int($key) ); } } return @supplies; } sub _ps_type { my $alu = shift; my $psnum = shift; my @ps = $alu->_power_supplies(); if ( $psnum > $#ps ) { return "none"; } my $supply = $ps[$psnum]; my $descr = $alu->e_descr($supply); return $descr->{$supply}; } sub _ps_status { my $alu = shift; my $psnum = shift; my @ps = $alu->_power_supplies(); if ( $psnum > $#ps ) { return "not present"; } my $supply = $ps[$psnum]; my $status = $alu->chasEntPhysOperStatus($supply); return $status->{$supply}; } sub ps1_type { my $alu = shift; return $alu->_ps_type(0); } sub ps2_type { my $alu = shift; return $alu->_ps_type(1); } sub ps1_status { my $alu = shift; return $alu->_ps_status(0); } sub ps2_status { my $alu = shift; return $alu->_ps_status(1); } # The interface description contains the software version, so # to avoid losing historical information through a software upgrade # we use interface name instead. sub interfaces { my $alu = shift; my $partial = shift; return $alu->orig_i_name($partial); } # Work around buggy bp_index in 6.3.1.871.R01 and 6.3.1.975.R01 sub bp_index { my $alu = shift; my $partial = shift; my $bp_index = $alu->SUPER::bp_index($partial); # # This device sometimes reports an ifIndex and sometimes reports # dot1dBasePort for the dot1d port values - e.g., # in 6.3.1.871.R01 both dot1dTpFdbPort and dot1qTpFdbPort report # the ifIndex; in 6.3.1.975.R01 dot1dTpFdbPort has been updated # to report the dot1dBasePort but dot1qTpFdbPort still returns an # ifIndex. For this reason, we augment the dot1dBasePort # mapping with ifIndex->ifIndex mappings -- we can do this because # the ifIndex and dot1dBasePort spaces don't overlap, at least for # the ports we care about. my @keys = keys %$bp_index; foreach my $idx (@keys) { my $ifIndex = $bp_index->{$idx}; $bp_index->{$ifIndex} = $ifIndex; } # # In addition, aggregates aren't reported at all in bp_index. # We grab them from i_index. my $i_index = $alu->i_index(); foreach my $idx ( keys %$i_index ) { my $ifIndex = $i_index->{$idx}; if ( int($ifIndex) > 40000001 ) { $bp_index->{$ifIndex} = $ifIndex; # dot1dTpFdbPort seems to use 4098, 4099, 4100 for # 40000001, 40000002, 40000003. I guess this is # 4096 + 1 + aggregate number. my $tmp = sprintf( "%d", int($ifIndex) - 39995903 ); $bp_index->{$tmp} = $ifIndex; } } return $bp_index; } # Workaround for unimplemented Q-BRIDGE-MIB::dot1qPvid # If there is only one VLAN on which a given port is output # untagged, then call that one the PVID. This is a guess that # works in obvious configurations but may be wrong in # subtle cases (like there's one output VLAN but a different # input one - the only way to know that is via the dot1qPvid # object) # # Newer versions have implemented dot1qPvid (but wrong, but # that's just life) #sub i_vlan { # my $alu = shift; # # my $qb_v_untagged = $alu->qb_v_untagged(); # my $bp_index = $alu->bp_index(); # my $vlan_list = {}; # foreach my $vlan (keys %$qb_v_untagged) { # my $portlist = $qb_v_untagged->{$vlan}; # my $port; # for ($port = 0; $port <= $#$portlist; $port++) { # if ($portlist->[$port]) { # my $ifindex = $bp_index->{$port + 1}; # if ($ifindex) { # push(@{$vlan_list->{$ifindex}}, int($vlan)); # } # } # } # } # # my $i_vlan = {}; # foreach my $ifindex (keys %$vlan_list) { # if ($#{$vlan_list->{$ifindex}} == 0) { # $i_vlan->{$ifindex} = ${$vlan_list->{$ifindex}}[0]; # } # } # return $i_vlan; #} # Power-Ethernet ifIndex mapping. I've only seen this from a # fixed-config single-module system, so this is only a plausible # guess as to the mapping on a stack or modular system. sub peth_port_ifindex { my $alu = shift; my $partial = shift; my $peth_port_status = $alu->peth_port_status($partial); my $peth_port_ifindex = {}; foreach my $key ( keys %$peth_port_status ) { my @oid = split( m/\./, $key ); $peth_port_ifindex->{$key} = int( $oid[0] ) * 1000 + int( $oid[1] ); } return $peth_port_ifindex; } 1; __END__ =head1 NAME SNMP::Info::Layer3::AlcatelLucent - SNMP Interface to Alcatel-Lucent OmniSwitch =head1 AUTHOR Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $alu = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $alu->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Alcatel-Lucent OmniSwitch devices =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::MAU =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item F =item F =item F Note that Alcatel-Lucent distributes their own proprietary version of the F, but the MIB module name that they distribute is simply F. This module must be hand-edited to change the module name to F so that it can be used simultaneously with the standard F. =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $alu->vendor() Returns 'alcatel-lucent' =item $alu->model() Tries to reference $alu->id() to one of the product MIBs listed above Removes 'device' from the name for readability. =item $alu->os() Returns 'AOS' =item $alu->os_ver() Grabs the os version from C =item $alu->ps1_type() Return the type of the first power supply from the F =item $alu->ps2_type() Return the type of the second power supply from the F =item $alu->ps1_status() Return the status of the first power supply from the F =item $alu->ps2_status() Return the status of the second power supply from the F =back =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::MAU See documentation in L for details. =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $alu->interfaces() Returns interface name from C, since the default return value of C includes the OS version. =item $alu->bp_index() Work around various bugs in the F and F implementations, by returning both C and C mappings to C values. =item $alu->i_duplex_admin() Returns info from F =item $alu->i_speed_admin() Returns info from F =item $alu->peth_port_ifindex() Returns the C value for power-ethernet ports using the OmniSwitch algorithm. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/AlteonAD.pm000444000765000024 4202213215550564 20427 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::AlteonAD # $Id$ # # Copyright (c) 2008 Eric Miller # All Rights Reserved # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::AlteonAD; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::AlteonAD::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::AlteonAD::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'ALTEON-ROOT-MIB' => 'aceswitch184', 'ALTEON-TIGON-SWITCH-MIB' => 'hwPowerSupplyStatus', 'ALTEON-CHEETAH-SWITCH-MIB' => 'hwFanStatus', 'ALTEON-TS-PHYSICAL-MIB' => 'agPortTableMaxEnt', 'ALTEON-CS-PHYSICAL-MIB' => 'vlanCurCfgLearn', 'ALTEON-TS-NETWORK-MIB' => 'ripCurCfgSupply', 'ALTEON-CHEETAH-NETWORK-MIB' => 'ripCurCfgIntfSupply', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, 'old_sw_ver' => 'ALTEON_TIGON_SWITCH_MIB__agSoftwareVersion', 'new_sw_ver' => 'ALTEON_CHEETAH_SWITCH_MIB__agSoftwareVersion', 'old_tftp_action' => 'ALTEON_TIGON_SWITCH_MIB__agTftpAction', 'new_tftp_action' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpAction', 'old_tftp_host' => 'ALTEON_TIGON_SWITCH_MIB__agTftpServer', 'new_tftp_host' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpServer', 'old_tftp_file' => 'ALTEON_TIGON_SWITCH_MIB__agTftpCfgFileName', 'new_tftp_file' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpCfgFileName', 'old_tftp_result' => 'ALTEON_TIGON_SWITCH_MIB__agTftpLastActionStatus', 'new_tftp_result' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpLastActionStatus', 'old_ip_max' => 'ALTEON_TS_NETWORK_MIB__ipInterfaceTableMax', 'new_ip_max' => 'ALTEON_CHEETAH_NETWORK_MIB__ipInterfaceTableMax', 'fan' => 'ALTEON_CHEETAH_SWITCH_MIB__hwFanStatus', 'old_ps1_stat' => 'ALTEON_TIGON_SWITCH_MIB__hwPowerSupplyStatus', 'old_ps2_stat' => 'ALTEON_TIGON_SWITCH_MIB__hwRedundantPSStatus', 'new_ps_stat' => 'ALTEON_CHEETAH_SWITCH_MIB__hwPowerSupplyStatus', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, # From agPortCurCfgTable 'old_ag_p_cfg_idx' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgIndx', 'new_ag_p_cfg_idx' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgIndx', 'old_ag_p_cfg_pref' => 'agPortCurCfgPrefLink', 'new_ag_p_cfg_pref' => 'agPortCurCfgPreferred', 'old_ag_p_cfg_pvid' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgPVID', 'new_ag_p_cfg_pvid' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgPVID', 'old_ag_p_cfg_fe_auto' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgFastEthAutoNeg', 'new_ag_p_cfg_fe_auto' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgFastEthAutoNeg', 'old_ag_p_cfg_fe_mode' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgFastEthMode', 'new_ag_p_cfg_fe_mode' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgFastEthMode', 'old_ag_p_cfg_ge_auto' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgGigEthAutoNeg', 'new_ag_p_cfg_ge_auto' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgGigEthAutoNeg', 'old_ag_p_cfg_name' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgPortName', 'new_ag_p_cfg_name' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgPortName', # From portInfoTable 'old_p_info_idx' => 'ALTEON_TS_PHYSICAL_MIB__portInfoIndx', 'new_p_info_idx' => 'ALTEON_CHEETAH_SWITCH_MIB__portInfoIndx', 'old_p_info_mode' => 'ALTEON_TS_PHYSICAL_MIB__portInfoMode', 'new_p_info_mode' => 'ALTEON_CHEETAH_SWITCH_MIB__portInfoMode', # From ipCurCfgIntfTable 'old_ip_cfg_vlan' => 'ALTEON_TS_NETWORK_MIB__ipCurCfgIntfVlan', 'new_ip_cfg_vlan' => 'ALTEON_CHEETAH_NETWORK_MIB__ipCurCfgIntfVlan', # From vlanCurCfgTable 'old_vlan_id' => 'ALTEON_TS_PHYSICAL_MIB__vlanCurCfgVlanId', 'new_vlan_id' => 'ALTEON_CS_PHYSICAL_MIB__vlanCurCfgVlanId', 'old_vlan_state' => 'ALTEON_TS_PHYSICAL_MIB__vlanCurCfgState', 'new_vlan_state' => 'ALTEON_CS_PHYSICAL_MIB__vlanCurCfgState', 'old_vlan_name' => 'ALTEON_TS_PHYSICAL_MIB__vlanCurCfgVlanName', 'new_vlan_name' => 'ALTEON_CS_PHYSICAL_MIB__vlanCurCfgVlanName', 'old_vlan_ports' => 'ALTEON_TS_PHYSICAL_MIB__vlanCurCfgPorts', 'new_vlan_ports' => 'ALTEON_CS_PHYSICAL_MIB__vlanCurCfgPorts', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub model { my $alteon = shift; my $id = $alteon->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::AlteonAD::model() - Device does not support sysObjectID\n" if $alteon->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^(aceswitch|aws|ods)//; $model =~ s/^acedirector/AD/; $model =~ s/^(copper|fiber)Module/BladeCenter GbESM/; return $model; } sub vendor { return 'radware'; } sub os { return 'alteon'; } sub os_ver { my $alteon = shift; my $version = $alteon->new_sw_ver() || $alteon->old_sw_ver(); return unless defined $version; return $version; } sub ps1_status { my $alteon = shift; my $old_ps = $alteon->old_ps1_stat(); my $new_ps = $alteon->new_ps_stat(); return $old_ps if $old_ps; if ($new_ps) { return 'ok' if ($new_ps eq 'singlePowerSupplyOk'); return 'failed' if ($new_ps eq 'firstPowerSupplyFailed'); } return; } sub ps2_status { my $alteon = shift; my $old_ps = $alteon->old_ps2_stat(); my $new_ps = $alteon->new_ps_stat(); return $old_ps if $old_ps; if ($new_ps) { return 'ok' if ($new_ps eq 'doublePowerSupplyOk'); return 'failed' if ($new_ps eq 'secondPowerSupplyFailed'); } return; } sub interfaces { my $alteon = shift; my $interfaces = $alteon->i_index(); my $descriptions = $alteon->i_description(); my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %interfaces = (); foreach my $iid ( keys %$interfaces ) { my $desc = $descriptions->{$iid}; next unless defined $desc; if ( $desc =~ /(^net\d+)/ ) { $desc = $1; } # IP interfaces are first followed by physical, number possible # varies by switch model elsif ( defined $ip_max and $iid > $ip_max ) { $desc = ( $iid % $ip_max ); $desc = 'mgmt' if $desc == 231; } $interfaces{$iid} = $desc; } return \%interfaces; } sub i_duplex { my $alteon = shift; my $p_mode = $alteon->new_p_info_mode() || $alteon->old_p_info_mode() || {}; my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %i_duplex; foreach my $if ( keys %$p_mode ) { my $duplex = $p_mode->{$if}; next unless defined $duplex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; my $idx; $idx = $if + $ip_max if ( defined $ip_max ); $i_duplex{$idx} = $duplex; } return \%i_duplex; } sub i_duplex_admin { my $alteon = shift; my $ag_pref = $alteon->new_ag_p_cfg_pref() || $alteon->old_ag_p_cfg_pref() || {}; my $ag_fe_auto = $alteon->new_ag_p_cfg_fe_auto() || $alteon->old_ag_p_cfg_fe_auto() || {}; my $ag_fe_mode = $alteon->new_ag_p_cfg_fe_mode() || $alteon->old_ag_p_cfg_fe_mode() || {}; my $ag_ge_auto = $alteon->new_ag_p_cfg_ge_auto() || $alteon->old_ag_p_cfg_ge_auto() || {}; my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my $i_speed = $alteon->i_speed() || {}; my %i_duplex_admin; foreach my $if ( keys %$ag_ge_auto ) { my $pref = $ag_pref->{$if} || ''; my $speed = $i_speed->{$if} || ''; my $ge_auto = $ag_ge_auto->{$if} || ''; my $fe_auto = $ag_fe_auto->{$if} || ''; my $fe_mode = $ag_fe_mode->{$if} || ''; # Default to auto my $string = 'auto'; if ( $ge_auto =~ /off/i && ( $pref =~ /gigabit/i || $speed eq '1.0 Gbps' ) ) { $string = 'full'; } if ( $fe_auto =~ /off/i && ( $pref =~ /fast/i || $speed =~ /100?\sMbps/ ) ) { $string = 'half' if ( $fe_mode =~ /half/i ); $string = 'full' if ( $fe_mode =~ /full/i ); } my $idx; $idx = $if + $ip_max if ( defined $ip_max ); $i_duplex_admin{$idx} = $string; } return \%i_duplex_admin; } sub i_name { my $alteon = shift; my $p_name = $alteon->new_ag_p_cfg_name() || $alteon->old_ag_p_cfg_name() || {}; my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %i_name; foreach my $iid ( keys %$p_name ) { my $name = $p_name->{$iid}; next unless defined $name; my $idx; $idx = $iid + $ip_max if ( defined $ip_max ); $i_name{$idx} = $name; } return \%i_name; } sub v_index { my $alteon = shift; my $partial = shift; return $alteon->new_vlan_id($partial) || $alteon->old_vlan_id($partial); } sub v_name { my $alteon = shift; my $partial = shift; return $alteon->new_vlan_name($partial) || $alteon->old_vlan_name($partial); } sub i_vlan { my $alteon = shift; my $ag_vlans = $alteon->new_ag_p_cfg_pvid() || $alteon->old_ag_p_cfg_pvid() || {}; my $ip_vlans = $alteon->new_ip_cfg_vlan() || $alteon->old_ip_cfg_vlan() || {}; my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %i_vlan; foreach my $if ( keys %$ip_vlans ) { my $ip_vlanid = $ip_vlans->{$if}; next unless defined $ip_vlanid; $i_vlan{$if} = $ip_vlanid; } foreach my $if ( keys %$ag_vlans ) { my $ag_vlanid = $ag_vlans->{$if}; next unless defined $ag_vlanid; my $idx; $idx = $if + $ip_max if ( defined $ip_max ); $i_vlan{$idx} = $ag_vlanid; } return \%i_vlan; } sub i_vlan_membership { my $alteon = shift; my $v_ports = $alteon->old_vlan_ports() || $alteon->new_vlan_ports() || {}; my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my $i_vlan_membership = {}; foreach my $vlan ( keys %$v_ports ) { my $portlist = [ split( //, unpack( "B*", $v_ports->{$vlan} ) ) ]; my $ret = []; # Convert portlist bit array to ifIndex array for ( my $i = 0; $i <= scalar(@$portlist); $i++ ) { my $idx; $idx = $i + $ip_max if ( defined $ip_max ); push( @{$ret}, $idx ) if ( @$portlist[$i] ); } #Create HoA ifIndex -> VLAN array foreach my $port ( @{$ret} ) { push( @{ $i_vlan_membership->{$port} }, $vlan ); } } return $i_vlan_membership; } sub i_vlan_membership_untagged { my $alteon = shift; my $partial = shift; my $vlans = $alteon->i_vlan($partial); my $i_vlan_membership = {}; foreach my $port (keys %$vlans) { my $vlan = $vlans->{$port}; push( @{ $i_vlan_membership->{$port} }, $vlan ); } return $i_vlan_membership; } # Bridge MIB does not map Bridge Port to ifIndex correctly on some code # versions sub bp_index { my $alteon = shift; my $b_index = $alteon->orig_bp_index(); my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %bp_index; foreach my $iid ( keys %$b_index ) { my $port = $b_index->{$iid}; next unless defined $port; $port = $port + $ip_max if ( defined $ip_max and $iid == $ip_max ); $bp_index{$iid} = $port; } return \%bp_index; } 1; __END__ =head1 NAME SNMP::Info::Layer3::AlteonAD - SNMP Interface to Radware Alteon ADC Switches. =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $alteon = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $alteon->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Radware Alteon Series ADC switches and Nortel BladeCenter Layer2-3 GbE Switch Modules. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $alteon = new SNMP::Info::Layer3::AlteonAD(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $alteon->model() Returns model type. Checks $alteon->id() against the F and then parses out C, C, and C replaces C with AD, and replaces copperModule/fiberModule with BladeCenter GbESM. =item $alteon->vendor() Returns 'radware' =item $alteon->os() Returns 'alteon' =item $alteon->os_ver() Returns the software version reported by C =item $alteon->tftp_action() (C) =item $alteon->tftp_host() (C) =item $alteon->tftp_file() (C) =item $alteon->tftp_result() (C) =item $alteon->fan() (C) =item $alteon->ps1_status() Returns status of primary power supply =item $alteon->ps2_status() Returns status of redundant power supply =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $alteon->interfaces() Returns reference to the map between IID and physical port. Utilizes description for network interfaces. Ports are determined by formula (C). =item $alteon->i_duplex() Returns reference to hash. Maps port operational duplexes to IIDs. =item $alteon->i_duplex_admin() Returns reference to hash. Maps port admin duplexes to IIDs. =item $alteon->i_vlan() Returns a mapping between C and the PVID or default VLAN. =item $alteon->i_vlan_membership() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the egress list for the port. Example: my $interfaces = $alteon->interfaces(); my $vlans = $alteon->i_vlan_membership(); foreach my $iid (sort keys %$interfaces) { my $port = $interfaces->{$iid}; my $vlan = join(',', sort(@{$vlans->{$iid}})); print "Port: $port VLAN: $vlan\n"; } =item $alteon->i_vlan_membership_untagged() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port. =item $alteon->v_index() Returns VLAN IDs =item $alteon->v_name() Human-entered name for vlans. =item $alteon->i_name() Maps (C) to port and returns the human set port name if exists. =item $alteon->bp_index() Returns a mapping between C and the Bridge Table. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Altiga.pm000444000765000024 3007313215550564 20204 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Altiga # $Id$ # # Copyright (c) 2008 Jeroen van Ingen Schenau # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Altiga; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Altiga::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Altiga::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE $int_include_vpn $fake_idx $type_class/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'ALTIGA-VERSION-STATS-MIB' => 'alVersionString', 'ALTIGA-SESSION-STATS-MIB' => 'alActiveSessionCount', 'ALTIGA-HARDWARE-STATS-MIB' => 'alHardwarePs1Type', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, # From ALTIGA-VERSION-STATS-MIB 'os_ver' => 'alVersionString', # From ALTIGA-SESSION-STATS-MIB 'vpn_act_sess' => 'alActiveSessionCount', 'vpn_total_sess' => 'alTotalSessionCount', 'vpn_max_sess' => 'alMaxSessionCount', 'vpn_l2l_sess' => 'alActiveLanToLanSessionCount', 'vpn_mgmt_sess' => 'alActiveManagementSessionCount', 'vpn_ras_sess' => 'alActiveRemoteAccessSessionCount', # From ALTIGA-HARDWARE-STATS-MIB 'ps1_type' => 'alHardwarePs1Type', 'ps1_3v_alarm' => 'alHardwarePs1Voltage3vAlarm', 'ps1_5v_alarm' => 'alHardwarePs1Voltage5vAlarm', 'ps2_type' => 'alHardwarePs2Type', 'ps2_3v_alarm' => 'alHardwarePs2Voltage3vAlarm', 'ps2_5v_alarm' => 'alHardwarePs2Voltage5vAlarm', 'fan1_alarm' => 'alHardwareFan1RpmAlarm', 'fan2_alarm' => 'alHardwareFan2RpmAlarm', 'fan3_alarm' => 'alHardwareFan3RpmAlarm', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, 'i_type2' => 'ifType', 'i_lastchange2' => 'ifLastChange', 'vpn_sess_status' => 'alActiveSessionRowStatus', 'vpn_sess_user' => 'alActiveSessionUserName', 'vpn_sess_peer_ip' => 'alActiveSessionIpAddress', 'vpn_sess_protocol' => 'alActiveSessionProtocol', 'vpn_sess_encr' => 'alActiveSessionEncrType', 'vpn_sess_start' => 'alActiveSessionStartTime', 'vpn_sess_conntime' => 'alActiveSessionConnectTime', 'vpn_sess_out_oct' => 'alActiveSessionOctetsSent', 'vpn_sess_in_oct' => 'alActiveSessionOctetsRcvd', 'vpn_sess_group' => 'alActiveSessionGroupName', 'vpn_sess_gid' => 'alActiveSessionGroupId', 'vpn_sess_rem_ip' => 'alActiveSessionPublicIpAddress', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, 'ps1_3v_alarm' => \&munge_alarm, 'ps1_5v_alarm' => \&munge_alarm, 'ps2_3v_alarm' => \&munge_alarm, 'ps2_5v_alarm' => \&munge_alarm, 'fan1_alarm' => \&munge_alarm, 'fan2_alarm' => \&munge_alarm, 'fan3_alarm' => \&munge_alarm, ); # Variable to modify behaviour of "interfaces" subroutine. # * When set to 0, "interfaces" returns only fixed interfaces from the IF-MIB, # * When set to 1, "interfaces" returns fixed interfaces from IF-MIB and LAN-to-LAN tunnels from ALTIGA-SESSION-MIB # TODO: This should be an instance method, not a class global $int_include_vpn = 1; # Variable to prepended to each tunnel index when tunnel is added to %interfaces, to avoid overwriting "real" ifIndex entries $fake_idx = 3076; # Variable to classify session types into categories: 0 - unclassified, 1 - LAN-to-LAN or fixed, 2 - RAS or dynamic, 3 - administrative $type_class = { 'pptp' => 2, 'l2tp' => 2, 'ipsec' => 2, 'http' => 3, 'ftp' => 3, 'telnet' => 3, 'snmp' => 3, 'tftp' => 3, 'console' => 3, 'debugTelnet' => 3, 'debugConsole' => 3, 'other' => 3, 'ike' => 0, 'l2tpOverIpSec' => 2, 'ipsecLanToLan' => 1, 'ipsecOverUdp' => 2, 'ssh' => 3, 'vcaLanToLan' => 1, 'ipsecOverTcp' => 2, 'pppoe' => 2, 'ipsecOverNatT' => 2, 'ipsecLan2LanOverNatT' => 1, 'l2tpOverIpsecOverNatT' => 2, 'userHttps' => 2, 'pop3s' => 2, 'imap4s' => 2, 'smtps' => 2, 'httpsTunnel' => 2, }; sub vendor { return 'altiga'; } sub os { return 'altiga'; } # $altiga->interfaces() - Map the Interfaces to their physical names # Add interface number to interface name to prevent duplicate ifDescr # Included statically configured VPN tunnels if ($int_include_vpn) sub interfaces { my $altiga = shift; my $partial = shift; my $interfaces = $altiga->i_index($partial); my $descriptions = $altiga->i_description($partial); my %int_rev = (); my %interfaces = (); foreach my $iid (sort {$a cmp $b} keys %$interfaces) { my $desc = $descriptions->{$iid}; next unless defined $desc; if (!exists $int_rev{$desc}) { $interfaces{$iid} = $desc; $int_rev{$desc} = $iid; } else { my $done = 0; my $unique_desc; my $cnt = 1; until ($done) { $cnt++; $unique_desc = sprintf("%s (%d)", $desc, $cnt); if (!exists $int_rev{$unique_desc}) { $done++; } } $int_rev{$unique_desc} = $iid; $interfaces{$iid} = $unique_desc; $interfaces{ $int_rev{$desc} } = sprintf("%s (%d)", $desc, 1); } } if ($int_include_vpn) { my $tun_type = $altiga->vpn_sess_protocol(); my $peer = $altiga->vpn_sess_peer_ip(); my $remote = $altiga->vpn_sess_rem_ip(); my $group = $altiga->vpn_sess_gid(); foreach my $tunnel (keys %$tun_type) { if ($type_class->{$tun_type->{$tunnel}} eq 1) { $interfaces{"$fake_idx.$tunnel"} = sprintf("%s VPN to %s", uc($tun_type->{$tunnel}), $remote->{$tunnel}); } } } return \%interfaces; } sub i_type { my $altiga = shift; my $partial = shift; my $types = $altiga->i_type2(); if ($int_include_vpn) { my $tun_type = $altiga->vpn_sess_protocol(); foreach my $tunnel (keys %$tun_type) { $types->{"$fake_idx.$tunnel"} = $tun_type->{$tunnel}; } } return $types; } sub i_lastchange { my $altiga = shift; my $partial = shift; # TODO: This is what munges are for. my $lastchange = $altiga->i_lastchange2(); if ($int_include_vpn) { my $tun_start = $altiga->vpn_sess_start(); foreach my $tunnel (keys %$tun_start) { $lastchange->{"$fake_idx.$tunnel"} = $tun_start->{$tunnel}; } } return $lastchange; } sub ps1_status { my $altiga = shift; my $alarm_3v = $altiga->ps1_3v_alarm() || ""; my $alarm_5v = $altiga->ps1_5v_alarm() || ""; return sprintf("3V: %s, 5V: %s", $alarm_3v, $alarm_5v); } sub ps2_status { my $altiga = shift; my $alarm_3v = $altiga->ps2_3v_alarm() || ""; my $alarm_5v = $altiga->ps2_5v_alarm() || ""; return sprintf("3V: %s, 5V: %s", $alarm_3v, $alarm_5v); } sub fan { my $altiga = shift; my $alarm_fan1 = $altiga->fan1_alarm() || ""; my $alarm_fan2 = $altiga->fan2_alarm() || ""; my $alarm_fan3 = $altiga->fan3_alarm() || ""; return sprintf("Fan 1: %s, Fan 2: %s, Fan 3: %s", $alarm_fan1, $alarm_fan2, $alarm_fan3); } sub munge_alarm { my $alarm = shift; if ($alarm eq 'false') { return 'OK'; } elsif ($alarm eq 'true') { return 'FAIL'; } else { return "(n/a)"; } } 1; __END__ =head1 NAME SNMP::Info::Layer3::Altiga - SNMP Interface to Cisco (formerly Altiga) VPN concentrators =head1 AUTHOR Jeroen van Ingen Schenau =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $altiga = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'my_vpn_host', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $altiga->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Cisco (formerly Altiga) VPN concentrators =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 Class Variables (options) =over =item $SNMP::Info::Layer3::Altiga::int_include_vpn Variable to modify behavior of "interfaces" subroutine. * When set to 0, "interfaces" returns only fixed interfaces from the IF-MIB, * When set to 1, "interfaces" returns fixed interfaces from IF-MIB and LAN-to-LAN tunnels from ALTIGA-SESSION-MIB (default) =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $altiga->vendor() Returns 'altiga' =item $altiga->os() Returns 'altiga' =item $altiga->os_ver() Tries to determine OS version from the C field. Returns version or C =item $altiga->fan() Combines results from C, C, and C methods. =item $altiga->ps1_status() Combines C and C methods. =item $altiga->ps2_status() Combines C and C methods. =back =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $altiga->interfaces() This method overrides the interfaces() method inherited from SNMP::Info. It provides a mapping between the Interface Table Index (iid) and the physical port name, adding a port number to the port name to prevent duplicate names. =item $altiga->i_lastchange() Filters out the results depending on the value of $SNMP::Info::Layer3::Altiga::int_include_vpn =item $altiga->i_type() Filters out the results depending on the value of $SNMP::Info::Layer3::Altiga::int_include_vpn =back =head1 MUNGES =over =item munge_alarm() Changes C and C to C, C, and C<(n/a)>. =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Arista.pm000444000765000024 1542413215550564 20231 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Arista # $Id$ # # Copyright (c) 2008 Arista Networks, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of Arista Networks, Inc. nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Arista; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::MAU; use SNMP::Info::LLDP; use SNMP::Info::Aggregate 'agg_ports_ifstack'; @SNMP::Info::Layer3::Arista::ISA = qw/ SNMP::Info::Aggregate SNMP::Info::LLDP SNMP::Info::MAU SNMP::Info::Layer3 Exporter /; @SNMP::Info::Layer3::Arista::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::MAU::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::Aggregate::MIBS, 'ARISTA-PRODUCTS-MIB' => 'aristaProducts', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::MAU::GLOBALS, %SNMP::Info::LLDP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::MAU::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::MAU::MUNGE, %SNMP::Info::LLDP::MUNGE, ); # use MAU-MIB for admin. duplex and admin. speed *SNMP::Info::Layer3::Arista::i_duplex_admin = \&SNMP::Info::MAU::mau_i_duplex_admin; *SNMP::Info::Layer3::Arista::i_speed_admin = \&SNMP::Info::MAU::mau_i_speed_admin; sub vendor { return 'arista'; } sub os { return 'EOS'; } sub os_ver { my $arista = shift; my $descr = $arista->description(); my $os_ver = undef; $os_ver = $1 if ( $descr =~ /\s+EOS\s+version\s+(\S+)\s+/ ); return $os_ver; } sub model { my $arista = shift; my $id = $arista->id(); my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^arista//; return $model; } # The LLDP MIB leaves it up in the air what the index means. # On EOS, it's a dot1d port. sub lldp_if { my $arista = shift; my $partial = shift; # We pick a column that someone else is likely to want, # so that the cache means that hopefully this doesn't # cause any more SNMP transactions in total. my $desc = $arista->lldp_rem_desc($partial) || {}; my $bp_index = $arista->bp_index() || {}; my $lldp_if = {}; foreach my $key ( keys %$desc ) { my @aOID = split( '\.', $key ); my $port = $aOID[1]; $lldp_if->{$key} = $bp_index->{$port}; } return $lldp_if; } sub agg_ports { return agg_ports_ifstack(@_) } 1; __END__ =head1 NAME SNMP::Info::Layer3::Arista - SNMP Interface to Arista Networks EOS =head1 AUTHOR Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $arista = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $arista->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Arista Networks EOS-based devices =head2 Inherited Classes =over =item SNMP::Info::Aggregate =item SNMP::Info::Layer3 =item SNMP::Info::MAU =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar values from SNMP =over =item $arista->vendor() Returns 'Arista Networks, Inc.' =item $arista->model() Tries to reference $arista->id() to one of the product MIBs listed above Removes 'arista' from the name for readability. =item $arista->os() Returns 'EOS' =item $arista->os_ver() Grabs the os version from C =back =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::MAU See documentation in L for details. =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $arista->i_duplex_admin() Returns info from F =item $arista->i_speed_admin() Returns info from F =item $arista->lldp_if() Returns the mapping to the SNMP Interface Table. =item C Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Aruba.pm000444000765000024 12526213215550564 20062 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Aruba # $Id$ # # Copyright (c) 2013 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Aruba; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; @SNMP::Info::Layer3::Aruba::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Aruba::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, 'WLSR-AP-MIB' => 'wlsrHideSSID', 'WLSX-IFEXT-MIB' => 'ifExtVlanName', 'WLSX-POE-MIB' => 'wlsxPseSlotPowerAvailable', 'WLSX-SWITCH-MIB' => 'wlsxHostname', 'WLSX-SYSTEMEXT-MIB' => 'wlsxSysExtSwitchBaseMacaddress', 'WLSX-USER-MIB' => 'nUserCurrentVlan', 'WLSX-WLAN-MIB' => 'wlanAPFQLN', #'ALCATEL-IND1-TP-DEVICES' => 'familyOmniAccessWireless', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'aruba_serial_old' => 'wlsxSwitchLicenseSerialNumber', 'aruba_serial_new' => 'wlsxSysExtLicenseSerialNumber', 'aruba_model' => 'wlsxModelName', 'mac' => 'wlsxSysExtSwitchBaseMacaddress', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, # WLSR-AP-MIB::wlsrConfigTable 'aruba_ap_ssidbcast' => 'wlsrHideSSID', # WLSX-IFEXT-MIB::wlsxIfExtPortTable 'aruba_if_idx' => 'ifExtPortIfIndex', 'aruba_if_mode' => 'ifExtMode', 'aruba_if_pvid' => 'ifExtTrunkNativeVlanId', 'aruba_if_duplex' => 'ifExtPortDuplex', # WLSX-IFEXT-MIB::wlsxIfExtVlanMemberTable 'aruba_if_vlan_member' => 'ifExtVlanMemberStatus', # WLSX-IFEXT-MIB::::wlsxIfExtVlanTable 'aruba_v_name' => 'ifExtVlanName', # Other cd11_ methods are indexed by staPhyAddress, we need to # strip staAccessPointBSSID from the aruba_cd11_ methods. # wlanStaRSSI and staSignalToNoiseRatio don't appear to be reporting # distinct values. # WLSX-SWITCH-MIB::wlsxSwitchStationMgmtTable 'aruba_cd11_sigqual' => 'staSignalToNoiseRatio', 'aruba_cd11_txrate' => 'staTransmitRate', # WLSX-SWITCH-MIB::wlsxSwitchStationStatsTable 'aruba_cd11_rxbyte' => 'staRxBytes', 'aruba_cd11_txbyte' => 'staTxBytes', 'aruba_cd11_rxpkt' => 'staRxPackets', 'aruba_cd11_txpkt' => 'staTxPackets', # WLSX-SYSTEMEXT-MIB::wlsxSysExtCardTable 'aruba_card_type' => 'sysExtCardType', 'aruba_card_serial' => 'sysExtCardSerialNo', 'aruba_card_hw' => 'sysExtCardHwRevision', 'aruba_card_fpga' => 'sysExtCardFpgaRevision', 'aruba_card_no' => 'sysExtCardAssemblyNo', # WLSX-USER-MIB::wlsxUserTable 'aruba_user_vlan' => 'nUserCurrentVlan', 'aruba_user_bssid' => 'nUserApBSSID', 'aruba_user_name' => 'userName', # WLSX-WLAN-MIB::wlsxWlanRadioTable 'aruba_apif_ch_num' => 'wlanAPRadioChannel', 'aruba_apif_power' => 'wlanAPRadioTransmitPower', 'aruba_apif_type' => 'wlanAPRadioType', 'aruba_apif_name' => 'wlanAPRadioAPName', # WLSX-WLAN-MIB::wlsxWlanAPTable 'aruba_ap_fqln' => 'wlanAPFQLN', 'aruba_ap_status' => 'wlanAPStatus', 'aruba_ap_type' => 'wlanAPModel', 'aruba_ap_serial' => 'wlanAPSerialNumber', 'aruba_ap_model' => 'wlanAPModelName', 'aruba_ap_name' => 'wlanAPName', 'aruba_ap_ip' => 'wlanAPIpAddress', 'aruba_ap_hw_ver' => 'wlanAPHwVersion', 'aruba_ap_sw_ver' => 'wlanAPSwVersion', # WLSX-WLAN-MIB::wlsxWlanESSIDVlanPoolTable 'aruba_ssid_vlan' => 'wlanESSIDVlanPoolStatus', # WLSX-WLAN-MIB::wlsxWlanAPBssidTable 'aruba_ap_bssid_ssid' => 'wlanAPESSID', # We pretend to have the CISCO-DOT11-MIB for signal strengths, etc. # WLSX-WLAN-MIB::wlsxWlanStationTable 'cd11_sigstrength' => 'wlanStaRSSI', 'cd11_ssid' => 'wlanStaAccessPointESSID', 'cd11_uptime' => 'wlanStaUpTime', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, 'aruba_ap_fqln' => \&munge_aruba_fqln, 'aruba_ap_type' => \&SNMP::Info::munge_e_type, 'aruba_card_type' => \&SNMP::Info::munge_e_type, 'aruba_ap_bssid_ssid' => \&SNMP::Info::munge_null, 'aruba_user_bssid' => \&SNMP::Info::munge_mac, 'cd11_ssid' => \&SNMP::Info::munge_null, ); sub layers { return '00000111'; } sub os { my $aruba = shift; my %osmap = ( 'alcatel-lucent' => 'aos-w', ); return $osmap{ $aruba->vendor() } || 'airos'; } sub vendor { my $aruba = shift; my $id = $aruba->id() || 'undef'; my %oidmap = ( 6486 => 'alcatel-lucent', ); $id = $1 if ( defined($id) && $id =~ /^\.1\.3\.6\.1\.4\.1\.(\d+)/ ); if ( defined($id) and exists( $oidmap{$id} ) ) { return $oidmap{$id}; } else { return 'aruba'; } } sub os_ver { my $aruba = shift; my $descr = $aruba->description(); return unless defined $descr; if ( $descr =~ m/Version\s+(\d+\.\d+\.\d+\.\d+)/ ) { return $1; } return; } sub model { my $aruba = shift; my $id = $aruba->id(); return unless defined $id; my $model = &SNMP::translateObj($id); return $id unless defined $model; return $model; } sub serial { my $aruba = shift; return $aruba->aruba_serial_old() || $aruba->aruba_serial_new(); } # Thin APs do not support ifMIB requirement sub i_index { my $aruba = shift; my $partial = shift; my $i_index = $aruba->orig_i_index($partial) || {}; my $ap_index = $aruba->aruba_apif_ch_num($partial) || {}; my %if_index; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; $if_index{$iid} = $index; } # Get Attached APs as Interfaces foreach my $ap_id ( keys %$ap_index ) { if ( $ap_id =~ /(\d+\.\d+\.\d+\.\d+\.\d+\.\d+)\.(\d+)/ ) { my $mac = join( ':', map { sprintf( "%02x", $_ ) } split( /\./, $1 ) ); my $radio = $2; next unless ( ( defined $mac ) and ( defined $radio ) ); $if_index{$ap_id} = "$mac.$radio"; } } return \%if_index; } sub interfaces { my $aruba = shift; my $partial = shift; my $i_index = $aruba->i_index($partial) || {}; my $i_name = $aruba->orig_i_name($partial) || {}; my %if; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { # Replace the Index with the ifName field. my $port = $i_name->{$iid}; next unless defined $port; $if{$iid} = $port; } else { $if{$iid} = $index; } } return \%if; } sub i_name { my $aruba = shift; my $partial = shift; my $i_index = $aruba->i_index($partial) || {}; my $i_name = $aruba->orig_i_name($partial) || {}; my $ap_name = $aruba->aruba_apif_name($partial) || {}; my %i_name; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $name = $i_name->{$iid}; next unless defined $name; $i_name{$iid} = $name; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { my $name = $ap_name->{$iid}; next unless defined $name; $i_name{$iid} = $name; } else { $i_name{$iid} = $index; } } return \%i_name; } sub i_description { my $aruba = shift; my $partial = shift; my $i_descr = $aruba->orig_i_description($partial) || {}; my $ap_index = $aruba->aruba_apif_ch_num($partial) || {}; my $ap_loc = $aruba->aruba_ap_fqln($partial) || {}; my %descr; foreach my $iid ( keys %$i_descr ) { my $descr = $i_descr->{$iid}; next unless defined $descr; $descr{$iid} = $descr; } foreach my $iid ( keys %$ap_index ) { my @parts = split( /\./, $iid ); my $idx = join( ".", @parts[ 0 .. 5 ] ); my $loc = $ap_loc->{$idx}; next unless defined $loc; $descr{$iid} = $loc; } return \%descr; } sub i_type { my $aruba = shift; my $partial = shift; my $i_type = $aruba->orig_i_type($partial) || {}; my $apif_type = $aruba->aruba_apif_type($partial) || {}; my %i_type; foreach my $iid ( keys %$i_type ) { my $type = $i_type->{$iid}; next unless defined $type; $i_type{$iid} = $type; } foreach my $iid ( keys %$apif_type ) { my $type = $apif_type->{$iid}; next unless defined $type; $i_type{$iid} = $type; } return \%i_type; } sub i_up { my $aruba = shift; my $partial = shift; my $i_up = $aruba->orig_i_up($partial) || {}; my $ap_index = $aruba->aruba_apif_ch_num($partial) || {}; my $ap_up = $aruba->aruba_ap_status($partial) || {}; my %i_up; foreach my $iid ( keys %$i_up ) { my $status = $i_up->{$iid}; next unless defined $status; $i_up{$iid} = $status; } foreach my $iid ( keys %$ap_index ) { my @parts = split( /\./, $iid ); my $idx = join( ".", @parts[ 0 .. 5 ] ); my $status = $ap_up->{$idx}; next unless defined $status; $i_up{$iid} = $status; } return \%i_up; } # Fake this for AP's since admin up if operationally up sub i_up_admin { my $aruba = shift; my $partial = shift; my $i_up = $aruba->orig_i_up_admin($partial) || {}; my $ap_index = $aruba->aruba_apif_ch_num($partial) || {}; my $ap_up = $aruba->aruba_ap_status($partial) || {}; my %i_up; foreach my $iid ( keys %$i_up ) { my $status = $i_up->{$iid}; next unless defined $status; $i_up{$iid} = $status; } foreach my $iid ( keys %$ap_index ) { my @parts = split( /\./, $iid ); my $idx = join( ".", @parts[ 0 .. 5 ] ); my $status = $ap_up->{$idx}; next unless defined $status; $i_up{$iid} = $status; } return \%i_up; } sub i_mac { my $aruba = shift; my $partial = shift; my $i_index = $aruba->i_index($partial) || {}; my $i_mac = $aruba->orig_i_mac($partial) || {}; my %i_mac; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( $index =~ /^\d+$/ ) { my $mac = $i_mac->{$iid}; next unless defined $mac; $i_mac{$iid} = $mac; } elsif ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { $index =~ s/\.\d+$//; next unless defined $index; $i_mac{$iid} = $index; } } return \%i_mac; } sub i_duplex { my $aruba = shift; my $partial = shift; my $index = $aruba->aruba_if_idx(); if ($partial) { my %r_index = reverse %$index; $partial = $r_index{$partial}; } my $ap_duplex = $aruba->aruba_if_duplex($partial) || {}; my %i_duplex; foreach my $if ( keys %$ap_duplex ) { my $duplex = $ap_duplex->{$if}; next unless defined $duplex; my $ifindex = $index->{$if}; next unless defined $ifindex; $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; $duplex = 'auto' if $duplex =~ /auto/i; $i_duplex{$ifindex} = $duplex; } return \%i_duplex; } sub v_index { my $aruba = shift; my $partial = shift; return $aruba->SUPER::v_index($partial) if keys %{ $aruba->SUPER::v_index($partial) }; my $v_name = $aruba->v_name($partial); my %v_index; foreach my $idx ( keys %$v_name ) { $v_index{$idx} = $idx; } return \%v_index; } sub v_name { my $aruba = shift; my $partial = shift; return $aruba->SUPER::v_name() || $aruba->aruba_v_name(); } sub i_vlan { my $aruba = shift; my $partial = shift; return $aruba->SUPER::i_vlan($partial) if keys %{ $aruba->SUPER::i_vlan($partial) }; # If we don't have Q-BRIDGE-MIB, we're a wireless controller my $index = $aruba->aruba_if_idx(); if ($partial) { my %r_index = reverse %$index; $partial = $r_index{$partial}; } my $i_pvid = $aruba->aruba_if_pvid($partial) || {}; my %i_vlan; foreach my $port ( keys %$i_pvid ) { my $vlan = $i_pvid->{$port}; my $ifindex = $index->{$port}; next unless defined $ifindex; $i_vlan{$ifindex} = $vlan; } return \%i_vlan; } sub i_vlan_membership { my $aruba = shift; my $partial = shift; return $aruba->SUPER::i_vlan_membership($partial) if keys %{ $aruba->SUPER::i_vlan_membership($partial) }; # If we don't have Q-BRIDGE-MIB, we're a wireless controller my $essid_ssid = $aruba->aruba_ap_bssid_ssid(); my $ssid_vlans = $aruba->aruba_ssid_vlan(); my $if_vlans = $aruba->aruba_if_vlan_member(); my %vlan_essid; # Create a hash of vlan and textual ssid # Possible to have more than one vlan per ssid foreach my $oid ( keys %$ssid_vlans ) { my @parts = split( /\./, $oid ); my $ssidlen = shift(@parts); my $ssid = pack( "C*", splice( @parts, 0, $ssidlen ) ); # Remove any control chars $ssid =~ s/[[:cntrl:]]//g; my $vlan = shift(@parts); $vlan_essid{$vlan} = $ssid; } my $i_vlan_membership = {}; # Handle physical ports first foreach my $oid ( keys %$if_vlans ) { my @parts = split( /\./, $oid ); my $vlan = shift(@parts); my $ifindex = shift(@parts); push( @{ $i_vlan_membership->{$ifindex} }, $vlan ); } foreach my $oid ( keys %$essid_ssid ) { my $ssid = $essid_ssid->{$oid}; my @parts = split( /\./, $oid ); my $idx = join( ".", @parts[ 0 .. 6 ] ); my @vlans = grep { $vlan_essid{$_} eq $ssid } keys %vlan_essid; foreach my $vlan (@vlans) { push( @{ $i_vlan_membership->{$idx} }, $vlan ); } } return $i_vlan_membership; } sub i_vlan_membership_untagged { my $aruba = shift; my $partial = shift; return $aruba->SUPER::i_vlan_membership_untagged($partial) if keys %{ $aruba->SUPER::i_vlan_membership_untagged($partial) }; # If we don't have Q-BRIDGE-MIB, we're a wireless controller # It is unclear if native VLAN is transmitted untagged # This assumes Cisco-like behavior on trunks that native VLAN is # transmitted untagged, if this needs to be changed we will need to # consider ifExtMode rather than just using i_vlan my $if_membership = $aruba->i_vlan_membership(); my $if_ = $aruba->i_vlan(); my $if_mode = $aruba->aruba_if_mode(); my $vlans = $aruba->i_vlan($partial); my $i_vlan_membership = {}; foreach my $port (keys %$vlans) { my $vlan = $vlans->{$port}; push( @{ $i_vlan_membership->{$port} }, $vlan ); } return $i_vlan_membership; } sub i_80211channel { my $aruba = shift; my $partial = shift; return $aruba->aruba_apif_ch_num($partial); } sub dot11_cur_tx_pwr_mw { my $aruba = shift; my $partial = shift; return $aruba->aruba_apif_power($partial); } sub i_ssidlist { my $aruba = shift; my $partial = shift; my $essid_ssid = $aruba->aruba_ap_bssid_ssid($partial) || {}; my %i_ssidlist; foreach my $oid ( keys %$essid_ssid ) { my $ssid = $essid_ssid->{$oid}; my @parts = split( /\./, $oid ); # Give the SSID a numeric value based upon tail of BSSID my $id = pop(@parts); # Get i_index my $iid = join( ".", @parts[ 0 .. 6 ] ); $i_ssidlist{"$iid.$id"} = $ssid; } return \%i_ssidlist; } sub i_ssidbcast { my $aruba = shift; my $partial = shift; my $essid_ssid = $aruba->aruba_ap_bssid_ssid($partial) || {}; my $ap_bc = $aruba->aruba_ap_ssidbcast($partial) || {}; my %i_bc; foreach my $oid ( keys %$essid_ssid ) { my @parts = split( /\./, $oid ); # Give the SSID a numeric value based upon tail of BSSID my $id = $parts[-1]; my $iid = join( ".", splice( @parts, 0, 7 ) ); my $bssid = join( ':', @parts ); my $bc = $ap_bc->{$bssid}; next unless defined $bc; $bc = ( $bc ? 0 : 1 ); $i_bc{"$iid.$id"} = $bc; } return \%i_bc; } sub i_ssidmac { my $aruba = shift; my $partial = shift; my $essid_ssid = $aruba->aruba_ap_bssid_ssid($partial) || {}; my %i_ssidmac; foreach my $oid ( keys %$essid_ssid ) { my @parts = split( /\./, $oid ); # Give the SSID a numeric value based upon tail of BSSID my $id = $parts[-1]; my $iid = join( ".", splice( @parts, 0, 7 ) ); my $bssid = join( ':', map { sprintf( "%02x", $_ ) } @parts ); $i_ssidmac{"$iid.$id"} = $bssid; } return \%i_ssidmac; } # Wireless switches do not support the standard Bridge MIB # Wired switches currently (AOS 7.2.0.0) do, but it seems only for # dot1q ports or access ports that are 'untrusted' ? sub bp_index { my $aruba = shift; my $partial = shift; my $i_index = $aruba->ifExtPortIfIndex($partial) || {}; my $essid_ssid = $aruba->aruba_ap_bssid_ssid($partial) || {}; # Collect standard bp_index first my $wired_bp_index = $aruba->SUPER::bp_index($partial) || {}; my %bp_index; my %offset; foreach my $iid ( keys %$wired_bp_index ) { my $index = $wired_bp_index->{$iid}; my $delta = $iid - $index; $offset{$delta}++; $bp_index{$iid} = $index; } # If the offset between dot1dBasePortIfIndex and ifIndex is consistent # add potentially missing mappings if ( keys %offset == 1 ) { foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; # Only augment bp_index, don't overwrite any existing mappings my $iid = (keys %offset)[0] + $index; next if exists $bp_index{$iid}; $bp_index{$iid} = $index; } } # Get Attached APs as Interfaces foreach my $oid ( keys %$essid_ssid ) { my @parts = split( /\./, $oid ); my $iid = join( ".", splice( @parts, 0, 7 ) ); my $bssid = join( '.', @parts ); $bp_index{$bssid} = $iid; } return \%bp_index; } sub fw_port { my $aruba = shift; my $partial = shift; my $fw_idx = $aruba->aruba_user_bssid($partial) || {}; my $wired_fw_port = $aruba->SUPER::qb_fw_port($partial) || {}; my %fw_port = %$wired_fw_port; foreach my $idx ( keys %$fw_idx ) { my $port = $fw_idx->{$idx}; next unless $port; my $iid = join( '.', map { hex($_) } split( ':', $port ) ); $fw_port{$idx} = $iid; } return \%fw_port; } sub fw_mac { my $aruba = shift; my $partial = shift; my $fw_idx = $aruba->aruba_user_bssid($partial) || {}; my $wired_fw_mac = $aruba->SUPER::qb_fw_mac($partial) || {}; my %fw_mac = %$wired_fw_mac; foreach my $idx ( keys %$fw_idx ) { my @parts = split( /\./, $idx ); my $mac = join( ':', map { sprintf( "%02x", $_ ) } @parts[ 0 .. 5 ] ); $fw_mac{$idx} = $mac; } return \%fw_mac; } sub qb_fw_vlan { my $aruba = shift; my $partial = shift; my $vlans = $aruba->aruba_user_vlan($partial) || {}; my $wired_fw_vlan = $aruba->SUPER::qb_fw_vlan($partial) || {}; my %fw_vlan = %$wired_fw_vlan; foreach my $idx ( keys %$vlans ) { my $vlan = $vlans->{$idx}; next unless $vlan; $fw_vlan{$idx} = $vlan; } return \%fw_vlan; } sub cd11_mac { my $aruba = shift; my $cd11_sigstrength = $aruba->cd11_sigstrength(); my $ret = {}; foreach my $idx ( keys %$cd11_sigstrength ) { my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); $ret->{$idx} = $mac; } return $ret; } sub cd11_sigqual { my $aruba = shift; my $cd11_sigqual = $aruba->aruba_cd11_sigqual(); my $ret = {}; foreach my $idx ( keys %$cd11_sigqual ) { my $value = $cd11_sigqual->{$idx}; $idx =~ s/(.\d+){6}$//; $ret->{$idx} = $value; } return $ret; } sub cd11_txrate { my $aruba = shift; my $cd11_txrate = $aruba->aruba_cd11_txrate(); my $ret = {}; foreach my $idx ( keys %$cd11_txrate ) { my $value = $cd11_txrate->{$idx}; my @rates; if ( $value =~ /(\d+)Mbps/ ) { push @rates, $1; } $idx =~ s/(.\d+){6}$//; $ret->{$idx} = \@rates; } return $ret; } sub cd11_rxbyte { my $aruba = shift; my $cd11_rxbyte = $aruba->aruba_cd11_rxbyte(); my $ret = {}; foreach my $idx ( keys %$cd11_rxbyte ) { my $value = $cd11_rxbyte->{$idx}; $idx =~ s/(.\d+){6}$//; $ret->{$idx} = $value; } return $ret; } sub cd11_txbyte { my $aruba = shift; my $cd11_txbyte = $aruba->aruba_cd11_txbyte(); my $ret = {}; foreach my $idx ( keys %$cd11_txbyte ) { my $value = $cd11_txbyte->{$idx}; $idx =~ s/(.\d+){6}$//; $ret->{$idx} = $value; } return $ret; } sub cd11_rxpkt { my $aruba = shift; my $cd11_rxpkt = $aruba->aruba_cd11_rxpkt(); my $ret = {}; foreach my $idx ( keys %$cd11_rxpkt ) { my $value = $cd11_rxpkt->{$idx}; $idx =~ s/(.\d+){6}$//; $ret->{$idx} = $value; } return $ret; } sub cd11_txpkt { my $aruba = shift; my $cd11_txpkt = $aruba->aruba_cd11_txpkt(); my $ret = {}; foreach my $idx ( keys %$cd11_txpkt ) { my $value = $cd11_txpkt->{$idx}; $idx =~ s/(.\d+){6}$//; $ret->{$idx} = $value; } return $ret; } # Pseudo ENTITY-MIB methods sub e_index { my $aruba = shift; my $ap_model = $aruba->aruba_ap_model() || {}; my $ap_cards = $aruba->aruba_card_serial() || {}; my %e_index; # Chassis $e_index{0} = 1; # Cards foreach my $idx ( keys %$ap_cards ) { $e_index{$idx} = $idx + 1; } # We're going to hack an index to capture APs foreach my $idx ( keys %$ap_model ) { # Create the integer index by joining the last three octets of the MAC. # Hopefully, this will be unique since the manufacturer should be # limited to Aruba. We can't use the entire MAC since # we would exceed the integer size limit. if ( $idx =~ /(\d+\.\d+\.\d+)$/ ) { my $index = int( join( '', map { sprintf "%03d", $_ } split /\./, $1 ) ); $e_index{$idx} = $index; } } return \%e_index; } sub e_class { my $aruba = shift; my $e_idx = $aruba->e_index() || {}; my %e_class; foreach my $iid ( keys %$e_idx ) { if ( $iid eq 0 ) { $e_class{$iid} = 'chassis'; } elsif ( $iid =~ /\d+/ ) { $e_class{$iid} = 'module'; } # This isn't a valid PhysicalClass, but we're hacking this anyway else { $e_class{$iid} = 'ap'; } } return \%e_class; } sub e_name { my $aruba = shift; my $e_idx = $aruba->e_index() || {}; my %e_name; foreach my $iid ( keys %$e_idx ) { if ( $iid eq 0 ) { $e_name{$iid} = 'WLAN Controller'; } elsif ( $iid =~ /^\d+$/ ) { $e_name{$iid} = "Card $iid"; } else { # APs $e_name{$iid} = 'AP'; } } return \%e_name; } sub e_descr { my $aruba = shift; my $ap_model = $aruba->aruba_ap_model() || {}; my $ap_name = $aruba->aruba_ap_name() || {}; my $ap_loc = $aruba->aruba_ap_fqln() || {}; my $card_type = $aruba->aruba_card_type() || {}; my $card_assy = $aruba->aruba_card_no() || {}; my %e_descr; # Chassis $e_descr{0} = $aruba->aruba_model(); #Cards foreach my $iid ( keys %$card_type ) { my $card = $card_type->{$iid}; next unless defined $card; my $assy = $card_assy->{$iid} || 'unknown'; $e_descr{$iid} = "$card Assembly: $assy"; } # APs foreach my $iid ( keys %$ap_name ) { my $name = $ap_name->{$iid}; next unless defined $name; my $model = $ap_model->{$iid} || 'AP'; my $loc = $ap_loc->{$iid} || 'unknown'; $e_descr{$iid} = "$model: $name ($loc)"; } return \%e_descr; } sub e_model { my $aruba = shift; my $ap_model = $aruba->aruba_ap_model() || {}; my $card_model = $aruba->aruba_card_type() || {}; my %e_model; # Chassis $e_model{0} = $aruba->aruba_model(); #Cards foreach my $iid ( keys %$card_model ) { my $card = $card_model->{$iid}; next unless defined $card; $e_model{$iid} = $card; } # APs foreach my $iid ( keys %$ap_model ) { my $model = $ap_model->{$iid}; next unless defined $model; $e_model{$iid} = $model; } return \%e_model; } sub e_type { my $aruba = shift; return $aruba->aruba_ap_type() || {}; } sub e_hwver { my $aruba = shift; my $ap_hw = $aruba->aruba_card_hw() || {}; my $ap_fpga = $aruba->aruba_card_fpga() || {}; my $ap_hw_ver = $aruba->aruba_ap_hw_ver() || {}; my %e_hwver; # Cards foreach my $iid ( keys %$ap_hw ) { my $hw = $ap_hw->{$iid}; next unless defined $hw; my $fpga = $ap_fpga->{$iid} || 'unknown'; $e_hwver{$iid} = "$hw $fpga"; } # APs foreach my $idx ( keys %$ap_hw_ver ) { my $hw_ver = $ap_hw_ver->{$idx}; next unless defined $hw_ver; $e_hwver{$idx} = "$hw_ver"; } return \%e_hwver; } sub e_swver { my $aruba = shift; my $ap_sw_ver = $aruba->aruba_ap_hw_ver() || {}; my %e_swver; # APs foreach my $idx ( keys %$ap_sw_ver ) { my $sw_ver = $ap_sw_ver->{$idx}; next unless defined $sw_ver; $e_swver{$idx} = "$sw_ver"; } return \%e_swver; } sub e_vendor { my $aruba = shift; my $e_idx = $aruba->e_index() || {}; my %e_vendor; foreach my $iid ( keys %$e_idx ) { $e_vendor{$iid} = 'aruba'; } return \%e_vendor; } sub e_serial { my $aruba = shift; my $ap_serial = $aruba->aruba_ap_serial() || {}; my $card_serial = $aruba->aruba_card_serial() || {}; my %e_serial; # Chassis $e_serial{0} = $aruba->serial() || ''; # Cards foreach my $iid ( keys %$card_serial ) { my $serial = $card_serial->{$iid}; next unless defined $serial; $e_serial{$iid} = $serial; } # APs foreach my $iid ( keys %$ap_serial ) { my $serial = $ap_serial->{$iid}; next unless defined $serial; $e_serial{$iid} = $serial; } return \%e_serial; } sub e_pos { my $aruba = shift; my $e_idx = $aruba->e_index() || {}; my %e_pos; # $pos is for AP's, set it high enough that cards come first my $pos = 100; foreach my $iid ( sort keys %$e_idx ) { if ( $iid eq 0 ) { $e_pos{$iid} = -1; next; } elsif ( $iid =~ /^\d+$/ ) { $e_pos{$iid} = $iid; next; } else { $pos++; $e_pos{$iid} = $pos; } } return \%e_pos; } sub e_parent { my $aruba = shift; my $e_idx = $aruba->e_index() || {}; my %e_parent; foreach my $iid ( sort keys %$e_idx ) { if ( $iid eq 0 ) { $e_parent{$iid} = 0; next; } else { $e_parent{$iid} = 1; } } return \%e_parent; } # arpnip: # # This is the controller snooping on the MAC->IP mappings. # Pretending this is arpnip data allows us to get MAC->IP # mappings even for stations that only communicate locally. # We also use the controller's knowledge of the APs' MAC and # IP addresses to augment the data. sub at_paddr { my $aruba = shift; my $user_mac = $aruba->aruba_user_bssid(); my $ap_ip = $aruba->aruba_ap_ip(); my %at_paddr; foreach my $idx ( keys %$user_mac ) { $idx =~ s/(.\d+){4}$//; my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); next unless $mac; $at_paddr{$idx} = $mac; } foreach my $idx ( keys %$ap_ip ) { next if ( $ap_ip->{$idx} eq '0.0.0.0' ); my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); $at_paddr{$idx} = $mac; } return \%at_paddr; } sub at_netaddr { my $aruba = shift; my $user_mac = $aruba->aruba_user_bssid(); my $ap_ip = $aruba->aruba_ap_ip(); my %at_netaddr; foreach my $idx ( keys %$ap_ip ) { next if ( $ap_ip->{$idx} eq '0.0.0.0' ); $at_netaddr{$idx} = $ap_ip->{$idx}; } foreach my $idx ( keys %$user_mac ) { my @parts = split( /\./, $idx ); my $iid = join( ".", splice( @parts, 0, 6 ) ); my $ip = join( ".", @parts ); next unless ( $ip =~ /^(\d+\.){3}(\d+)$/ ); next if ( $idx eq '0.0.0.0' ); $at_netaddr{$iid} = $ip; } return \%at_netaddr; } sub munge_aruba_fqln { my $loc = shift; $loc =~ s/\\\.0//g; return $loc; } # The index of wlsxPsePortTable is wlsxPsePortIndex which equals # ifIndex; however, to emulate POWER-ETHERNET-MIB we need a "module.port" # index. If ifDescr has the format x/x/x use it to determine the module # otherwise default to 1. Unfortunately, this means we can't map any # wlsxPsePortTable leafs directly and partials will not be supported. sub peth_port_ifindex { my $aruba = shift; my $indexes = $aruba->wlsxPsePortAdminStatus(); my $descrs = $aruba->i_description(); my $peth_port_ifindex = {}; foreach my $i ( keys %$indexes ) { my $descr = $descrs->{$i}; next unless $descr; my $new_idx = "1.$i"; if ( $descr =~ /(\d+)\/\d+\/\d+/ ) { $new_idx = "$1.$i"; } $peth_port_ifindex->{$new_idx} = $i; } return $peth_port_ifindex; } sub peth_port_admin { my $aruba = shift; my $p_index = $aruba->peth_port_ifindex() || {}; my $admin_states = $aruba->wlsxPsePortAdminStatus() || {}; my $peth_port_admin = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $state = $admin_states->{$port}; if ( $state =~ /enable/ ) { $peth_port_admin->{$i} = 'true'; } else { $peth_port_admin->{$i} = 'false'; } } return $peth_port_admin; } sub peth_port_neg_power { my $aruba = shift; my $p_index = $aruba->peth_port_ifindex() || {}; my $port_alloc = $aruba->wlsxPsePortPowerAllocated() || {}; my $peth_port_neg_power = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $power = $port_alloc->{$port}; next unless $power; $peth_port_neg_power->{$i} = $power; } return $peth_port_neg_power; } sub peth_port_power { my $aruba = shift; my $p_index = $aruba->peth_port_ifindex() || {}; my $port_consumed = $aruba->wlsxPsePortPowerConsumed() || {}; my $peth_port_power = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $power = $port_consumed->{$port}; next unless $power; $peth_port_power->{$i} = $power; } return $peth_port_power; } sub peth_port_class { my $aruba = shift; my $p_index = $aruba->peth_port_ifindex() || {}; my $port_class = $aruba->wlsxPsePortPdClass() || {}; my $peth_port_class = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $power = $port_class->{$port}; next unless $power; $peth_port_class->{$i} = $power; } return $peth_port_class; } sub peth_port_status { my $aruba = shift; my $p_index = $aruba->peth_port_ifindex() || {}; my $admin_states = $aruba->wlsxPsePortState() || {}; my $peth_port_status = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $state = $admin_states->{$port}; if ( $state eq 'on' ) { $peth_port_status->{$i} = 'deliveringPower'; } else { $peth_port_status->{$i} = 'disabled'; } } return $peth_port_status; } sub peth_power_status { my $aruba = shift; my $partial = shift; my $watts = $aruba->wlsxPseSlotPowerAvailable($partial) || {}; my $offset = (exists $watts->{0}) ? 1 : 0; my $peth_power_status = {}; foreach my $i ( keys %$watts ) { $peth_power_status->{$i + $offset} = 'on'; } return $peth_power_status; } sub peth_power_watts { my $aruba = shift; my $partial = shift; my $watts_total = $aruba->wlsxPseSlotPowerAvailable($partial) || {}; my $offset = (exists $watts_total->{0}) ? 1 : 0; my $peth_power_watts = {}; foreach my $i ( keys %$watts_total ) { my $total = $watts_total->{$i}; next unless $total; $peth_power_watts->{$i + $offset} = $total; } return $peth_power_watts; } sub peth_power_consumption { my $aruba = shift; my $watts = $aruba->wlsxPseSlotPowerConsumption() || {}; my $offset = (exists $watts->{0}) ? 1 : 0; my $peth_power_consumed = {}; foreach my $i ( keys %$watts ) { my $total = $watts->{$i}; next unless $total; $peth_power_consumed->{$i + $offset} = $total; } return $peth_power_consumed; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Aruba - SNMP Interface to Aruba wireless switches =head1 AUTHOR Eric Miller =head1 SYNOPSIS my $aruba = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $aruba->class(); print " Using device sub class : $class\n"; =head1 DESCRIPTION SNMP::Info::Layer3::Aruba is a subclass of SNMP::Info that provides an interface to Aruba wireless switches. The Aruba platform utilizes intelligent wireless switches which control thin access points. The thin access points themselves are unable to be polled for end station information. This class emulates bridge functionality for the wireless switch. This enables end station MAC addresses collection and correlation to the thin access point the end station is using for communication. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $aruba = new SNMP::Info::Layer3::Aruba(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =item F =item F =back =head2 Inherited MIBs See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $aruba->model() Returns model type. Cross references $aruba->id() with product IDs in the Aruba MIB. =item $aruba->vendor() Returns 'aruba' =item $aruba->os() Returns 'airos' =item $aruba->os_ver() Returns the software version extracted from C =back =head2 Overrides =over =item $aruba->layers() Returns 00000111. Class emulates Layer 2 and Layer 3functionality for Thin APs through proprietary MIBs. =item $aruba->serial() Returns the device serial number extracted from C or C =back =head2 Globals imported from SNMP::Info::Layer3 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $aruba->i_80211channel() Returns reference to hash. Current operating frequency channel of the radio interface. (C) =item $aruba->dot11_cur_tx_pwr_mw() Returns reference to hash. Current transmit power, in milliwatts, of the radio interface. (C) =item $aruba->i_ssidlist() Returns reference to hash. SSID's recognized by the radio interface. (C) =item $aruba->i_ssidbcast() Returns reference to hash. Indicates whether the SSID is broadcast, true or false. (C) =item $aruba->i_ssidmac() With the same keys as i_ssidlist, returns the Basic service set identification (BSSID), MAC address, the AP is using for the SSID. =item $aruba->cd11_mac() Returns client radio interface MAC addresses. =item $aruba->cd11_sigqual() Returns client signal quality. =item $aruba->cd11_txrate() Returns to hash of arrays. Client transmission speed in Mbs. =item $aruba->cd11_rxbyte() Total bytes received by the wireless client. =item $aruba->cd11_txbyte() Total bytes transmitted by the wireless client. =item $aruba->cd11_rxpkt() Total packets received by the wireless client. =item $aruba->cd11_txpkt() Total packets transmitted by the wireless client. =back =head2 Overrides =over =item $aruba->i_index() Returns reference to map of IIDs to Interface index. Extends C to support APs as device interfaces. =item $aruba->interfaces() Returns reference to map of IIDs to ports. Thin APs are implemented as device interfaces. The thin AP MAC address and radio number (C) are combined as the port identifier. =item $aruba->i_name() Interface name. Returns (C) for Ethernet interfaces and (C) for AP interfaces. =item $aruba->i_description() Returns reference to map of IIDs to interface descriptions. Returns C for Ethernet interfaces and the Fully Qualified Location Name (C) for AP interfaces. =item $aruba->i_type() Returns reference to map of IIDs to interface types. Returns C for Ethernet interfaces and C for AP interfaces. =item $aruba->i_up() Returns reference to map of IIDs to link status of the interface. Returns C for Ethernet interfaces and C for AP interfaces. =item $aruba->i_up_admin() Returns reference to map of IIDs to administrative status of the interface. Returns C for Ethernet interfaces and C for AP interfaces. =item $aruba->i_mac() Interface MAC address. Returns interface MAC address for Ethernet interfaces of ports and APs. =item $aruba->i_duplex() Returns reference to map of IIDs to current link duplex. Ethernet interfaces only. =item $aruba->v_index() Returns VLAN IDs. =item $aruba->v_name() Human-entered name for vlans. =item $aruba->i_vlan() Returns reference to map of IIDs to VLAN ID of the interface. =item $aruba->i_vlan_membership() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs for which the port is a member. =item $aruba->i_vlan_membership_untagged() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port. =item $aruba->bp_index() Augments the bridge MIB by returning reference to a hash containing the index mapping of BSSID to device port (AP). =item $aruba->fw_port() Augments the bridge MIB by including the BSSID a wireless end station is communicating through (C). =item $aruba->fw_mac() Augments the bridge MIB by including the wireless end station MAC (C) as extracted from the IID. =item $aruba->qb_fw_vlan() Augments the bridge MIB by including wireless end station VLANs (C). =back =head2 Pseudo F information These methods emulate F Physical Table methods using F and F. APs are included as subcomponents of the wireless controller. =over =item $aruba->e_index() Returns reference to hash. Key: IID and Value: Integer. The index for APs is created with an integer representation of the last three octets of the AP MAC address. =item $aruba->e_class() Returns reference to hash. Key: IID, Value: General hardware type. Returns 'ap' for wireless access points. =item $aruba->e_name() More computer friendly name of entity. Name is 'WLAN Controller' for the chassis, Card # for modules, or 'AP'. =item $aruba->e_descr() Returns reference to hash. Key: IID, Value: Human friendly name. =item $aruba->e_model() Returns reference to hash. Key: IID, Value: Model name. =item $aruba->e_type() Returns reference to hash. Key: IID, Value: Type of component. =item $aruba->e_hwver() Returns reference to hash. Key: IID, Value: Hardware revision. =item $aruba->e_swver() Returns reference to hash. Key: IID, Value: Software revision. =item $aruba->e_vendor() Returns reference to hash. Key: IID, Value: aruba. =item $aruba->e_serial() Returns reference to hash. Key: IID, Value: Serial number. =item $aruba->e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. Chassis cards are ordered to come before APs. =item $aruba->e_parent() Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. =back =head2 Power Over Ethernet Port Table These methods emulate the F Power Source Entity (PSE) Port Table C methods using the F Power over Ethernet Port Table C. =over =item $aruba->peth_port_ifindex() Creates an index of module.port to align with the indexing of the C with a value of C. The module defaults 1 if otherwise unknown. =item $aruba->peth_port_admin() Administrative status: is this port permitted to deliver power? C =item $aruba->peth_port_status() Current status: is this port delivering power. =item $aruba->peth_port_class() Device class: if status is delivering power, this represents the 802.3af class of the device being powered. =item $aruba->peth_port_neg_power() The power, in milliwatts, that has been committed to this port. This value is derived from the 802.3af class of the device being powered. =item $aruba->peth_port_power() The power, in milliwatts, that the port is delivering. =back =head2 Power Over Ethernet Module Table These methods emulate the F Main Power Source Entity (PSE) Table C methods using the F Power over Ethernet Port Table C. =over =item $aruba->peth_power_watts() The power supply's capacity, in watts. =item $aruba->peth_power_status() The power supply's operational status. =item $aruba->peth_power_consumption() How much power, in watts, this power supply has been committed to deliver. =back =head2 Arp Cache Table Augmentation The controller has knowledge of MAC->IP mappings for wireless clients. Augmenting the arp cache data with these MAC->IP mappings enables visibility for stations that only communicate locally. We also capture the AP MAC->IP mappings. =over =item $aruba->at_paddr() Adds MAC addresses extracted from the index of C. =item $aruba->at_netaddr() Adds IP addresses extracted from the index of C. =back =head2 Table Methods imported from SNMP::Info::Layer3 See L for details. =head1 Data Munging Callback Subroutines =over =item $aruba->munge_aruba_fqln() Remove nulls encoded as '\.0' from the Fully Qualified Location Name (C). =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/BayRS.pm000444000765000024 14232213215550564 20004 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::BayRS # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::BayRS; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Layer3; use SNMP::Info::Bridge; @SNMP::Info::Layer3::BayRS::ISA = qw/SNMP::Info SNMP::Info::Layer3 SNMP::Info::Bridge Exporter/; @SNMP::Info::Layer3::BayRS::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE %MODEL_MAP %MODID_MAP %PROCID_MAP/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::Layer3::MIBS, %SNMP::Info::Bridge::MIBS, 'Wellfleet-HARDWARE-MIB' => 'wfHwBpIdOpt', 'Wellfleet-OSPF-MIB' => 'wfOspfRouterId', 'Wellfleet-DOT1QTAG-CONFIG-MIB' => 'wfDot1qTagCfgVlanName', 'Wellfleet-CSMACD-MIB' => 'wfCSMACDCct', 'Wellfleet-MODULE-MIB' => 'wfHwModuleSlot', ); %GLOBALS = ( %SNMP::Info::GLOBALS, %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::Bridge::GLOBALS, 'bp_id' => 'wfHwBpIdOpt', 'bp_serial' => 'wfHwBpSerialNumber', 'ospf_rtr_id' => 'wfOspfRouterId', ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::Layer3::FUNCS, %SNMP::Info::Bridge::FUNCS, # From Wellfleet-CSMACD-MIB::wfCSMACDTable 'wf_csmacd_cct' => 'wfCSMACDCct', 'wf_csmacd_slot' => 'wfCSMACDSlot', 'wf_csmacd_conn' => 'wfCSMACDConnector', 'wf_csmacd_mtu' => 'wfCSMACDMtu', 'wf_duplex' => 'wfCSMACDLineCapability', 'wf_csmacd_line' => 'wfCSMACDLineNumber', # From Wellfleet-CSMACD-MIB::wfCSMACDAutoNegTable 'wf_auto' => 'wfCSMACDAutoNegSpeedSelect', # From Wellfleet-DOT1QTAG-CONFIG-MIB::wfDot1qTagConfigTable 'wf_vlan_name' => 'wfDot1qTagCfgVlanName', 'wf_local_vlan_id' => 'wfDot1qTagCfgLocalVlanId', 'wf_global_vlan_id' => 'wfDot1qTagCfgGlobalVlanId', 'wf_vlan_port' => 'wfDot1qTagCfgPhysicalPortId', # From Wellfleet-HARDWARE-MIB::wfHwTable 'wf_hw_slot' => 'wfHwSlot', 'wf_hw_mod_id' => 'wfHwModIdOpt', 'wf_hw_mod_rev' => 'wfHwModRev', 'wf_hw_mod_ser' => 'wfHwModSerialNumber', 'wf_hw_mobo_id' => 'wfHwMotherBdIdOpt', 'wf_hw_mobo_rev' => 'wfHwMotherBdRev', 'wf_hw_mobo_ser' => 'wfHwMotherBdSerialNumber', 'wf_hw_diag' => 'wfHwDiagPromRev', 'wf_hw_boot' => 'wfHwBootPromRev', 'wf_hw_mobo_mem' => 'wfHwMotherBdMemorySize', 'wf_hw_cfg_time' => 'wfHwConfigDateAndTime', 'wf_hw_db_ser' => 'wfHwDaughterBdSerialNumber', 'wf_hw_bb_ser' => 'wfHwBabyBdSerialNumber', 'wf_hw_mm_ser' => 'wfHwModuleModSerialNumber', 'wf_hw_md1_ser' => 'wfHwModDaughterBd1SerialNumber', 'wf_hw_md2_ser' => 'wfHwModDaughterBd2SerialNumber', ); %MUNGE = ( %SNMP::Info::MUNGE, %SNMP::Info::Layer3::MUNGE, %SNMP::Info::Bridge::MUNGE, 'wf_hw_boot' => \&munge_hw_rev, 'wf_hw_diag' => \&munge_hw_rev, 'wf_hw_mobo_ser' => \&munge_wf_serial, 'wf_hw_mod_ser' => \&munge_wf_serial, 'wf_hw_db_ser' => \&munge_wf_serial, 'wf_hw_bb_ser' => \&munge_wf_serial, 'wf_hw_mm_ser' => \&munge_wf_serial, 'wf_hw_md1_ser' => \&munge_wf_serial, 'wf_hw_md2_ser' => \&munge_wf_serial, ); %MODEL_MAP = ( 'acefn' => 'FN', 'aceln' => 'LN', 'acecn' => 'CN', 'afn' => 'AFN', 'in' => 'IN', 'an' => 'AN', 'arn' => 'ARN', 'sys5000' => '5000', 'freln' => 'BLN', 'frecn' => 'BCN', 'frerbln' => 'BLN-2', 'asn' => 'ASN', 'asnzcable' => 'ASN-Z', 'asnbcable' => 'ASN-B', ); %MODID_MAP = ( 1 => 'DUAL ENET', 8 => 'DUAL ENET', 16 => 'QSYNC', 24 => 'DUAL T1', 32 => 'SSE,DSE', 40 => 'TS 4/16 - 1x2', 44 => 'TS 4/16 - 1x1', 45 => 'TS 4/16 - 1x0', 48 => 'SYSTEM I/O', 49 => 'SYSTEM I/O', 56 => 'DUAL T1', 57 => 'DUAL T1 - 56K', 58 => 'T1 - SINGLE PORT', 60 => 'T1 56K - SINGLE PORT', 61 => 'E1 - 75 OHM', 80 => 'QSYNC', 112 => 'DSDE 4', 116 => 'DSE', 118 => 'SSE', 132 => 'ESA 2x0', 156 => 'ESA 2x2', 162 => 'QUAD ENET with CAM DAUGHTERCARD', 164 => 'QUAD ENET with CAM DAUGHTERCARD,QUAD ENET CAM DAUGHTER CARD', 168 => 'MCT1 - 2', 169 => 'MCT1 - 1', 176 => 'DUAL TOKEN', 184 => 'MCE1 - DUAL PORT', 185 => 'MCE1 - SINGLE PORT', 192 => 'MULTIMODE FDDI', 193 => 'SINGLEMODE FDDI PHY-B', 194 => 'SINGLEMODE FDDI PHY-A/B', 195 => 'SINGLEMODE FDDI PHY-A', 196 => 'MULTIMODE FDDI,FDDI CAM DAUGHTER CARD', 197 => 'SINGLEMODE FDDI PHY-B,FDDI CAM DAUGHTER CARD', 198 => 'SINGLEMODE FDDI PHY-A/B,FDDI CAM DAUGHTER CARD', 199 => 'SINGLEMODE FDDI PHY-A,FDDI CAM DAUGHTER CARD', 208 => { 0 => 'AFNes - V.35,AFNes - X.21,AFNes - CCITT V.35,AFNes - RS449/RS422,AFNes - V.35 w/FLASH,AFNes - X.21 w/FLASH,AFNes-CCITT V.35 w/FL,AFNes - RS422 w/FLASH AFNes 16M - V.35,AFNes 16M - X.21,AFNes 16M - CCITT V.35,AFNes 16M - RS449/RS422,AFNes 16M V.35 w/Flash,AFNes 16M X.21 w/Flash,AFNes 16M CCITT V.35 w/Flash,AFNes 16M RS449/RS422 w/Flash', 4096 => 'AFNes - V.35,AFNes - X.21,AFNes - CCITT V.35,AFNes - RS449/RS422,AFNes - V.35 w/FLASH,AFNes - X.21 w/FLASH,AFNes-CCITT V.35 w/FL,AFNes - RS422 w/FLASH', 16384 => 'AFNes 16M - V.35,AFNes 16M - X.21,AFNes 16M - CCITT V.35,AFNes 16M - RS449/RS422,AFNes 16M V.35 w/Flash,AFNes 16M X.21 w/Flash,AFNes 16M CCITT V.35 w/Flash,AFNes 16M RS449/RS422 w/Flash', }, 216 => { 0 => 'AFNts 2x2,AFNts 2x2 - w/FLASH,AFNTS 2X2 16MB,AFNTS 2X2 16MB FLASH', 4096 => 'AFNts 2x2,AFNts 2x2 - w/FLASH', 16384 => 'AFNTS 2X2 16MB,AFNTS 2X2 16MB FLASH', }, 217 => { 0 => 'AFNts 1x2,AFNts 1x2 - w/FLASH,AFNTS 1X2 16MB,AFNTS 1X2 16MB FLASH', 4096 => 'AFNts 1x2,AFNts 1x2 - w/FLASH', 16384 => 'AFNTS 1X2 16MB,AFNTS 1X2 16MB FLASH', }, 225 => 'HSSI - SINGLE PORT', 232 => 'EASF 0 DEFA & 0 CAMS', 236 => 'ESAF w/DEFA & 2 CAMS,ESAF w/DEFA & 6 CAMS', 256 => 'QUAD TOKEN', 512 => 'SPX NET MODULE', 769 => 'HOT SWAP SPEX NET MOD', 1024 => { 4096 => 'AN-ENET 1X2 SPARE 4F/8D,BAYSTACK AN-ES 8MB', 8192 => 'AN-ENET 1X2 SPARE 4F/8D,BAYSTACK AN-ES 8MB', 16384 => 'AN-ENET 1X2 SPARE 4F/16D,BAYSTACK AN-ES 16MB', }, 1025 => { 4096 => 'AN-ENET/TOK 1X1X2 SPARE 4F/8D,BAYSTACK AN-ETS 8MB', 8192 => 'AN-ENET/TOK 1X1X2 SPARE 4F/8D,BAYSTACK AN-ETS 8MB', 16384 => 'AN-ENET/TOK 1X1X2 SPARE 4F/16D,BAYSTACK AN-ETS 16MB', }, 1026 => { 4096 => 'AN-HUB SPARE 4F/8D,BAYSTACK ANH-12 8MB', 8192 => 'AN-HUB SPARE 4F/8D,BAYSTACK ANH-12 8MB', 16384 => 'AN - HUB SPARE 4F/16D,BAYSTACK ANH-12 16MB', }, 1027 => { 4096 => 'AN-ENET 1X2 SPARE 4F/8D,AN ISDN BRI DAUGHTER CARD', 8192 => 'AN-ENET 1X2 SPARE 4F/8D,AN ISDN BRI DAUGHTER CARD', 16384 => 'AN-ENET 1X2 SPARE 4F/16D,AN ISDN BRI DAUGHTER CARD', }, 1028 => { 4096 => 'AN-ENET/TOK 1X1X2 SPARE 4F/8D,AN ISDN BRI DAUGHTER CARD', 8192 => 'AN-ENET/TOK 1X1X2 SPARE 4F/8D,AN ISDN BRI DAUGHTER CARD', 16384 => 'AN-ENET/TOK 1X1X2 SPARE 4F/16D,AN ISDN BRI DAUGHTER CARD', }, 1029 => { 4096 => 'AN-HUB SPARE 4F/8D,AN ISDN BRI DAUGHTER CARD', 8192 => 'AN-HUB SPARE 4F/8D,AN ISDN BRI DAUGHTER CARD', 16384 => 'AN - HUB SPARE 4F/16D,AN ISDN BRI DAUGHTER CARD', }, 1030 => { 4096 => 'AN 3RD SYNC DAUGHTER CARD,AN-ENET 1X2 SPARE 4F/8D,BAYSTACK AN-ES 8MB', 8192 => 'AN 3RD SYNC DAUGHTER CARD,AN-ENET 1X2 SPARE 4F/8D,BAYSTACK AN-ES 8MB', 16384 => 'AN 3RD SYNC DAUGHTER CARD,AN-ENET 1X2 SPARE 4F/16D,BAYSTACK AN-ES 16MB', }, 1031 => { 4096 => 'AN 3RD SYNC DAUGHTER CARD,AN-ENET/TOK 1X1X2 SPARE 4F/8D,BAYSTACK AN-ETS 8MB', 8192 => 'AN 3RD SYNC DAUGHTER CARD,AN-ENET/TOK 1X1X2 SPARE 4F/8D,BAYSTACK AN-ETS 8MB', 16384 => 'AN 3RD SYNC DAUGHTER CARD,AN-ENET/TOK 1X1X2 SPARE 4F/16D,BAYSTACK AN-ETS 16MB', }, 1032 => { 4096 => 'AN 3RD SYNC DAUGHTER CARD,AN-HUB SPARE 4F/8D,BAYSTACK ANH-12 8MB', 8192 => 'AN 3RD SYNC DAUGHTER CARD,AN-HUB SPARE 4F/8D,BAYSTACK ANH-12 8MB', 16384 => 'AN 3RD SYNC DAUGHTER CARD,AN - HUB SPARE 4F/16D,BAYSTACK ANH-12 16MB', }, 1033 => { 4096 => 'AN 2ND ENET DAUGHTER CARD,AN-ENET 1X2 SPARE 4F/8D,BAYSTACK AN-ES 8MB', 8192 => 'AN 2ND ENET DAUGHTER CARD,AN-ENET 1X2 SPARE 4F/8D,BAYSTACK AN-ES 8MB', 16384 => 'AN 2ND ENET DAUGHTER CARD,AN-ENET 1X2 SPARE 4F/16D,BAYSTACK AN-ES 16MB', }, 1035 => { 4096 => 'AN 2ND ENET DAUGHTER CARD,AN-HUB SPARE 4F/8D,BAYSTACK ANH-12 8MB', 8192 => 'AN 2ND ENET DAUGHTER CARD,AN-HUB SPARE 4F/8D,BAYSTACK ANH-12 8MB', 16384 => 'AN 2ND ENET DAUGHTER CARD,AN - HUB SPARE 4F/16D,BAYSTACK ANH-12 16MB', }, 1037 => { 4096 => 'AN-TOK 1X2 SPARE 4F/8D,BAYSTACK AN-TS 8MB', 8192 => 'AN-TOK 1X2 SPARE 4F/8D,BAYSTACK AN-TS 8MB', 16384 => 'AN-TOK 1X2 SPARE 4F/16D,BAYSTACK AN-TS 16MB', }, 1038 => { 4096 => 'AN-TOK 1X2 SPARE 4F/8D,AN ISDN BRI DAUGHTER CARD', 8192 => 'AN-TOK 1X2 SPARE 4F/8D,AN ISDN BRI DAUGHTER CARD', 16384 => 'AN-TOK 1X2 SPARE 4F/16D,AN ISDN BRI DAUGHTER CARD', }, 1039 => { 4096 => 'AN 3RD SYNC DAUGHTER CARD,AN-TOK 1X2 SPARE 4F/8D,BAYSTACK AN-TS 8MB', 8192 => 'AN 3RD SYNC DAUGHTER CARD,AN-TOK 1X2 SPARE 4F/8D,BAYSTACK AN-TS 8MB', 16384 => 'AN 3RD SYNC DAUGHTER CARD,AN-TOK 1X2 SPARE 4F/16D,BAYSTACK AN-TS 16MB', }, 1042 => { 4096 => 'BAYSTACK AN-ETS 8MB,BAYSTACK AN N11 DCM', 8192 => 'BAYSTACK AN-ETS 8MB,BAYSTACK AN N11 DCM', 16384 => 'BAYSTACK AN-ETS 16MB,BAYSTACK AN N11 DCM', }, 1043 => { 4096 => 'BAYSTACK AN-ES 8MB,AN ISDN BRI DAUGHTER CARD', 8192 => 'BAYSTACK AN-ES 8MB,AN ISDN BRI DAUGHTER CARD', 16384 => 'BAYSTACK AN-ES 16MB,AN ISDN BRI DAUGHTER CARD', }, 1044 => { 4096 => 'BAYSTACK AN-ETS 8MB,AN ISDN BRI DAUGHTER CARD', 8192 => 'BAYSTACK AN-ETS 8MB,AN ISDN BRI DAUGHTER CARD', 16384 => 'BAYSTACK AN-ETS 16MB,AN ISDN BRI DAUGHTER CARD', }, 1045 => { 4096 => 'BAYSTACK ANH-12 8MB,AN ISDN BRI DAUGHTER CARD', 8192 => 'BAYSTACK ANH-12 8MB,AN ISDN BRI DAUGHTER CARD', 16384 => 'BAYSTACK ANH-12 16MB,AN ISDN BRI DAUGHTER CARD', }, 1046 => { 4096 => 'BAYSTACK AN-TS 8MB,AN ISDN BRI DAUGHTER CARD', 8192 => 'BAYSTACK AN-TS 8MB,AN ISDN BRI DAUGHTER CARD', 16384 => 'BAYSTACK AN-TS 16MB,AN ISDN BRI DAUGHTER CARD', }, 1047 => { 4096 => 'BAYSTACK ANH-8 8MB', 8192 => 'BAYSTACK ANH-8 8MB', 16384 => 'BAYSTACK ANH-8 16MB', }, 1048 => { 4096 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 N11 DCM', 8192 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 N11 DCM', 16384 => 'BAYSTACK ANH-8 16MB,BAYSTACK ANH-8 N11 DCM', }, 1049 => { 4096 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 3RD SYNC DAUGHTER CARD', 8192 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 3RD SYNC DAUGHTER CARD', 16384 => 'BAYSTACK ANH-8 16MB,BAYSTACK ANH-8 3RD SYNC DAUGHTER CARD', }, 1050 => { 4096 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 2ND ENET DAUGHTER CARD', 8192 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 2ND ENET DAUGHTER CARD', 16384 => 'BAYSTACK ANH-8 16MB,BAYSTACK ANH-8 2ND ENET DAUGHTER CARD', }, 1051 => { 4096 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 ISDN BRI DAUGHTER CARD', 8192 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 ISDN BRI DAUGHTER CARD', 16384 => 'BAYSTACK ANH-8 16MB,BAYSTACK ANH-8 ISDN BRI DAUGHTER CARD', }, 1052 => { 4096 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 3RD SYNC DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', 8192 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 3RD SYNC DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', 16384 => 'BAYSTACK ANH-8 16MB,BAYSTACK ANH-8 3RD SYNC DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', }, 1053 => { 4096 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 2ND ENET DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', 8192 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 2ND ENET DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', 16384 => 'BAYSTACK ANH-8 16MB,BAYSTACK ANH-8 2ND ENET DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', }, 1054 => { 4096 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 ISDN BRI DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', 8192 => 'BAYSTACK ANH-8 8MB,BAYSTACK ANH-8 ISDN BRI DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', 16384 => 'BAYSTACK ANH-8 16MB,BAYSTACK ANH-8 ISDN BRI DAUGHTER CARD,BAYSTACK ANH-8 N11 DCM', }, 1055 => { 4096 => 'BAYSTACK AN-ES 8MB,BAYSTACK AN N11 DCM', 8192 => 'BAYSTACK AN-ES 8MB,BAYSTACK AN N11 DCM', 16384 => 'BAYSTACK AN-ES 16MB,BAYSTACK AN N11 DCM', }, 1056 => { 4096 => 'BAYSTACK AN-ES 8MB,AN 3RD SYNC DAUGHTER CARD,BAYSTACK AN N11 DCM', 8192 => 'BAYSTACK AN-ES 8MB,AN 3RD SYNC DAUGHTER CARD,BAYSTACK AN N11 DCM', 16384 => 'BAYSTACK AN-ES 16MB,AN 3RD SYNC DAUGHTER CARD,BAYSTACK AN N11 DCM', }, 1057 => { 4096 => 'BAYSTACK AN-ES 8MB,AN 2ND ENET DAUGHTER CARD,BAYSTACK AN N11 DCM', 8192 => 'BAYSTACK AN-ES 8MB,AN 2ND ENET DAUGHTER CARD,BAYSTACK AN N11 DCM', 16384 => 'BAYSTACK AN-ES 16MB,AN 2ND ENET DAUGHTER CARD,BAYSTACK AN N11 DCM', }, 1059 => { 4096 => 'BAYSTACK AN-ETS 8MB,AN 3RD SYNC DAUGHTER CARD,BAYSTACK AN N11 DCM', 8192 => 'BAYSTACK AN-ETS 8MB,AN 3RD SYNC DAUGHTER CARD,BAYSTACK AN N11 DCM', 16384 => 'BAYSTACK AN-ETS 16MB,AN 3RD SYNC DAUGHTER CARD,BAYSTACK AN N11 DCM', }, 1062 => { 4096 => 'BAYSTACK AN-ES 8MB,AN ISDN BRI DAUGHTER CARD,BAYSTACK AN N11 DCM', 8192 => 'BAYSTACK AN-ES 8MB,AN ISDN BRI DAUGHTER CARD,BAYSTACK AN N11 DCM', 16384 => 'BAYSTACK AN-ES 16MB,AN ISDN BRI DAUGHTER CARD,BAYSTACK AN N11 DCM', }, 1063 => { 4096 => 'BAYSTACK AN-ETS 8MB,AN ISDN BRI DAUGHTER CARD,BAYSTACK AN N11 DCM', 8192 => 'BAYSTACK AN-ETS 8MB,AN ISDN BRI DAUGHTER CARD,BAYSTACK AN N11 DCM', 16384 => 'BAYSTACK AN-ETS 16MB,AN ISDN BRI DAUGHTER CARD,BAYSTACK AN N11 DCM', }, 1280 => 'DUAL ENET NET MODULE', 1536 => 'DUAL SYNC NET MODULE', 1537 => 'DUAL SYNC NET MODULE', 1538 => 'DUAL SYNC NET MODULE', 1540 => 'DUAL SYNC NET MODULE', 1541 => 'DUAL SYNC NET MODULE', 1542 => 'DUAL SYNC NET MODULE', 1544 => 'DUAL SYNC NET MODULE', 1545 => 'DUAL SYNC NET MODULE', 1546 => 'DUAL SYNC NET MODULE', 1584 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1585 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1586 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1588 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1589 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1590 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1592 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1593 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1594 => 'DUAL SYNC NET MODULE,ASN ISDN DAUGHTER CARD', 1793 => 'MUTLIMODE FDDI NET MODULE', 1801 => 'SINGLEMODE FDDI NET MODULE', 1825 => 'S.M. PHY A FDDI NET MODULE', 1833 => 'S.M. PHY B FDDI NET MODULE', 2048 => 'DUAL TOKEN NET MODULE', 2304 => '100 BASE-TX NET MODULE', 2560 => 'QUAD ISDN BRI NET MOD', 2816 => 'MCE1 NET MODULE', 3584 => 'SINGLE HSSI NET MODULE', 4098 => 'ATM LINK - OC3 MULTIMODE', 4099 => 'ATM LINK - OC3 SINGLEMODE', 4352 => 'OCTAL SYNC LINK MODULE', 4353 => 'OCTAL SYNC LINK MODULE,32 CONTEXTS HARDWARE COMPRESSION DGHTR. CARD', 4354 => 'OCTAL SYNC LINK MODULE,128 CONTEXTS HARDWARE COMPRESSION DGHTR. CARD', 4608 => 'SONET/SDH MMF LINK', 4609 => 'SONET/SDH SMF LINK', 4864 => '100 BASE-Tx ETHERNET', 5376 => 'QUAD PORT MULTICHANNEL T1 (QMCT1) RJ48', 5377 => 'QUAD PORT MULTICHANNEL T1 (QMCT1) DB15', 5378 => 'QUAD PORT MULTICHANNEL T1 DS0A (QMCT1 w/DS0A) DB15', 6144 => '4-PORT 10/100BASE-TX', 6145 => '4-PORT 100BASE-FX', 6400 => '1000BASE-SX', 6401 => '1000BASE-LX', 8448 => 'SRM-L', 8704 => 'ARN Motherboard Single Token Ring', 8720 => 'ARN Motherboard Single Ethernet', 8728 => 'ARN Motherboard Single 10/100BASE-TX', 8729 => 'ARN Motherboard Single 10/100BASE-FX', 8736 => 'ARN Serial Adapter Module', 8752 => 'ARN V.34 Modem Adapter Module', 8768 => 'ARN 56/64 DSU/CSU Adapter Module', 8784 => 'ARN ISDN BRI S/T Adapter Module', 8800 => 'ARN ISDN BRI U Adapter Module', 8816 => 'ARN Token Ring Expansion Module', 8832 => 'ARN Ethernet Expansion Module', 8848 => 'ARN Tri Serial Expansion Module', 8864 => 'ARN Ethernet and Tri-Serial Expansion Module', 8880 => 'ARN Token Ring and Tri-Serial Expansion Module', 8896 => 'arnmbenx10', 8912 => 'arnmbtrx10', 8928 => 'arnpbenx10', 8944 => 'arnpbtrx10', 8960 => 'arnpbtenx10', 8976 => 'arnpbttrx10', ); %PROCID_MAP = ( 1 => 'SYSTEM CONTROLLER', 2 => '5MEG ACE25', 3 => { 5120 => '5MEG ACE25', 8192 => '8MEG ACE25', }, 4 => { 4096 => 'ACE32', 8192 => '8MEG ACE32', 16384 => '16MEG ACE32', }, 5 => 'AFN', 6 => 'LN', 7 => 'FLASH SYSTEM CTRL.', 16384 => 'AN', 32 => { 4096 => 'ARN Ethernet - 4 MEG', 8192 => 'ARN Ethernet - 8 MEG', 16384 => 'ARN Ethernet - 16 MEG', 32768 => 'ARN Ethernet - 32 MEG', }, 256 => 'FAST ROUTING ENGINE', 768 => { 8192 => 'FRE2 - 8MEG', 16384 => 'FRE2 - 16MEG', 24576 => 'FRE2 - 24MEG', 32768 => 'FRE2 - 32MEG', }, 769 => { 8192 => 'FRE2 060 - 8MEG', 16384 => 'FRE2 060 - 16MEG', 32768 => 'FRE2 060 - 32MEG', 65536 => 'FRE2 060 - 64MEG', }, 1024 => { 8192 => 'ASN MOTHER BOARD - 8MB,ASN TRAY / POWER SUPPLY ASSEMBLY', 16384 => 'ASN MOTHER BOARD - 16MB,ASN TRAY / POWER SUPPLY ASSEMBLY', 32768 => 'ASN MOTHER BOARD - 32MB,ASN TRAY / POWER SUPPLY ASSEMBLY', }, 1025 => { 8192 => 'ASN2 MOTHER BOARD - 8MB,ASN TRAY / POWER SUPPLY ASSEMBLY', 16384 => 'ASN2 MOTHER BOARD - 16MB,ASN TRAY / POWER SUPPLY ASSEMBLY', 32768 => 'ASN2 MOTHER BOARD - 32MB,ASN TRAY / POWER SUPPLY ASSEMBLY', }, 1280 => { 9216 => 'ARE - 8MB DRAM & 1MB VBM', 19456 => 'ARE - 16MB DRAM & 3MB VBM', 38912 => 'ARE -32MB DRAM & 6MB VBM', 71680 => 'ARE -64MB DRAM & 6MB VBM', }, 8704 => 'SRM-F', 1536 => 'ARE5000', 1792 => 'ASN500', 6656 => { 49152 => 'FRE4-PPC - 32MEG', 81920 => 'FRE4-PPC - 64MEG', 147456 => 'FRE4-PPC - 128MEG', }, ); sub model { my $bayrs = shift; my $bp_id = $bayrs->bp_id(); return defined $MODEL_MAP{$bp_id} ? $MODEL_MAP{$bp_id} : $bp_id; } sub vendor { return 'avaya'; } sub os { return 'bayrs'; } sub os_ver { my $bayrs = shift; my $descr = $bayrs->description(); return unless defined $descr; if ( $descr =~ m/^\s*Image:\s+re[lv]\/((\d+\.){1,3}\d+)/ ) { return $1; } return; } sub serial { my $bayrs = shift; my $serialnum = $bayrs->bp_serial(); $serialnum = hex( join( '', '0x', map { sprintf "%02X", $_ } unpack( "C*", $serialnum ) ) ); return $serialnum if defined $serialnum; return; } sub interfaces { my $bayrs = shift; my $description = $bayrs->i_description(); my $vlan_ids = $bayrs->wf_global_vlan_id(); my $vlan_idx = $bayrs->wf_local_vlan_id(); my %interfaces = (); foreach my $iid ( keys %$description ) { my $desc = $description->{$iid}; next unless defined $desc; $desc = $1 if $desc =~ /(^[A-Z]\d+)/; $interfaces{$iid} = $desc; } foreach my $iid ( keys %$vlan_ids ) { my $vlan = $vlan_ids->{$iid}; next unless defined $vlan; my $vlan_if = $vlan_idx->{$iid}; next unless defined $vlan_if; my $desc = 'Vlan' . $vlan; $interfaces{$vlan_if} = $desc; } return \%interfaces; } sub i_name { my $bayrs = shift; my $i_index = $bayrs->i_index(); my $description = $bayrs->i_description(); my $v_name = $bayrs->wf_vlan_name(); my $vlan_idx = $bayrs->wf_local_vlan_id(); my %i_name; foreach my $iid ( keys %$description ) { my $name = $description->{$iid}; next unless defined $name; $i_name{$iid} = $name; } # Get VLAN Virtual Router Interfaces foreach my $vid ( keys %$v_name ) { my $v_name = $v_name->{$vid}; next unless defined $v_name; my $vlan_if = $vlan_idx->{$vid}; next unless defined $vlan_if; $i_name{$vlan_if} = $v_name; } return \%i_name; } sub i_duplex { my $bayrs = shift; my $wf_cct = $bayrs->wf_csmacd_cct(); my $wf_duplex = $bayrs->wf_duplex(); my %i_duplex; foreach my $if ( keys %$wf_cct ) { my $idx = $wf_cct->{$if}; next unless defined $idx; my $duplex = $wf_duplex->{$if}; next unless defined $duplex; my $string = 'half'; $string = 'full' if $duplex =~ /duplex/i; $i_duplex{$idx} = $string; } return \%i_duplex; } sub i_duplex_admin { my $bayrs = shift; my $wf_cct = $bayrs->wf_csmacd_cct(); my $wf_duplex = $bayrs->wf_duplex(); my $wf_auto = $bayrs->wf_auto(); my $wf_slot = $bayrs->wf_csmacd_slot(); my $wf_conn = $bayrs->wf_csmacd_conn(); my %i_duplex_admin; foreach my $if ( keys %$wf_cct ) { my $idx = $wf_cct->{$if}; next unless defined $idx; my $duplex = $wf_duplex->{$if}; next unless defined $duplex; my $slot = $wf_slot->{$if}; my $conn = $wf_conn->{$if}; my $auto_idx = "$slot.$conn"; my $auto = $wf_auto->{$auto_idx}; my $string = 'other'; if ($auto) { $string = 'half'; $string = 'full' if $auto =~ /duplex/i; $string = 'auto' if $auto =~ /nway/i; } elsif ($duplex) { $string = 'half'; $string = 'full' if $duplex =~ /duplex/i; } $i_duplex_admin{$idx} = $string; } return \%i_duplex_admin; } sub i_vlan { my $bayrs = shift; my $wf_cct = $bayrs->wf_csmacd_cct(); my $wf_mtu = $bayrs->wf_csmacd_mtu(); my $wf_line = $bayrs->wf_csmacd_line(); my $wf_local_vid = $bayrs->wf_local_vlan_id(); my $wf_global_vid = $bayrs->wf_global_vlan_id(); my $wf_vport = $bayrs->wf_vlan_port(); my %i_vlan; # Look for VLANs on Ethernet Interfaces foreach my $if ( keys %$wf_cct ) { my $idx = $wf_cct->{$if}; next unless defined $idx; # Check MTU size, if unable to carry VLAN tag skip. my $mtu = $wf_mtu->{$if}; next if ( ( $mtu =~ /default/i ) or ( $mtu < 1522 ) ); my $line = $wf_line->{$if}; my @vlans = (); foreach my $v_idx ( keys %$wf_vport ) { my $port = $wf_vport->{$v_idx}; next unless defined $port; next if ( $port != $line ); my $vlan = $wf_global_vid->{$v_idx}; push( @vlans, $vlan ); } my $vlans = join( ',', @vlans ); $i_vlan{$idx} = $vlans; } # Add VLAN on VLAN Interfaces foreach my $idx ( keys %$wf_global_vid ) { my $v_if = $wf_local_vid->{$idx}; next unless defined $v_if; my $vlan = $wf_global_vid->{$idx}; next unless defined $vlan; $i_vlan{$v_if} = $vlan; } return \%i_vlan; } sub i_pvid { goto &i_vlan } sub root_ip { my $bayrs = shift; my $ip_index = $bayrs->ip_index(); my $ip_table = $bayrs->ip_table(); # Check for CLIP foreach my $entry ( keys %$ip_index ) { my $idx = $ip_index->{$entry}; next unless $idx == 0; my $clip = $ip_table->{$entry}; next unless ( ( defined $clip ) and ( $clip ne '0.0.0.0' ) and ( $bayrs->snmp_connect_ip($clip) ) ); print " SNMP::Layer3::BayRS::root_ip() using $clip\n" if $bayrs->debug(); return $clip; } # Check for OSPF Router ID my $ospf_ip = $bayrs->ospf_rtr_id(); if ( ( defined $ospf_ip ) and ( $ospf_ip ne '0.0.0.0' ) and ( $bayrs->snmp_connect_ip($ospf_ip) ) ) { print " SNMP::Layer3::BayRS::root_ip() using $ospf_ip\n" if $bayrs->debug(); return $ospf_ip; } return; } # Pseudo ENTITY-MIB methods sub e_index { my $bayrs = shift; my $bp_id = $bayrs->bp_id(); # Don't like polling all these columns to build the index, can't think of # a better way right now. Luckly all this data will be cached for the # rest of the e_* methods # Using mib leafs so we don't have to define everything in FUNCS # Processor - All models should support these my $wf_mb = $bayrs->wfHwMotherBdIdOpt() || {}; my $wf_db = $bayrs->wfHwDaughterBdIdOpt() || {}; my $wf_bb = $bayrs->wfHwBabyBdIdOpt() || {}; my ( $wf_mod, $wf_mod1, $wf_mod2, $wf_mm, $wf_dm ) = {}; # Only query objects we need # Link Module if ( $bp_id !~ /arn|asn/ ) { $wf_mod = $bayrs->wfHwModIdOpt() || {}; $wf_mod1 = $bayrs->wfHwModDaughterBd1IdOpt() || {}; $wf_mod2 = $bayrs->wfHwModDaughterBd2IdOpt() || {}; } # Hardware Module if ( $bp_id =~ /arn|asn/ ) { $wf_mm = $bayrs->wfHwModuleModIdOpt() || {}; $wf_dm = $bayrs->wfHwModuleDaughterBdIdOpt() || {}; } my @slots = ( $wf_mb, $wf_db, $wf_bb, $wf_mod, $wf_mod1, $wf_mod2 ); my @mods = ( $wf_mm, $wf_dm ); # We're going to hack an index: Slot/Module/Postion my %wf_e_index; # Chassis on BN types if ( $bp_id !~ /an|arn|asn/ ) { $wf_e_index{1} = 1; } # Handle Processor / Link Modules first foreach my $idx ( keys %$wf_mb ) { my $index = "$idx" . "0000"; unless ( $bp_id =~ /an|arn|asn/ ) { $wf_e_index{$index} = $index; } foreach my $slot (@slots) { $index++; $wf_e_index{$index} = $index if $slot->{$idx}; } } # Handle Hardware Modules foreach my $iid ( keys %$wf_mm ) { my $main_mod = $wf_mm->{$iid}; next unless $main_mod; my $index = join( '', map { sprintf "%02d", $_ } split /\./, $iid ); $index = "$index" . "00"; $wf_e_index{$index} = $index; foreach my $mod (@mods) { $index++; $wf_e_index{$index} = $index if $mod->{$iid}; } } return \%wf_e_index; } sub e_class { my $bayrs = shift; my $bp_id = $bayrs->bp_id(); my $wf_e_idx = $bayrs->e_index() || {}; my %wf_e_class; foreach my $iid ( keys %$wf_e_idx ) { if ( $iid == 1 ) { $wf_e_class{$iid} = 'chassis'; } elsif ( $bp_id =~ /an|arn|asn/ and $iid == '10001' ) { $wf_e_class{$iid} = 'chassis'; } elsif ( $iid =~ /(00){1,2}$/ ) { $wf_e_class{$iid} = 'container'; } else { $wf_e_class{$iid} = 'module'; } } return \%wf_e_class; } sub e_name { my $bayrs = shift; my $bp_id = $bayrs->bp_id(); my $wf_e_idx = $bayrs->e_index() || {}; my %wf_e_name; # Chassis foreach my $iid ( keys %$wf_e_idx ) { if ( $iid == 1 ) { $wf_e_name{$iid} = 'Router'; next; } my $pos = substr( $iid, -1 ); my $sub = substr( $iid, -4, 2 ); $sub =~ s/^0//; my $slot = substr( $iid, -6, 2 ); $slot =~ s/^0//; if ( $bp_id =~ /an|arn|asn/ and $iid == '10001' ) { $wf_e_name{$iid} = 'Router'; } elsif ( $iid =~ /(00){2}$/ ) { $wf_e_name{$iid} = "Slot $slot"; } elsif ( $iid =~ /(00){1}$/ and $bp_id =~ /asn/ ) { $wf_e_name{$iid} = "Module Container $slot $sub"; } elsif ( $iid =~ /(00){1}$/ and $bp_id =~ /an|arn/ ) { $sub--; if ( $sub == 0 ) { $wf_e_name{$iid} = "Motherboard Container"; } else { $wf_e_name{$iid} = "Module Container $sub"; } } elsif ( $bp_id !~ /an|arn|asn/ and $iid =~ /1$/ ) { $wf_e_name{$iid} = "Processor Slot $slot"; } elsif ( $bp_id =~ /asn/ and $iid =~ /1$/ ) { $wf_e_name{$iid} = "Module $slot $sub"; } elsif ( $bp_id =~ /an|arn/ and $iid =~ /1$/ ) { $sub--; if ( $sub == 0 ) { $wf_e_name{$iid} = "Motherboard"; } else { $wf_e_name{$iid} = "Module $sub"; } } elsif ( $bp_id !~ /asn/ and $iid =~ /2$/ ) { $wf_e_name{$iid} = "Processor Daughter Board Slot $slot"; } elsif ( $bp_id !~ /an|arn/ and $iid =~ /2$/ ) { $wf_e_name{$iid} = "Processor Daughter Board"; } elsif ( $bp_id =~ /asn/ and $iid =~ /2$/ ) { $wf_e_name{$iid} = "Module Daughter Board $slot $sub"; } elsif ( $bp_id =~ /an|arn/ and $iid =~ /2$/ ) { $sub--; $wf_e_name{$iid} = "Module Daughter Board $sub"; } elsif ( $iid =~ /3$/ ) { $wf_e_name{$iid} = "Processor Baby Board Slot $slot"; } elsif ( $iid =~ /4$/ ) { $wf_e_name{$iid} = "Link Module Slot $slot"; } elsif ( $iid =~ /5$/ ) { $wf_e_name{$iid} = "Link Module Daughter Board 1 Slot $slot"; } elsif ( $iid =~ /6$/ ) { $wf_e_name{$iid} = "Link Module Daughter Board 2 Slot $slot"; } else { next; } } return \%wf_e_name; } sub e_descr { my $bayrs = shift; my $bp_id = $bayrs->bp_id(); # Using mib leafs so we don't have to define everything in FUNCS # We only have descriptions for the processors and modules # Processor my $wf_mb = $bayrs->wfHwMotherBdIdOpt() || {}; my $wf_mb_mem = $bayrs->wfHwMotherBdMemorySize() || {}; my ( $wf_mod, $wf_mm ) = {}; # Link Module if ( $bp_id !~ /arn|asn/ ) { $wf_mod = $bayrs->wfHwModIdOpt() || {}; } # Hardware Module if ( $bp_id =~ /arn|asn/ ) { $wf_mm = $bayrs->wfHwModuleModIdOpt() || {}; } my %wf_e_descr; # Chassis if ( $bp_id !~ /an|arn|asn/ ) { $wf_e_descr{1} = $bayrs->model(); } # Handle Processor / Link Modules first foreach my $idx ( keys %$wf_mb ) { unless ( $bp_id =~ /an|arn|asn/ ) { $wf_e_descr{ "$idx" . "0000" } = 'Slot ' . $idx; } my $mb_id; $mb_id = &SNMP::mapEnum( 'wfHwMotherBdIdOpt', $wf_mb->{$idx} ) if $wf_mb->{$idx}; my $mb_mem = $wf_mb_mem->{$idx}; my $mod_id; $mod_id = &SNMP::mapEnum( 'wfHwModIdOpt', $wf_mod->{$idx} ) if $wf_mod->{$idx}; # Processor if ($mb_id) { if ( ref( $PROCID_MAP{$mb_id} ) =~ /HASH/ ) { $wf_e_descr{ "$idx" . "0001" } = defined $PROCID_MAP{$mb_id}{$mb_mem} ? $PROCID_MAP{$mb_id}{$mb_mem} : $mb_id; } else { $wf_e_descr{ "$idx" . "0001" } = defined $PROCID_MAP{$mb_id} ? $PROCID_MAP{$mb_id} : $mb_id; } } # Link Module if ($mod_id) { if ( ref( $MODID_MAP{$mod_id} ) =~ /HASH/ ) { $wf_e_descr{ "$idx" . "0004" } = defined $MODID_MAP{$mod_id}{$mb_mem} ? $MODID_MAP{$mod_id}{$mb_mem} : $mod_id; } else { $wf_e_descr{ "$idx" . "0004" } = defined $MODID_MAP{$mod_id} ? $MODID_MAP{$mod_id} : $mod_id; } } } # Handle Hardware Modules foreach my $iid ( keys %$wf_mm ) { next unless ( $wf_mm->{$iid} ); my $idx = join( '', map { sprintf "%02d", $_ } split /\./, $iid ); my ( $slot, $mod ) = split /\./, $iid; if ( $bp_id =~ /an|arn/ ) { $mod--; if ( $mod == 0 ) { $wf_e_descr{ "$idx" . "00" } = "Motherboard Container"; } else { $wf_e_descr{ "$idx" . "00" } = "Module Container $mod"; } } else { $wf_e_descr{ "$idx" . "00" } = "Module Container $slot $mod"; } my $mm_id = &SNMP::mapEnum( 'wfHwModuleModIdOpt', $wf_mm->{$iid} ); my $index = join( '', map { sprintf "%02d", $_ } split /\./, $iid ); $wf_e_descr{ "$index" . "01" } = defined $MODID_MAP{$mm_id} ? $MODID_MAP{$mm_id} : $mm_id; } return \%wf_e_descr; } sub e_type { my $bayrs = shift; my $bp_id = $bayrs->bp_id(); # Using mib leafs so we don't have to define everything in FUNCS # Processor my $wf_mb = $bayrs->wfHwMotherBdIdOpt() || {}; my $wf_db = $bayrs->wfHwDaughterBdIdOpt() || {}; my $wf_bb = $bayrs->wfHwBabyBdIdOpt() || {}; my ( $wf_mod, $wf_mod1, $wf_mod2, $wf_mm, $wf_dm ) = {}; # Link Module if ( $bp_id !~ /arn|asn/ ) { $wf_mod = $bayrs->wfHwModIdOpt() || {}; $wf_mod1 = $bayrs->wfHwModDaughterBd1IdOpt() || {}; $wf_mod2 = $bayrs->wfHwModDaughterBd2IdOpt() || {}; } # Hardware Module if ( $bp_id =~ /arn|asn/ ) { $wf_mm = $bayrs->wfHwModuleModIdOpt() || {}; $wf_dm = $bayrs->wfHwModuleDaughterBdIdOpt() || {}; } my @slots = ( $wf_mb, $wf_db, $wf_bb, $wf_mod, $wf_mod1, $wf_mod2 ); my @mods = ( $wf_mm, $wf_dm ); my %wf_e_type; # Chassis if ( $bp_id !~ /an|arn|asn/ ) { $wf_e_type{1} = $bayrs->bp_id(); } # Handle Processor / Link Modules first foreach my $idx ( keys %$wf_mb ) { my $index = "$idx" . "0000"; unless ( $bp_id =~ /an|arn|asn/ ) { $wf_e_type{$index} = "zeroDotZero"; } foreach my $slot (@slots) { $index++; $wf_e_type{$index} = $slot->{$idx} if $slot->{$idx}; } } # Handle Hardware Modules foreach my $iid ( keys %$wf_mm ) { my $main_mod = $wf_mm->{$iid}; next unless $main_mod; my $index = join( '', map { sprintf "%02d", $_ } split /\./, $iid ); $index = "$index" . "00"; $wf_e_type{$index} = "zeroDotZero"; foreach my $mod (@mods) { $index++; $wf_e_type{$index} = $mod->{$iid} if $mod->{$iid}; } } return \%wf_e_type; } sub e_hwver { my $bayrs = shift; my $bp_id = $bayrs->bp_id(); # Using mib leafs so we don't have to define everything in FUNCS # Processor my $wf_mb = $bayrs->wfHwMotherBdRev() || {}; my $wf_db = $bayrs->wfHwDaughterBdRev() || {}; my $wf_bb = $bayrs->wfHwBabyBdRev() || {}; my ( $wf_mod, $wf_mod1, $wf_mod2, $wf_mm ) = {}; # Link Module if ( $bp_id !~ /arn|asn/ ) { $wf_mod = $bayrs->wfHwModRev() || {}; $wf_mod1 = $bayrs->wfHwModDaughterBd1Rev() || {}; $wf_mod2 = $bayrs->wfHwModDaughterBd2Rev() || {}; } # Hardware Module if ( $bp_id =~ /arn|asn/ ) { $wf_mm = $bayrs->wfHwModuleModRev() || {}; } my @slots = ( $wf_mb, $wf_db, $wf_bb, $wf_mod, $wf_mod1, $wf_mod2 ); my %wf_e_hwver; # Chassis if ( $bp_id !~ /an|arn|asn/ ) { my $bp_rev = $bayrs->wfHwBpRev(); $bp_rev = hex( join( '', '0x', map { sprintf "%02X", $_ } unpack( "C*", $bp_rev ) ) ); $wf_e_hwver{1} = $bp_rev; } # Handle Processor / Link Modules first foreach my $idx ( keys %$wf_mb ) { my $index = "$idx" . "0000"; foreach my $slot (@slots) { $index++; next unless ( $slot->{$idx} ); my $mod; $mod = hex( join( '', '0x', map { sprintf "%02X", $_ } unpack( "C*", $slot->{$idx} ) ) ) if $slot->{$idx}; $wf_e_hwver{$index} = $mod if $mod; } } foreach my $iid ( keys %$wf_mm ) { my $index = join( '', map { sprintf "%02d", $_ } split /\./, $iid ); my $mod; $mod = hex( join( '', '0x', map { sprintf "%02X", $_ } unpack( "C*", $wf_mm->{$iid} ) ) ) if $wf_mm->{$iid}; $index = "$index" . "00"; $index++; next unless ( $wf_mm->{$iid} ); $wf_e_hwver{$index} = $mod if $mod; } return \%wf_e_hwver; } sub e_vendor { my $bayrs = shift; my $wf_e_idx = $bayrs->e_index() || {}; my %wf_e_vendor; foreach my $iid ( keys %$wf_e_idx ) { $wf_e_vendor{$iid} = 'avaya'; } return \%wf_e_vendor; } sub e_serial { my $bayrs = shift; my $bp_id = $bayrs->bp_id(); # Processor my $wf_mb = $bayrs->wf_hw_mobo_ser() || {}; my $wf_db = $bayrs->wf_hw_db_ser() || {}; my $wf_bb = $bayrs->wf_hw_bb_ser() || {}; my ( $wf_mod, $wf_mod1, $wf_mod2, $wf_mm ) = {}; # Link Module if ( $bp_id !~ /arn|asn/ ) { $wf_mod = $bayrs->wf_hw_mod_ser() || {}; $wf_mod1 = $bayrs->wf_hw_md1_ser() || {}; $wf_mod2 = $bayrs->wf_hw_md2_ser() || {}; } # Hardware Module if ( $bp_id =~ /arn|asn/ ) { $wf_mm = $bayrs->wf_hw_mm_ser() || {}; } my @slots = ( $wf_mb, $wf_db, $wf_bb, $wf_mod, $wf_mod1, $wf_mod2 ); my %wf_e_serial; # Chassis if ( $bp_id !~ /an|arn|asn/ ) { $wf_e_serial{1} = $bayrs->serial(); } # Handle Processor / Link Modules first foreach my $idx ( keys %$wf_mb ) { my $index = "$idx" . "0000"; foreach my $slot (@slots) { $index++; my $mod = $slot->{$idx}; next unless ($mod); $wf_e_serial{$index} = $mod if $mod; } } # Handle Hardware Modules foreach my $iid ( keys %$wf_mm ) { my $index = join( '', map { sprintf "%02d", $_ } split /\./, $iid ); my $mod = $wf_mm->{$iid}; $index = "$index" . "00"; $index++; next unless ($mod); $wf_e_serial{$index} = $mod if $mod; } return \%wf_e_serial; } sub e_pos { my $bayrs = shift; my $wf_e_idx = $bayrs->e_index() || {}; my $bp_id = $bayrs->bp_id(); my %wf_e_pos; foreach my $iid ( keys %$wf_e_idx ) { if ( $iid == 1 ) { $wf_e_pos{$iid} = -1; next; } my $pos = substr( $iid, -1 ); my $sub = substr( $iid, -4, 2 ); my $slot = substr( $iid, -6, 2 ); if ( $bp_id =~ /an|arn|asn/ and $iid == '10001' ) { $wf_e_pos{$iid} = -1; } elsif ( $iid =~ /(00){2}$/ ) { $wf_e_pos{$iid} = $slot; } elsif ( $iid =~ /(00){1}$/ ) { $wf_e_pos{$iid} = $sub; } else { $wf_e_pos{$iid} = $pos; } } return \%wf_e_pos; } sub e_fwver { my $bayrs = shift; # Only on Processor my $wf_mb = $bayrs->wf_hw_boot() || {}; my %wf_e_hwver; foreach my $idx ( keys %$wf_mb ) { my $fw = $wf_mb->{$idx}; next unless $fw; $wf_e_hwver{ "$idx" . "0001" } = $fw; } return \%wf_e_hwver; } sub e_swver { my $bayrs = shift; # Only on Processor my $wf_mb = $bayrs->wfHwActiveImageSource() || {}; my %wf_e_swver; foreach my $idx ( keys %$wf_mb ) { my $sw = $wf_mb->{$idx}; next unless $sw; $wf_e_swver{ "$idx" . "0001" } = $sw; } return \%wf_e_swver; } sub e_parent { my $bayrs = shift; my $wf_e_idx = $bayrs->e_index() || {}; my $bp_id = $bayrs->bp_id(); my %wf_e_parent; foreach my $iid ( keys %$wf_e_idx ) { if ( $iid == 1 ) { $wf_e_parent{$iid} = 0; next; } my $mod = substr( $iid, -4, 2 ); my $slot = substr( $iid, -6, 2 ); if ( $bp_id =~ /an|arn|asn/ and $iid == '10001' ) { $wf_e_parent{$iid} = 0; } elsif ( $iid =~ /(00){1,2}$/ ) { my $parent = 1; $parent = '10001' if ( $bp_id =~ /an|arn|asn/ ); $wf_e_parent{$iid} = $parent; } elsif ( $mod != 0 ) { $wf_e_parent{$iid} = "$slot" . "$mod" . "00"; } else { $wf_e_parent{$iid} = "$slot" . "0000"; } } return \%wf_e_parent; } sub munge_hw_rev { my $hw_boot = shift; my @bytes = map { sprintf "%02X", $_ } unpack( "C*", $hw_boot ); my $major = hex( "$bytes[0]" . "$bytes[1]" ); my $minor = hex( "$bytes[2]" . "$bytes[3]" ); my $rev = "$major.$minor"; return $rev if defined($rev); return; } sub munge_wf_serial { my $wf_serial = shift; my $serial = hex( join( '', '0x', map { sprintf "%02X", $_ } unpack( "C*", $wf_serial ) ) ); return $serial if defined($serial); return; } 1; __END__ =head1 NAME SNMP::Info::Layer3::BayRS - SNMP Interface to Avaya/Nortel routers running BayRS. =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $bayrs = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $bayrs->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for routers running Avaya/Nortel BayRS. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $bayrs = new SNMP::Info::Layer3::BayRS(...); =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Bridge =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =back =head2 Inherited MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $bayrs->model() Returns the model of the BayRS router. Will translate between the MIB model and the common model with this map : C<%MODEL_MAP = ( 'acefn' => 'FN', 'aceln' => 'LN', 'acecn' => 'CN', 'afn' => 'AFN', 'in' => 'IN', 'an' => 'AN', 'arn' => 'ARN', 'sys5000' => '5000', 'freln' => 'BLN', 'frecn' => 'BCN', 'frerbln' => 'BLN-2', 'asn' => 'ASN', 'asnzcable' => 'ASN-Z', 'asnbcable' => 'ASN-B', );> =item $bayrs->vendor() Returns 'avaya' =item $bayrs->os() Returns 'bayrs' =item $bayrs->os_ver() Returns the software version extracted from C =item $bayrs->serial() Returns (C) after conversion to ASCII decimal =item $bayrs->root_ip() Returns the primary IP used to communicate with the router. Returns the first found: CLIP (CircuitLess IP), (C), or undefined. =back =head2 Globals imported from SNMP::Info See documentation in L for details. =head2 Globals imported from SNMP::Info::Bridge See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. Note: These methods do not support partial table fetches, a partial can be passed but the entire table will be returned. =head2 Overrides =over =item $bayrs->interfaces() Returns reference to the map between IID and physical Port. The physical port name is stripped to letter and numbers to signify port type and slot port (S11) if the default platform naming was maintained. Otherwise the port is the interface description. =item $bayrs->i_name() Returns (C) along with VLAN name (C) for VLAN interfaces. =item $bayrs->i_duplex() Returns reference to hash. Maps port operational duplexes to IIDs for Ethernet interfaces. =item $bayrs->i_duplex_admin() Returns reference to hash. Maps port admin duplexes to IIDs for Ethernet interfaces. =item $bayrs->i_vlan() Returns reference to hash. Maps port VLAN ID to IIDs. =item $bayrs->i_pvid() Returns reference to hash. Maps port VLAN ID to IIDs. =back =head2 Pseudo F information These methods emulate F Physical Table methods using F and F. =over =item $bayrs->e_index() Returns reference to hash. Key and Value: Integer. The index is created by combining the slot, module, and position into a five or six digit integer. Slot can be either one or two digits while the module and position are each two digits padded with leading zero if required. =item $bayrs->e_class() Returns reference to hash. Key: IID, Value: General hardware type. This class only returns container and module types. =item $bayrs->e_descr() Returns reference to hash. Key: IID, Value: Human friendly name. =item $bayrs->e_name() Returns reference to hash. Key: IID, Value: Human friendly name. =item $bayrs->e_hwver() Returns reference to hash. Key: IID, Value: Hardware version. =item $bayrs->e_vendor() Returns reference to hash. Key: IID, Value: avaya. =item $bayrs->e_serial() Returns reference to hash. Key: IID, Value: Serial number. =item $bayrs->e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. =item $bayrs->e_type() Returns reference to hash. Key: IID, Value: Type of component/sub-component as defined in F for processors and link modules or F for hardware modules. =item $bayrs->e_fwver() Returns reference to hash. Key: IID, Value: Firmware revision. Only available on processors. =item $bayrs->e_swver() Returns reference to hash. Key: IID, Value: Software revision. Only available on processors. =item $bayrs->e_parent() Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. A value of zero indicates this entity is not contained in any other entity. =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Bridge See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head1 Data Munging Callback Subroutines =over =item $bayrs->munge_hw_rev() Converts octets to a decimal major.minor string. =item $bayrs->munge_wf_serial() Coverts octets to a decimal string. =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/BlueCoatSG.pm000444000765000024 1027213215550564 20732 0ustar00oliverstaff000000000000package SNMP::Info::Layer3::BlueCoatSG; # Copyright (c) 2011 Netdisco Project # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::BlueCoatSG::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::BlueCoatSG::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::Layer3::MIBS, 'BLUECOAT-SG-PROXY-MIB' => 'sgProxyAdmin', ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::Layer3::GLOBALS, #From BLUECOAT-SG-PROXY-MIB 'serial1'=> 'sgProxySerialNumber', 'sw_ver' => 'sgProxyVersion', ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'Blue Coat'; } sub os { return 'sgos'; } sub os_ver { my $sg = shift; my $os_string = $sg->sw_ver(); if ($os_string =~ /^Version:\s(\w+)\s([\d\.]+)/) { return $2; } else { return ''; # perhaps we can try sysDescr or some other object... } } 1; __END__ =head1 NAME SNMP::Info::Layer3::BlueCoatSG - SNMP Interface to Blue Coat SG Series proxy devices =head1 AUTHOR Jeroen van Ingen =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $router = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $router->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Blue Coat SG Series proxy devices =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs BLUECOAT-SG-PROXY-MIB =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $router->vendor() Returns C<'Blue Coat'> =item $router->os() Returns C<'sgos'> =item $router->os_ver() Tries to resolve version string from C<"sgProxyVersion">. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/C3550.pm000444000765000024 2262013215550564 17501 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::C3550 # $Id$ # # Copyright (c) 2008-2009 Max Baker changes from version 0.8 and beyond. # Copyright (c) 2004 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::C3550; use strict; use warnings; use Exporter; use SNMP::Info::CiscoStack; use SNMP::Info::Layer3::CiscoSwitch; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; # NOTE : Top-most items gets precedence for @ISA @SNMP::Info::Layer3::C3550::ISA = qw/ SNMP::Info::CiscoStack SNMP::Info::Layer3::CiscoSwitch Exporter/; @SNMP::Info::Layer3::C3550::EXPORT_OK = qw//; $VERSION = '3.39'; # NOTE: Order creates precedence # Example: v_name exists in Bridge.pm and CiscoVTP.pm # Bridge is called from Layer3 and CiscoStpExtensions # So we want CiscoVTP to come last to get the right one. # The @ISA order should match these orders. %MIBS = ( %SNMP::Info::Layer3::CiscoSwitch::MIBS, %SNMP::Info::CiscoStack::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer3::CiscoSwitch::GLOBALS, %SNMP::Info::CiscoStack::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::CiscoSwitch::FUNCS, %SNMP::Info::CiscoStack::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::CiscoSwitch::MUNGE, %SNMP::Info::CiscoStack::MUNGE, ); sub vendor { return 'cisco'; } sub model { my $c3550 = shift; my $id = $c3550->id(); my $model = &SNMP::translateObj($id) || $id; $model =~ s/^catalyst//; # turn 355048 into 3550-48 if ( $model =~ /^(35\d\d)(\d\d(T|G)?)$/ ) { $model = "$1-$2"; } return $model; } # Ports is encoded into the model number sub ports { my $c3550 = shift; my $id = $c3550->id(); my $model = &SNMP::translateObj($id); if ( $model =~ /(12|24|48)(C|T|TS|G|TS-E|TS-S|T-E)?$/ ) { return $1; } my $ports = $c3550->orig_ports(); return $ports; } # Verions prior to 12.1(22)EA1a use the older CiscoStack method # Newer versions use the ETHERLIKE-MIB to report operational duplex. # See http://www.ciscosystems.com/en/US/products/hw/switches/ps646/prod_release_note09186a00802a08ee.html sub i_duplex { my $c3550 = shift; my $partial = shift; my $el_duplex = $c3550->el_duplex($partial); # Newer software if ( defined $el_duplex and scalar( keys %$el_duplex ) ) { my %i_duplex; foreach my $el_port ( keys %$el_duplex ) { my $duplex = $el_duplex->{$el_port}; next unless defined $duplex; $i_duplex{$el_port} = 'half' if $duplex =~ /half/i; $i_duplex{$el_port} = 'full' if $duplex =~ /full/i; } return \%i_duplex; } # Fall back to CiscoStack method else { return $c3550->SUPER::i_duplex($partial); } } # Software >= 12.1(22)EA1a uses portDuplex as admin setting sub i_duplex_admin { my $c3550 = shift; my $partial = shift; my $el_duplex = $c3550->el_duplex($partial); # Newer software if ( defined $el_duplex and scalar( keys %$el_duplex ) ) { my $p_port = $c3550->p_port() || {}; my $p_duplex = $c3550->p_duplex() || {}; my $i_duplex_admin = {}; foreach my $port ( keys %$p_duplex ) { my $iid = $p_port->{$port}; next unless defined $iid; next if ( defined $partial and $iid !~ /^$partial$/ ); $i_duplex_admin->{$iid} = $p_duplex->{$port}; } return $i_duplex_admin; } # Fall back to CiscoStack method else { return $c3550->SUPER::i_duplex_admin($partial); } } sub set_i_duplex_admin { # map a textual duplex to an integer one the switch understands my %duplexes = qw/half 1 full 2 auto 4/; my $c3550 = shift; my ( $duplex, $iid ) = @_; my $el_duplex = $c3550->el_duplex($iid); # Auto duplex only supported on newer software if ( defined $el_duplex and scalar( keys %$el_duplex ) ) { my $p_port = $c3550->p_port() || {}; my %reverse_p_port = reverse %$p_port; $duplex = lc($duplex); return 0 unless defined $duplexes{$duplex}; $iid = $reverse_p_port{$iid}; return $c3550->set_p_duplex( $duplexes{$duplex}, $iid ); } else { return $c3550->SUPER::set_i_duplex_admin; } } 1; __END__ =head1 NAME SNMP::Info::Layer3::C3550 - SNMP Interface to Cisco Catalyst 3550 Layer 2/3 Switches running IOS =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $c3550 = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $c3550->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Cisco Catalyst 3550 Layer 2/3 Switches. These devices run IOS but have some of the same characteristics as the Catalyst WS-C family (5xxx,6xxx). For example, forwarding tables are held in VLANs, and extended interface information is gleaned from F. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $c3550 = new SNMP::Info::Layer3::C3550(...); =head2 Inherited Classes =over =item SNMP::Info::CiscoStack =item SNMP::Info::Layer3::CiscoSwitch =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $c3550->vendor() Returns 'cisco' =item $c3550->model() Will take the translated model number and try to format it better. 355048 -> 3550-48 355012G -> 3550-12G =item $c3550->ports() Tries to cull the number of ports from the model number. =back =head2 Globals imported from SNMP::Info::CiscoStack See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3::CiscoSwitch See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $c3550->i_duplex() Returns reference to hash of iid to current link duplex setting. Software version 12.1(22)EA1a or greater returns duplex based upon the result of $c3550->el_duplex(). Otherwise it uses the result of the call to CiscoStack::i_duplex(). See L for el_duplex() method and L for its i_duplex() method. =item $c3550->i_duplex_admin() Returns reference to hash of iid to administrative duplex setting. Software version 12.1(22)EA1a or greater returns duplex based upon the result of $c3550->p_duplex(). Otherwise it uses the result of the call to CiscoStack::i_duplex(). See L for its i_duplex() and p_duplex() methods. =item $c3550->set_i_duplex_admin(duplex, ifIndex) Sets port duplex, must be supplied with duplex and port C. Speed choices are 'auto', 'half', 'full'. Crosses $c3550->p_port() with $c3550->p_duplex() to utilize port C. Example: my %if_map = reverse %{$c3550->interfaces()}; $c3550->set_i_duplex_admin('auto', $if_map{'FastEthernet0/1'}) or die "Couldn't change port duplex. ",$c3550->error(1); =back =head2 Table Methods imported from SNMP::Info::CiscoStack See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3::CiscoSwitch See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/C4000.pm000444000765000024 1435613215550564 17477 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::C4000 # $Id$ # # Copyright (c) 2008 Bill Fenner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::C4000; use strict; use warnings; use Exporter; use SNMP::Info::Layer3::CiscoSwitch; use SNMP::Info::MAU; @SNMP::Info::Layer3::C4000::ISA = qw/ SNMP::Info::Layer3::CiscoSwitch SNMP::Info::MAU Exporter/; @SNMP::Info::Layer3::C4000::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MAU::MIBS, %SNMP::Info::Layer3::CiscoSwitch::MIBS, 'CISCO-ENVMON-MIB' => 'ciscoEnvMonMIB', ); %GLOBALS = ( %SNMP::Info::MAU::GLOBALS, %SNMP::Info::Layer3::CiscoSwitch::GLOBALS, 'ps1_type' => 'ciscoEnvMonSupplyStatusDescr.1', 'ps1_status' => 'ciscoEnvMonSupplyState.1', 'ps2_type' => 'ciscoEnvMonSupplyStatusDescr.2', 'ps2_status' => 'ciscoEnvMonSupplyState.2', ); %FUNCS = ( %SNMP::Info::MAU::FUNCS, %SNMP::Info::Layer3::CiscoSwitch::FUNCS, 'fan_state' => 'ciscoEnvMonFanState', 'fan_descr' => 'ciscoEnvMonFanStatusDescr', ); %MUNGE = ( %SNMP::Info::MAU::MUNGE, %SNMP::Info::Layer3::CiscoSwitch::MUNGE, ); # Override Inheritance for these specific methods # use MAU-MIB for admin. duplex and admin. speed *SNMP::Info::Layer3::C4000::i_duplex_admin = \&SNMP::Info::MAU::mau_i_duplex_admin; *SNMP::Info::Layer3::C4000::i_speed_admin = \&SNMP::Info::MAU::mau_i_speed_admin; *SNMP::Info::Layer3::C4000::set_i_duplex_admin = \&SNMP::Info::MAU::mau_set_i_duplex_admin; *SNMP::Info::Layer3::C4000::set_i_speed_admin = \&SNMP::Info::MAU::mau_set_i_speed_admin; sub fan { my $c4000 = shift; my $fan_state = $c4000->fan_state(); my $fan_descr = $c4000->fan_descr(); my $ret = ""; my $s = ""; foreach my $i ( sort { $a <=> $b } keys %$fan_state ) { $ret .= $s . $fan_descr->{$i} . ": " . $fan_state->{$i}; $s = ", "; } return if ( $s eq "" ); return $ret; } 1; __END__ =head1 NAME SNMP::Info::Layer3::C4000 - SNMP Interface to Cisco Catalyst 4000 Layer 2/3 Switches running IOS =head1 AUTHOR Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $c4000 = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $c4000->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Cisco Catalyst 4000 Layer 2/3 Switches. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $c4000 = new SNMP::Info::Layer3::C4000(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3::CiscoSwitch =item SNMP::Info::MAU =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $c4000->fan() Returns fan status =back =head2 Globals imported from SNMP::Info::Layer3::CiscoSwitch See documentation in L for details. =head2 Globals imported from SNMP::Info::MAU See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $c4000->i_duplex() Parses mau_index and mau_link to return the duplex information for interfaces. =item $c4000->i_duplex_admin() Parses C,C,C in order to find the admin duplex setting for all the interfaces. Returns either (auto,full,half). =item $c4000->i_speed_admin() Returns administrative speed for interfaces. =item $c4000->set_i_speed_admin(speed, ifIndex) Sets port speed, must be supplied with speed and port C. Speed choices are '10', '100', '1000', 'auto'. =item $c4000->set_i_duplex_admin(duplex, ifIndex) Sets port duplex, must be supplied with duplex and port C. Duplex choices are 'auto', 'half', 'full'. =back =head2 Table Methods imported from SNMP::Info::Layer3::CiscoSwitch See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/C6500.pm000444000765000024 2617713215550564 17512 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::C6500 # $Id$ # # Copyright (c) 2008-2009 Max Baker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::C6500; use strict; use warnings; use Exporter; use SNMP::Info::CiscoStack; use SNMP::Info::Layer3::CiscoSwitch; use SNMP::Info::MAU; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; # NOTE : Top-most items gets precedence for @ISA @SNMP::Info::Layer3::C6500::ISA = qw/ SNMP::Info::CiscoStack SNMP::Info::Layer3::CiscoSwitch SNMP::Info::MAU Exporter /; @SNMP::Info::Layer3::C6500::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; # NOTE: Order creates precedence # Example: v_name exists in Bridge.pm and CiscoVTP.pm # Bridge is called from Layer3 and CiscoStpExtensions # So we want CiscoVTP to come last to get the right one. # The @ISA order should match these orders. %MIBS = ( %SNMP::Info::MAU::MIBS, %SNMP::Info::Layer3::CiscoSwitch::MIBS, %SNMP::Info::CiscoStack::MIBS, 'CISCO-VIRTUAL-SWITCH-MIB' => 'cvsSwitchMode', ); %GLOBALS = ( %SNMP::Info::MAU::GLOBALS, %SNMP::Info::Layer3::CiscoSwitch::GLOBALS, %SNMP::Info::CiscoStack::GLOBALS, ); %FUNCS = ( %SNMP::Info::MAU::FUNCS, %SNMP::Info::Layer3::CiscoSwitch::FUNCS, %SNMP::Info::CiscoStack::FUNCS, ); %MUNGE = ( %SNMP::Info::MAU::MUNGE, %SNMP::Info::Layer3::CiscoSwitch::MUNGE, %SNMP::Info::CiscoStack::MUNGE, ); sub vendor { return 'cisco'; } sub serial { my $c6500 = shift; my $serial = $c6500->SUPER::serial(); return $serial if defined $serial and $serial; # now grab the table only if SUPER cannot find it my $e_serial = $c6500->e_serial(); # Find entity table entry for this unit foreach my $e ( sort keys %$e_serial ) { if (defined $e_serial->{$e} and $e_serial->{$e} !~ /^\s*$/) { return $e_serial->{$e}; } } } # Newer versions use the ETHERLIKE-MIB to report operational duplex. sub i_duplex { my $c6500 = shift; my $partial = shift; my $el_duplex = $c6500->el_duplex($partial); # Newer software if ( defined $el_duplex and scalar( keys %$el_duplex ) ) { my %i_duplex; foreach my $el_port ( keys %$el_duplex ) { my $duplex = $el_duplex->{$el_port}; next unless defined $duplex; $i_duplex{$el_port} = 'half' if $duplex =~ /half/i; $i_duplex{$el_port} = 'full' if $duplex =~ /full/i; } return \%i_duplex; } # Fall back to CiscoStack method else { return $c6500->SUPER::i_duplex($partial); } } # Newer software uses portDuplex as admin setting sub i_duplex_admin { my $c6500 = shift; my $partial = shift; my $el_duplex = $c6500->el_duplex($partial); # Newer software if ( defined $el_duplex and scalar( keys %$el_duplex ) ) { my $p_port = $c6500->p_port() || {}; my $p_duplex = $c6500->p_duplex() || {}; my $i_duplex_admin = {}; foreach my $port ( keys %$p_duplex ) { my $iid = $p_port->{$port}; next unless defined $iid; next if ( defined $partial and $iid !~ /^$partial$/ ); $i_duplex_admin->{$iid} = $p_duplex->{$port}; } return $i_duplex_admin; } # Fall back to CiscoStack method else { return $c6500->SUPER::i_duplex_admin($partial); } } sub is_virtual_switch { my $cvs = shift; my $cvsSwM = $cvs->cvsSwitchMode() || ''; if ( $cvsSwM eq 'multiNode' ) { return 1; } return 0; } sub set_i_duplex_admin { # map a textual duplex to an integer one the switch understands my %duplexes = qw/half 1 full 2 auto 4/; my $c6500 = shift; my ( $duplex, $iid ) = @_; if ( $c6500->is_virtual_switch() ) { # VSS -> MAU # Due to VSS bug # 1. Set the ifMauDefaultType # 2. Disable ifMauAutoNegAdminStatus # If the second set is not done, this is not going to be # working... Cisco Bug id CSCty97033. # SXI is not working (up to at least relase SXI9). # SXJ is working at SXJ3 (not before). return $c6500->mau_set_i_duplex_admin( $duplex, $iid ); } my $el_duplex = $c6500->el_duplex($iid); # Auto duplex only supported on newer software if ( defined $el_duplex and scalar( keys %$el_duplex ) ) { my $p_port = $c6500->p_port() || {}; my %reverse_p_port = reverse %$p_port; $duplex = lc($duplex); return 0 unless defined $duplexes{$duplex}; $iid = $reverse_p_port{$iid}; return $c6500->set_p_duplex( $duplexes{$duplex}, $iid ); } else { return $c6500->SUPER::set_i_duplex_admin( $duplex, $iid ); } } sub set_i_speed_admin { my $c6500 = shift; my ( $speed, $iid ) = @_; if ( $c6500->is_virtual_switch() ) { # VSS -> MAU # Due to VSS bug # 1. Set the ifMauDefaultType # 2. Disable ifMauAutoNegAdminStatus # If the second set is not done, this is not going to be working... # Cisco Bug id CSCty97033. # SXI is not working (at least up to relase SXI9). # SXJ is working at SXJ3 (not before). return $c6500->mau_set_i_speed_admin( $speed, $iid ); } else { # normal behavior using the CiscoStack method return $c6500->SUPER::set_i_speed_admin( $speed, $iid ); } } 1; __END__ =head1 NAME SNMP::Info::Layer3::C6500 - SNMP Interface to Cisco Catalyst 6500 Layer 2/3 Switches running IOS and/or CatOS =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $c6500 = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $c6500->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Cisco Catalyst 6500 Layer 2/3 Switches. These devices run IOS but have some of the same characteristics as the Catalyst WS-C family (5xxx). For example, forwarding tables are held in VLANs, and extended interface information is gleaned from F. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $c6500 = new SNMP::Info::Layer3::C6500(...); =head2 Inherited Classes =over =item SNMP::Info::CiscoStack =item SNMP::Info::Layer3::CiscoSwitch =item SNMP::Info::MAU =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $c6500->vendor() Returns 'cisco' =item $c6500->cvsSwitchMode() Returns the Switch status: multiNode or standalone. =item $c6500->is_virtual_switch() Return 1 if the switch (C) is in multimode (VSS). =item $c6500->serial() Returns serial number of unit (falls back to C). =back =head2 Globals imported from SNMP::Info::CiscoStack See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3::CiscoSwitch See documentation in L for details. =head2 Globals imported from SNMP::Info::MAU See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $c6500->i_duplex() Returns reference to hash of iid to current link duplex setting. Newer software versions return duplex based upon the result of $c6500->el_duplex(). Otherwise it uses the result of the call to CiscoStack::i_duplex(). See L for el_duplex() method and L for its i_duplex() method. =item $c6500->i_duplex_admin() Returns reference to hash of iid to administrative duplex setting. Newer software versions return duplex based upon the result of $c6500->p_duplex(). Otherwise it uses the result of the call to CiscoStack::i_duplex(). See L for its i_duplex() and p_duplex() methods. =item $c6500->set_i_duplex_admin(duplex, ifIndex) Sets port duplex, must be supplied with duplex and port C. Speed choices are 'auto', 'half', 'full'. Crosses $c6500->p_port() with $c6500->p_duplex() to utilize port C. Example: my %if_map = reverse %{$c6500->interfaces()}; $c6500->set_i_duplex_admin('auto', $if_map{'FastEthernet0/1'}) or die "Couldn't change port duplex. ",$c6500->error(1); =item $c6500->set_i_speed_admin(speed, ifIndex) Sets port speed, must be supplied with speed and port C. Speed choices are '10', '100', '1000'. Crosses $c6500->p_port() with $c6500->p_speed() to utilize port C. =back =head2 Table Methods imported from SNMP::Info::CiscoStack See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3::CiscoSwitch See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Cisco.pm000444000765000024 2351413215550564 20045 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Cisco # $Id$ # # Copyright (c) 2008 Max Baker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Cisco; use strict; use warnings; use Exporter; use SNMP::Info::CiscoVTP; use SNMP::Info::LLDP; use SNMP::Info::CDP; use SNMP::Info::CiscoStats; use SNMP::Info::CiscoRTT; use SNMP::Info::CiscoQOS; use SNMP::Info::CiscoConfig; use SNMP::Info::CiscoPower; use SNMP::Info::CiscoStpExtensions; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Cisco::ISA = qw/SNMP::Info::CiscoVTP SNMP::Info::LLDP SNMP::Info::CDP SNMP::Info::CiscoStats SNMP::Info::CiscoRTT SNMP::Info::CiscoQOS SNMP::Info::CiscoConfig SNMP::Info::CiscoPower SNMP::Info::CiscoStpExtensions SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Cisco::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::CiscoStpExtensions::MIBS, %SNMP::Info::CiscoPower::MIBS, %SNMP::Info::CiscoConfig::MIBS, %SNMP::Info::CiscoQOS::MIBS, %SNMP::Info::CiscoRTT::MIBS, %SNMP::Info::CiscoStats::MIBS, %SNMP::Info::CDP::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::CiscoVTP::MIBS, 'CISCO-EIGRP-MIB' => 'cEigrpAsRouterId', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::CiscoStpExtensions::GLOBALS, %SNMP::Info::CiscoPower::GLOBALS, %SNMP::Info::CiscoConfig::GLOBALS, %SNMP::Info::CiscoQOS::GLOBALS, %SNMP::Info::CiscoRTT::GLOBALS, %SNMP::Info::CiscoStats::GLOBALS, %SNMP::Info::CDP::GLOBALS, %SNMP::Info::LLDP::GLOBALS, %SNMP::Info::CiscoVTP::GLOBALS, 'eigrp_id' => 'cEigrpAsRouterId', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::CiscoStpExtensions::FUNCS, %SNMP::Info::CiscoPower::FUNCS, %SNMP::Info::CiscoConfig::FUNCS, %SNMP::Info::CiscoQOS::FUNCS, %SNMP::Info::CiscoRTT::FUNCS, %SNMP::Info::CiscoStats::FUNCS, %SNMP::Info::CDP::FUNCS, %SNMP::Info::LLDP::FUNCS, %SNMP::Info::CiscoVTP::FUNCS, # EIGRP 'eigrp_peers' => 'cEigrpPeerAddr', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::CiscoStpExtensions::MUNGE, %SNMP::Info::CiscoPower::MUNGE, %SNMP::Info::CiscoConfig::MUNGE, %SNMP::Info::CiscoQOS::MUNGE, %SNMP::Info::CiscoRTT::MUNGE, %SNMP::Info::CiscoStats::MUNGE, %SNMP::Info::CDP::MUNGE, %SNMP::Info::LLDP::MUNGE, %SNMP::Info::CiscoVTP::MUNGE, 'eigrp_peers' => \&SNMP::Info::munge_ip, ); sub i_vlan { my $cisco = shift; my $partial = shift; my $i_type = $cisco->i_type($partial); my $i_descr = $cisco->i_description($partial); my $i_vlan = $cisco->SUPER::i_vlan($partial); foreach my $idx ( keys %$i_descr ) { next unless $i_type->{$idx}; if ( $i_type->{$idx} eq 'l2vlan' || $i_type->{$idx} eq '135' && !defined $i_vlan->{$idx} ) { if ( $i_descr->{$idx} =~ /\.(\d+)$/ ) { $i_vlan->{$idx} = $1; } } } return $i_vlan; } sub cisco_comm_indexing { my $cisco = shift; # If we get a VTP version, it's *extremely* likely that the device needs community based indexing my $vtp = $cisco->vtp_version() || '0'; return ($vtp ne '0'); } 1; __END__ =head1 NAME SNMP::Info::Layer3::Cisco - SNMP Interface to L3 and L2+L3 IOS Cisco Device that are not covered in other classes and the base L3 Cisco class for other device specific L3 Cisco classes. =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $cisco = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $cisco->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Generic Cisco Routers running IOS and the base L3 Cisco class for other device specific L3 Cisco classes. =head2 Inherited Classes =over =item SNMP::Info::CiscoVTP =item SNMP::Info::LLDP =item SNMP::Info::CDP =item SNMP::Info::CiscoStats =item SNMP::Info::CiscoRTT =item SNMP::Info::CiscoQOS =item SNMP::Info::CiscoConfig =item SNMP::Info::Power =item SNMP::Info::CiscoStpExtensions =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $cisco->eigrp_id() (C) =item $switch->cisco_comm_indexing() Returns 1 when the device is likely to need vlan indexing. Determined by checking C. =back =head2 Global Methods imported from SNMP::Info::CiscoVTP See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head2 Globals imported from SNMP::Info::CDP See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoStats See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoRTT See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoQOS See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoConfig See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoPower See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoStpExtensions See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $cisco->eigrp_peers() Returns EIGRP peer IP addresses (C) =item $cisco->i_vlan() Returns a mapping between C and the PVID or default VLAN. =back =head2 Table Methods imported from SNMP::Info::CiscoVTP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoStats See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoRTT See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoQOS See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoConfig See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoPower See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoStpExtensions See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/CiscoASA.pm000444000765000024 1212713215550564 20370 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::CiscoASA # $Id$ # # Copyright (c) 2013 Moe Kraus # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::CiscoASA; use strict; use warnings; use Exporter; use SNMP::Info::CiscoStats; use SNMP::Info::Layer3; @SNMP::Info::Layer3::CiscoASA::ISA = qw/ SNMP::Info::CiscoStats SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::CiscoASA::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::CiscoStats::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::CiscoStats::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::CiscoStats::FUNCS, 'mac_table' => 'ifPhysAddress', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::CiscoStats::MUNGE, 'mac_table' => \&SNMP::Info::munge_mac, ); sub b_mac { my ($asa) = shift; my $macs = $asa->mac_table(); my @macs; # gather physical addresses foreach my $i ( keys %$macs ) { my $mac = $macs->{$i}; # don't catch the bad macs with bogus OUI if ( $mac !~ m/(0{1,2}:){2}(00|01)/ ) { push( @macs, $mac ); } @macs = sort(@macs); } # return the least mac return $macs[0]; } sub i_description { my $self = shift; my $partial = shift; my $i_descr = $self->orig_i_description($partial) || {}; foreach my $ifindex ( keys %$i_descr ) { $i_descr->{$ifindex} =~ /'(.*)'/; $i_descr->{$ifindex} = $1 if defined $1; } return $i_descr; } 1; __END__ =head1 NAME SNMP::Info::Layer3::CiscoASA - Cisco Adaptive Security Appliance =head1 AUTHOR Moe Kraus =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $cisco = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $asa->class(); print "SNMP::Info determined this device to fall under subclass: $class\n"; =head1 DESCRIPTION Subclass for Cisco ASA Devices =head2 Inherited Classes =over =item SNMP::Info::CiscoStats =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $asa->b_mac() Returns base mac. Overrides base mac function in L. =item $asa->i_description() Overrides base interface description function in L to return the configured interface name instead of "Adaptive Security Appliance '$configured interface name' interface". =back =head2 Globals imported from SNMP::Info::CiscoStats See documentation in L for details. =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::CiscoStats See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/CiscoFWSM.pm000444000765000024 1377113215550564 20546 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::CiscoFWSM # $Id$ # # Copyright (c) 2010 Brian De Wolf # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::CiscoFWSM; use strict; use warnings; use Exporter; use SNMP::Info::CiscoStats; use SNMP::Info::Layer3; @SNMP::Info::Layer3::CiscoFWSM::ISA = qw/SNMP::Info::CiscoStats SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::CiscoFWSM::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::CiscoStats::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::CiscoStats::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::CiscoStats::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::CiscoStats::MUNGE, ); # For FWSMs, the ipNetToPhysicalPhysAddress table appears to be of the form: # $ifindex.$inetaddresstype.$proto.$ip_address -> $mac_address # # Using the output of ipNetToPhysicalPhysAddress, we can emulate the other # functions. # # This doesn't really line up to what at_* return, so we munge it sub at_paddr { my ($fwsm) = shift; my ($partial) = shift; my $paddrs = $fwsm->n2p_paddr($partial); my $n_paddrs = {}; foreach my $key ( keys %$paddrs ) { my $paddr = $paddrs->{$key}; my @parts = split /\./, $key; my ( $ifindex, $addrtype, $proto ) = splice @parts, 0, 3; my $ip = join ".", @parts; next if ( $proto != 4 ); # at_paddr doesn't support non-IPv4 $n_paddrs->{"$ifindex.$ip"} = $paddr; } return $n_paddrs; } sub at_netaddr { my ($fwsm) = shift; my ($partial) = shift; my $paddrs = $fwsm->n2p_paddr($partial); my $netaddrs = {}; foreach my $key ( keys %$paddrs ) { my $paddr = $paddrs->{$key}; my @parts = split /\./, $key; my ( $ifindex, $addrtype, $proto ) = splice @parts, 0, 3; my $ip = join ".", @parts; next if ( $proto != 4 ); # at_netaddr doesn't support non-IPv4 $netaddrs->{"$ifindex.$ip"} = $ip; } return $netaddrs; } sub at_ifaddr { my ($fwsm) = shift; my ($partial) = shift; my $paddrs = $fwsm->n2p_paddr($partial); my $ifaddrs = {}; foreach my $key ( keys %$paddrs ) { my $paddr = $paddrs->{$key}; my @parts = split /\./, $key; my ( $ifindex, $addrtype, $proto ) = splice @parts, 0, 3; my $ip = join ".", @parts; next if ( $proto != 4 ); # at_ifaddr doesn't support non-IPv4 $ifaddrs->{"$ifindex.$ip"} = $ip; } return $ifaddrs; } 1; __END__ =head1 NAME SNMP::Info::Layer3::CiscoFWSM - SNMP Interface to Firewall Services Modules for features not covered elsewhere. =head1 AUTHOR Brian De Wolf =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $fwsm = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $fwsm->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Cisco Firewall Services Modules =head2 Inherited Classes =over =item SNMP::Info::CiscoStats =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS =head2 Globals imported from SNMP::Info::CiscoStats See documentation in L for details. =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =back =head2 Overrides =over =item $fwsm->at_paddr() This function derives the at_paddr information from the n2p_paddr() table as the MIB to provide that information isn't supported on FWSM. =item $fwsm->at_netaddr() This function derives the at_netaddr information from the n2p_paddr() table as the MIB to provide that information isn't supported on FWSM. =item $fwsm->at_ifaddr() This function derives the at_ifaddr information from the n2p_paddr() table as the MIB to provide that information isn't supported on FWSM. =back =head2 Table Methods imported from SNMP::Info::CiscoStats See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/CiscoSwitch.pm000444000765000024 1247513215550564 21233 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::CiscoSwitch # $Id$ # # Copyright (c) 2014 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::CiscoSwitch; use strict; use warnings; use Exporter; use SNMP::Info::CiscoAgg; use SNMP::Info::CiscoPortSecurity; use SNMP::Info::Layer3::Cisco; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; @SNMP::Info::Layer3::CiscoSwitch::ISA = qw/ SNMP::Info::CiscoAgg SNMP::Info::CiscoPortSecurity SNMP::Info::Layer3::Cisco Exporter /; @SNMP::Info::Layer3::CiscoSwitch::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::Cisco::MIBS, %SNMP::Info::CiscoPortSecurity::MIBS, %SNMP::Info::CiscoAgg::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer3::Cisco::GLOBALS, %SNMP::Info::CiscoPortSecurity::GLOBALS, %SNMP::Info::CiscoAgg::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::Cisco::FUNCS, %SNMP::Info::CiscoPortSecurity::FUNCS, %SNMP::Info::CiscoAgg::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::Cisco::MUNGE, %SNMP::Info::CiscoPortSecurity::MUNGE, %SNMP::Info::CiscoAgg::MUNGE, ); sub cisco_comm_indexing { return 1; } 1; __END__ =head1 NAME SNMP::Info::Layer3::CiscoSwitch - Base class for L3 Cisco switches =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $switch = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $switch->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Base subclass for Cisco Layer 2/3 Switches. These devices have switch specific characteristics beyond those in traditional routers covered by L. For example, port security interface information from L. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $swich = new SNMP::Info::Layer3::CiscoSwitch(...); =head2 Inherited Classes =over =item SNMP::Info::CiscoAgg =item SNMP::Info::CiscoPortSecurity =item SNMP::Info::Layer3::Cisco =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $switch->cisco_comm_indexing() Returns 1. Use vlan indexing. =back =head2 Global Methods imported from SNMP::Info::CiscoAgg See documentation in L for details. =head2 Globals imported from SNMP::Info::CiscoPortSecurity See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3::Cisco See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::CiscoAgg See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CiscoPortSecurity See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3::Cisco See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Contivity.pm000444000765000024 1632713215550564 21001 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Contivity # $Id$ # # Copyright (c) 2010 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Contivity; use strict; use Exporter; use SNMP::Info; use SNMP::Info::Layer3; use SNMP::Info::Entity; @SNMP::Info::Layer3::Contivity::ISA = qw/SNMP::Info SNMP::Info::Layer3 SNMP::Info::Entity Exporter/; @SNMP::Info::Layer3::Contivity::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::MIBS, %SNMP::Info::Layer3::MIBS, %SNMP::Info::Entity::MIBS, ); %GLOBALS = ( %SNMP::Info::GLOBALS, %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::Entity::GLOBALS, ); %FUNCS = ( %SNMP::Info::FUNCS, %SNMP::Info::Layer3::FUNCS, %SNMP::Info::Entity::FUNCS, ); %MUNGE = ( %SNMP::Info::MUNGE, %SNMP::Info::Layer3::MUNGE, %SNMP::Info::Entity::MUNGE, ); sub layers { return '00000100'; } sub vendor { return 'avaya'; } sub model { my $contivity = shift; my $e_model = $contivity->e_model() || {}; my $model = $e_model->{1} || undef; return $1 if ( defined $model and $model =~ /(CES\d+|NVR\d+)/i ); return; } sub os { return 'contivity'; } sub os_ver { my $contivity = shift; my $descr = $contivity->description(); return unless defined $descr; if ( $descr =~ m/V(\d+_\d+\.\d+)/i ) { return $1; } return; } sub mac { my $contivity = shift; my $i_mac = $contivity->i_mac(); # Return Interface MAC foreach my $entry ( keys %$i_mac ) { my $sn = $i_mac->{$entry}; next unless $sn; return $sn; } return; } sub serial { my $contivity = shift; my $e_serial = $contivity->e_serial() || {}; my $serial = $e_serial->{1} || undef; return $1 if ( defined $serial and $serial =~ /(\d+)/ ); return; } sub interfaces { my $contivity = shift; my $partial = shift; my $description = $contivity->i_description($partial) || {}; my %interfaces = (); foreach my $iid ( keys %$description ) { my $desc = $description->{$iid}; # Skip everything except Ethernet interfaces next unless ( defined $desc and $desc =~ /fe/i ); $interfaces{$iid} = $desc; } return \%interfaces; } sub i_name { my $contivity = shift; my $partial = shift; my $i_name2 = $contivity->orig_i_name($partial) || {}; my %i_name; foreach my $iid ( keys %$i_name2 ) { my $name = $i_name2->{$iid}; #Skip everything except Ethernet interfaces next unless ( defined $name and $name =~ /fe/i ); $name = $1 if $name =~ /(fei\.\d+\.\d+)/; $i_name{$iid} = $name; } return \%i_name; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Contivity - SNMP Interface to Avaya/Nortel VPN Routers (formerly Contivity Extranet Switches). =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $contivity = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $contivity->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Avaya/Nortel VPN Routers (formerly Contivity Extranet Switch). For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $contivity = new SNMP::Info::Layer3::Contivity(...); =head2 Inherited Classes =over =item SNMP::Info =item SNMP::Info::Layer3 =item SNMP::Info::Entity =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $contivity->vendor() Returns 'avaya' =item $contivity->model() Returns the chassis name. (C) =item $contivity->os() Returns C<'CES'> =item $contivity->os_ver() Returns the software version extracted from (C). =item $contivity->serial() Returns the chassis serial number. (C) =item $contivity->mac() Returns the MAC address of the first Ethernet Interface. =back =head2 Overrides =over =item $contivity->layers() Returns 00000100. Contivity does not support bridge MIB, so override reported layers. =back =head2 Globals imported from SNMP::Info See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Globals imported from SNMP::Info::Entity See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $contivity->interfaces() Returns reference to the map between IID and physical Port. Skips loopback and tunnel interfaces. =item $contivity->i_name() Interface Name field. Skips loopback and tunnel interfaces. =back =head2 Table Methods imported from SNMP::Info See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Entity See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/DLink.pm000444000765000024 661313215550564 17767 0ustar00oliverstaff000000000000package SNMP::Info::Layer3::DLink; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; @SNMP::Info::Layer3::DLink::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::DLink::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, 'DLINK-ID-REC-MIB' => 'dlink', 'SWPRIMGMT-DES3200-MIB' => 'dlink-des3200SeriesProd', 'SWPRIMGMT-DES30XXP-MIB' => 'dlink-des30xxproductProd', 'SWPRIMGMT-DES1228ME-MIB' => 'dlink-des1228MEproductProd', 'SWDES3528-52PRIMGMT-MIB' => 'dlink-Des3500Series', 'DES-1210-28-AX' => 'des-1210-28ax', 'DES-1210-10MEbx' => 'des-1210-10mebx', 'DES-1210-26MEbx' => 'des-1210-26mebx', 'DES-1210-52-BX' => 'des-1210-52bx', 'DES-1210-52-CX' => 'des-1210-52-cx', 'DGS-1210-24-AX' => 'dgs-1210-24ax', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, 'dlink_fw' => 'probeSoftwareRev', 'dlink_hw' => 'probeHardwareRev', 'dlink_stp_i_root_port' => 'MSTP_MIB__swMSTPInstRootPort', 'dlink_serial_no' => 'AGENT_GENERAL_MIB__agentSerialNumber', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub model { my $dlink=shift; my $id = $dlink->id(); my $model = &SNMP::translateObj($id); return $id unless defined $model; if (defined $model && $model !~ /dlink-products/) { return $model; } else { #If don't have a device MIB return $dlink->description(); } } sub vendor { return 'dlink'; } sub serial { my $dlink = shift; my $model = $dlink->model(); my $id = $dlink->id(); my $serial; if ($model =~ /1210/) { #Due to the zoo of MIB from DLink by 1210 series $serial->{0} = $dlink->session()->get($id.'.1.30.0'); } else { $serial = $dlink->dlink_serial_no(); } return $serial->{0} if ( defined $serial->{0} and $serial->{0} !~ /^\s*$/ and $serial->{0} !~ 'NOSUCHOBJECT' ); return $dlink->SUPER::serial(); } sub fwver { my $dlink=shift; my $model = $dlink->model(); my $id = $dlink->id(); my $fw; if ($model =~ /1210/) { #Due to the zoo of MIB from DLink by 1210 series $fw->{0} = $dlink->session()->get($id.'.1.3.0'); } else { $fw = $dlink->dlink_fw(); } return $fw->{0} if ( defined $fw->{0} and $fw->{0} !~ /^\s*$/ and $fw->{0} !~ 'NOSUCHOBJECT'); } sub hwver { my $dlink=shift; my $model = $dlink->model(); my $id = $dlink->id(); my $hw; if ($model =~ /1210/) { #Due to the zoo of MIB from DLink by 1210 series $hw->{0} = $dlink->session()->get($id.'.1.2.0'); } else { $hw = $dlink->dlink_hw(); } return $hw->{0} if ( defined $hw->{0} and $hw->{0} !~ /^\s*$/ and $hw->{0} !~ 'NOSUCHOBJECT'); } sub stp_i_root_port { my $dlink=shift; my $model = $dlink->model(); my $id = $dlink->id(); my $stp_i_root_port; if ($model =~ /1210-(?:10|26)/) { #Due to the zoo of MIB from DLink by 1210 series $stp_i_root_port->{0} = $dlink->session()->get($id.'.6.1.13.0'); } else { $stp_i_root_port = $dlink->dlink_stp_i_root_port(); } return $stp_i_root_port if ( defined $stp_i_root_port->{0} and $stp_i_root_port->{0} !~ /^\s*$/ and $stp_i_root_port->{0} !~ 'NOSUCHOBJECT'); return $dlink->SUPER::stp_i_root_port(); } 1; __END__ SNMP-Info-3.39/lib/SNMP/Info/Layer3/Dell.pm000444000765000024 2775313215550564 17676 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Dell - SNMP Interface to Dell devices # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Dell; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; @SNMP::Info::Layer3::Dell::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Dell::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, 'RADLAN-Physicaldescription-MIB' => 'rlPhdStackReorder', 'RADLAN-rlInterfaces' => 'rlIfNumOfLoopbackPorts', 'RADLAN-HWENVIROMENT' => 'rlEnvPhysicalDescription', 'Dell-Vendor-MIB' => 'productIdentificationVersion', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'os_ver' => 'productIdentificationVersion', 'dell_id_name' => 'productIdentificationDisplayName', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, # RADLAN-rlInterfaces:swIfTable 'dell_duplex_admin' => 'swIfDuplexAdminMode', 'dell_duplex' => 'swIfDuplexOperMode', 'dell_tag_mode' => 'swIfTaggedMode', 'dell_i_type' => 'swIfType', 'dell_fc_admin' => 'swIfFlowControlMode', 'dell_speed_admin' => 'swIfSpeedAdminMode', 'dell_auto' => 'swIfSpeedDuplexAutoNegotiation', 'dell_fc' => 'swIfOperFlowControlMode', # RADLAN-Physicaldescription-MIB:rlPhdUnitGenParamTable 'dell_unit' => 'rlPhdUnitGenParamStackUnit', 'dell_sw_ver' => 'rlPhdUnitGenParamSoftwareVersion', 'dell_fw_ver' => 'rlPhdUnitGenParamFirmwareVersion', 'dell_hw_ver' => 'rlPhdUnitGenParamHardwareVersion', 'dell_serial_no' => 'rlPhdUnitGenParamSerialNum', 'dell_asset_no' => 'rlPhdUnitGenParamAssetTag', # RADLAN-COPY-MIB:rlCopyTable 'dell_cp_idx' => 'rlCopyIndex', 'dell_cp_sloc' => 'rlCopySourceLocation', 'dell_cp_sip' => 'rlCopySourceIpAddress', 'dell_cp_sunit' => 'rlCopySourceUnitNumber', 'dell_cp_sfile' => 'rlCopySourceFileName', 'dell_cp_stype' => 'rlCopySourceFileType', 'dell_cp_dloc' => 'rlCopyDestinationLocation', 'dell_cp_dip' => 'rlCopyDestinationIpAddress', 'dell_cp_dunit' => 'rlCopyDestinationUnitNumber', 'dell_cp_dfile' => 'rlCopyDestinationFileName', 'dell_cp_dtype' => 'rlCopyDestinationFileType', 'dell_cp_state' => 'rlCopyOperationState', 'dell_cp_bkgnd' => 'rlCopyInBackground', 'dell_cp_rstatus' => 'rlCopyRowStatus', # RADLAN-HWENVIROMENT:rlEnvMonSupplyStatusTable 'dell_pwr_src' => 'rlEnvMonSupplySource', 'dell_pwr_state' => 'rlEnvMonSupplyState', 'dell_pwr_desc' => 'rlEnvMonSupplyStatusDescr', # RADLAN-HWENVIROMENT:rlEnvMonFanStatusTable 'dell_fan_state' => 'rlEnvMonFanState', 'dell_fan_desc' => 'rlEnvMonFanStatusDescr', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); # Method OverRides sub model { my $dell = shift; my $name = $dell->dell_id_name(); my $descr = $dell->description(); if ( defined $name and $name =~ m/(\d+)/ ) { return $1; } # Don't have a vendor MIB for D-Link else { return $descr; } } sub vendor { my $dell = shift; return $dell->_vendor(); } sub os { my $dell = shift; return $dell->_vendor(); } sub serial { my $dell = shift; my $numbers = $dell->dell_serial_no(); foreach my $key ( keys %$numbers ) { my $serial = $numbers->{$key}; return $serial if ( defined $serial and $serial !~ /^\s*$/ ); next; } # Last resort return $dell->SUPER::serial(); } # check all fans, and report overall status sub fan { my $dell = shift; my $fan = $dell->dell_fan_desc() || {}; my $state = $dell->dell_fan_state() || {}; my @messages = (); foreach my $k (keys %$fan) { next if $state->{$k} and $state->{$k} eq 'normal'; push @messages, "$fan->{$k}: $state->{$k}"; } push @messages, ((scalar keys %$fan). " fans OK") if scalar @messages == 0; return (join ", ", @messages); } sub _ps_status { my ($dell, $unit) = @_; my $status = 'unknown'; return $status if !defined $unit; my $desc = $dell->dell_pwr_desc() || {}; my $state = $dell->dell_pwr_state() || {}; foreach my $k (keys %$desc) { next unless $desc->{$k} and $desc->{$k} eq "ps1_unit$unit"; return ($state->{$k} || $status); } return $status; } sub ps1_type { return 'internalRedundant' } sub ps2_type { return 'internalRedundant' } sub ps1_status { return (shift)->_ps_status(1) } sub ps2_status { return (shift)->_ps_status(2) } sub interfaces { my $dell = shift; my $partial = shift; my $i_descr = $dell->i_description($partial) || {}; my $i_name = $dell->orig_i_name($partial) || {}; # Descriptions are all the same on some Dells, so use name instead if # available foreach my $iid ( keys %$i_name ) { my $name = $i_name->{$iid}; next unless defined $name; $i_descr->{$iid} = $name; } return $i_descr; } sub i_duplex_admin { my $dell = shift; my $partial = shift; my $interfaces = $dell->interfaces($partial) || {}; my $dell_duplex = $dell->dell_duplex_admin($partial) || {}; my $dell_auto = $dell->dell_auto($partial) || {}; my %i_duplex_admin; foreach my $if ( keys %$interfaces ) { my $duplex = $dell_duplex->{$if}; next unless defined $duplex; my $auto = $dell_auto->{$if} || 'false'; $duplex = 'half' if ( $duplex =~ /half/i and $auto =~ /false/i ); $duplex = 'full' if ( $duplex =~ /half/i and $auto =~ /false/i ); $duplex = 'auto' if $auto =~ /true/i; $i_duplex_admin{$if} = $duplex; } return \%i_duplex_admin; } sub _vendor { my $dell = shift; my $id = $dell->id() || 'undef'; my %oidmap = ( 2 => 'ibm', 171 => 'dlink', 674 => 'dell', 3955 => 'linksys', ); $id = $1 if ( defined($id) && $id =~ /^\.1\.3\.6\.1\.4\.1\.(\d+)/ ); if ( defined($id) and exists( $oidmap{$id} ) ) { return $oidmap{$id}; } else { return 'dlink'; } } # dot1qTpFdbTable uses dot1qVlanIndex rather than dot1qFdbId as index, # so pretend we don't have the mapping sub qb_fdb_index {return} 1; __END__ =head1 NAME SNMP::Info::Layer3::Dell - SNMP Interface to Dell Power Connect Network Devices =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $dell = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $dell->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from an Dell Power Connect device through SNMP. D-Link and the IBM BladeCenter Gigabit Ethernet Switch Module also use this module based upon MIB support. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $dell = new SNMP::Info::Layer3::Dell(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item F =item F =item Inherited Classes' MIBs See classes listed above for their required MIBs. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $dell->os_ver() (C) =item $dell->dell_id_name() (C) =item $dell->model() Returns model type. Returns numeric from (C) if available, otherwise if returns description(). =item $dell->vendor() Returns 'dell', 'dlink', or 'ibm' based upon the IANA enterprise number in id(). Defaults to 'dlink'. =item $dell->os() Returns 'dell', 'dlink', or 'ibm' based upon the IANA enterprise number in id(). Defaults to 'dlink'. =item $dell->fan() Return the status of all fans from the F =item $dell->ps1_type() Return the type of the first power supply from the F =item $dell->ps2_type() Return the type of the second power supply from the F =item $dell->ps1_status() Return the status of the first power supply from the F =item $dell->ps2_status() Return the status of the second power supply from the F =back =head2 Overrides =over =item $dell->serial() Returns serial number. Returns (C) if available, otherwise uses the Layer3 serial method. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 RADLAN Interface Table (C) =over =item $dell->dell_duplex_admin() (C) =item $dell->dell_duplex() (C) =item $dell->dell_tag_mode() (C) =item $dell->dell_i_type() (C) =item $dell->dell_fc_admin() (C) =item $dell->dell_speed_admin() (C) =item $dell->dell_auto() (C) =item $dell->dell_fc() (C) =back =head2 Overrides =over =item $dell->interfaces() Returns the map between SNMP Interface Identifier (iid) and physical port name. Uses name if available instead of description since descriptions are sometimes not unique. =item $dell->i_duplex_admin() Returns reference to hash of iid to current link administrative duplex setting. =item $dell->qb_fdb_index() Returns nothing to work around incorrect indexing of C =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Enterasys.pm000444000765000024 2603713215550564 20765 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Enterasys - SNMP Interface to Enterasys devices # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Enterasys; use strict; use Exporter; use SNMP::Info::MAU; use SNMP::Info::LLDP; use SNMP::Info::CDP; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Enterasys::ISA = qw/SNMP::Info::MAU SNMP::Info::LLDP SNMP::Info::CDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Enterasys::EXPORT_OK = qw//; use vars qw/$VERSION $DEBUG %GLOBALS %FUNCS $INIT %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::CDP::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::MAU::MIBS, 'ENTERASYS-OIDS-MIB' => 'etsysOidDevice', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::CDP::GLOBALS, %SNMP::Info::LLDP::GLOBALS, %SNMP::Info::MAU::GLOBALS, 'mac' => 'dot1dBaseBridgeAddress', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::CDP::FUNCS, %SNMP::Info::LLDP::FUNCS, %SNMP::Info::MAU::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::CDP::MUNGE, %SNMP::Info::LLDP::MUNGE, %SNMP::Info::MAU::MUNGE, ); sub model { my $enterasys = shift; my $id = $enterasys->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::Enterasys::model() - Device does not support sysObjectID\n" if $enterasys->debug(); return; } my $model = &SNMP::translateObj($id); $model =~ s/^etsysOidDev//i; $model =~ s/^etsysOidPhy//i; return $id unless defined $model; return $model; } sub vendor { return 'enterasys'; } sub os { return 'enterasys'; } sub os_ver { my $enterasys = shift; my $descr = $enterasys->description(); return unless defined $descr; if ( $descr =~ m/\bRev ([\d.]*)/ ) { return $1; } return; } # Use ifName as it is used for CDP and LLDP. sub interfaces { my $enterasys = shift; my $partial = shift; # We need the original ifName, SUPER:: would give us a method definition # in a higher class, we could use orig_ but just call the MIB leaf since # that's what we really want anyway. return $enterasys->ifName($partial) || $enterasys->i_description($partial); } sub i_ignore { my $enterasys = shift; my $partial = shift; my $interfaces = $enterasys->i_type($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { if ( $interfaces->{$if} =~ /(rs232|tunnel|loopback|\blo\b|null)/i ) { $i_ignore{$if}++; } } return \%i_ignore; } sub i_duplex { my $enterasys = shift; my $partial = shift; return $enterasys->mau_i_duplex($partial); } sub i_duplex_admin { my $enterasys = shift; my $partial = shift; return $enterasys->mau_i_duplex_admin($partial); } # TimeFilter implementation continuously increments when walked # and we may never reach the end of the table. This behavior can be # modified with the "set snmp timefilter break disable" command, # unfortunately it is not the default. Query with a partial value of zero # which means no time filter for tables with and index containing a # TimeFilter sub qb_fdb_index { my $bridge = shift; my $qb_fdb_ids = $bridge->dot1qVlanFdbId(0) || {}; # Strip the TimeFilter my $vl_fdb_index = {}; for my $fdb_entry (keys(%$qb_fdb_ids)) { (my $vlan = $fdb_entry) =~ s/^\d+\.//; $vl_fdb_index->{$qb_fdb_ids->{$fdb_entry}} = $vlan; } return $vl_fdb_index; } sub i_vlan_membership { my $bridge = shift; my $partial = shift; # dot1qVlanCurrentTable TimeFilter index my $v_ports = $bridge->qb_cv_egress(0) || $bridge->qb_v_egress(); return $bridge->_vlan_hoa($v_ports, $partial); } sub i_vlan_membership_untagged { my $bridge = shift; my $partial = shift; # dot1qVlanCurrentTable TimeFilter index my $v_ports = $bridge->qb_cv_untagged(0) || $bridge->qb_v_untagged(); return $bridge->_vlan_hoa($v_ports, $partial); } sub lldp_ip { my $enterasys = shift; my $partial = shift || 0; return $enterasys->SUPER::lldp_ip($partial); } # [3564920] LLDP-MIB::lldpLocPortDesc isn't always unique, # use LLDP-MIB::lldpLocPortId this cross references to ifName sub lldp_if { my $lldp = shift; my $partial = shift || 0; my $addr = $lldp->lldp_rem_pid($partial) || {}; my $i_descr = $lldp->ifName() || {}; my %r_i_descr = reverse %$i_descr; my %lldp_if; foreach my $key ( keys %$addr ) { my @aOID = split( '\.', $key ); my $port = $aOID[1]; next unless $port; # Local LLDP port may not equate to ifIndex # Cross reference lldpLocPortId with ifName to get ifIndex my $lldp_desc = $lldp->lldpLocPortId($port); my $desc = $lldp_desc->{$port}; # If cross reference is successful use it, otherwise stick with lldpRemLocalPortNum if ( exists $r_i_descr{$desc} ) { $port = $r_i_descr{$desc}; } $lldp_if{$key} = $port; } return \%lldp_if; } sub lldp_port { my $enterasys = shift; my $partial = shift || 0; return $enterasys->SUPER::lldp_port($partial); } sub lldp_id { my $enterasys = shift; my $partial = shift || 0; return $enterasys->SUPER::lldp_id($partial); } sub lldp_platform { my $enterasys = shift; my $partial = shift || 0; return $enterasys->SUPER::lldp_rem_sysdesc($partial); } 1; __END__ =head1 NAME SNMP::Info::Layer3::Enterasys - SNMP Interface to Enterasys Network Devices =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $enterasys = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $enterasys->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from an Enterasys device through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $enterasys = new SNMP::Info::Layer3::Enterasys(...); =head2 Inherited Classes =over =item SNMP::Info::MAU =item SNMP::Info::LLDP =item SNMP::Info::CDP =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =back =head2 Inherited MIBs See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $enterasys->model() Returns model type. Checks $enterasys->id() against the F. =item $enterasys->vendor() Returns enterasys =item $enterasys->os() Returns enterasys =item $enterasys->os_ver() Returns os version extracted from C =item $enterasys->mac() Returns base mac (C) =back =head2 Globals imported from SNMP::Info::MAU See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head2 Globals imported from SNMP::Info::CDP See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $enterasys->interfaces() Mapping between the Interface Table Index (iid) and the physical port name. =item $enterasys->i_ignore() Returns reference to hash. Creates a key for each IID that should be ignored. Currently looks for rs232, tunnel,loopback,lo,null from $enterasys->interfaces() =item $enterasys->i_duplex() See documentation for mau_i_duplex() in L. =item $enterasys->i_duplex_admin() See documentation for mau_i_duplex_admin() in L. =back =head2 Time Filter Table Index Overrides The time filter C implementation continuously increments when walked and we may never reach the end of the table. This behavior can be modified with the C<"set snmp timefilter break disable"> command, unfortunately it is not the default. These methods are overridden to supply a partial value of zero which means no time filter. =over =item $enterasys->qb_fdb_index() =item $enterasys->i_vlan_membership() =item $enterasys->i_vlan_membership_untagged() =item $enterasys->lldp_if() =item $enterasys->lldp_ip() =item $enterasys->lldp_port() =item $enterasys->lldp_id() =item $enterasys->lldp_platform() =back =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::CDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Extreme.pm000444000765000024 10614213215550564 20435 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Extreme - SNMP Interface to Extreme devices # $Id$ # # Copyright (c) 2012 Eric Miller # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Extreme; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::MAU; use SNMP::Info::LLDP; use SNMP::Info::EDP; @SNMP::Info::Layer3::Extreme::ISA = qw/SNMP::Info::Layer3 SNMP::Info::MAU SNMP::Info::LLDP SNMP::Info::EDP Exporter/; @SNMP::Info::Layer3::Extreme::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::MAU::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::EDP::MIBS, 'EXTREME-BASE-MIB' => 'extremeAgent', 'EXTREME-SYSTEM-MIB' => 'extremeSystem', 'EXTREME-FDB-MIB' => 'extremeFdbMacFdbMacAddress', 'EXTREME-VLAN-MIB' => 'extremeVlan', 'EXTREME-POE-MIB' => 'extremePethSystemAdminEnable', 'EXTREME-STP-EXTENSIONS-MIB' => 'extremeStpDomainBridgeId', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::MAU::GLOBALS, %SNMP::Info::LLDP::GLOBALS, %SNMP::Info::EDP::GLOBALS, 'serial1' => 'extremeSystemID.0', 'temp' => 'extremeCurrentTemperature', 'ps1_status_old' => 'extremePrimaryPowerOperational.0', 'ps1_status_new' => 'extremePowerSupplyStatus.1', 'ps2_status_old' => 'extremeRedundantPowerStatus.0', 'ps2_status_new' => 'extremePowerSupplyStatus.2', 'mac' => 'dot1dBaseBridgeAddress', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::MAU::FUNCS, %SNMP::Info::LLDP::FUNCS, %SNMP::Info::EDP::FUNCS, 'fan_state' => 'extremeFanOperational', # EXTREME-FDB-MIB:extremeFdbMacFdbTable 'ex_fw_mac' => 'extremeFdbMacFdbMacAddress', 'ex_fw_port' => 'extremeFdbMacFdbPortIfIndex', 'ex_fw_status' => 'extremeFdbMacFdbStatus', # EXTREME-VLAN-MIB:extremeVlanIfTable 'ex_vlan_descr' => 'extremeVlanIfDescr', 'ex_vlan_global_id' => 'extremeVlanIfGlobalIdentifier', 'ex_vlan_id' => 'extremeVlanIfVlanId', # EXTREME-VLAN-MIB:extremeVlanEncapsIfTable 'ex_vlan_encap_tag' => 'extremeVlanEncapsIfTag', # EXTREME-VLAN-MIB:extremeVlanOpaqueTable 'ex_vlan_untagged' => 'extremeVlanOpaqueUntaggedPorts', 'ex_vlan_tagged' => 'extremeVlanOpaqueTaggedPorts', # EXTREME-POE-MIB::extremePethPseSlotTable 'peth_power_watts' => 'extremePethSlotPowerLimit', # EXTREME-POE-MIB::extremePethPsePortTable 'peth_port_power' => 'extremePethPortMeasuredPower', # EXTREME-STP-EXTENSIONS-MIB::extremeStpDomainTable 'stp_i_time' => 'extremeStpDomainTimeSinceTopologyChange', 'stp_i_ntop' => 'extremeStpDomainTopChanges', 'stp_i_root' => 'extremeStpDomainDesignatedRoot', 'stp_i_root_port' => 'extremeStpDomainRootPortIfIndex', 'stp_i_priority' => 'extremeStpDomainBridgePriority', 'ex_stp_i_mac' => 'extremeStpDomainBridgeId', # EXTREME-STP-EXTENSIONS-MIB::extremeStpPortTable 'stp_p_priority' => 'extremeStpPortPortPriority', 'stp_p_state' => 'extremeStpPortPortState', 'stp_p_cost' => 'extremeStpPortPathCost', 'stp_p_root' => 'extremeStpPortDesignatedRoot', 'stp_p_bridge' => 'extremeStpPortDesignatedBridge', 'stp_p_port' => 'extremeStpPortDesignatedPort', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::Layer3::MUNGE, %SNMP::Info::MAU::MUNGE, %SNMP::Info::LLDP::MUNGE, %SNMP::Info::EDP::MUNGE, 'ex_fw_mac' => \&SNMP::Info::munge_mac, 'ps1_status_old' => \&munge_true_ok, 'ps1_status_new' => \&munge_power_stat, 'ps2_status_old' => \&munge_power_stat, 'ps2_status_new' => \&munge_power_stat, 'fan_state' => \&munge_true_ok, 'ex_vlan_untagged' => \&SNMP::Info::munge_port_list, 'ex_vlan_tagged' => \&SNMP::Info::munge_port_list, 'ex_stp_i_mac' => \&SNMP::Info::munge_prio_mac, 'stp_i_root' => \&SNMP::Info::munge_prio_mac, 'stp_p_root' => \&SNMP::Info::munge_prio_mac, 'stp_p_bridge' => \&SNMP::Info::munge_prio_mac, 'stp_p_port' => \&SNMP::Info::munge_prio_port, ); # Method OverRides *SNMP::Info::Layer3::Extreme::i_duplex = \&SNMP::Info::MAU::mau_i_duplex; *SNMP::Info::Layer3::Extreme::i_duplex_admin = \&SNMP::Info::MAU::mau_i_duplex_admin; sub model { my $extreme = shift; my $id = $extreme->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::Extreme::model() - Device does not support sysObjectID\n" if $extreme->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; return $model; } sub vendor { return 'extreme'; } sub os { my $extreme = shift; my $desc = $extreme->description(); if ( $desc =~ /xos/i ) { return 'xos'; } return 'extremeware'; } sub os_ver { my $extreme = shift; my $descr = $extreme->description(); return unless defined $descr; if ( $descr =~ m/Version\s+([^ ]+)/i ) { return $1; } return; } # # ifName is a nice concise port name on Extreme devices. # Layer3.pm defaults to i_description, which is verbose # and has spaces. However, ifName has the IP address # assigned for router interfaces, so we use ifDescr # for those. sub interfaces { my $extreme = shift; my $partial = shift; my $i_name = $extreme->orig_i_name($partial); my $i_description = $extreme->orig_i_description($partial); my $interfaces = {}; foreach my $idx ( keys %$i_name ) { if ( $i_name->{$idx} =~ /\([0-9.]+\)/ ) { $interfaces->{$idx} = $i_description->{$idx}; } else { $interfaces->{$idx} = $i_name->{$idx}; } } return $interfaces; } # # Ignore VLAN meta-interfaces and loopback sub i_ignore { my $extreme = shift; my $partial = shift; my $i_description = $extreme->i_description($partial) || {}; my %i_ignore; foreach my $if ( keys %$i_description ) { if ( $i_description->{$if} =~ /^(802.1Q Encapsulation Tag \d+|VLAN \d+|lo\d+|VirtualRouter\d+)/i ) { $i_ignore{$if}++; } } return \%i_ignore; } # When we use the extreme_fw_* objects, we're not using BRIDGE-MIB. # Either way, Extreme uses a 1:1 mapping of bridge interface ID to # ifIndex. sub bp_index { my $extreme = shift; my $bindex = $extreme->SUPER::bp_index(); return $bindex if (keys %$bindex); my $if_index = $extreme->i_index(); my %bp_index; foreach my $iid ( keys %$if_index ) { $bp_index{$iid} = $iid; } return \%bp_index; } sub munge_true_ok { my $val = shift; return unless defined($val); return "OK" if ( $val eq 'true' ); return "Not OK" if ( $val eq 'false' ); return $val; } sub munge_power_stat { my $val = shift; return unless defined($val); $val =~ s/^present//; $val =~ s/^not/Not /i; return $val; } sub ps1_status { my $extreme = shift; my $ps1_status = $extreme->ps1_status_new(); return $ps1_status || $extreme->ps1_status_old(); } sub ps2_status { my $extreme = shift; my $ps2_status = $extreme->ps2_status_new(); return $ps2_status || $extreme->ps2_status_old(); } sub fan { my $extreme = shift; my $fan_state = $extreme->fan_state(); my $ret = ""; my $s = ""; foreach my $i ( sort { $a <=> $b } keys %$fan_state ) { $ret .= $s . $i . ": " . $fan_state->{$i}; $s = ", "; } return if ( $s eq "" ); return $ret; } # For xos based VLAN functions we need to know how the ports are indexed # default is slot * 1000, but some older switches start at 1 sub _slot_factor { my $extreme = shift; my $index = $extreme->i_index(); return 1 if (exists $index->{1} && $index->{1} == 1); return 1000; } # Some versions of the Extreme firmware have vendor-specific tables # for this; those are ex_fw_*(). Some don't have these tables, # we use the BRIDGE-MIB tables if available then the ex_fw_*() methods. sub fw_mac { my $extreme = shift; my $b = $extreme->SUPER::fw_mac(); return $b if (keys %$b); return $extreme->ex_fw_mac(); } sub fw_port { my $extreme = shift; my $b = $extreme->SUPER::fw_port(); return $b if (keys %$b); return $extreme->ex_fw_port(); } sub fw_status { my $extreme = shift; my $b = $extreme->SUPER::fw_status(); return $b if (keys %$b); return $extreme->ex_fw_status(); } # Mapping the virtual VLAN interfaces: # The virtual VLAN interfaces in extremeVlanIfTable # are the higher layer above the interfaces that are # untagged, and also above an interface in # extremeVlanEncapsIfTable that does the encapsulation. # Note that it's possible to have a VLAN defined that # does not have a tag, if it has all native interfaces. # To represent this, we use a negative version of the # internal VLAN ID (the deprecated extremeVlanIfGlobalIdentifier) sub _if2tag { my $extreme = shift; my $partial = shift; my $stack = shift || $extreme->ifStackStatus($partial); my $encap_tag = $extreme->ex_vlan_encap_tag(); my $vlan_descr = $extreme->ex_vlan_descr(); my $stackmap = {}; foreach my $idx ( keys %$stack ) { my ( $higher, $lower ) = split( /\./, $idx ); $stackmap->{$higher}->{$lower} = $stack->{$idx}; } my %if2tag = (); my $missed = 0; foreach my $if ( keys %$vlan_descr ) { $if2tag{$if} = -1; foreach my $tagif ( keys %$encap_tag ) { if ( defined( $stackmap->{$if}->{$tagif} ) && $stackmap->{$if}->{$tagif} eq 'active' ) { $if2tag{$if} = $encap_tag->{$tagif}; } } if ( $if2tag{$if} == -1 ) { $missed++; } } if ($missed) { my $global_id = $extreme->ex_vlan_id(); foreach my $if ( keys %if2tag ) { $if2tag{$if} = -$global_id->{$if} if ( $if2tag{$if} == -1 && defined( $global_id->{$if} ) ); } } return \%if2tag; } # No partial support in v_name or v_index, because the obvious partial # is the VLAN ID and the index here is the ifIndex of # the VLAN interface. sub v_name { my $extreme = shift; return $extreme->ex_vlan_descr(); } sub v_index { my $extreme = shift; return $extreme->ex_vlan_id || $extreme->_if2tag(); } sub i_vlan { my $extreme = shift; my $partial = shift; # Some devices support Q-Bridge, if so short circuit and return it my $q_bridge = $extreme->SUPER::i_vlan($partial); return $q_bridge if (keys %$q_bridge); # Next we try extremeVlanOpaqueTable my $xos = $extreme->_xos_i_vlan($partial); return $xos if (keys %$xos); # Try older ifStack method my $extremeware = $extreme->_extremeware_i_vlan($partial); return $extremeware if (keys %$extremeware); return; } sub _xos_i_vlan { my $extreme = shift; my $partial = shift; my $index = $extreme->i_index(); my $vlans = $extreme->ex_vlan_id() || {}; my $slotx = $extreme->_slot_factor() || 1000; my $u_ports = $extreme->ex_vlan_untagged() || {}; my $i_vlan = {}; foreach my $idx ( keys %$u_ports ) { next unless ( defined $u_ports->{$idx} ); my $portlist = $u_ports->{$idx}; my $ret = []; my ( $vlan_if, $slot ) = $idx =~ /^(\d+)\.(\d+)/; my $vlan = $vlans->{$vlan_if} || ''; # Convert portlist bit array to bp_index array for ( my $i = 0; $i <= $#$portlist; $i++ ) { push( @{$ret}, ( $slotx * $slot + $i + 1 ) ) if ( @$portlist[$i] ); } #Create HoA ifIndex -> VLAN array foreach my $port ( @{$ret} ) { my $ifindex = $index->{$port}; next unless ( defined($ifindex) ); # shouldn't happen next if ( defined $partial and $ifindex !~ /^$partial$/ ); $i_vlan->{$ifindex} = $vlan; } } return $i_vlan; } sub _extremeware_i_vlan { my $extreme = shift; my $partial = shift; my $stack = $extreme->ifStackStatus($partial); my $encap_tag = $extreme->ex_vlan_encap_tag(); my $vlan_descr = $extreme->ex_vlan_descr(); my $stackmap = {}; foreach my $idx ( keys %$stack ) { my ( $higher, $lower ) = split( /\./, $idx ); $stackmap->{$higher}->{$lower} = $stack->{$idx}; } my $if2tag = $extreme->_if2tag( $partial, $stack ); # # Now that we've done all that mapping work, we can map the # ifStack indexes. my %i_vlan = (); foreach my $if ( keys %$if2tag ) { foreach my $lowif ( keys %{ $stackmap->{$if} } ) { $i_vlan{$lowif} = $if2tag->{$if}; } } return \%i_vlan; } sub i_vlan_membership { my $extreme = shift; my $partial = shift; # Some devices support Q-Bridge, if so short circuit and return it my $q_bridge = $extreme->SUPER::i_vlan_membership($partial); return $q_bridge if (ref {} eq ref $q_bridge and scalar keys %$q_bridge); # Next we try extremeVlanOpaqueTable my $xos = $extreme->_xos_i_vlan_membership($partial); return $xos if (ref {} eq ref $xos and scalar keys %$xos); # Try older ifStack method my $extremeware = $extreme->_extremeware_i_vlan_membership($partial); return $extremeware if (ref {} eq ref $extremeware and scalar keys %$extremeware); return; } sub _xos_i_vlan_membership { my $extreme = shift; my $partial = shift; my $index = $extreme->i_index(); my $vlans = $extreme->ex_vlan_id(); my $slotx = $extreme->_slot_factor() || 1000; my $u_ports = $extreme->ex_vlan_untagged() || {}; my $t_ports = $extreme->ex_vlan_tagged() || {}; my $i_vlan_membership = {}; foreach my $idx ( keys %$u_ports ) { next unless ( defined $u_ports->{$idx} ); my $u_portlist = $u_ports->{$idx}; my $t_portlist = $t_ports->{$idx}; my $ret = []; my ( $vlan_if, $slot ) = $idx =~ /^(\d+)\.(\d+)/; my $vlan = $vlans->{$vlan_if} || ''; foreach my $portlist ( $u_portlist, $t_portlist ) { # Convert portlist bit array to bp_index array for ( my $i = 0; $i <= $#$portlist; $i++ ) { push( @{$ret}, ( $slotx * $slot + $i + 1 ) ) if ( @$portlist[$i] ); } } #Create HoA ifIndex -> VLAN array foreach my $port ( @{$ret} ) { my $ifindex = $index->{$port}; next unless ( defined($ifindex) ); # shouldn't happen next if ( defined $partial and $ifindex !~ /^$partial$/ ); push( @{ $i_vlan_membership->{$ifindex} }, $vlan ); } } return $i_vlan_membership; } sub _extremeware_i_vlan_membership { my $extreme = shift; my $partial = shift; my $stack = $extreme->ifStackStatus($partial); my $encap_tag = $extreme->ex_vlan_encap_tag(); my $vlan_descr = $extreme->ex_vlan_descr(); my $stackmap = {}; foreach my $idx ( keys %$stack ) { my ( $higher, $lower ) = split( /\./, $idx ); $stackmap->{$higher}->{$lower} = $stack->{$idx}; } my $if2tag = $extreme->_if2tag( $partial, $stack ); # # Now that we've done all that mapping work, we can map the # ifStack indexes. my %i_vlan_membership = (); foreach my $if ( keys %$if2tag ) { foreach my $lowif ( keys %{ $stackmap->{$if} } ) { push( @{ $i_vlan_membership{$lowif} }, $if2tag->{$if} ); } } # # Now add all the tagged ports. foreach my $if ( keys %$encap_tag ) { foreach my $lowif ( keys %{ $stackmap->{$if} } ) { push( @{ $i_vlan_membership{$lowif} }, $encap_tag->{$if} ); } } return \%i_vlan_membership; } sub i_vlan_membership_untagged { my $extreme = shift; my $partial = shift; # Some devices support Q-Bridge, if so short circuit and return it my $q_bridge = $extreme->SUPER::i_vlan_membership_untagged($partial); return $q_bridge if (ref {} eq ref $q_bridge and scalar keys %$q_bridge); # Next we try extremeVlanOpaqueTable my $xos = $extreme->_xos_i_vlan_membership_untagged($partial); return $xos if (ref {} eq ref $xos and scalar keys %$xos); # Try older ifStack method my $extremeware = $extreme->_extremeware_i_vlan_membership_untagged($partial); return $extremeware if (ref {} eq ref $extremeware and scalar keys %$extremeware); return; } sub _xos_i_vlan_membership_untagged { my $extreme = shift; my $partial = shift; my $index = $extreme->i_index(); my $vlans = $extreme->ex_vlan_id(); my $slotx = $extreme->_slot_factor() || 1000; my $u_ports = $extreme->ex_vlan_untagged() || {}; my $i_vlan_membership = {}; foreach my $idx ( keys %$u_ports ) { next unless ( defined $u_ports->{$idx} ); my $u_portlist = $u_ports->{$idx}; my $ret = []; my ( $vlan_if, $slot ) = $idx =~ /^(\d+)\.(\d+)/; my $vlan = $vlans->{$vlan_if} || ''; foreach my $portlist ( $u_portlist ) { # Convert portlist bit array to bp_index array for ( my $i = 0; $i <= $#$portlist; $i++ ) { push( @{$ret}, ( $slotx * $slot + $i + 1 ) ) if ( @$portlist[$i] ); } } #Create HoA ifIndex -> VLAN array foreach my $port ( @{$ret} ) { my $ifindex = $index->{$port}; next unless ( defined($ifindex) ); # shouldn't happen next if ( defined $partial and $ifindex !~ /^$partial$/ ); push( @{ $i_vlan_membership->{$ifindex} }, $vlan ); } } return $i_vlan_membership; } # Assuming Cisco-like trunk behavior that native VLAN is transmitted untagged sub _extremeware_i_vlan_membership_untagged { my $extreme = shift; my $partial = shift; my $vlans = $extreme->_extremeware_i_vlan($partial); my $i_vlan_membership = {}; foreach my $port (keys %$vlans) { my $vlan = $vlans->{$port}; push( @{ $i_vlan_membership->{$port} }, $vlan ); } return $i_vlan_membership; } # VLAN management. # See extreme-vlan.mib for a detailed description of # Extreme's use of ifStackTable and EXTREME-VLAN-MIB. sub set_i_vlan { my $extreme = shift; return $extreme->_extreme_set_i_vlan( 0, @_ ); } sub set_i_pvid { my $extreme = shift; return $extreme->_extreme_set_i_vlan( 1, @_ ); } # set_i_vlan implicitly turns off any encapsulation # set_i_pvid retains any encapsulation # otherwise they do the same: set the unencapsulated # vlan ID. # First arg to _set_i_vlan is whether or not to turn # off any encapsulation. sub _extreme_set_i_vlan { my $extreme = shift; my ( $is_pvid, $vlan_id, $ifindex ) = @_; my $encap_tag = $extreme->ex_vlan_encap_tag(); # The inverted stack MIB would make this easier, since # we need to find the vlan interface # that's stacked above $ifindex. my $cur_stack = $extreme->ifStackStatus(); # # create inverted stack my $invstack; foreach my $idx ( keys %$cur_stack ) { my ( $higher, $lower ) = split( /\./, $idx ); $invstack->{$lower}->{$higher} = $cur_stack->{$idx}; } # create vlan tag -> encap interface map my %encapif = reverse %$encap_tag; # now find encap interface from tag my $encapidx = $encapif{$vlan_id}; if ( !defined($encapidx) ) { $extreme->error_throw( "can't map $vlan_id to encapsulation interface"); return; } # now find vlan interface stacked above encap my @abovevlan = keys %{ $invstack->{$encapidx} }; if ( @abovevlan != 1 ) { $extreme->error_throw( "can't map encap interface $encapidx for $vlan_id to encapsulation interface" ); return; } my $vlanidx = $abovevlan[0]; my $rv; # Delete old VLAN mapping foreach my $oldidx ( keys %{ $invstack->{$ifindex} } ) { if ( $is_pvid && defined( $encap_tag->{$oldidx} ) ) { next; # Don't delete tagged mappings } $rv = $extreme->set_ifStackStatus( "destroy", $oldidx . "." . $ifindex ); unless ($rv) { $extreme->error_throw( "Unable to remove $ifindex from old VLAN index $oldidx"); return; } } # Add new VLAN mapping $rv = $extreme->set_ifStackStatus( "createAndGo", $vlanidx . "." . $ifindex ); unless ($rv) { $extreme->error_throw( "Unable to add new VLAN index $vlanidx to ifIndex $ifindex"); return; } # XXX invalidate cache of ifstack? # XXX Info.pm library function for this? # XXX set_ should do invalidation? # $store = $extreme->store(); delete $store->{ifStackStatus}; $extreme->store($store); # $extreme->{_ifStackStatus} = 0; return $rv; } sub set_remove_i_vlan_tagged { my $extreme = shift; my ( $vlan_id, $ifindex ) = @_; my $encap_tag = $extreme->ex_vlan_encap_tag(); # create vlan tag -> encap interface map my %encapif = reverse %$encap_tag; # now find encap interface from tag my $encapidx = $encapif{$vlan_id}; if ( !defined($encapidx) ) { $extreme->error_throw( "can't map $vlan_id to encapsulation interface"); return; } my $rv = $extreme->set_ifStackStatus( "destroy", $encapidx . "." . $ifindex ); unless ($rv) { $extreme->error_throw( "Unable to delete VLAN encap ifIndex $encapidx for VLAN $vlan_id from ifIndex $ifindex" ); return; } # invalidate cache of ifstack? return $rv; } sub set_add_i_vlan_tagged { my $extreme = shift; my ( $vlan_id, $ifindex ) = @_; my $encap_tag = $extreme->ex_vlan_encap_tag(); # create vlan tag -> encap interface map my %encapif = reverse %$encap_tag; # now find encap interface from tag my $encapidx = $encapif{$vlan_id}; if ( !defined($encapidx) ) { $extreme->error_throw( "can't map $vlan_id to encapsulation interface"); return; } my $rv = $extreme->set_ifStackStatus( "createAndGo", $encapidx . "." . $ifindex ); unless ($rv) { $extreme->error_throw( "Unable to add VLAN encap ifIndex $encapidx for VLAN $vlan_id to ifIndex $ifindex" ); return; } # invalidate cache of ifstack? return $rv; } # LLDP uses the bridge index rather than ifIndex sub lldp_if { my $extreme = shift; my $partial = shift; my $addr = $extreme->lldp_rem_pid($partial) || {}; my $b_index = $extreme->bp_index() || {}; #my %r_i_descr = reverse %$i_descr; my %lldp_if; foreach my $key ( keys %$addr ) { my @aOID = split( '\.', $key ); my $port = $aOID[1]; next unless $port; my $idx = $b_index->{$port}; $lldp_if{$key} = $idx; } return \%lldp_if; } # extremeStpDomainStpdInstance not accessible, so we need to extract from iid sub stp_i_id { my $extreme = shift; my $partial = shift; my $stp_i_roots = $extreme->stp_i_root($partial); my %stp_i_id; foreach my $iid ( keys %$stp_i_roots ) { $stp_i_id{$iid} = $iid; } return \%stp_i_id; } # extremeStpDomainBridgeId returns priority and mac, # for cross class compatibility we just need mac sub stp_i_mac { my $extreme = shift; my $partial = shift; my $stp_i_bids = $extreme->ex_stp_i_mac($partial); my %stp_i_mac; foreach my $iid ( keys %$stp_i_bids ) { my $mac = $stp_i_bids->{$iid}; next unless $mac; $mac =~ s/^([0-9A-F][0-9A-F]:){2}//; $stp_i_mac{$iid} = $mac; } return \%stp_i_mac; } # Break up the extremeStpPortEntry INDEX into Stpd Instance and IfIndex. sub _ex_stpport_index { my $idx = shift; my ( $id, $ifindex ) = split( /\./, $idx); return ($id, $ifindex); } # extremeStpPortPortIfIndex not-accessible, extract from iid sub stp_p_id { my $extreme = shift; my $partial = shift; my $stp_port = $extreme->stp_p_root($partial); my $stp_p_id = {}; foreach my $idx ( keys %$stp_port ) { my ( $id, $ifindex ) = _ex_stpport_index($idx); $stp_p_id->{$idx} = $ifindex; } return $stp_p_id; } # extremeStpDomainStpdInstance not-accessible, extract from iid sub stp_p_stg_id { my $extreme = shift; my $partial = shift; my $stp_port = $extreme->stp_p_root($partial); my $stp_p_stg_id = {}; foreach my $idx ( keys %$stp_port ) { my ( $id, $ifindex ) = _ex_stpport_index($idx); $stp_p_stg_id->{$idx} = $id; } return $stp_p_stg_id; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Extreme - Perl5 Interface to Extreme Network Devices =head1 AUTHOR Eric Miller, Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $extreme = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $extreme->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from an Extreme device through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $extreme = new SNMP::Info::Layer3::Extreme(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::MAU =item SNMP::Info::LLDP =item SNMP::Info::EDP =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =item Inherited Classes' MIBs See classes listed above for their required MIBs. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $extreme->model() Returns model type. Checks $extreme->id() against the F. =item $extreme->vendor() Returns extreme =item $extreme->os() Returns extreme =item $extreme->os_ver() Parses device operating system version from description() =item $extreme->serial() Returns serial number (C) =item $extreme->temp() Returns system temperature (C) =item $extreme->ps1_status() Returns status of power supply 1 (C) =item $extreme->ps2_status() Returns status of power supply 2 (C) =item $extreme->fan() Returns fan status (C) =item $extreme->mac() Returns base mac (C) =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Globals imported from SNMP::Info::MAU See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head2 Globals imported from SNMP::Info::EDP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $extreme->interfaces() Returns a mapping between the Interface Table Index (iid) and the physical port name. =item $extreme->i_duplex() Parses mau_index and mau_link to return the duplex information for interfaces. =item $extreme->i_duplex_admin() Parses C,C,C in order to find the admin duplex setting for all the interfaces. Returns either (auto,full,half). =item $extreme->i_ignore() Returns reference to hash. Increments value of IID if port is to be ignored. Ignores VLAN meta interfaces and loopback =item $extreme->fw_mac() (C) =item $extreme->fw_port() (C) =item $extreme->fw_status() (C) =item $extreme->lldp_if() Returns the mapping to the SNMP Interface Table. Extreme LLDP uses the bridge index rather than ifIndex. =item $extreme->i_vlan() Returns a mapping between C and the VLAN. =item $extreme->i_vlan_membership() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the egress list for the port. Example: my $interfaces = $extreme->interfaces(); my $vlans = $extreme->i_vlan_membership(); foreach my $iid (sort keys %$interfaces) { my $port = $interfaces->{$iid}; my $vlan = join(',', sort(@{$vlans->{$iid}})); print "Port: $port VLAN: $vlan\n"; } =item $extreme->i_vlan_membership_untagged() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port. =item $extreme->v_index() Returns VLAN IDs =item $extreme->v_name() Returns VLAN names (C) =item $extreme->bp_index() Returns reference to hash of bridge port table entries map back to interface identifier (iid) Returns (C) for both key and value since we're using F rather than F. =item $extreme->peth_port_power() Power supplied by PoE ports, in milliwatts (C) =item $extreme->peth_power_watts() The configured maximum amount of in-line power available to the slot. (C) =back =head2 Spanning Tree Instance Globals =over =item $extreme->stp_i_mac() Returns the MAC extracted from (C). =item $extreme->stp_i_id() Returns the unique identifier of the STP domain. (C) =item $extreme->stp_i_time() Returns time since last topology change detected. (100ths/second) (C) =item $extreme->stp_i_time() Returns time since last topology change detected. (100ths/second) (C) =item $extreme->stp_i_time() Returns the total number of topology changes detected. (C) =item $extreme->stp_i_root() Returns root of STP. (C) =item $extreme->stp_i_root_port() Returns the port number of the port that offers the lowest cost path to the root bridge. (C) =item $extreme->stp_i_priority() Returns the port number of the port that offers the lowest cost path to the root bridge. (C) =back =head2 Spanning Tree Protocol Port Table =over =item $extreme->stp_p_id() (C) =item $extreme->stp_p_stg_id() (C) =item $extreme->stp_p_priority() (C) =item $extreme->stp_p_state() (C) =item $extreme->stp_p_cost() (C) =item $extreme->stp_p_root() (C) =item $extreme->stp_p_bridge() (C) =item $extreme->stp_p_port() (C) =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::EDP See documentation in L for details. =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =over =item $extreme->set_i_vlan ( vlan, ifIndex ) Changes an access (untagged) port VLAN, must be supplied with the numeric VLAN ID and port C. This method should only be used on end station (non-trunk) ports. Example: my %if_map = reverse %{$extreme->interfaces()}; $extreme->set_i_vlan('2', $if_map{'FastEthernet0/1'}) or die "Couldn't change port VLAN. ",$extreme->error(1); =item $extreme->set_i_pvid ( pvid, ifIndex ) Sets port default VLAN, must be supplied with the numeric VLAN ID and port C. This method should only be used on trunk ports. Example: my %if_map = reverse %{$extreme->interfaces()}; $extreme->set_i_pvid('2', $if_map{'FastEthernet0/1'}) or die "Couldn't change port default VLAN. ",$extreme->error(1); =item $extreme->set_add_i_vlan_tagged ( vlan, ifIndex ) Adds the VLAN to the enabled VLANs list of the port, must be supplied with the numeric VLAN ID and port C. Example: my %if_map = reverse %{$extreme->interfaces()}; $extreme->set_add_i_vlan_tagged('2', $if_map{'FastEthernet0/1'}) or die "Couldn't add port to egress list. ",$extreme->error(1); =item $extreme->set_remove_i_vlan_tagged ( vlan, ifIndex ) Removes the VLAN from the enabled VLANs list of the port, must be supplied with the numeric VLAN ID and port C. Example: my %if_map = reverse %{$extreme->interfaces()}; $extreme->set_remove_i_vlan_tagged('2', $if_map{'FastEthernet0/1'}) or die "Couldn't add port to egress list. ",$extreme->error(1); =back =head1 Data Munging Callback Subroutines =over =item $extreme->munge_power_stat() Removes 'present' and changes 'not' to 'Not' in the front of a string. =item $extreme->munge_true_ok() Replaces 'true' with "OK" and 'false' with "Not OK". =back =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/F5.pm000444000765000024 2664113215550564 17263 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::F5 # # Copyright (c) 2012 Eric Miller # All Rights Reserved # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::F5; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::F5::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::F5::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'F5-BIGIP-SYSTEM-MIB' => 'sysAttrArpMaxEntries', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, 'os_ver' => 'sysProductVersion', 'mkt_name' => 'sysPlatformInfoMarketingName', 'ps1_status' => 'sysChassisPowerSupplyStatus.1', 'ps2_status' => 'sysChassisPowerSupplyStatus.2', # Named serial1 to override serial1 in L3 serial method 'serial1' => 'sysGeneralChassisSerialNum', 'qb_vlans' => 'sysVlanNumber', 'ports' => 'sysInterfaceNumber', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, # sysInterfaceTable 'i_index' => 'sysInterfaceName', 'i_description' => 'sysInterfaceName', 'i_mtu' => 'sysInterfaceMtu', 'i_speed' => 'sysInterfaceMediaActiveSpeed', 'i_mac' => 'sysInterfaceMacAddr', 'i_up_admin' => 'sysInterfaceEnabled', 'i_up' => 'sysInterfaceStatus', # sysIfxStatTable 'i_octet_in64' => 'sysIfxStatHcInOctets', 'i_octet_out64' => 'sysIfxStatHcOutOctets', 'i_pkts_ucast_in64' => 'sysIfxStatHcInUcastPkts', 'i_pkts_ucast_out64' => 'sysIfxStatHcOutUcastPkts', 'i_pkts_mutli_in64' => 'sysIfxStatInMulticastPkts', 'i_pkts_multi_out64' => 'sysIfxStatOutMulticastPkts', 'i_pkts_bcast_in64' => 'sysIfxStatInBroadcastPkts', 'i_pkts_bcast_out64' => 'sysIfxStatOutBroadcastPkts', # sysInterfaceStatTable 'i_discards_in' => 'sysInterfaceStatDropsIn', 'i_discards_out' => 'sysInterfaceStatDropsOut', 'i_errors_in' => 'sysInterfaceStatErrorsIn', 'i_errors_out' => 'sysInterfaceStatErrorsOut', # sysInterfaceTable 'sys_i_duplex' => 'sysInterfaceMediaActiveDuplex', # sysChassisFanTable 'fan_state' => 'sysChassisFanStatus', # sysVlanTable 'sys_v_id' => 'sysVlanId', 'v_name' => 'sysVlanVname', # sysVlanMemberTable 'sys_vm_tagged' => 'sysVlanMemberTagged', 'sys_vm_name' => 'sysVlanMemberVmname', 'sys_vmp_name' => 'sysVlanMemberParentVname', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'f5'; } sub os { return 'f5'; } sub fan { my $f5 = shift; my $fan_state = $f5->fan_state(); my $ret = ""; my $s = ""; foreach my $i ( sort { $a <=> $b } keys %$fan_state ) { $ret .= $s . $i . ': ' . $fan_state->{$i}; $s = ', '; } return if ( $s eq "" ); return $ret; } sub model { my $f5 = shift; my $name = $f5->mkt_name(); if ( defined $name ) { return $name; } my $id = $f5->id(); my $model = &SNMP::translateObj($id); if ( !defined $model ) { return $id; } return $model; } # Override L3 interfaces sub interfaces { my $f5 = shift; my $partial = shift; return $f5->i_index($partial); } # Override L3 i_name sub i_name { my $f5 = shift; my $partial = shift; return $f5->i_index($partial); } # We don't have this, so fake it sub i_type { my $f5 = shift; my $partial = shift; my $idx = $f5->i_index($partial); my %i_type; foreach my $if ( keys %$idx ) { $i_type{$if} = ((exists $f5->{sess}->{UseEnums} and $f5->{sess}->{UseEnums}) ? 'ethernetCsmacd' : 6 ); } return \%i_type; } # Override L3 i_duplex sub i_duplex { my $f5 = shift; my $partial = shift; my $duplexes = $f5->sys_i_duplex() || {}; my %i_duplex; foreach my $if ( keys %$duplexes ) { my $duplex = $duplexes->{$if}; next unless defined $duplex; next if ( $duplex eq 'none' ); $i_duplex{$if} = $duplex; } return \%i_duplex; } # Override Bridge v_index sub v_index { my $f5 = shift; my $partial = shift; return $f5->sys_v_id($partial); } sub i_vlan { my $f5 = shift; my $partial = shift; my $index = $f5->i_index($partial) || {}; my $tagged = $f5->sys_vm_tagged() || {}; my $vlans = $f5->v_index() || {}; my $i_vlan = {}; foreach my $iid ( keys %$tagged ) { my $tag = $tagged->{$iid}; next if ( $tag eq 'true' ); # IID is length.vlan name index.length.interface index # Split out and use as the IID to get the VLAN ID and ifIndex my @iid_array = split /\./, $iid; my $len = $iid_array[0]; my $v_idx = join '.', ( splice @iid_array, 0, $len + 1 ); my $idx = join '.', @iid_array; # Check to make sure we can map to a port my $p_idx = $index->{$idx}; next unless $p_idx; my $vlan = $vlans->{$v_idx}; next unless $vlan; $i_vlan->{$idx} = $vlan; } return $i_vlan; } sub i_vlan_membership { my $f5 = shift; my $partial = shift; my $index = $f5->i_index($partial) || {}; my $tagged = $f5->sys_vm_tagged() || {}; my $vlans = $f5->v_index() || {}; my $i_vlan_membership = {}; foreach my $iid ( keys %$tagged ) { # IID is length.vlan name index.length.interface index # Split out and use as the IID to get the VLAN ID and ifIndex my @iid_array = split /\./, $iid; my $len = $iid_array[0]; my $v_idx = join '.', ( splice @iid_array, 0, $len + 1 ); my $idx = join '.', @iid_array; # Check to make sure we can map to a port my $p_idx = $index->{$idx}; next unless $p_idx; my $vlan = $vlans->{$v_idx}; next unless $vlan; push( @{ $i_vlan_membership->{$idx} }, $vlan ); } return $i_vlan_membership; } sub i_vlan_membership_untagged { my $f5 = shift; my $partial = shift; my $index = $f5->i_index($partial) || {}; my $tagged = $f5->sys_vm_tagged() || {}; my $vlans = $f5->v_index() || {}; my $i_vlan_membership = {}; foreach my $iid ( keys %$tagged ) { next unless $tagged->{$iid} eq 'false'; # IID is length.vlan name index.length.interface index # Split out and use as the IID to get the VLAN ID and ifIndex my @iid_array = split /\./, $iid; my $len = $iid_array[0]; my $v_idx = join '.', ( splice @iid_array, 0, $len + 1 ); my $idx = join '.', @iid_array; # Check to make sure we can map to a port my $p_idx = $index->{$idx}; next unless $p_idx; my $vlan = $vlans->{$v_idx}; next unless $vlan; push( @{ $i_vlan_membership->{$idx} }, $vlan ); } return $i_vlan_membership; } 1; __END__ =head1 NAME SNMP::Info::Layer3::F5 - SNMP Interface to F5 network devices. =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $f5 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $f5->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for F5 network devices. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $f5 = new SNMP::Info::Layer3::F5(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $f5->model() Return (C), otherwise tries to reference $f5->id() to F. =item $f5->vendor() Returns 'f5' =item $f5->os() Returns 'f5' =item $f5->os_ver() Returns the software version reported by C =item $f5->fan() Combines (C) into a single string. =item $f5->ps1_status() Returns status of primary power supply =item $f5->ps2_status() Returns status of redundant power supply =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $f5->interfaces() Returns reference to the map between IID and physical port. (C). =item $f5->i_duplex() Returns reference to hash. Maps port operational duplexes to IIDs. =item $f5->i_vlan() Returns a mapping between C and the default VLAN. =item $f5->i_vlan_membership() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. Example: my $interfaces = $f5->interfaces(); my $vlans = $f5->i_vlan_membership(); foreach my $iid (sort keys %$interfaces) { my $port = $interfaces->{$iid}; my $vlan = join(',', sort(@{$vlans->{$iid}})); print "Port: $port VLAN: $vlan\n"; } =item $f5->i_vlan_membership_untagged() Returns reference to hash of arrays: key = C, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port. =item $f5->v_index() Returns VLAN IDs =item $f5->v_name() Human-entered name for vlans. =item $f5->i_name() Returns the human set port name if exists. =item $f5->i_type() Returns C<'ethernetCsmacd'> for each C. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Force10.pm000444000765000024 1643613215550564 20211 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Force10 # $Id$ # # Copyright (c) 2012 William Bulley # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Force10; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::MAU; use SNMP::Info::LLDP; @SNMP::Info::Layer3::Force10::ISA = qw/SNMP::Info::LLDP SNMP::Info::MAU SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Force10::EXPORT_OK = qw//; use vars qw/$VERSION $DEBUG %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::MAU::MIBS, %SNMP::Info::LLDP::MIBS, 'F10-PRODUCTS-MIB' => 'f10Products', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::MAU::GLOBALS, %SNMP::Info::LLDP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::MAU::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::MAU::MUNGE, %SNMP::Info::LLDP::MUNGE, ); # use MAU-MIB for admin. duplex and admin. speed *SNMP::Info::Layer3::Force10::i_duplex_admin = \&SNMP::Info::MAU::mau_i_duplex_admin; *SNMP::Info::Layer3::Force10::i_speed_admin = \&SNMP::Info::MAU::mau_i_speed_admin; sub vendor { return 'force10'; } sub os { return 'ftos'; } sub os_ver { my $force10 = shift; my $descr = $force10->description(); my $os_ver = undef; $os_ver = $1 if ( $descr =~ /Force10\s+Application\s+Software\s+Version:\s+(\S+)/s ); return $os_ver; } sub model { my $force10 = shift; my $id = $force10->id(); my $model = &SNMP::translateObj($id); return $id unless defined $model; return $model; } sub v_name { my $force10 = shift; my $partial = shift; return $force10->qb_v_name($partial); } # ------------------- stub for now----------------- sub i_vlan { my $force10 = shift; my $partial = shift; my $i_vlan = {}; return $i_vlan; } # Apparently index doesn't use VLAN ID, so override the HOA private # method here to correct the mapping sub _vlan_hoa { my $force10 = shift; my ( $v_ports, $partial ) = @_; my $index = $force10->bp_index(); my $v_index = $force10->v_index(); my $vlan_hoa = {}; foreach my $idx ( sort keys %{$v_ports} ) { next unless ( defined $v_ports->{$idx} ); my $portlist = $v_ports->{$idx}; # is an array reference my $ret = []; my $vlan_ndx = $idx; # Strip TimeFilter if we're using VlanCurrentTable ( $vlan_ndx = $idx ) =~ s/^\d+\.//; # Convert portlist bit array to bp_index array for ( my $i = 0; $i <= $#$portlist; $i++ ) { push( @{$ret}, $i + 1 ) if ( @$portlist[$i] ); } #Create HoA ifIndex -> VLAN array foreach my $port ( @{$ret} ) { my $ifindex = $index->{$port}; next unless ( defined($ifindex) ); # shouldn't happen next if ( defined $partial and $ifindex !~ /^$partial$/ ); my $vlan_tag = $v_index->{$vlan_ndx}; # FIXME: would be preferable to use # the mapping from Q-BRIDGE-MIB::dot1qVlanFdbId my $mod = $vlan_tag % 4096; push ( @{ $vlan_hoa->{$ifindex} }, ($mod) ); } } return $vlan_hoa; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Force10 - SNMP Interface to Force10 Networks FTOS =head1 AUTHOR William Bulley =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $force10 = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $force10->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Force10 Networks FTOS-based devices. =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::MAU =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar values from SNMP: =over =item $force10->vendor() Returns C<'force10'> =item $force10->model() Tries to reference $force10->id() to the Force10 product MIB listed above. =item $force10->os() Returns C<'ftos'>. =item $force10->os_ver() Grabs the operating system version from C =back =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::MAU See documentation in L for details. =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $force10->v_name() Returns the VLAN names. =item $force10->i_vlan() Currently not implemented. =item $force10->i_duplex_admin() Returns info from F =item $force10->i_speed_admin() Returns info from F =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Fortinet.pm000444000765000024 1113113215550564 20567 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Fortinet # # Copyright (c) 2014 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Fortinet; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Fortinet::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Fortinet::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'FORTINET-CORE-MIB' => 'fnSysSerial', 'FORTINET-FORTIGATE-MIB' => 'fgVdMaxVdoms', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'fortinet'; } sub model { my $fortinet = shift; my $id = $fortinet->id() || ''; my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^f[grsw][tfw]?//i; return $model; } sub os { return 'fortios'; } sub os_ver { my $fortinet = shift; my $ver = $fortinet->fgSysVersion() || ''; if ( $ver =~ /(\d+[\.\d]+)/ ) { return $1; } return $ver; } sub serial { my $fortinet = shift; return $fortinet->fnSysSerial(); } 1; __END__ =head1 NAME SNMP::Info::Layer3::Fortinet - SNMP Interface to Fortinet network devices. =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $fortinet = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $fortinet->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Fortinet network devices. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $fortinet = new SNMP::Info::Layer3::Fortinet(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $fortinet->vendor() Returns 'fortinet' =item $fortinet->model() Returns the chassis model. =item $fortinet->os() Returns 'fortios' =item $fortinet->os_ver() Returns the software version extracted from (C). =item $fortinet->serial() Returns the chassis serial number. (C) =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Foundry.pm000444000765000024 7654413215550564 20446 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Foundry - SNMP Interface to Foundry devices # $Id$ # # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. # # Copyright (c) 2002,2003 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Foundry; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::FDP; use SNMP::Info::LLDP; @SNMP::Info::Layer3::Foundry::ISA = qw/ SNMP::Info::FDP SNMP::Info::LLDP SNMP::Info::Layer3 Exporter /; @SNMP::Info::Layer3::Foundry::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::FDP::MIBS, 'FOUNDRY-SN-ROOT-MIB' => 'foundry', 'FOUNDRY-SN-AGENT-MIB' => 'snChasPwrSupplyDescription', 'FOUNDRY-SN-SWITCH-GROUP-MIB' => 'snSwGroupOperMode', 'FOUNDRY-SN-STACKING-MIB' => 'snStackingOperUnitRole', 'FOUNDRY-POE-MIB' => 'snAgentPoeGblPowerCapacityTotal', 'FOUNDRY-SN-SWITCH-GROUP-MIB' => 'snSwGroupOperMode', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, %SNMP::Info::FDP::GLOBALS, 'mac' => 'ifPhysAddress.1', 'chassis' => 'entPhysicalDescr.1', 'temp' => 'snChasActualTemperature', 'ps1_type' => 'snChasPwrSupplyDescription.1', 'ps1_status' => 'snChasPwrSupplyOperStatus.1', 'fan' => 'snChasFanOperStatus.1', 'img_ver' => 'snAgImgVer', 'ch_serial' => 'snChasSerNum', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, %SNMP::Info::FDP::FUNCS, # FOUNDRY-SN-SWITCH-GROUP-MIB # snSwPortInfoTable - Switch Port Information Group 'sw_index' => 'snSwPortIfIndex', 'sw_duplex' => 'snSwPortInfoChnMode', 'sw_type' => 'snSwPortInfoMediaType', 'sw_speed' => 'snSwPortInfoSpeed', # FOUNDRY-SN-AGENT-MIB::snAgentConfigModule2Table 'ag_mod2_type' => 'snAgentConfigModule2Type', # FOUNDRY-SN-AGENT-MIB::snAgentConfigModuleTable 'ag_mod_type' => 'snAgentConfigModuleType', # FOUNDRY-SN-AGENT-MIB::snVLanByPortTable 'stp_i_id' => 'snVLanByPortVLanId', 'stp_i_mac' => 'snVLanByPortBaseBridgeAddress', 'stp_i_time' => 'snVLanByPortStpTimeSinceTopologyChange', 'stp_i_ntop' => 'snVLanByPortStpTopChanges', 'stp_i_root' => 'snVLanByPortStpDesignatedRoot', 'stp_i_root_port' => 'snVLanByPortStpRootPort', 'stp_i_priority' => 'snVLanByPortStpPriority', # FOUNDRY-SN-AGENT-MIB::snPortStpTable 'stp_p_id' => 'snPortStpPortNum', 'stp_p_stg_id' => 'snPortStpVLanId', 'stp_p_priority' => 'snPortStpPortPriority', 'stp_p_state' => 'snPortStpPortState', 'stp_p_cost' => 'snPortStpPortDesignatedCost', 'stp_p_root' => 'snPortStpPortDesignatedRoot', 'stp_p_bridge' => 'snPortStpPortDesignatedBridge', 'stp_p_port' => 'snPortStpPortDesignatedPort', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, %SNMP::Info::FDP::MUNGE, 'ag_mod2_type' => \&SNMP::Info::munge_e_type, 'ag_mod_type' => \&SNMP::Info::munge_e_type, 'stp_i_mac' => \&SNMP::Info::munge_mac, 'stp_i_root' => \&SNMP::Info::munge_prio_mac, 'stp_p_root' => \&SNMP::Info::munge_prio_mac, 'stp_p_bridge' => \&SNMP::Info::munge_prio_mac, 'stp_p_port' => \&SNMP::Info::munge_prio_port, ); sub i_ignore { my $foundry = shift; my $partial = shift; my $interfaces = $foundry->interfaces($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { if ( $interfaces->{$if} =~ /(tunnel|loopback|\blo\b|lb|null)/i ) { $i_ignore{$if}++; } } return \%i_ignore; } sub i_duplex { my $foundry = shift; my $partial = shift; my $sw_index = $foundry->sw_index($partial); my $sw_duplex = $foundry->sw_duplex($partial); unless ( defined $sw_index and defined $sw_duplex ) { return $foundry->SUPER::i_duplex(); } my %i_duplex; foreach my $sw_port ( keys %$sw_duplex ) { my $iid = $sw_index->{$sw_port}; my $duplex = $sw_duplex->{$sw_port}; next if $duplex =~ /none/i; $i_duplex{$iid} = 'half' if $duplex =~ /half/i; $i_duplex{$iid} = 'full' if $duplex =~ /full/i; } return \%i_duplex; } sub model { my $foundry = shift; my $id = $foundry->id(); my $model = &SNMP::translateObj($id); # EdgeIron if ( $id =~ /\.1991\.1\.[45]\./ ) { my $e_name = $foundry->e_name(); # Find entity table entry for "unit.1" my $unit_iid = undef; foreach my $e ( keys %$e_name ) { my $name = $e_name->{$e} || ''; $unit_iid = $e if $name eq 'unit.1'; } # Find Model Name my $e_model = $foundry->e_model(); if ( defined $e_model->{$unit_iid} ) { return $e_model->{$unit_iid}; } } return $id unless defined $model; $model =~ s/^sn//; $model =~ s/Switch//; return $model; } sub os { return 'brocade'; } sub vendor { return 'brocade'; } sub os_ver { my $foundry = shift; return $foundry->img_ver() if ( defined $foundry->img_ver() ); # Some older ones don't have this value,so we cull it from the description my $descr = $foundry->description(); if ( $descr =~ m/Version (\d\S*)/ ) { return $1; } # EdgeIron my $e_name = $foundry->e_name(); # find entity table entry for "stackmanaget.1" my $unit_iid = undef; foreach my $e ( keys %$e_name ) { my $name = $e_name->{$e} || ''; $unit_iid = $e if $name eq 'stackmanaget.1'; } if ( defined $unit_iid ) { # Find Model Name my $e_fwver = $foundry->e_fwver(); if ( defined $e_fwver->{$unit_iid} ) { return $e_fwver->{$unit_iid}; } } # See if we report from Flash if wouldn't report from running above return $foundry->snAgFlashImgVer() if ( defined $foundry->snAgFlashImgVer() ); # Last resort return $foundry->SUPER::os_ver(); } sub serial { my $foundry = shift; # Return chassis serial number if available return $foundry->ch_serial() if ( $foundry->ch_serial() ); # If no chassis serial use first module serial my $mod_serials = $foundry->snAgentConfigModuleSerialNumber() || {}; foreach my $mod ( sort keys %$mod_serials ) { my $serial = $mod_serials->{$mod} || ''; next unless defined $serial; return $serial; } # EdgeIron my $e_name = $foundry->e_name(); # find entity table entry for "unit.1" my $unit_iid = undef; foreach my $e ( keys %$e_name ) { my $name = $e_name->{$e} || ''; $unit_iid = $e if $name eq 'unit.1'; } if ( defined $unit_iid ) { # Look up serial of found entry. my $e_serial = $foundry->e_serial(); return $e_serial->{$unit_iid} if defined $e_serial->{$unit_iid}; } # Last resort return $foundry->SUPER::serial(); } sub interfaces { my $foundry = shift; my $partial = shift; my $i_descr = $foundry->i_description($partial) || {}; my $i_name = $foundry->i_name($partial) || {}; # Use ifName for EdgeIrons else use ifDescr foreach my $iid ( keys %$i_name ) { my $name = $i_name->{$iid}; next unless defined $name; $i_descr->{$iid} = $name if $name =~ /^port\d+/i; } return $i_descr; } # Entity MIB is supported on the Brocade NetIron XMR, NetIron MLX, MLXe, # NetIron CES, NetIron CER, and older EdgeIron series devices. # Try Entity MIB methods first and fall back to Pseudo ENTITY-MIB methods for # other devices. # e_fwver, e_hwver, e_swver not supported in psuedo methods, no need to # override sub e_index { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_index($partial) || $foundry->brcd_e_index($partial); } sub e_class { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_class($partial) || $foundry->brcd_e_class($partial); } sub e_descr { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_descr($partial) || $foundry->brcd_e_descr($partial); } sub e_name { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_name($partial) || $foundry->brcd_e_name($partial); } sub e_parent { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_parent($partial) || $foundry->brcd_e_parent($partial); } sub e_pos { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_pos($partial) || $foundry->brcd_e_pos($partial); } sub e_serial { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_serial($partial) || $foundry->brcd_e_serial($partial); } sub e_type { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_type($partial) || $foundry->brcd_e_type($partial); } sub e_vendor { my $foundry = shift; my $partial = shift; return $foundry->SUPER::e_vendor($partial) || $foundry->brcd_e_vendor($partial); } # Pseudo ENTITY-MIB methods # This class supports both stackable and chassis based switches, identify if # we have a stackable so that we return appropriate entPhysicalClass # Identify if the stackable is actually a stack vs. single switch sub _brcd_stack_master { my $foundry = shift; my $roles = $foundry->snStackingOperUnitRole() || {}; foreach my $iid ( keys %$roles ) { my $role = $roles->{$iid}; next unless $role; if ( $role eq 'active' ) { return $iid; } } return; } sub brcd_e_index { my $foundry = shift; my $partial = shift; my $stack_master = $foundry->_brcd_stack_master(); my $brcd_e_idx = $foundry->snAgentConfigModule2Description($partial) || $foundry->snAgentConfigModuleDescription($partial) || {}; my %brcd_e_index; if ($stack_master) { # Stack Entity $brcd_e_index{0} = 1; } foreach my $iid ( keys %$brcd_e_idx ) { my $index = $iid; # Format into consistent integer format so that numeric sorting works if ( $iid =~ /(\d+)\.(\d+)/ ) { $index = "$1" . sprintf "%02d", $2; } $brcd_e_index{$iid} = $index; } return \%brcd_e_index; } sub brcd_e_class { my $foundry = shift; my $partial = shift; my $e_idx = $foundry->brcd_e_index($partial) || {}; my %e_class; foreach my $iid ( keys %$e_idx ) { if ( $iid == 0 ) { $e_class{$iid} = 'stack'; } # Were going to assume chassis at slot/index 1 # If this turns out to be false in some cases we can check # snAgentConfigModuleNumberOfCpus as other modules won't have cpus? elsif ( $iid =~ /1$/ ) { $e_class{$iid} = 'chassis'; } else { $e_class{$iid} = 'module'; } } return \%e_class; } sub brcd_e_descr { my $foundry = shift; my $partial = shift; my $brcd_e_idx = $foundry->brcd_e_index($partial) || {}; my $m_descrs = $foundry->snAgentConfigModule2Description($partial) || $foundry->snAgentConfigModuleDescription($partial) || {}; my %brcd_e_descr; foreach my $iid ( keys %$brcd_e_idx ) { if ( $iid == 0 ) { $brcd_e_descr{$iid} = $foundry->description(); } my $descr = $m_descrs->{$iid}; next unless defined $descr; $brcd_e_descr{$iid} = $descr; } return \%brcd_e_descr; } sub brcd_e_name { my $foundry = shift; my $partial = shift; my $stack_master = $foundry->_brcd_stack_master(); my $e_idx = $foundry->brcd_e_index($partial) || {}; my %brcd_e_name; foreach my $iid ( keys %$e_idx ) { if ( $iid == 0 ) { $brcd_e_name{$iid} = 'Stack Master Unit'; } elsif ( $stack_master && $iid =~ /(\d+)\.1$/ ) { $brcd_e_name{$iid} = "Switch Stack Unit $1"; } elsif ( $iid =~ /1$/ ) { $brcd_e_name{$iid} = "Switch"; } else { $brcd_e_name{$iid} = 'Module'; } } return \%brcd_e_name; } sub brcd_e_vendor { my $foundry = shift; my $partial = shift; my $e_idx = $foundry->brcd_e_index($partial) || {}; my %brcd_e_vendor; foreach my $iid ( keys %$e_idx ) { my $vendor = 'brocade'; $brcd_e_vendor{$iid} = $vendor; } return \%brcd_e_vendor; } sub brcd_e_serial { my $foundry = shift; my $partial = shift; my $e_idx = $foundry->brcd_e_index($partial) || {}; my $serials = $foundry->snAgentConfigModule2SerialNumber($partial) || $foundry->snAgentConfigModuleSerialNumber($partial) || {}; my %brcd_e_serial; foreach my $iid ( keys %$e_idx ) { if ( $iid == 0 ) { $brcd_e_serial{$iid} = $foundry->serial(); } my $serial = $serials->{$iid}; next unless defined $serial; $brcd_e_serial{$iid} = $serial; } return \%brcd_e_serial; } sub brcd_e_type { my $foundry = shift; my $partial = shift; my $e_idx = $foundry->brcd_e_index($partial) || {}; my $types = $foundry->ag_mod2_type($partial) || $foundry->ag_mod_type($partial) || {}; my %brcd_e_type; foreach my $iid ( keys %$e_idx ) { if ( $iid == 0 ) { $brcd_e_type{$iid} = $foundry->model(); } my $type = $types->{$iid}; next unless defined $type; $brcd_e_type{$iid} = $type; } return \%brcd_e_type; } sub brcd_e_pos { my $foundry = shift; my $partial = shift; my $e_idx = $foundry->brcd_e_index($partial) || {}; my %brcd_e_pos; foreach my $iid ( keys %$e_idx ) { my $pos; if ( $iid == 0 ) { $pos = -1; } elsif ( $iid =~ /(\d+)\.1$/ ) { $pos = $1; } elsif ( $iid =~ /(\d+)$/ ) { $pos = $1; } $brcd_e_pos{$iid} = $pos; } return \%brcd_e_pos; } sub brcd_e_parent { my $foundry = shift; my $partial = shift; my $stack_master = $foundry->_brcd_stack_master(); my $e_idx = $foundry->brcd_e_index($partial) || {}; my %brcd_e_parent; foreach my $iid ( keys %$e_idx ) { if ( $iid == 0 ) { $brcd_e_parent{$iid} = 0; } elsif ( $stack_master && $iid =~ /(\d+)\.1$/ ) { $brcd_e_parent{$iid} = 1; } elsif ( $iid =~ /1$/ ) { $brcd_e_parent{$iid} = 0; } elsif ( $iid =~ /(\d+).\d+/ ) { $brcd_e_parent{$iid} = "$1" . "01"; } # assume non-stacked and chassis at index 1 else { $brcd_e_parent{$iid} = 1; } } return \%brcd_e_parent; } # The index of snAgentPoePortTable is snAgentPoePortNumber which equals # ifIndex; however, to emulate POWER-ETHERNET-MIB we need a "module.port" # index. If ifDescr has the format x/x/x use it to determine the module # otherwise default to 1. Unfortunately, this means we can't map any # snAgentPoePortTable leafs directly and partials will not be supported. sub peth_port_ifindex { my $foundry = shift; my $indexes = $foundry->snAgentPoePortNumber(); my $descrs = $foundry->i_description(); my $peth_port_ifindex = {}; foreach my $i ( keys %$indexes ) { my $descr = $descrs->{$i}; next unless $descr; my $new_idx = "1.$i"; if ( $descr =~ /(\d+)\/\d+\/\d+/ ) { $new_idx = "$1.$i"; } $peth_port_ifindex->{$new_idx} = $i; } return $peth_port_ifindex; } sub peth_port_admin { my $foundry = shift; my $p_index = $foundry->peth_port_ifindex() || {}; my $admin_states = $foundry->snAgentPoePortControl() || {}; my $peth_port_admin = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $state = $admin_states->{$port}; if ( $state =~ /enable/ ) { $peth_port_admin->{$i} = 'true'; } else { $peth_port_admin->{$i} = 'false'; } } return $peth_port_admin; } sub peth_port_neg_power { my $foundry = shift; my $p_index = $foundry->peth_port_ifindex() || {}; my $peth_port_class = $foundry->snAgentPoePortClass() || {}; my $poemax = { '0' => 12950, '1' => 3840, '2' => 6490, '3' => 12950, '4' => 25500 }; my $peth_port_neg_power = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $power = $poemax->{ $peth_port_class->{$port} }; next unless $power; $peth_port_neg_power->{$i} = $power; } return $peth_port_neg_power; } sub peth_port_power { my $foundry = shift; my $p_index = $foundry->peth_port_ifindex() || {}; my $port_consumed = $foundry->snAgentPoePortConsumed() || {}; my $peth_port_power = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $power = $port_consumed->{$port}; next unless $power; $peth_port_power->{$i} = $power; } return $peth_port_power; } sub peth_port_class { my $foundry = shift; my $p_index = $foundry->peth_port_ifindex() || {}; my $port_class = $foundry->snAgentPoePortClass() || {}; my $peth_port_class = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $power = $port_class->{$port}; next unless $power; $peth_port_class->{$i} = "class$power"; } return $peth_port_class; } sub peth_port_status { my $foundry = shift; my $p_index = $foundry->peth_port_ifindex() || {}; my $admin_states = $foundry->snAgentPoePortControl() || {}; my $peth_port_status = {}; foreach my $i ( keys %$p_index ) { my ( $module, $port ) = split( /\./, $i ); my $state = $admin_states->{$port}; if ( $state =~ /enable/ ) { $peth_port_status->{$i} = 'deliveringPower'; } else { $peth_port_status->{$i} = 'disabled'; } } return $peth_port_status; } sub peth_power_status { my $foundry = shift; my $partial = shift; my $watts = $foundry->snAgentPoeUnitPowerCapacityTotal($partial) || {}; my $peth_power_status = {}; foreach my $i ( keys %$watts ) { $peth_power_status->{$i} = 'on'; } return $peth_power_status; } sub peth_power_watts { my $foundry = shift; my $partial = shift; my $watts_total = $foundry->snAgentPoeUnitPowerCapacityTotal($partial) || {}; my $peth_power_watts = {}; foreach my $i ( keys %$watts_total ) { my $total = $watts_total->{$i}; next unless $total; $peth_power_watts->{$i} = $total / 1000; } return $peth_power_watts; } sub peth_power_consumption { my $foundry = shift; my $partial = shift; my $watts_total = $foundry->snAgentPoeUnitPowerCapacityTotal($partial) || {}; my $watts_free = $foundry->snAgentPoeUnitPowerCapacityFree($partial) || {}; my $peth_power_consumed = {}; foreach my $i ( keys %$watts_total ) { my $total = $watts_total->{$i}; next unless $total; my $free = $watts_free->{$i} || 0; $peth_power_consumed->{$i} = ( $total - $free ) / 1000; } return $peth_power_consumed; } sub agg_ports { my $dev = shift; # TODO: implement partial my $trunks = $dev->snMSTrunkPortList; my $ports = $dev->snSwPortIfIndex; # sw_index() return {} unless ref {} eq ref $trunks and scalar keys %$trunks and ref {} eq ref $ports and scalar keys %$ports; my $ret = {}; foreach my $m (keys %$trunks) { my $skip = 0; while (my $s = unpack("x${skip}n2", $trunks->{$m})) { $ret->{ $ports->{$s} } = $ports->{$m}; $skip += 2; } } return $ret; } sub i_stp_state { my $foundry = shift; my $partial = shift; my $bp_index = $foundry->bp_index($partial); my $stp_p_state = $foundry->dot1dStpPortState($partial); my %i_stp_state; foreach my $index ( keys %$stp_p_state ) { my $state = $stp_p_state->{$index}; my $iid = $bp_index->{$index}; next unless defined $iid; next unless defined $state; $i_stp_state{$iid} = $state; } return \%i_stp_state; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Foundry - SNMP Interface to Brocade (Foundry) Network Devices =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $foundry = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $foundry->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Brocade (Foundry) Networks devices. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $foundry = new SNMP::Info::Layer3::Foundry(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3; =item SNMP::Info::FDP; =item SNMP::Info::LLDP; =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $foundry->model() Returns model type. Checks $foundry->id() against the F and removes 'C' and 'C'. EdgeIron models determined through F. =item $foundry->vendor() Returns 'brocade' =item $foundry->os() Returns 'brocade' =item $foundry->os_ver() Returns the software version =item $foundry->mac() Returns MAC Address of root port. (C) =item $foundry->chassis() Returns Chassis type. (C) =item $foundry->serial() Returns serial number of device. =item $foundry->temp() Returns the chassis temperature (C) =item $foundry->ps1_type() Returns the Description for the power supply (C) =item $foundry->ps1_status() Returns the status of the power supply. (C) =item $foundry->fan() Returns the status of the chassis fan. (C) =item $foundry->img_ver() Returns device image version. (C) =item $foundry->ch_serial() Returns chassis serial number. (C) =back =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::FDP See documentation in L for details. =head2 Global Methods imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $foundry->interfaces() Returns reference to hash of interface names to iids. =item $foundry->i_ignore() Returns reference to hash of interfaces to be ignored. Ignores interfaces with descriptions of tunnel,loopback,null =item $foundry->i_duplex() Returns reference to hash of interface link duplex status. Crosses $foundry->sw_duplex() with $foundry->sw_index() =item $foundry->i_stp_state() Returns the mapping of (C) to the interface index (iid). =item $foundry->agg_ports() Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =back =head2 F Information F is supported on the Brocade NetIron XMR, NetIron MLX, MLXe, NetIron CES, NetIron CER, and older EdgeIron series devices. For other devices which do not support it, these methods emulate Physical Table methods using F. See Pseudo F information below for details on brcd_e_* methods. =over =item $foundry->e_index() If the device doesn't support C, this will try brcd_e_index(). Note that this is based on C due to implementation details of SNMP::Info::Entity::e_index(). =item $foundry->e_class() If the device doesn't support C, this will try brcd_e_class(). =item $foundry->e_descr() If the device doesn't support C, this will try brcd_e_descr(). =item $foundry->e_name() If the device doesn't support C, this will try brcd_e_name(). =item $foundry->e_parent() If the device doesn't support C, this will try brcd_e_parent(). =item $foundry->e_pos() If the device doesn't support C, this will try brcd_e_pos(). =item $foundry->e_serial() If the device doesn't support C, this will try brcd_e_serial(). =item $foundry->e_type() If the device doesn't support C, this will try brcd_e_type(). =item $foundry->e_vendor() If the device doesn't support C, this will try brcd_e_vendor(). =back =head2 Pseudo F information These methods emulate F Physical Table methods using F. =over =item $foundry->brcd_e_index() Returns reference to hash. Key: IID, Value: Integer, Indices are combined into an integer, each index is two digits padded with leading zero if required. =item $foundry->brcd_e_class() Returns reference to hash. Key: IID, Value: General hardware type. Returns 'stack' for the stack master in an active stack, 'chassis' for base switches that contain modules, and 'module' for others. =item $foundry->brcd_e_descr() Returns reference to hash. Key: IID, Value: Human friendly name (C) or (C) =item $foundry->brcd_e_name() Returns reference to hash. Key: IID, Value: Human friendly name =item $foundry->brcd_e_vendor() Returns reference to hash. Key: IID, Value: brocade =item $foundry->brcd_e_serial() Returns reference to hash. Key: IID, Value: Serial number Serial number is $foundry->serial() for a stack master unit and (C) or (C) for all others. =item $foundry->brcd_e_type() Returns reference to hash. Key: IID, Value: Type of component/sub-component as defined under C or C in F. =item $foundry->brcd_e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. (C) =item $foundry->brcd_e_parent() Returns reference to hash. Key: IID, Value: The value of brcd_e_index() for the entity which 'contains' this entity. A value of zero indicates this entity is not contained in any other entity. =back =head2 Foundry Switch Port Information Table (C) =over =item $foundry->sw_index() Returns reference to hash. Maps Table to Interface IID. (C) =item $foundry->sw_duplex() Returns reference to hash. Current duplex status for switch ports. (C) =item $foundry->sw_type() Returns reference to hash. Current Port Type . (C) =item $foundry->sw_speed() Returns reference to hash. Current Port Speed. (C) =back =head2 Power Over Ethernet Port Table These methods emulate the F Power Source Entity (PSE) Port Table C methods using the F Power over Ethernet Port Table C. =over =item $foundry->peth_port_ifindex() Creates an index of module.port to align with the indexing of the C with a value of C. The module defaults 1 if otherwise unknown. =item $foundry->peth_port_admin() Administrative status: is this port permitted to deliver power? C =item $foundry->peth_port_status() Current status: is this port delivering power. =item $foundry->peth_port_class() Device class: if status is delivering power, this represents the 802.3af class of the device being powered. =item $foundry->peth_port_neg_power() The power, in milliwatts, that has been committed to this port. This value is derived from the 802.3af class of the device being powered. =item $foundry->peth_port_power() The power, in milliwatts, that the port is delivering. =back =head2 Power Over Ethernet Module Table These methods emulate the F Main Power Source Entity (PSE) Table C methods using the F Power over Ethernet Port Table C. =over =item $foundry->peth_power_watts() The power supply's capacity, in watts. =item $foundry->peth_power_status() The power supply's operational status. =item $foundry->peth_power_consumption() How much power, in watts, this power supply has been committed to deliver. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::FDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/H3C.pm000444000765000024 1422513215550564 17361 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::H3C # # Copyright (c) 2012 Jeroen van Ingen # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::H3C; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; use SNMP::Info::IEEE802dot3ad 'agg_ports_lag'; @SNMP::Info::Layer3::H3C::ISA = qw/ SNMP::Info::IEEE802dot3ad SNMP::Info::LLDP SNMP::Info::Layer3 Exporter /; @SNMP::Info::Layer3::H3C::EXPORT_OK = qw/ agg_ports /; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::IEEE802dot3ad::MIBS, 'HH3C-LswDEVM-MIB' => 'hh3cDevMFanStatus', 'HH3C-LswINF-MIB' => 'hh3cSlotPortMax', 'HH3C-LSW-DEV-ADM-MIB' => 'hh3cLswSysVersion', 'HH3C-PRODUCT-ID-MIB' => 'hh3c-s5500-28C-EI', 'HH3C-ENTITY-VENDORTYPE-OID-MIB' => 'hh3cevtOther', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'fan' => 'hh3cDevMFanStatus.1', 'ps1_status' => 'hh3cDevMPowerStatus.1', 'ps2_status' => 'hh3cDevMPowerStatus.2', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, i_duplex_admin => 'hh3cifEthernetDuplex', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub vendor { my $h3c = shift; my $mfg = $h3c->entPhysicalMfgName(1) || {}; return $mfg->{1} || "H3C"; } sub os { my $h3c = shift; my $descr = $h3c->description(); return $1 if ( $descr =~ /(\S+)\s+Platform Software/ ); return "H3C"; } sub os_ver { my $h3c = shift; my $descr = $h3c->description(); # my $version = $h3c->hh3cLswSysVersion(); # Don't use, indicates base version only, no release details my $ver_release = $h3c->entPhysicalSoftwareRev(2) || {}; my $os_ver = undef; $os_ver = "$1 $2" if ( $descr =~ /Software Version ([^,]+),.*(Release\s\S+)/i ); $os_ver = "$1" if ( $descr =~ /Product Version ([0-9.]+)/i ); return $ver_release->{2} || $os_ver; } sub i_ignore { my $l3 = shift; my $partial = shift; my $interfaces = $l3->interfaces($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { # lo0 etc if ( $interfaces->{$if} =~ /\blo\d*\b/i ) { $i_ignore{$if}++; } } return \%i_ignore; } sub agg_ports { return agg_ports_lag(@_) } 1; __END__ =head1 NAME SNMP::Info::Layer3::H3C - SNMP Interface to L3 Devices, H3C & HP A-series =head1 AUTHORS Jeroen van Ingen =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $h3c = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $h3c->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for H3C & HP A-series devices =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $h3c->vendor() Returns value for C. =item $h3c->os() Returns the OS extracted from C. =item $h3c->os_ver() Returns the software version. Either C or extracted from C. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $h3c->i_ignore() Returns reference to hash. Increments value of IID if port is to be ignored. Ignores loopback =item C Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/HP9300.pm000444000765000024 2350613215550564 17631 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::HP9300 - SNMP Interface to HP Foundry OEM devices # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::HP9300; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::FDP; use SNMP::Info::LLDP; @SNMP::Info::Layer3::HP9300::ISA = qw/SNMP::Info::FDP SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::HP9300::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::FDP::MIBS, 'HP-SN-ROOT-MIB' => 'hp', 'HP-SN-AGENT-MIB' => 'snChasPwrSupplyDescription', 'HP-SN-SWITCH-GROUP-MIB' => 'snSwGroupOperMode', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, %SNMP::Info::FDP::GLOBALS, 'mac' => 'ifPhysAddress.1', 'chassis' => 'entPhysicalDescr.1', 'temp' => 'snChasActualTemperature', 'ps1_type' => 'snChasPwrSupplyDescription.1', 'ps1_status' => 'snChasPwrSupplyOperStatus.1', 'fan' => 'snChasFanOperStatus.1', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, %SNMP::Info::FDP::FUNCS, # HP-SN-SWITCH-GROUP-MIB # snSwPortInfoTable - Switch Port Information Group # Fully qualify these since FDP class will load # FOUNDRY-SN-SWITCH-GROUP-MIB which contains the same leaf names 'sw_index' => 'HP_SN_SWITCH_GROUP_MIB__snSwPortIfIndex', 'sw_duplex' => 'HP_SN_SWITCH_GROUP_MIB__snSwPortInfoChnMode', 'sw_type' => 'HP_SN_SWITCH_GROUP_MIB__snSwPortInfoMediaType', 'sw_speed' => 'HP_SN_SWITCH_GROUP_MIB__snSwPortInfoSpeed', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, %SNMP::Info::FDP::MUNGE, ); sub i_ignore { my $hp9300 = shift; my $partial = shift; my $interfaces = $hp9300->interfaces($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { if ( $interfaces->{$if} =~ /(tunnel|loopback|\blo\b|lb|null)/i ) { $i_ignore{$if}++; } } return \%i_ignore; } sub i_duplex { my $hp9300 = shift; my $partial = shift; my $sw_index = $hp9300->sw_index($partial); my $sw_duplex = $hp9300->sw_duplex($partial); unless ( defined $sw_index and defined $sw_duplex ) { return $hp9300->SUPER::i_duplex(); } my %i_duplex; foreach my $sw_port ( keys %$sw_duplex ) { my $iid = $sw_index->{$sw_port}; my $duplex = $sw_duplex->{$sw_port}; next if $duplex =~ /none/i; $i_duplex{$iid} = 'half' if $duplex =~ /half/i; $i_duplex{$iid} = 'full' if $duplex =~ /full/i; } return \%i_duplex; } sub model { my $hp9300 = shift; my $id = $hp9300->id(); my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^hpSwitch//; return $model; } sub os { return 'hp'; } sub vendor { return 'hp'; } sub os_ver { my $hp9300 = shift; return $hp9300->snAgImgVer() if ( defined $hp9300->snAgImgVer() ); # Some older ones don't have this value,so we cull it from the description my $descr = $hp9300->description(); if ( $descr =~ m/Version (\d\S*)/ ) { return $1; } # Last resort return $hp9300->SUPER::os_ver(); } sub serial { my $hp9300 = shift; # Return chassis serial number if available return $hp9300->snChasSerNum() if ( $hp9300->snChasSerNum() ); # If no chassis serial use first module serial my $mod_serials = $hp9300->snAgentConfigModuleSerialNumber(); foreach my $mod ( sort keys %$mod_serials ) { my $serial = $mod_serials->{$mod} || ''; next unless defined $serial; return $serial; } # Last resort return $hp9300->SUPER::serial(); } sub interfaces { my $hp9300 = shift; my $partial = shift; my $i_descr = $hp9300->i_description($partial) || {}; my $i_name = $hp9300->i_name($partial) || {}; # Use ifName for EdgeIrons else use ifDescr foreach my $iid ( keys %$i_name ) { my $name = $i_name->{$iid}; next unless defined $name; $i_descr->{$iid} = $name if $name =~ /^port\d+/i; } return $i_descr; } 1; __END__ =head1 NAME SNMP::Info::Layer3::HP9300 - SNMP Interface to HP Foundry OEM Network Devices =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $hp9300 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $hp9300->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for HP network devices which Foundry Networks was the Original Equipment Manufacturer (OEM) such as the HP ProCurve 9300 series. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $hp9300 = new SNMP::Info::Layer3::HP9300(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3; =item SNMP::Info::FDP; =item SNMP::Info::LLDP; =back =head2 Required MIBs =over =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $hp9300->model() Returns model type. Checks $hp9300->id() against the F and removes C. =item $hp9300->vendor() Returns 'hp' =item $hp9300->os() Returns 'hp' =item $hp9300->os_ver() Returns the software version =item $hp9300->mac() Returns MAC Address of root port. (C) =item $hp9300->chassis() Returns Chassis type. (C) =item $hp9300->serial() Returns serial number of device. =item $hp9300->temp() Returns the chassis temperature (C) =item $hp9300->ps1_type() Returns the Description for the power supply (C) =item $hp9300->ps1_status() Returns the status of the power supply. (C) =item $hp9300->fan() Returns the status of the chassis fan. (C) =back =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::FDP See documentation in L for details. =head2 Global Methods imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $hp9300->interfaces() Returns reference to hash of interface names to iids. =item $hp9300->i_ignore() Returns reference to hash of interfaces to be ignored. Ignores interfaces with descriptions of tunnel,loopback,null =item $hp9300->i_duplex() Returns reference to hash of interface link duplex status. Crosses $hp9300->sw_duplex() with $hp9300->sw_index() =back =head2 Switch Port Information Table (C) =over =item $hp9300->sw_index() Returns reference to hash. Maps Table to Interface IID. (C) =item $hp9300->sw_duplex() Returns reference to hash. Current duplex status for switch ports. (C) =item $hp9300->sw_type() Returns reference to hash. Current Port Type . (C) =item $hp9300->sw_speed() Returns reference to hash. Current Port Speed. (C) =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::FDP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Huawei.pm000444000765000024 1263113215550564 20225 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Huawei # # Copyright (c) 2015 Jeroen van Ingen # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Huawei; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; use SNMP::Info::IEEE802dot3ad 'agg_ports_lag'; @SNMP::Info::Layer3::Huawei::ISA = qw/ SNMP::Info::IEEE802dot3ad SNMP::Info::LLDP SNMP::Info::Layer3 Exporter /; @SNMP::Info::Layer3::Huawei::EXPORT_OK = qw/ agg_ports /; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, %SNMP::Info::IEEE802dot3ad::MIBS, 'HUAWEI-MIB' => 'quidway', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub vendor { return "Huawei"; } sub os { my $huawei = shift; my $descr = $huawei->description(); return $1 if ( $descr =~ /\b(VRP)\b/ ); return "huawei"; } sub os_ver { my $huawei = shift; my $descr = $huawei->description(); my $os_ver = undef; $os_ver = "$1" if ( $descr =~ /\bVersion ([0-9.]+)/i ); return $os_ver; } sub i_ignore { my $l3 = shift; my $partial = shift; my $interfaces = $l3->interfaces($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { # lo0 etc if ( $interfaces->{$if} =~ /\b(inloopback|console)\d*\b/i ) { $i_ignore{$if}++; } } return \%i_ignore; } sub agg_ports { return agg_ports_lag(@_) } 1; __END__ =head1 NAME SNMP::Info::Layer3::Huawei - SNMP Interface to Huawei Layer 3 switches and routers. =head1 AUTHORS Jeroen van Ingen =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $huawei = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $huawei->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Huawei Quidway switches =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::LLDP =item SNMP::Info::IEEE802dot3ad =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $huawei->vendor() Returns 'Huawei'. =item $huawei->os() Returns 'VRP' if contained in C, 'huawei' otherwise. =item $huawei->os_ver() Returns the software version extracted from C. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $huawei->i_ignore() Returns reference to hash. Increments value of IID if port is to be ignored. Ignores InLoopback and Console interfaces =item C Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/IBMGbTor.pm000444000765000024 2426713215550564 20360 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::IBMGbTor - SNMP Interface to IBM Rackswitch devices # $Id$ # # Copyright (c) 2013 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::IBMGbTor; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; @SNMP::Info::Layer3::IBMGbTor::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::IBMGbTor::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, # LLDP MIBs not loaded to prevent possible unqualified namespace conflict # with IBM definitions 'IBM-GbTOR-10G-L2L3-MIB' => 'lldpInfoRemoteDevicesLocalPort', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'temp' => 'hwTempSensors', 'fan' => 'hwFanSpeed', # Can't find the equivalent in IBM-GbTOR-10G-L2L3-MIB # use a different strategy for lldp_sys_cap in hasLLDP() #'lldp_sysname' => 'lldpLocSysName', #'lldp_sysdesc' => 'lldpLocSysDesc', #'lldp_sys_cap' => 'lldpLocSysCapEnabled', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, # IBM-GbTOR-10G-L2L3-MIB::portInfoTable 'sw_duplex' => 'portInfoMode', # Can't find the equivalent in IBM-GbTOR-10G-L2L3-MIB # not currently used in LLDP class #'lldp_lman_addr' => 'lldpLocManAddrIfId', # IBM-GbTOR-10G-L2L3-MIB::lldpInfoPortTable 'lldp_port_status' => 'lldpInfoPortAdminStatus', # IBM-GbTOR-10G-L2L3-MIB::lldpInfoRemoteDevicesTable 'lldp_rem_id_type' => 'lldpInfoRemoteDevicesChassisSubtype', 'lldp_rem_id' => 'lldpInfoRemoteDevicesSystemName', 'lldp_rem_pid_type' => 'lldpInfoRemoteDevicesPortSubtype', 'lldp_rem_pid' => 'lldpInfoRemoteDevicesPortId', 'lldp_rem_desc' => 'lldpInfoRemoteDevicesPortDescription', 'lldp_rem_sysname' => 'lldpInfoRemoteDevicesSystemName', 'lldp_rem_sysdesc' => 'lldpInfoRemoteDevicesSystemDescription', 'lldp_rem_sys_cap' => 'lldpInfoRemoteDevicesSystemCapEnabled', # IBM-GbTOR-10G-L2L3-MIB::lldpInfoRemoteDevicesManAddrTable 'lldp_rman_type' => 'lldpInfoRemoteDevicesManAddrSubtype', 'lldp_rman_addr' => 'lldpInfoRemoteDevicesManAddr', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub hasLLDP { my $ibm = shift; # We may be have LLDP, but nothing in lldpRemoteSystemsData Tables # Look to see if LLDP Rx enabled on any port my $lldp_cap = $ibm->lldp_port_status(); foreach my $if ( keys %$lldp_cap ) { if ( $lldp_cap->{$if} =~ /enabledRx/i ) { return 1; } } return; } sub lldp_ip { my $ibm = shift; my $partial = shift; my $rman_type = $ibm->lldp_rman_type($partial) || {}; my $rman_addr = $ibm->lldp_rman_addr($partial) || {}; my %lldp_ip; foreach my $key ( keys %$rman_addr ) { my $type = $rman_type->{$key}; next unless defined $type; next unless $type eq 'ipV4'; if ( $key =~ /^(\d+)\./ ) { $lldp_ip{$1} = $rman_addr->{$key}; } } return \%lldp_ip; } sub lldp_if { my $lldp = shift; my $partial = shift; my $lldp_desc = $lldp->lldpInfoRemoteDevicesLocalPort($partial) || {}; my $i_descr = $lldp->i_description() || {}; my $i_alias = $lldp->i_alias() || {}; my %r_i_descr = reverse %$i_descr; my %r_i_alias = reverse %$i_alias; my %lldp_if; foreach my $key ( keys %$lldp_desc ) { # Cross reference lldpLocPortDesc with ifDescr and ifAlias to get ifIndex, # prefer ifAlias over ifDescr since MIB says 'alias'. my $desc = $lldp_desc->{$key}; next unless $desc; my $port = $desc; # If cross reference is successful use it, otherwise stick with # lldpRemLocalPortNum if ( exists $r_i_alias{$desc} ) { $port = $r_i_alias{$desc}; } elsif ( exists $r_i_descr{$desc} ) { $port = $r_i_descr{$desc}; } $lldp_if{$key} = $port; } return \%lldp_if; } sub lldp_platform { my $ibm = shift; my $partial = shift; return $ibm->lldpInfoRemoteDevicesSystemDescription($partial); } sub i_ignore { my $ibm = shift; my $partial = shift; my $interfaces = $ibm->interfaces($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { if ( $interfaces->{$if} =~ /(tunnel|loopback|\blo\b|lb|null)/i ) { $i_ignore{$if}++; } } return \%i_ignore; } sub i_duplex { my $ibm = shift; my $partial = shift; return $ibm->sw_duplex($partial); } sub model { my $ibm = shift; my $id = $ibm->id(); my $descr = $ibm->description(); my $model = &SNMP::translateObj($id); if ( $descr =~ /RackSwitch\s(.*)/ ) { return $1; } return $model || $id; } sub os { return 'ibm'; } sub vendor { return 'ibm'; } sub os_ver { my $ibm = shift; return $ibm->agSoftwareVersion(); } sub interfaces { my $ibm = shift; my $partial = shift; my $i_descr = $ibm->i_description($partial) || {}; my $i_name = $ibm->i_name($partial) || {}; foreach my $iid ( keys %$i_name ) { my $name = $i_name->{$iid}; next unless defined $name; $i_descr->{$iid} = $name if $name =~ /^port\d+/i; } return $i_descr; } 1; __END__ =head1 NAME SNMP::Info::Layer3::IBMGbTor - SNMP Interface to IBM Rackswitch devices =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $ibm = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $ibm->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for IBM Rackswitch (formerly Blade Network Technologies) network devices. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $ibm = new SNMP::Info::Layer3::IBMGbTor(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3; =item SNMP::Info::LLDP; =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $ibm->model() Returns model type. Attempts to pull model from device description. Otherwise checks $ibm->id() against the F. =item $ibm->vendor() Returns 'ibm' =item $ibm->os() Returns 'ibm' =item $ibm->os_ver() Returns the software version (C) =item $ibm->temp() (C) =item $ibm->fan() (C) =back =head2 Overrides =over =item $ibm->hasLLDP() Is LLDP is active in this device? Note: LLDP may be active, but nothing in C Tables so the device would not return any useful topology information. Checks to see if at least one interface is enabled to receive LLDP packets. =back =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $ibm->interfaces() Returns reference to hash of interface names to iids. =item $ibm->i_ignore() Returns reference to hash of interfaces to be ignored. Ignores interfaces with descriptions of tunnel, loopback, and null. =item $ibm->i_duplex() Returns reference to hash of interface link duplex status. (C) =item $ibm->lldp_if() Returns the mapping to the SNMP Interface Table. Tries to cross reference (C) with (C) and (C) to get (C). =item $ibm->lldp_ip() Returns remote IPv4 address. Returns for all other address types, use lldp_addr if you want any return address type. =item $ibm->lldp_platform() Returns remote device system description. (C) =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Juniper.pm000444000765000024 4765213215550564 20432 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Juniper # $Id$ # # Copyright (c) 2008 Bill Fenner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Juniper; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; @SNMP::Info::Layer3::Juniper::ISA = qw/SNMP::Info::Layer3 SNMP::Info::LLDP Exporter/; @SNMP::Info::Layer3::Juniper::EXPORT_OK = qw//; use vars qw/$VERSION $DEBUG %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, 'JUNIPER-CHASSIS-DEFINES-MIB' => 'jnxChassisDefines', 'JUNIPER-MIB' => 'jnxBoxAnatomy', 'JUNIPER-VIRTUALCHASSIS-MIB' => 'jnxVirtualChassisMemberTable', 'JUNIPER-VLAN-MIB' => 'jnxVlanMIBObjects', 'JUNIPER-L2ALD-MIB' => 'jnxL2aldVlanFdbId', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'serial' => 'jnxBoxSerialNo.0', 'mac' => 'dot1dBaseBridgeAddress', 'box_descr' => 'jnxBoxDescr' ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, # JUNIPER-VLAN-MIB::jnxExVlanTable 'v_index' => 'jnxExVlanTag', 'v_type' => 'jnxExVlanType', 'v_name' => 'jnxExVlanName', # JUNIPER-VLAN-MIB::jnxExVlanPortGroupTable 'i_trunk' => 'jnxExVlanPortAccessMode', # JUNPIER-MIB 'e_contents_type' => 'jnxContentsType', 'e_containers_type' => 'jnxContainersType', 'e_hwver' => 'jnxContentsRevision', 'v_fdb_id' => 'jnxL2aldVlanFdbId', 'v_vlan_tag' => 'jnxL2aldVlanTag', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, 'e_containers_type' => \&SNMP::Info::munge_e_type, 'e_contents_type' => \&SNMP::Info::munge_e_type, ); sub vendor { return 'juniper'; } sub os { return 'junos'; } sub layers { my $juniper = shift; my $layers = $juniper->SUPER::layers(); # Some models don't report L2 properly my $macs = $juniper->fw_mac(); if (keys %$macs) { my $l = substr $layers, 6, 1, "1"; } return $layers; } sub os_ver { my $juniper = shift; my $sys_descr = $juniper->description() || ''; my $lldp_descr = $juniper->lldp_sysdesc() || ''; foreach my $descr ($sys_descr, $lldp_descr) { if ( $descr =~ m/kernel JUNOS ([^,\s]+)/ ) { return $1; } elsif ( $descr =~ m/version\s(\S+)\s/ ) { return $1; } } return; } sub model { my $l3 = shift; my $id = $l3->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::Juniper::model() - Device does not support sysObjectID\n" if $l3->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^jnxProductName//i; return $model; } # Override the fancy Layer3.pm serial function sub serial { my $juniper = shift; return $juniper->orig_serial(); } # 'i_trunk' => 'jnxExVlanPortAccessMode', sub i_trunk { my $juniper = shift; my $partial = shift; my $access = $juniper->jnxExVlanPortAccessMode($partial); my %i_trunk; foreach (keys %$access) { my $old_key = $_; m/^\d+\.(\d+)$/o; my $new_key = $1; $i_trunk{$new_key} = $access->{$old_key}; } return \%i_trunk; } sub qb_fdb_index { my $juniper = shift; my $partial = shift; return $juniper->jnxExVlanTag($partial); } # 'v_type' => 'jnxExVlanType', sub v_type { my $juniper = shift; my $partial = shift; my $v_type = $juniper->jnxExVlanType($partial); return $v_type; } # 'v_index' => 'jnxExVlanTag', sub v_index { my ($juniper) = shift; my ($partial) = shift; my ($v_index) = $juniper->jnxExVlanTag($partial); return $v_index; } sub i_vlan { my $juniper = shift; my $partial = shift; my $index = $juniper->bp_index(); # If given a partial it will be an ifIndex, we need to use dot1dBasePort if ($partial) { my %r_index = reverse %$index; $partial = $r_index{$partial}; } my $v_index = $juniper->jnxExVlanTag(); my $i_pvid = $juniper->qb_i_vlan($partial) || {}; my $i_vlan = {}; foreach my $bport ( keys %$i_pvid ) { my $q_vlan = $i_pvid->{$bport}; my $vlan = $v_index->{$q_vlan} || $q_vlan; my $ifindex = $index->{$bport}; unless ( defined $ifindex ) { print " Port $bport has no bp_index mapping. Skipping.\n" if $DEBUG; next; } $i_vlan->{$ifindex} = $vlan; } return $i_vlan; } # Index doesn't use VLAN ID, so override the HOA private method here to # correct the mapping sub _vlan_hoa { my $juniper = shift; my ( $v_ports, $partial ) = @_; my $index = $juniper->bp_index(); my $v_index = $juniper->jnxExVlanTag($partial); my $vlan_hoa = {}; foreach my $idx ( keys %$v_ports ) { next unless ( defined $v_ports->{$idx} ); my $portlist = $v_ports->{$idx}; my $ret = []; my $vlan_ndx; # Strip TimeFilter if we're using VlanCurrentTable ( $vlan_ndx = $idx ) =~ s/^\d+\.//; # Convert portlist bit array to bp_index array for ( my $i = 0; $i <= $#$portlist; $i++ ) { push( @{$ret}, $i + 1 ) if ( @$portlist[$i] ); } #Create HoA ifIndex -> VLAN array foreach my $port ( @{$ret} ) { my $ifindex = $index->{$port}; next unless ( defined($ifindex) ); # shouldn't happen next if ( defined $partial and $ifindex !~ /^$partial$/ ); push( @{ $vlan_hoa->{$ifindex} }, $v_index->{$vlan_ndx} ); } } return $vlan_hoa; } sub i_vlan_membership { my $juniper = shift; my $partial = shift; my $res; my $dot1qVlanStaticEgressPorts = $juniper->dot1qVlanCurrentEgressPorts($partial) || $juniper->dot1qVlanStaticEgressPorts($partial); my $bp_index = $juniper->bp_index(); foreach my $vlan (keys %$dot1qVlanStaticEgressPorts) { my @bp_indexes = split /,/, $dot1qVlanStaticEgressPorts->{$vlan}; push @{$res->{$bp_index->{$_}}}, $vlan for @bp_indexes; } return $res; } sub qb_fw_vlan { my $juniper = shift; my $qb_fw_vlan = $juniper->SUPER::qb_fw_vlan(); my $v_fdb_id = $juniper->v_fdb_id(); my $v_vlan_tag = $juniper->v_vlan_tag(); return $qb_fw_vlan unless $v_fdb_id && $v_vlan_tag; my %fdb_id_to_tag = reverse %$v_fdb_id; foreach my $key (keys %$qb_fw_vlan) { my $v = $qb_fw_vlan->{$key}; $qb_fw_vlan->{$key} = $v_vlan_tag->{$fdb_id_to_tag{$v}}; } return $qb_fw_vlan; } # Pseudo ENTITY-MIB methods # This class supports both virtual chassis (stackable) and physical chassis # based devices, identify if we have a virtual chassis so that we return # appropriate entPhysicalClass and correct ordering sub _e_is_virtual { my $juniper = shift; my $v_test = $juniper->jnxVirtualChassisMemberRole() || {}; #If we are functioning as a stack someone should be master foreach my $iid ( keys %$v_test ) { my $role = $v_test->{$iid}; return 1 if ($role =~ /master/i); } return 0; } sub _e_virtual_index { my $juniper = shift; my $containers = $juniper->jnxContainersWithin() || {}; my $members = $juniper->jnxVirtualChassisMemberRole() || {}; my %v_index; foreach my $key (keys %$containers) { foreach my $member ( keys %$members ) { # Virtual chassis members start at zero $member++; # We will be duplicating and eliminating some keys, # but this is for the benefit of e_parent() my $index = sprintf ("%02d", $key) . sprintf ("%02d", $member) . "0000"; my $iid = "$key\.$member\.0\.0"; $v_index{$iid} = $index; } unless ($containers->{$key}) { my $index = sprintf ("%02d", $key) . "000000"; $v_index{$key} = $index; } } return \%v_index; } sub e_index { my $juniper = shift; my $contents = $juniper->jnxContentsDescr() || {}; my $containers = $juniper->jnxContainersDescr() || {}; my $virtuals = $juniper->_e_virtual_index() || {}; my $is_virtual = $juniper->_e_is_virtual(); # Format into consistent integer format so that numeric sorting works my %e_index; if ($is_virtual) { foreach my $key ( keys %$virtuals ) { $e_index{$key} = $virtuals->{$key}; } } else { foreach my $key ( keys %$containers ) { $e_index{$key} = sprintf ("%02d", $key) . "000000"; } } foreach my $key ( keys %$contents ) { $e_index{$key} = join( '', map { sprintf "%02d", $_ } split /\./, $key ); } return \%e_index; } sub e_class { my $juniper = shift; my $e_index = $juniper->e_index() || {}; my $fru_type = $juniper->jnxFruType() || {}; my $c_type = $juniper->jnxContainersDescr() || {}; my $is_virtual = $juniper->_e_is_virtual(); my %e_class; foreach my $iid ( keys %$e_index ) { my $type = $fru_type->{$iid} || 0; my $container = $c_type->{$iid} || 0; if ( $type =~ /power/i ) { $e_class{$iid} = 'powerSupply'; } elsif ( $type =~ /fan/i ) { $e_class{$iid} = 'fan'; } elsif ( $type ) { $e_class{$iid} = 'module'; } # Shouldn't get here if we have type which means # we only have container, chassis, and stack left elsif (($container =~ /chassis/i) and (!$is_virtual) ) { $e_class{$iid} = 'chassis'; } elsif (($container =~ /chassis/i) and ($is_virtual)) { $e_class{$iid} = 'stack'; } # Were calling the second level chassis a container in the case # of a virtual chassis but not sure that it really matters else { $e_class{$iid} = 'container'; } } return \%e_class; } sub e_descr { my $juniper = shift; my $e_index = $juniper->e_index() || {}; my $box_descr = $juniper->box_descr; my $contents = $juniper->jnxContentsDescr() || {}; my $containers = $juniper->jnxContainersDescr() || {}; my %e_descr; foreach my $iid ( keys %$e_index ) { my $content_descr = $contents->{$iid} || 0; my $container_descr = $containers->{$iid} || 0; if ($content_descr) { $e_descr{$iid} = $content_descr; } elsif ($container_descr and $container_descr !~ /chassis/) { $e_descr{$iid} = $container_descr; } elsif ($container_descr and $container_descr =~ /chassis/) { $e_descr{$iid} = $box_descr; } # We should only be left with virtual entries created in # _e_virtual_index() elsif ($iid =~ /^(\d+)\.(\d+)(\.0)+?/) { my $descr = $containers->{$1}; $e_descr{$iid} = $descr; } # Anything past here undef } return \%e_descr; } sub e_serial { my $juniper = shift; my $e_index = $juniper->e_index() || {}; my $serials = $juniper->jnxContentsSerialNo() || {}; my $e_class = $juniper->e_class() || {}; my $is_virtual = $juniper->_e_is_virtual(); my $box_serial = $juniper->serial(); my %e_serial; foreach my $iid ( keys %$e_index ) { my $serial = $serials->{$iid} || ''; my $class = $e_class->{$iid} || ''; # Chassis serial number is seperate on true chassis # Virtual chassis (stack) report master switch serial if (!$is_virtual and ($class =~ /chassis/i)){ $e_serial{$iid} = $box_serial; } elsif (($serial !~ /^\w/) or ($serial =~ /builtin/i)) { next; } else { $e_serial{$iid} = $serial; } } return \%e_serial; } sub e_fru { my $juniper = shift; my $e_index = $juniper->e_index() || {}; my $frus = $juniper->jnxContentsPartNo() || {}; my %e_fru; foreach my $iid ( keys %$e_index ) { my $fru = $frus->{$iid} || ''; if ( ($fru !~ /^\w/) or ($fru =~ /builtin/i)) { $e_fru{$iid} = "false"; } else { $e_fru{$iid} = "true"; } } return \%e_fru; } sub e_type { my $juniper = shift; my $e_index = $juniper->e_index() || {}; my $contents = $juniper->e_contents_type() || {}; my $containers = $juniper->e_containers_type() || {}; my %e_type; foreach my $iid ( keys %$e_index ) { my $content_type = $contents->{$iid} || 0; my $container_type = $containers->{$iid} || 0; if ($content_type) { $content_type =~ s/\.0//; $e_type{$iid} = $content_type; } elsif ($container_type) { $container_type =~ s/\.0//; $e_type{$iid} = $container_type; } # We should only be left with virtual entries created in # _e_virtual_index() elsif ($iid =~ /^(\d+)\.(\d+)(\.0)+?/) { my $descr = $containers->{$1}; $descr =~ s/\.0//; $e_type{$iid} = $descr; } # Anything past here undef } return \%e_type; } sub e_vendor { my $juniper = shift; my $e_idx = $juniper->e_index() || {}; my %e_vendor; foreach my $iid ( keys %$e_idx ) { $e_vendor{$iid} = 'juniper'; } return \%e_vendor; } sub e_pos { my $juniper = shift; # We could look at index levels, but his will work as well return $juniper->e_index(); } sub e_parent { my $juniper = shift; my $e_idx = $juniper->e_index() || {}; my $c_within = $juniper->jnxContainersWithin() || {}; my $e_descr = $juniper->e_descr() || {}; my $is_virtual = $juniper->_e_is_virtual(); my %e_parent; foreach my $iid ( keys %$e_idx ) { next unless $iid; my ($idx, $l1,$l2, $l3) = split /\./, $iid; my $within = $c_within->{$idx}; my $descr = $e_descr->{$iid}; if ( !$is_virtual and ($iid =~ /^(\d+)\.\d+/) ) { $e_parent{$iid} = sprintf ("%02d", $1) . "000000"; } elsif ( $is_virtual and ($descr =~ /chassis/i) and ($iid =~ /^(\d+)\.(\d+)(\.0)+?/) ) { $e_parent{$iid} = sprintf ("%02d", $1) . "000000"; } elsif ( $is_virtual and ($iid =~ /^(\d+)\.(\d+)(\.0)+?/) ) { $e_parent{$iid} = sprintf ("%02d", $within) . sprintf ("%02d", $2) . "0000"; } elsif ( $is_virtual and ($iid =~ /^(\d+)\.(\d+)\.[1-9]+/) ) { $e_parent{$iid} = sprintf ("%02d", $1) . sprintf ("%02d", $2) . "0000"; } elsif ( defined $within and $iid =~ /\d+/ ) { $e_parent{$iid} = sprintf ("%02d", $within) . "000000"; } else { next; } } return \%e_parent; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Juniper - SNMP Interface to L3 Juniper Devices =head1 AUTHOR Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $juniper = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $juniper->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Juniper Devices running JUNOS =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item F dated "200901090000Z" or later. =item F =item F =item F =back =head2 Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $juniper->vendor() Returns 'juniper' =item $juniper->os() Returns 'junos' =item $juniper->layers() Checks forwarding table for Layer 2 support since some routers with switches do not report layers properly. =item $juniper->os_ver() Returns the software version extracted first from C or C if not available in C. =item $juniper->model() Returns the model from C, with C removed from the beginning. =item $juniper->serial() Returns serial number (C) =item $juniper->mac() Returns the MAC address used by this bridge when it must be referred to in a unique fashion. (C) =item $juniper->box_descr() The name, model, or detailed description of the device. (C) =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $juniper->qb_fdb_index() Returns reference to hash: key = VLAN ID, value = FDB ID. =item $juniper->v_index() (C) =item $juniper->v_name() (C) =item $juniper->v_type() (C) =item $juniper->i_trunk() (C) =item $juniper->i_vlan() Returns a mapping between C and the PVID or default VLAN. =back =head2 Pseudo F information These methods emulate F Physical Table methods using F and F. =over =item $juniper->e_index() Returns reference to hash. Key: IID, Value: Integer, Indices are combined into a eight digit integer, each index is two digits padded with leading zero if required. =item $juniper->e_class() Returns reference to hash. Key: IID, Value: General hardware type. =item $juniper->e_descr() Returns reference to hash. Key: IID, Value: Human friendly name =item $juniper->e_hwver() Returns reference to hash. Key: IID, Value: Hardware version =item $juniper->e_vendor() Returns reference to hash. Key: IID, Value: juniper =item $juniper->e_serial() Returns reference to hash. Key: IID, Value: Serial number =item $juniper->e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. =item $juniper->e_type() Returns reference to hash. Key: IID, Value: Type of component/sub-component as defined in F. =item $juniper->e_parent() Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. A value of zero indicates this entity is not contained in any other entity. =item $entity->e_fru() BOOLEAN. Is a Field Replaceable unit? (C) =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Lantronix.pm000444000765000024 1434713215550564 20767 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Lantronix # $Id$ # # Copyright (c) 2012 J R Binks # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Lantronix; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Lantronix::ISA = qw/ SNMP::Info::Layer3 Exporter /; @SNMP::Info::Layer3::Lantronix::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'LANTRONIX-MIB' => 'products', 'LANTRONIX-SLC-MIB' => 'slcNetwork', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, 'slc_os_ver' => 'slcSystemFWRev', 'slc_serial' => 'slcSystemSerialNo', 'slc_model' => 'slcSystemModel', 'slc_psu_a_status' => 'slcDevPowerSupplyA', 'slc_psu_b_status' => 'slcDevPowerSupplyB', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); # General notes: # # Products like the EDS have very minimal MIB support for the basics. # Much information has to be derived from sysDescr string. # sub vendor { return 'lantronix'; } sub os { my $device = shift; my $descr = $device->description() || ''; my $os; # On EDS, it is called the "Evolution OS" # Not sure what, if any, name it has a name on other products $os = 'EvolutionOS' if ( $descr =~ m/Lantronix EDS\w+ V([\d\.R]+)/ ); return 'LantronixOS'; } sub os_ver { my $device = shift; my $descr = $device->description() || ''; my $slc_os_ver = $device->slc_os_ver; my $os_ver; return $slc_os_ver if defined $slc_os_ver; return unless defined $descr; # EDS: "Lantronix EDS16PR V4.0.0.0R15 (1307.....X)" $os_ver = $1 if ( $descr =~ m/Lantronix EDS\w+ V([\d\.R]+)/ ); return $os_ver; } sub serial { my $device = shift; my $descr = $device->description() || ''; my $slc_serial = $device->slc_serial; my $serial; return $slc_serial if defined $slc_serial; return unless defined $descr; # EDS: "Lantronix EDS16PR V4.0.0.0R15 (1307.....X)" $serial = $1 if ( $descr =~ m/Lantronix EDS\w+ V[\d\.R]+ \((\w+)\)/ ); return $serial; } sub model { my $device = shift; my $descr = $device->description() || ''; my $slc_model = $device->slc_model; my $model; return $slc_model if defined $slc_model; return unless defined $descr; # EDS: "Lantronix EDS16PR V4.0.0.0R15 (1307.....X)" $model = $1 if ( $descr =~ m/Lantronix (EDS\w+)/ ); return $model; } sub ps1_status { my $device = shift; my $slc_psu_a_status = $device->slc_psu_a_status; return $slc_psu_a_status if defined $slc_psu_a_status; return; } sub ps2_status { my $device = shift; my $slc_psu_b_status = $device->slc_psu_b_status; return $slc_psu_b_status if defined $slc_psu_b_status; return; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Lantronix - SNMP Interface to Lantronix devices such as terminal servers =head1 AUTHOR J R Binks =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $device = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'mydevice', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $device->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Lantronix devices such as terminal servers. =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =back =head2 Inherited Classes' MIBs See L for its own MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP. =over =item $device->vendor() Returns 'lantronix'. =item $device->os() Returns 'EvolutionOS' for EDS devices. =item $device->os_ver() Returns the software version. =item $device->model() Returns the model. =item $device->serial() Returns the serial number. =item $device->ps1_status() Power supply 1 status =item $device->ps2_status() Power supply 2 status =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =over =back =head2 Overrides =over =item $device->i_ignore() Returns reference to hash. Increments value of IID if port is to be ignored. =back =head2 Lantronix specific items None at present. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Microsoft.pm000444000765000024 1125313215550564 20747 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Microsoft # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Microsoft; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Microsoft::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Microsoft::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'microsoft'; } sub os { return 'windows'; } sub os_ver { return ''; } sub model { return 'Windows Router'; } sub serial { return ''; } # $l3->interfaces() - Map the Interfaces to their physical names # Add interface number to interface name because if MS Win # have identical interface cards ("HP NC7782 Gigabit Server Adapter" # for example), than MS Win return identical ifDescr sub interfaces { my $l3 = shift; my $partial = shift; my $interfaces = $l3->i_index($partial); my $descriptions = $l3->i_description($partial); my %interfaces = (); foreach my $iid ( keys %$interfaces ) { my $desc = $descriptions->{$iid}; next unless defined $desc; $interfaces{$iid} = sprintf( "(%U) %s", $iid, $desc ); } return \%interfaces; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Microsoft - SNMP Interface to L3 Microsoft Windows router =head1 AUTHOR begemot =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $router = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $router->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Generic Microsoft Routers running Microsoft Windows OS =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $router->vendor() Returns C<'microsoft'> =item $router->os() Returns C<'windows'> =item $router->os_ver() Returns '' =item $router->model() Returns C<'Windows Router'> =item $router->serial() Returns '' =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $router->interfaces() Map the Interfaces to their physical names. Adds interface number to interface name because identical interface cards return identical C. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Mikrotik.pm000444000765000024 1174013215550564 20574 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Mikrotik # $Id$ # # Copyright (c) 2011 Jeroen van Ingen # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Mikrotik; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Mikrotik::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Mikrotik::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'HOST-RESOURCES-MIB' => 'hrSystem', 'MIKROTIK-MIB' => 'mtxrLicVersion', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, 'hrSystemUptime' => 'hrSystemUptime', 'os_level' => 'mtxrLicLevel', 'os_ver' => 'mtxrLicVersion', 'serial1' => 'mtxrSystem.3.0', 'firmware' => 'mtxrSystem.4.0', 'fan_type' => 'mtxrHlActiveFan', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'mikrotik'; } sub serial { my $mikrotik = shift; return $mikrotik->serial1; } sub model { my $mikrotik = shift; my $descr = $mikrotik->description() || ''; my $model = undef; $model = $1 if ( $descr =~ /^RouterOS\s+(\S+)$/i ); return $model; } sub os { return 'routeros'; } sub board_temp { my $mikrotik = shift; my $temp = $mikrotik->mtxrHlTemperature; return $temp / 10.0; } sub cpu_temp { my $mikrotik = shift; my $temp = $mikrotik->mtxrHlProcessorTemperature; return $temp / 10.0; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Mikrotik - SNMP Interface to Mikrotik devices =head1 AUTHORS Jeroen van Ingen initial version based on SNMP::Info::Layer3::NetSNMP by Bradley Baetz and Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $mikrotik = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $mikrotik->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Mikrotik devices =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $mikrotik->vendor() Returns C<'mikrotik'>. =item $mikrotik->os() Returns C<'routeros'>. =item $mikrotik->model() Tries to extract the device model from C. =item $mikrotik->os_ver() Returns the value of C. =item $mikrotik->os_level() Returns the value of RouterOS level C =item $mikrotik->board_temp() =item $mikrotik->cpu_temp() Returns the appropriate temperature values =item $mikrotik->serial() Returns the device serial. =item $mikrotik->firmware() Returns the firmware version of hardware. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides None. =over =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/N1600.pm000444000765000024 1676413215550564 17522 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::N1600 - SNMP Interface to Nortel N16XX devices # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::N1600; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::SONMP; @SNMP::Info::Layer3::N1600::ISA = qw/SNMP::Info::Layer3 SNMP::Info::SONMP Exporter/; @SNMP::Info::Layer3::N1600::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::SONMP::MIBS, 'SWL2MGMT-MIB' => 'swL2MgmtMIB', 'RAPID-CITY' => 'rapidCity', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::SONMP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::SONMP::FUNCS, # SWL2MGMT-MIB # swL2PortInfoTable 'n1600_nway_status' => 'swL2PortInfoNwayStatus', # swL2PortCtrlTable 'n1600_nway_state' => 'swL2PortCtrlNwayState', ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::Layer3::MUNGE, %SNMP::Info::SONMP::MUNGE, ); # Method OverRides sub model { my $n1600 = shift; my $id = $n1600->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::N1600::model() - Device does not support sysObjectID\n" if $n1600->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^rcA//i; return $model; } sub vendor { return 'avaya'; } sub os { return 'passport'; } sub os_ver { my $n1600 = shift; my $descr = $n1600->description(); return unless defined $descr; if ( $descr =~ m/(\d+\.\d+\.\d+\.\d+)/ ) { return $1; } return; } sub interfaces { my $n1600 = shift; my $partial = shift; my $i_index = $n1600->i_index($partial) || {}; my %if; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; my $slotport = "1.$index"; $if{$iid} = $slotport; } return \%if; } sub i_duplex { my $n1600 = shift; my $partial = shift; my $nway_status = $n1600->n1600_nway_status($partial) || {}; my %i_duplex; foreach my $iid ( keys %$nway_status ) { my $duplex = $nway_status->{$iid}; next unless defined $duplex; next if $duplex =~ /other/i; $i_duplex{$iid} = 'half' if $duplex =~ /half/i; $i_duplex{$iid} = 'full' if $duplex =~ /full/i; } return \%i_duplex; } sub i_duplex_admin { my $n1600 = shift; my $partial = shift; my $nway_state = $n1600->n1600_nway_state($partial) || {}; my %i_duplex; foreach my $iid ( keys %$nway_state ) { my $duplex = $nway_state->{$iid}; next unless defined $duplex; next if $duplex =~ /other/i; $i_duplex{$iid} = 'half' if $duplex =~ /half/i; $i_duplex{$iid} = 'full' if $duplex =~ /full/i; $i_duplex{$iid} = 'auto' if $duplex =~ /nway-enabled/i; } return \%i_duplex; } # Required for SNMP::Info::SONMP sub index_factor { return 64; } 1; __END__ =head1 NAME SNMP::Info::Layer3::N1600 - SNMP Interface to Avaya/Nortel 16XX Network Devices =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $n1600 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $n1600->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from an Avaya/Nortel N16XX device through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $n1600 = new SNMP::Info::Layer3::N1600(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::SONMP =back =head2 Required MIBs =over =item F =item F =item Inherited Classes' MIBs See classes listed above for their required MIBs. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $n1600->bulkwalk_no Return C<1>. Bulkwalk is currently turned off for this class. =item $n1600->model() Returns model type. Checks $n1600->id() against the F and then parses out C. =item $n1600->vendor() Returns 'avaya' =item $n1600->os() Returns 'passport' =item $n1600->os_ver() Returns os version extracted from C. =back =head2 Overrides =over =item $n1600->index_factor() Required by SNMP::Info::SONMP. Number representing the number of ports reserved per slot within the device MIB. Returns 64 since largest switch has 48 ports. Since these switches can not stack, the only requirement to reserve more than the max number of ports. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Globals imported from SNMP::Info::SONMP See documentation in SNMP::SONMP::Layer3 for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $n1600->interfaces() Returns reference to hash of interface names to iids. Places a 1 in front of index number. This is required for compatibility with SNMP::Info::SONMP. =item $n1600->i_duplex() Returns reference to hash of interface operational link duplex status. =item $n1600->i_duplex_admin() Returns reference to hash of interface administrative link duplex status. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::SONMP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/NetSNMP.pm000444000765000024 1474513215550564 20237 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::NetSNMP # $Id$ # # Copyright (c) 2008 Bill Fenner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::NetSNMP; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; @SNMP::Info::Layer3::NetSNMP::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::NetSNMP::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, 'UCD-SNMP-MIB' => 'versionTag', 'NET-SNMP-TC' => 'netSnmpAgentOIDs', 'HOST-RESOURCES-MIB' => 'hrSystem', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, 'netsnmp_vers' => 'versionTag', 'hrSystemUptime' => 'hrSystemUptime', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub vendor { return 'Net-SNMP'; } sub os { my $netsnmp = shift; my $descr = $netsnmp->description(); return $1 if ( $descr =~ /^(\S+)\s+/ ); return; } sub os_ver { my $netsnmp = shift; my $descr = $netsnmp->description(); my $vers = $netsnmp->netsnmp_vers(); my $os_ver = undef; $os_ver = $1 if ( $descr =~ /^\S+\s+\S+\s+(\S+)\s+/ ); if ($vers) { $os_ver = "???" unless defined($os_ver); $os_ver .= " / Net-SNMP " . $vers; } return $os_ver; } sub serial { return ''; } # sysUptime gives us the time since the SNMP daemon has restarted, # so return the system uptime since that's probably what the user # wants. (Caution: this could cause trouble if using # sysUptime-based discontinuity timers or other TimeStamp # objects. sub uptime { my $netsnmp = shift; my $uptime; $uptime = $netsnmp->hrSystemUptime(); return $uptime if defined $uptime; return $netsnmp->SUPER::uptime(); } sub i_ignore { my $l3 = shift; my $partial = shift; my $interfaces = $l3->interfaces($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { # lo0 etc if ( $interfaces->{$if} =~ /\blo\d*\b/i ) { $i_ignore{$if}++; } } return \%i_ignore; } 1; __END__ =head1 NAME SNMP::Info::Layer3::NetSNMP - SNMP Interface to L3 Net-SNMP Devices =head1 AUTHORS Bradley Baetz and Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $netsnmp = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $netsnmp->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Generic Net-SNMP devices =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $netsnmp->vendor() Returns 'Net-SNMP'. =item $netsnmp->os() Returns the OS extracted from C. =item $netsnmp->os_ver() Returns the software version extracted from C, along with the Net-SNMP version. =item $netsnmp->uptime() Returns the system uptime instead of the agent uptime. NOTE: discontinuity timers and other Time Stamp based objects are based on agent uptime, so use orig_uptime(). =item $netsnmp->serial() Returns ''. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $netsnmp->i_ignore() Returns reference to hash. Increments value of IID if port is to be ignored. Ignores loopback =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =head1 NOTES In order to cause SNMP::Info to classify your device into this class, it may be necessary to put a configuration line into your F similar to sysobjectid .1.3.6.1.4.1.8072.3.2.N where N is the object ID for your OS from the C MIB (or 255 if not listed). Some Net-SNMP installations default to an incorrect return value for C. In order to recognize a Net-SNMP device as Layer3, it may be necessary to put a configuration line similar to sysservices 76 in your F. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Netscreen.pm000444000765000024 4523613215550564 20740 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Netscreen # # Copyright (c) 2012 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Netscreen; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::IEEE802dot11; @SNMP::Info::Layer3::Netscreen::ISA = qw/SNMP::Info::Layer3 SNMP::Info::IEEE802dot11 Exporter/; @SNMP::Info::Layer3::Netscreen::EXPORT_OK = qw//; use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::IEEE802dot11::MIBS, 'NETSCREEN-SMI' => 'netscreenSetting', 'NETSCREEN-PRODUCTS-MIB' => 'netscreenGeneric', 'NETSCREEN-INTERFACE-MIB' => 'nsIfIndex', 'NETSCREEN-SET-GEN-MIB' => 'nsSetGenSwVer', 'NETSCREEN-IP-ARP-MIB' => 'nsIpArpAOD', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::IEEE802dot11::GLOBALS, 'os_version' => 'nsSetGenSwVer', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::IEEE802dot11::FUNCS, ns_i_index => 'nsIfIndex', ns_i_name => 'nsIfName', ns_i_description => 'nsIfDescr', ns_i_mac => 'nsIfMAC', ns_i_up => 'nsIfStatus', ns_ip_table => 'nsIfIp', ns_ip_netmask => 'nsIfNetmask', bp_index => 'nsIfInfo', std_at_paddr => 'ipNetToMediaPhysAddress', ns_at_paddr => 'nsIpArpMac', ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::IEEE802dot11::MUNGE, 'ns_i_mac' => \&SNMP::Info::munge_mac, 'ns_at_paddr' => \&SNMP::Info::munge_mac, 'std_at_paddr' => \&SNMP::Info::munge_mac, ); sub layers { return '01001110'; } sub vendor { return 'juniper'; } sub os { return 'screenos'; } sub os_ver { my $netscreen = shift; my $descr = $netscreen->description(); if ( $descr =~ m/version (\d\S*) \(SN: / ) { return $1; } return; } sub serial { my $netscreen = shift; my $e_serial = $netscreen->e_serial() || {}; my $serial = $e_serial->{1} || undef; return $1 if ( defined $serial and $serial =~ /(\d+)/ ); my $descr = $netscreen->description(); if ( $descr =~ m/version .*\(SN: (\d\S*),/ ) { return $1; } return; } sub model { my $netscreen = shift; my $id = $netscreen->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::model() - Device does not support sysObjectID\n" if $netscreen->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^netscreen//i; return $model; } # provides mapping from IF-MIB to nsIf interfaces - many to 1 (!) # - on WLAN devices wireless0/0(|-[ag]) -> wireless0/0 !! sub _if_nsif_map { my $netscreen = shift; my $i_descr = $netscreen->SUPER::i_description; my $ns_descr = $netscreen->i_description; my %if_nsif_map = (); my @ikeys = sort { $a <=> $b } keys %$i_descr; my @nskeys = sort { $a <=> $b } keys %$ns_descr; my $i = 0; my $n = 0; # assumes descriptions are in the same order from both walks while ( $i < @ikeys && $n < @nskeys ) { # find matching sub interfaces while ( $i < @ikeys && substr( $i_descr->{ $ikeys[$i] }, 0, length $ns_descr->{ $nskeys[$n] } ) eq $ns_descr->{ $nskeys[$n] } ) { $if_nsif_map{ $ikeys[$i] } = $nskeys[$n]; $i++; } $n++; # skip non-matching interfaces (e.g. tunnel.N) while ( $i < @ikeys && substr( $i_descr->{ $ikeys[$i] }, 0, length $ns_descr->{ $nskeys[$n] } ) ne $ns_descr->{ $nskeys[$n] } && $n < @nskeys ) { $if_nsif_map{ $ikeys[$i] } = 0; # no matching interface $i++; } } return \%if_nsif_map; } # Provides mapping from nsIf interfaces to IF-MIB interfaces - many to 1 # Example, tunnel.# interfaces are not present in IF-MIB. There exist no # mapping of index IID's between the tables so create mapping based on names sub _nsif_if_map { my $netscreen = shift; my $i_descr = $netscreen->SUPER::i_description; my $ns_descr = $netscreen->i_description; my %rev_i_descr = reverse %$i_descr; my %rev_ns_descr = reverse %$ns_descr; my %nsif_if_map = (); foreach my $value ( values %$ns_descr ) { if ( exists $rev_i_descr{$value} ) { $nsif_if_map{ $rev_ns_descr{$value} } = $rev_i_descr{$value}; } else { $nsif_if_map{ $rev_ns_descr{$value} } = 0; } } return \%nsif_if_map; } sub interfaces { my $netscreen = shift; return $netscreen->i_description(); } sub i_index { my $netscreen = shift; return $netscreen->ns_i_index(); } sub i_name { my $netscreen = shift; return $netscreen->ns_i_name(); } sub i_description { my $netscreen = shift; # Versions prior to 5.4 do not support nsIfDescr but do have nsIfName return $netscreen->ns_i_description() || $netscreen->ns_i_name(); } sub i_mac { my $netscreen = shift; my $ns_mac = $netscreen->ns_i_mac() || {}; my $if_i_mac = $netscreen->SUPER::i_mac() || {}; my $ns_i_map = $netscreen->_nsif_if_map(); my %i_mac = (); foreach my $iid ( keys %$ns_i_map ) { $i_mac{$iid} = $ns_mac->{$iid} || $if_i_mac->{ $ns_i_map->{$iid} }; } return \%i_mac; } sub i_lastchange { my $netscreen = shift; my $if_i_lastchange = $netscreen->SUPER::i_lastchange() || {}; my $ns_i_map = $netscreen->_nsif_if_map(); my %i_lastchange; foreach my $iid ( keys %$ns_i_map ) { $i_lastchange{$iid} = $if_i_lastchange->{ $ns_i_map->{$iid} }; } return \%i_lastchange; } sub i_up { my $netscreen = shift; return $netscreen->ns_i_up(); } sub i_up_admin { my $netscreen = shift; my $i_up = $netscreen->i_up(); my $i_up_admin = $netscreen->SUPER::i_up_admin(); my $ns_i_map = $netscreen->_nsif_if_map(); my %i_up_admin; foreach my $iid ( keys %$ns_i_map ) { $i_up_admin{$iid} = $i_up->{$iid} eq "up" && "up" || $i_up_admin->{ $ns_i_map->{$iid} } || 0; } return \%i_up_admin; } sub i_type { my $netscreen = shift; my $if_i_type = $netscreen->SUPER::i_type() || {}; my $ns_i_map = $netscreen->_nsif_if_map(); my %i_type; foreach my $iid ( keys %$ns_i_map ) { $i_type{$iid} = $if_i_type->{ $ns_i_map->{$iid} } || "tunnel"; } return \%i_type; } sub i_mtu { my $netscreen = shift; my $i_type = $netscreen->SUPER::i_mtu() || {}; my $ns_i_map = $netscreen->_nsif_if_map(); my %i_mtu; foreach my $iid ( keys %$ns_i_map ) { $i_mtu{$iid} = $i_type->{ $ns_i_map->{$iid} }; } return \%i_mtu; } sub i_ignore { return; } sub i_speed { my $netscreen = shift; my $i_speed = $netscreen->SUPER::i_speed(); my $i_name = $netscreen->i_name(); my $ns_i_map = $netscreen->_nsif_if_map; my %i_speed; foreach my $iid ( keys %$ns_i_map ) { $i_speed{$iid} = $i_speed->{ $ns_i_map->{$iid} } || $i_name->{$iid} =~ /tunnel/ && "vpn" || 0; } return \%i_speed; } sub _mac_map { my $netscreen = shift; my $arp_mac = $netscreen->nsIpArpMac() || {}; my %mac_map = (); foreach my $iid ( keys %$arp_mac ) { my $oid = join( ".", ( unpack( "C6", $arp_mac->{$iid} ) ) ); $mac_map{$oid} = $iid; } return \%mac_map; } # Interfaces can have two addresses, we want to capture both the network # address and the management address sub ip_index { my $netscreen = shift; my $ns_ip = $netscreen->ns_ip_table() || {}; my $if_mng_ip = $netscreen->nsIfMngIp() || {}; my %ip_index = (); foreach my $iid ( keys %$ns_ip ) { $ip_index{ $ns_ip->{$iid} } = $iid if $ns_ip->{$iid} ne "0.0.0.0"; } foreach my $iid ( keys %$if_mng_ip ) { $ip_index{ $if_mng_ip->{$iid} } = $iid if $if_mng_ip->{$iid} ne "0.0.0.0"; } return \%ip_index; } sub ip_table { my $netscreen = shift; my $ip_index = $netscreen->ip_index() || {}; my $if_mng_ip = $netscreen->nsIfMngIp() || {}; my %ip_table = (); foreach my $iid ( keys %$ip_index ) { my $mgmt_ip = $if_mng_ip->{$iid}; if ( defined $mgmt_ip && $mgmt_ip ne '0.0.0.0' ) { $ip_table{$iid} = $mgmt_ip; } else { $ip_table{$iid} = $iid; } } return \%ip_table; } # There is only one netmask for the interface both network and management # addresses should have the same netmask sub ip_netmask { my $netscreen = shift; my $ip_index = $netscreen->ip_index() || {}; my $ns_netmask = $netscreen->ns_ip_netmask(); my %ip_netmask = (); foreach my $iid ( keys %$ip_index ) { $ip_netmask{$iid} = $ns_netmask->{ $ip_index->{$iid} }; } return \%ip_netmask; } sub fw_index { my $netscreen = shift; my %fw_index = (); my $arp_mac = $netscreen->nsIpArpMac() || {}; foreach my $iid ( keys %$arp_mac ) { my $oid = join( ".", ( unpack( "C6", $arp_mac->{$iid} ) ) ); $fw_index{$iid} = $oid; } return \%fw_index; } sub fw_mac { my $netscreen = shift; my $mac_map = $netscreen->_mac_map() || {}; my %fw_mac = (); foreach my $oid ( keys %$mac_map ) { my $mac = join( ":", ( map { sprintf "%lx", $_ } split( /\./, $oid ) ) ); $fw_mac{$oid} = $mac; } return \%fw_mac; } sub bp_index { my $netscreen = shift; my $if_info = $netscreen->nsIfInfo() || {}; my %bp_index = (); foreach my $iid ( keys %$if_info ) { $bp_index{ $if_info->{$iid} } = $iid; } return \%bp_index; } sub fw_port { my $netscreen = shift; my $fw_index = $netscreen->fw_index(); my $arp_if = $netscreen->nsIpArpIfIdx() || {}; my %fw_port; foreach my $iid ( keys %$arp_if ) { $fw_port{ $fw_index->{$iid} } = $arp_if->{$iid} if defined $fw_index->{$iid}; } return \%fw_port; } # need to remap from IF-MIB index to nsIf index sub i_ssidlist { my $netscreen = shift; my $i_ssidlist = $netscreen->SUPER::i_ssidlist() || {}; my $ns_i_map = $netscreen->_if_nsif_map(); my %i_ssidlist; foreach my $iid ( keys %$i_ssidlist ) { $i_ssidlist{ $ns_i_map->{$iid} } = $i_ssidlist->{$iid}; } return \%i_ssidlist; } sub i_80211channel { my $netscreen = shift; my $i_80211channel = $netscreen->SUPER::i_80211channel() || {}; my $ns_i_map = $netscreen->_if_nsif_map(); my %i_80211channel; foreach my $iid ( keys %$i_80211channel ) { $i_80211channel{ $ns_i_map->{$iid} } = $i_80211channel->{$iid}; } return \%i_80211channel; } sub at_index { my $netscreen = shift; my $std = $netscreen->ipNetToMediaIfIndex(); return $std if (ref {} eq ref $std and scalar keys %$std); return $netscreen->nsIpArpIfIdx(); } sub at_paddr { my $netscreen = shift; my $std = $netscreen->std_at_paddr(); return $std if (ref {} eq ref $std and scalar keys %$std); return $netscreen->ns_at_paddr(); } sub at_netaddr { my $netscreen = shift; my $std = $netscreen->ipNetToMediaNetAddress(); return $std if (ref {} eq ref $std and scalar keys %$std); return $netscreen->nsIpArpIp(); } 1; __END__ =head1 NAME SNMP::Info::Layer3::Netscreen - SNMP Interface to Juniper Netscreen Devices =head1 AUTHOR Kent Hamilton =head1 SYNOPSIS #Let SNMP::Info determine the correct subclass for you. my $netscreen = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $netscreen->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a Juniper Netscreen devices through SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $netscreen = new SNMP::Info::Layer3::Netscreen(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::IEEE802dot11 =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =item Inherited Classes' MIBs See L for its MIB requirements. See L for its MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $netscreen->model() Tries to reference $netscreen->id() to F =item $netscreen->vendor() Returns C<'juniper'> =item $netscreen->os() Returns C<'screenos'> =item $netscreen->os_ver() Extracts the OS version from the description string. =item $netscreen->serial() Returns serial number. =back =head2 Overrides =over =item $netscreen->layers() Returns 01001110. Device doesn't report layers properly, modified to reflect Layer 2 and 3 functionality. =back =head2 Globals imported from SNMP::Info::Layer3 See L for details. =head2 Globals imported from SNMP::Info::IEEE802dot11 See L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =head3 Interface Information =over =item $netscreen->interfaces() Creates a map between the interface identifier (iid) and the physical port name. Defaults to C if available, uses C if not. =item $netscreen->i_description() Description of the interface. Uses C if available, C if not. =item $netscreen->i_ignore() Returns without defining any interfaces to ignore. =item $netscreen->i_index() Default SNMP IID to Interface index. (C) =item $netscreen->i_lastchange() The value of C when this port last changed states (up,down), maps from C to C. (C) =item $netscreen->i_mac() MAC address of the interface. Note this is just the MAC of the port, not anything connected to it. Uses C if available, C if not. =item $netscreen->i_mtu() INTEGER. Interface MTU value, maps from C to C. (C) =item $netscreen->i_name() Interface Name field. (C) =item $netscreen->i_speed() Speed of the link, maps from C to C. =item $netscreen->i_type() Interface type. Maps from C to C. (C) =item $netscreen->i_up() Link Status of the interface. Typical values are 'up' and 'down'. (C) =item $netscreen->i_up_admin() Administrative status of the port. Checks both C and C. =back =head3 IP Address Table Each entry in this table is an IP address in use on this device. =over =item $netscreen->ip_index() Maps the IP Table to the IID =item $netscreen->ip_table() Maps the Table to the IP address (C) =item $netscreen->ip_netmask() Gives netmask setting for IP table entry. (C) =back =head3 Forwarding Table Uses C to emulate the forwarding table. =over =item $netscreen->fw_index() Maps the Forwarding Table to the IID =item $netscreen->fw_mac() Returns reference to hash of forwarding table MAC Addresses. =item $netscreen->fw_port() Returns reference to hash of forwarding table entries port interface identifier (IID). =item $netscreen->bp_index() Returns reference to hash of bridge port table entries map back to interface identifier (IID). =back =head2 Arp Cache Table =over =item $netscreen->at_index() Returns reference to hash. Maps ARP table entries to Interface IIDs If the device doesn't support C, this will try the proprietary C. =item $netscreen->at_paddr() Returns reference to hash. Maps ARP table entries to MAC addresses. If the device doesn't support C, this will try the proprietary C. =item $netscreen->at_netaddr() Returns reference to hash. Maps ARP table entries to IP addresses. If the device doesn't support C, this will try the proprietary C. =back =head3 Wireless Information =over =item $dot11->i_ssidlist() Returns reference to hash. SSID's recognized by the radio interface. Remaps from C to C. (C) =item $dot11->i_80211channel() Returns reference to hash. Current operating frequency channel of the radio interface. Remaps from C to C. =back =head2 Table Methods imported from SNMP::Info::Layer3 See L for details. =head2 Table Methods imported from SNMP::Info::IEEE802dot11 See L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Nexus.pm000444000765000024 2364013215550564 20107 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Nexus # # Copyright (c) 2014 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Nexus; use strict; use warnings; use Exporter; use SNMP::Info::Layer3::CiscoSwitch; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; # NOTE : Top-most items gets precedence for @ISA @SNMP::Info::Layer3::Nexus::ISA = qw/ SNMP::Info::Layer3::CiscoSwitch Exporter /; @SNMP::Info::Layer3::Nexus::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; # NOTE: Order creates precedence # Example: v_name exists in Bridge.pm and CiscoVTP.pm # Bridge is called from Layer3 and CiscoStpExtensions # So we want CiscoVTP to come last to get the right one. # The @ISA order should be reverse of these orders. %MIBS = ( %SNMP::Info::Layer3::CiscoSwitch::MIBS, 'CISCO-ENTITY-VENDORTYPE-OID-MIB' => 'cevMIBObjects', ); %GLOBALS = ( %SNMP::Info::Layer3::CiscoSwitch::GLOBALS, 'mac' => 'dot1dBaseBridgeAddress', ); %FUNCS = ( %SNMP::Info::Layer3::CiscoSwitch::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::CiscoSwitch::MUNGE, ); sub os { return 'nx-os'; } sub os_ver { my $nexus = shift; my $descr = $nexus->description(); return $1 if ( $descr =~ /\),\s+Version\s+(.+?),/ ); return $descr; } sub _get_snmpid_chassis { my $self = shift; my $funcname = (caller(0))[3]; # Name of this sub, including package, used for debug logging my $snmpid_chassis; my $position; my $entity_entry = $self->e_class; for ( keys %$entity_entry ) { # filter by class (chassis is 3, but with proper MIBs loaded we should get the translated textual value) if ( ($entity_entry->{$_} eq 'chassis') or ($entity_entry->{$_} eq '3') ) { printf("%s - chassis with id %s found, position %s\n", $funcname, $_, $self->e_pos->{$_}) if $self->debug(); # and if it's the topmost one if ( !defined $position || $self->e_pos->{$_} < $position ) { $snmpid_chassis = $_; $position = $self->e_pos->{$_}; } } } if ( defined $snmpid_chassis && defined $position ) { printf(" %s - chassis with id %s, position %s selected\n", $funcname, $snmpid_chassis, $position); } else { printf(" %s - no chassis found\n", $funcname); } return $snmpid_chassis; } sub serial { my $nexus = shift; my $snmpid_chassis = $nexus->_get_snmpid_chassis; return $nexus->e_serial($snmpid_chassis)->{$snmpid_chassis} if defined $snmpid_chassis; return; } # sysObjectID returns an IID to an entry in the CISCO-ENTITY-VENDORTYPE-OID-MIB. # Look it up and return it. sub model { my $nexus = shift; my $id = $nexus->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::Nexus::model() - Device does not support sysObjectID\n" if $nexus->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^cevChassis//i; return $model; } # Reported version 6.x of NX-OS doesn't use the IPv4 address as index # override methods in ipAddrTable sub ip_table { my $nexus = shift; my $orig_ip_table = $nexus->orig_ip_table(); my %ip_table; foreach my $iid ( keys %$orig_ip_table ) { my $ip = $orig_ip_table->{$iid}; next unless defined $ip; $ip_table{$ip} = $ip; } my $local_addrs = $nexus->_local_addr(); foreach my $addr (keys %$local_addrs) { $ip_table{$addr} = $addr unless exists $ip_table{$addr}; } return \%ip_table; } sub ip_index { my $nexus = shift; my $orig_ip_table = $nexus->orig_ip_table(); my $orig_ip_index = $nexus->orig_ip_index(); my %ip_index; foreach my $iid ( keys %$orig_ip_table ) { my $ip = $orig_ip_table->{$iid}; my $index = $orig_ip_index->{$iid}; next unless ( defined $ip && defined $index ); $ip_index{$ip} = $index; } my $local_addrs = $nexus->_local_addr(); foreach my $addr (keys %$local_addrs) { $ip_index{$addr} = 0 unless exists $ip_index{$addr}; } return \%ip_index; } sub ip_netmask { my $nexus = shift; my $orig_ip_table = $nexus->orig_ip_table(); my $orig_ip_netmask = $nexus->orig_ip_netmask(); my %ip_netmask; foreach my $iid ( keys %$orig_ip_table ) { my $ip = $orig_ip_table->{$iid}; my $netmask = $orig_ip_netmask->{$iid}; next unless ( defined $ip && defined $netmask ); $ip_netmask{$ip} = $netmask; } my $local_addrs = $nexus->_local_addr(); foreach my $addr (keys %$local_addrs) { $ip_netmask{$addr} = $local_addrs->{$addr} unless exists $ip_netmask{$addr}; } return \%ip_netmask; } sub ip_broadcast { my $nexus = shift; my $orig_ip_table = $nexus->orig_ip_table(); my $orig_ip_broadcast = $nexus->orig_ip_broadcast(); my %ip_broadcast; foreach my $iid ( keys %$orig_ip_table ) { my $ip = $orig_ip_table->{$iid}; my $broadcast = $orig_ip_broadcast->{$iid}; next unless ( defined $ip && defined $broadcast ); $ip_broadcast{$ip} = $broadcast; } my $local_addrs = $nexus->_local_addr(); foreach my $addr (keys %$local_addrs) { $ip_broadcast{$addr} = $addr unless exists $ip_broadcast{$addr}; } return \%ip_broadcast; } sub _local_addr { my $nexus = shift; my $listen_addr = $nexus->udpLocalAddress() || {}; my %local_addr; foreach my $sock (keys %$listen_addr) { my $addr = $listen_addr->{$sock}; next if ($addr =~ /^127\./); # localhost next if ($addr eq '0.0.0.0'); # "any" next if ($addr =~ /^(\d+)\./ and $1 ge 224); # Class D or E space: Multicast or Experimental $local_addr{$addr} = '255.255.255.255'; # Fictional netmask } return \%local_addr; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Nexus - SNMP Interface to Cisco Nexus Switches running NX-OS =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $nexus = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $nexus->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Cisco Nexus Switches running NX-OS. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $nexus = new SNMP::Info::Layer3::Nexus(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3::CiscoSwitch =back =head2 Required MIBs =over =item F =back =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return a scalar value from SNMP =over =item $nexus->os() Returns C<'nx-os'> =item $nexus->os_ver() Returns operating system version extracted from C. =item $nexus->serial() Returns the serial number of the chassis from F. =item $nexus->model() Tries to reference $nexus->id() to F Removes C<'cevChassis'> for readability. =item $nexus->mac() C =back =head2 Overrides =head3 IP Address Table Each entry in this table is an IP address in use on this device. Some versions do not index the table with the IPv4 address in accordance with the MIB definition, these overrides correct that behavior. Also, the table is augmented with IP addresses in use by UDP sockets on the device, as determined by checking F. Valid addresses from this table (any IPv4 that is not localhost, 0.0.0.0, Class D (multicast) or Class E (experimental) are added as a /32 on interface ID 0. This is a workaround to determine possible VPC Keepalive IP addresses on the device, which are probably advertised by CDP/LLDP to neighbors. =over =item $nexus->ip_index() Maps the IP Table to the IID (C) =item $nexus->ip_table() Maps the Table to the IP address (C) =item $nexus->ip_netmask() Gives netmask setting for IP table entry. (C) =item $nexus->ip_broadcast() Gives broadcast address for IP table entry. (C) =back =head2 Globals imported from SNMP::Info::Layer3::CiscoSwitch See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer3::CiscoSwitch See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/PacketFront.pm000444000765000024 1334413215550564 21225 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::PacketFront # $Id$ # # Copyright (c) 2011 Jeroen van Ingen # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::PacketFront; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::PacketFront::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::PacketFront::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'UCD-SNMP-MIB' => 'versionTag', 'NET-SNMP-TC' => 'netSnmpAgentOIDs', 'HOST-RESOURCES-MIB' => 'hrSystem', 'PACKETFRONT-PRODUCTS-MIB' => 'drg100', 'PACKETFRONT-DRG-MIB' => 'productName', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, 'snmpd_vers' => 'versionTag', 'hrSystemUptime' => 'hrSystemUptime', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'packetfront'; } sub os { # Only DRGOS for now (not tested with other product lines than DRG series) my $pfront = shift; my $descr = $pfront->description(); if ( $descr =~ /drgos/i ) { return 'drgos'; } else { return; } } sub os_ver { my $pfront = shift; my $descr = $pfront->description(); my $os_ver = undef; if ( $descr =~ /Version:\sdrgos-(\w+)-([\w\-\.]+)/ ) { $os_ver = $2; } return $os_ver; } sub serial { my $pfront = shift; return $pfront->productSerialNo(); } sub i_ignore { my $l3 = shift; my $partial = shift; my $interfaces = $l3->interfaces($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { # lo0 etc if ( $interfaces->{$if} =~ /\blo\d*\b/i ) { $i_ignore{$if}++; } } return \%i_ignore; } sub layers { my $pfront = shift; my $layers = $pfront->SUPER::layers(); # Some models or softwware versions don't report L2 properly # so add L2 capability to the output if the device has bridge ports. my $bports = $pfront->b_ports(); if ($bports) { my $l = substr $layers, 6, 1, "1"; } return $layers; } 1; __END__ =head1 NAME SNMP::Info::Layer3::PacketFront - SNMP Interface to PacketFront devices =head1 AUTHORS Jeroen van Ingen initial version based on SNMP::Info::Layer3::NetSNMP by Bradley Baetz and Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $pfront = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $pfront->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for PacketFront devices =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item F =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $pfront->vendor() Returns C<'packetfront'>. =item $pfront->os() Returns the OS extracted from C. =item $pfront->os_ver() Returns the software version extracted from C. =item $pfront->serial() Returns the value of C. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $pfront->i_ignore() Returns reference to hash. Increments value of IID if port is to be ignored. Ignores loopback =item $pfront->layers() L2 capability isn't always reported correctly by the device itself; what the device reports is augmented with L2 capability if the device has bridge ports. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/PaloAlto.pm000444000765000024 1056213215550564 20517 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::PaloAlto # # Copyright (c) 2014-2016 Max Kosmach # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::PaloAlto; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::PaloAlto::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::PaloAlto::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'PAN-COMMON-MIB' => 'panSysSwVersion', 'PAN-PRODUCTS-MIB' => 'panProductsMibsModule', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, 'mac' => 'ifPhysAddress.1', # Oids from PAN-COMMON-MIB. 'os_ver' => 'panSysSwVersion', 'serial1' => 'panSysSerialNumber', 'pa_model' => 'panChassisType' ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'Palo Alto Networks'; } sub model { my $pa = shift; my $model = $pa->pa_model; $model =~ s/^pan//; return $model; } sub os { return 'PAN-OS'; } sub layers { return '01001100'; } # TODO: # support fan and temp sensors from ENTITY-SENSOR-MIB # test with other Palo Alto devices 1; __END__ =head1 NAME SNMP::Info::Layer3::PaloAlto - SNMP Interface to Palo Alto devices =head1 AUTHORS Max Kosmach =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $pa = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $pa->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Palo Alto devices =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $pa->vendor() Returns C<'Palo Alto Networks'>. =item $pa->os() Returns C<'PANOS'>. =item $pa->model() Returns the value of C. =item $pa->os_ver() Returns the value of C. =item $pa->serial() Returns the value of C. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $pa->layers() Returns 01001110. Palo Alto doesn't report layers, modified to reflect Layer 2,3,4,7 functionality. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Passport.pm000444000765000024 11642613215550564 20645 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Passport # # Copyright (c) 2016 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Passport; use warnings; use strict; use Exporter; use SNMP::Info::SONMP; use SNMP::Info::RapidCity; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Passport::ISA = qw/SNMP::Info::SONMP SNMP::Info::RapidCity SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Passport::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::RapidCity::MIBS, %SNMP::Info::SONMP::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::RapidCity::GLOBALS, %SNMP::Info::SONMP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::RapidCity::FUNCS, %SNMP::Info::SONMP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::RapidCity::MUNGE, %SNMP::Info::SONMP::MUNGE, ); sub model { my $passport = shift; my $id = $passport->id(); unless ( defined $id ) { print " SNMP::Info::Layer3::Passport::model() - Device does not support sysObjectID\n" if $passport->debug(); return; } my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^rc(A)?//i; return $model; } sub vendor { return 'avaya'; } sub os { return 'passport'; } sub os_ver { my $passport = shift; my $descr = $passport->description(); return unless defined $descr; #ERS / Passport if ( $descr =~ m/(\d+\.\d+\.\d+\.\d+)/ ) { return $1; } #Accelar if ( $descr =~ m/(\d+\.\d+\.\d+)/ ) { return $1; } return; } sub i_index { my $passport = shift; my $partial = shift; my $i_index = $passport->orig_i_index($partial); my $model = $passport->model(); my %if_index; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; $if_index{$iid} = $index; } # Get VLAN Virtual Router Interfaces if (!defined $partial || (defined $model && ( ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ ) || ( $partial > 256 && $model =~ /^1[012][05]0/ ) ) ) ) { my $vlan_index = $passport->rc_vlan_if() || {}; foreach my $vid ( keys %$vlan_index ) { my $v_index = $vlan_index->{$vid}; next unless defined $v_index; next if $v_index == 0; next if ( defined $partial and $v_index !~ /^$partial$/ ); $if_index{$v_index} = $v_index; } } if ( defined $model and $model =~ /^8[86]/ ) { my $cpu_index = $passport->rc_cpu_ifindex($partial) || {}; my $virt_ip = $passport->rc_virt_ip(); # Get CPU Ethernet Interfaces foreach my $cid ( keys %$cpu_index ) { my $c_index = $cpu_index->{$cid}; next unless defined $c_index; next if $c_index == 0; $if_index{$c_index} = $c_index; } # Check for Virtual Mgmt Interface unless ( $virt_ip eq '0.0.0.0' ) { # Make up an index number, 1 is not reserved AFAIK $if_index{1} = 1; } } return \%if_index; } sub interfaces { my $passport = shift; my $partial = shift; my $i_index = $passport->i_index($partial); my $i_descr = $passport->orig_i_description($partial) || {}; my $model = $passport->model(); my $index_factor = $passport->index_factor(); my $port_offset = $passport->port_offset(); my $slot_offset = $passport->slot_offset(); my $vlan_index = {}; my %reverse_vlan; my $vlan_id = {}; if (!defined $partial || (defined $model && ( ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ ) || ( $partial > 256 && $model =~ /^1[012][05]0/ ) ) ) ) { $vlan_index = $passport->rc_vlan_if() || {}; %reverse_vlan = reverse %$vlan_index; $vlan_id = $passport->rc_vlan_id(); } my %if; foreach my $iid ( keys %$i_index ) { my $index = $i_index->{$iid}; next unless defined $index; if ( ( $index == 1 ) and ( $model =~ /^8[86]/ ) ) { $if{$index} = 'Cpu.Virtual'; } elsif ( ( $iid == 64 ) and ( $model =~ /^VSP[478]/ ) ) { $if{$index} = 'Mgmt.1'; } elsif ( ( $index == 192 ) and ( $model =~ /^8[86]03/ ) ) { $if{$index} = 'Cpu.3'; } elsif ( ( $index == 320 ) and ( $model =~ /^8[86][10][06]/ ) ) { $if{$index} = 'Cpu.5'; } elsif ( ( $index == 384 ) and ( $model =~ /^8[86][10][06]/ ) ) { $if{$index} = 'Cpu.6'; } elsif (( $index > 2000 and $model =~ /^8[8631]|16|VSP/ ) or ( $index > 256 and $model =~ /^1[012][05]0/ ) ) { my $v_index = $reverse_vlan{$iid}; my $v_id = $vlan_id->{$v_index}; next unless defined $v_id; my $v_port = 'Vlan' . "$v_id"; $if{$index} = $v_port; } else { if ($model =~ /VSP/ and $i_descr->{$iid} and $i_descr->{$iid} =~ m) { my $ps = $1; $ps =~ s|/|.|g; $if{$iid} = $ps; } else { my $port = ( $index % $index_factor ) + $port_offset; my $slot = int( $index / $index_factor ) + $slot_offset; my $slotport = "$slot.$port"; $if{$iid} = $slotport; } } } return \%if; } sub i_mac { my $passport = shift; my $partial = shift; my $i_mac = $passport->orig_i_mac($partial) || {}; my $model = $passport->model(); my %if_mac; foreach my $iid ( keys %$i_mac ) { my $mac = $i_mac->{$iid}; next unless defined $mac; $if_mac{$iid} = $mac; } # Get VLAN Virtual Router Interfaces if (!defined $partial || (defined $model && ( ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ ) || ( $partial > 256 && $model =~ /^1[012][05]0/ ) ) ) ) { my $vlan_index = $passport->rc_vlan_if() || {}; my $vlan_mac = $passport->rc_vlan_mac() || {}; foreach my $iid ( keys %$vlan_mac ) { my $v_mac = $vlan_mac->{$iid}; next unless defined $v_mac; my $v_id = $vlan_index->{$iid}; next unless defined $v_id; next if ( defined $partial and $v_id !~ /^$partial$/ ); $if_mac{$v_id} = $v_mac; } } if ( defined $model and $model =~ /^8[86]/ ) { my $cpu_mac = $passport->rc_cpu_mac($partial) || {}; my $virt_ip = $passport->rc_virt_ip() || '0.0.0.0'; # Get CPU Ethernet Interfaces foreach my $iid ( keys %$cpu_mac ) { my $mac = $cpu_mac->{$iid}; next unless defined $mac; $if_mac{$iid} = $mac; } # Check for Virtual Mgmt Interface unless ( ( $virt_ip eq '0.0.0.0' ) or ( defined $partial and $partial ne "1" ) ) { my $chassis_base_mac = $passport->rc_base_mac(); if ( defined $chassis_base_mac ) { my @virt_mac = split /:/, $chassis_base_mac; $virt_mac[0] = hex( $virt_mac[0] ); $virt_mac[1] = hex( $virt_mac[1] ); $virt_mac[2] = hex( $virt_mac[2] ); $virt_mac[3] = hex( $virt_mac[3] ); $virt_mac[4] = hex( $virt_mac[4] ) + 0x03; $virt_mac[5] = hex( $virt_mac[5] ) + 0xF8; my $mac = join( ':', map { sprintf "%02x", $_ } @virt_mac ); $if_mac{1} = $mac; } } } return \%if_mac; } sub i_description { my $passport = shift; my $partial = shift; my $i_descr = $passport->orig_i_description($partial) || {}; my $model = $passport->model(); my %descr; foreach my $iid ( keys %$i_descr ) { my $if_descr = $i_descr->{$iid}; next unless defined $if_descr; $descr{$iid} = $if_descr; } # Get VLAN Virtual Router Interfaces if (!defined $partial || (defined $model && ( ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ ) || ( $partial > 256 && $model =~ /^1[012][05]0/ ) ) ) ) { my $v_descr = $passport->v_name(); my $vlan_index = $passport->rc_vlan_if(); foreach my $vid ( keys %$v_descr ) { my $vl_descr = $v_descr->{$vid}; next unless defined $vl_descr; my $v_id = $vlan_index->{$vid}; next unless defined $v_id; next if ( defined $partial and $v_id !~ /^$partial$/ ); $descr{$v_id} = $vl_descr; } } return \%descr; } sub i_name { my $passport = shift; my $partial = shift; my $model = $passport->model(); my $i_index = $passport->i_index($partial) || {}; my $rc_alias = $passport->rc_alias($partial) || {}; my $i_name2 = $passport->orig_i_name($partial) || {}; my $v_name = {}; my $vlan_index = {}; my %reverse_vlan; if (!defined $partial || (defined $model && ( ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ ) || ( $partial > 256 && $model =~ /^1[012][05]0/ ) ) ) ) { $v_name = $passport->v_name() || {}; $vlan_index = $passport->rc_vlan_if() || {}; %reverse_vlan = reverse %$vlan_index; } my %i_name; foreach my $iid ( keys %$i_index ) { if ( ( $iid == 1 ) and ( $model =~ /^8[86]/ ) ) { $i_name{$iid} = 'CPU Virtual Management IP'; } elsif ( ( $iid == 64 ) and ( $model =~ /^VSP[478]/ ) ) { $i_name{$iid} = 'Mgmt Port'; } elsif ( ( $iid == 192 ) and ( $model =~ /^8[86]03/ ) ) { $i_name{$iid} = 'CPU 3 Ethernet Port'; } elsif ( ( $iid == 320 ) and ( $model =~ /^8[86][10][06]/ ) ) { $i_name{$iid} = 'CPU 5 Ethernet Port'; } elsif ( ( $iid == 384 ) and ( $model =~ /^8[86][10][06]/ ) ) { $i_name{$iid} = 'CPU 6 Ethernet Port'; } elsif ( ( $iid > 2000 and defined $model and $model =~ /^8[8631]|16|VSP/ ) or ( $iid > 256 and defined $model and $model =~ /^1[012][05]0/ ) ) { my $vlan_idx = $reverse_vlan{$iid}; my $vlan_name = $v_name->{$vlan_idx}; next unless defined $vlan_name; $i_name{$iid} = $vlan_name; } else { my $name = $i_name2->{$iid}; my $alias = $rc_alias->{$iid}; $i_name{$iid} = ( defined $alias and $alias !~ /^\s*$/ ) ? $alias : $name; } } return \%i_name; } sub ip_index { my $passport = shift; my $partial = shift; my $model = $passport->model(); my $ip_index = $passport->orig_ip_index($partial) || {}; my %ip_index; foreach my $ip ( keys %$ip_index ) { my $iid = $ip_index->{$ip}; next unless defined $iid; # Skip VSP default CPU addresses next if ($ip =~ /^192\.168\.1\.1/); # Skip default CPU addresses next if ($ip =~ /^192\.168\.168\.16[89]/); $ip_index{$ip} = $iid; } # Only 8600 has CPU and Virtual Management IP if ( defined $model and $model =~ /^8[86]/ ) { my $cpu_ip = $passport->rc_cpu_ip($partial) || {}; my $virt_ip = $passport->rc_virt_ip($partial); # Get CPU Ethernet IP foreach my $cid ( keys %$cpu_ip ) { my $c_ip = $cpu_ip->{$cid}; next unless defined $c_ip; # Skip default CPU addresses next if ($c_ip =~ /192\.168\.168\.16[89]/); $ip_index{$c_ip} = $cid; } # Get Virtual Mgmt IP $ip_index{$virt_ip} = 1 if ( defined $virt_ip ); } return \%ip_index; } sub ip_netmask { my $passport = shift; my $partial = shift; my $model = $passport->model(); my $ip_mask = $passport->orig_ip_netmask($partial) || {}; my %ip_index; foreach my $iid ( keys %$ip_mask ) { # Skip VSP default CPU addresses next if ($iid =~ /^192\.168\.1\./); # Skip default CPU addresses next if ($iid =~ /^192\.168\.168\.16[89]/); my $mask = $ip_mask->{$iid}; next unless defined $mask; $ip_index{$iid} = $mask; } # Only 8600 has CPU and Virtual Management IP if ( defined $model and $model =~ /^8[86]/ ) { my $cpu_ip = $passport->rc_cpu_ip($partial) || {}; my $cpu_mask = $passport->rc_cpu_mask($partial) || {}; my $virt_ip = $passport->rc_virt_ip($partial); my $virt_mask = $passport->rc_virt_mask($partial) || {}; # Get CPU Ethernet IP foreach my $iid ( keys %$cpu_mask ) { my $c_ip = $cpu_ip->{$iid}; next unless defined $c_ip; # Skip default CPU addresses next if ($c_ip =~ /192\.168\.168\.16[89]/); my $c_mask = $cpu_mask->{$iid}; next unless defined $c_mask; $ip_index{$c_ip} = $c_mask; } # Get Virtual Mgmt IP $ip_index{$virt_ip} = $virt_mask if ( defined $virt_mask and defined $virt_ip ); } return \%ip_index; } sub root_ip { my $passport = shift; my $model = $passport->model(); my $rc_ip_addr = $passport->rc_ip_addr(); my $rc_ip_type = $passport->rc_ip_type(); my $virt_ip = $passport->rc_virt_ip(); my $router_ip = $passport->router_ip(); my $sonmp_topo_port = $passport->sonmp_topo_port(); my $sonmp_topo_ip = $passport->sonmp_topo_ip(); # Only 8600 and 1600 have CLIP or Management Virtual IP if ( defined $model and $model =~ /^8[86]|16|VSP/ ) { # Return CLIP (CircuitLess IP) foreach my $iid ( keys %$rc_ip_type ) { my $ip_type = $rc_ip_type->{$iid}; next unless ( ( defined $ip_type ) and ( $ip_type =~ /circuitLess/i ) ); my $ip = $rc_ip_addr->{$iid}; next unless defined $ip; return $ip if $passport->snmp_connect_ip($ip); } # Return Management Virtual IP address if ( ( defined $virt_ip ) and ( $virt_ip ne '0.0.0.0' ) ) { return $virt_ip if $passport->snmp_connect_ip($virt_ip); } } # Return OSPF Router ID if ( ( defined $router_ip ) and ( $router_ip ne '0.0.0.0' ) ) { foreach my $iid ( keys %$rc_ip_addr ) { my $ip = $rc_ip_addr->{$iid}; next unless $router_ip eq $ip; return $router_ip if $passport->snmp_connect_ip($router_ip); } } # Otherwise Return SONMP Advertised IP Address foreach my $entry ( keys %$sonmp_topo_port ) { my $port = $sonmp_topo_port->{$entry}; next unless $port == 0; my $ip = $sonmp_topo_ip->{$entry}; return $ip if (( defined $ip ) and ( $ip ne '0.0.0.0' ) and ( $passport->snmp_connect_ip($ip) ) ); } return; } # Required for SNMP::Info::SONMP sub index_factor { my $passport = shift; my $model = $passport->model(); my $index_factor = 64; # Older Accelar models use base 16 instead of 64 $index_factor = 16 if ( defined $model and $model =~ /^1[012][05]0/ ); return $index_factor; } sub slot_offset { my $passport = shift; my $model = $passport->model(); # Newer VSP 4K and 8K start at an index of 192 ~ slot 3 but really slot 1 return -2 if ( defined $model and $model =~ /^VSP[478]/ ); return 0; } sub port_offset { return 1; } # Bridge MIB does not map Bridge Port to ifIndex correctly sub bp_index { my $passport = shift; my $partial = shift; my $if_index = $passport->i_index($partial) || {}; my %bp_index; foreach my $iid ( keys %$if_index ) { $bp_index{$iid} = $iid; } # If we have MLT's map them to the designated port my $trunks = $passport->rc_mlt_index; my $dps = $passport->rc_mlt_dp || {}; if ( ref {} eq ref $trunks and scalar keys %$trunks ) { foreach my $m ( keys %$trunks ) { my $m_idx = $trunks->{$m}; next unless $m_idx; my $i_idx = $dps->{$m} ? $dps->{$m} : $m_idx; $bp_index{$m_idx} = $i_idx; } } return \%bp_index; } # We have devices which support BRIDGE-MIB, Q-BRIDGE-MIB, and RAPID-CITY # exclusively. Use standards-based first and fall back to RAPID-CITY. sub fw_mac { my $passport = shift; my $partial = shift; my $qb = $passport->SUPER::fw_mac($partial); return $qb if (ref {} eq ref $qb and scalar keys %$qb); my $qb_fw_port = $passport->rcBridgeTpFdbPort($partial); my $qb_fw_mac = {}; foreach my $idx ( keys %$qb_fw_port ) { my ( $fdb_id, $mac ) = _rc_fdbtable_index($idx); $qb_fw_mac->{$idx} = $mac; } return $qb_fw_mac; } sub fw_port { my $passport = shift; my $partial = shift; my $qb = $passport->SUPER::fw_port($partial); return $qb if (ref {} eq ref $qb and scalar keys %$qb); return $passport->rcBridgeTpFdbPort($partial); } sub fw_status { my $passport = shift; my $partial = shift; my $qb = $passport->SUPER::fw_status($partial); return $qb if (ref {} eq ref $qb and scalar keys %$qb); return $passport->rcBridgeTpFdbStatus($partial); } sub qb_fw_vlan { my $passport = shift; my $partial = shift; my $qb = $passport->SUPER::qb_fw_vlan($partial); return $qb if (ref {} eq ref $qb and scalar keys %$qb); my $qb_fw_port = $passport->rcBridgeTpFdbPort($partial); my $qb_fw_vlan = {}; foreach my $idx ( keys %$qb_fw_port ) { my ( $fdb_id, $mac ) = _rc_fdbtable_index($idx); $qb_fw_vlan->{$idx} = $fdb_id; } return $qb_fw_vlan; } # break up the rcBridgeTpFdbEntry INDEX into FDB ID and MAC Address. sub _rc_fdbtable_index { my $idx = shift; my @values = split( /\./, $idx ); my $fdb_id = shift(@values); return ( $fdb_id, join( ':', map { sprintf "%02x", $_ } @values ) ); } # Pseudo ENTITY-MIB methods sub e_index { my $passport = shift; my $model = $passport->model(); my $rc_ps_t = $passport->rc_ps_type() || {}; # We're going to hack an index: Slot/Mda/Postion # We're going to put chassis and power supplies in a slot # which doesn't exist my %rc_e_index; # Make up a chassis index $rc_e_index{1} = 1; # Power supplies are common, handle them first foreach my $idx ( keys %$rc_ps_t ) { next unless $idx; # We should never have 90 slots, they will also # sort numerically at the bottom my $index = $idx + 90 . "0000"; $rc_e_index{$index} = $index; } # Older Accelars use RAPID-CITY::rcCardTable if ( defined $model and $model =~ /^1[012][05]0/ ) { my $rc_c_t = $passport->rc_c_type() || {}; foreach my $idx ( keys %$rc_c_t ) { next unless $idx; my $index = "$idx" . "0000"; $rc_e_index{$index} = $index; $index++; $rc_e_index{$index} = $index; } } # All newer models use RAPID-CITY::rc2kCardTable else { my $rc2_c_t = $passport->rc2k_c_ftype() || {}; my $rc2_m_t = $passport->rc2k_mda_type() || {}; foreach my $idx ( keys %$rc2_c_t ) { next unless $idx; my $index = "$idx" . "0000"; for ( 0 .. 2 ) { $rc_e_index{$index} = $index; $index++; } } foreach my $idx ( keys %$rc2_m_t ) { next unless $idx; next if $idx == 0; my ( $slot, $mda ) = split /\./, $idx; $mda = sprintf( "%02d", $mda ); my $index = "$idx" . "$mda" . "00"; $rc_e_index{$index} = $index; $index++; $rc_e_index{$index} = $index; } } return \%rc_e_index; } sub e_class { my $passport = shift; my $rc_e_idx = $passport->e_index() || {}; my %rc_e_class; foreach my $iid ( keys %$rc_e_idx ) { if ( $iid == 1 ) { $rc_e_class{$iid} = 'chassis'; } elsif ( $iid =~ /^9(\d)/ and length $iid > 5 ) { $rc_e_class{$iid} = 'powerSupply'; } elsif ( $iid =~ /0000$/ ) { $rc_e_class{$iid} = 'container'; } else { $rc_e_class{$iid} = 'module'; } } return \%rc_e_class; } sub e_descr { my $passport = shift; my $model = $passport->model(); my $rc_ps = $passport->rc_ps_detail() || {}; my $rc_ch = $passport->chassis() || ''; $rc_ch =~ s/a//; my %rc_e_descr; # Chassis $rc_e_descr{1} = $rc_ch; # Power supplies are common, handle them first foreach my $idx ( keys %$rc_ps ) { next unless $idx; my $ps = $rc_ps->{$idx}; next unless $ps; my $index = $idx + 90 . "0000"; $rc_e_descr{$index} = $ps; } # Older Accelars use RAPID-CITY::rcCardTable if ( defined $model and $model =~ /^1[012][05]0/ ) { my $rc_c_t = $passport->rc_c_type() || {}; foreach my $idx ( keys %$rc_c_t ) { next unless $idx; my $type = $rc_c_t->{$idx}; next unless $type; my $index = "$idx" . "0000"; $rc_e_descr{$index} = "Slot " . "$idx"; $index++; $rc_e_descr{$index} = $type; } } # All newer models use RAPID-CITY::rc2kCardTable else { my $rc2_cf = $passport->rc2k_c_fdesc() || {}; my $rc2_cb = $passport->rc2k_c_bdesc() || {}; my $rc2_m = $passport->rc2k_mda_desc() || {}; foreach my $idx ( keys %$rc2_cf ) { next unless $idx; my $cf = $rc2_cf->{$idx}; next unless $idx; my $cb = $rc2_cb->{$idx}; my $index = "$idx" . "0000"; $rc_e_descr{$index} = "Slot " . "$idx"; $index++; $rc_e_descr{$index} = $cf; $index++; $rc_e_descr{$index} = $cb; } foreach my $idx ( keys %$rc2_m ) { next unless $idx; my $cm = $rc2_m->{$idx}; next unless $cm; my ( $slot, $mda ) = split /\./, $idx; $mda = sprintf( "%02d", $mda ); my $index = "$idx" . "$mda" . "00"; $rc_e_descr{$index} = $cm; } } return \%rc_e_descr; } sub e_type { my $passport = shift; my $model = $passport->model(); my $rc_ps = $passport->rc_ps_type() || {}; my $rc_ch = $passport->chassis(); my %rc_e_type; # Chassis $rc_e_type{1} = $rc_ch; # Power supplies are common, handle them first foreach my $idx ( keys %$rc_ps ) { next unless $idx; my $ps = $rc_ps->{$idx}; next unless $ps; my $index = $idx + 90 . "0000"; $rc_e_type{$index} = $ps; } # Older Accelars use RAPID-CITY::rcCardTable if ( defined $model and $model =~ /^1[012][05]0/ ) { my $rc_c_t = $passport->rc_c_type() || {}; foreach my $idx ( keys %$rc_c_t ) { next unless $idx; my $type = $rc_c_t->{$idx}; next unless $type; my $index = "$idx" . "0000"; $rc_e_type{$index} = "zeroDotZero"; $index++; $rc_e_type{$index} = $type; } } # All newer models use RAPID-CITY::rc2kCardTable else { my $rc2_cf = $passport->rc2k_c_ftype() || {}; my $rc2_cb = $passport->rc2k_c_btype() || {}; my $rc2_m = $passport->rc2k_mda_type() || {}; foreach my $idx ( keys %$rc2_cf ) { next unless $idx; my $cf = $rc2_cf->{$idx}; next unless $idx; my $cb = $rc2_cb->{$idx}; my $index = "$idx" . "0000"; $rc_e_type{$index} = "zeroDotZero"; $index++; $rc_e_type{$index} = $cf; $index++; $rc_e_type{$index} = $cb; } foreach my $idx ( keys %$rc2_m ) { next unless $idx; my $cm = $rc2_m->{$idx}; next unless $cm; my ( $slot, $mda ) = split /\./, $idx; $mda = sprintf( "%02d", $mda ); my $index = "$idx" . "$mda" . "00"; $rc_e_type{$index} = $cm; } } return \%rc_e_type; } sub e_name { my $passport = shift; my $model = $passport->model(); my $rc_e_idx = $passport->e_index() || {}; my %rc_e_name; foreach my $iid ( keys %$rc_e_idx ) { if ( $iid == 1 ) { $rc_e_name{$iid} = 'Chassis'; next; } my $mod = int( substr( $iid, -4, 2 ) ); my $slot = substr( $iid, -6, 2 ); if ( $iid =~ /^9(\d)/ and length $iid > 5 ) { $rc_e_name{$iid} = "Power Supply $1"; } elsif ( $iid =~ /(00){2}$/ ) { $rc_e_name{$iid} = "Slot $slot"; } elsif ( $iid =~ /(00){1}$/ ) { $rc_e_name{$iid} = "Card $slot, MDA $mod"; } elsif ( defined $model and $model =~ /^1[012][05]0/ and $iid =~ /1$/ ) { $rc_e_name{$iid} = "Card $slot"; } elsif ( $iid =~ /1$/ ) { $rc_e_name{$iid} = "Card $slot (front)"; } elsif ( $iid =~ /2$/ ) { $rc_e_name{$iid} = "Card $slot (back)"; } } return \%rc_e_name; } sub e_hwver { my $passport = shift; my $model = $passport->model(); my $rc_ps = $passport->rc_ps_rev() || {}; my %rc_e_hwver; # Chassis $rc_e_hwver{1} = $passport->rc_ch_rev(); # Power supplies are common, handle them first foreach my $idx ( keys %$rc_ps ) { next unless $idx; my $ps = $rc_ps->{$idx}; next unless $ps; my $index = $idx + 90 . "0000"; $rc_e_hwver{$index} = $ps; } # Older Accelars use RAPID-CITY::rcCardTable if ( defined $model and $model =~ /^1[012][05]0/ ) { my $rc_c_t = $passport->rc_c_rev() || {}; foreach my $idx ( keys %$rc_c_t ) { next unless $idx; my $type = $rc_c_t->{$idx}; next unless $type; my $index = "$idx" . "0001"; $rc_e_hwver{$index} = $type; } } # All newer models use RAPID-CITY::rc2kCardTable else { my $rc2_cf = $passport->rc2k_c_frev() || {}; my $rc2_cb = $passport->rc2k_c_brev() || {}; my $rc2_m = $passport->rc2k_mda_rev() || {}; foreach my $idx ( keys %$rc2_cf ) { next unless $idx; my $cf = $rc2_cf->{$idx}; next unless $idx; my $cb = $rc2_cb->{$idx}; my $index = "$idx" . "0001"; $rc_e_hwver{$index} = $cf; $index++; $rc_e_hwver{$index} = $cb; } foreach my $idx ( keys %$rc2_m ) { next unless $idx; my $cm = $rc2_m->{$idx}; next unless $cm; my ( $slot, $mda ) = split /\./, $idx; $mda = sprintf( "%02d", $mda ); my $index = "$idx" . "$mda" . "00"; $rc_e_hwver{$index} = $cm; } } return \%rc_e_hwver; } sub e_vendor { my $passport = shift; my $rc_e_idx = $passport->e_index() || {}; my %rc_e_vendor; foreach my $iid ( keys %$rc_e_idx ) { $rc_e_vendor{$iid} = 'avaya'; } return \%rc_e_vendor; } sub e_serial { my $passport = shift; my $model = $passport->model(); my $rc_ps = $passport->rc_ps_serial() || {}; my %rc_e_serial; # Chassis $rc_e_serial{1} = $passport->rc_serial(); # Power supplies are common, handle them first foreach my $idx ( keys %$rc_ps ) { next unless $idx; my $ps = $rc_ps->{$idx}; next unless $ps; my $index = $idx + 90 . "0000"; $rc_e_serial{$index} = $ps; } # Older Accelars use RAPID-CITY::rcCardTable if ( defined $model and $model =~ /^1[012][05]0/ ) { my $rc_c_t = $passport->rc_c_serial() || {}; foreach my $idx ( keys %$rc_c_t ) { next unless $idx; my $type = $rc_c_t->{$idx}; next unless $type; my $index = "$idx" . "0001"; $rc_e_serial{$index} = $type; } } # All newer models use RAPID-CITY::rc2kCardTable else { my $rc2_cf = $passport->rc2k_c_fserial() || {}; my $rc2_cb = $passport->rc2k_c_bserial() || {}; my $rc2_m = $passport->rc2k_mda_serial() || {}; foreach my $idx ( keys %$rc2_cf ) { next unless $idx; my $cf = $rc2_cf->{$idx}; next unless $idx; my $cb = $rc2_cb->{$idx}; my $index = "$idx" . "0001"; $rc_e_serial{$index} = $cf; $index++; $rc_e_serial{$index} = $cb; } foreach my $idx ( keys %$rc2_m ) { next unless $idx; my $cm = $rc2_m->{$idx}; next unless $cm; my ( $slot, $mda ) = split /\./, $idx; $mda = sprintf( "%02d", $mda ); my $index = "$idx" . "$mda" . "00"; $rc_e_serial{$index} = $cm; } } return \%rc_e_serial; } sub e_pos { my $passport = shift; my $rc_e_idx = $passport->e_index() || {}; my %rc_e_pos; foreach my $iid ( keys %$rc_e_idx ) { next unless $iid; if ( $iid == 1 ) { $rc_e_pos{$iid} = -1; next; } my $sub = int( substr( $iid, -2, 2 ) ); my $mod = int( substr( $iid, -4, 2 ) ); my $slot = substr( $iid, -6, 2 ); if ( $iid =~ /(00){2}$/ ) { $rc_e_pos{$iid} = $slot; } elsif ( $iid =~ /(00){1}$/ ) { $rc_e_pos{$iid} = $mod * 100; } else { $rc_e_pos{$iid} = $sub; } } return \%rc_e_pos; } sub e_parent { my $passport = shift; my $rc_e_idx = $passport->e_index() || {}; my %rc_e_parent; foreach my $iid ( keys %$rc_e_idx ) { next unless $iid; if ( $iid == 1 ) { $rc_e_parent{$iid} = 0; next; } my $slot = substr( $iid, -6, 2 ); if ( $iid =~ /(00){1,2}$/ ) { $rc_e_parent{$iid} = 1; } else { $rc_e_parent{$iid} = "$slot" . "0000"; } } return \%rc_e_parent; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Passport - SNMP Interface to modular Avaya Ethernet Routing Switch 8000 Series and VSP 9000 Series switches. =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $passport = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $passport->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for modular Avaya Ethernet Routing Switch 8000 Series (formerly Nortel/Bay Passport/Accelar) and VSP 9000 Series switches. These devices have some of the same characteristics as the stackable Avaya Ethernet Switches (Baystack). For example, extended interface information is gleaned from F. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $passport = new SNMP::Info::Layer3::Passport(...); =head2 Inherited Classes =over =item SNMP::Info::SONMP =item SNMP::Info::RapidCity =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $passport->model() Returns model type. Checks $passport->id() against the F and then parses out C. =item $passport->vendor() Returns 'avaya' =item $passport->os() Returns 'passport' =item $passport->os_ver() Returns the software version extracted from C =item $passport->serial() Returns (C) =item $passport->root_ip() Returns the primary IP used to communicate with the device. Returns the first found: CLIP (CircuitLess IP), Management Virtual IP (C), OSPF Router ID (C), SONMP Advertised IP Address. =back =head2 Overrides =over =item $passport->index_factor() Required by SNMP::Info::SONMP. Returns 64 for 8600, 16 for Accelar. =item $passport->port_offset() Required by SNMP::Info::SONMP. Returns 1. =item $passport->slot_offset() Required by SNMP::Info::SONMP. Returns 0. =back =head2 Global Methods imported from SNMP::Info::SONMP See documentation in L for details. =head2 Global Methods imported from SNMP::Info::RapidCity See documentation in L for details. =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $passport->i_index() Returns SNMP IID to Interface index. Extends (C) by adding the index of the CPU virtual management IP (if present), each CPU Ethernet port, and each VLAN to ensure the virtual router ports are captured. =item $passport->interfaces() Returns reference to the map between IID and physical Port. Slot and port numbers on the Passport switches are determined by the formula: port = (C) + port_offset, slot = int(C). The physical port name is returned as slot.port. CPU Ethernet ports are prefixed with CPU and VLAN interfaces are returned as the VLAN ID prefixed with Vlan. =item $passport->i_mac() MAC address of the interface. Note this is just the MAC of the port, not anything connected to it. =item $passport->i_description() Description of the interface. Usually a little longer single word name that is both human and machine friendly. Not always. =item $passport->i_name() Crosses rc_alias() (C) with ifAlias() and returns the human set port name if exists. =item $passport->ip_index() Maps the IP Table to the IID. Extends (C) by adding the index of the CPU virtual management IP (if present) and each CPU Ethernet port. =item $passport->ip_netmask() Extends (C) by adding the mask of the CPU virtual management IP (if present) and each CPU Ethernet port. =item $passport->bp_index() Returns reference to hash of bridge port table entries map back to interface identifier (iid) Returns (C) for both key and value since some devices seem to have problems with F =back =head2 Forwarding Table These methods utilize, in order; F, F, and F to obtain the forwarding table information. =over =item $passport->fw_mac() Returns reference to hash of forwarding table MAC Addresses (C), (C), (C) =item $passport->fw_port() Returns reference to hash of forwarding table entries port interface identifier (iid) (C), (C), (C) =item $passport->fw_status() Returns reference to hash of forwarding table entries status (C), (C), (C) =item $passport->qb_fw_vlan() Returns reference to hash of forwarding table entries VLAN ID (C), (C) =back =head2 Pseudo F information These devices do not support F. These methods emulate Physical Table methods using the F. =over =item $passport->e_index() Returns reference to hash. Key and Value: Integer. The index is created by combining the slot, module, and position into a five or six digit integer. Slot can be either one or two digits while the module and position are each two digits padded with leading zero if required. =item $passport->e_class() Returns reference to hash. Key: IID, Value: General hardware type. This class only returns container, module, and power supply types. =item $passport->e_descr() Returns reference to hash. Key: IID, Value: Human friendly name. =item $passport->e_name() Returns reference to hash. Key: IID, Value: Human friendly name. =item $passport->e_hwver() Returns reference to hash. Key: IID, Value: Hardware version. =item $passport->e_vendor() Returns reference to hash. Key: IID, Value: avaya. =item $passport->e_serial() Returns reference to hash. Key: IID, Value: Serial number. =item $passport->e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. =item $passport->e_type() Returns reference to hash. Key: IID, Value: Type of component/sub-component. =item $passport->e_parent() Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. A value of zero indicates this entity is not contained in any other entity. =back =head2 Table Methods imported from SNMP::Info::SONMP See documentation in L for details. =head2 Table Methods imported from SNMP::Info::RapidCity See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Pf.pm000444000765000024 1353413215550564 17353 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Pf # $Id$ # # Copyright (c) 2010 Max Baker # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of Pf Networks, Inc. nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Pf; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; @SNMP::Info::Layer3::Pf::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Pf::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, # Enterprise container where BEGEMOT-* lives 'FOKUS-MIB' => 'fokus', # MIBs used included in Layer3 and above: # UDP-MIB # TCP-MIB # IF-MIB # # Stuff in these MIBs but not used for Netdisco yet for my test device: # #'BEGEMOT-SNMPD-MIB', #'BEGEMOT-PF-MIB', #'BEGEMOT-NETGRAPH-MIB', #'BEGEMOT-MIB2-MIB', #'BEGEMOT-HOSTRES-MIB', # HOST-RESOURCES-MIB # IP-FORWARD-MIB # # Nothing in these MIBs for my test device: # #'BEGEMOT-IP-MIB', #'BEGEMOT-MIB', #'BEGEMOT-BRIDGE-MIB', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub vendor { return 'FreeBSD'; } sub model { my $pf = shift; my $descr = $pf->description() || ''; my $model = undef; $model = $1 if ( $descr =~ /FreeBSD\s+(\S+)/ ); return $model if defined $model; return $pf->os_ver(); } sub os { return 'Pf'; } sub os_ver { my $pf = shift; my $id = $pf->id(); my $os_ver = &SNMP::translateObj($id); return $id unless defined $os_ver; # From /usr/share/snmp/defs/tree.def on a Pf Machine # (2 begemotSnmpdDefs # (1 begemotSnmpdAgent # (1 begemotSnmpdAgentFreeBSD OID op_dummy) # We're leaving the 1.1 and trimming off up to the 2 $os_ver =~ s/fokus.1.1.2.//; return $os_ver; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Pf - SNMP Interface to FreeBSD-Based Firewalls using Pf /Pf Sense =head1 AUTHOR Max Baker =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $pf = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $pf->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Free-BSD PF-Based devices =head1 LLDP Support LLDP Support is included but untested in this Device Class. It is reported that the available CDP/LLDP modules for net-snmp don't work on FreeBSD (on which pfSense is based) as they assume certain Linux specific Ethernet structures. This problem is apparently solved on PF based firewall appliances by using the ladvd package, for which a port may be found here: L. I'm not sure if this module ties into Net-SNMP or not. =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar values from SNMP =over =item $pf->vendor() Returns 'FreeBSD' =item $pf->model() Grabs the os version from C =item $pf->os() Returns 'Pf' =item $pf->os_ver() Tries to reference $pf->id() to one of the product MIBs listed above. Will probably return a truncation of the default OID for pf-based systems C. =back =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Pica8.pm000444000765000024 1102213215550564 17740 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Pica8 # # Copyright (c) 2013 Jeroen van Ingen # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Pica8; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::LLDP; @SNMP::Info::Layer3::Pica8::ISA = qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Pica8::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::LLDP::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::LLDP::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::LLDP::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); sub vendor { return 'Pica8'; } sub os { my $pica8 = shift; my $descr = $pica8->description(); return $1 if ( $descr =~ /(\S+)\s+Platform Software/i ); return; } sub os_ver { my $pica8 = shift; my $descr = $pica8->description(); return $1 if ( $descr =~ /Software version ([\d\.]+)/i ); return; } sub model { my $pica8 = shift; my $descr = $pica8->description(); return $1 if ( $descr =~ /Hardware model (P-\d{4})/i ); return; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Pica8 - SNMP Interface to L3 Devices, Pica8 =head1 AUTHORS Jeroen van Ingen =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $pica8 = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $pica8->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Pica8 devices =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::LLDP =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $pica8->vendor() Returns 'Pica8' =item $pica8->model() Returns the model name extracted from C. =item $pica8->os() Returns the OS extracted from C. =item $pica8->os_ver() Returns the OS version extracted from C. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Globals imported from SNMP::Info::LLDP See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::LLDP See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/SonicWALL.pm000444000765000024 1113613215550564 20535 0ustar00oliverstaff000000000000package SNMP::Info::Layer3::SonicWALL; # Copyright (c) 2011 Netdisco Project # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::SonicWALL::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::SonicWALL::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::Layer3::MIBS, 'SNWL-COMMON-MIB' => 'snwlCommonModule', ); %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::Layer3::GLOBALS, #From SNWL-COMMON-MIB 'sw_model' => 'snwlSysModel', 'sw_serial' => 'snwlSysSerialNumber', 'sw_firmware' => 'snwlSysFirmwareVersion', ); %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'SonicWALL'; } sub os { my $sonicos = shift; my $swos = $sonicos->sw_firmware(); if ($swos =~ /Enhanced/) { return 'SonicOS Enhanced'; } return 'SonicOS Standard'; } sub os_ver { my $sonicosver = shift; my $osver = $sonicosver->sw_firmware(); if ( $osver =~ /\S+\s\S+\s(\S+)/) { return $1 } } sub serial { my $sw = shift; my $serial = $sw->sw_serial(); return $serial; } sub model { my $swmodel = shift; my $model = $swmodel->sw_model(); return $model; } 1; __END__ =head1 NAME SNMP::Info::Layer3::SonicWALL - SNMP Interface to L3 SonicWALL Firewall =head1 AUTHOR phishphreek@gmail.com =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $router = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $router->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Generic SonicWALL Firewalls =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =head2 Overrides =over =item $router->vendor() Returns C<'SonicWALL'> =item $router->os() Returns C<'SonicOS'> =item $router->os_ver() Returns '4.2.0.0-10e' =item $router->model() Returns C<'PRO 3060 Enhanced'> =item $router->serial() Returns the MAC address of the first X0/LAN interface. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Steelhead.pm000444000765000024 1146313215550564 20703 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Steelhead # # Copyright (c) 2013 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Steelhead; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Steelhead::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Steelhead::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'STEELHEAD-MIB' => 'serialNumber', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, # Fully qualified to remove ambiguity of 'model' 'rb_model' => 'STEELHEAD-MIB::model', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub layers { return '01001100'; } sub vendor { return 'riverbed'; } sub model { my $riverbed = shift; my $model = $riverbed->rb_model() || ''; if ($model =~ /^(\d+)/) { return $1; } return $model; } sub os { return 'steelhead'; } sub os_ver { my $riverbed = shift; my $ver = $riverbed->systemVersion() || ''; if ( $ver =~ /(\d+[\.\d]+)/ ) { return $1; } return $ver; } sub serial { my $riverbed = shift; return $riverbed->serialNumber(); } 1; __END__ =head1 NAME SNMP::Info::Layer3::Steelhead - SNMP Interface to Riverbed Steelhead WAN optimization appliances. =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $riverbed = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $riverbed->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Abstraction subclass for Riverbed Steelhead WAN optimization appliances. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $riverbed = new SNMP::Info::Layer3::Steelhead(...); =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs F =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $riverbed->vendor() Returns 'riverbed' =item $riverbed->model() Returns the chassis model. (C) =item $riverbed->os() Returns 'steelhead' =item $riverbed->os_ver() Returns the software version extracted from (C). =item $riverbed->serial() Returns the chassis serial number. (C) =back =head2 Overrides =over =item $riverbed->layers() Returns 01001100. Steelhead does not support bridge MIB, so override reported layers. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Sun.pm000444000765000024 1104213215550564 17543 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Sun # $Id$ # # Copyright (c) 2008 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Sun; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Sun::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Sun::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, 'sun_hostid' => '.1.3.6.1.4.1.42.3.1.2.0', 'motd' => '.1.3.6.1.4.1.42.3.1.3.0', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'sun'; } sub os { return 'sun'; } sub os_ver { my $sun = shift; my $descr = $sun->motd(); return unless defined $descr; if ( $descr =~ m/SunOS (\S+)/ ) { return $1; } return; } sub model { return 'Solaris Router'; } sub serial { my $sun = shift; my $serial = unpack( "H*", $sun->sun_hostid() ); return $serial; } sub i_ignore { my $l3 = shift; my $partial = shift; my $interfaces = $l3->interfaces($partial) || {}; my %i_ignore; foreach my $if ( keys %$interfaces ) { # lo0 if ( $interfaces->{$if} =~ /\blo0\b/i ) { $i_ignore{$if}++; } } return \%i_ignore; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Sun - SNMP Interface to L3 Sun Solaris =head1 AUTHOR begemot =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $sun = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'mysunrouter', Community => 'public', Version => 1 ) or die "Can't connect to DestHost.\n"; my $class = $sun->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Generic Sun Routers running SunOS =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $sun->vendor() Returns 'sun' =item $sun->os() Returns 'sun' =item $sun->os_ver() Returns the software version extracted from message of the day. =item $sun->model() Returns 'Solaris Router' =item $sun->serial() Returns serial number =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =item $sun->i_ignore() Returns reference to hash. Increments value of IID if port is to be ignored. Ignores loopback =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Tasman.pm000444000765000024 3247213215550564 20233 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Tasman # # Copyright (c) 2012 Eric Miller # All Rights Reserved # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Tasman; use strict; use warnings; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::MAU; @SNMP::Info::Layer3::Tasman::ISA = qw/SNMP::Info::MAU SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Tasman::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::MAU::MIBS, 'NT-ENTERPRISE-DATA-MIB' => 'ntEnterpriseRouters', 'SYSTEM-MIB' => 'nnsysVersion', 'CHASSIS-MIB' => 'nnchassisModel', 'ENVIRONMENT-MIB' => 'nnenvPwrsupStatus', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::MAU::GLOBALS, 'ps1_type' => 'nnenvPwrsupType.1', 'ps1_status' => 'nnenvPwrsupStatus.1', 'ps2_type' => 'nnenvPwrsupType.2', 'ps2_status' => 'nnenvPwrsupStatus.2', 'nn_sys_ver' => 'nnsysVersion', 'nn_ch_model' => 'nnchassisModel', 'nn_ch_op_stat' => 'nnchassisOperStatus', 'nn_ch_serial' => 'nnchassisSerialNumber', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, %SNMP::Info::MAU::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::MAU::MUNGE, ); # use MAU-MIB for admin. duplex and admin. speed *SNMP::Info::Layer3::Tasman::i_duplex_admin = \&SNMP::Info::MAU::mau_i_duplex_admin; *SNMP::Info::Layer3::Tasman::i_speed_admin = \&SNMP::Info::MAU::mau_i_speed_admin; my $module_map = { ADSL_ANX_A => '1-port ADSL2+ Annex A', ADSL_ANX_B => '1-port ADSL2+ Annex B', BRI_2ST => '2-port ST-interface ISDN BRI for both TDM and Packet', FXO_2M => 'Voice Interface card - 2 port FXO', FXO_4M => 'Voice Interface card - 4 port FXO', FXS_2M => 'Voice Interface card - 2 port FXS', FXS_4M => 'Voice Interface card - 4 port FXS', HSSI_1 => '1-port High Speed Serial', LMF_24 => '24-port 10/100 Fast Ethernet Layer2/3 switch', LMG_10 => '10-port non-blocking 10/100/1000 Gigabit Ethernet Layer2/3 switch', LMG_44 => '44-port 10/100/1000 Gigabit Ethernet Layer 2/3 switch', LMP_24 => '24-port 10/100 fast Ethernet Layer2/3 PoE switch', PVIM_A => 'Packetized Voice Module (PVIM)', SCIM_A => 'Ipsec VPN Encryption Module', SERV_MOD => 'Secure Router 4134 Server Module', VCM_A => 'Medium Carrier module supports up to 4 FXO or FXS Small Modules', VOIP_A => 'Packetized Voice Module (PVM)', VPN_A => 'High Performance IPsec VPN Encryption Module', WDS3_1C => '1-port Clear Channel DS3', WT3_1C => '1-port Channelized T3', DS3_1C => '1-port Channelized T3', WTE_1 => '1-port T1/E1 w DS0 and DS1 support for both TDM and Packet', WTE_2S => '2-port Sync and Async Serial', WTE_8 => '8-port T1/E1' }; sub vendor { return 'avaya'; } sub os { return 'tasman'; } sub os_ver { my $tasman = shift; my $version = $tasman->nn_sys_ver() || ""; my $descr = $tasman->description() || ""; # Newer versions return $1 if ( $version =~ /^SW:\s+(.+?)\s+/ ); # Older versions return $1 if ( $descr =~ /Software Version\s+=\s+[r]*(.+),/ ); # Can't find return; } sub model { my $tasman = shift; my $id = $tasman->id(); my $ch_model = $tasman->nn_ch_model(); return $ch_model if $ch_model; my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^ntSecureRouter/SR/; return $model; } sub serial { my $tasman = shift; # Newer versions of the software redefined the MIB in a non-backwards # compatible manner. Try the old OID first. my $serial = $tasman->nn_ch_op_stat(); # Newer versions populate status, serial should contain some letters # while a status is an integer return $serial if ( $serial !~ /^\D+$/ ); # Unfortunately newer versions don't seem to populate the newer OID. # so check modules for a chassis my $e_parent = $tasman->e_parent(); foreach my $iid ( keys %$e_parent ) { my $parent = $e_parent->{$iid}; if ( $parent eq '0' ) { my $ser = $tasman->e_serial($iid); return $ser->{$iid}; } } # If everything else failed just return what is supposed to hold the # serial although it probably doesn't return $tasman->nn_ch_serial(); } # Slots 1–4 are Small Module slots. Slots 5–7 are Medium Module slots. # A Large Module spans slots 6 and 7. It will be identified as slot 6. sub e_index { my $tasman = shift; my $index = $tasman->nnchassisInfoSlotSubSlotString() || {}; # In some cases the modules are duplicated, remove duplicates my %seen; my %e_index; foreach my $key ( keys %$index ) { my $string = $index->{$key}; $string =~ s/\D//; unless ( $seen{$string} ) { $seen{$string}++; $e_index{$key} = $string + 1; } } return \%e_index; } sub e_class { my $tasman = shift; my $e_index = $tasman->e_index() || {}; my %e_class; foreach my $iid ( keys %$e_index ) { my $index = $e_index->{$iid}; if ( $index == 1 ) { $e_class{$iid} = 'chassis'; } else { $e_class{$iid} = 'module'; } } return \%e_class; } sub e_descr { my $tasman = shift; my $e_index = $tasman->e_index() || {}; my $types = $tasman->nnchassisInfoCardType || {}; my %e_descr; foreach my $iid ( keys %$e_index ) { my $type = $types->{$iid}; next unless $type; if ( $type =~ /^MPU/ ) { $e_descr{$iid} = $tasman->model(); } elsif ( defined $module_map->{$type} ) { $e_descr{$iid} = $module_map->{$type}; } else { next; } } return \%e_descr; } sub e_serial { my $tasman = shift; my $e_index = $tasman->e_index() || {}; my $serials = $tasman->nnchassisInfoSerialNumber() || {}; my %e_serial; foreach my $iid ( keys %$e_index ) { $e_serial{$iid} = $serials->{$iid} || ''; } return \%e_serial; } sub e_fru { my $tasman = shift; my $e_index = $tasman->e_index() || {}; my %e_fru; foreach my $iid ( keys %$e_index ) { $e_fru{$iid} = "true"; } return \%e_fru; } sub e_type { my $tasman = shift; my $e_index = $tasman->e_index() || {}; my $types = $tasman->nnchassisInfoCardType || {}; my %e_type; foreach my $iid ( keys %$e_index ) { $e_type{$iid} = $types->{$iid} || ''; } return \%e_type; } sub e_vendor { my $tasman = shift; my $e_idx = $tasman->e_index() || {}; my %e_vendor; foreach my $iid ( keys %$e_idx ) { $e_vendor{$iid} = 'avaya'; } return \%e_vendor; } sub e_pos { my $tasman = shift; return $tasman->e_index(); } sub e_parent { my $tasman = shift; my $e_idx = $tasman->e_index() || {}; my $e_classes = $tasman->e_class() || {}; my $cha_idx = 0; foreach my $i ( keys %$e_classes ) { my $class = $e_classes->{$i}; my $pos = $e_idx->{$i}; if ( $class && $class eq 'chassis' ) { $cha_idx = $pos; } } my %e_parent; foreach my $iid ( keys %$e_idx ) { my $idx = $e_idx->{$iid}; if ( $idx == 1 ) { $e_parent{$iid} = 0; } elsif ( $idx =~ /^(\d)\d$/ ) { $e_parent{$iid} = $1; } else { $e_parent{$iid} = $cha_idx; } } return \%e_parent; } 1; __END__ =head1 NAME SNMP::Info::Layer3::Tasman - SNMP Interface to Avaya Secure Routers =head1 AUTHOR Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $tasman = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $tasman->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Avaya Secure Routers =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::MAU =back =head2 Required MIBs =over =item F =item F =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar values from SNMP =over =item $tasman->vendor() Returns C<'avaya'> =item $tasman->model() Tries to get the model from C and if not available cross references $tasman->id() to F. Substitutes 'SR' for C<'ntSecureRouter'> in the name for readability. =item $tasman->os() Returns C<'tasman'> =item $tasman->os_ver() Grabs the os version from C =item $tasman->ps1_type() (C) =item $tasman->ps1_status() (C) =item $tasman->ps2_type() (C) =item $tasman->ps2_status() (C) =item $tasman->nn_sys_ver() (C) =item $tasman->nn_ch_model() (C) =item $tasman->nn_ch_op_stat() (C) =item $tasman->nn_ch_serial() (C) =item $tasman->serial() Tries both (C) and (C) as oid was redefined between versions. =back =head2 Global Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::MAU See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over 4 =item $tasman->i_duplex_admin() Returns reference to hash of iid to administrative duplex setting. First checks for fixed gigabit ports which are always full duplex. Next checks the port administrative speed (C) which if set to autonegotiate then the duplex will also autonegotiate, otherwise it uses the reported port duplex (C). =item $tasman->i_speed_admin() Returns reference to hash of iid to administrative speed setting. C =back =head2 Pseudo F information These methods emulate F Physical Table methods using F. =over =item $tasman->e_index() Returns reference to hash. Key: IID, Value: Integer. =item $tasman->e_class() Returns reference to hash. Key: IID, Value: General hardware type. =item $tasman->e_descr() Returns reference to hash. Key: IID, Value: Human friendly name =item $tasman->e_vendor() Returns reference to hash. Key: IID, Value: avaya =item $tasman->e_serial() Returns reference to hash. Key: IID, Value: Serial number =item $tasman->e_pos() Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent. =item $tasman->e_type() Returns reference to hash. Key: IID, Value: Type of component/sub-component. =item $tasman->e_parent() Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. A value of zero indicates this entity is not contained in any other entity. =item $entity->e_fru() BOOLEAN. Is a Field Replaceable unit? =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::MAU See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/Timetra.pm000444000765000024 1124513215550564 20410 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::Timetra # $Id$ # # Copyright (c) 2008 Bill Fenner # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::Timetra; use strict; use Exporter; use SNMP::Info::Layer3; @SNMP::Info::Layer3::Timetra::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::Timetra::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer3::MIBS, 'TIMETRA-GLOBAL-MIB' => 'timetraReg', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub model { my $timetra = shift; my $id = $timetra->id(); my $model = &SNMP::translateObj($id); return $id unless defined $model; $model =~ s/^tmnxModel//; return $model; } sub os { return 'TiMOS'; } sub vendor { return 'alcatel-lucent'; } sub os_ver { my $timetra = shift; my $descr = $timetra->description(); if ( $descr =~ m/^TiMOS-(\S+)/ ) { return $1; } # No clue what this will try but hey return $timetra->SUPER::os_ver(); } # The interface description contains the SFP type, so # to avoid losing historical information through a configuration change # we use interface name instead. sub interfaces { my $alu = shift; my $partial = shift; return $alu->orig_i_name($partial); } 1; __END__ =head1 NAME SNMP::Info::Layer3::Timetra - SNMP Interface to Alcatel-Lucent SR =head1 AUTHOR Bill Fenner =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $alu = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $alu->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Alcatel-Lucent Service Routers =head2 Inherited Classes =over =item SNMP::Info::Layer3 =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $alu->vendor() Returns 'alcatel-lucent' =item $alu->os() Returns 'TiMOS' =item $alu->os_ver() Grabs the version string from C. =item $alu->model() Tries to reference $alu->id() to one of the product MIBs listed above Removes 'tmnxModel' from the name for readability. =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =over =item $alu->interfaces() Returns C, since the default Layer3 C varies based upon the transceiver inserted. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer3/VMware.pm000444000765000024 1165413215550564 20210 0ustar00oliverstaff000000000000# SNMP::Info::Layer3::VMware # # Copyright (c) 2014-2016 Max Kosmach # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer3::VMware; use strict; use Exporter; use SNMP::Info::Layer3; use SNMP::Info::IEEE802dot3ad 'agg_ports_lag'; @SNMP::Info::Layer3::VMware::ISA = qw/SNMP::Info::IEEE802dot3ad SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::VMware::EXPORT_OK = qw/agg_ports/; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::IEEE802dot3ad::MIBS, %SNMP::Info::Layer3::MIBS, 'VMWARE-PRODUCTS-MIB' => 'vmwProducts', 'VMWARE-SYSTEM-MIB' => 'vmwProdName', ); %GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, # VMWARE-SYSTEM-MIB 'vmwProdVersion' => 'vmwProdVersion', 'vmwProdBuild' => 'vmwProdBuild', 'vmwProdUpdate' => 'vmwProdUpdate', 'vmwProdPatch' => 'vmwProdPatch', 'os' => 'vmwProdName', ); %FUNCS = ( %SNMP::Info::Layer3::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer3::MUNGE, ); sub vendor { return 'VMware'; } sub os_ver { my $vmware = shift; my $vmwProdVersion = $vmware->vmwProdVersion(); my $vmwProdBuild = $vmware->vmwProdBuild() || ''; my $vmwProdUpdate = $vmware->vmwProdUpdate() || ''; my $vmwProdPatch = $vmware->vmwProdPatch() || ''; my $ver = "$vmwProdVersion" . "-" . "$vmwProdUpdate.$vmwProdPatch.$vmwProdBuild"; return $ver; } sub agg_ports { return agg_ports_lag(@_); } #sub layers { # return '01001010'; #} 1; __END__ =head1 NAME SNMP::Info::Layer3::VMware - SNMP Interface to VMware ESXi =head1 AUTHORS Max Kosmach =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $host = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myhost', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $host->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for VMware ESXi =head2 Inherited Classes =over =item SNMP::Info::Layer3 =item SNMP::Info::IEEE802dot3ad =back =head2 Required MIBs =over =item F =item F =back =head2 Inherited Classes' MIBs See L for its MIB requirements. See L for its MIB requirements. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $vmware->vendor() Returns C<'VMware'>. =item $vmware->os() Returns the value of C. =item $vmware->os_ver() Returns the software version specified as major-update.patch.build (ex. 5.1.0-3.55.2583090). (C)-(C).(C).(C) =back =head2 Globals imported from SNMP::Info::Layer3 See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =over =item C Returns a HASH reference mapping from slave to master port for each member of a port bundle on the device. Keys are ifIndex of the slave ports, Values are ifIndex of the corresponding master ports. =back =head2 Table Methods imported from SNMP::Info::Layer3 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer7000755000765000024 013215550564 16271 5ustar00oliverstaff000000000000SNMP-Info-3.39/lib/SNMP/Info/Layer7/APC.pm000444000765000024 1311413215550564 17407 0ustar00oliverstaff000000000000# SNMP::Info::Layer7::APC - SNMP Interface to APC UPS devices # # Copyright (c) 2011 Jeroen van Ingen # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer7::APC; use strict; use Exporter; use SNMP::Info::Layer7; @SNMP::Info::Layer7::APC::ISA = qw/SNMP::Info::Layer7 Exporter/; @SNMP::Info::Layer7::APC::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer7::MIBS, 'PowerNet-MIB' => 'upsBasicIdentModel', ); %GLOBALS = ( %SNMP::Info::Layer7::GLOBALS, 'mac' => 'ifPhysAddress.2', 'ups_serial' => 'upsAdvIdentSerialNumber.0', 'pdu_serial' => 'rPDUIdentSerialNumber.0', 'mgmt_serial' => 'experimental.2.4.1.2.1', 'os_ver' => 'experimental.2.4.1.4.1', 'os_bin' => 'experimental.2.4.1.4.2', 'ups_model' => 'upsBasicIdentModel.0', 'pdu_model' => 'rPDUIdentModelNumber.0', 'ps1_status' => 'upsBasicOutputStatus.0', 'ps2_status' => 'upsBasicBatteryStatus.0', ); %FUNCS = ( %SNMP::Info::Layer7::FUNCS, ); %MUNGE = ( # Inherit all the built in munging %SNMP::Info::Layer7::MUNGE, ); # Method Overrides sub os { return 'aos'; } sub vendor { return 'apc'; } sub model { my $apc = shift; return $apc->ups_model() || $apc->pdu_model(); } sub serial { my $apc = shift; my $ups = $apc->ups_serial() || 'unknown'; my $mgmt = $apc->mgmt_serial() || 'unknown'; return sprintf("UPS: %s, management card: %s", $ups, $mgmt); } sub ps1_type { return 'UPS status'; } sub ps2_type { return 'Battery status'; } 1; __END__ =head1 NAME SNMP::Info::Layer7::APC - SNMP Interface to APC UPS devices =head1 AUTHOR Jeroen van Ingen =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $apc = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myswitch', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $apc->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Provides abstraction to the configuration information obtainable from a APC UPS via SNMP. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. my $apc = new SNMP::Info::Layer7::APC(...); =head2 Inherited Classes =over =item SNMP::Info::Layer7 =back =head2 Required MIBs =over =item F =back All required MIBs can be found in the netdisco-mibs package. =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $apc->os() Returns C<'aos'> =item $apc->os_bin() C =item $apc->os_ver() C =item $apc->serial() Combines the UPS serial C with the management card serial C into a pretty string. =item $apc->vendor() Returns C<'apc'> =item $apc->model() C =item $apc->ps1_type() Returns 'UPS status' =item $apc->ps1_status() Returns the main UPS status from C =item $apc->ps2_type() Returns 'Battery status' =item $apc->ps2_status() Returns the battery status from C =back =head2 Globals imported from SNMP::Info::Layer7 See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Overrides =over =back =head2 Table Methods imported from SNMP::Info::Layer7 See documentation in L for details. =head1 MUNGES =over =back =head1 SET METHODS These are methods that provide SNMP set functionality for overridden methods or provide a simpler interface to complex set operations. See L for general information on set operations. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer7/CiscoIPS.pm000444000765000024 1314313215550564 20422 0ustar00oliverstaff000000000000# SNMP::Info::Layer::CiscoIPS # $Id$ # # Copyright (c) 2013 Moe Kraus # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer7::CiscoIPS; use strict; use warnings; use Exporter; use SNMP::Info::CiscoStats; use SNMP::Info::Layer7; use SNMP::Info::Entity; @SNMP::Info::Layer7::CiscoIPS::ISA = qw/ SNMP::Info::CiscoStats SNMP::Info::Layer7 Exporter/; @SNMP::Info::Layer7::CiscoIPS::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer7::MIBS, %SNMP::Info::Entity::MIBS, ); %GLOBALS = ( %SNMP::Info::Layer7::GLOBALS, %SNMP::Info::Entity::GLOBALS, ); %FUNCS = ( %SNMP::Info::Layer7::FUNCS, %SNMP::Info::Entity::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer7::MUNGE, %SNMP::Info::Entity::MUNGE, ); my ($serial, $descr, $model); sub _fetch_info { my $self = shift; foreach my $id ( keys %{ $self->e_id() } ){ if ( $self->e_name->{$id} =~ m/^Module$/ and $self->e_model->{$id} =~ m/IPS/ ) { $serial = $self->e_serial->{$id}; $descr = $self->e_descr->{$id}; $model = $self->e_model->{$id}; } } } sub layers { return '01001000'; } sub serial { my $self = shift; _fetch_info($self) unless defined $serial; return $serial; } sub sysdescr { my $self = shift; _fetch_info($self) unless defined $descr; return $descr; } sub model { my $self = shift; _fetch_info($self) unless defined $descr; $descr =~ s/ Security Services Processor//g; $descr =~ s/ /-/g; return $descr; } sub productname { my $self = shift; return $self->model; } sub b_mac { my ( $self ) = shift; foreach my $mac ( values %{$self->i_mac()} ){ next unless defined $mac; next unless $mac =~ m/^e4:d3:f1/; return $mac; } return ''; } sub e_index { my $self = shift(); my %index; foreach my $id ( keys %{$self->e_id} ){ %index->{$id} = $id; } return \%index; } 1; __END__ =head1 NAME SNMP::Info::Layer7::CiscoIPS - Cisco Adaptive Security Appliance IPS module =head1 AUTHOR Moe Kraus =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $info = new SNMP::Info( AutoSpecify => 1, Debug => 1, # These arguments are passed directly to SNMP::Session DestHost => 'myIPS', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $ips->class(); print "SNMP::Info determined this device to fall under subclass: $class\n"; =head1 DESCRIPTION Subclass for Cisco IPS Module =head2 Inherited Classes =over =item SNMP::Info::Entity =item SNMP::Info::Layer7 =back =head2 Required MIBs =over =item Inherited Classes' MIBs See classes listed above for their required MIBs. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $info->b_mac() Returns base mac. Matches only on e4:d3:f1 =item $info->serial() Fetches serial from Module =item $info->e_index() overrides Entity->e_index() since entity table the IPS delivering is buggy. =item $info->layers Returns '01001000' =item $info->model Returns model name =item $info->productname Retruns the product name =item $info->serial Returns the serial number =item $info->sysdescr Returns the system description =back =head2 Global Methods imported from SNMP::Info::Layer7 See documentation in L for details. =head2 Global Methods imported from SNMP::Info::Entity See documentation in L for details. =head1 TABLE METHODS These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer7 See documentation in L for details. =head2 Table Methods imported from SNMP::Info::Entity See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer7/Neoteris.pm000444000765000024 754413215550564 20566 0ustar00oliverstaff000000000000# SNMP::Info::Layer7::Neoteris # # Copyright (c) 2012 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer7::Neoteris; use strict; use Exporter; use SNMP::Info::Layer7; @SNMP::Info::Layer7::Neoteris::ISA = qw/SNMP::Info::Layer7 Exporter/; @SNMP::Info::Layer7::Neoteris::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer7::MIBS, 'UCD-SNMP-MIB' => 'versionTag', 'JUNIPER-IVE-MIB' => 'productVersion', ); %GLOBALS = ( %SNMP::Info::Layer7::GLOBALS, 'os_ver' => 'productVersion', 'cpu' => 'iveCpuUtil', ); %FUNCS = ( %SNMP::Info::Layer7::FUNCS, ); %MUNGE = ( %SNMP::Info::Layer7::MUNGE, ); sub vendor { return 'juniper'; } sub os { return 'ive'; } sub serial { return ''; } 1; __END__ =head1 NAME SNMP::Info::Layer7::Neoteris - SNMP Interface to Juniper SSL VPN appliances =head1 AUTHORS Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $neoteris = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $neoteris->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Juniper SSL VPN appliances =head2 Inherited Classes =over =item SNMP::Info::Layer7 =back =head2 Required MIBs =over =item F =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $neoteris->vendor() Returns 'juniper'. =item $neoteris->os() Returns C<'ive'>. =item $neoteris->os_ver() C =item $neoteris->cpu() C =item $neoteris->serial() Returns ''. =back =head2 Globals imported from SNMP::Info::Layer7 See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =head2 Table Methods imported from SNMP::Info::Layer7 See documentation in L for details. =cut SNMP-Info-3.39/lib/SNMP/Info/Layer7/Netscaler.pm000444000765000024 1122413215550564 20724 0ustar00oliverstaff000000000000# SNMP::Info::Layer7::Netscaler # # Copyright (c) 2012 Eric Miller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the University of California, Santa Cruz nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. package SNMP::Info::Layer7::Netscaler; use strict; use Exporter; use SNMP::Info::Layer7; @SNMP::Info::Layer7::Netscaler::ISA = qw/SNMP::Info::Layer7 Exporter/; @SNMP::Info::Layer7::Netscaler::EXPORT_OK = qw//; use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; $VERSION = '3.39'; %MIBS = ( %SNMP::Info::Layer7::MIBS, 'NS-ROOT-MIB' => 'sysBuildVersion', ); %GLOBALS = ( %SNMP::Info::Layer7::GLOBALS, 'build_ver' => 'sysBuildVersion', 'sys_hw_desc' => 'sysHardwareVersionDesc', 'cpu' => 'resCpuUsage', ); %FUNCS = ( %SNMP::Info::Layer7::FUNCS, # IP Address Table - NS-ROOT-MIB::nsIpAddrTable 'ip_index' => 'ipAddr', 'ip_netmask' => 'ipNetmask', # TODO VLAN - NS-ROOT-MIB::vlanTable 'ns_vid' =>'vlanId', 'ns_vlan_mem' => 'vlanMemberInterfaces', 'ns_vtag_int' => 'vlanTaggedInterfaces', ); %MUNGE = ( %SNMP::Info::Layer7::MUNGE, ); sub vendor { return 'citrix'; } sub os { return 'netscaler'; } sub serial { return ''; } sub model { my $ns = shift; my $desc = $ns->sys_hw_desc() || ''; $desc =~ s/^.+\bNS//i; return $desc; } sub os_ver { my $ns = shift; my $ver = $ns->build_ver() || ''; if ($ver =~ /^.+\bNS(\d+\.\d+)/) { $ver = $1; } return $ver; } 1; __END__ =head1 NAME SNMP::Info::Layer7::Netscaler - SNMP Interface to Citrix Netscaler appliances =head1 AUTHORS Eric Miller =head1 SYNOPSIS # Let SNMP::Info determine the correct subclass for you. my $ns = new SNMP::Info( AutoSpecify => 1, Debug => 1, DestHost => 'myrouter', Community => 'public', Version => 2 ) or die "Can't connect to DestHost.\n"; my $class = $ns->class(); print "SNMP::Info determined this device to fall under subclass : $class\n"; =head1 DESCRIPTION Subclass for Citrix Netscaler appliances =head2 Inherited Classes =over =item SNMP::Info::Layer7 =back =head2 Required MIBs =over =item F =item Inherited Classes' MIBs See L for its own MIB requirements. =back =head1 GLOBALS These are methods that return scalar value from SNMP =over =item $ns->vendor() Returns 'citrix'. =item $ns->os() Returns 'netscaler'. =item $ns->os_ver() Release extracted from C. =item $ns->model() Model extracted from C. =item $ns->cpu() C =item $ns->build_ver() C =item $ns->sys_hw_desc() C =item $ns->serial() Returns ''. =back =head2 Globals imported from SNMP::Info::Layer7 See documentation in L for details. =head1 TABLE ENTRIES These are methods that return tables of information in the form of a reference to a hash. =over =item $ns->ip_index() C =item $ns->ip_netmask() C =back =head2 Table Methods imported from SNMP::Info::Layer7 See documentation in L for details. =cut SNMP-Info-3.39/t000755000765000024 013215550564 13153 5ustar00oliverstaff000000000000SNMP-Info-3.39/t/00_load.t000444000765000024 33513215550564 14674 0ustar00oliverstaff000000000000#!/usr/bin/perl # 00-load.t - Test loading of SNMP::Info # $Id$ use strict; use warnings; use Test::More tests => 1; BEGIN { use_ok( 'SNMP::Info' ); } diag( "Testing SNMP::Info $SNMP::Info::VERSION, Perl $], $^X" ); SNMP-Info-3.39/xt000755000765000024 013215550564 13343 5ustar00oliverstaff000000000000SNMP-Info-3.39/xt/.perltidyrc000444000765000024 126313215550564 15664 0ustar00oliverstaff000000000000# .perltidyrc - PBP perltidy configuration file for SNMP::Info # $Id$ -l=78 # Max line width is 78 cols -i=4 # Indent level is 4 cols -ci=4 # Continuation indent is 4 cols -nst # Output to STDOUT -se # Errors to STDERR -vt=2 # Maximal vertical tightness -cti=0 # No extra indentation for closing brackets -pt=1 # Medium parenthesis tightness -bt=1 # Medium brace tightness -sbt=1 # Medium square bracket tightness -bbt=1 # Medium block brace tightness -nsfs # No space before semicolons -nolq # Don't outdent long quoted strings -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= && += -= /= |= >>= ||= .= %= ^= x=" # Break before all operators SNMP-Info-3.39/xt/00_local_distribution.t000444000765000024 52313215550564 20035 0ustar00oliverstaff000000000000#!/usr/bin/perl # 00_local_distribution.t - Private test to check distribution # $Id$ use strict; use warnings; use Test::More; eval { require Test::Distribution; }; plan skip_all => 'Optional Test::Distribution not installed' if ($@); # Skip POD tests as we will test separately import Test::Distribution not => [ qw/pod podcover/ ]; SNMP-Info-3.39/xt/00_local_docininfo.t000444000765000024 202213215550564 17302 0ustar00oliverstaff000000000000#!/usr/bin/perl # 00_local_versionsync.t - Private test to check that all modules are listed in Info.pm # $Id$ use warnings; use strict; use File::Find; use Test::More; eval "use File::Slurp"; plan skip_all => "File::Slurp required for testing version sync" if $@; plan qw(no_plan); my %Items; # Grab all the =item's from Info.pm open (I,"blib/lib/SNMP/Info.pm") or fail("Can't open Info.pm"); while () { next unless /^\s*=item\s*(\S+)/; $Items{$1}++; } close I; #warn "items : ",join(', ',keys %Items),"\n"; # Check that each package is represented in Info.pm docs find({wanted => \&check_version, no_chdir => 1}, 'blib'); sub check_version { # $_ is the full path to the file return unless (m{blib/lib/}xms and m{\.pm \z}xms); my $content = read_file($_); # Make sure that this package is listed in Info.pm fail($_) unless $content =~ m/^\s*package\s+(\S+)\s*;/m; my $package = $1; return if $package eq 'SNMP::Info'; fail($_) unless defined $Items{$package}; pass($_); } SNMP-Info-3.39/xt/00_local_perlcritic.t000444000765000024 46013215550564 17456 0ustar00oliverstaff000000000000#!/usr/bin/perl # 00_local_perlcritic.t - Test file for PBP compliance for SNMP::Info # $Id$ use strict; use warnings; use Test::More; eval "use Test::Perl::Critic (-severity => 5)"; plan skip_all => "Test::Perl::Critic required for testing PBP compliance" if $@; Test::Perl::Critic::all_critic_ok(); SNMP-Info-3.39/xt/00_local_pod-coverage.t000444000765000024 117313215550564 17713 0ustar00oliverstaff000000000000#!/usr/bin/perl # pod-coverage.t - Test to check POD coverage of SNMP::Info # $Id$ use strict; use warnings; use Test::More; # Ensure a recent version of Test::Pod::Coverage my $min_tpc = 1.08; eval "use Test::Pod::Coverage $min_tpc"; plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" if $@; # Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, # but older versions don't recognize some common documentation styles my $min_pc = 0.18; eval "use Pod::Coverage $min_pc"; plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" if $@; all_pod_coverage_ok(); SNMP-Info-3.39/xt/00_local_pod.t000444000765000024 45213215550564 16101 0ustar00oliverstaff000000000000#!/usr/bin/perl # pod.t - Test to check for POD errors in SNMP::Info # $Id$ use strict; use warnings; use Test::More; # Ensure a recent version of Test::Pod my $min_tp = 1.22; eval "use Test::Pod $min_tp"; plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; all_pod_files_ok(); SNMP-Info-3.39/xt/00_local_prereq.t000444000765000024 453313215550564 16641 0ustar00oliverstaff000000000000#!/usr/local/bin/perl -w # prereq.t - Test file for prerequesites for SNMP::Info # $Id$ use strict; use warnings; use Test::More tests=> 3; # Check for SNMP Module my $have_snmp=0; eval { require SNMP; }; if ($@){ print STDERR <<'end_snmp'; Net-SNMP not found. Net-SNMP installs the perl modules SNMP and SNMP::Session. Versions 4.2.1 to 5.3 the Perl modules are not distributed on CPAN, you must install from the distribution. Install Net-SNMP from http://net-snmp.sourceforge.net and make sure you run configure with the --with-perl-modules switch! Note to Redhat Users: Redhat, in its infinite wisdom, does not install the Perl modules as part of their 8.0 RPMS. Please uninstall them and install the newest version by hand. Versions 5.3.1 and higher are once again available from CPAN. end_snmp ok(0,'Net-SNMP not installed, or missing Perl modules.'); } else { $have_snmp=1; ok(1,'Net-SNMP installed'); } # Check for version SKIP: { skip('SNMP not installed, no further testing',2) unless $have_snmp; my $VERSION = $SNMP::VERSION; ok(defined $VERSION ? 1 : 1, "found version for SNMP"); my ($ver_maj,$ver_min,$ver_rev) = split(/\./,$VERSION); ok ($ver_maj >= 4, 'Net-SNMP ver 4 or higher'); if ($ver_maj == 4 and $ver_min == 2 and $ver_rev == 0){ print STDERR << "end_420"; SNMP module version 4.2.0 found. Please triple check that you have version 4.2.0 of Net-SNMP installed, and that you did not accidently install the SNMP module found on CPAN. All newer versions are bundled with Net-SNMP, and are not available on CPAN. Please find them at http://net-snmp.sourceforge.net . Make sure you run configure with the --with-perl-modules switch. end_420 } if( $ver_maj == 5 and $ver_min == 0 and $ver_rev == 1 ){ print STDERR << "end_501"; Perl module of Net-SNMP 5.0.1 is buggy. Please upgrade. end_501 } if(( $ver_maj == 5 and $ver_min == 3 and $ver_rev == 1 ) or ( $ver_maj == 5 and $ver_min == 2 and $ver_rev == 3 )) { print STDERR << "end_bulkwalk"; Perl module of Net-SNMP Versions 5.3.1 and 5.2.3 have issues with bulkwalk, turn off bulkwalk. Please upgrade. end_bulkwalk } } print STDERR << "end_mibs"; Make sure you download and install the MIBS needed for SNMP::Info. See Man page or perldoc for SNMP::Info. end_mibs # vim:syntax=perl SNMP-Info-3.39/xt/00_local_spelling.t000444000765000024 513613215550564 17160 0ustar00oliverstaff000000000000#!/usr/bin/perl # 00_local_spelling.t - Private test to spell check documentation # $Id$ use warnings; use strict; use Test::More; eval "use Test::Spelling"; plan skip_all => "Test::Spelling required for checking spelling" if $@; set_spell_cmd('aspell list'); add_stopwords(); all_pod_files_spelling_ok(); __DATA__ 5000BH accelar acl actial adsl ADSL af agere airespace aironet airos alcatel Alcatel alteon altiga Altiga AMAP anycast AOS ap APC APs arista Arista arn arp aruba asa asante ascii asn ati attr ATUC ATUR augenstein autonegotiate autospecify avaya Avaya baetz Barthel bayrs baystack bcn begemot Bernhard bes bgp bigint bigiron Binks bitmask bladecenter bln bpdus BSSID bulkrepeaters bulkwalk Bulley cabletron casted catos cdp centillion CER CES circuitless cisco cisco's ciscovtp citrix Citrix cli concentrators conf config contivity CPAN CPE cpu ctron CVTA cyclades DataSMART datatype De deauthenticate debugsnmp dhcp dlink dmitry DOCSIS DRG ds dslam dslams dsss dynamicgvrp eapol edgeiron eigrp enterasys EOS erszenyi ess ESXi etherlike ethernet EvolutionOS extranet fastiron fdb fdp fenner fixups fortinet Fortinet fortios FreeBSD FS fsm FTOS fwsm FWSM gbe gbesm Gbps getnext Ghz gigabit Gorwits hartmaier huawei Huawei iana ibm icf ieee ietf ifindex ifStackTable igmp IgnoreNetSNMPConf iid iids indices ingen InLoopback ios IOS ip IPv IPV ISID jeroen junos Kentrox Kosmach kramarov Kraus ladvd lans lantronix Lantronix linksys lldp loopback loopdetect lorensen lsb lucent Lucent luiggi lwapp macfilter mau maxrepeaters mbs mckeown mda MERCHANTABILITY mib MIB mibdirs mibs Mikrotik milliwatts MLT MLX MLXe msb mtu multi multicast multimode multiNode multiseg multivlan munge munges namespace ndp netdisco netgear NetIron netmask netscaler Netscaler netscreen Nic Nicolai nmm nopassword nortel nosuch NX oem ofdm oid oids OmniSwitch OO os osi ospf overridable PacketFront pae PAgP Palo petri pfSense phy pinkoski poe pov powerconnect PPI procurve propvirtual proxim PSE pvid PVST qbridge qos queueing Quidway Rackswitch radlan radware Radware Ralf rapidcity readme readonly rebranded retreved retrynosuch Robbert rom ros RouterOS rtt rttmon sca Schenau sergienko SG sieborger Smartport snmp SNMP SNMP's snmpv2 snmpv3 snmpwalk solaris SonicWALL sonmp Sourceforge SPBM ssid SSIDs SSID's SSL stackable stdout steelhead stg Stickland stp subclassesand subcomponents subnet sunos supply's synoptics sys Telesis telesyn telesys terabit tftp tftpfilename tftpserver TiMOS tmnxModel todo tuttle Ubiquiti ucsc UDP unicast uninstall untagged uptime vlan vlans VMware VoIP VPC vpn VRP VSP VSS vtp watanabe wlan wlans WS XMR zoltan zyxel SNMP-Info-3.39/xt/00_local_versionsync.t000444000765000024 207713215550564 17726 0ustar00oliverstaff000000000000#!/usr/bin/perl # 00_local_versionsync.t - Private test to check all version numbers match # $Id$ use warnings; use strict; use File::Find; use Test::More; eval "use File::Slurp"; plan skip_all => "File::Slurp required for testing version sync" if $@; plan qw(no_plan); my $last_version = undef; find({wanted => \&check_version, no_chdir => 1}, 'blib'); if (! defined $last_version) { fail('Failed to find any files with $VERSION'); } sub check_version { # $_ is the full path to the file return if (! m{blib/script/}xms && ! m{\.pm \z}xms); my $content = read_file($_); # only look at perl scripts, not sh scripts return if (m{blib/script/}xms && $content !~ m/\A \#![^\r\n]+?perl/xms); my @version_lines = $content =~ m/ ( [^\n]* \$VERSION\s= [^\n]* ) /gxms; if (@version_lines == 0) { fail($_); } for my $line (@version_lines) { if (!defined $last_version) { $last_version = shift @version_lines; pass($_); } else { is($line, $last_version, $_); } } }