#!/usr/bin/perl
# Snmputils module
# managment snmp devices


use Nas;
use Snmputils;
use Socket;


use SNMP_Session;
use SNMP_util;
use BER;


use Carp;


require "Abills/nas.pl";

my $nas = Nas->new($db, \%conf);
my $Snmputils = Snmputils->new($db, $admin, \%conf);


my $debug=0;
$FORM{GET_USERS}=1;

          my @association_state = ('initial',
                         'authenNotAssociated',
                         'assocAndAuthenticated',
                         'assocNotAnuthenticated',
                         'authenticated');


my %loaded_mibs = ();

my %OIDS_HASH = 
  (
    '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',
  );


                                       

#*******************************************************************
# 
# 
#*******************************************************************
sub snmputils_monitor {



my %info = ();
my %func_hash = ('pm25'          => \&snmputils_portmaster,
                 'patton'        => \&snmputils_patton_dialin,
                 'cisco_air'     => \&snmputils_ciscoair,
                 'docsis_modems' => \&snmputils_docsis_modems,
                 'bsr1000'       => \&snmputils_docsis_modems,
                 'dlink_pb'      => \&snmputils_dlink_pb_monitor,
                 'mikrotik_info' => \&snmputils_mikrotik_info);


$info{NAS_TYPES} = $html->form_select('NAS_TYPE',                                           
                                     { 
                                       SELECTED    => $FORM{NAS_TYPE},
                                       SEL_HASH    => {'pm25'          => 'Portmaster 2/3',
 	                                       	             'patton'        => 'Patton RAS 29xx',
                                                       'cisco_air'     => 'Cisco Aironets',
                                                       'mikrotik'      => 'Mikrotik (not work yet)',
                                                       'bsr1000'       => 'BSR1000 Modems',
                                                       'docsis'        => 'Docsis modems',
                                                       'dlink_pb'      => 'D-Link port binding',
                                                       'mikrotik_info' => "Mikrotik $_INFO"
 	                                          	        },
                                       NO_ID   => 1
                                     });



my $table = $html->table( { width       => '100%',
                            title_plain => [ "$_TYPE: ".      $info{NAS_TYPES},
                                             "HOST: ".      $html->form_input('SNMP_HOST', "$FORM{SNMP_HOST}"),
                                             "COMMUNITY: ".   $html->form_input('SNMP_COMMUNITY', "$FORM{SNMP_COMMUNITY}"),
                                             "$_REFRESH (sec): ".   $html->form_input('REFRESH', int($FORM{REFRESH}), { SIZE => 4 } ),
                                             $html->form_input('SHOW',  $_SHOW, {TYPE => 'SUBMIT'})  
                                            ],
                           });

print $html->form_main({ CONTENT => $table->show(),
	                       HIDDEN  => { index =>  "$index" },
	                       METHOD  => 'GET'
                        });



if ($FORM{change}) {
  snmp_info_form();
}




if ($FORM{HOST}) {
#  $func_hash{$NAS_TYPE}->();
 }
elsif ($FORM{NAS_TYPE}) {
  $func_hash{$FORM{NAS_TYPE}}->();
 }

}


#**********************************************************
#
#**********************************************************
sub dlink_ip_mac_port {
	my ($attr) = @_;
	
	
}

sub hex2bin {
    my ($digit) = shift;
    print $no_revb
        ? unpack("B4", pack("H", $digit))
        : substr(unpack("b8", pack("H", $digit)), -4);
    print "$char";
}

#**********************************************************
# HOST, 
# COMMUNITY:
# IP/MAC
# 
#
#**********************************************************
sub snmputils_dlink_pb {
	my ($attr) = @_;
	
	my $debug = $attr->{DEBUG} || 0;
  my $debug_output = '';
  
#Get nas servers TYPE: dlink_pb
  my $list = $nas->list({ PAGE_ROWS => 100000, TYPE => dlink_pb, DISABLE => 0 });
  foreach my $line (@$list) {
    $debug_output .= "NAS: $line->[0], $line->[9], $line->[11] $line->[12]\n" if ($debug > 1);
    #GET users for this NAS
    my $list = $Snmputils->snmputils_nas_ipmac({ NAS_ID    => $line->[0], 
    	                                           PG        => 0, 
    	                                           PAGE_ROWS => 10000 });

    my $SNMP_COMMUNITY = "$line->[11]\@$line->[9]";

    if($Snmputils->{TOTAL} > 0) {
      
      $line->[12]=~/Assign-Ports=\"(.+)\"/;
      my $ports = $1 || '';
      my $SWICH_INFO = snmputils_dlink_pb_version({ SNMP_COMMUNITY => $SNMP_COMMUNITY });

      if (! $SWICH_INFO->{version}) {
      	 $debug_output .= "Unknow version\n" if ($debug > 1);
      	 next;
       }

      my($ACTIVE_MAC, $BLOCK_MAC) = snmputils_dlink_pb_list({ SNMP_COMMUNITY => $SNMP_COMMUNITY,
                                                              SWITCH_INFO    => $SWITCH_INFO,
	                                                          });

      my %SERVER_MAC = (); #Now active in server
      my %MUST_ACTIVATE = (); #Need to be active
      if ($ACTIVE_MAC->{MAC}) {
        # IP -> MAC
        %SERVER_MAC = %{ $ACTIVE_MAC->{MAC} };
       }

      foreach my $line (@$list) {
        my $user_ports='';
        if ($line->[5] =~ /pb=([0-9,]+)/) {
          $user_ports = $1;
     	   }

     	  $debug_output .= "$line->[0], UID: $line->[1] IP: $line->[2] MAC: $line->[3] PORT: $user_ports\n" if ($debug > 2);
        if ($line->[4] >= 0) {
          $MUST_ACTIVATE{$line->[3]}="$line->[2]:$user_ports";
         }
        else {
        	$debug_output .= " Negative deposit\n" if ($debug > 2);
         }
       }

      while(my($ip, $mac)=each %SERVER_MAC) {
     	    $debug_output .= "IP: $ip MAC: $mac" if ($debug > 0);
     	    if ($MUST_ACTIVATE{$mac}) {
     	       delete $MUST_ACTIVATE{$mac};
     	       delete $SERVER_MAC{$ip};
     	       $debug_output .= " Skip...\n" if ($debug > 0);
           }
          else {
       	    if ($debug < 3) {
       	      my $message = snmputils_dlink_pb_del({ SNMP_COMMUNITY => $SNMP_COMMUNITY,
            	                                       DEL            => $ip,
     	                                               SWITCH_INFO    => $SWITCH_INFO,
     	                                               MAC            => $mac,
     	                                               DEBUG          => $debug
     	                                          });

             }
          	$debug_output .= " Delete\n" if ($debug > 0);
           }
       }
      
      $debug_output .= "Add to server:\n" if ($debug > 0);
      while(my($mac, $ip_port)=each %MUST_ACTIVATE) {
     	    $debug_output .= "$ip_port, $mac\n" if ($debug > 0);
          my ($ip, $user_ports) = split(/:/, $ip_port, 2);
          
   	      if ($debug < 3) {
   	        my $message = snmputils_dlink_pb_add({  
        	    SNMP_COMMUNITY => $SNMP_COMMUNITY,
         	    IP             => $ip,
              PORT_ID        => ($user_ports ne '') ? $user_ports : $ports,
              MAC            => $mac,
        	    SWITCH_INFO    => $SWITCH_INFO,
        	    ACL_IP_MAC     => 1
         	   });
            $debug_output .= "! $message\n";
           }
       }
     #Active ports
     
     my @ports_arr = split(/,/, $ports);
     $debug_output .= "Active port: ";
     foreach my $port (@ports_arr) {
       
       if ($debug < 3) {
         my $message =  snmputils_dlink_pb_state({ SNMP_COMMUNITY => $SNMP_COMMUNITY,
     	                                             STATE          => 2,
     	                                             PORT           => $port,
     	                                             SWITCH_INFO    => $SWITCH_INFO,
     	                                             DEBUG          => $debug
     	                                          });
        }
       $debug_output .= "$port," if ($debug > 1);
      }
    $debug_output .= "\n";
    }
   }

  $DEBUG = $debug_output;
  return $debug_output;
}


#**********************************************************
#
#**********************************************************
sub snmputils_dlink_pb_version {
	my ($attr)=@_;

  my $SNMP_COMMUNITY = $attr->{SNMP_COMMUNITY} || '';
  my %RESULT = ();
  
  $RESULT{version}='';
  $RESULT{SNMP_COMMUNITY}=$SNMP_COMMUNITY; 
  $RESULT{oid_prefix} = '.1.3.6.1.4.1.171.11.64.1.2.7.';
  $RESULT{oid_sufix} =  {'IP'     => '2.1.1',
                   'MAC'    => '2.1.2',
                   'PORT'   => '2.1.4',
                   'ACTIVE' => '2.1.5',
                   'MODE'   => '2.1.6',
                   'STATE'  => '1.1.2',
                   'MAKE'   => '2.1.3'
                  };
  
  if($RESULT{version} = snmpget($SNMP_COMMUNITY, ".1.3.6.1.2.1.1.1.0")) {
    # For 3526
    #.1.3.6.1.2.1.16.19.2.0 = "Build 4.01-B19"
    #.1.3.6.1.4.1.171.12.11.1.9.4.1.8.1 = "4.01-B19"
    
    if ($RESULT{version} =~ /DES-3550/ ) {
      $RESULT{oid_prefix} = '.1.3.6.1.4.1.171.11.64.2.2.7.';
      $RESULT{firmware}  = snmpget($SNMP_COMMUNITY, ".1.3.6.1.2.1.16.19.2.0");
      $RESULT{firmware2}  = snmpget($SNMP_COMMUNITY, ".1.3.6.1.4.1.171.12.11.1.9.4.1.8.1");
     }
    elsif ($RESULT{version} =~ /DES-3828/) {
  	  $RESULT{oid_prefix} = '.1.3.6.1.4.1.171.11.69.1.2.7.';
     }
    elsif ($RESULT{version} =~ /DES-3828DC/) {
  	  $RESULT{oid_prefix} = '.1.3.6.1.4.1.171.11.69.2.2.7.';
     }
    elsif ($RESULT{version} =~ /DES-3828P/) {
  	  $RESULT{oid_prefix} = '.1.3.6.1.4.1.171.11.69.3.2.7.';
     }
    elsif ($RESULT{version} =~ /DES-3852/) {
  	  $RESULT{oid_prefix} = '.1.3.6.1.4.1.171.11.69.4.2.7.';
     }
    elsif ($RESULT{version} =~ /DES-30/) {
  	  $RESULT{oid_prefix} = '.1.3.6.1.4.1.171.12.23.';
  	  $RESULT{oid_sufix} = {'STATE'  => '3.2.1.2',
  	                'IP'     => '4.1.1.1',
                    'MAC'    => '4.1.1.2',
                    'MAKE'   => '4.1.1.3',
                    'PORT'   => '4.1.1.4' };
     }
    else {
 	    $RESULT{firmware}  = snmpget($SNMP_COMMUNITY, ".1.3.6.1.2.1.16.19.2.0");
      $RESULT{firmware2}  = snmpget($SNMP_COMMUNITY, ".1.3.6.1.4.1.171.12.11.1.9.4.1.8.1");
     }
   }
  else {
  	print "$SNMP_Session::suppress_warnings / $SNMP_Session::errmsg";
  	return 0;
   }
 
  #Get ports state
  my @result_ports = &snmpwalk("$SNMP_COMMUNITY", $RESULT{oid_prefix} . "$RESULT{oid_sufix}{STATE}" );
  $RESULT{PORT_STATE}=\@result_ports;


  return \%RESULT;
}

