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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*_############################################################################
  2.   _## 
  3.   _##  snmpWalk.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 snmpwalk_cpp_version[]="@(#) SNMP++ $Id: snmpWalk.cpp,v 1.9 2005/10/11 18:08:05 katz Exp $";
  47. #include "snmp_pp/snmp_pp.h"
  48. #include <stdlib.h>
  49. #include <stdio.h>
  50. #ifdef WIN32
  51. #define strcasecmp stricmp
  52. #endif
  53. #ifdef SNMP_PP_NAMESPACE
  54. using namespace Snmp_pp;
  55. #endif
  56. #if (__GNUC__ > 2)
  57. #include <iostream>
  58. using std::cerr;
  59. using std::cout;
  60. using std::endl;
  61. using std::flush;
  62. #else
  63. #include <iostream.h>
  64. #endif
  65. #define BULK_MAX 10
  66. int main(int argc, char **argv)
  67. {
  68.   int requests = 0;        // keep track of # of requests
  69.   int objects  = 0;
  70.    //---------[ check the arg count ]----------------------------------------
  71.    if ( argc < 2) {
  72.   cout << "Usage:n";
  73.   cout << "snmpWalk IpAddress | DNSName [StartOid] [options]n";
  74.   cout << "StartOid: sysDescr object is defaultn";
  75.   cout << "options: -vN , use SNMP version 1, 2 or 3, default is 1n";
  76.   cout << "         -PPort , remote port to usen";
  77.   cout << "         -S , only walk within subtreen";
  78.   cout << "         -CCommunity_name, specify community default is 'public' n";
  79.   cout << "         -rN , retries default is N = 1 retryn";
  80.   cout << "         -tN , timeout in hundredths of seconds; default is N = 100n";
  81. #ifdef _SNMPv3
  82.           cout << "         -snSecurityName, " << endl;
  83.           cout << "         -slN , securityLevel to use, default N = 3 = authPriv" << endl;
  84.           cout << "         -smN , securityModel to use, only default N = 3 = USM possiblen";
  85.           cout << "         -cnContextName, default empty string" << endl;
  86.           cout << "         -ceContextEngineID, as hex e.g. 800007E580, default empty string" << endl;
  87.           cout << "         -authPROT, use authentication protocol NONE, SHA or MD5n";
  88.           cout << "         -privPROT, use privacy protocol NONE, DES, 3DESEDE, IDEA, AES128, AES192 or AES256n";
  89.           cout << "         -uaAuthPasswordn";
  90.           cout << "         -upPrivPasswordn";
  91. #endif
  92.   return 1;
  93.    }
  94.    Snmp::socket_startup();  // Initialize socket subsystem
  95.    //---------[ make a GenAddress and Oid object to retrieve ]---------------
  96.    UdpAddress address( argv[1]);      // make a SNMP++ Generic address
  97.    if ( !address.valid()) {           // check validity of address
  98.   cout << "Invalid Address or DNS Name, " << argv[1] << "n";
  99.   return 1;
  100.    }
  101.    Oid oid("1");                      // default is beginning of MIB 
  102.    if ( argc >= 3) {                  // if 3 args, then use the callers Oid
  103.   if ( strstr( argv[2],"-")==0) {
  104.      oid = argv[2];
  105.      if ( !oid.valid()) {            // check validity of user oid
  106.     cout << "Invalid Oid, " << argv[2] << "n";
  107.     return 1;
  108.          }
  109.       }
  110.    }
  111.    //---------[ determine options to use ]-----------------------------------
  112.    snmp_version version=version1;                  // default is v1
  113.    int retries=1;                                  // default retries is 1
  114.    int timeout=100;                                // default is 1 second
  115.    u_short port=161;                               // default snmp port is 161
  116.    OctetStr community("public");                   // community name
  117.    bool subtree = false;
  118. #ifdef _SNMPv3
  119.    OctetStr privPassword("");
  120.    OctetStr authPassword("");
  121.    OctetStr securityName("");
  122.    int securityModel = SecurityModel_USM;
  123.    int securityLevel = SecurityLevel_authPriv;
  124.    OctetStr contextName("");
  125.    OctetStr contextEngineID("");
  126.    long authProtocol = SNMPv3_usmNoAuthProtocol;
  127.    long privProtocol = SNMPv3_usmNoPrivProtocol;
  128.    v3MP *v3_MP;
  129. #endif
  130.    char *ptr;
  131.    for(int x=1;x<argc;x++) {                           // parse for version
  132.      if ( strstr( argv[x],"-v2")!= 0) {
  133.        version = version2c;
  134.        continue;
  135.      }
  136.      if ( strstr( argv[x],"-r")!= 0) {                 // parse for retries
  137.        ptr = argv[x]; ptr++; ptr++;
  138.        retries = atoi(ptr);
  139.        if (( retries<0)|| (retries>5)) retries=1; 
  140.        continue;
  141.      }
  142.      if ( strstr( argv[x], "-t")!=0) {                 // parse for timeout
  143.        ptr = argv[x]; ptr++; ptr++;
  144.        timeout = atoi( ptr);
  145.        if (( timeout < 100)||( timeout>500)) timeout=100;
  146.        continue;
  147.      }
  148.      if ( strstr( argv[x],"-C")!=0) {
  149.        ptr = argv[x]; ptr++; ptr++;
  150.        community = ptr;
  151.        continue;
  152.      }
  153.      if ( strstr( argv[x],"-P")!=0) {
  154.        ptr = argv[x]; ptr++; ptr++;
  155.        sscanf(ptr, "%hu", &port);
  156.        continue;
  157.      }
  158.      if ( strstr( argv[x],"-S") != 0) {
  159.        subtree = true;
  160.        continue;
  161.      }
  162. #ifdef _SNMPv3
  163.      if ( strstr( argv[x],"-v3")!= 0) {
  164.        version = version3;
  165.        continue;
  166.      }
  167.      if ( strstr( argv[x],"-auth") != 0) {
  168.        ptr = argv[x]; ptr+=5;
  169.        if (strcasecmp(ptr, "SHA") == 0)
  170.    authProtocol = SNMP_AUTHPROTOCOL_HMACSHA;
  171.        else if (strcasecmp(ptr, "MD5") == 0)
  172.    authProtocol = SNMP_AUTHPROTOCOL_HMACMD5;
  173.        else
  174.    authProtocol = SNMP_AUTHPROTOCOL_NONE;
  175.        continue;
  176.      }
  177.      if ( strstr( argv[x],"-priv") != 0) {
  178.        ptr = argv[x]; ptr+=5;
  179.        if (strcasecmp(ptr, "DES") == 0)
  180.    privProtocol = SNMP_PRIVPROTOCOL_DES;
  181.        else if (strcasecmp(ptr, "3DESEDE") == 0)
  182.    privProtocol = SNMP_PRIVPROTOCOL_3DESEDE;
  183.        else if (strcasecmp(ptr, "IDEA") == 0)
  184.    privProtocol = SNMP_PRIVPROTOCOL_IDEA;
  185.        else if (strcasecmp(ptr, "AES128") == 0)
  186.    privProtocol = SNMP_PRIVPROTOCOL_AES128;
  187.        else if (strcasecmp(ptr, "AES192") == 0)
  188.    privProtocol = SNMP_PRIVPROTOCOL_AES192;
  189.        else if (strcasecmp(ptr, "AES256") == 0)
  190.    privProtocol = SNMP_PRIVPROTOCOL_AES256;
  191.        else
  192.    privProtocol = SNMP_PRIVPROTOCOL_NONE;
  193.        printf("nnPrivProt : %ldn", privProtocol);
  194.        continue;
  195.      }
  196.      if ( strstr( argv[x],"-sn")!=0) {
  197.        ptr = argv[x]; ptr+=3;
  198.        securityName = ptr;
  199.        continue;
  200.       }
  201.      if ( strstr( argv[x], "-sl")!=0) {
  202.        ptr = argv[x]; ptr+=3;
  203.        securityLevel = atoi( ptr);
  204.        if (( securityLevel < SecurityLevel_noAuthNoPriv) ||
  205.            ( securityLevel > SecurityLevel_authPriv))
  206.          securityLevel = SecurityLevel_authPriv;
  207.        continue;
  208.      }
  209.      if ( strstr( argv[x], "-sm")!=0) {
  210.        ptr = argv[x]; ptr+=3;
  211.        securityModel = atoi( ptr);
  212.        if (( securityModel < SecurityModel_v1) ||
  213.            ( securityModel > SecurityModel_USM))
  214.          securityModel = SecurityModel_USM;
  215.        continue;
  216.      }
  217.      if ( strstr( argv[x],"-cn")!=0) {
  218.        ptr = argv[x]; ptr+=3;
  219.        contextName = ptr;
  220.        continue;
  221.      }
  222.      if ( strstr( argv[x],"-ce")!=0) {
  223.        ptr = argv[x]; ptr+=3;
  224.        contextEngineID = OctetStr::from_hex_string(ptr);
  225.        continue;
  226.      }
  227.      if ( strstr( argv[x],"-ua")!=0) {
  228.        ptr = argv[x]; ptr+=3;
  229.        authPassword = ptr;
  230.        continue;
  231.      }
  232.      if ( strstr( argv[x],"-up")!=0) {
  233.        ptr = argv[x]; ptr+=3;
  234.        privPassword = ptr;
  235.        continue;
  236.      }
  237. #endif
  238.    }
  239.    //----------[ create a SNMP++ session ]-----------------------------------
  240.    int status;
  241.    // bind to any port and use IPv6 if needed
  242.    Snmp snmp(status, 0, (address.get_ip_version() == Address::version_ipv6));
  243.    if ( status != SNMP_CLASS_SUCCESS) {
  244.       cout << "SNMP++ Session Create Fail, " << snmp.error_msg(status) << "n";
  245.       return 1;
  246.    }
  247.    //---------[ init SnmpV3 ]--------------------------------------------
  248. #ifdef _SNMPv3
  249.    if (version == version3) {
  250.      char *engineId = "snmpWalk";
  251.      char *filename = "snmpv3_boot_counter";
  252.      unsigned int snmpEngineBoots = 0;
  253.      int status;
  254.      status = getBootCounter(filename, engineId, snmpEngineBoots);
  255.      if ((status != SNMPv3_OK) && (status < SNMPv3_FILEOPEN_ERROR))
  256.      {
  257.        cout << "Error loading snmpEngineBoots counter: " << status << endl;
  258.        return 1;
  259.      }
  260.      snmpEngineBoots++;
  261.      status = saveBootCounter(filename, engineId, snmpEngineBoots);
  262.      if (status != SNMPv3_OK)
  263.      {
  264.        cout << "Error saving snmpEngineBoots counter: " << status << endl;
  265.        return 1;
  266.      }
  267.      int construct_status;
  268.      v3_MP = new v3MP(engineId, snmpEngineBoots, construct_status);
  269.      USM *usm = v3_MP->get_usm();
  270.      usm->add_usm_user(securityName,
  271.        authProtocol, privProtocol,
  272.        authPassword, privPassword);
  273.    }
  274.    else
  275.    {
  276.      // MUST create a dummy v3MP object if _SNMPv3 is enabled!
  277.      int construct_status;
  278.      v3_MP = new v3MP("dummy", 0, construct_status);
  279.    }
  280. #endif
  281.    //--------[ build up SNMP++ object needed ]-------------------------------
  282.    Pdu pdu;                               // construct a Pdu object
  283.    Vb vb;                                 // construct a Vb object
  284.    vb.set_oid( oid);                      // set the Oid portion of the Vb
  285.    pdu += vb;                             // add the vb to the Pdu
  286.    address.set_port(port);
  287.    CTarget ctarget( address);             // make a target using the address
  288. #ifdef _SNMPv3
  289.    UTarget utarget( address);
  290.    if (version == version3) {
  291.      utarget.set_version( version);          // set the SNMP version SNMPV1 or V2 or V3
  292.      utarget.set_retry( retries);            // set the number of auto retries
  293.      utarget.set_timeout( timeout);          // set timeout
  294.      utarget.set_security_model( securityModel);
  295.      utarget.set_security_name( securityName);
  296.      pdu.set_security_level( securityLevel);
  297.      pdu.set_context_name (contextName);
  298.      pdu.set_context_engine_id(contextEngineID);
  299.    }
  300.    else {
  301. #endif
  302.      ctarget.set_version( version);         // set the SNMP version SNMPV1 or V2
  303.      ctarget.set_retry( retries);           // set the number of auto retries
  304.      ctarget.set_timeout( timeout);         // set timeout
  305.      ctarget.set_readcommunity( community); // set the read community name
  306. #ifdef _SNMPv3
  307.    }
  308. #endif
  309.    //-------[ issue the request, blocked mode ]-----------------------------
  310.    cout << "SNMP++ snmpWalk to " << argv[1] << " SNMPV" 
  311. #ifdef _SNMPv3
  312.         << ((version==version3) ? (version) : (version+1))
  313. #else
  314.         << (version+1)
  315. #endif
  316.         << " Retries=" << retries
  317.         << " Timeout=" << timeout * 10 <<"ms";
  318. #ifdef _SNMPv3
  319.    if (version == version3)
  320.      cout << endl
  321.           << "securityName= " << securityName.get_printable()
  322.           << ", securityLevel= " << securityLevel
  323.           << ", securityModel= " << securityModel << endl
  324.           << "contextName= " << contextName.get_printable()
  325.           << ", contextEngineID= " << contextEngineID.get_printable()
  326.           << endl;
  327.    else
  328. #endif
  329.      cout << " Community=" << community.get_printable() << endl << flush;
  330.    SnmpTarget *target;
  331. #ifdef _SNMPv3
  332.    if (version == version3)
  333.      target = &utarget;
  334.    else
  335. #endif
  336.      target = &ctarget;
  337.    while (( status = snmp.get_bulk( pdu,*target,0,BULK_MAX))== SNMP_CLASS_SUCCESS) {
  338.   requests++;
  339.   for ( int z=0;z<pdu.get_vb_count(); z++) {
  340.      pdu.get_vb( vb,z);
  341. #ifdef _SNMPv3
  342.      if (pdu.get_type() == REPORT_MSG) {
  343.        Oid tmp;
  344.        vb.get_oid(tmp);
  345.        cout << "Received a reportPdu: "
  346.     << snmp.error_msg( tmp) 
  347.     << endl
  348.     << vb.get_printable_oid() << " = "
  349.     << vb.get_printable_value() << endl;
  350.        return -5;
  351.      }
  352. #endif
  353.      Oid tmp;
  354.      vb.get_oid(tmp);
  355.      if (subtree && (oid.nCompare(oid.len(), tmp) != 0))
  356.      {
  357.  cout << "End of SUBTREE Reachedn";
  358.  cout << "Total # of Requests = " << requests << "n";
  359.  cout << "Total # of Objects  = " << objects  << "n";
  360.  return -4;
  361.      }
  362.  objects++;
  363.  // look for var bind exception, applies to v2 only   
  364.  if ( vb.get_syntax() != sNMP_SYNTAX_ENDOFMIBVIEW) {
  365.    cout << vb.get_printable_oid() << " = ";
  366.    cout << vb.get_printable_value() << "n";
  367.  }
  368.  else {
  369.    cout << "End of MIB Reachedn";
  370.    cout << "Total # of Requests = " << requests << "n";
  371.    cout << "Total # of Objects  = " << objects  << "n";
  372.    return -4;
  373.  }
  374.   }
  375.   // last vb becomes seed of next rquest
  376.   pdu.set_vblist(&vb, 1);
  377.    }
  378.    if ( status != SNMP_ERROR_NO_SUCH_NAME)
  379.      cout << "SNMP++ snmpWalk Error, " << snmp.error_msg( status) << "n";
  380.    cout << "Total # of Requests = " << requests << "n";
  381.    cout << "Total # of Objects  = " << objects  << "n";
  382.    Snmp::socket_cleanup();  // Shut down socket subsystem
  383. }