snmpWalkThreads.cpp
上传用户:cnryan
上传日期:2008-12-15
资源大小:260k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*_############################################################################
  2.   _## 
  3.   _##  snmpWalkThreads.cpp  
  4.   _##
  5.   _##  SNMP++v3.2.21
  6.   _##  -----------------------------------------------
  7.   _##  Copyright (c) 2001-2006 Jochen Katz, Frank Fock
  8.   _##
  9.   _##  This software is based on SNMP++2.6 from Hewlett Packard:
  10.   _##  
  11.   _##    Copyright (c) 1996
  12.   _##    Hewlett-Packard Company
  13.   _##  
  14.   _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  15.   _##  Permission to use, copy, modify, distribute and/or sell this software 
  16.   _##  and/or its documentation is hereby granted without fee. User agrees 
  17.   _##  to display the above copyright notice and this license notice in all 
  18.   _##  copies of the software and any documentation of the software. User 
  19.   _##  agrees to assume all liability for the use of the software; 
  20.   _##  Hewlett-Packard and Jochen Katz make no representations about the 
  21.   _##  suitability of this software for any purpose. It is provided 
  22.   _##  "AS-IS" without warranty of any kind, either express or implied. User 
  23.   _##  hereby grants a royalty-free license to any and all derivatives based
  24.   _##  upon this software code base. 
  25.   _##  
  26.   _##  Stuttgart, Germany, Fri Jun 16 17:48:57 CEST 2006 
  27.   _##  
  28.   _##########################################################################*/
  29. /*
  30.   snmpWalk.cpp 
  31.   
  32.   Copyright (c) 1996
  33.   Hewlett-Packard Company
  34.   ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  35.   Permission to use, copy, modify, distribute and/or sell this software
  36.   and/or its documentation is hereby granted without fee. User agrees
  37.   to display the above copyright notice and this license notice in all
  38.   copies of the software and any documentation of the software. User
  39.   agrees to assume all liability for the use of the software; Hewlett-Packard
  40.   makes no representations about the suitability of this software for any
  41.   purpose. It is provided "AS-IS" without warranty of any kind,either express
  42.   or implied. User hereby grants a royalty-free license to any and all
  43.   derivatives based upon this software code base.
  44.   Peter E. Mellquist
  45. */
  46. char snmpwalkthreads_cpp_version[]="@(#) SNMP++ $Id: snmpWalkThreads.cpp,v 1.8 2005/10/11 18:08:05 katz Exp $";
  47. #include "snmp_pp/snmp_pp.h"
  48. #include "snmp_pp/reentrant.h"
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51. #ifdef SNMP_PP_NAMESPACE
  52. using namespace Snmp_pp;
  53. #endif
  54. #if (__GNUC__ > 2)
  55. #include <iostream>
  56. using std::cerr;
  57. using std::cout;
  58. using std::endl;
  59. using std::flush;
  60. #else
  61. #include <iostream.h>
  62. #endif
  63. #ifdef _THREADS
  64. static pthread_attr_t* attr = 0;
  65. #ifdef _WIN32THREADS
  66. #error "This example is not available on WIN32 platforms!"
  67. #endif
  68. #endif
  69. UdpAddress address[1000];
  70. Snmp* snmp = 0;
  71. snmp_version version=version1;                       // default is v1
  72. int retries=1;                                       // default retries is 1
  73. int timeout=100;                                     // default is 1 second
  74. u_short port=161;                                    // default snmp port is 161
  75. OctetStr community("public");                        // read community
  76. #ifdef _SNMPv3
  77. OctetStr privPassword("");
  78. OctetStr authPassword("");
  79. OctetStr securityName("");
  80. int securityModel = SecurityModel_USM;
  81. int securityLevel = SecurityLevel_authPriv;
  82. OctetStr contextName("");
  83. OctetStr contextEngineID("");
  84. long authProtocol = SNMPv3_usmNoAuthProtocol;
  85. long privProtocol = SNMPv3_usmNoPrivProtocol;
  86. #endif
  87. #define BULK_MAX 10
  88. SnmpSynchronized ssync;
  89. void* runable(void *data) {
  90.   //--------[ build up SNMP++ object needed ]-------------------------------
  91.   ssync.lock();
  92.   printf("HELLO:%sn", community.get_printable());
  93.   int t = *((int*)data);
  94.   Pdu pdu;                              // construct a Pdu object
  95.   Vb vb;                                // construct a Vb object
  96.   vb.set_oid("1");                     // set the Oid portion of the Vb
  97.   pdu += vb;                            // add the vb to the Pdu
  98.   CTarget ctarget(address[t]);            // make a target using the address
  99. #ifdef _SNMPv3
  100.   UTarget utarget(address[t]);
  101.   if (version == version3) {
  102.     utarget.set_version( version);          // set the SNMP version SNMPV1 or V2 or V3
  103.     utarget.set_retry( retries);            // set the number of auto retries
  104.     utarget.set_timeout( timeout);          // set timeout
  105.     utarget.set_security_model( securityModel);
  106.     utarget.set_security_name( securityName);
  107.     pdu.set_security_level( securityLevel);
  108.     pdu.set_context_name (contextName);
  109.     pdu.set_context_engine_id(contextEngineID);
  110.   }
  111.   else {
  112. #endif
  113.     ctarget.set_version( version);          // set the SNMP version SNMPV1 or V2 or V3
  114.     ctarget.set_retry( retries);            // set the number of auto retries
  115.     ctarget.set_timeout( timeout);          // set timeout
  116.     ctarget.set_readcommunity( community);  // set the read community to use
  117.     ctarget.set_writecommunity( community);
  118. #ifdef _SNMPv3
  119.   }
  120. #endif
  121.   //-------[ issue the request, blocked mode ]-----------------------------
  122.   cout << "(" << t << "): " 
  123.        << "SNMP++ snmpWalk to " << address[t].get_printable() << " SNMPV" 
  124. #ifdef _SNMPv3
  125.        << ((version==version3) ? (version) : (version+1)) 
  126. #else
  127.        << (version+1) 
  128. #endif
  129.        << " Retries=" << retries
  130.        << " Timeout=" << timeout * 10 <<"ms";
  131. #ifdef _SNMPv3
  132.   if (version == version3)
  133.     cout << endl 
  134.  << "securityName= " << securityName.get_printable()
  135.  << ", securityLevel= " << securityLevel
  136.  << ", securityModel= " << securityModel << endl
  137.  << "contextName= " << contextName.get_printable()
  138.  << ", contextEngineID= " << contextEngineID.get_printable()
  139.  << endl;
  140.   else
  141. #endif
  142.     cout << " Community=" << community.get_printable() << endl << flush;
  143.   SnmpTarget *target;
  144. #ifdef _SNMPv3
  145.   if (version == version3)
  146.     target = &utarget;
  147.   else
  148. #endif
  149.     target = &ctarget;
  150.   int status = 0;
  151.   int requests = 0;
  152.   int objects = 0;
  153.   ssync.unlock();
  154.   while (( status = snmp->get_bulk( pdu,*target,0,BULK_MAX))
  155.  == SNMP_CLASS_SUCCESS)
  156.   {
  157.     requests++;
  158.     ssync.lock();
  159.     for ( int z=0;z<pdu.get_vb_count(); z++) {
  160.       pdu.get_vb( vb,z);
  161. #ifdef _SNMPv3
  162.       if (pdu.get_type() == REPORT_MSG) {
  163. Oid tmp;
  164. vb.get_oid(tmp);
  165. cout << "(" << t << "): " << "Received a reportPdu: "
  166.      << snmp->error_msg( tmp) 
  167.      << endl
  168.      << vb.get_printable_oid() << " = "
  169.      << vb.get_printable_value() << endl;
  170. ssync.unlock();
  171. return 0;
  172.       }
  173. #endif
  174.       objects++;
  175.       // look for var bind exception, applies to v2 only   
  176.       if ( vb.get_syntax() != sNMP_SYNTAX_ENDOFMIBVIEW) {
  177. cout <<  "(" << t << "): " 
  178.      << vb.get_printable_oid() << " = ";
  179. cout << vb.get_printable_value() << "n";
  180.       }
  181.       else {
  182. cout <<  "(" << t << "): " 
  183.      << "End of MIB Reachedn";
  184. cout <<  "(" << t << "): " 
  185.      << "Total # of Requests = " << requests << "n";
  186. cout <<  "(" << t << "): "
  187.      << "Total # of Objects  = " << objects  << "n";
  188. ssync.unlock();
  189. return 0;
  190.       }
  191.     }
  192.     ssync.unlock();
  193.     // last vb becomes seed of next rquest
  194.     pdu.set_vblist(&vb, 1);
  195.   }
  196.   if ( status != SNMP_ERROR_NO_SUCH_NAME)
  197.     cout <<  "(" << t << "): "
  198.  << "SNMP++ snmpWalk Error, " << snmp->error_msg( status) << "n";
  199.   cout <<  "(" << t << "): "
  200.        << "Total # of Requests = " << requests << "n";
  201.   cout <<  "(" << t << "): "
  202.        << "Total # of Objects  = " << objects  << "n";
  203.   return 0;
  204. }  // end Walk 
  205. int main(int argc, char **argv)
  206. {
  207.   //---------[ check the arg count ]----------------------------------------
  208.   if ( argc < 2) {
  209.   cout << "Usage:n";
  210.   cout << "snmpWalkThreads host/port [host/port]... [options]n";
  211.   cout << "StartOid: 1n";
  212.   cout << "options: -vN , use SNMP version 1, 2 or 3, default is 1n";
  213.   cout << "         -PPort , remote port to usen";
  214.   cout << "         -CCommunity_name, specify community default is 'public' n";
  215.   cout << "         -rN , retries default is N = 1 retryn";
  216.   cout << "         -tN , timeout in hundredths of seconds; default is N = 100n";
  217. #ifdef _SNMPv3
  218.           cout << "         -snSecurityName, " << endl;
  219.           cout << "         -slN , securityLevel to use, default N = 3 = authPriv" << endl;
  220.           cout << "         -smN , securityModel to use, only default N = 3 = USM possiblen";
  221.           cout << "         -cnContextName, default empty string" << endl;
  222.           cout << "         -ceContextEngineID, as hex e.g. 800007E580, default empty string" << endl;
  223.           cout << "         -authPROT, use authentication protocol NONE, SHA or MD5n";
  224.           cout << "         -privPROT, use privacy protocol NONE, DES, 3DESEDE, IDEA, AES128, AES192 or AES256n";
  225.           cout << "         -uaAuthPasswordn";
  226.           cout << "         -upPrivPasswordn";
  227. #endif
  228.           return 0;
  229.   }
  230.   Snmp::socket_startup();  // Initialize socket subsystem
  231.   //---------[ make a GenAddress and Oid object to retrieve ]---------------
  232.   address[0] = UdpAddress(argv[1]);
  233.   if ( !address[0].valid()) {           // check validity of address
  234.     cout << "Invalid Address or DNS Name, " << argv[1] << "n";
  235.     return -1;
  236.   }
  237.   int x=2;
  238.   while ((x<argc) && (x<100) && (strstr(argv[x],"-")==0)) {
  239.     address[x-1] = UdpAddress(argv[x]);
  240.     if ( !address[x-1].valid()) {           // check validity of address
  241.       cout << "Invalid Address or DNS Name, " << argv[x] << "n";
  242.       return -1;
  243.     }     
  244.     x++;
  245.   }
  246.   int threads = x-1;
  247.   cout << community.get_printable() << endl;
  248.    //---------[ determine options to use ]-----------------------------------
  249.    char *ptr;
  250.    for(;x<argc;x++) {                           // parse for version
  251.      if ( strstr( argv[x],"-v2")!= 0) {
  252.        version = version2c;
  253.        continue;
  254.      }
  255.      if ( strstr( argv[x],"-r")!= 0) {                 // parse for retries
  256.        ptr = argv[x]; ptr++; ptr++;
  257.        retries = atoi(ptr);
  258.        if (( retries<0)|| (retries>5)) retries=1; 
  259.        continue;
  260.      }
  261.      if ( strstr( argv[x], "-t")!=0) {                 // parse for timeout
  262.        ptr = argv[x]; ptr++; ptr++;
  263.        timeout = atoi( ptr);
  264.        if (( timeout < 100)||( timeout>500)) timeout=100;
  265.        continue;
  266.      }
  267.      if ( strstr( argv[x],"-C")!=0) {
  268.        ptr = argv[x]; ptr++; ptr++;
  269.        community = ptr;
  270.        continue;
  271.      }
  272.      if ( strstr( argv[x],"-P")!=0) {
  273.        ptr = argv[x]; ptr++; ptr++;
  274.        sscanf(ptr, "%hu", &port);
  275.        continue;
  276.      }
  277. #ifdef _SNMPv3
  278.      if ( strstr( argv[x],"-v3")!= 0) {
  279.        version = version3;
  280.        continue;
  281.      }
  282.      if ( strstr( argv[x],"-auth") != 0) {
  283.        ptr = argv[x]; ptr+=5;
  284.        if (strcasecmp(ptr, "SHA") == 0)
  285.    authProtocol = SNMP_AUTHPROTOCOL_HMACSHA;
  286.        else if (strcasecmp(ptr, "MD5") == 0)
  287.    authProtocol = SNMP_AUTHPROTOCOL_HMACMD5;
  288.        else
  289.    authProtocol = SNMP_AUTHPROTOCOL_NONE;
  290.        continue;
  291.      }
  292.      if ( strstr( argv[x],"-priv") != 0) {
  293.        ptr = argv[x]; ptr+=5;
  294.        if (strcasecmp(ptr, "DES") == 0)
  295.    privProtocol = SNMP_PRIVPROTOCOL_DES;
  296.        else if (strcasecmp(ptr, "3DESEDE") == 0)
  297.    privProtocol = SNMP_PRIVPROTOCOL_3DESEDE;
  298.        else if (strcasecmp(ptr, "IDEA") == 0)
  299.    privProtocol = SNMP_PRIVPROTOCOL_IDEA;
  300.        else if (strcasecmp(ptr, "AES128") == 0)
  301.    privProtocol = SNMP_PRIVPROTOCOL_AES128;
  302.        else if (strcasecmp(ptr, "AES192") == 0)
  303.    privProtocol = SNMP_PRIVPROTOCOL_AES192;
  304.        else if (strcasecmp(ptr, "AES256") == 0)
  305.    privProtocol = SNMP_PRIVPROTOCOL_AES256;
  306.        else
  307.    privProtocol = SNMP_PRIVPROTOCOL_NONE;
  308.        printf("nnPrivProt : %ldn", privProtocol);
  309.        continue;
  310.      }
  311.      if ( strstr( argv[x],"-sn")!=0) {
  312.        ptr = argv[x]; ptr+=3;
  313.        securityName = ptr;
  314.        continue;
  315.       }
  316.      if ( strstr( argv[x], "-sl")!=0) {
  317.        ptr = argv[x]; ptr+=3;
  318.        securityLevel = atoi( ptr);
  319.        if (( securityLevel < SecurityLevel_noAuthNoPriv) ||
  320.            ( securityLevel > SecurityLevel_authPriv))
  321.          securityLevel = SecurityLevel_authPriv;
  322.        continue;
  323.      }
  324.      if ( strstr( argv[x], "-sm")!=0) {
  325.        ptr = argv[x]; ptr+=3;
  326.        securityModel = atoi( ptr);
  327.        if (( securityModel < SecurityModel_v1) ||
  328.            ( securityModel > SecurityModel_USM))
  329.          securityModel = SecurityModel_USM;
  330.        continue;
  331.      }
  332.      if ( strstr( argv[x],"-cn")!=0) {
  333.        ptr = argv[x]; ptr+=3;
  334.        contextName = ptr;
  335.        continue;
  336.      }
  337.      if ( strstr( argv[x],"-ce")!=0) {
  338.        ptr = argv[x]; ptr+=3;
  339.        contextEngineID = OctetStr::from_hex_string(ptr);
  340.        continue;
  341.      }
  342.      if ( strstr( argv[x],"-ua")!=0) {
  343.        ptr = argv[x]; ptr+=3;
  344.        authPassword = ptr;
  345.        continue;
  346.      }
  347.      if ( strstr( argv[x],"-up")!=0) {
  348.        ptr = argv[x]; ptr+=3;
  349.        privPassword = ptr;
  350.        continue;
  351.      }
  352. #endif
  353.    }
  354.    //----------[ create a SNMP++ session ]-----------------------------------
  355.    int status;
  356.    // bind to any port and use IPv6 if enabled
  357. #ifdef SNMP_PP_IPv6
  358.    snmp = new Snmp(status, 0, true);
  359. #else
  360.    snmp = new Snmp(status);
  361. #endif
  362.    if ( status != SNMP_CLASS_SUCCESS) {
  363.      cout << "SNMP++ Session Create Fail, " 
  364.   << snmp->error_msg(status) << "n";
  365.      return -3;
  366.    }
  367. #ifdef _SNMPv3
  368.    //---------[ init SnmpV3 ]--------------------------------------------
  369.    v3MP *v3_MP;
  370.    if (version == version3) {
  371.      char *engineId = "snmpWalk";
  372.      char *filename = "snmpv3_boot_counter";
  373.      unsigned int snmpEngineBoots = 0;
  374.      int status;
  375.      status = getBootCounter(filename, engineId, snmpEngineBoots);
  376.      if ((status != SNMPv3_OK) && (status < SNMPv3_FILEOPEN_ERROR))
  377.      {
  378.        cout << "Error loading snmpEngineBoots counter: " << status << endl;
  379.        return 1;
  380.      }
  381.      snmpEngineBoots++;
  382.      status = saveBootCounter(filename, engineId, snmpEngineBoots);
  383.      if (status != SNMPv3_OK)
  384.      {
  385.        cout << "Error saving snmpEngineBoots counter: " << status << endl;
  386.        return 1;
  387.      }
  388.      int construct_status;
  389.      v3_MP = new v3MP(engineId, snmpEngineBoots, construct_status);
  390.      USM *usm = v3_MP->get_usm();
  391.      usm->add_usm_user(securityName,
  392.        authProtocol, privProtocol,
  393.        authPassword, privPassword);
  394.    }
  395.    else
  396.    {
  397.      // MUST create a dummy v3MP object if _SNMPv3 is enabled!
  398.      int construct_status;
  399.      v3_MP = new v3MP("dummy", 0, construct_status);
  400.    }
  401. #endif
  402. #ifdef _THREADS
  403.   pthread_t thread[100];
  404.   int started = threads;
  405. #endif
  406.   while (threads) {
  407. #ifdef _THREADS
  408.     if (!attr) {
  409.       attr = new pthread_attr_t;
  410.       pthread_attr_init(attr);
  411.       pthread_attr_setdetachstate(attr, PTHREAD_CREATE_JOINABLE);
  412.     }
  413.     pthread_create(&thread[threads-1], 0, 
  414.    &runable,
  415.    (void*)new int(threads-1));
  416. #else
  417.     int n = threads - 1;
  418.     runable(&n);
  419. #endif
  420.     threads--;
  421.   }
  422. #ifdef _THREADS
  423.   // wait for threads to terminate
  424.   for (int i=0; i<started; i++) {
  425.     cout << "JOINING THREAD " << i << endl;
  426.     pthread_join(thread[i], 0);
  427.   }
  428. #endif
  429.   cout << "END" << endl;
  430.   Snmp::socket_cleanup();  // Shut down socket subsystem
  431. }