#**********************************************************
#
#**********************************************************
sub snmputils_dlink_pb_add {
	my ($attr)=@_;
	my $message='';

  my $SNMP_COMMUNITY = $attr->{SNMP_COMMUNITY} || '';

	my $sw_info = $attr->{SWITCH_INFO} || snmputils_dlink_pb_version({ SNMP_COMMUNITY => $SNMP_COMMUNITY });

	my $ip   = $attr->{IP}   || '0.0.0.0';
  my $port = $attr->{PORT} || 0;
  my $port_list = $attr->{PORT_ID} || '';
  my $mac  = $attr->{MAC}  || 0;
	
	
	my $oid_prefix = $sw_info->{oid_prefix};
	my %oid_sufix = %{ $sw_info->{oid_sufix} } ;
	
	#Шаг 1. Задать IP-адрес связки:
	my $oid = $oid_prefix.$oid_sufix{MAKE}.".$ip";
  $message .= "$oid => 4\n";
  if(snmpset($SNMP_COMMUNITY, $oid, "integer", "4")) {
   	$message .= " Ok\n";
   }

  #Шаг 3. Задать MAC-адрес (AA-BB-CC-DD-EE-FF) связки:
  my @mac_arr = split(/:|-/, $mac);
  $mac = '';
  foreach my $c (@mac_arr) {
    $mac .= chr(hex($c));
   }

  $message .= $oid_prefix.$oid_sufix{MAC}.".$ip => $mac\n";
  if(snmpset($SNMP_COMMUNITY, $oid_prefix.$oid_sufix{MAC}.".$ip", "string", "$mac")) {
    $message .= "Ok\n";
   }
  else {
    print "$SNMP_Session::suppress_warnings / $SNMP_Session::errmsg";	
   }

  #Шаг 2. Назначить эту связку на порт 1:
  #Convert to D-Link port value
  #   my $first_port = 0b10000000000000000000000000000000;
  #     my $port_binding = ($port > 1) ? $first_port >> $port - 1 : $first_port;
  #     
  #     my @ar =  unpack("A2A2A2A2", sprintf("%.8x",  $port_binding));
  #
  #     printf("\n%.32b\n",  $port_binding);
  print $port_list;
  my $port_count = $#{ $sw_info->{PORT_STATE} };

  $port_list=~s/ //g;

	my @get_arr = split(/,/, $port_list);
  my @port_array = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  print "$port_count<br>";
  $port_count=30;
  foreach my $id (@get_arr) {
   	if ($sw_info->{version} =~ /DES-30/) {
   	  $port_array[$port_count+2-$id]=1;
   	 }
   	else {
   	  $port_array[$id-1]=1;
   	 }
   }
#  for(my $i=0; $i<=$port_count; $i++) {
#  	$port_array[$i]=(in_array(($i+1), \@get_arr)) ? 1 : 0;
#   }
  print join("", @port_array);
  my @ar = unpack("H2H2H2H2", pack("B32", join("", @port_array)));

  my $port_binding = '';
  foreach my $c (@ar) {
    print "$c:";
    $port_binding .= chr(hex($c));
   }
     
  $message .= $oid_prefix.$oid_sufix{PORT}.".$ip => '$port_binding'\n";
  if(snmpset($SNMP_COMMUNITY, $oid_prefix.$oid_sufix{PORT}.".$ip", "string", "$port_binding")) {
  	$message .= "Ok\n";
   }
  else {
    print "$oid_prefix / $oid_sufix{PORT} / $ip => $port_binding\n";
    print "$SNMP_Session::suppress_warnings / $SNMP_Session::errmsg";	
   }


  #Шаг 4. Задать режим связки IP MAC Port Binding (ARP / ACL):
  my $mode = ($attr->{ACL_IP_MAC}) ? 1 : 0;
  $message .= $oid_prefix.$oid_sufix.".$ip => $mode\n";
  if(snmpset($SNMP_COMMUNITY, $oid_prefix.$oid_sufix{MODE}.".$ip", "integer", $mode)) {
    $message .= "Ok\n";
   }

  #Шаг 5. Включить IP-MAC-Port Binding на этом порту:
  $message .= $oid_prefix.$oid_sufix{STATE}.".$port => 2\n";
  if(snmpset($SNMP_COMMUNITY, $oid_prefix.$oid_sufix{STATE}.".$port", "integer", "2")) {
    $message .= "Ok\n";
   }

  if($sw_info->{version} =~ /DES-30/) {
  	print "=> $oid\n";
  	if(snmpset($SNMP_COMMUNITY, $oid, "integer", "4")) {
   	  $message .= " Ok\n";
     }
   }




  return $message;	
}

#**********************************************************
#
#**********************************************************
sub snmputils_dlink_pb_state {
	my ($attr)=@_;

	my $message='';
  my $SNMP_COMMUNITY = $attr->{SNMP_COMMUNITY} || '';
	my $sw_info = $attr->{SWITCH_INFO} || snmputils_dlink_pb_version({ SNMP_COMMUNITY => $SNMP_COMMUNITY });

  #Шаг 5. Включить IP-MAC-Port Binding на этом порту:
  $message .= $sw_info->{oid_prefix}.$sw_info->{oid_sufix}{STATE}.".$attr->{PORT} => $attr->{STATE}\n";
  if(snmpset($SNMP_COMMUNITY, $sw_info->{oid_prefix}.$sw_info->{oid_sufix}{STATE}.".$attr->{PORT}", "integer", "$attr->{STATE}")) {
 	  $message .= "Ok\n";
   }
  else {
    $message .="$SNMP_Session::suppress_warnings / $SNMP_Session::errmsg";
   }
  
  return $message;
}


#**********************************************************
#
#**********************************************************
sub snmputils_dlink_pb_del {
	my ($attr)=@_;
  
  my $message = '';
  my $SNMP_COMMUNITY = $attr->{SNMP_COMMUNITY} || '';
	my $sw_info = $attr->{SWITCH_INFO} || snmputils_dlink_pb_version({ SNMP_COMMUNITY => $SNMP_COMMUNITY });

	my $oid_prefix = $sw_info->{oid_prefix};
	my %oid_sufix = %{ $sw_info->{oid_sufix} } ;

	if ($attr->{DEL} eq 'block') {
    if(snmpset($SNMP_COMMUNITY, $oid_prefix. "1.$attr->{MAC}", "integer", "3")) {
   	  $message = "$_DELETED $FORM{MAC}";
     }
   }
  #delete from binding list
  elsif(snmpset($SNMP_COMMUNITY, $oid_prefix.$oid_sufix{MAKE}.".$attr->{DEL}", "integer", "6")) {
  	 $message = "$_DELETED $attr->{DEL}";
   }

  if($SNMP_Session::suppress_warnings) { 
  	$message =	"$SNMP_Session::suppress_warnings / $SNMP_Session::errmsg"; 
   };

  return $message;
}

#**********************************************************
#
#**********************************************************
sub snmputils_dlink_pb_change {


}

#**********************************************************
#
#**********************************************************
sub snmputils_dlink_pb_list {
	my ($attr)=@_;
	
	my $debug = $attr->{DEBUG} || 0;

  my $SNMP_COMMUNITY = $attr->{SNMP_COMMUNITY} || '';
	my $SWITCH_INFO = $attr->{SWITCH_INFO} || snmputils_dlink_pb_version({ SNMP_COMMUNITY => $SNMP_COMMUNITY });
	
	
  my %PREFIX  = ( 1 => 'IP',
                  2 => 'MAC',
                  4 => 'PORT',
                  5 => 'ACTIVE',
                  6 => 'MODE');

	my %info = ();
  my %BLOCK_HASH = ();
  if ( ! $SWITCH_INFO->{oid_prefix}) {
  	print "No swich info '$attr->{SNMP_COMMUNITY}'\n";
  	return 0;
   }
  #Full list
  my @result = &snmpwalk("$SNMP_COMMUNITY", $SWITCH_INFO->{oid_prefix});
  print $SWITCH_INFO->{oid_prefix}." / $SWITCH_INFO->{oid_sufix}{STATE}" if ($debug > 0);
  my $expr_val = chr(0)."-".chr(255);                                            
  foreach my $line (@result) {
    print "$line<br>\n" if ($debug > 0);
    #Blocked address
    if($line =~ /^[\d\.]{0,2}\d\.\d\.(\d)\.\d\.(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(.+)/ ) {
    	$BLOCK_HASH{$2}{$1}=$3;
    	print "Block<br>" if ($debug > 0);
     }
    #Binding Address
    elsif($line =~ /^[\d\.]{0,2}\d\.\d\.(\d)\.(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}):([$expr_val]+)/g) {
      print "=> $1 / $2 / $3 <br>\n" if ($debug > 0);
      #Port
  	  if ($1 == 4) {
  	    my $port = $3;
        my $ip = $2;
        my $string = unpack("B32",  $port);
        if ($debug > 0) {
       	  my $hex_val = join(':', unpack("H2H2H2H2", pack("B32", $string)));
       	  print "IP: $ip PORT: $hex_val ($string)<BR>\n";
         }

        my $multi_ports = '';
        #my $count=0;
        while ( $string =~ m/1/g ) {
   	      if ($SWITCH_INFO->{version} =~ /DES-30/) {
            $port = 33 - pos($string);
           }
          else {
            $port = pos($string);
           }

          $multi_ports .= ",$port";
    	  	push @{ $info{PORT}{$port} },  $ip;
    	  	#$count++;
         }

        $info{MULTIPORTS}{$2}="$multi_ports"; #if ($count>1);
  	   }
  	  elsif ($1 == 2) {
  	  	if ($debug > 0) {
  	  		 print "IP: $2 MAC: $3<br>\n";
  	  	 }
  	  	$info{MAC}{$2}=join(':', unpack("H2H2H2H2H2H2", $3));
  	   }
  	  elsif ($PREFIX{$1}) {
  		  $info{$PREFIX{$1}}{$2}=$3;
  	   }
    }
   }
	
	
	return \%info, \%BLOCK_HASH;
}


