From 3623e33d0ae10eaeca653e00a3796495dbc0f713 Mon Sep 17 00:00:00 2001 From: Tobi Oetiker Date: Fri, 11 Feb 2005 20:22:38 +0000 Subject: initial import --- lib/SNMP_util.pm | 1266 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1266 insertions(+) create mode 100644 lib/SNMP_util.pm (limited to 'lib/SNMP_util.pm') diff --git a/lib/SNMP_util.pm b/lib/SNMP_util.pm new file mode 100644 index 0000000..d103dbc --- /dev/null +++ b/lib/SNMP_util.pm @@ -0,0 +1,1266 @@ +### - *- mode: Perl -*- +###################################################################### +### SNMP_util -- SNMP utilities using SNMP_Session.pm and BER.pm +###################################################################### +### Copyright (c) 1998-2002, Mike Mitchell. +### +### This program is free software; you can redistribute it under the +### "Artistic License" included in this distribution (file "Artistic"). +###################################################################### +### Created by: Mike Mitchell +### +### Contributions and fixes by: +### +### Tobias Oetiker : Basic layout +### Simon Leinen : SNMP_session.pm/BER.pm +### Jeff Allen : length() of undefined value +### Johannes Demel : MIB file parse problem +### Simon Leinen : more OIDs from Interface MIB +### Jacques Supcik : Specify local IP, port +### Tobias Oetiker : HASH as first OID to set SNMP options +### Simon Leinen : 'undefined port' bug +### Daniel McDonald : request for getbulk support +### Laurent Girod : code for snmpwalkhash +### Ian Duplisse : MIB parsing suggestions +### Jakob Ilves : return_array_refs for snmpwalk() +### Valerio Bontempi : IPv6 support +### Lorenzo Colitti : IPv6 support +### Joerg Kummer : TimeTicks support in snmpset() +###################################################################### + +package SNMP_util; + +require 5.004; + +use strict; +use vars qw(@ISA @EXPORT $VERSION); +use Exporter; +use Carp; + +use BER "0.95"; +use SNMP_Session "0.97"; +use Socket; + +$VERSION = '0.98'; + +@ISA = qw(Exporter); + +@EXPORT = qw(snmpget snmpgetnext snmpwalk snmpset snmptrap snmpgetbulk snmpmaptable snmpmaptable4 snmpwalkhash snmpmapOID snmpMIB_to_OID snmpLoad_OID_Cache snmpQueue_MIB_File); + +# The OID numbers from RFC1213 (MIB-II) and RFC1315 (Frame Relay) +# are pre-loaded below. +%SNMP_util::OIDS = + ( + 'iso' => '1', + 'org' => '1.3', + 'dod' => '1.3.6', + 'internet' => '1.3.6.1', + 'directory' => '1.3.6.1.1', + 'mgmt' => '1.3.6.1.2', + 'mib-2' => '1.3.6.1.2.1', + 'system' => '1.3.6.1.2.1.1', + 'sysDescr' => '1.3.6.1.2.1.1.1.0', + 'sysObjectID' => '1.3.6.1.2.1.1.2.0', + 'sysUpTime' => '1.3.6.1.2.1.1.3.0', + 'sysUptime' => '1.3.6.1.2.1.1.3.0', + 'sysContact' => '1.3.6.1.2.1.1.4.0', + 'sysName' => '1.3.6.1.2.1.1.5.0', + 'sysLocation' => '1.3.6.1.2.1.1.6.0', + 'sysServices' => '1.3.6.1.2.1.1.7.0', + 'interfaces' => '1.3.6.1.2.1.2', + 'ifNumber' => '1.3.6.1.2.1.2.1.0', + 'ifTable' => '1.3.6.1.2.1.2.2', + 'ifEntry' => '1.3.6.1.2.1.2.2.1', + 'ifIndex' => '1.3.6.1.2.1.2.2.1.1', + 'ifInOctets' => '1.3.6.1.2.1.2.2.1.10', + 'ifInUcastPkts' => '1.3.6.1.2.1.2.2.1.11', + 'ifInNUcastPkts' => '1.3.6.1.2.1.2.2.1.12', + 'ifInDiscards' => '1.3.6.1.2.1.2.2.1.13', + 'ifInErrors' => '1.3.6.1.2.1.2.2.1.14', + 'ifInUnknownProtos' => '1.3.6.1.2.1.2.2.1.15', + 'ifOutOctets' => '1.3.6.1.2.1.2.2.1.16', + 'ifOutUcastPkts' => '1.3.6.1.2.1.2.2.1.17', + 'ifOutNUcastPkts' => '1.3.6.1.2.1.2.2.1.18', + 'ifOutDiscards' => '1.3.6.1.2.1.2.2.1.19', + 'ifDescr' => '1.3.6.1.2.1.2.2.1.2', + 'ifOutErrors' => '1.3.6.1.2.1.2.2.1.20', + 'ifOutQLen' => '1.3.6.1.2.1.2.2.1.21', + 'ifSpecific' => '1.3.6.1.2.1.2.2.1.22', + 'ifType' => '1.3.6.1.2.1.2.2.1.3', + 'ifMtu' => '1.3.6.1.2.1.2.2.1.4', + 'ifSpeed' => '1.3.6.1.2.1.2.2.1.5', + 'ifPhysAddress' => '1.3.6.1.2.1.2.2.1.6', + 'ifAdminHack' => '1.3.6.1.2.1.2.2.1.7', + 'ifAdminStatus' => '1.3.6.1.2.1.2.2.1.7', + 'ifOperHack' => '1.3.6.1.2.1.2.2.1.8', + 'ifOperStatus' => '1.3.6.1.2.1.2.2.1.8', + 'ifLastChange' => '1.3.6.1.2.1.2.2.1.9', + 'at' => '1.3.6.1.2.1.3', + 'atTable' => '1.3.6.1.2.1.3.1', + 'atEntry' => '1.3.6.1.2.1.3.1.1', + 'atIfIndex' => '1.3.6.1.2.1.3.1.1.1', + 'atPhysAddress' => '1.3.6.1.2.1.3.1.1.2', + 'atNetAddress' => '1.3.6.1.2.1.3.1.1.3', + 'ip' => '1.3.6.1.2.1.4', + 'ipForwarding' => '1.3.6.1.2.1.4.1', + 'ipOutRequests' => '1.3.6.1.2.1.4.10', + 'ipOutDiscards' => '1.3.6.1.2.1.4.11', + 'ipOutNoRoutes' => '1.3.6.1.2.1.4.12', + 'ipReasmTimeout' => '1.3.6.1.2.1.4.13', + 'ipReasmReqds' => '1.3.6.1.2.1.4.14', + 'ipReasmOKs' => '1.3.6.1.2.1.4.15', + 'ipReasmFails' => '1.3.6.1.2.1.4.16', + 'ipFragOKs' => '1.3.6.1.2.1.4.17', + 'ipFragFails' => '1.3.6.1.2.1.4.18', + 'ipFragCreates' => '1.3.6.1.2.1.4.19', + 'ipDefaultTTL' => '1.3.6.1.2.1.4.2', + 'ipAddrTable' => '1.3.6.1.2.1.4.20', + 'ipAddrEntry' => '1.3.6.1.2.1.4.20.1', + 'ipAdEntAddr' => '1.3.6.1.2.1.4.20.1.1', + 'ipAdEntIfIndex' => '1.3.6.1.2.1.4.20.1.2', + 'ipAdEntNetMask' => '1.3.6.1.2.1.4.20.1.3', + 'ipAdEntBcastAddr' => '1.3.6.1.2.1.4.20.1.4', + 'ipAdEntReasmMaxSize' => '1.3.6.1.2.1.4.20.1.5', + 'ipRouteTable' => '1.3.6.1.2.1.4.21', + 'ipRouteEntry' => '1.3.6.1.2.1.4.21.1', + 'ipRouteDest' => '1.3.6.1.2.1.4.21.1.1', + 'ipRouteAge' => '1.3.6.1.2.1.4.21.1.10', + 'ipRouteMask' => '1.3.6.1.2.1.4.21.1.11', + 'ipRouteMetric5' => '1.3.6.1.2.1.4.21.1.12', + 'ipRouteInfo' => '1.3.6.1.2.1.4.21.1.13', + 'ipRouteIfIndex' => '1.3.6.1.2.1.4.21.1.2', + 'ipRouteMetric1' => '1.3.6.1.2.1.4.21.1.3', + 'ipRouteMetric2' => '1.3.6.1.2.1.4.21.1.4', + 'ipRouteMetric3' => '1.3.6.1.2.1.4.21.1.5', + 'ipRouteMetric4' => '1.3.6.1.2.1.4.21.1.6', + 'ipRouteNextHop' => '1.3.6.1.2.1.4.21.1.7', + 'ipRouteType' => '1.3.6.1.2.1.4.21.1.8', + 'ipRouteProto' => '1.3.6.1.2.1.4.21.1.9', + 'ipNetToMediaTable' => '1.3.6.1.2.1.4.22', + 'ipNetToMediaEntry' => '1.3.6.1.2.1.4.22.1', + 'ipNetToMediaIfIndex' => '1.3.6.1.2.1.4.22.1.1', + 'ipNetToMediaPhysAddress' => '1.3.6.1.2.1.4.22.1.2', + 'ipNetToMediaNetAddress' => '1.3.6.1.2.1.4.22.1.3', + 'ipNetToMediaType' => '1.3.6.1.2.1.4.22.1.4', + 'ipRoutingDiscards' => '1.3.6.1.2.1.4.23', + 'ipInReceives' => '1.3.6.1.2.1.4.3', + 'ipInHdrErrors' => '1.3.6.1.2.1.4.4', + 'ipInAddrErrors' => '1.3.6.1.2.1.4.5', + 'ipForwDatagrams' => '1.3.6.1.2.1.4.6', + 'ipInUnknownProtos' => '1.3.6.1.2.1.4.7', + 'ipInDiscards' => '1.3.6.1.2.1.4.8', + 'ipInDelivers' => '1.3.6.1.2.1.4.9', + 'icmp' => '1.3.6.1.2.1.5', + 'icmpInMsgs' => '1.3.6.1.2.1.5.1', + 'icmpInTimestamps' => '1.3.6.1.2.1.5.10', + 'icmpInTimestampReps' => '1.3.6.1.2.1.5.11', + 'icmpInAddrMasks' => '1.3.6.1.2.1.5.12', + 'icmpInAddrMaskReps' => '1.3.6.1.2.1.5.13', + 'icmpOutMsgs' => '1.3.6.1.2.1.5.14', + 'icmpOutErrors' => '1.3.6.1.2.1.5.15', + 'icmpOutDestUnreachs' => '1.3.6.1.2.1.5.16', + 'icmpOutTimeExcds' => '1.3.6.1.2.1.5.17', + 'icmpOutParmProbs' => '1.3.6.1.2.1.5.18', + 'icmpOutSrcQuenchs' => '1.3.6.1.2.1.5.19', + 'icmpInErrors' => '1.3.6.1.2.1.5.2', + 'icmpOutRedirects' => '1.3.6.1.2.1.5.20', + 'icmpOutEchos' => '1.3.6.1.2.1.5.21', + 'icmpOutEchoReps' => '1.3.6.1.2.1.5.22', + 'icmpOutTimestamps' => '1.3.6.1.2.1.5.23', + 'icmpOutTimestampReps' => '1.3.6.1.2.1.5.24', + 'icmpOutAddrMasks' => '1.3.6.1.2.1.5.25', + 'icmpOutAddrMaskReps' => '1.3.6.1.2.1.5.26', + 'icmpInDestUnreachs' => '1.3.6.1.2.1.5.3', + 'icmpInTimeExcds' => '1.3.6.1.2.1.5.4', + 'icmpInParmProbs' => '1.3.6.1.2.1.5.5', + 'icmpInSrcQuenchs' => '1.3.6.1.2.1.5.6', + 'icmpInRedirects' => '1.3.6.1.2.1.5.7', + 'icmpInEchos' => '1.3.6.1.2.1.5.8', + 'icmpInEchoReps' => '1.3.6.1.2.1.5.9', + 'tcp' => '1.3.6.1.2.1.6', + 'tcpRtoAlgorithm' => '1.3.6.1.2.1.6.1', + 'tcpInSegs' => '1.3.6.1.2.1.6.10', + 'tcpOutSegs' => '1.3.6.1.2.1.6.11', + 'tcpRetransSegs' => '1.3.6.1.2.1.6.12', + 'tcpConnTable' => '1.3.6.1.2.1.6.13', + 'tcpConnEntry' => '1.3.6.1.2.1.6.13.1', + 'tcpConnState' => '1.3.6.1.2.1.6.13.1.1', + 'tcpConnLocalAddress' => '1.3.6.1.2.1.6.13.1.2', + 'tcpConnLocalPort' => '1.3.6.1.2.1.6.13.1.3', + 'tcpConnRemAddress' => '1.3.6.1.2.1.6.13.1.4', + 'tcpConnRemPort' => '1.3.6.1.2.1.6.13.1.5', + 'tcpInErrs' => '1.3.6.1.2.1.6.14', + 'tcpOutRsts' => '1.3.6.1.2.1.6.15', + 'tcpRtoMin' => '1.3.6.1.2.1.6.2', + 'tcpRtoMax' => '1.3.6.1.2.1.6.3', + 'tcpMaxConn' => '1.3.6.1.2.1.6.4', + 'tcpActiveOpens' => '1.3.6.1.2.1.6.5', + 'tcpPassiveOpens' => '1.3.6.1.2.1.6.6', + 'tcpAttemptFails' => '1.3.6.1.2.1.6.7', + 'tcpEstabResets' => '1.3.6.1.2.1.6.8', + 'tcpCurrEstab' => '1.3.6.1.2.1.6.9', + 'udp' => '1.3.6.1.2.1.7', + 'udpInDatagrams' => '1.3.6.1.2.1.7.1', + 'udpNoPorts' => '1.3.6.1.2.1.7.2', + 'udpInErrors' => '1.3.6.1.2.1.7.3', + 'udpOutDatagrams' => '1.3.6.1.2.1.7.4', + 'udpTable' => '1.3.6.1.2.1.7.5', + 'udpEntry' => '1.3.6.1.2.1.7.5.1', + 'udpLocalAddress' => '1.3.6.1.2.1.7.5.1.1', + 'udpLocalPort' => '1.3.6.1.2.1.7.5.1.2', + 'egp' => '1.3.6.1.2.1.8', + 'egpInMsgs' => '1.3.6.1.2.1.8.1', + 'egpInErrors' => '1.3.6.1.2.1.8.2', + 'egpOutMsgs' => '1.3.6.1.2.1.8.3', + 'egpOutErrors' => '1.3.6.1.2.1.8.4', + 'egpNeighTable' => '1.3.6.1.2.1.8.5', + 'egpNeighEntry' => '1.3.6.1.2.1.8.5.1', + 'egpNeighState' => '1.3.6.1.2.1.8.5.1.1', + 'egpNeighStateUps' => '1.3.6.1.2.1.8.5.1.10', + 'egpNeighStateDowns' => '1.3.6.1.2.1.8.5.1.11', + 'egpNeighIntervalHello' => '1.3.6.1.2.1.8.5.1.12', + 'egpNeighIntervalPoll' => '1.3.6.1.2.1.8.5.1.13', + 'egpNeighMode' => '1.3.6.1.2.1.8.5.1.14', + 'egpNeighEventTrigger' => '1.3.6.1.2.1.8.5.1.15', + 'egpNeighAddr' => '1.3.6.1.2.1.8.5.1.2', + 'egpNeighAs' => '1.3.6.1.2.1.8.5.1.3', + 'egpNeighInMsgs' => '1.3.6.1.2.1.8.5.1.4', + 'egpNeighInErrs' => '1.3.6.1.2.1.8.5.1.5', + 'egpNeighOutMsgs' => '1.3.6.1.2.1.8.5.1.6', + 'egpNeighOutErrs' => '1.3.6.1.2.1.8.5.1.7', + 'egpNeighInErrMsgs' => '1.3.6.1.2.1.8.5.1.8', + 'egpNeighOutErrMsgs' => '1.3.6.1.2.1.8.5.1.9', + 'egpAs' => '1.3.6.1.2.1.8.6', + 'transmission' => '1.3.6.1.2.1.10', + 'frame-relay' => '1.3.6.1.2.1.10.32', + 'frDlcmiTable' => '1.3.6.1.2.1.10.32.1', + 'frDlcmiEntry' => '1.3.6.1.2.1.10.32.1.1', + 'frDlcmiIfIndex' => '1.3.6.1.2.1.10.32.1.1.1', + 'frDlcmiState' => '1.3.6.1.2.1.10.32.1.1.2', + 'frDlcmiAddress' => '1.3.6.1.2.1.10.32.1.1.3', + 'frDlcmiAddressLen' => '1.3.6.1.2.1.10.32.1.1.4', + 'frDlcmiPollingInterval' => '1.3.6.1.2.1.10.32.1.1.5', + 'frDlcmiFullEnquiryInterval' => '1.3.6.1.2.1.10.32.1.1.6', + 'frDlcmiErrorThreshold' => '1.3.6.1.2.1.10.32.1.1.7', + 'frDlcmiMonitoredEvents' => '1.3.6.1.2.1.10.32.1.1.8', + 'frDlcmiMaxSupportedVCs' => '1.3.6.1.2.1.10.32.1.1.9', + 'frDlcmiMulticast' => '1.3.6.1.2.1.10.32.1.1.10', + 'frCircuitTable' => '1.3.6.1.2.1.10.32.2', + 'frCircuitEntry' => '1.3.6.1.2.1.10.32.2.1', + 'frCircuitIfIndex' => '1.3.6.1.2.1.10.32.2.1.1', + 'frCircuitDlci' => '1.3.6.1.2.1.10.32.2.1.2', + 'frCircuitState' => '1.3.6.1.2.1.10.32.2.1.3', + 'frCircuitReceivedFECNs' => '1.3.6.1.2.1.10.32.2.1.4', + 'frCircuitReceivedBECNs' => '1.3.6.1.2.1.10.32.2.1.5', + 'frCircuitSentFrames' => '1.3.6.1.2.1.10.32.2.1.6', + 'frCircuitSentOctets' => '1.3.6.1.2.1.10.32.2.1.7', + 'frOutOctets' => '1.3.6.1.2.1.10.32.2.1.7', + 'frCircuitReceivedFrames' => '1.3.6.1.2.1.10.32.2.1.8', + 'frCircuitReceivedOctets' => '1.3.6.1.2.1.10.32.2.1.9', + 'frInOctets' => '1.3.6.1.2.1.10.32.2.1.9', + 'frCircuitCreationTime' => '1.3.6.1.2.1.10.32.2.1.10', + 'frCircuitLastTimeChange' => '1.3.6.1.2.1.10.32.2.1.11', + 'frCircuitCommittedBurst' => '1.3.6.1.2.1.10.32.2.1.12', + 'frCircuitExcessBurst' => '1.3.6.1.2.1.10.32.2.1.13', + 'frCircuitThroughput' => '1.3.6.1.2.1.10.32.2.1.14', + 'frErrTable' => '1.3.6.1.2.1.10.32.3', + 'frErrEntry' => '1.3.6.1.2.1.10.32.3.1', + 'frErrIfIndex' => '1.3.6.1.2.1.10.32.3.1.1', + 'frErrType' => '1.3.6.1.2.1.10.32.3.1.2', + 'frErrData' => '1.3.6.1.2.1.10.32.3.1.3', + 'frErrTime' => '1.3.6.1.2.1.10.32.3.1.4', + 'frame-relay-globals' => '1.3.6.1.2.1.10.32.4', + 'frTrapState' => '1.3.6.1.2.1.10.32.4.1', + 'snmp' => '1.3.6.1.2.1.11', + 'snmpInPkts' => '1.3.6.1.2.1.11.1', + 'snmpInBadValues' => '1.3.6.1.2.1.11.10', + 'snmpInReadOnlys' => '1.3.6.1.2.1.11.11', + 'snmpInGenErrs' => '1.3.6.1.2.1.11.12', + 'snmpInTotalReqVars' => '1.3.6.1.2.1.11.13', + 'snmpInTotalSetVars' => '1.3.6.1.2.1.11.14', + 'snmpInGetRequests' => '1.3.6.1.2.1.11.15', + 'snmpInGetNexts' => '1.3.6.1.2.1.11.16', + 'snmpInSetRequests' => '1.3.6.1.2.1.11.17', + 'snmpInGetResponses' => '1.3.6.1.2.1.11.18', + 'snmpInTraps' => '1.3.6.1.2.1.11.19', + 'snmpOutPkts' => '1.3.6.1.2.1.11.2', + 'snmpOutTooBigs' => '1.3.6.1.2.1.11.20', + 'snmpOutNoSuchNames' => '1.3.6.1.2.1.11.21', + 'snmpOutBadValues' => '1.3.6.1.2.1.11.22', + 'snmpOutGenErrs' => '1.3.6.1.2.1.11.24', + 'snmpOutGetRequests' => '1.3.6.1.2.1.11.25', + 'snmpOutGetNexts' => '1.3.6.1.2.1.11.26', + 'snmpOutSetRequests' => '1.3.6.1.2.1.11.27', + 'snmpOutGetResponses' => '1.3.6.1.2.1.11.28', + 'snmpOutTraps' => '1.3.6.1.2.1.11.29', + 'snmpInBadVersions' => '1.3.6.1.2.1.11.3', + 'snmpEnableAuthenTraps' => '1.3.6.1.2.1.11.30', + 'snmpInBadCommunityNames' => '1.3.6.1.2.1.11.4', + 'snmpInBadCommunityUses' => '1.3.6.1.2.1.11.5', + 'snmpInASNParseErrs' => '1.3.6.1.2.1.11.6', + 'snmpInTooBigs' => '1.3.6.1.2.1.11.8', + 'snmpInNoSuchNames' => '1.3.6.1.2.1.11.9', + 'ifName' => '1.3.6.1.2.1.31.1.1.1.1', + 'ifInMulticastPkts' => '1.3.6.1.2.1.31.1.1.1.2', + 'ifInBroadcastPkts' => '1.3.6.1.2.1.31.1.1.1.3', + 'ifOutMulticastPkts' => '1.3.6.1.2.1.31.1.1.1.4', + 'ifOutBroadcastPkts' => '1.3.6.1.2.1.31.1.1.1.5', + 'ifHCInOctets' => '1.3.6.1.2.1.31.1.1.1.6', + 'ifHCInUcastPkts' => '1.3.6.1.2.1.31.1.1.1.7', + 'ifHCInMulticastPkts' => '1.3.6.1.2.1.31.1.1.1.8', + 'ifHCInBroadcastPkts' => '1.3.6.1.2.1.31.1.1.1.9', + 'ifHCOutOctets' => '1.3.6.1.2.1.31.1.1.1.10', + 'ifHCOutUcastPkts' => '1.3.6.1.2.1.31.1.1.1.11', + 'ifHCOutMulticastPkts' => '1.3.6.1.2.1.31.1.1.1.12', + 'ifHCOutBroadcastPkts' => '1.3.6.1.2.1.31.1.1.1.13', + 'ifLinkUpDownTrapEnable' => '1.3.6.1.2.1.31.1.1.1.14', + 'ifHighSpeed' => '1.3.6.1.2.1.31.1.1.1.15', + 'ifPromiscuousMode' => '1.3.6.1.2.1.31.1.1.1.16', + 'ifConnectorPresent' => '1.3.6.1.2.1.31.1.1.1.17', + 'ifAlias' => '1.3.6.1.2.1.31.1.1.1.18', + 'ifCounterDiscontinuityTime' => '1.3.6.1.2.1.31.1.1.1.19', + 'experimental' => '1.3.6.1.3', + 'private' => '1.3.6.1.4', + 'enterprises' => '1.3.6.1.4.1', + ); + +# GIL +my %revOIDS = (); # Reversed %SNMP_util::OIDS hash +my $RevNeeded = 1; + +my $agent_start_time = time; + +undef $SNMP_util::Host; +undef $SNMP_util::Session; +undef $SNMP_util::Version; +undef $SNMP_util::LHost; +undef $SNMP_util::IPv4only; +$SNMP_util::Debug = 0; +$SNMP_util::CacheFile = "OID_cache.txt"; +$SNMP_util::CacheLoaded = 0; +$SNMP_util::Return_array_refs = 0; + +srand(time + $$); + +### Prototypes +sub snmpget ($@); +sub snmpgetnext ($@); +sub snmpopen ($$$); +sub snmpwalk ($@); +sub snmpwalk_flg ($$@); +sub snmpset ($@); +sub snmptrap ($$$$$@); +sub snmpgetbulk ($$$@); +sub snmpmaptable ($$@); +sub snmpmaptable4 ($$$@); +sub snmpwalkhash ($$@); +sub toOID (@); +sub snmpmapOID (@); +sub snmpMIB_to_OID ($); +sub encode_oid_with_errmsg ($); +sub Check_OID ($); +sub snmpLoad_OID_Cache ($); +sub snmpQueue_MIB_File (@); + +sub version () { $VERSION; } + +# +# Start an snmp session +# +sub snmpopen ($$$) { + my($host, $type, $vars) = @_; + my($nhost, $port, $community, $lhost, $lport, $nlhost); + my($timeout, $retries, $backoff, $version); + my $v4onlystr; + + $type = 0 if (!defined($type)); + $community = "public"; + $nlhost = ""; + + ($community, $host) = ($1, $2) if ($host =~ /^(.*)@([^@]+)$/); + + # We can't split on the : character because a numeric IPv6 + # address contains a variable number of :'s + my $opts; + if( ($host =~ /^(\[.*\]):(.*)$/) || ($host =~ /^(\[.*\])$/) ) { + # Numeric IPv6 address between [] + ($host, $opts) = ($1, $2); + } else { + # Hostname or numeric IPv4 address + ($host, $opts) = split(':', $host, 2); + } + ($port, $timeout, $retries, $backoff, $version, $v4onlystr) = split(':', $opts, 6) + if(defined($opts) && (length $opts > 0) ); + + undef($version) if (defined($version) && length($version) <= 0); + $v4onlystr = "" unless defined $v4onlystr; + $version = '1' unless defined $version; + if (defined($port) && ($port =~ /^([^!]*)!(.*)$/)) { + ($port, $lhost) = ($1, $2); + $nlhost = $lhost; + ($lhost, $lport) = ($1, $2) if ($lhost =~ /^(.*)!(.*)$/); + undef($lhost) if (defined($lhost) && (length($lhost) <= 0)); + undef($lport) if (defined($lport) && (length($lport) <= 0)); + } + undef($port) if (defined($port) && length($port) <= 0); + $port = 162 if ($type == 1 && !defined($port)); + $nhost = "$community\@$host"; + $nhost .= ":" . $port if (defined($port)); + + if ((!defined($SNMP_util::Session)) + || ($SNMP_util::Host ne $nhost) + || ($SNMP_util::Version ne $version) + || ($SNMP_util::LHost ne $nlhost) + || ($SNMP_util::IPv4only ne $v4onlystr)) { + if (defined($SNMP_util::Session)) { + $SNMP_util::Session->close(); + undef $SNMP_util::Session; + undef $SNMP_util::Host; + undef $SNMP_util::Version; + undef $SNMP_util::LHost; + undef $SNMP_util::IPv4only; + } + $SNMP_util::Session = ($version =~ /^2c?$/i) + ? SNMPv2c_Session->open($host, $community, $port, undef, + $lport, undef, $lhost, ($v4onlystr eq 'v4only') ? 1:0 ) + : SNMP_Session->open($host, $community, $port, undef, + $lport, undef, $lhost, ($v4onlystr eq 'v4only') ? 1:0 ); + ($SNMP_util::Host = $nhost, $SNMP_util::Version = $version, + $SNMP_util::LHost = $nlhost, $SNMP_util::IPv4only = $v4onlystr) if defined($SNMP_util::Session); + } + + if (defined($SNMP_util::Session)) { + if (ref $vars->[0] eq 'HASH') { + my $opts = shift @$vars; + foreach $type (keys %$opts) { + if ($type eq 'return_array_refs') { + $SNMP_util::Return_array_refs = $opts->{$type}; + } + else { + if (exists $SNMP_util::Session->{$type}) { + if ($type eq 'timeout') { + $SNMP_util::Session->set_timeout($opts->{$type}); + } elsif ($type eq 'retries') { + $SNMP_util::Session->set_retries($opts->{$type}); + } elsif ($type eq 'backoff') { + $SNMP_util::Session->set_backoff($opts->{$type}); + } else { + $SNMP_util::Session->{$type} = $opts->{$type}; + } + } else { + carp "SNMPopen Unknown SNMP Option Key '$type'\n" + unless ($SNMP_Session::suppress_warnings > 1); + } + } + } + } + $SNMP_util::Session->set_timeout($timeout) + if (defined($timeout) && (length($timeout) > 0)); + $SNMP_util::Session->set_retries($retries) + if (defined($retries) && (length($retries) > 0)); + $SNMP_util::Session->set_backoff($backoff) + if (defined($backoff) && (length($backoff) > 0)); + } + return $SNMP_util::Session; +} + + +# +# A restricted snmpget. +# +sub snmpget ($@) { + my($host, @vars) = @_; + my(@enoid, $var, $response, $bindings, $binding, $value, $oid, @retvals); + my $session; + + $session = &snmpopen($host, 0, \@vars); + if (!defined($session)) { + carp "SNMPGET Problem for $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + + @enoid = &toOID(@vars); + return undef unless defined $enoid[0]; + + if ($session->get_request_response(@enoid)) { + $response = $session->pdu_buffer; + ($bindings) = $session->decode_get_response($response); + while ($bindings) { + ($binding, $bindings) = decode_sequence($bindings); + ($oid, $value) = decode_by_template($binding, "%O%@"); + my $tempo = pretty_print($value); + push @retvals, $tempo; + } + return(@retvals); + } + $var = join(' ', @vars); + carp "SNMPGET Problem for $var on $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; +} + +# +# A restricted snmpgetnext. +# +sub snmpgetnext ($@) { + my($host, @vars) = @_; + my(@enoid, $var, $response, $bindings, $binding); + my($value, $upoid, $oid, @retvals); + my($noid); + my $session; + + $session = &snmpopen($host, 0, \@vars); + if (!defined($session)) { + carp "SNMPGETNEXT Problem for $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + + @enoid = &toOID(@vars); + return undef unless defined $enoid[0]; + + undef @vars; + undef @retvals; + foreach $noid (@enoid) { + $upoid = pretty_print($noid); + push(@vars, $upoid); + } + if ($session->getnext_request_response(@enoid)) { + $response = $session->pdu_buffer; + ($bindings) = $session->decode_get_response($response); + while ($bindings) { + ($binding, $bindings) = decode_sequence($bindings); + ($oid, $value) = decode_by_template($binding, "%O%@"); + my $tempo = pretty_print($oid); + my $tempv = pretty_print($value); + push @retvals, "$tempo:$tempv"; + } + return (@retvals); + } else { + $var = join(' ', @vars); + carp "SNMPGETNEXT Problem for $var on $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } +} + +# +# A restricted snmpwalk. +# +sub snmpwalk ($@) { + my($host, @vars) = @_; + return(&snmpwalk_flg($host, undef, @vars)); +} + +# +# Walk the MIB, putting everything you find into hashes. +# +sub snmpwalkhash($$@) { +# my($host, $hash_sub, @vars) = @_; + return(&snmpwalk_flg( @_ )); +} + +sub snmpwalk_flg ($$@) { + my($host, $hash_sub, @vars) = @_; + my(@enoid, $var, $response, $bindings, $binding); + my($value, $upoid, $oid, @retvals, @retvaltmprefs); + my($got, @nnoid, $noid, $ok, $ix, @avars); + my $session; + my(%soid); + my(%done, %rethash); + + $session = &snmpopen($host, 0, \@vars); + if (!defined($session)) { + carp "SNMPWALK Problem for $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + + @enoid = toOID(@vars); + return undef unless defined $enoid[0]; + + # GIL + # + # Create/Refresh a reversed hash with oid -> name + # + if (defined($hash_sub) && $RevNeeded) { + %revOIDS = reverse %SNMP_util::OIDS; + $RevNeeded = 0; + } + + $got = 0; + @nnoid = @enoid; + undef @vars; + foreach $noid (@enoid) { + $upoid = pretty_print($noid); + push(@vars, $upoid); + } + + # @vars is the original set of walked variables. + # @avars is the current set of walked variables as the + # walk goes on. + # @vars stays static while @avars may shrink as we reach end + # of walk for individual variables during PDU exchange. + + @avars = @vars; + + # IlvJa + # + # Create temporary array of refs to return vals. + + if ($SNMP_util::Return_array_refs) { + for($ix = 0;$ix < scalar @vars; $ix++) { + my $tmparray = []; + $retvaltmprefs[$ix] = $tmparray; + $retvals[$ix] = $tmparray; + } + } + + + while(($SNMP_util::Version ne '1' && $session->{'use_getbulk'}) + ? $session->getbulk_request_response(0, + $session->default_max_repetitions(), + @nnoid) + : $session->getnext_request_response(@nnoid)) + { + $got = 1; + $response = $session->pdu_buffer; + ($bindings) = $session->decode_get_response($response); + $ix = 0; + while ($bindings) { + ($binding, $bindings) = decode_sequence($bindings); + unless ($nnoid[$ix]) { # IlvJa + $ix = ++$ix % (scalar @avars); + next; + } + ($oid, $value) = decode_by_template($binding, "%O%@"); + $ok = 0; + my $tempo = pretty_print($oid); + $noid = $avars[$ix]; # IlvJa + if ($tempo =~ /^$noid\./ || $tempo eq $noid ) { + $ok = 1; + $upoid = $noid; + } else { + # IlvJa + # + # The walk for variable $var[$ix] has been finished as + # $nnoid[$ix] no longer is in the $avar[$ix] OID tree. + # So we exclude this variable from further requests. + + $avars[$ix] = ""; + $nnoid[$ix] = ""; + $retvaltmprefs[$ix] = undef if $SNMP_util::Return_array_refs; + } + if ($ok) { + my $tmp = encode_oid_with_errmsg ($tempo); + return undef unless defined $tmp; + next if (exists($done{$tmp})); # GIL + $nnoid[$ix] = $tmp; # Keep on walking. (IlvJa) + my $tempv = pretty_print($value); + if (defined($hash_sub)) { + # + # extract name of the oid, if possible, the rest becomes the instance + # + my $inst = ""; + my $upo = $upoid; + while (!exists($revOIDS{$upo}) && length($upo)) { + $upo =~ s/(\.\d+?)$//; + if (defined($1) && length($1)) { + $inst = $1 . $inst; + } else { + $upo = ""; + last; + } + } + if (length($upo) && exists($revOIDS{$upo})) { + $upo = $revOIDS{$upo} . $inst; + } else { + $upo = $upoid; + } + + $inst = ""; + while (!exists($revOIDS{$tempo}) && length($tempo)) { + $tempo =~ s/(\.\d+?)$//; + if (defined($1) && length($1)) { + $inst = $1 . $inst; + } else { + $tempo = ""; + last; + } + } + if (length($tempo) && exists($revOIDS{$tempo})) { + $tempo = $revOIDS{$tempo} . $inst; + } else { + $tempo = pretty_print($oid); + } + # + # call hash_sub + # + &$hash_sub(\%rethash, $host, $revOIDS{$tempo}, $tempo, $inst, + $tempv, $upo); + } else { + if ($SNMP_util::Return_array_refs) { + $tempo=~s/^$upoid\.//; + push @{$retvaltmprefs[$ix]}, "$tempo:$tempv"; + } else { + $tempo=~s/^$upoid\.// if ($#enoid <= 0); + push @retvals, "$tempo:$tempv"; + } + } + $done{$tmp} = 1; # GIL + } + $ix = ++$ix % (scalar @avars); + } + + # Ok, @nnoid should contain the remaining variables for the + # next request. Some or all entries in @nnoid might be the empty + # string. If the nth element in @nnoid is "" that means that + # the walk related to the nth variable in the last request has been + # completed and we should not include that var in subsequent reqs. + + # Clean up both @nnoid and @avars so "" elements are removed. + @nnoid = grep (($_), @nnoid); + @avars = grep (($_), @avars); + @retvaltmprefs = grep (($_), @retvaltmprefs); + + last if ($#nnoid < 0); # @nnoid empty means we are done walking. + } + if ($got) { + if (defined($hash_sub)) { + return (%rethash) + } else { + return (@retvals); + } + } else { + $var = join(' ', @vars); + carp "SNMPWALK Problem for $var on $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } +} + +# +# A restricted snmpset. +# +sub snmpset($@) { + my($host, @vars) = @_; + my(@enoid, $response, $bindings, $binding); + my($oid, @retvals, $type, $value); + my $session; + + $session = &snmpopen($host, 0, \@vars); + if (!defined($session)) { + carp "SNMPSET Problem for $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + + while(@vars) { + ($oid) = toOID((shift @vars)); + $type = shift @vars; + $value = shift @vars; + if ($type =~ /string/i) { + $value = encode_string($value); + push @enoid, [$oid,$value]; + } elsif ($type =~ /ipaddr/i) { + $value = encode_ip_address($value); + push @enoid, [$oid,$value]; + } elsif ($type =~ /int/i) { + $value = encode_int($value); + push @enoid, [$oid,$value]; + } elsif ($type =~ /oid/i) { + my $tmp = encode_oid_with_errmsg($value); + return undef unless defined $tmp; + push @enoid, [$oid,$tmp]; + } elsif ($type =~ /timeticks/i) { + $value = encode_timeticks($value); + push @enoid, [$oid,$value]; + } else { + carp "unknown SNMP type: $type\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + } + return undef unless defined $enoid[0]; + if ($session->set_request_response(@enoid)) { + $response = $session->pdu_buffer; + ($bindings) = $session->decode_get_response($response); + while ($bindings) { + ($binding, $bindings) = decode_sequence($bindings); + ($oid, $value) = decode_by_template($binding, "%O%@"); + my $tempo = pretty_print($value); + push @retvals, $tempo; + } + return (@retvals); + } + return undef; +} + +# +# Send an SNMP trap +# +sub snmptrap($$$$$@) { + my($host, $ent, $agent, $gen, $spec, @vars) = @_; + my($oid, @retvals, $type, $value); + my(@enoid); + my $session; + + $session = &snmpopen($host, 1, \@vars); + if (!defined($session)) { + carp "SNMPTRAP Problem for $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + + if ($agent =~ /^\d+\.\d+\.\d+\.\d+(.*)/ ) { + $agent = pack("C*", split /\./, $agent); + } else { + $agent = inet_aton($agent); + } + push @enoid, toOID(($ent)); + push @enoid, encode_ip_address($agent); + push @enoid, encode_int($gen); + push @enoid, encode_int($spec); + push @enoid, encode_timeticks((time-$agent_start_time) * 100); + while(@vars) { + ($oid) = toOID((shift @vars)); + $type = shift @vars; + $value = shift @vars; + if ($type =~ /string/i) { + $value = encode_string($value); + push @enoid, [$oid,$value]; + } elsif ($type =~ /ipaddr/i) { + $value = encode_ip_address($value); + push @enoid, [$oid,$value]; + } elsif ($type =~ /int/i) { + $value = encode_int($value); + push @enoid, [$oid,$value]; + } elsif ($type =~ /oid/i) { + my $tmp = encode_oid_with_errmsg($value); + return undef unless defined $tmp; + push @enoid, [$oid,$tmp]; + } else { + carp "unknown SNMP type: $type\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + } + return($session->trap_request_send(@enoid)); +} + +# +# A restricted snmpgetbulk. +# +sub snmpgetbulk ($$$@) { + my($host, $nr, $mr, @vars) = @_; + my(@enoid, $var, $response, $bindings, $binding); + my($value, $upoid, $oid, @retvals); + my($noid); + my $session; + + $session = &snmpopen($host, 0, \@vars); + if (!defined($session)) { + carp "SNMPGETBULK Problem for $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + + @enoid = &toOID(@vars); + return undef unless defined $enoid[0]; + + undef @vars; + undef @retvals; + foreach $noid (@enoid) { + $upoid = pretty_print($noid); + push(@vars, $upoid); + } + if ($session->getbulk_request_response($nr, $mr, @enoid)) { + $response = $session->pdu_buffer; + ($bindings) = $session->decode_get_response($response); + while ($bindings) { + ($binding, $bindings) = decode_sequence($bindings); + ($oid, $value) = decode_by_template($binding, "%O%@"); + my $tempo = pretty_print($oid); + my $tempv = pretty_print($value); + push @retvals, "$tempo:$tempv"; + } + return (@retvals); + } else { + $var = join(' ', @vars); + carp "SNMPGETBULK Problem for $var on $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } +} + +# +# walk a table, calling a user-supplied function for each +# column of a table. +# +sub snmpmaptable($$@) { + my($host, $fun, @vars) = @_; + return snmpmaptable4($host, $fun, 0, @vars); +} + +sub snmpmaptable4($$$@) { + my($host, $fun, $max_reps, @vars) = @_; + my(@enoid, $var, $session); + + $session = &snmpopen($host, 0, \@vars); + if (!defined($session)) { + carp "SNMPMAPTABLE Problem for $host\n" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + + foreach $var (toOID(@vars)) { + push(@enoid, [split('\.', pretty_print($var))]); + } + + $max_reps = $session->default_max_repetitions() if ($max_reps <= 0); + + return $session->map_table_start_end( [@enoid], + sub() { + my ($ind, @vals) = @_; + my (@pvals, $val); + + foreach $val (@vals) { + push(@pvals, pretty_print($val)); + } + &$fun($ind, @pvals); + }, + "", undef, $max_reps); +} + + +# +# Given an OID in either ASN.1 or mixed text/ASN.1 notation, return an +# encoded OID. +# +sub toOID(@) { + my(@vars) = @_; + my($oid, $var, $tmp, $tmpv, @retvar); + + undef @retvar; + foreach $var (@vars) { + ($oid, $tmp) = &Check_OID($var); + if (!$oid && $SNMP_util::CacheLoaded == 0) { + $tmp = $SNMP_Session::suppress_warnings; + $SNMP_Session::suppress_warnings = 1000; + + &snmpLoad_OID_Cache($SNMP_util::CacheFile); + + $SNMP_util::CacheLoaded = 1; + $SNMP_Session::suppress_warnings = $tmp; + + ($oid, $tmp) = &Check_OID($var); + } + while (!$oid && $#SNMP_util::MIB_Files >= 0) { + $tmp = $SNMP_Session::suppress_warnings; + $SNMP_Session::suppress_warnings = 1000; + + snmpMIB_to_OID(shift(@SNMP_util::MIB_Files)); + + $SNMP_Session::suppress_warnings = $tmp; + + ($oid, $tmp) = &Check_OID($var); + if ($oid) { + open(CACHE, ">>$SNMP_util::CacheFile"); + print CACHE "$tmp\t$oid\n"; + close(CACHE); + } + } + if ($oid) { + $var =~ s/^$tmp/$oid/; + } else { + carp "Unknown SNMP var $var\n" + unless ($SNMP_Session::suppress_warnings > 1); + next; + } + while ($var =~ /\"([^\"]*)\"/) { + $tmp = sprintf("%d.%s", length($1), join(".", map(ord, split(//, $1)))); + $var =~ s/\"$1\"/$tmp/; + } + print "toOID: $var\n" if $SNMP_util::Debug; + $tmp = encode_oid_with_errmsg($var); + return undef unless defined $tmp; + push(@retvar, $tmp); + } + return @retvar; +} + +# +# Add passed-in text, OID pairs to the OID mapping table. +# +sub snmpmapOID(@) +{ + my(@vars) = @_; + my($oid, $txt, $ind); + + $ind = 0; + while($ind <= $#vars) { + $txt = $vars[$ind++]; + next unless($txt =~ /^(([a-zA-Z][a-zA-Z\d\-]*\.)*([a-zA-Z][a-zA-Z\d\-]*))$/); + + $oid = $vars[$ind++]; + next unless($oid =~ /^((\d+.)*\d+)$/); + + $SNMP_util::OIDS{$txt} = $oid; + $RevNeeded = 1; + print "snmpmapOID: $txt => $oid\n" if $SNMP_util::Debug; + } + + return undef; +} + +# +# Open the passed-in file name and read it in to populate +# the cache of text-to-OID map table. It expects lines +# with two fields, the first the textual string like "ifInOctets", +# and the second the OID value, like "1.3.6.1.2.1.2.2.1.10". +# +# blank lines and anything after a '#' or between '--' is ignored. +# +sub snmpLoad_OID_Cache ($) { + my($arg) = @_; + my($txt, $oid); + + if (!open(CACHE, $arg)) { + carp "snmpLoad_OID_Cache: Can't open $arg: $!" + unless ($SNMP_Session::suppress_warnings > 1); + return -1; + } + + while() { + s/#.*//; + s/--.*--//g; + s/--.*//; + next if (/^$/); + next unless (/\s/); + chop; + ($txt, $oid) = split(' ', $_, 2); + &snmpmapOID($txt, $oid); + } + close(CACHE); + return 0; +} + +# +# Check to see if an OID is in the text-to-OID cache. +# Returns the OID and the corresponding text as two separate +# elements. +# +sub Check_OID ($) { + my($var) = @_; + my($tmp, $tmpv, $oid); + + if ($var =~ /^(([a-zA-Z][a-zA-Z\d\-]*\.)*([a-zA-Z][a-zA-Z\d\-]*))/) + { + $tmp = $&; + $tmpv = $tmp; + for (;;) { + last if defined($SNMP_util::OIDS{$tmpv}); + last if !($tmpv =~ s/^[^\.]*\.//); + } + $oid = $SNMP_util::OIDS{$tmpv}; + if ($oid) { + return ($oid, $tmp); + } else { + return undef; + } + } + return ($var, $var); +} + +# +# Save the passed-in list of MIB files until an OID can't be +# found in the existing table. At that time the MIB file will +# be loaded, and the lookup attempted again. +# +sub snmpQueue_MIB_File (@) { + my(@files) = @_; + my($file); + + foreach $file (@files) { + push(@SNMP_util::MIB_Files, $file); + } +} + +# +# Read in the passed MIB file, parsing it +# for their text-to-OID mappings +# +sub snmpMIB_to_OID ($) { + my($arg) = @_; + my($quote, $buf, $var, $code, $val, $tmp, $tmpv, $strt); + my($ret, $pass, $pos, $need2pass, $cnt, %prev); + my(%Link) = ( + 'org' => 'iso', + 'dod' => 'org', + 'internet' => 'dod', + 'directory' => 'internet', + 'mgmt' => 'internet', + 'mib-2' => 'mgmt', + 'experimental' => 'internet', + 'private' => 'internet', + 'enterprises' => 'private', + ); + + if (!open(MIB, $arg)) { + carp "snmpMIB_to_OID: Can't open $arg: $!" + unless ($SNMP_Session::suppress_warnings > 1); + return -1; + } + print "snmpMIB_to_OID: loading $arg\n" if $SNMP_util::Debug; + $ret = 0; + $pass = 0; + $need2pass = 1; + $cnt = 0; + $pos = tell(MIB); + while($need2pass) { + while() { + s/--.*--//g; # throw away comments (-- anything --) + s/--.*//; # throw away comments (-- anything EOL) + if ($quote) { + next unless /"/; + $quote = 0; + } + chop; +# +# $buf = "$buf $_"; +# Previous line removed (and following replacement) +# suggested by Brian Reichert, reichert@numachi.com +# + $buf .= ' ' . $_; + $buf =~ s/\s+/ /g; + + if ($buf =~ / DEFINITIONS ::= BEGIN/) { + if ($pass == 0 && $need2pass) { + seek(MIB, $pos, 0); + $buf = ""; + $pass = 1; + $need2pass = 0; + $cnt = 0; + next; + } + $need2pass = 0; + $pass = 0; + $pos = tell(MIB); + undef %Link; + undef %prev; + %Link = ( + 'org' => 'iso', + 'dod' => 'org', + 'internet' => 'dod', + 'directory' => 'internet', + 'mgmt' => 'internet', + 'mib-2' => 'mgmt', + 'experimental' => 'internet', + 'private' => 'internet', + 'enterprises' => 'private', + ); + $buf = ""; + next; + } + + $buf =~ s/OBJECT-TYPE/OBJECT IDENTIFIER/; + $buf =~ s/OBJECT-IDENTITY/OBJECT IDENTIFIER/; + $buf =~ s/OBJECT-GROUP/OBJECT IDENTIFIER/; + $buf =~ s/MODULE-IDENTITY/OBJECT IDENTIFIER/; + $buf =~ s/ IMPORTS .*\;//; + $buf =~ s/ SEQUENCE {.*}//; + $buf =~ s/ SYNTAX .*//; + $buf =~ s/ [\w-]+ ::= OBJECT IDENTIFIER//; + $buf =~ s/ OBJECT IDENTIFIER .* ::= {/ OBJECT IDENTIFIER ::= {/; + $buf =~ s/".*"//; + if ($buf =~ /"/) { + $quote = 1; + } + + if ($buf =~ / ([\w\-]+) OBJECT IDENTIFIER ::= {([^}]+)}/) { + $var = $1; + $buf = $2; + undef $val; + $buf =~ s/ +$//; + ($code, $val) = split(' ', $buf, 2); + + if (!defined($val) || (length($val) <= 0)) { + $SNMP_util::OIDS{$var} = $code; + $cnt++; + print "'$var' => '$code'\n" if $SNMP_util::Debug; + } else { + $strt = $code; + while($val =~ / /) { + ($tmp, $val) = split(' ', $val, 2); + if ($tmp =~ /([\w\-]+)\((\d+)\)/) { + $tmp = $1; + $tmpv = "$SNMP_util::OIDS{$strt}.$2"; + $Link{$tmp} = $strt; + if (!defined($prev{$tmp}) && defined($SNMP_util::OIDS{$tmp})) { + if ($tmpv ne $SNMP_util::OIDS{$tmp}) { + $strt = "$strt.$tmp"; + $SNMP_util::OIDS{$strt} = $tmpv; + $cnt++; + } + } else { + $prev{$tmp} = 1; + $SNMP_util::OIDS{$tmp} = $tmpv; + $cnt++; + $strt = $tmp; + } + } + } + + if (!defined($SNMP_util::OIDS{$strt})) { + if ($pass) { + carp "snmpMIB_to_OID: $arg: \"$strt\" prefix unknown, load the parent MIB first.\n" + unless ($SNMP_Session::suppress_warnings > 1); + } else { + $need2pass = 1; + } + } + $Link{$var} = $strt; + $val = "$SNMP_util::OIDS{$strt}.$val"; + if (!defined($prev{$var}) && defined($SNMP_util::OIDS{$var})) { + if ($val ne $SNMP_util::OIDS{$var}) { + $var = "$strt.$var"; + } + } + + $SNMP_util::OIDS{$var} = $val; + $prev{$var} = 1; + $cnt++; + + print "'$var' => '$val'\n" if $SNMP_util::Debug; + } + undef $buf; + } + } + if ($pass == 0 && $need2pass) { + seek(MIB, $pos, 0); + $buf = ""; + $pass = 1; + $cnt = 0; + } else { + $ret += $cnt; + $need2pass = 0; + } + } + close(MIB); + $RevNeeded = 1; + return $ret; +} + +sub encode_oid_with_errmsg ($) { + my ($oid) = @_; + my $tmp = encode_oid(split(/\./, $oid)); + if (! defined $tmp) { + carp "cannot encode Object ID $oid: $BER::errmsg" + unless ($SNMP_Session::suppress_warnings > 1); + return undef; + } + return $tmp; +} + +1; -- cgit v1.2.3-24-g4f1b