SnmpExtensionQuery is the API that the extendible agent will call when it determines that the OID of an SNMP request matches the supportedView OID that the extension agent DLL returned from SnmpExtensionInit.
The requestType argument indicates what type of SNMP request is being processed. The possible requestTypes are:
The routine ResolveVarBind is responsible for carrying out the actual setting or retrieving of the VarBind data. Since the DLL is capable of handling a VarBindList, multiple objects could be modified in a single request. SNMP requires that if an agent is not successful in carrying out all operation in a single PDU, then it should not carry out any. Because of this all-or-nothing requirement, the ResolveVarBind routine only modifies cached data. The Toaster SnmpExtensionQuery routine checks to make sure that the errorStatus argument is set to SNMP_ERRORSTATUS_NOERROR and, if so, it calls ActionCaches with the TOASTER_COMMIT value to take the cached data and commit it. This is an important detail to keep in mind. Many SNMP management scenarios depend on this concept to tell if an action taken was successfully accomplished. If an error was detected, calling Action Caches with the argument TOASTER_CLEAR throws away the temporarily cached data.
The second thing to note in this routine is the handling of the case of a GETNEXT request falling beyond the end of the MIB view that this DLL supports. Note that the routine checks for the error status SNMP_ERRORSTATUS_NOSUCHNAME returned from ResolveVarBind and, if it finds this to be true, will change the OID of the VarBind passed in, to a point just beyond the view of the current DLL and indicate no error. The extendible agent will check for this condition and process the request accordingly.
BOOL WINAPI SnmpExtensionQuery( IN BYTE requestType, IN OUT RFC1157VarBindList *variableBindings, OUT AsnInteger *errorStatus, OUT AsnInteger *errorIndex) { UINT I; // Iterate through the variable bindings list to resolve // individual variable bindings. for ( I=0;I < variableBindings->len;I++ ) { *errorStatus = ResolveVarBind( &variableBindings->list[I], requestType ); // Test and handle case where Get Next past end of MIB // view supported by this Extension Agent occurs. // Special processing is required to communicate this // situation to the Extendible Agent so it can take // appropriate action, possibly querying other Extension // Agents. if ( *errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME && requestType == MIB_ACTION_GETNEXT ) { *errorStatus = SNMP_ERRORSTATUS_NOERROR; // Modify variable binding of such variables so the // OID points just outside the MIB view supported by // this Extension Agent.The Extendible Agent tests // for this, and takes appropriate action. SNMP_oidfree( &variableBindings->list[I].name ); SNMP_oidcpy( &variableBindings->list[I].name, &MIB_OidPrefix ); variableBindings->list[I].name.ids[MIB_PREFIX_LEN-1]++; } // If an error was indicated, communicate error status // and error index to the Extendible Agent. The // Extendible Agent will ensurethat the origional // variable bindings are returned in the response // packet. if ( *errorStatus != SNMP_ERRORSTATUS_NOERROR ) { *errorIndex = I+1; break; } } if (*errorStatus == SNMP_ERRORSTATUS_NOERROR) ActionCaches(TOASTER_COMMIT); else ActionCaches(TOASTER_CLEAR); // Indicate that Extension Agent processing was sucessfull. return TRUE; } // end SnmpExtensionQuery()