home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / snmp / snmputil / snmputil.c < prev    next >
C/C++ Source or Header  |  1996-08-09  |  14KB  |  464 lines

  1. /*++ BUILD Version: 0001    // Increment this if a change has global effects
  2.  
  3. Copyright (c) 1991-1995  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     snmputil.c
  8.  
  9. Abstract:
  10.  
  11.     Sample SNMP Management API usage for Windows NT.
  12.  
  13.     This file is an example of how to code management applications using
  14.     the SNMP Management API for Windows NT.  It is similar in operation to
  15.     the other commonly available SNMP command line utilities.
  16.  
  17.     Extensive comments have been included to describe its structure and
  18.     operation.  See also "Microsoft Windows/NT SNMP Programmer's Reference".
  19.  
  20. Created:
  21.  
  22.     28-Jun-1991
  23.  
  24. Revision History:
  25.  
  26. --*/
  27.  
  28.  
  29. static char *vcsid = "@(#) $Logfile:   N:/agent/mgmtapi/vcs/snmputil.c_v  $ $Revision:   1.5  $";
  30.  
  31.  
  32. // General notes:
  33. //   Microsoft's SNMP Management API for Windows NT is implemented as a DLL
  34. // that is linked with the developer's code.  These APIs (examples follow in
  35. // this file) allow the developer's code to generate SNMP queries and receive
  36. // SNMP traps.  A simple MIB compiler and related APIs are also available to
  37. // allow conversions between OBJECT IDENTIFIERS and OBJECT DESCRIPTORS.
  38.  
  39.  
  40. // Necessary includes.
  41.  
  42. #include <windows.h>
  43.  
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <malloc.h>
  47.  
  48. #include <snmp.h>
  49. #include <mgmtapi.h>
  50.  
  51.  
  52. // Constants used in this example.
  53.  
  54. #define GET     1
  55. #define GETNEXT 2
  56. #define WALK    3
  57. #define TRAP    4
  58.  
  59. #define TIMEOUT 6000 /* milliseconds */
  60. #define RETRIES 3
  61.  
  62.  
  63. // Main program.
  64.  
  65. INT _CRTAPI1 main(
  66.     IN int  argumentCount,
  67.     IN char *argumentVector[])
  68.     {
  69.     INT                operation;
  70.     LPSTR              agent;
  71.     LPSTR              community;
  72.     RFC1157VarBindList variableBindings;
  73.     LPSNMP_MGR_SESSION session;
  74.  
  75.     INT        timeout = TIMEOUT;
  76.     INT        retries = RETRIES;
  77.  
  78.     BYTE       requestType;
  79.     AsnInteger errorStatus;
  80.     AsnInteger errorIndex;
  81.     char        *chkPtr = NULL;
  82.  
  83.  
  84.     // Parse command line arguments to determine requested operation.
  85.  
  86.     // Verify number of arguments...
  87.     if      (argumentCount < 5 && argumentCount != 2)
  88.         {
  89.         printf("Error:  Incorrect number of arguments specified.\n");
  90.         printf(
  91. "\nusage:  snmputil [get|getnext|walk] agent community oid [oid ...]\n");
  92.         printf(
  93.   "        snmputil trap\n");
  94.  
  95.         return 1;
  96.         }
  97.  
  98.     // Get/verify operation...
  99.     argumentVector++;
  100.     argumentCount--;
  101.     if      (!strcmp(*argumentVector, "get"))
  102.         operation = GET;
  103.     else if (!strcmp(*argumentVector, "getnext"))
  104.         operation = GETNEXT;
  105.     else if (!strcmp(*argumentVector, "walk"))
  106.         operation = WALK;
  107.     else if (!strcmp(*argumentVector, "trap"))
  108.         operation = TRAP;
  109.     else
  110.         {
  111.         printf("Error:  Invalid operation, '%s', specified.\n",
  112.                *argumentVector);
  113.  
  114.         return 1;
  115.         }
  116.  
  117.     if (operation != TRAP)
  118.         {
  119.         if (argumentCount < 4)
  120.             {
  121.             printf("Error:  Incorrect number of arguments specified.\n");
  122.             printf(
  123. "\nusage:  snmputil [get|getnext|walk] agent community oid [oid ...]\n");
  124.             printf(
  125.   "        snmputil trap\n");
  126.  
  127.             return 1;
  128.             }
  129.  
  130.         // Get agent address...
  131.         argumentVector++;
  132.         argumentCount--;
  133.         agent = (LPSTR)SNMP_malloc(strlen(*argumentVector) + 1);
  134.         strcpy(agent, *argumentVector);
  135.  
  136.         // Get agent community...
  137.         argumentVector++;
  138.         argumentCount--;
  139.         community = (LPSTR)SNMP_malloc(strlen(*argumentVector) + 1);
  140.         strcpy(community, *argumentVector);
  141.  
  142.         // Get oid's...
  143.         variableBindings.list = NULL;
  144.         variableBindings.len = 0;
  145.  
  146.         while(--argumentCount)
  147.             {
  148.             AsnObjectIdentifier reqObject;
  149.  
  150.             argumentVector++;
  151.  
  152.             // Convert the string representation to an internal representation.
  153.             if (!SnmpMgrStrToOid(*argumentVector, &reqObject))
  154.                 {
  155.                 printf("Error: Invalid oid, %s, specified.\n", *argumentVector);
  156.  
  157.                 return 1;
  158.                 }
  159.             else
  160.                 {
  161.                 // Since sucessfull, add to the variable bindings list.
  162.                 variableBindings.len++;
  163.                 if ((variableBindings.list = (RFC1157VarBind *)SNMP_realloc(
  164.                     variableBindings.list, sizeof(RFC1157VarBind) *
  165.                     variableBindings.len)) == NULL)
  166.                     {
  167.                     printf("Error: Error allocating oid, %s.\n",
  168.                            *argumentVector);
  169.  
  170.                     return 1;
  171.                     }
  172.  
  173.                 variableBindings.list[variableBindings.len - 1].name =
  174.                     reqObject; // NOTE!  structure copy
  175.                 variableBindings.list[variableBindings.len - 1].value.asnType =
  176.                     ASN_NULL;
  177.                 }
  178.             } // end while()
  179.  
  180.         // Make sure only one variable binding was specified if operation
  181.         // is WALK.
  182.         if (operation == WALK && variableBindings.len != 1)
  183.             {
  184.             printf("Error: Multiple oids specified for WALK.\n");
  185.  
  186.             return 1;
  187.             }
  188.  
  189.  
  190.         // Establish a SNMP session to communicate with the remote agent.  The
  191.         // community, communications timeout, and communications retry count
  192.         // for the session are also required.
  193.  
  194.         if ((session = SnmpMgrOpen(agent, community, timeout, retries)) == NULL)
  195.             {
  196.             printf("error on SnmpMgrOpen %d\n", GetLastError());
  197.  
  198.             return 1;
  199.             }
  200.  
  201.         } // end if(TRAP)
  202.  
  203.  
  204.     // Determine and perform the requested operation.
  205.  
  206.     if      (operation == GET || operation == GETNEXT)
  207.         {
  208.         // Get and GetNext are relatively simple operations to perform.
  209.         // Simply initiate the request and process the result and/or
  210.         // possible error conditions.
  211.  
  212.  
  213.         if (operation == GET)
  214.             requestType = ASN_RFC1157_GETREQUEST;
  215.         else
  216.             requestType = ASN_RFC1157_GETNEXTREQUEST;
  217.  
  218.  
  219.         // Request that the API carry out the desired operation.
  220.  
  221.         if (!SnmpMgrRequest(session, requestType, &variableBindings,
  222.                             &errorStatus, &errorIndex))
  223.             {
  224.             // The API is indicating an error.
  225.  
  226.             printf("error on SnmpMgrRequest %d\n", GetLastError());
  227.             }
  228.         else
  229.             {
  230.             // The API succeeded, errors may be indicated from the remote
  231.             // agent.
  232.  
  233.             if (errorStatus > 0)
  234.                 {
  235.                 printf("Error: errorStatus=%d, errorIndex=%d\n",
  236.                        errorStatus, errorIndex);
  237.                 }
  238.             else
  239.                 {
  240.                 // Display the resulting variable bindings.
  241.  
  242.                 UINT i;
  243.                 char *string = NULL;
  244.  
  245.                 for(i=0; i < variableBindings.len; i++)
  246.                     {
  247.                     SnmpMgrOidToStr(&variableBindings.list[i].name, &string);
  248.                     printf("Variable = %s\n", string);
  249.                     if (string) SNMP_free(string);
  250.  
  251.                     printf("Value    = ");
  252.                     SnmpUtilPrintAsnAny(&variableBindings.list[i].value);
  253.  
  254.                     printf("\n");
  255.                     } // end for()
  256.                 }
  257.             }
  258.  
  259.  
  260.         // Free the variable bindings that have been allocated.
  261.  
  262.         SnmpUtilVarBindListFree(&variableBindings);
  263.  
  264.  
  265.         }
  266.     else if (operation == WALK)
  267.         {
  268.         // Walk is a common term used to indicate that all MIB variables
  269.         // under a given OID are to be traversed and displayed.  This is
  270.         // a more complex operation requiring tests and looping in addition
  271.         // to the steps for get/getnext above.
  272.  
  273.  
  274.         AsnObjectIdentifier root;
  275.         AsnObjectIdentifier tempOid;
  276.  
  277.  
  278.         SnmpUtilOidCpy(&root, &variableBindings.list[0].name);
  279.  
  280.         requestType = ASN_RFC1157_GETNEXTREQUEST;
  281.  
  282.  
  283.         while(1)
  284.             {
  285.             if (!SnmpMgrRequest(session, requestType, &variableBindings,
  286.                                 &errorStatus, &errorIndex))
  287.                 {
  288.                 // The API is indicating an error.
  289.  
  290.                 printf("error on SnmpMgrRequest %d\n", GetLastError());
  291.  
  292.                 break;
  293.                 }
  294.             else
  295.                 {
  296.                 // The API succeeded, errors may be indicated from the remote
  297.                 // agent.
  298.  
  299.  
  300.                 // Test for end of subtree or end of MIB.
  301.  
  302.                 if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
  303.                     SnmpUtilOidNCmp(&variableBindings.list[0].name,
  304.                                     &root, root.idLength))
  305.                     {
  306.                     printf("End of MIB subtree.\n\n");
  307.  
  308.                     break;
  309.                     }
  310.  
  311.  
  312.                 // Test for general error conditions or sucesss.
  313.  
  314.                 if (errorStatus > 0)
  315.                     {
  316.                     printf("Error: errorStatus=%d, errorIndex=%d \n",
  317.                            errorStatus, errorIndex);
  318.  
  319.                     break;
  320.                     }
  321.                 else
  322.                     {
  323.                     // Display resulting variable binding for this iteration.
  324.  
  325.                     char *string = NULL;
  326.  
  327.                     SnmpMgrOidToStr(&variableBindings.list[0].name, &string);
  328.                     printf("Variable = %s\n", string);
  329.                     if (string) SNMP_free(string);
  330.  
  331.                     printf("Value    = ");
  332.                     SnmpUtilPrintAsnAny(&variableBindings.list[0].value);
  333.  
  334.                     printf("\n");
  335.                     }
  336.                 } // end if()
  337.  
  338.  
  339.             // Prepare for the next iteration.  Make sure returned oid is
  340.             // preserved and the returned value is freed.
  341.  
  342.             SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name);
  343.  
  344.             SnmpUtilVarBindFree(&variableBindings.list[0]);
  345.  
  346.             SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid);
  347.             variableBindings.list[0].value.asnType = ASN_NULL;
  348.  
  349.             SnmpUtilOidFree(&tempOid);
  350.  
  351.             } // end while()
  352.  
  353.  
  354.         // Free the variable bindings that have been allocated.
  355.  
  356.         SnmpUtilVarBindListFree(&variableBindings);
  357.  
  358.         SnmpUtilOidFree(&root);
  359.  
  360.  
  361.         }
  362.     else if (operation == TRAP)
  363.         {
  364.         // Trap handling can be done two different ways: event driven or
  365.         // polled.  The following code illustrates the steps to use event
  366.         // driven trap reception in a management application.
  367.  
  368.  
  369.         HANDLE hNewTraps = NULL;
  370.  
  371.  
  372.         if (!SnmpMgrTrapListen(&hNewTraps))
  373.             {
  374.             printf("error on SnmpMgrTrapListen %d\n", GetLastError());
  375.             }
  376.         else
  377.             {
  378.             printf("snmputil: listening for traps...\n");
  379.             }
  380.  
  381.  
  382.         while(1)
  383.             {
  384.             DWORD dwResult;
  385.  
  386.             if ((dwResult = WaitForSingleObject(hNewTraps, 0xffffffff))
  387.                 == 0xffffffff)
  388.                 {
  389.                 printf("error on WaitForSingleObject %d\n",
  390.                        GetLastError());
  391.                 }
  392.             else if (!ResetEvent(hNewTraps))
  393.                 {
  394.                 printf("error on ResetEvent %d\n", GetLastError());
  395.                 }
  396.             else
  397.                 {
  398.                 AsnObjectIdentifier enterprise;
  399.                 AsnNetworkAddress   IPAddress;
  400.                 AsnInteger          genericTrap;
  401.                 AsnInteger          specificTrap;
  402.                 AsnTimeticks        timeStamp;
  403.                 RFC1157VarBindList  variableBindings;
  404.  
  405.                 UINT i;
  406.                 char *string = NULL;
  407.  
  408.                 while(SnmpMgrGetTrap(&enterprise, &IPAddress, &genericTrap,
  409.                                      &specificTrap, &timeStamp, &variableBindings))
  410.                     {
  411.                     printf("snmputil: trap generic=%d specific=%d\n",
  412.                            genericTrap, specificTrap);
  413.                     if (IPAddress.length == 4) {
  414.                         printf("  from -> %d.%d.%d.%d\n",
  415.                              (int)IPAddress.stream[0], (int)IPAddress.stream[1],
  416.                              (int)IPAddress.stream[2], (int)IPAddress.stream[3]);
  417.  
  418.                     }
  419.                     if (IPAddress.dynamic) {
  420.                         SNMP_free(IPAddress.stream);
  421.                     }
  422.  
  423.                     for(i=0; i < variableBindings.len; i++)
  424.                         {
  425.                         SnmpMgrOidToStr(&variableBindings.list[i].name, &string);
  426.                         printf("Variable = %s\n", string);
  427.                         if (string) SNMP_free(string);
  428.  
  429.                         printf("Value    = ");
  430.                         SnmpUtilPrintAsnAny(&variableBindings.list[i].value);
  431.                         } // end for()
  432.                     printf("\n");
  433.  
  434.  
  435.                     SnmpUtilOidFree(&enterprise);
  436.  
  437.                     SnmpUtilVarBindListFree(&variableBindings);
  438.                     }
  439.                 }
  440.             } // end while()
  441.  
  442.  
  443.         } // end if(operation)
  444.  
  445.  
  446.     if (operation != TRAP)
  447.         {
  448.         // Close SNMP session with the remote agent.
  449.  
  450.         if (!SnmpMgrClose(session))
  451.             {
  452.             printf("error on SnmpMgrClose %d\n", GetLastError());
  453.  
  454.             return 1;
  455.             }
  456.         }
  457.  
  458.  
  459.     // Let the command interpreter know things went ok.
  460.  
  461.     return 0;
  462.  
  463.     } // end main()
  464.