TESTMIB.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:18k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*++ BUILD Version: 0001    // Increment this if a change has global effects
  2. Copyright (c) 1992-1996  Microsoft Corporation
  3. Module Name:
  4.     testmib.c
  5. Abstract:
  6.     Sample SNMP Extension Agent for Windows NT.
  7.     These files (testdll.c, testmib.c, and testmib.h) provide an example of 
  8.     how to structure an Extension Agent DLL which works in conjunction with 
  9.     the SNMP Extendible Agent for Windows NT.
  10.     Extensive comments have been included to describe its structure and
  11.     operation.  See also "Microsoft Windows NT SNMP Programmer's Reference".
  12. --*/
  13. // This Extension Agent implements the Internet toaster MIB.  It's 
  14. // definition follows here:
  15. //
  16. //
  17. //         TOASTER-MIB DEFINITIONS ::= BEGIN
  18. //
  19. //         IMPORTS
  20. //                 enterprises
  21. //                         FROM RFC1155-SMI
  22. //                 OBJECT-TYPE
  23. //                         FROM RFC-1212
  24. //                 DisplayString
  25. //                         FROM RFC-1213;
  26. //
  27. //         epilogue        OBJECT IDENTIFIER ::= { enterprises 12 }
  28. //         toaster         OBJECT IDENTIFIER ::= { epilogue 2 }
  29. //
  30. //         -- toaster MIB
  31. //
  32. //         toasterManufacturer OBJECT-TYPE
  33. //             SYNTAX  DisplayString
  34. //             ACCESS  read-only
  35. //             STATUS  mandatory
  36. //             DESCRIPTION
  37. //                     "The name of the toaster's manufacturer. For instance,
  38. //                      Sunbeam."
  39. //             ::= { toaster 1 }
  40. //
  41. //         toasterModelNumber OBJECT-TYPE
  42. //             SYNTAX  DisplayString
  43. //             ACCESS  read-only
  44. //             STATUS  mandatory
  45. //             DESCRIPTION
  46. //                     "The name of the toaster's model. For instance,
  47. //                      Radiant Automatic."
  48. //             ::= { toaster 2 }
  49. //
  50. //         toasterControl OBJECT-TYPE
  51. //             SYNTAX  INTEGER  {
  52. //                         up(1),
  53. //                         down(2)
  54. //                     }
  55. //             ACCESS  read-write
  56. //             STATUS  mandatory
  57. //             DESCRIPTION
  58. //                     "This variable controls the current state of the 
  59. //                      toaster. To begin toasting, set it to down(2). To 
  60. //                      abort toasting (perhaps in the event of an 
  61. //                      emergency), set it to up(2)."
  62. //             ::= { toaster 3 }
  63. //
  64. //         toasterDoneness OBJECT-TYPE
  65. //             SYNTAX  INTEGER (1..10)
  66. //             ACCESS  read-write
  67. //             STATUS  mandatory
  68. //             DESCRIPTION
  69. //                     "This variable controls how well done ensuing toast 
  70. //                      should be on a scale of 1 to 10. Toast made at 10 
  71. //                      is generally considered unfit for human consumption; 
  72. //                      toast made at 1 is lightly warmed."
  73. //             ::= { toaster 4 }
  74. //
  75. //         toasterToastType OBJECT-TYPE
  76. //             SYNTAX  INTEGER  {
  77. //                         white-bread(1),
  78. //                         wheat-bread(2),
  79. //                         wonder-bread(3),
  80. //                         frozen-waffle(4),
  81. //                         frozen-bagel(5),
  82. //                         hash-brown(6),
  83. //                         other(7)
  84. //                     }
  85. //             ACCESS  read-write
  86. //             STATUS  mandatory
  87. //             DESCRIPTION
  88. //                     "This variable informs the toaster of the type of 
  89. //                      material being toasted. The toaster uses this 
  90. //                      information combined with toasterToastDoneness to 
  91. //                      compute how long the material must be toasted for 
  92. //                      to achieve the desired doneness."
  93. //             ::= { toaster 5 }
  94. //
  95. //         END
  96. // Necessary includes.
  97. #include <windows.h>
  98. #include <snmp.h>
  99. // Contains definitions for the table structure describing the MIB.  This
  100. // is used in conjunction with testmib.c where the MIB requests are resolved.
  101. #include "testmib.h"
  102. // If an addition or deletion to the MIB is necessary, there are several
  103. // places in the code that must be checked and possibly changed.
  104. //
  105. // The last field in each MIB entry is used to point to the NEXT
  106. // leaf variable.  If an addition or deletetion is made, these pointers
  107. // may need to be updated to reflect the modification.
  108. // The prefix to all of these MIB variables is 1.3.6.1.4.1.12
  109. UINT OID_Prefix[] = { 1, 3, 6, 1, 4, 1, 12 };
  110. AsnObjectIdentifier MIB_OidPrefix = { OID_SIZEOF(OID_Prefix), OID_Prefix };
  111. //                         //
  112. // OID definitions for MIB //
  113. //                         //
  114. // Definition of the toaster group
  115. UINT MIB_toaster[]  = { 2 };
  116. // Definition of leaf variables under the toaster group
  117. // All leaf variables have a zero appended to their OID to indicate
  118. // that it is the only instance of this variable and it exists.
  119. UINT MIB_toasterManufacturer[]     = { 2, 1, 0 };
  120. UINT MIB_toasterModelNumber[]      = { 2, 2, 0 };
  121. UINT MIB_toasterControl[]          = { 2, 3, 0 };
  122. UINT MIB_toasterDoneness[]         = { 2, 4, 0 };
  123. UINT MIB_toasterToastType[]        = { 2, 5, 0 };
  124. //                             //
  125. // Storage definitions for MIB //
  126. //                             //
  127. char       MIB_toasterManStor[]     = "Microsoft Corporation";
  128. char       MIB_toasterModelStor[]   = 
  129.                "Example SNMP Extension Agent for Windows/NT (TOASTER-MIB).";
  130. AsnInteger MIB_toasterControlStor   = 1;
  131. AsnInteger MIB_toasterDonenessStor  = 2;
  132. AsnInteger MIB_toasterToastTypeStor = 3;
  133. // MIB definiton
  134. MIB_ENTRY Mib[] = {
  135.       { { OID_SIZEOF(MIB_toasterManufacturer), MIB_toasterManufacturer },
  136.         &MIB_toasterManStor, ASN_RFC1213_DISPSTRING,
  137.         MIB_ACCESS_READ, MIB_leaf_func, &Mib[1] },
  138.       { { OID_SIZEOF(MIB_toasterModelNumber), MIB_toasterModelNumber },
  139.         &MIB_toasterModelStor, ASN_RFC1213_DISPSTRING,
  140.         MIB_ACCESS_READ, MIB_leaf_func, &Mib[2] },
  141.       { { OID_SIZEOF(MIB_toasterControl), MIB_toasterControl },
  142.         &MIB_toasterControlStor, ASN_INTEGER,
  143.         MIB_ACCESS_READWRITE, MIB_control_func, &Mib[3] },
  144.       { { OID_SIZEOF(MIB_toasterDoneness), MIB_toasterDoneness },
  145.         &MIB_toasterDonenessStor, ASN_INTEGER,
  146.         MIB_ACCESS_READWRITE, MIB_doneness_func, &Mib[4] },
  147.       { { OID_SIZEOF(MIB_toasterToastType), MIB_toasterToastType },
  148.         &MIB_toasterToastTypeStor, ASN_INTEGER,
  149.         MIB_ACCESS_READWRITE, MIB_toasttype_func, NULL }
  150.       };
  151. UINT MIB_num_variables = sizeof Mib / sizeof( MIB_ENTRY );
  152. //
  153. // ResolveVarBind
  154. //    Resolves a single variable binding.  Modifies the variable on a GET
  155. //    or a GET-NEXT.
  156. //
  157. // Notes:
  158. //
  159. // Return Codes:
  160. //    Standard PDU error codes.
  161. //
  162. // Error Codes:
  163. //    None.
  164. //
  165. UINT ResolveVarBind(
  166.         IN OUT RFC1157VarBind *VarBind, // Variable Binding to resolve
  167. IN UINT PduAction               // Action specified in PDU
  168. )
  169. {
  170. MIB_ENTRY            *MibPtr;
  171. AsnObjectIdentifier  TempOid;
  172. int                  CompResult;
  173. UINT                 I;
  174. UINT                 nResult;
  175.    // Search for var bind name in the MIB
  176.    I      = 0;
  177.    MibPtr = NULL;
  178.    while ( MibPtr == NULL && I < MIB_num_variables )
  179.       {
  180.       // Construct OID with complete prefix for comparison purposes
  181.       SnmpUtilOidCpy( &TempOid, &MIB_OidPrefix );
  182.       SnmpUtilOidAppend( &TempOid, &Mib[I].Oid );
  183.       // Check for OID in MIB - On a GET-NEXT the OID does not have to exactly
  184.       // match a variable in the MIB, it must only fall under the MIB root.
  185.       CompResult = SnmpUtilOidCmp( &VarBind->name, &TempOid );
  186.       if ( 0 > CompResult )
  187.  {
  188.  // Since there is not an exact match, the only valid action is GET-NEXT
  189.  if ( MIB_ACTION_GETNEXT != PduAction )
  190.     {
  191.     nResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  192.     goto Exit;
  193.     }
  194.  // Since the match was not exact, but var bind name is within MIB,
  195.  // we are at the NEXT MIB variable down from the one specified.
  196.  PduAction = MIB_ACTION_GET;
  197.  MibPtr = &Mib[I];
  198.          // Replace var bind name with new name
  199.          SnmpUtilOidFree( &VarBind->name );
  200.          SnmpUtilOidCpy( &VarBind->name, &MIB_OidPrefix );
  201.          SnmpUtilOidAppend( &VarBind->name, &MibPtr->Oid );
  202.  }
  203.       else
  204.          {
  205.  // An exact match was found.
  206.          if ( 0 == CompResult )
  207.             {
  208.     MibPtr = &Mib[I];
  209.     }
  210.  }
  211.       // Free OID memory before checking another variable
  212.       SnmpUtilOidFree( &TempOid );
  213.       I++;
  214.       } // while
  215.    // If OID not within scope of MIB, then no such name
  216.    if ( MibPtr == NULL )
  217.       {
  218.       nResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  219.       goto Exit;
  220.       }
  221.    // Call function to process request.  Each MIB entry has a function pointer
  222.    // that knows how to process its MIB variable.
  223.    nResult = (*MibPtr->MibFunc)( PduAction, MibPtr, VarBind );
  224.    // Free temp memory
  225.    SnmpUtilOidFree( &TempOid );
  226. Exit:
  227.    return nResult;
  228. } // ResolveVarBind
  229. //
  230. // MIB_leaf_func
  231. //    Performs generic actions on LEAF variables in the MIB.
  232. //
  233. // Notes:
  234. //
  235. // Return Codes:
  236. //    Standard PDU error codes.
  237. //
  238. // Error Codes:
  239. //    None.
  240. //
  241. UINT MIB_leaf_func(
  242.         IN UINT Action,
  243. IN MIB_ENTRY *MibPtr,
  244. IN RFC1157VarBind *VarBind
  245. )
  246. {
  247. UINT   ErrStat;
  248.    switch ( Action )
  249.       {
  250.       case MIB_ACTION_GETNEXT:
  251.  // If there is no GET-NEXT pointer, this is the end of this MIB
  252.  if ( MibPtr->MibNext == NULL )
  253.     {
  254.     ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  255.     goto Exit;
  256.     }
  257.          // Setup var bind name of NEXT MIB variable
  258.          SnmpUtilOidFree( &VarBind->name );
  259.          SnmpUtilOidCpy( &VarBind->name, &MIB_OidPrefix );
  260.          SnmpUtilOidAppend( &VarBind->name, &MibPtr->MibNext->Oid );
  261.          // Call function to process request.  Each MIB entry has a function
  262.  // pointer that knows how to process its MIB variable.
  263.          ErrStat = (*MibPtr->MibNext->MibFunc)( MIB_ACTION_GET,
  264.                                         MibPtr->MibNext, VarBind );
  265.          break;
  266.       case MIB_ACTION_GET:
  267.          // Make sure that this variable's ACCESS is GET'able
  268.  if ( MibPtr->Access != MIB_ACCESS_READ &&
  269.       MibPtr->Access != MIB_ACCESS_READWRITE )
  270.     {
  271.     ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  272.     goto Exit;
  273.     }
  274.  // Setup varbind's return value
  275.  VarBind->value.asnType = MibPtr->Type;
  276.  switch ( VarBind->value.asnType )
  277.     {
  278.             case ASN_RFC1155_COUNTER:
  279.             case ASN_RFC1155_GAUGE:
  280.             case ASN_INTEGER:
  281.                VarBind->value.asnValue.number = *(AsnInteger *)(MibPtr->Storage);
  282.        break;
  283.             case ASN_OCTETSTRING: // This entails ASN_RFC1213_DISPSTRING also
  284.        VarBind->value.asnValue.string.length =
  285.                                  strlen( (LPSTR)MibPtr->Storage );
  286.        if ( NULL == 
  287.                     (VarBind->value.asnValue.string.stream =
  288.                     SnmpUtilMemAlloc(VarBind->value.asnValue.string.length *
  289.                            sizeof(char))) )
  290.           {
  291.           ErrStat = SNMP_ERRORSTATUS_GENERR;
  292.           goto Exit;
  293.           }
  294.        memcpy( VarBind->value.asnValue.string.stream,
  295.                (LPSTR)MibPtr->Storage,
  296.                VarBind->value.asnValue.string.length );
  297.        VarBind->value.asnValue.string.dynamic = TRUE;
  298.        break;
  299.     default:
  300.        ErrStat = SNMP_ERRORSTATUS_GENERR;
  301.        goto Exit;
  302.     }
  303.  break;
  304.       case MIB_ACTION_SET:
  305.          // Make sure that this variable's ACCESS is SET'able
  306.  if ( MibPtr->Access != MIB_ACCESS_READWRITE &&
  307.       MibPtr->Access != MIB_ACCESS_WRITE )
  308.     {
  309.     ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  310.             goto Exit;
  311.     }
  312.          // Check for proper type before setting
  313.          if ( MibPtr->Type != VarBind->value.asnType )
  314.     {
  315.     ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  316.     goto Exit;
  317.     }
  318.  // Save value in MIB
  319.  switch ( VarBind->value.asnType )
  320.     {
  321.             case ASN_RFC1155_COUNTER:
  322.             case ASN_RFC1155_GAUGE:
  323.             case ASN_INTEGER:
  324.                *(AsnInteger *)(MibPtr->Storage) = VarBind->value.asnValue.number;
  325.        break;
  326.             case ASN_OCTETSTRING: // This entails ASN_RFC1213_DISPSTRING also
  327.                // The storage must be adequate to contain the new string
  328.                // including a NULL terminator.
  329.                memcpy( (LPSTR)MibPtr->Storage,
  330.                        VarBind->value.asnValue.string.stream,
  331.                        VarBind->value.asnValue.string.length );
  332.        ((LPSTR)MibPtr->Storage)[VarBind->value.asnValue.string.length] =
  333.                                                                           '';
  334.        break;
  335.     default:
  336.        ErrStat = SNMP_ERRORSTATUS_GENERR;
  337.        goto Exit;
  338.     }
  339.          break;
  340.       default:
  341.  ErrStat = SNMP_ERRORSTATUS_GENERR;
  342.  goto Exit;
  343.       } // switch
  344.    // Signal no error occurred
  345.    ErrStat = SNMP_ERRORSTATUS_NOERROR;
  346. Exit:
  347.    return ErrStat;
  348. } // MIB_leaf_func
  349. //
  350. // MIB_control_func
  351. //    Performs specific actions on the toasterControl MIB variable
  352. //
  353. // Notes:
  354. //
  355. // Return Codes:
  356. //    Standard PDU error codes.
  357. //
  358. // Error Codes:
  359. //    None.
  360. //
  361. UINT MIB_control_func(
  362.         IN UINT Action,
  363. IN MIB_ENTRY *MibPtr,
  364. IN RFC1157VarBind *VarBind
  365. )
  366. {
  367. UINT   ErrStat;
  368.    switch ( Action )
  369.       {
  370.       case MIB_ACTION_SET:
  371.          // Make sure that this variable's ACCESS is SET'able
  372.  if ( MibPtr->Access != MIB_ACCESS_READWRITE &&
  373.       MibPtr->Access != MIB_ACCESS_WRITE )
  374.     {
  375.     ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  376.             goto Exit;
  377.     }
  378.          // Check for proper type before setting
  379.          if ( MibPtr->Type != VarBind->value.asnType )
  380.     {
  381.     ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  382.     goto Exit;
  383.     }
  384.          // Make sure the value is valid
  385.          if ( MIB_TOASTER_UP > VarBind->value.asnValue.number ||
  386.               MIB_TOASTER_DOWN < VarBind->value.asnValue.number )
  387.             {
  388.     ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  389.     goto Exit;
  390.             }
  391.          // Let fall through purposefully for further processing by
  392.          // generic leaf function.
  393.       case MIB_ACTION_GETNEXT:
  394.       case MIB_ACTION_GET:
  395.  // Call the more generic function to perform the action
  396.          ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  397.          break;
  398.       default:
  399.  ErrStat = SNMP_ERRORSTATUS_GENERR;
  400.  goto Exit;
  401.       } // switch
  402. Exit:
  403.    return ErrStat;
  404. } // MIB_control_func
  405. //
  406. // MIB_doneness_func
  407. //    Performs specific actions on the toasterDoneness MIB variable
  408. //
  409. // Notes:
  410. //
  411. // Return Codes:
  412. //    Standard PDU error codes.
  413. //
  414. // Error Codes:
  415. //    None.
  416. //
  417. UINT MIB_doneness_func(
  418.         IN UINT Action,
  419. IN MIB_ENTRY *MibPtr,
  420. IN RFC1157VarBind *VarBind
  421. )
  422. {
  423. UINT   ErrStat;
  424.    switch ( Action )
  425.       {
  426.       case MIB_ACTION_SET:
  427.          // Make sure that this variable's ACCESS is SET'able
  428.  if ( MibPtr->Access != MIB_ACCESS_READWRITE &&
  429.       MibPtr->Access != MIB_ACCESS_WRITE )
  430.     {
  431.     ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  432.             goto Exit;
  433.     }
  434.          // Check for proper type before setting
  435.          if ( MibPtr->Type != VarBind->value.asnType )
  436.     {
  437.     ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  438.     goto Exit;
  439.     }
  440.          // Make sure the value is valid
  441.          if ( MIB_TOASTER_LIGHTLYWARM > VarBind->value.asnValue.number ||
  442.               MIB_TOASTER_BURNT < VarBind->value.asnValue.number )
  443.             {
  444.     ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  445.     goto Exit;
  446.             }
  447.          // Let fall through purposefully for further processing by
  448.          // generic leaf function.
  449.       case MIB_ACTION_GETNEXT:
  450.       case MIB_ACTION_GET:
  451.  // Call the more generic function to perform the action
  452.          ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  453.          break;
  454.       default:
  455.  ErrStat = SNMP_ERRORSTATUS_GENERR;
  456.  goto Exit;
  457.       } // switch
  458. Exit:
  459.    return ErrStat;
  460. } // MIB_doneness_func
  461. //
  462. // MIB_toasttype_func
  463. //    Performs specific actions on the toasterToastType MIB variable
  464. //
  465. // Notes:
  466. //
  467. // Return Codes:
  468. //    Standard PDU error codes.
  469. //
  470. // Error Codes:
  471. //    None.
  472. //
  473. UINT MIB_toasttype_func(
  474.         IN UINT Action,
  475. IN MIB_ENTRY *MibPtr,
  476. IN RFC1157VarBind *VarBind
  477. )
  478. {
  479. UINT   ErrStat;
  480.    switch ( Action )
  481.       {
  482.       case MIB_ACTION_SET:
  483.          // Make sure that this variable's ACCESS is SET'able
  484.  if ( MibPtr->Access != MIB_ACCESS_READWRITE &&
  485.       MibPtr->Access != MIB_ACCESS_WRITE )
  486.     {
  487.     ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  488.             goto Exit;
  489.     }
  490.          // Check for proper type before setting
  491.          if ( MibPtr->Type != VarBind->value.asnType )
  492.     {
  493.     ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  494.     goto Exit;
  495.     }
  496.          // Make sure the value is valid
  497.          if ( MIB_TOASTER_WHITEBREAD > VarBind->value.asnValue.number ||
  498.               MIB_TOASTER_OTHERBREAD < VarBind->value.asnValue.number )
  499.             {
  500.     ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  501.     goto Exit;
  502.             }
  503.          // Let fall through purposefully for further processing by
  504.          // generic leaf function.
  505.       case MIB_ACTION_GETNEXT:
  506.       case MIB_ACTION_GET:
  507.  // Call the more generic function to perform the action
  508.          ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  509.          break;
  510.       default:
  511.  ErrStat = SNMP_ERRORSTATUS_GENERR;
  512.  goto Exit;
  513.       } // switch
  514. Exit:
  515.    return ErrStat;
  516. } // MIB_toasttype_func