/*
*
* U.S. Government Rights - Commercial software. Government users are subject
* to the Sun Microsystems, Inc. standard license agreement and applicable
* provisions of the FAR and its supplements.
*
*
* This distribution may include materials developed by third parties. Sun,
* Sun Microsystems, the Sun logo and Solaris are trademarks or registered
* trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
*
*/
/* @example demo_module_9.c
*
*
* This example demonstrates how to implement objects that normally would
* block the agent as it waits for external events in such a way that the
* agent can continue responding to other requests while this implementation waits.
*
* This example uses the following features of SMA:
*
* - Use of the instance helper, which registers an exact OID such that GENEXT requests
* are handled entirely by the helper.
*
* - Setting the delegated member of the requests structure to 1 to indicate to the
* agent that this request should be delayed. The agent queues this request
* to be handled later and then is available to handle other requests. The
* agent is not blocked by this request.
*
* - Registering an SNMP alarm to update the results at a later time.
*
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include "demo_module_9.h"
// default delay time for SNMP alarm
void
init_demo_module_9(void)
{
{ 1, 3, 6, 1, 4, 1,42, 2, 2, 4, 4, 9, 1, 1, 0 };
/*
* Creates a registration handler, my_test, and passes
* the pointer it returns to the netsnmp_register_instance
* helper function.
*/
my_test =
netsnmp_create_handler_registration("delayed_instance_example",
}
int
{
/*
This handler is called to handle SNMP GET and SNMP SET
requests for the my_delayed_oid object. If it is called to
handle SNMP GET requests, the handler does not need to
handle a GETNEXT if it is registered as an instance handler.
Instance handlers only deliver one request at a time, so we
do not need to loop over a list of requests. */
/*
* here we merely mention that we'll answer this request
* later. we don't actually care about the mode type in this
* example, but for certain cases you may, so I'll leave in the
* otherwise useless switch and case statements
*/
default:
/*
* Mark this variable as something that cannot be handled now
* by setting the delegated member of the requests structure
* to 1. The agent queues the request to be handled at a later
* time and continues responding to other client requests.
*
*/
/*
* Register an alarm to update the results at a later
* time. Normally, we might have to query something else
* (like an external request sent to a different network
* or system socket, etc), but for this example we'll do
* something really simply and just insert an alarm for a
* certain period of time.
*/
delay_time));
0, /* dont repeat. */
return_delayed_response, /* the function
* to call */
/*
* Create a "cache" of useful
* information that can be retrieved
* at a later time. This argument is
* passed back to the module in the callback
* function for an alarm.
*/
(void *)
NULL));
break;
}
return SNMP_ERR_NOERROR;
}
void
{
/*
* Extract the cache from the passed argument.
*/
/*
* Make sure the cache created earlier is still
* valid. If not, the request timed out for some reason and we
* do not need to keep processing things. Should never happen, but
* this double checks.
*/
if (!cache) {
return;
}
/*
* Re-establish the previous pointers,
*/
DEBUGMSGTL(("demo_module_9",
"continuing delayed request, mode = %d\n",
/*
* Set delegated to zero to indicate that the request is no longer
* delegated and answer the query.
*/
/*
* Registering as an instance means we do not need to deal with
* GETNEXT processing, so we do not handle it here at all.
*
* However, since the instance handler already reset the mode
* back to GETNEXT from the GET mode, we need to do the
* same thing in both cases.
*
*/
case MODE_GET:
case MODE_GETNEXT:
/*
* Return the current delay time
*/
(u_char *) & delay_time,
sizeof(delay_time));
DEBUGMSGTL(("demo_module_9",
"Got delay time = %d\n",
delay_time));
break;
case MODE_SET_RESERVE1:
/*
* check type
*/
/*
* If not an integer, return SNMP error.
*/
/*
* Free cache. It is no longer needed.
*/
return;
}
break;
case MODE_SET_RESERVE2:
/*
* Store old value for UNDO support in the future.
*/
/*
* malloc failed
*/
if (delay_time_cache == NULL) {
return;
}
/*
* Add our temporary information to the request itself.
* This is then retrivable later. The free function
* passed auto-frees it when the request is later
* deleted.
*/
delay_time_cache, free));
break;
case MODE_SET_ACTION:
/*
* Update current value.
*/
delay_time));
break;
case MODE_SET_UNDO:
/*
* A failure occurred. Reset to the
* previously value by extracting the previosuly
* stored information from the request.
*/
break;
case MODE_SET_COMMIT:
case MODE_SET_FREE:
/*
* The only thing to do here is free the old memdup'ed
* value, but it's auto-freed by the datalist recovery, so
* we don't have anything to actually do here
*/
break;
}
/*
* free the information cache
*/
}