#**********************************************************
# http://www.dlink.ru/technical/faq_hub_switch_100.php
# Примеры настройки функции IP-MAC-Port Binding по SNMP для серий DES-38XX и DES-35XX 
#**********************************************************
sub snmputils_dlink_ip_mac_port{
  my ($attr) = @_;
  
  my $debug = $FORM{DEBUG} || 0;
  my $SNMP_COMMUNITY = $attr->{SNMP_COMMUNITY} || '';
  my $message = '';
  
  if ($FORM{TEST}) {
    print "<pre>";
    print  snmputils_dlink_pb({ DEBUG => $FORM{DEBUG} });
    print "</pre>";
    return 0;
   }

  my $SWITCH_INFO = snmputils_dlink_pb_version({ SNMP_COMMUNITY => $SNMP_COMMUNITY });

  my $oid_prefix=$SWITCH_INFO->{oid_prefix};
  my %MAIN_OPTIONS = (enable_mode  => $oid_prefix.'4.0',  # enable_mode
                      loging_mode  => $oid_prefix.'5.0',  # Loging
                      acl_ip_mac   => $oid_prefix.'6.0'   # ACL IP MAC 
                      );

  print "$SWITCH_INFO->{version}/$SWITCH_INFO->{firmware}/$SWITCH_INFO->{firmware2}";
  if ($FORM{add}) {
     my $message = snmputils_dlink_pb_add({  
     	    SNMP_COMMUNITY => $SNMP_COMMUNITY,
     	    IP             => $FORM{IP},
          PORT_ID        => $FORM{PORT_ID},
          MAC            => $FORM{MAC},
     	    SWITCH_INFO    => $SWITCH_INFO,
     	    ACL_IP_MAC     => $FORM{ACL_IP_MAC},
     	    DEBUG          => $FORM{DEBUG}
     	});
     print $html->message('info', $_INFO, "$message");
   }
  elsif($FORM{state}) {
     my $message =  snmputils_dlink_pb_state({ SNMP_COMMUNITY => $SNMP_COMMUNITY,
     	                                         STATE          => $FORM{state},
     	                                         PORT           => $FORM{PORT},
     	                                         SWITCH_INFO    => $SWITCH_INFO,
     	                                         DEBUG          => $FORM{DEBUG}
     	                                       });
     $SWITCH_INFO = snmputils_dlink_pb_version({ SNMP_COMMUNITY => $SNMP_COMMUNITY });
     print $html->message('info', $_INFO, "$message");
   }
  elsif ($FORM{MAIN_CONF}) {
  	
    if(snmpset($SNMP_COMMUNITY, "$MAIN_OPTIONS{$FORM{MAIN_CONF}}", "integer", "$FORM{key}")) {
   	  $message .= "Ok\n";
     }

    print $html->message('info', $_INFO, "$FORM{MAIN_CONF} $MAIN_OPTIONS{$FORM{MAIN_CONF}} $message");
   }
  elsif ($FORM{del}) {
    my $message = snmputils_dlink_pb_del({ SNMP_COMMUNITY => $SNMP_COMMUNITY,
     	                                     DEL            => $FORM{del},
     	                                     SWITCH_INFO    => $SWITCH_INFO,
     	                                     MAC            => $FORM{MAC},
     	                                     DEBUG          => $FORM{DEBUG}
     	                                   });
 
    print $html->message('info', $_DELETED, "$message");
   }
  
  


  #Port binding enable mode
  my %THREE_MODE = (1 => $_OTHER,
                    2 => $_ENABLE,
                    3 => $_DISABLE );
                    
  my $MAIN_VALUE = ();
  my $table = $html->table({ width       => '100%',
                             border      => 1,
                             cols_align  => ['left', 'center'],
                           });

  while(my($key, $value)= each %MAIN_OPTIONS) {
    $MAIN_VALUE{$key} = snmpget("$SNMP_COMMUNITY", "$value") || 0;
    if (! $MAIN_VALUE{$key}) {
  	  $html->message("info", $_INFO, "'$key':$value  _NOT_SUPPORT");
     }
    else {
      $table->addrow($key, 
        $THREE_MODE{int($MAIN_VALUE{$key})}, 
        $html->button(($MAIN_VALUE{$key} != 2) ? $_ENABLE : $_DISABLE, 
          "index=$index&NAS_ID=$FORM{NAS_ID}&TYPE=$FORM{TYPE}&SHOW=1&MAIN_CONF=$key&key=". (($MAIN_VALUE{$key} != 2) ? 2 : 3) )
       );
     }
  }
  
  print $table->show();


#Port section  
  $table = $html->table({ width       => '100%',
                          caption     => "IP-MAC-Port Binding",
                          border      => 1,
                          title       => ["$_USER", "$_PORT", "$_STATE", "IP", "MAC", "$_STATUS", "_MODE", "-", "-"],
                          cols_align  => ['left', 'left', 'center', 'right', 'right', 'right', 'right', 'center', 'center', 'center'],
                      });



  
  my @ports = ();
  my %MODES = (0 => 'ARP', 1 => 'ACL' );
  
  my($ACTIVE_MAC, $BLOCK_MAC) = snmputils_dlink_pb_list({ SNMP_COMMUNITY => $SNMP_COMMUNITY,
                                                          SWITCH_INFO    => $SWITCH_INFO,
                                                          DEBUG          => $FORM{DEBUG}
	                                                      });


  foreach my $line (@{ $SWITCH_INFO->{PORT_STATE} }) {
  	my ($port, $state) = split(/:/, $line, 2);
  	#my @ip_arr = @{ $info{PORT}{$port} };
  	#@ip_arr = () if ()
  	#my $ips_count  = $#ip_arr;
    push @ports, $port;
  	
    $table->addtd(
             $table->td('-'),
             $table->td($port,    { rowspan => 1 } ),
             $table->td($THREE_MODE{$state}, { bgcolor => ($state == 2) ? '#00FF00' : $_COLORS[1], rowspan => 1  }), 
             $table->td(''),
             $table->td(''),
             $table->td(''),
             $table->td(''),
             $table->td($html->button(($state == 2) ? $THREE_MODE{3} : $THREE_MODE{2}, "NAS_ID=$FORM{NAS_ID}&TYPE=$FORM{TYPE}&SHOW=1&index=$index&PORT=$port&state=". (($state == 2) ? 3 : 2) )),
             $table->td('-')
             #$table->td($html->button($_DEL, "index=$index&del=$ip_arr[0]&NAS_ID=$FORM{NAS_ID}&TYPE=$FORM{TYPE}&SHOW=1"))
      );
   }

#My multiports  section
  my $binding;

  if ($FORM{GET_USERS}) {
    my $IDS = '';
    while(my($ip, $mac) = each %{ $ACTIVE_MAC->{MAC} } ) {
     	$IDS .= "'$mac',";    	
     }

    while(my($mac_dec, $value) = each %$BLOCK_MAC ) {
   	  my $mac = join(':', unpack("H2H2H2H2H2H2", $BLOCK_MAC->{$mac_dec}{2}));
   	  $IDS .= "'$mac',";
     }

   	chop($IDS);
    $binding = snmputils_get_users({ IDS => "$IDS" });
   }


  $table->td($port,    { colspan => 9, bgcolor => $_COLORS[0] } );

  while(my($ip, $ports) = each %{ $ACTIVE_MAC->{MULTIPORTS} } ) {
    my @arr = (
             
             $table->td($ports,    { colspan => 2 } ),
             $table->td($ip),
             $table->td($ACTIVE_MAC->{MAC}{"$ip"}),
             $table->td( $THREE_MODE{$ACTIVE_MAC->{ACTIVE}{"$ip"}} ),
             $table->td( $MODES{$ACTIVE_MAC->{MODE}{"$ip"}} ),
             $table->td($html->button(($state == 2) ? $THREE_MODE{3} : $THREE_MODE{2}, "NAS_ID=$FORM{NAS_ID}&TYPE=$FORM{TYPE}&SHOW=1&index=$index&PORT=$port&state=". (($state == 2) ? 3 : 2) )),
             $table->td($html->button($_DEL, "index=$index&del=$ip&NAS_ID=$FORM{NAS_ID}&TYPE=$FORM{TYPE}&SHOW=1"))
      );
     
    if($binding->{$ACTIVE_MAC->{MAC}{"$ip"}}) {
 		  my ($name, $uid) = split(/:/, $binding->{$ACTIVE_MAC->{MAC}{"$ip"}});
    	unshift @arr, $table->td($html->button("$name", "index=15&UID=$uid"));
     }
    else {
    	unshift @arr, $table->td('-');
     }	
    
    $table->addtd(@arr);
   }
 
  print $table->show();


  $Snmputils->{PORT_SEL}=$table = $html->table({ width       => '100%',
                                                 cols_align  => ['right', 'right', 'right', 'right', 'right', 'right', 'right' ]
                                               });
  my @arr=();
  foreach my $port (@ports) {
    push @arr, " $port".$html->form_input('PORT_ID', "$port", {TYPE => 'checkbox' });	
    if ($#arr !=0 && $#arr % 7 == 0) {
       $table->addrow(@arr);
       @arr=();
     }
   }
  $table->addrow(@arr) if ($#arr > -1);
  $Snmputils->{PORT_SEL}=$table->show(); 
 
  $html->tpl_show(_include('snmputils_ip_mac_port', 'Snmputils'), { %$Snmputils, %FORM }); 
 
 
 
  $table = $html->table({ width       => '100%',
                          caption     => "$_DISABLED",
                          border      => 1,
                          title       => ["$_USER", "ID", "$_PORT", "MAC", "VID", "-"],
                          cols_align  => ['left', 'left', 'center', 'right', 'right', 'right', 'right', 'center', 'center', 'center'],
                      });
 
  
  
  while(my($key, $val) = each %$BLOCK_MAC) {
    my $mac = join(':', unpack("H2H2H2H2H2H2", $BLOCK_MAC->{$key}{2}));
    my @arr = ('-',
               $BLOCK_MAC->{$key}{1}, 
  	           $BLOCK_MAC->{$key}{4},
  	           $mac,
  	           $BLOCK_MAC->{$key}{3},
  	           $BLOCK_MAC->{$key}{5},
  	           $html->button($_DEL, "index=$index&del=block&MAC=$key&NAS_ID=$FORM{NAS_ID}&TYPE=$FORM{TYPE}&SHOW=1")
  	          );

     if($binding->{$mac}) {
 		  my ($name, $uid) = split(/:/, $binding->{$mac});
    	$arr[0] = $html->button("$name", "index=15&UID=$uid");
     }

  	$table->addrow(@arr);
   }
 print $table->show(); 
  
}

#*******************************************************************
# 
# 
#*******************************************************************
sub snmputils_dlink_pb_monitor {
  my ($attr) = @_;
  
  my $debug = $attr->{DEBUG} || 0;

  my $table = $html->table({ width       => '100%',
                             caption     => "$_DISABLED",
                             border      => 1,
                             title       => ["$_USER", "ID", "$_PORT", "MAC", "VID", "-"],
                             cols_align  => ['left', 'left', 'center', 'right', 'right', 'right', 'right', 'center', 'center', 'center'],
                           });

  my $list = $nas->list({ PAGE_ROWS => 10000, 
  	                      SORT      => 2, 
  	                      TYPE      => dlink_pb, 
  	                      DISABLE   => 0 
  	                    });


  foreach my $line (@$list) {
    $debug_output .= "NAS: $line->[0], $line->[9], $line->[11] $line->[12]\n" if ($debug > 1);
    #GET users for this NAS
    
    $table->{rowcolor}=$_COLORS[0];
    $table->{extra}="colspan='5' class='small'";
    $table->addrow("$line->[0]:<b>$line->[1]</b>:$line->[3] " );

    undef($table->{rowcolor});
    undef($table->{extra});

    
    my $SNMP_COMMUNITY = "$line->[11]\@$line->[9]";
    my $SWICH_INFO = snmputils_dlink_pb_version({ SNMP_COMMUNITY => $SNMP_COMMUNITY });

    my($ACTIVE_MAC, $BLOCK_MAC) = snmputils_dlink_pb_list({ SNMP_COMMUNITY => $SNMP_COMMUNITY,
                                                            SWITCH_INFO    => $SWITCH_INFO,
	                                                          });
 
    my $binding;
    if ($FORM{GET_USERS}) {
      my $IDS = '';
      while(my($mac_dec, $value) = each %$BLOCK_MAC ) {
     	  my $mac = join(':', unpack("H2H2H2H2H2H2", $BLOCK_MAC->{$mac_dec}{2}));
     	  $IDS .= "'$mac',";
       }
   	  chop($IDS);
      $binding = snmputils_get_users({ IDS => "$IDS" });
     }

 
    
    
    while(my($key, $val) = each %$BLOCK_MAC) {
  	  my $mac = join(':', unpack("H2H2H2H2H2H2", $BLOCK_MAC->{$key}{2}));
  	  my @arr = ('-',
  	             $BLOCK_MAC->{$key}{1}, 
  	             $BLOCK_MAC->{$key}{4},
  	             $mac,
  	             $BLOCK_MAC->{$key}{3},
  	             $BLOCK_MAC->{$key}{5},
  	             $html->button($_DEL, "index=$index&del=block&MAC=$key&NAS_ID=$FORM{NAS_ID}&TYPE=$FORM{TYPE}&SHOW=1")
  	            );
     
      if($binding->{$mac}) {
  		  my ($name, $uid) = split(/:/, $binding->{$mac});
   		  $arr[0] = $html->button("$name", "index=15&UID=$uid");  
       }

  	  $table->addrow(@arr);
     }
  }





 print $table->show(); 

	



}

#*******************************************************************
# 
# 
#*******************************************************************
sub snmputils_ciscoair {

my $Nas = Nas->new($db, \%conf);
my $list = $Nas->list({ TYPE => 'cisco_air', DISABLE => 0 });

my %fields = ( 
                #Info
                cDot11ClientAddress           => '.1.3.6.1.4.1.9.9.273.1.2.1.1.1',
                cDot11ClientParentAddress     => '.1.3.6.1.4.1.9.9.273.1.2.1.1.2',
                cDot11ClientRoleClassType     => '.1.3.6.1.4.1.9.9.273.1.2.1.1.3',
                cDot11ClientDevType           => '.1.3.6.1.4.1.9.9.273.1.2.1.1.4',
                cDot11ClientRadioType         => '.1.3.6.1.4.1.9.9.273.1.2.1.1.5',
                cDot11ClientWepEnabled        => '.1.3.6.1.4.1.9.9.273.1.2.1.1.6',
                cDot11ClientWepKeyMixEnabled  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.7',
                cDot11ClientMicEnabled        => '.1.3.6.1.4.1.9.9.273.1.2.1.1.8',
                cDot11ClientPowerSaveMode     => '.1.3.6.1.4.1.9.9.273.1.2.1.1.9',
                cDot11ClientAid               => '.1.3.6.1.4.1.9.9.273.1.2.1.1.10',
                cDot11ClientDataRateSet       => '.1.3.6.1.4.1.9.9.273.1.2.1.1.11',
                cDot11ClientSoftwareVersion   => '.1.3.6.1.4.1.9.9.273.1.2.1.1.12',
                cDot11ClientName              => '.1.3.6.1.4.1.9.9.273.1.2.1.1.13',
                cDot11ClientAssociationState  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.14',
                cDot11ClientIpAddressType     => '.1.3.6.1.4.1.9.9.273.1.2.1.1.15',
                cDot11ClientIpAddress         => '.1.3.6.1.4.1.9.9.273.1.2.1.1.16',
                cDot11ClientVlanId            => '.1.3.6.1.4.1.9.9.273.1.2.1.1.17',
                cDot11ClientSubIfIndex        => '.1.3.6.1.4.1.9.9.273.1.2.1.1.18',
#                cDot11ClientAuthenAlgorithm   => '.1.3.6.1.4.1.9.9.273.1.2.1.1.19',
                cDot11ClientAdditionalAuthen  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.2.20',
                cDot11ClientDot1xAuthenAlgorithm => '.1.3.6.1.4.1.9.9.273.1.2.1.1.2.21',
                cDot11ClientKeyManagement     => '.1.3.6.1.4.1.9.9.273.1.2.1.1.2.22',
                cDot11ClientUnicastCipher     => '.1.3.6.1.4.1.9.9.273.1.2.1.1.2.23',
                cDot11ClientMulticastCipher   => '.1.3.6.1.4.1.9.9.273.1.2.1.1.2.24',

                #Stats
                cDot11ClientCurrentTxRateSet  => '.1.3.6.1.4.1.9.9.273.1.3.1.1.1',
                cDot11ClientUpTime            => '.1.3.6.1.4.1.9.9.273.1.3.1.1.2',
                cDot11ClientSignalStrength    => '.1.3.6.1.4.1.9.9.273.1.3.1.1.3',
                cDot11ClientSigQuality        => '.1.3.6.1.4.1.9.9.273.1.3.1.1.4',
                cDot11ClientAgingLeft         => '.1.3.6.1.4.1.9.9.273.1.3.1.1.5',
                cDot11ClientPacketsReceived   => '.1.3.6.1.4.1.9.9.273.1.3.1.1.6',
                cDot11ClientBytesReceived     => '.1.3.6.1.4.1.9.9.273.1.3.1.1.7',
                cDot11ClientPacketsSent       => '.1.3.6.1.4.1.9.9.273.1.3.1.1.8',
                cDot11ClientBytesSent         => '.1.3.6.1.4.1.9.9.273.1.3.1.1.9',
                cDot11ClientDuplicates        => '.1.3.6.1.4.1.9.9.273.1.3.1.1.10',
                cDot11ClientMsduRetries       => '.1.3.6.1.4.1.9.9.273.1.3.1.1.11',
                cDot11ClientMsduFails         => '.1.3.6.1.4.1.9.9.273.1.3.1.1.12',
                cDot11ClientWepErrors         => '.1.3.6.1.4.1.9.9.273.1.3.1.1.13',
                cDot11ClientMicErrors         => '.1.3.6.1.4.1.9.9.273.1.3.1.1.14',
                cDot11ClientMicMissingFrames  => '.1.3.6.1.4.1.9.9.273.1.3.1.1.15',


              'ClientConfigInfoEntry'  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.17',
              'ClientConfigInfoEntry2' => '.1.3.6.1.4.1.9.9.273.1.2.1.1.18',
              'ClientConfigInfoEntry3' => '.1.3.6.1.4.1.9.9.273.1.2.1.1.19',
              'ClientConfigInfoEntry4'  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.20',
              'ClientConfigInfoEntry5'  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.21',
              'ClientConfigInfoEntry6'  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.22',
              'ClientConfigInfoEntry7'  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.23',
              'ClientConfigInfoEntry8'  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.24',
              'ClientConfigInfoEntry9'  => '.1.3.6.1.4.1.9.9.273.1.2.1.1.25',

#              'MAC                    => '.1.3.6.1.2.1.17.4.3.1.1.'
              );

if ($FORM{Client}) {
	my %info = ();
  my $list = $Snmputils->snmputils_binding_list({ BINDING => $FORM{MAC}, PAGE_ROWS => 10000 }); 
  #cisco_air:00:11:95:e9:3b:2e
  if ($Snmputils->{TOTAL} > 0) {
	  $info{LOGIN} = $html->button("$list->[0]->[0]", "index=11&UID=$list->[0]->[5]");
	 }
  else {
	  $info{LOGIN} = "Check binding";
	 }
  
  $Nas->info({ NAS_ID => $FORM{NAS_ID} });
  foreach my $key (keys %fields) {
	 	$info{$key} = snmpget("$Nas->{NAS_MNG_PASSWORD}\@$Nas->{NAS_IP}", $fields{$key}. '.1.7.119.108.97.110.119.101.112.'. $FORM{Client});
	
	  if ($debug  > 0) {
	 	  print "$key: $fields{$key}.1.7.119.108.97.110.119.101.112.$FORM{Client} = $info{$key}<br>";
      if ($SNMP_Session::errmsg) {
        print "$SNMP_Session::errmsg<br>";
      }	 	
    }	 	

	 	$info{$key} = data_convert($key, $info{$key});
	 }
  $info{MAC}=$FORM{MAC};
	$html->tpl_show(_include('snmputils_cisco_air_client_info', 'Snmputils'), \%info);
	return 0;
}


my @default_fields = ('cDot11ClientName',
                'cDot11ClientDevType',
                'cDot11ClientIpAddress',
                'cDot11ClientAssociationState',
                'cDot11ClientSigQuality', 
                'cDot11ClientSignalStrength',
                'cDot11ClientUpTime', 
                'cDot11ClientDuplicates'
                     );


if ($FORM{fields}) {
  @default_fields = split(/, /, $FORM{fields});
}

my @CAPTION = ('MAC', @default_fields, '-');

my $binding; 
if ($FORM{GET_USERS}) {
  unshift @CAPTION, $_USERS;
}

$table = $html->table({ width       => '100%',
                        caption     => "CISCO Aironets",
                        border      => 1,
                        title       => \@CAPTION,
                        cols_align  => ['left', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'center'],
                      });

my $total_sessions = 0;
my $oid_prefix = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';

foreach my $line (@$list) {
  my %result = ();

  foreach my $field (@default_fields) {
    my @arr = snmpwalk("$line->[11]\@$line->[3]", $fields{$field});
    
    print "<b>$fields{$field}</b><br>" if ($debug == 1);
    
    foreach my $line (@arr) {
      if ('.'.$line =~ /^$oid_prefix\.(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(.+)/) {
        $result{$field}{$1}=$2;
        print "$field // $line<br> // $1 / $2 <br>" if ($debug == 1);
       }
     }
   }

  my @MAC_ARR = keys %{ $result{ $default_fields[0] } } ;
 
  if ($FORM{GET_USERS}) { 
    my $IDS = '';
    foreach my $mac (@MAC_ARR) {
      my @mac_arr = split(/\./, $mac);
      for(my $i=0; $i<=$#mac_arr; $i++) {
     	  $mac_arr[$i] = sprintf("%.2X", $mac_arr[$i]);
       }
      my $mac = join(':', @mac_arr);
     	$IDS .= "'$mac',";    	
     }
   	chop($IDS);
    $binding = snmputils_get_users({ IDS => "$IDS" });
   }

  $table->{rowcolor}=$_COLORS[0];
  $table->{extra}="colspan='". ($#CAPTION + 2) ."' class='small'";
  $table->addrow("$line->[0]:<b>$line->[1]</b>:$line->[3] (". 
  $html->button('WEB', "", { GLOBAL_URL => "http://$line->[3]" }) 
   ."):$_TOTAL: ". ( $#MAC_ARR + 1 ) );

  $total_sessions += $#MAC_ARR + 1;

  undef($table->{rowcolor});
  undef($table->{extra});

    foreach my $k ( @MAC_ARR ) {
      my @mac_arr = split(/\./, $k);
      for(my $i=0; $i<=$#mac_arr; $i++) {
     	  $mac_arr[$i] = sprintf("%.2X", $mac_arr[$i]);
      }
      my $mac = join(':', @mac_arr);

      my @arr = ();
      foreach my $ft (@default_fields) {
        
        $result{$ft}{$k} = data_convert($ft, $result{$ft}{$k});
      	push @arr, $result{$ft}{$k};
       }


     	unshift @arr, $html->button("<CODE>$mac</CODE>", "index=$index&NAS_TYPE=cisco_air&Client=$k&MAC=$mac&NAS_ID=$line->[0]");      
      #Get binding info    	
    	if ($FORM{GET_USERS}) {
    		if ($binding->{$mac}) {
    		  my ($name, $uid) = split(/:/, $binding->{$mac});
    		  unshift @arr, $html->button("$name", "index=15&UID=$uid");  
    		 }
        else {
        	unshift @arr, '';  
         }    		
    	 }


    	$table->addrow(
                     @arr,
    	               "(". $html->button('H', "index=$index&hangup=$k", { TITLE => 'Hangup' }). ")"
                     );


   }
  #last;

}

print $table->show();


$table = $html->table({ width       => '100%',
                        rowcolor    => $_COLORS[3],
                        cols_align  => ['right', 'left', 'right', 'right', 'center'],    
                        rows        => [ ["$_TOTAL:", "$_USERS:", "$total_users", "$_SESSIONS:", "$total_sessions" ]]
                      });

print $table->show();





  snmp_form_footer(\%fields, \@default_fields,  
    { OIDS_EXINFO =>  snmputils_load_mibs(['CISCO-SMI', 'CISCO-DOT11-IF-MIB', 'CISCO-DOT11-ASSOCIATION-MIB' ]) });
}

#***********************************************************
#
#**********************************************************
sub data_convert  {
	my ($name, $data, $attr) = @_;
	
	my $ret = '';
        if($attr->{OIDS_EXINFO} && $attr->{OIDS_EXINFO}{$name}{SYNTAX} eq 'MacAddress'){
           $ret = join(':', unpack("H2H2H2H2H2H2", $data));
         }
#Cisco Section
	      elsif ($name eq 'cDot11ClientIpAddress') {
           $ret = int2ip(unpack("N4", $data));
         }
        elsif ($name eq 'cDot11ClientParentAddress') {
        	$ret = join(':', unpack("H2H2H2H2H2H2", $data));
        	#$ret = join(':', unpack("H*", $data));
         }
        elsif ($name eq 'cDot11ClientUpTime') {
      	  $ret = sec2time($data, { str => 1});
         }
        elsif ($name eq 'cDot11ClientDataRateSet') {
          my @arr = unpack("C*", $data);
          for(my $i; $i<$#arr; $i++) {
          	 $arr[$i]=$arr[$i]/2;
           }
          $ret = join(", ", @arr). ' Mbps';
         }
        elsif ($name eq 'cDot11ClientCurrentTxRateSet' || $name eq 'ClientCurrentTxRateSet') {
          $ret = (hex((unpack("H2", $data)) ) / 2) . " Mbps";
         }
        elsif ($name eq 'cDot11ClientAssociationState') {
          $ret = $association_state[$data];
         }
        else {
        	$ret = $data;
         }
	
	return $ret;
}

#**********************************************************
#
#**********************************************************
sub snmputils_patton_dialin {
   
 
   my %fields = (

      diactIndex                  => '1',
      diactMultiIndex             => '2',
      diactState                  => '3',
      diactProtocol               => '4',
      diactAccessLevel            => '5',
      diactDSPIndex               => '6',
      diactIFIndex                => '7',
      diactLinkIndex              => '8',
      diactSlotIndex              => '9',
      diactIP                     => '10',
      diactPort                   => '11',
      diStatBadAddresses          => '12',
      diStatBadControls           => '13',
      diStatPacketTooLongs        => '14',
      diStatBadFCSs               => '15',
      diStatLocalMRU              => '16',
      diStatRemoteMRU             => '17',
      diStatLocalToPeerACCMap     => '18',
      diStatPeerToLocalACCMap     => '19',
      diStatLocalToRemoteProtComp => '20',
      diStatRemoteToLocalProtComp => '21',
      diStatLocalToRemoteACComp   => '22',
      diStatRemoteToLocalACComp   => '22',
      diStatTransmitFcsSize       => '23',
      diStatReceiveFcsSize        => '24',
      diIpOperStatus              => '25',
      diIpLocalToRemoteCompProt   => '26',
      diIpRemoteToLocalCompProt   => '27',
      diIpRemoteMaxSlotId         => '28',
      diIpLocalMaxSlotId          => '29',
      diactSessionTime            => '30',
      diactRemainingIdle          => '31',
      diactRemainingSession       => '33',
      diactNumberDialed           => '34',
      diactCallingPhone           => '35',
      diactSentOctets             => '36',
      diactReceivedOctets         => '37',
      diactSentDataFrames         => '38',
      diactReceivedDataFrames     => '39',
      diactErrorFrames            => '40',
      diactSessionStartTime       => '41',
      diactModulation             => '43',
      diactErrorCorrection        => '44',
      diactCompression            => '45',
      diactMultiLinkFlag          => '46',
      diactSymbolRate             => '48',

      diactTxSpeed                => '49',
      diactRxSpeed                => '50',
      
      diactUsername               => '56',
      diactPassword               => '57',
      diactTerminateReason        => '58',
      diactTerminateState         => '59',
      diactLocalRenegotiates      => '60',
      diactLocalRetrains          => '61',
      diactRemoteRenegotiates     => '62',
      diactRemoteRetrains         => '63',
      diStatLcpRemoteMRRU         => '64',
      diStatLcpLocalMRRU          => '65',
      diStatLcpAuth               => '66',

      diStatIpFilterA             => '70',
      diStatIpFilterB             => '71',
      diStatIpFilterC             => '72',
      diStatIpFilterD             => '73',
      diStatIpFilterE             => '74',
      diStatIpFilterF             => '75',
      diStatIpFilterG             => '76',
      diStatIpFilterH             => '77',
      diStatIpFilterI             => '78',
      diStatIpFilterJ             => '79',

      diactForceNextHop           => '67',
      diactPrimaryDNS             => '100',
      diactSecondaryDNS           => '101'
 );



snmputils_multioid_view({
  FIELDS         => \%fields,
  DEFAULT_FIELDS => ['diactIndex', 'diactSlotIndex', 'diactUsername', 'diactState'],
  OID_PREFIX     => '1.3.6.1.4.1.1768.5.100.1',
  NAS_TYPE       => 'patton',
  MIBS           => ['corporat.mib', 'common.mib', 'product.mib']
  });
}




#**********************************************************
#
#**********************************************************
sub snmputils_portmaster {

  
   my %fields = (
	    livingstonSerialIndex              => 1,
      livingstonSerialPortName           => 2,
      livingstonSerialPhysType           => 3,
      livingstonSerialUser               => 4,
      livingstonSerialSessionId          => 5,
      livingstonSerialType               => 6,
      livingstonSerialDirection          => 7,
      livingstonSerialPortStatus         => 8,
      livingstonSerialStarted            => 9,
      livingstonSerialIdle               => 10,
      livingstonSerialInSpeed            => 11,
      livingstonSerialOutSpeed           => 12,
      livingstonSerialModemName          => 13,
      livingstonSerialIpAddress          => 14,
      livingstonSerialifDescr            => 15,
      livingstonSerialInOctets           => 16,
      livingstonSerialOutOctets          => 17,
      livingstonSerialQOctets            => 18,
      livingstonSerialModemStatus        => 19,
      livingstonSerialModemCompression   => 20,
      livingstonSerialModemProtocol      => 21,
      livingstonSerialModemRetrains      => 22,
      livingstonSerialModemRenegotiates  => 23,
#      livingstonSerialSlotId             => 24,
#      livingstonSerialPortId             => 25
   );
	
	
	snmputils_multioid_view({
	   FIELDS         => \%fields,
	   DEFAULT_FIELDS => ['livingstonSerialIndex',  'livingstonSerialUser',  'livingstonSerialIpAddress', 'livingstonSerialSessionId',  'livingstonSerialModemStatus'],
	   OID_PREFIX     => '.1.3.6.1.4.1.307.3.2.1.1.1',
	   NAS_TYPE       => 'pm25',
	   MIBS           => ['livingston.mib']
	  });
}

#**********************************************************
#
#**********************************************************
sub snmputils_mikrotik_info {

  my %fields = ('uptime'          => '.1.3.6.1.2.1.1.3.0',
                'total-hdd-space' => '.1.3.6.1.2.1.25.2.3.1.5.1',
                'used-hdd-space'  => '.1.3.6.1.2.1.25.2.3.1.6.1',
                'total-memory'    => '.1.3.6.1.2.1.25.2.3.1.5.2',
                'used-memory'     => '.1.3.6.1.2.1.25.2.3.1.6.2',
                'cpu-load'        => '.1.3.6.1.2.1.25.3.3.1.2.1');



my @caption = ('uptime', 'total-hdd-space', 'used-hdd-space', 'total-memory', 'used-memory','cpu-load');
my $table = $html->table({ width    => '100%',
                           title       => \@caption,
                           cols_align  => ['right', 'left', 'right', 'right', 'center'],    
                         });

	snmputils_multioid_view({
	   DEFAULT_FIELDS => ['uptime', 'total-hdd-space', 'used-hdd-space', 'total-memory', 'used-memory','cpu-load'],
	   NAS_TYPE       => 'Mikrotik',
	   SINGLE         => \%fields
	 });


}

#**********************************************************
#
#**********************************************************
sub snmputils_docsis_modems {
	

  my %fields = (
            #docsIfCmtsCmStatusIndex               => '1',
            docsIfCmtsCmStatusMacAddress          => '2',
            docsIfCmtsCmStatusIpAddress           => '3',
            docsIfCmtsCmStatusDownChannelIfIndex  => '4',
            docsIfCmtsCmStatusUpChannelIfIndex    => '5',
            docsIfCmtsCmStatusRxPower             => '6',
            docsIfCmtsCmStatusTimingOffset        => '7',
            docsIfCmtsCmStatusEqualizationData    => '8',

            docsIfCmtsCmStatusValue               => '9',
            docsIfCmtsCmStatusUnerroreds          => '10',
            docsIfCmtsCmStatusCorrecteds          => '11',
            docsIfCmtsCmStatusUncorrectables      => '12',
            docsIfCmtsCmStatusSignalNoise         => '13',
            docsIfCmtsCmStatusMicroreflections    => '14'   
           );
	
#	docsIfCmtsCmStatusValue OBJECT-TYPE
#        SYNTAX      INTEGER {
#            other(1),
#            ranging(2),
#            rangingAborted(3),
#            rangingComplete(4),
#            ipComplete(5),
#            registrationComplete(6),
#            accessDenied(7)
	
	
	snmputils_multioid_view({
	   FIELDS         => \%fields,
	   DEFAULT_FIELDS => ['docsIfCmtsCmStatusIndex',  
	                      'docsIfCmtsCmStatusMacAddress', 
	                      'docsIfCmtsCmStatusIpAddress',
	                      'docsIfCmtsCmStatusDownChannelIfIndex',
	                      'docsIfCmtsCmStatusUpChannelIfIndex',
	                      'docsIfCmtsCmStatusValue' ],
	   OID_PREFIX     => '1.3.6.1.2.1.10.127.1.3.3.1',
	   NAS_TYPE       => 'BSR1000',
	   MIBS           => ['DOCS-IF-MIB']
	  });

}

#**********************************************************
#
#**********************************************************
sub snmputils_multioid_view {
   my ($attr) = @_;

       my $fields         = $attr->{FIELDS};
       my @default_fields = @{ $attr->{DEFAULT_FIELDS} };
       my $oid_prefix     = $attr->{OID_PREFIX} || '';
       my $nas_type       = $attr->{NAS_TYPE} || '';
      
if ($FORM{fields}) {
  @default_fields = split(/, /, $FORM{fields});
}

my $OIDS_EXINFO;
if ($attr->{MIBS}) {
	$OIDS_EXINFO = snmputils_load_mibs($attr->{MIBS});
}

$table = $html->table({ width       => '100%',
                        caption     => "$nas_type",
                        border      => 1,
                        title       => [@default_fields, "-"],
                        cols_align  => ['left', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'center']
                      });


my $Nas = Nas->new($db, \%conf);
my $list = $Nas->list({ TYPE => $nas_type, DISABLE => 0 });

foreach my $line (@$list) {
  my %result = ();

  if ($attr->{SINGLE}) {
    while(my($name, $oid) = each %{ $attr->{SINGLE} } ) {
	    $result{$name}{0}=snmpget("$line->[11]\@$line->[3]", $oid);
     }
   }
  else {
    foreach my $field (@default_fields) {
      my @arr = ();
      if (@arr = snmpwalk("$line->[11]\@$line->[3]", $oid_prefix.'.'.$fields->{$field})) {
        my $oid = "$field - $oid_prefix/$fields->{$field}";
      
        if ($SNMP_Session::errmsg) {
          print $html->message('err', $_ERROR, "$oid<br>$SNMP_Session::suppress_warnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmrnings / $SNMP_Session::errmsg");
          last;
         }
        foreach my $line (@arr) {
          if ($line =~ /([\d\.]+):(.+)/) {
            $result{$field}{$1}=$2;
            print "$field // $line ($1:$2) <br>"if ($debug == 1);
           }
         }
       }
      else {
        print "- $field - $oid_prefix/$fields->{$field} <br>" if ($debug == 1);
        print $html->message('err', $_ERROR, "No response");
        last;
       }
   }
 }

#  $SORT = 0;
#  $SORT = $FORM{sort} - 1 if ($FORM{sort});
  
  
  $table->{rowcolor}=$_COLORS[0];
  $table->{extra}="colspan='". ($#default_fields + 2) ."' class='small'";
  $table->addrow("$line->[0]:<b>$line->[1]</b>:$line->[3] ");
  $page_qs .= "&NAS_ID=$line->[0]";
  $total_sessions += $#MAC_ARR + 1;

  undef($table->{rowcolor});
  undef($table->{extra});

  
my @SESSION_ARR = sort keys %{ $result{ $default_fields[0] } } ;

#print "$default_fields[$sort] / $SORT <br>";
#print join(', ', @SESSION_ARR);

    foreach my $k ( @SESSION_ARR ) {
      my @arr = ();
      foreach my $ft (@default_fields) {
        $result{$ft}{$k} = data_convert($ft, $result{$ft}{$k}, { OIDS_EXINFO => $OIDS_EXINFO});
      	push @arr, ($OIDS_EXINFO->{$ft}{ACCESS} eq 'read-write') ? $html->button($result{$ft}{$k}, "index=$index&change=y&SNMP_INDEX=$inst&SNMP_OID=$OIDS_HASH{$ft}$page_qs") :  $result{$ft}{$k}
       }
   	
    	$table->addrow(@arr,
    	               "(". $html->button('H', "index=$index&hangup=$k", { TITLE => 'Hangup' }). ")"
                     );

   }

}



print $table->show();
$table = $html->table({ width       => '100%',
                        rowcolor    => $_COLORS[3],
                        cols_align  => ['right', 'left', 'right', 'right', 'center'],    
                        rows        => [ ["$_TOTAL:", "$_USERS:", "$total_users", "$_SESSIONS:", "$total_sessions" ]]
                      });

print $table->show();

	
	
snmp_form_footer($fields, \@default_fields, { OIDS_EXINFO => $OIDS_EXINFO });

}



#**********************************************************
#
#**********************************************************
sub snmp_form_footer {
	my ($fields, $active_fields, $attr) = @_;



  #if ($attr->{OIDS_EXINFO});
 

my $table2 = $html->table({ width => '100%' });
my @arr = ();
foreach my $name ( sort keys %$fields) {
  my $ex_info = ($attr->{OIDS_EXINFO}->{$name}{DESCRIBE}) ?  " ($attr->{OIDS_EXINFO}->{$name}{ACCESS})<br>$attr->{OIDS_EXINFO}->{$name}{DESCRIBE}" : '';
  push @arr, $html->form_input('fields', "$name", { TYPE => 'checkbox', STATE => (in_array($name, $active_fields)) ? 1 : undef  }). " <b>$name</b>$ex_info";

  if ($#arr > 2) {
    $table2->addrow(@arr);
    @arr = ();
  }
}

if ($#arr > -1 ) {
  $table2->addrow(@arr);
 }




my $table = $html->table( { width       => '100%',
                         title_plain => [ 
                                           "$_REFRESH (sec): ".   $html->form_input('REFRESH', int($FORM{REFRESH}), { SIZE => 4 } ),
                                           $html->form_input('SHOW',  $_SHOW, { TYPE => 'SUBMIT'})  
                                         ],
                          cols_align => ['center:noprint', 'center:noprint'],
                       });

print  $output .= $html->form_main({ CONTENT => $table2->show(). $table->show(),
	                                   HIDDEN  => { index         =>  "$index",
	                                   	            NAS_TYPE      =>  "$FORM{NAS_TYPE}",
	                                   	            NAS_HOST      =>  "$FORM{NAS_HOST}",
	                                   	            NAS_COMMUNITY =>  "$FORM{NAS_COMMUNITY}"
	                                   	           },
	                                   METHOD  => 'GET'
                                   });

	
}


#**********************************************************
#
#**********************************************************
sub snmputils_load_mibs  {
 my ($mib_array, $attr) = @_;

 my %OIDS_EXINFO = ();

#if (-d '../../Abills/MIBs/') {
#  opendir DIR, '../../Abills/MIBs/' or die "Can't open dir '../../Abills/MIBs/' $!\n";
#    my @contents = grep  !/^\.\.?$/  , readdir DIR;
#  closedir DIR;
#  foreach my $line (@contents) {
#    $info{MIBS}.=$html->form_input('MIBS', "$line", { TYPE => 'checkbox', STATE => 0 }). " $line<br>\n";
#   }
#}
#if ($FORM{MIBS}) {
#   @mib_array = split(', ', $FORM{MIBS});
#}
  
  print "<pre>\n";
  foreach my $line (@$mib_array) {
    next if (! -f "../../Abills/MIBs/$line");
    my($ret, $oid_hash, $oid_ex) = snmpMIB_to_OID_extended("../../Abills/MIBs/$line");

    print "MIBS: $line Loaded<br> " if ($debug == 1);

    while(my($k, $v)=each %$oid_hash) {
  	  $OIDS_EXINFO{$k}{DESCRIBE}=$oid_ex->{$k}{DESCRIPTION} if ($oid_ex->{$k}{DESCRIPTION});
  	  $OIDS_EXINFO{$k}{ACCESS}=$oid_ex->{$k}{ACCESS} if ($oid_ex->{$k}{ACCESS});
  	  $OIDS_EXINFO{$k}{SYNTAX}=$oid_ex->{$k}{SYNTAX} if ($oid_ex->{$k}{SYNTAX});
  	  $OIDS_EXINFO{$k}{MIB}="$line" if (! $OIDS_EXINFO{$k}{MIB});
  	  snmpmapOID("$k", "$v");
     }
   }
  
  print "</pre>\n";
  return \%OIDS_EXINFO;
}

#**********************************************************
#
#**********************************************************
sub snmp_info_form {

 
  my %info = ();

  $info{ACTION}='add';
  $info{ACTION_LNG}=$_ADD;


  snmpmapOID("ipRoutingTable", "1.3.6.1.2.1.4.21");
# $SNMP_util::Debug = 1;


  my %OIDS_EXINFO = %{ snmputils_load_mibs([ 'SNMPv2-SMI', 
                                             'SNMPv2-MIB', 
                                             'SNMPv2-CONF',
                                             'SNMPv2-TC',
                                             'IF-MIB', 
                   'IP-MIB',
                   'RFC1212-MIB',
                   'RFC1155-SMI',
                   'RFC1213-MIB',
                   'ENTITY-MIB',

 #Cisco Mibs       
                   'CISCO-SMI',
                   'CISCO-DOT11-IF-MIB',
                   'CISCO-DOT11-ASSOCIATION-MIB',
 #'livingston.mib' 
                   'corporat.mib',
                   'common.mib',
                   'product.mib',
 #DOCSIS
                   'DOCS-IF-MIB',
                   'DOCS-CABLE-DEVICE-MIB',
                   'DOCS-IF-EXT-MIB',
                   
 #River Delta                   
                   'RDN-MIB',

                   
                   'RDN-CABLE-SPECTRUM',
                   'RDN-CABLE-SPECTRUM-GROUP-MIB',
#                   'RDN-CMTS-MIB',
                   'RDN-SYSLOG-MIB',                   
                   
     ] ) };


  $info{TYPE_SEL}=$html->form_select('TYPE', 
                                          { 
 	                                          SELECTED    => $FORM{TYPE},
 	                                          SEL_HASH    => {'system'            => 'RFC1213-MIB System information',
 	                                          	              'interfaces'        => 'IF-MIB:ifTable',
                                                            'ipNetToMediaTable' => 'RFC1158-MIB:ipNetToMediaTable',
                                                            'ipRoutingTable'    => 'RFC1158-MIB:ipRoutingTable',
                                                            'tcpConnTable'      => 'RFC1213-MIB:tcpConnTable',
                                                            'udpTable'          => 'RFC1213-MIB:udpTable',
                                                            'dlink_ip_mac_port' => 'D-Link IP MAC Port Binding'
 	                                          	              },
                                       NO_ID   => 1
                                     });
  
 
  $info{NAS_SEL} = $html->form_select('NAS_ID', 
                                          { 
 	                                          SELECTED          => $FORM{NAS_ID},
 	                                          SEL_MULTI_ARRAY   => [['', ''], @{ $nas->list({ SORT => 2, PAGE_ROWS => 10000 }) } ],
 	                                          MULTI_ARRAY_KEY   => 0,
 	                                          MULTI_ARRAY_VALUE => 1,
 	                                        });


 

  
  

if ($FORM{change}) {
    my $SNMP_COMMUNITY = "$FORM{SNMP_COMMUNITY}\@$FORM{SNMP_HOST}";
   
    if ($FORM{NAS_ID}) {
      $nas->info({ NAS_ID => $FORM{NAS_ID} });
      if (! $nas->{NAS_MNG_PASSWORD}) {
   	     $html->message('err', $_ERROR, "NO SNMP COMMUNITY");
   	     return 0;
       }
      elsif (! $nas->{NAS_MNG_IP_PORT}) {
   	     $html->message('err', $_ERROR, "NO SNMP HOST");
   	     return 0;
       }
      $SNMP_COMMUNITY = "$nas->{NAS_MNG_PASSWORD}\@$nas->{NAS_MNG_IP_PORT}";
     }


    my %REV_HASH = reverse %OIDS_HASH;
    my $SNMP_OID_NAME = $REV_HASH{$FORM{SNMP_OID}};
    print "-- $OIDS_EXINFO{$SNMP_OID_NAME}{SYNTAX} --";

    if ($FORM{set}) {

       my $SNMP_OID = $FORM{SNMP_OID};
       $SNMP_OID .= '.'.$FORM{SNMP_INDEX} if ($FORM{SNMP_INDEX});

       if(snmpset($SNMP_COMMUNITY, $FORM{SNMP_OID}, "$FORM{SNMP_TYPE}", "$FORM{SNMP_VALUE}")) {
       	  print $html->message('info', $_CHANGED, "$FORM{SNMP_OID} => $FORM{SNMP_VALUE}");
        }
     }


   if ($FORM{SNMP_INDEX}) {
 	    $FORM{SNMP_OID} = $FORM{SNMP_OID}. '.'.$FORM{SNMP_INDEX};
    }

    undef $FORM{SNMP_VALUES};
    $info{SNMP_VALUE} = snmpget($SNMP_COMMUNITY, $FORM{SNMP_OID});
    

  $info{SNMP_TYPE_SEL}=$html->form_select('SNMP_TYPE', 
                                          { 
 	                                          SELECTED    => $FORM{SNMP_TYPE},
 	                                          SEL_ARRAY   => [
                                              'int',
                                              'integer',
                                              'string',
                                              'octetstring',
                                              'octet string',
                                              'oid',
                                              'object id',
                                              'object identifier',
                                              'ipaddr',
                                              'ip address',
                                              'timeticks',
                                              'uint',
                                              'uinteger',
                                              'uinteger32',
                                              'unsigned int',
                                              'unsigned integer',
                                              'unsigned integer32',
                                              'counter',
                                              'counter32',
                                              'counter64',
                                              'gauge',
                                              'gauge32'
 	                                          	              ],
                                       NO_ID   => 1
                                     });


  $html->tpl_show(_include('snmputils_set', 'Snmputils'), { %info, %FORM });
 }
else {
  $html->tpl_show(_include('snmputils_main', 'Snmputils'), { %info, %FORM });	
}

if ($FORM{SHOW}) {

    my $rows_count  =  0;
    $FORM{TYPE}=$FORM{SNMP_OID} if ($FORM{SNMP_OID});

    my $SNMP_COMMUNITY = "$FORM{SNMP_COMMUNITY}\@$FORM{SNMP_HOST}";

    if ($FORM{NAS_ID}) {
      $nas->info({ NAS_ID => $FORM{NAS_ID} });
      if (! $nas->{NAS_MNG_PASSWORD}) {
   	     $html->message('err', $_ERROR, "NO SNMP COMMUNITY");
   	     return 0;
       }
      elsif (! $nas->{NAS_MNG_IP_PORT}) {
   	     $html->message('err', $_ERROR, "NO SNMP HOST");
   	     return 0;
       }
      
      $page_qs = "&NAS_ID=$FORM{NAS_ID}";
      $SNMP_COMMUNITY = "$nas->{NAS_MNG_PASSWORD}\@$nas->{NAS_MNG_IP_PORT}";
     }
    else {
    	$page_qs = "\&SNMP_COMMUNITY=$FORM{SNMP_COMMUNITY}\&SNMP_HOST=$FORM{SNMP_HOST}";
     }

#External 
# Dlink Port binding
    if($FORM{TYPE} eq 'dlink_ip_mac_port') {
      snmputils_dlink_ip_mac_port({ SNMP_COMMUNITY => $SNMP_COMMUNITY });
      return 0;
     }

    my %result = &snmpwalkhash("$SNMP_COMMUNITY", \&my_simple_hash, $FORM{TYPE});
    my @CAPTION = keys %result;
    my @RES_ARR = sort { $a <=> $b } keys %{ $result{"$CAPTION[0]"} };
    
  
    if ($SNMP_Session::errmsg) {
       print $html->message('err', $_ERROR, "$FORM{TYPE}<br>$SNMP_Session::suppress_warnings / $SNMP_Session::errmsg");
     }


      
    if ($#RES_ARR > 0 && $FORM{TYPE} ne 'system') {


       $table = $html->table({ width      => '100%',
                              caption     => "$_RESULT: $SNMP_COMMUNITY",
                              border      => 1,
                              title       => ['index', @CAPTION],
                              cols_align  => ['left', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'center']
                           });
      
      foreach my $k (@RES_ARR) {
        my @arr = ($k);
        foreach my $ft (@CAPTION) {
          #$result{$ft}{$k} = data_convert($ft, $result{$ft}{$k});
        	push @arr, ($OIDS_EXINFO{$ft}{ACCESS} eq 'read-write') ? $html->button("$result{$ft}{$k}", "index=$index&change=y&SNMP_INDEX=$k&SNMP_OID=$OIDS_HASH{$ft}$page_qs") : $result{$ft}{$k};
         }
        $table->addrow(@arr);
        $rows_count++;
       }



     }
    else {
      $table = $html->table({ width     => '100%',
                           caption     => "$_RESULT: $SNMP_COMMUNITY",
                           border      => 1,
                           title       => ['MIB', 'OID Name', "inst", "$_VALUE", "ACCESS", "$_DESCRIBE"],
                           cols_align  => ['left', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'center'],
                         });

      foreach my $oid (keys %result) {
        foreach my $inst (sort { $a <=> $b } keys %{$result{$oid}})        {
          $table->addrow("$OIDS_EXINFO{$oid}{MIB}", "$oid", 
            "$inst", 
            $result{$oid}{$inst},
            ($OIDS_EXINFO{$oid}{ACCESS} eq 'read-write') ? $html->button($_CHANGE, "index=$index&change=y&SNMP_INDEX=$inst&SNMP_OID=$OIDS_HASH{$oid}$page_qs") : $OIDS_EXINFO{$oid}{ACCESS},
             $OIDS_EXINFO{$oid}{DESCRIBE}
           );
       }
      $rows_count++;
     }
    }

  print $table->show();
  
  $table = $html->table( {
  	                        width      => '100%',
                            cols_align => ['right', 'right'],
                            rowcolor   => $_COLORS[0],
                            rows       => [ ["$_TOTAL:", "<b>$rows_count</b>" ] ]
                        } );
  print $table->show();
   	
  snmp_form_footer(\%result, \@CAPTION, { OIDS_EXINFO => \%OIDS_EXINFO });
 
   if ($FORM{TYPE} eq 'ipRoutingTable')   {
     print $html->tpl_show(_include('snmputils_route', 'Snmputils'), \%info);   	
   }
   	
   	
  }
	
}


sub my_simple_hash {
        my ($h_ref, $host, $name, $oid, $inst, $value) = @_;
        $inst =~ s/^\.+//;
        
        
        my %ipNetToMediaType = (1 => 'other', 
                                2 => 'invalid',
                                3 => 'dynamic',
                                4 => 'static'
                               );
        
        if ($name =~/ifPhysAddress/ || $name =~ /ipNetToMediaPhysAddress/) {
                my $mac = '';
                map { $mac .= sprintf("%02X:",$_) } unpack "CCCCCC", $value;
                $value = $mac;
         }
        elsif ($name =~/ipNetToMediaType/) {
          $value = $ipNetToMediaType{$value};	
         }

        $h_ref->{$name}->{$inst} = $value;
}




#
# Read in the passed MIB file, parsing it
# for their text-to-OID mappings
#
sub snmpMIB_to_OID_extended ($) {
  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',
  );








  #my %OIDS_HASH = ();
  my %OIDS_EX = ();
  
  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);
  
  my %DESCRIBE_OIDS = ();
  #my @MIB_ARRAY =
  my $MIB_NAME;
  
  while($need2pass) {
    while(<MIB>) {
      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 ($buf =~ /(\S+) DEFINITIONS/) {
    $MIB_NAME = $1;
    #print "$MIB_NAME\n";
   }
  
	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;
 }
elsif ($buf =~ /FROM (\S+)/) {
	 if (! $loaded_mibs{$1}) {
	   print "FROM $1\n" if ($debug == 1);
	  }
	 $buf =~ s/FROM $1//;
 }

#print $buf."\n";

 if ($buf =~ /DESCRIPTION.+"(.+)"+/g) {
 	 $DESCRIBE_OIDS{DESCRIPTION}=$1;
 	 #print "DESCRIPTION: <b>$DESCRIBE_OIDS{DESCRIPTION}</b>\n";
 	 #next;
  }
 elsif ($buf =~ /ACCESS (\S+)/) {
   $DESCRIBE_OIDS{ACCESS}=$1;
   $buf =~ s/ACCESS $1//;
 	 next;
   #print "MAX-ACCESS <b>$DESCRIBE_OIDS{ACCESS}</b>\n";
  }
 elsif ($buf =~ /(\S+) OBJECT-TYPE/) {
   $DESCRIBE_OIDS{'OBJECT-TYPE'}=$1;
   #print "OBJECT-TYPE <b>$DESCRIBE_OIDS{'OBJECT-TYPE'}</b>\n";
   #next;
  }
 elsif ($buf =~ /SYNTAX (\w+)/) {
 	 #print "$buf<br>";
 	 $DESCRIBE_OIDS{'SYNTAX'}=$1;
   $buf =~ s/ SYNTAX .*//;
 	 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/ [\w-]+ ::= OBJECT IDENTIFIER//;
      $buf =~ s/ OBJECT IDENTIFIER .* ::= {/ OBJECT IDENTIFIER ::= {/;
      $buf =~ s/".*"//;

#


  if ($buf =~ /"/) {
	  $quote = 1;
    }
#      	print "----- $buf.\n";

      if ($buf =~ / ([\w\-]+) OBJECT IDENTIFIER ::= {([^}]+)}/) {
      	

	$var = $1;
	$buf = $2;
#print "$var  // $buf.
#      	DESCRIPTION: <b>$DESCRIBE_OIDS{DESCRIPTION}</b>
#      	MAX-ACCESS <b>$DESCRIBE_OIDS{ACCESS}</b>
#      	OBJECT-TYPE <b>$DESCRIBE_OIDS{'OBJECT-TYPE'}</b>
#
#";
#
     
	undef $val;
	$buf =~ s/ +$//;
	($code, $val) = split(' ', $buf, 2);

  $OIDS_EX{$var}{SYNTAX}=$DESCRIBE_OIDS{SYNTAX};
  $OIDS_EX{$var}{ACCESS}=$DESCRIBE_OIDS{ACCESS};
  $OIDS_EX{$var}{DESCRIPTION}=$DESCRIBE_OIDS{DESCRIPTION};
  
 
  %DESCRIBE_OIDS=();
  
	if (!defined($val) || (length($val) <= 0)) {
	  #$SNMP_util::OIDS{$var} = $code;
	  $OIDS_HASH{$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;
	      if (exists($OIDS_HASH{$strt})) {
		$tmpv = "$OIDS_HASH{$strt}.$2";
	      } else {
		$tmpv = $2;
	      }
	      $Link{$tmp} = $strt;
	      if (!exists($prev{$tmp}) && exists($OIDS_HASH{$tmp})) {
		if ($tmpv ne $OIDS_HASH{$tmp}) {
		  $strt = "$strt.$tmp";
		  $OIDS_HASH{$strt} = $tmpv;
		  $cnt++;
		}
	      } else {
		$prev{$tmp} = 1;
		$OIDS_HASH{$tmp} = $tmpv;
		$cnt++;
		$strt = $tmp;
	      }
	    }
	  }

	  if (!exists($OIDS_HASH{$strt})) {
	    if ($pass) {
	      carp "snmpMIB_to_OID: $arg: \"$strt\" prefix unknown, load the parent MIB first.\n"
		unless ($SNMP_Session::suppress_warnings > 1);
		print "snmpMIB_to_OID: $arg: \"$strt\" prefix unknown, load the parent MIB first.<br>\n";
	    } else {
		$need2pass = 1;
	    }
	  }
	  $Link{$var} = $strt;
	  if (exists($OIDS_HASH{$strt})) {
	    $val = "$OIDS_HASH{$strt}.$val";
	  }
	  if (!exists($prev{$var}) && exists($OIDS_HASH{$var})) {
	    if ($val ne $OIDS_HASH{$var}) {
	      $var = "$strt.$var";
	    }
	  }

	  $OIDS_HASH{$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;
  
  $loaded_mibs{$MIB_NAME}=1;
  
  return ($ret, \%OIDS_HASH, \%OIDS_EX);
}


#**********************************************************
# binding ID binding
#**********************************************************
sub snmputils_binding {
	my $binding;

	$Snmputils->{ACTION}='add';
	$Snmputils->{ACTION_LNG}=$_ADD;
  $Snmputils->{debug}=1;
  
  if($FORM{add}) {
    $Snmputils->snmp_binding_add({ %FORM });
    if(! $Snmputils->{errno}) {
      $html->message('info', $_INFO, "$_ADDED");
     }
  }
  elsif($FORM{change}) {
    $Snmputils->snmp_binding_change({ %FORM });
    if(! $Snmputils->{errno}) {
      $html->message('info', $_INFO, "$_CHANGED"); 
     }
  }
 	elsif(defined($FORM{chg})) {
    $Snmputils->snmp_binding_info($FORM{chg}, { %FORM });
    if(! $Snmputils->{errno}) {
      $html->message('info', $_INFO, "$_CHANGING");  	
     }
    $Snmputils->{ACTION}='change';
    $Snmputils->{ACTION_LNG}=$_CHANGE;
  }
  elsif(defined($FORM{del}) && defined($FORM{is_js_confirmed}) ) {
    $Snmputils->snmp_binding_del({ ID => $FORM{del} });
    if(! $Snmputils->{errno}) {
    	$html->message('info', $_INFO, "$_DELETED"); 
     }
  }

  if ($Snmputils->{errno} == 7) {
  	$html->message('err', $_ERROR, "$_EXIST '$FORM{BINDING}'"); 
   }
  elsif($Snmputils->{errno}) {
    $html->message('err', $_ERROR, "[$Snmputils->{errno}] $err_strs{$Snmputils->{errno}}"); 
   }



  $html->tpl_show(_include('snmputils_binding', 'Snmputils'), { %$Snmputils, %FORM }); 	
  
#  %LIST_PARAMS = ();
  $pages_qs="&UID=$FORM{UID}";
  snmputils_binding_list();  
}


#**********************************************************
# binding ID binding
#**********************************************************
sub snmputils_binding_list {

my $list = $Snmputils->snmputils_binding_list({ %LIST_PARAMS }); 

$table = $html->table({ width       => '100%',
                        caption     => "$_RESULT: $SNMP_COMMUNITY",
                        border      => 1,
                        title       => ["$_USER", "ID", "$_PARAMS", "$_COMMENTS", '-', '-'],
                        cols_align  => ['left', 'right', 'right', 'right', 'right', 'center', 'center'],
                        qs          => $pages_qs,
                        pages       => $Snmputils->{TOTAL}
                      });

 foreach my $line (@$list) {
    my $delete = $html->button($_DEL, "index=$index&del=$line->[1]$pages_qs", { MESSAGE => "$_DEL [$line->[1]] ?" });
    my $change = $html->button($_CHANGE, "index=$index&chg=$line->[4]$pages_qs");;

    $table->addrow($line->[0],
     $line->[1],
     $line->[2],
     $line->[3],
     $change,
     $delete);
  }


 print $table->show();

}


#**********************************************************
# binding users
#**********************************************************
sub snmputils_get_users {
  my ($attr) = @_;

  my %user_hash = ();
  my $list = $Snmputils->snmputils_binding_list({ IDS => $attr->{IDS}, PAGE_ROWS => 100000  }); 
  foreach my $line (@$list) {
  	$user_hash{"$line->[1]"}="$line->[0]:$line->[5]";
  	
#  	print $line->[1] . "/$line->[0]:$line->[5]<br>";
   }

  return \%user_hash; 
}

1

