summaryrefslogtreecommitdiff
path: root/agent/mibgroup/agent/nsCache.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/agent/nsCache.c')
-rw-r--r--agent/mibgroup/agent/nsCache.c428
1 files changed, 428 insertions, 0 deletions
diff --git a/agent/mibgroup/agent/nsCache.c b/agent/mibgroup/agent/nsCache.c
new file mode 100644
index 0000000..a56b0bd
--- /dev/null
+++ b/agent/mibgroup/agent/nsCache.c
@@ -0,0 +1,428 @@
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-features.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <net-snmp/agent/scalar.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include <net-snmp/agent/cache_handler.h>
+#include "agent/nsCache.h"
+
+netsnmp_feature_require(cache_get_head)
+
+
+/*
+ * use unadvertised function to get cache head. You really should not
+ * do this, since the internal storage mechanism might change.
+ */
+extern netsnmp_cache *netsnmp_cache_get_head(void);
+
+
+#define nsCache 1, 3, 6, 1, 4, 1, 8072, 1, 5
+
+/*
+ * OIDs for the cacheging control scalar objects
+ *
+ * Note that these we're registering the full object rather
+ * than the (sole) valid instance in each case, in order
+ * to handle requests for invalid instances properly.
+ */
+
+/*
+ * ... and for the cache table.
+ */
+
+#define NSCACHE_TIMEOUT 2
+#define NSCACHE_STATUS 3
+
+#define NSCACHE_STATUS_ENABLED 1
+#define NSCACHE_STATUS_DISABLED 2
+#define NSCACHE_STATUS_EMPTY 3
+#define NSCACHE_STATUS_ACTIVE 4
+#define NSCACHE_STATUS_EXPIRED 5
+
+NETSNMP_IMPORT struct snmp_alarm *
+sa_find_specific(unsigned int clientreg);
+
+
+void
+init_nsCache(void)
+{
+ const oid nsCacheTimeout_oid[] = { nsCache, 1 };
+ const oid nsCacheEnabled_oid[] = { nsCache, 2 };
+ const oid nsCacheTable_oid[] = { nsCache, 3 };
+
+ netsnmp_table_registration_info *table_info;
+ netsnmp_iterator_info *iinfo;
+
+ /*
+ * Register the scalar objects...
+ */
+ DEBUGMSGTL(("nsCacheScalars", "Initializing\n"));
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration(
+ "nsCacheTimeout", handle_nsCacheTimeout,
+ nsCacheTimeout_oid, OID_LENGTH(nsCacheTimeout_oid),
+ HANDLER_CAN_RWRITE)
+ );
+ netsnmp_register_scalar(
+ netsnmp_create_handler_registration(
+ "nsCacheEnabled", handle_nsCacheEnabled,
+ nsCacheEnabled_oid, OID_LENGTH(nsCacheEnabled_oid),
+ HANDLER_CAN_RWRITE)
+ );
+
+ /*
+ * ... and the table.
+ * We need to define the column structure and indexing....
+ */
+
+ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
+ if (!table_info) {
+ return;
+ }
+ netsnmp_table_helper_add_indexes(table_info, ASN_PRIV_IMPLIED_OBJECT_ID, 0);
+ table_info->min_column = NSCACHE_TIMEOUT;
+ table_info->max_column = NSCACHE_STATUS;
+
+
+ /*
+ * .... and the iteration information ....
+ */
+ iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
+ if (!iinfo) {
+ return;
+ }
+ iinfo->get_first_data_point = get_first_cache_entry;
+ iinfo->get_next_data_point = get_next_cache_entry;
+ iinfo->table_reginfo = table_info;
+
+
+ /*
+ * .... and register the table with the agent.
+ */
+ netsnmp_register_table_iterator2(
+ netsnmp_create_handler_registration(
+ "tzCacheTable", handle_nsCacheTable,
+ nsCacheTable_oid, OID_LENGTH(nsCacheTable_oid),
+ HANDLER_CAN_RWRITE),
+ iinfo);
+}
+
+
+/*
+ * nsCache scalar handling
+ */
+
+int
+handle_nsCacheTimeout(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ long cache_default_timeout =
+ netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_CACHE_TIMEOUT);
+ netsnmp_request_info *request=NULL;
+
+ switch (reqinfo->mode) {
+
+ case MODE_GET:
+ for (request = requests; request; request=request->next) {
+ snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
+ (u_char*)&cache_default_timeout,
+ sizeof(cache_default_timeout));
+ }
+ break;
+
+
+#ifndef NETSNMP_NO_WRITE_SUPPORT
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request=request->next) {
+ if ( request->status != 0 ) {
+ return SNMP_ERR_NOERROR; /* Already got an error */
+ }
+ if ( request->requestvb->type != ASN_INTEGER ) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
+ return SNMP_ERR_WRONGTYPE;
+ }
+ if ( *request->requestvb->val.integer < 0 ) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
+ return SNMP_ERR_WRONGVALUE;
+ }
+ }
+ break;
+
+ case MODE_SET_COMMIT:
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_CACHE_TIMEOUT,
+ *requests->requestvb->val.integer);
+ break;
+#endif /* !NETSNMP_NO_WRITE_SUPPORT */
+ }
+
+ return SNMP_ERR_NOERROR;
+}
+
+
+int
+handle_nsCacheEnabled(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ long enabled;
+ netsnmp_request_info *request=NULL;
+
+ switch (reqinfo->mode) {
+
+ case MODE_GET:
+ enabled = (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NO_CACHING)
+ ? NSCACHE_STATUS_ENABLED /* Actually True/False */
+ : NSCACHE_STATUS_DISABLED );
+ for (request = requests; request; request=request->next) {
+ snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
+ (u_char*)&enabled, sizeof(enabled));
+ }
+ break;
+
+
+#ifndef NETSNMP_NO_WRITE_SUPPORT
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request=request->next) {
+ if ( request->status != 0 ) {
+ return SNMP_ERR_NOERROR; /* Already got an error */
+ }
+ if ( request->requestvb->type != ASN_INTEGER ) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
+ return SNMP_ERR_WRONGTYPE;
+ }
+ if ((*request->requestvb->val.integer != NSCACHE_STATUS_ENABLED) &&
+ (*request->requestvb->val.integer != NSCACHE_STATUS_DISABLED)) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
+ return SNMP_ERR_WRONGVALUE;
+ }
+ }
+ break;
+
+ case MODE_SET_COMMIT:
+ enabled = *requests->requestvb->val.integer;
+ if (enabled == NSCACHE_STATUS_DISABLED)
+ enabled = 0;
+ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NO_CACHING, enabled);
+ break;
+#endif /* !NETSNMP_NO_WRITE_SUPPORT */
+ }
+
+ return SNMP_ERR_NOERROR;
+}
+
+
+/*
+ * nsCacheTable handling
+ */
+
+netsnmp_variable_list *
+get_first_cache_entry(void **loop_context, void **data_context,
+ netsnmp_variable_list *index,
+ netsnmp_iterator_info *data)
+{
+ netsnmp_cache *cache_head = netsnmp_cache_get_head();
+
+ if ( !cache_head )
+ return NULL;
+
+ snmp_set_var_value(index, (u_char*)cache_head->rootoid,
+ sizeof(oid) * cache_head->rootoid_len);
+ *loop_context = (void*)cache_head;
+ *data_context = (void*)cache_head;
+ return index;
+}
+
+netsnmp_variable_list *
+get_next_cache_entry(void **loop_context, void **data_context,
+ netsnmp_variable_list *index,
+ netsnmp_iterator_info *data)
+{
+ netsnmp_cache *cache = (netsnmp_cache *)*loop_context;
+ cache = cache->next;
+
+ if ( !cache )
+ return NULL;
+
+ snmp_set_var_value(index, (u_char*)cache->rootoid,
+ sizeof(oid) * cache->rootoid_len);
+ *loop_context = (void*)cache;
+ *data_context = (void*)cache;
+ return index;
+}
+
+
+int
+handle_nsCacheTable(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ long status;
+ netsnmp_request_info *request = NULL;
+ netsnmp_table_request_info *table_info = NULL;
+ netsnmp_cache *cache_entry = NULL;
+
+ switch (reqinfo->mode) {
+
+ case MODE_GET:
+ for (request=requests; request; request=request->next) {
+ if (request->processed != 0)
+ continue;
+
+ cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
+ table_info = netsnmp_extract_table_info(request);
+
+ switch (table_info->colnum) {
+ case NSCACHE_TIMEOUT:
+ if (!cache_entry) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
+ continue;
+ }
+ status = cache_entry->timeout;
+ snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
+ (u_char*)&status, sizeof(status));
+ break;
+
+ case NSCACHE_STATUS:
+ if (!cache_entry) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
+ continue;
+ }
+ status = (cache_entry->enabled ?
+ (cache_entry->timestampM ?
+ (!netsnmp_ready_monotonic(cache_entry->timestampM,
+ 1000*cache_entry->timeout) ?
+ NSCACHE_STATUS_ACTIVE:
+ NSCACHE_STATUS_EXPIRED) :
+ NSCACHE_STATUS_EMPTY) :
+ NSCACHE_STATUS_DISABLED);
+ snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
+ (u_char*)&status, sizeof(status));
+ break;
+
+ default:
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+ }
+ }
+ break;
+
+
+#ifndef NETSNMP_NO_WRITE_SUPPORT
+ case MODE_SET_RESERVE1:
+ for (request=requests; request; request=request->next) {
+ if (request->processed != 0)
+ continue;
+ if ( request->status != 0 ) {
+ return SNMP_ERR_NOERROR; /* Already got an error */
+ }
+ cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
+ table_info = netsnmp_extract_table_info(request);
+
+ switch (table_info->colnum) {
+ case NSCACHE_TIMEOUT:
+ if (!cache_entry) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
+ return SNMP_ERR_NOCREATION;
+ }
+ if ( request->requestvb->type != ASN_INTEGER ) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
+ return SNMP_ERR_WRONGTYPE;
+ }
+ if (*request->requestvb->val.integer < 0 ) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
+ return SNMP_ERR_WRONGVALUE;
+ }
+ break;
+
+ case NSCACHE_STATUS:
+ if (!cache_entry) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
+ return SNMP_ERR_NOCREATION;
+ }
+ if ( request->requestvb->type != ASN_INTEGER ) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
+ return SNMP_ERR_WRONGTYPE;
+ }
+ status = *request->requestvb->val.integer;
+ if (!((status == NSCACHE_STATUS_ENABLED ) ||
+ (status == NSCACHE_STATUS_DISABLED ) ||
+ (status == NSCACHE_STATUS_EMPTY ))) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
+ return SNMP_ERR_WRONGVALUE;
+ }
+ break;
+
+ default:
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
+ return SNMP_ERR_NOCREATION; /* XXX - is this right ? */
+ }
+ }
+ break;
+
+
+ case MODE_SET_COMMIT:
+ for (request=requests; request; request=request->next) {
+ if (request->processed != 0)
+ continue;
+ if ( request->status != 0 ) {
+ return SNMP_ERR_NOERROR; /* Already got an error */
+ }
+ cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
+ if (!cache_entry) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_COMMITFAILED);
+ return SNMP_ERR_COMMITFAILED; /* Shouldn't happen! */
+ }
+ table_info = netsnmp_extract_table_info(request);
+
+ switch (table_info->colnum) {
+ case NSCACHE_TIMEOUT:
+ cache_entry->timeout = *request->requestvb->val.integer;
+ /*
+ * check for auto repeat
+ */
+ if (cache_entry->timer_id) {
+ struct snmp_alarm * sa =
+ sa_find_specific(cache_entry->timer_id);
+ if (NULL != sa)
+ sa->t.tv_sec = cache_entry->timeout;
+ }
+ break;
+
+ case NSCACHE_STATUS:
+ switch (*request->requestvb->val.integer) {
+ case NSCACHE_STATUS_ENABLED:
+ cache_entry->enabled = 1;
+ break;
+ case NSCACHE_STATUS_DISABLED:
+ cache_entry->enabled = 0;
+ break;
+ case NSCACHE_STATUS_EMPTY:
+ cache_entry->free_cache(cache_entry, cache_entry->magic);
+ free(cache_entry->timestampM);
+ cache_entry->timestampM = NULL;
+ break;
+ }
+ break;
+ }
+ }
+ break;
+#endif /* !NETSNMP_NO_WRITE_SUPPORT */
+ }
+
+ return SNMP_ERR_NOERROR;
+}