SnmpExtensionTrap

The SnmpExtensionTrap API is called by the extendible agent when it receives notification via a signaled event (event passed back in SnmpExentionInit) that a particular extension agent needs to send a trap. The API returns TRUE if has successfully initialized the arguments supplied and wishes to be called again. There are two reasons the SnmpExtensionTrap API may wish to indicate it would like to be called again. The first may be to send the same trap to multiple management stations; the second may be to give the SnmpExtensionTrap API a chance to clean up any memory allocated for VarBinds that were dynamically allocated . By keeping a static variable with state information (such as whichTime in the sample code) the API can determine whether or not it is being called to send traps or clean up after sending a trap.

In the example below the VarBind ToastUp is used to indicate that the toaster has completed toasting something or that someone has ejected the toast. Either way the trap indicates that the toaster is now ready to be reloaded or reset. Note that this VarBind allocates the memory for its name dynamically, using the SNMP_alloc API. It is important to use the SNMP_ API to alloc, realloc and free memory. Recent bugs have been found when using MSVC2.0 to build SNMP agents and managers due to conflicting run time libraries between the NT and MSVC20 run-time libraries. Using these APIs instead of the generic C run times will insure proper behavior of your app. After all the data is initialized, the routine returns true, which indicates to the extendible agent that as soon as it successfully sends the trap it should call this API again immediately. Since the state variable WhichTime is set to TRAP_CLEANUP the routine frees up the memory associated with the VarBind using the SnmpUtilVarBindFree API, resets the state variable to TRAP_GENERATION and returns FALSE, indicating to the extendible agent that no action need be taken (that is, don't send a trap, the data is not valid).

The only other notable thing about SnmpExtensionTrap is enterprise OID. This is the OID of the enterprise that is sending the trap. A single enterprise may have many traps; therefore the combination of the enterprise, genericTrap and specificTrap values constitutes a unique trap.


BOOL WINAPI SnmpExtensionTrap(
    OUT AsnObjectIdentifier *enterprise,
    OUT AsnInteger          *genericTrap,
    OUT AsnInteger          *specificTrap,
    OUT AsnTimeticks        *timeStamp,
    OUT RFC1157VarBindList  *variableBindings)
    {

    // Toast Up object 6, value 1, toast complete, value 2,
     // ejected
    static UINT OidList[]  = { 1, 3, 6, 1, 4, 1, 12, 2, 6, 0 };
    static UINT OidListLen = 10;
    static RFC1157VarBind ToastUpVarBind;

    // The following variable is used to track state info about 
    // what phase of the trap we are processing. TRAP_GENERATION
    // indicates that this phase is building the Trap PDU and
    // TRAP_CLEANUP indicates that the trap PDU has been sent and
    // We are in the process of cleaning up allocated memory for 
    // the trap

    static whichTime = TRAP_GENERATION;

    if (whichTime == TRAP_GENERATION)
    {
        whichTime = TRAP_CLEANUP;    // Supports the simulation.

        // Communicate the trap data to the Extendible Agent.
        enterprise->idLength = OidListLen;
        enterprise->ids = (UINT *)SNMP_alloc(sizeof(UINT) *                                                     7);
        memcpy(enterprise->ids, OidList, sizeof(UINT) *                                                     7);

        *genericTrap      = SNMP_GENERICTRAP_ENTERSPECIFIC;

        *specificTrap     = 0;  // the ToastUp trap

        *timeStamp        = (GetCurrentTime()/10) - dwTimeZero;

        ToastUpVarBind->name.ids = SNMP_alloc(OidListLen);
        ToastUpVarBind->name.len = OidListLen;
        memcpy(ToastUpVarBind->name.ids, OidList, OidListLen);
        ToastUpVarBind->value.type = ASN_INTEGER;
        ToastUpVarBind->value.value = ReasonUp;

        variableBindings->list = ToastUpVarBind;
        variableBindings->len  = 1;


        // Indicate that valid trap data exists in the
        // and parameters.

        return TRUE;
    }
    else
    {
        whichTime = TRAP_GENERATION;

        SnmpUtilVarBindFree(variableBindings->list);
        
        // Indicate that no more traps are available and 
        // parameters do not refer to any valid data.
        return FALSE;
    }

 } // end SnmpExtensionTrap()