summaryrefslogtreecommitdiff
path: root/agent/mibgroup/notification-log-mib/notification_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/notification-log-mib/notification_log.c')
-rw-r--r--agent/mibgroup/notification-log-mib/notification_log.c770
1 files changed, 770 insertions, 0 deletions
diff --git a/agent/mibgroup/notification-log-mib/notification_log.c b/agent/mibgroup/notification-log-mib/notification_log.c
new file mode 100644
index 0000000..a12a338
--- /dev/null
+++ b/agent/mibgroup/notification-log-mib/notification_log.c
@@ -0,0 +1,770 @@
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-features.h>
+
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include <net-snmp/agent/ds_agent.h>
+#include <net-snmp/agent/instance.h>
+#include <net-snmp/agent/table.h>
+#include <net-snmp/agent/table_data.h>
+#include <net-snmp/agent/table_dataset.h>
+#include "net-snmp/agent/sysORTable.h"
+#include "notification_log.h"
+
+netsnmp_feature_require(register_ulong_instance_context)
+netsnmp_feature_require(register_read_only_counter32_instance_context)
+netsnmp_feature_require(delete_table_data_set)
+netsnmp_feature_require(table_dataset)
+netsnmp_feature_require(date_n_time)
+
+/*
+ * column number definitions for table nlmLogTable
+ */
+
+#define COLUMN_NLMLOGINDEX 1
+#define COLUMN_NLMLOGTIME 2
+#define COLUMN_NLMLOGDATEANDTIME 3
+#define COLUMN_NLMLOGENGINEID 4
+#define COLUMN_NLMLOGENGINETADDRESS 5
+#define COLUMN_NLMLOGENGINETDOMAIN 6
+#define COLUMN_NLMLOGCONTEXTENGINEID 7
+#define COLUMN_NLMLOGCONTEXTNAME 8
+#define COLUMN_NLMLOGNOTIFICATIONID 9
+
+/*
+ * column number definitions for table nlmLogVariableTable
+ */
+#define COLUMN_NLMLOGVARIABLEINDEX 1
+#define COLUMN_NLMLOGVARIABLEID 2
+#define COLUMN_NLMLOGVARIABLEVALUETYPE 3
+#define COLUMN_NLMLOGVARIABLECOUNTER32VAL 4
+#define COLUMN_NLMLOGVARIABLEUNSIGNED32VAL 5
+#define COLUMN_NLMLOGVARIABLETIMETICKSVAL 6
+#define COLUMN_NLMLOGVARIABLEINTEGER32VAL 7
+#define COLUMN_NLMLOGVARIABLEOCTETSTRINGVAL 8
+#define COLUMN_NLMLOGVARIABLEIPADDRESSVAL 9
+#define COLUMN_NLMLOGVARIABLEOIDVAL 10
+#define COLUMN_NLMLOGVARIABLECOUNTER64VAL 11
+#define COLUMN_NLMLOGVARIABLEOPAQUEVAL 12
+
+static u_long num_received = 0;
+static u_long num_deleted = 0;
+
+static u_long max_logged = 1000; /* goes against the mib default of infinite */
+static u_long max_age = 1440; /* 1440 = 24 hours, which is the mib default */
+
+static netsnmp_table_data_set *nlmLogTable;
+static netsnmp_table_data_set *nlmLogVarTable;
+
+static oid nlm_module_oid[] = { SNMP_OID_MIB2, 92 }; /* NOTIFICATION-LOG-MIB::notificationLogMIB */
+
+static void
+netsnmp_notif_log_remove_oldest(int count)
+{
+ netsnmp_table_row *deleterow, *tmprow, *deletevarrow;
+
+ DEBUGMSGTL(("notification_log", "deleting %d log entry(s)\n", count));
+
+ deleterow = netsnmp_table_data_set_get_first_row(nlmLogTable);
+ for (; count && deleterow; deleterow = tmprow, --count) {
+ /*
+ * delete contained varbinds
+ * xxx-rks: note that this assumes that only the default
+ * log is used (ie for the first nlmLogTable row, the
+ * first nlmLogVarTable rows will be the right ones).
+ * the right thing to do would be to do a find based on
+ * the nlmLogTable oid.
+ */
+ DEBUGMSGTL(("9:notification_log", " deleting notification\n"));
+ DEBUGIF("9:notification_log") {
+ DEBUGMSGTL(("9:notification_log",
+ " base oid:"));
+ DEBUGMSGOID(("9:notification_log", deleterow->index_oid,
+ deleterow->index_oid_len));
+ DEBUGMSG(("9:notification_log", "\n"));
+ }
+ deletevarrow = netsnmp_table_data_set_get_first_row(nlmLogVarTable);
+ for (; deletevarrow; deletevarrow = tmprow) {
+
+ tmprow = netsnmp_table_data_set_get_next_row(nlmLogVarTable,
+ deletevarrow);
+
+ DEBUGIF("9:notification_log") {
+ DEBUGMSGTL(("9:notification_log",
+ " :"));
+ DEBUGMSGOID(("9:notification_log", deletevarrow->index_oid,
+ deletevarrow->index_oid_len));
+ DEBUGMSG(("9:notification_log", "\n"));
+ }
+ if ((deleterow->index_oid_len == deletevarrow->index_oid_len - 1) &&
+ snmp_oid_compare(deleterow->index_oid,
+ deleterow->index_oid_len,
+ deletevarrow->index_oid,
+ deleterow->index_oid_len) == 0) {
+ DEBUGMSGTL(("9:notification_log", " deleting varbind\n"));
+ netsnmp_table_dataset_remove_and_delete_row(nlmLogVarTable,
+ deletevarrow);
+ }
+ else
+ break;
+ }
+
+ /*
+ * delete the master row
+ */
+ tmprow = netsnmp_table_data_set_get_next_row(nlmLogTable, deleterow);
+ netsnmp_table_dataset_remove_and_delete_row(nlmLogTable,
+ deleterow);
+ num_deleted++;
+ }
+ /** should have deleted all of them */
+ netsnmp_assert(0 == count);
+}
+
+static void
+check_log_size(unsigned int clientreg, void *clientarg)
+{
+ netsnmp_table_row *row;
+ netsnmp_table_data_set_storage *data;
+ u_long count = 0;
+ u_long uptime;
+
+ uptime = netsnmp_get_agent_uptime();
+
+ if (!nlmLogTable || !nlmLogTable->table ) {
+ DEBUGMSGTL(("notification_log", "missing log table\n"));
+ return;
+ }
+
+ /*
+ * check max allowed count
+ */
+ count = netsnmp_table_set_num_rows(nlmLogTable);
+ DEBUGMSGTL(("notification_log",
+ "logged notifications %lu; max %lu\n",
+ count, max_logged));
+ if (count > max_logged) {
+ count = count - max_logged;
+ DEBUGMSGTL(("notification_log", "removing %lu extra notifications\n",
+ count));
+ netsnmp_notif_log_remove_oldest(count);
+ }
+
+ /*
+ * check max age
+ */
+ if (0 == max_age)
+ return;
+ count = 0;
+ for (row = netsnmp_table_data_set_get_first_row(nlmLogTable);
+ row;
+ row = netsnmp_table_data_set_get_next_row(nlmLogTable, row)) {
+
+ data = (netsnmp_table_data_set_storage *) row->data;
+ data = netsnmp_table_data_set_find_column(data, COLUMN_NLMLOGTIME);
+
+ if (uptime < ((u_long)(*(data->data.integer) + max_age * 100 * 60)))
+ break;
+ ++count;
+ }
+
+ if (count) {
+ DEBUGMSGTL(("notification_log", "removing %lu expired notifications\n",
+ count));
+ netsnmp_notif_log_remove_oldest(count);
+ }
+}
+
+
+/** Initialize the nlmLogVariableTable table by defining its contents and how it's structured */
+static void
+initialize_table_nlmLogVariableTable(const char * context)
+{
+ static oid nlmLogVariableTable_oid[] =
+ { 1, 3, 6, 1, 2, 1, 92, 1, 3, 2 };
+ size_t nlmLogVariableTable_oid_len =
+ OID_LENGTH(nlmLogVariableTable_oid);
+ netsnmp_table_data_set *table_set;
+ netsnmp_handler_registration *reginfo;
+
+ /*
+ * create the table structure itself
+ */
+ table_set = netsnmp_create_table_data_set("nlmLogVariableTable");
+ nlmLogVarTable = table_set;
+ nlmLogVarTable->table->store_indexes = 1;
+
+ /***************************************************
+ * Adding indexes
+ */
+ /*
+ * declaring the nlmLogName index
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding index nlmLogName of type ASN_OCTET_STR to table nlmLogVariableTable\n"));
+ netsnmp_table_dataset_add_index(table_set, ASN_OCTET_STR);
+ /*
+ * declaring the nlmLogIndex index
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding index nlmLogIndex of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
+ netsnmp_table_dataset_add_index(table_set, ASN_UNSIGNED);
+ /*
+ * declaring the nlmLogVariableIndex index
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding index nlmLogVariableIndex of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
+ netsnmp_table_dataset_add_index(table_set, ASN_UNSIGNED);
+
+ /*
+ * adding column nlmLogVariableID of type ASN_OBJECT_ID and access of
+ * ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableID (#2) of type ASN_OBJECT_ID to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set, COLUMN_NLMLOGVARIABLEID,
+ ASN_OBJECT_ID, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableValueType of type ASN_INTEGER and
+ * access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableValueType (#3) of type ASN_INTEGER to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLEVALUETYPE,
+ ASN_INTEGER, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableCounter32Val of type ASN_COUNTER and
+ * access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableCounter32Val (#4) of type ASN_COUNTER to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLECOUNTER32VAL,
+ ASN_COUNTER, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableUnsigned32Val of type ASN_UNSIGNED and
+ * access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableUnsigned32Val (#5) of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLEUNSIGNED32VAL,
+ ASN_UNSIGNED, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableTimeTicksVal of type ASN_TIMETICKS and
+ * access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableTimeTicksVal (#6) of type ASN_TIMETICKS to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLETIMETICKSVAL,
+ ASN_TIMETICKS, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableInteger32Val of type ASN_INTEGER and
+ * access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableInteger32Val (#7) of type ASN_INTEGER to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLEINTEGER32VAL,
+ ASN_INTEGER, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableOctetStringVal of type ASN_OCTET_STR
+ * and access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableOctetStringVal (#8) of type ASN_OCTET_STR to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLEOCTETSTRINGVAL,
+ ASN_OCTET_STR, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableIpAddressVal of type ASN_IPADDRESS and
+ * access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableIpAddressVal (#9) of type ASN_IPADDRESS to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLEIPADDRESSVAL,
+ ASN_IPADDRESS, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableOidVal of type ASN_OBJECT_ID and access
+ * of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableOidVal (#10) of type ASN_OBJECT_ID to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLEOIDVAL,
+ ASN_OBJECT_ID, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableCounter64Val of type ASN_COUNTER64 and
+ * access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableCounter64Val (#11) of type ASN_COUNTER64 to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLECOUNTER64VAL,
+ ASN_COUNTER64, 0, NULL, 0);
+ /*
+ * adding column nlmLogVariableOpaqueVal of type ASN_OPAQUE and access
+ * of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
+ "adding column nlmLogVariableOpaqueVal (#12) of type ASN_OPAQUE to table nlmLogVariableTable\n"));
+ netsnmp_table_set_add_default_row(table_set,
+ COLUMN_NLMLOGVARIABLEOPAQUEVAL,
+ ASN_OPAQUE, 0, NULL, 0);
+
+ /*
+ * registering the table with the master agent
+ */
+ /*
+ * note: if you don't need a subhandler to deal with any aspects of
+ * the request, change nlmLogVariableTable_handler to "NULL"
+ */
+ reginfo =
+ netsnmp_create_handler_registration ("nlmLogVariableTable",
+ NULL,
+ nlmLogVariableTable_oid,
+ nlmLogVariableTable_oid_len,
+ HANDLER_CAN_RWRITE);
+ if (NULL != context)
+ reginfo->contextName = strdup(context);
+ netsnmp_register_table_data_set(reginfo, table_set, NULL);
+}
+
+/** Initialize the nlmLogTable table by defining its contents and how it's structured */
+static void
+initialize_table_nlmLogTable(const char * context)
+{
+ static oid nlmLogTable_oid[] = { 1, 3, 6, 1, 2, 1, 92, 1, 3, 1 };
+ size_t nlmLogTable_oid_len = OID_LENGTH(nlmLogTable_oid);
+ netsnmp_handler_registration *reginfo;
+
+ /*
+ * create the table structure itself
+ */
+ nlmLogTable = netsnmp_create_table_data_set("nlmLogTable");
+
+ /***************************************************
+ * Adding indexes
+ */
+ /*
+ * declaring the nlmLogIndex index
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding index nlmLogName of type ASN_OCTET_STR to table nlmLogTable\n"));
+ netsnmp_table_dataset_add_index(nlmLogTable, ASN_OCTET_STR);
+
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding index nlmLogIndex of type ASN_UNSIGNED to table nlmLogTable\n"));
+ netsnmp_table_dataset_add_index(nlmLogTable, ASN_UNSIGNED);
+
+ /*
+ * adding column nlmLogTime of type ASN_TIMETICKS and access of
+ * ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding column nlmLogTime (#2) of type ASN_TIMETICKS to table nlmLogTable\n"));
+ netsnmp_table_set_add_default_row(nlmLogTable, COLUMN_NLMLOGTIME,
+ ASN_TIMETICKS, 0, NULL, 0);
+ /*
+ * adding column nlmLogDateAndTime of type ASN_OCTET_STR and access of
+ * ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding column nlmLogDateAndTime (#3) of type ASN_OCTET_STR to table nlmLogTable\n"));
+ netsnmp_table_set_add_default_row(nlmLogTable,
+ COLUMN_NLMLOGDATEANDTIME,
+ ASN_OCTET_STR, 0, NULL, 0);
+ /*
+ * adding column nlmLogEngineID of type ASN_OCTET_STR and access of
+ * ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding column nlmLogEngineID (#4) of type ASN_OCTET_STR to table nlmLogTable\n"));
+ netsnmp_table_set_add_default_row(nlmLogTable, COLUMN_NLMLOGENGINEID,
+ ASN_OCTET_STR, 0, NULL, 0);
+ /*
+ * adding column nlmLogEngineTAddress of type ASN_OCTET_STR and access
+ * of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding column nlmLogEngineTAddress (#5) of type ASN_OCTET_STR to table nlmLogTable\n"));
+ netsnmp_table_set_add_default_row(nlmLogTable,
+ COLUMN_NLMLOGENGINETADDRESS,
+ ASN_OCTET_STR, 0, NULL, 0);
+ /*
+ * adding column nlmLogEngineTDomain of type ASN_OBJECT_ID and access
+ * of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding column nlmLogEngineTDomain (#6) of type ASN_OBJECT_ID to table nlmLogTable\n"));
+ netsnmp_table_set_add_default_row(nlmLogTable,
+ COLUMN_NLMLOGENGINETDOMAIN,
+ ASN_OBJECT_ID, 0, NULL, 0);
+ /*
+ * adding column nlmLogContextEngineID of type ASN_OCTET_STR and
+ * access of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding column nlmLogContextEngineID (#7) of type ASN_OCTET_STR to table nlmLogTable\n"));
+ netsnmp_table_set_add_default_row(nlmLogTable,
+ COLUMN_NLMLOGCONTEXTENGINEID,
+ ASN_OCTET_STR, 0, NULL, 0);
+ /*
+ * adding column nlmLogContextName of type ASN_OCTET_STR and access of
+ * ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding column nlmLogContextName (#8) of type ASN_OCTET_STR to table nlmLogTable\n"));
+ netsnmp_table_set_add_default_row(nlmLogTable,
+ COLUMN_NLMLOGCONTEXTNAME,
+ ASN_OCTET_STR, 0, NULL, 0);
+ /*
+ * adding column nlmLogNotificationID of type ASN_OBJECT_ID and access
+ * of ReadOnly
+ */
+ DEBUGMSGTL(("initialize_table_nlmLogTable",
+ "adding column nlmLogNotificationID (#9) of type ASN_OBJECT_ID to table nlmLogTable\n"));
+ netsnmp_table_set_add_default_row(nlmLogTable,
+ COLUMN_NLMLOGNOTIFICATIONID,
+ ASN_OBJECT_ID, 0, NULL, 0);
+
+ /*
+ * registering the table with the master agent
+ */
+ /*
+ * note: if you don't need a subhandler to deal with any aspects of
+ * the request, change nlmLogTable_handler to "NULL"
+ */
+ reginfo =
+ netsnmp_create_handler_registration("nlmLogTable", NULL,
+ nlmLogTable_oid,
+ nlmLogTable_oid_len,
+ HANDLER_CAN_RWRITE);
+ if (NULL != context)
+ reginfo->contextName = strdup(context);
+ netsnmp_register_table_data_set(reginfo, nlmLogTable, NULL);
+
+ /*
+ * hmm... 5 minutes seems like a reasonable time to check for out
+ * dated notification logs right?
+ */
+ snmp_alarm_register(300, SA_REPEAT, check_log_size, NULL);
+}
+
+static int
+notification_log_config_handler(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ /*
+ *this handler exists only to act as a trigger when the
+ * configuration variables get set to a value and thus
+ * notifications must be possibly deleted from our archives.
+ */
+#ifndef NETSNMP_NO_WRITE_SUPPORT
+ if (reqinfo->mode == MODE_SET_COMMIT)
+ check_log_size(0, NULL);
+#endif /* !NETSNMP_NO_WRITE_SUPPORT */
+ return SNMP_ERR_NOERROR;
+}
+
+void
+init_notification_log(void)
+{
+ static oid my_nlmStatsGlobalNotificationsLogged_oid[] =
+ { 1, 3, 6, 1, 2, 1, 92, 1, 2, 1, 0 };
+ static oid my_nlmStatsGlobalNotificationsBumped_oid[] =
+ { 1, 3, 6, 1, 2, 1, 92, 1, 2, 2, 0 };
+ static oid my_nlmConfigGlobalEntryLimit_oid[] =
+ { 1, 3, 6, 1, 2, 1, 92, 1, 1, 1, 0 };
+ static oid my_nlmConfigGlobalAgeOut_oid[] =
+ { 1, 3, 6, 1, 2, 1, 92, 1, 1, 2, 0 };
+ char * context;
+ char * apptype;
+
+ context = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_NOTIF_LOG_CTX);
+
+ DEBUGMSGTL(("notification_log", "registering with '%s' context\n",
+ SNMP_STRORNULL(context)));
+
+ /*
+ * static variables
+ */
+ netsnmp_register_read_only_counter32_instance_context
+ ("nlmStatsGlobalNotificationsLogged",
+ my_nlmStatsGlobalNotificationsLogged_oid,
+ OID_LENGTH(my_nlmStatsGlobalNotificationsLogged_oid),
+ &num_received, NULL, context);
+
+ netsnmp_register_read_only_counter32_instance_context
+ ("nlmStatsGlobalNotificationsBumped",
+ my_nlmStatsGlobalNotificationsBumped_oid,
+ OID_LENGTH(my_nlmStatsGlobalNotificationsBumped_oid),
+ &num_deleted, NULL, context);
+
+ netsnmp_register_ulong_instance_context("nlmConfigGlobalEntryLimit",
+ my_nlmConfigGlobalEntryLimit_oid,
+ OID_LENGTH
+ (my_nlmConfigGlobalEntryLimit_oid),
+ &max_logged,
+ notification_log_config_handler,
+ context);
+
+ netsnmp_register_ulong_instance_context("nlmConfigGlobalAgeOut",
+ my_nlmConfigGlobalAgeOut_oid,
+ OID_LENGTH
+ (my_nlmConfigGlobalAgeOut_oid),
+ &max_age,
+ notification_log_config_handler,
+ context);
+
+ /*
+ * tables
+ */
+ initialize_table_nlmLogVariableTable(context);
+ initialize_table_nlmLogTable(context);
+
+ /*
+ * disable flag
+ */
+ apptype = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_APPTYPE);
+ netsnmp_ds_register_config(ASN_BOOLEAN, apptype, "dontRetainLogs",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_DONT_RETAIN_NOTIFICATIONS);
+ netsnmp_ds_register_config(ASN_BOOLEAN, apptype, "doNotRetainNotificationLogs",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_DONT_RETAIN_NOTIFICATIONS);
+#if 0
+ /* xxx-rks: config for max size; should be peristent too, & tied to mib */
+ netsnmp_ds_register_config(ASN_INTEGER,
+ netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_APPTYPE),
+ "notificationLogMax",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NOTIF_LOG_MAX);
+#endif
+
+ REGISTER_SYSOR_ENTRY(nlm_module_oid,
+ "The MIB module for logging SNMP Notifications.");
+}
+
+void
+shutdown_notification_log(void)
+{
+ max_logged = 0;
+ check_log_size(0, NULL);
+ netsnmp_delete_table_data_set(nlmLogTable);
+ nlmLogTable = NULL;
+
+ UNREGISTER_SYSOR_ENTRY(nlm_module_oid);
+}
+
+void
+log_notification(netsnmp_pdu *pdu, netsnmp_transport *transport)
+{
+ long tmpl;
+ netsnmp_table_row *row;
+
+ static u_long default_num = 0;
+
+ static oid snmptrapoid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
+ size_t snmptrapoid_len = OID_LENGTH(snmptrapoid);
+ netsnmp_variable_list *vptr;
+ u_char *logdate;
+ size_t logdate_size;
+ time_t timetnow;
+
+ u_long vbcount = 0;
+ u_long tmpul;
+ int col;
+ netsnmp_pdu *orig_pdu = pdu;
+
+ if (!nlmLogVarTable
+ || netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_LOG)) {
+ return;
+ }
+
+ DEBUGMSGTL(("notification_log", "logging something\n"));
+ row = netsnmp_create_table_data_row();
+
+ ++num_received;
+ default_num++;
+
+ /*
+ * indexes to the table
+ */
+ netsnmp_table_row_add_index(row, ASN_OCTET_STR, "default",
+ strlen("default"));
+ netsnmp_table_row_add_index(row, ASN_UNSIGNED, &default_num,
+ sizeof(default_num));
+
+ /*
+ * add the data
+ */
+ tmpl = netsnmp_get_agent_uptime();
+ netsnmp_set_row_column(row, COLUMN_NLMLOGTIME, ASN_TIMETICKS,
+ &tmpl, sizeof(tmpl));
+ time(&timetnow);
+ logdate = date_n_time(&timetnow, &logdate_size);
+ netsnmp_set_row_column(row, COLUMN_NLMLOGDATEANDTIME, ASN_OCTET_STR,
+ logdate, logdate_size);
+ netsnmp_set_row_column(row, COLUMN_NLMLOGENGINEID, ASN_OCTET_STR,
+ pdu->securityEngineID,
+ pdu->securityEngineIDLen);
+ if (transport && transport->domain == netsnmpUDPDomain) {
+ /*
+ * check for the udp domain
+ */
+ struct sockaddr_in *addr =
+ (struct sockaddr_in *) pdu->transport_data;
+ if (addr) {
+ char buf[sizeof(in_addr_t) +
+ sizeof(addr->sin_port)];
+ in_addr_t locaddr = htonl(addr->sin_addr.s_addr);
+ u_short portnum = htons(addr->sin_port);
+ memcpy(buf, &locaddr, sizeof(in_addr_t));
+ memcpy(buf + sizeof(in_addr_t), &portnum,
+ sizeof(addr->sin_port));
+ netsnmp_set_row_column(row, COLUMN_NLMLOGENGINETADDRESS,
+ ASN_OCTET_STR, buf,
+ sizeof(in_addr_t) +
+ sizeof(addr->sin_port));
+ }
+ }
+ if (transport)
+ netsnmp_set_row_column(row, COLUMN_NLMLOGENGINETDOMAIN,
+ ASN_OBJECT_ID,
+ transport->domain,
+ sizeof(oid) * transport->domain_length);
+ netsnmp_set_row_column(row, COLUMN_NLMLOGCONTEXTENGINEID,
+ ASN_OCTET_STR, pdu->contextEngineID,
+ pdu->contextEngineIDLen);
+ netsnmp_set_row_column(row, COLUMN_NLMLOGCONTEXTNAME, ASN_OCTET_STR,
+ pdu->contextName, pdu->contextNameLen);
+
+ if (pdu->command == SNMP_MSG_TRAP)
+ pdu = convert_v1pdu_to_v2(orig_pdu);
+ for (vptr = pdu->variables; vptr; vptr = vptr->next_variable) {
+ if (snmp_oid_compare(snmptrapoid, snmptrapoid_len,
+ vptr->name, vptr->name_length) == 0) {
+ netsnmp_set_row_column(row, COLUMN_NLMLOGNOTIFICATIONID,
+ ASN_OBJECT_ID, vptr->val.string,
+ vptr->val_len);
+ } else {
+ netsnmp_table_row *myrow;
+ myrow = netsnmp_create_table_data_row();
+
+ /*
+ * indexes to the table
+ */
+ netsnmp_table_row_add_index(myrow, ASN_OCTET_STR, "default",
+ strlen("default"));
+ netsnmp_table_row_add_index(myrow, ASN_UNSIGNED, &default_num,
+ sizeof(default_num));
+ vbcount++;
+ netsnmp_table_row_add_index(myrow, ASN_UNSIGNED, &vbcount,
+ sizeof(vbcount));
+
+ /*
+ * OID
+ */
+ netsnmp_set_row_column(myrow, COLUMN_NLMLOGVARIABLEID,
+ ASN_OBJECT_ID, vptr->name,
+ vptr->name_length * sizeof(oid));
+
+ /*
+ * value
+ */
+ switch (vptr->type) {
+ case ASN_OBJECT_ID:
+ tmpul = 7;
+ col = COLUMN_NLMLOGVARIABLEOIDVAL;
+ break;
+
+ case ASN_INTEGER:
+ tmpul = 4;
+ col = COLUMN_NLMLOGVARIABLEINTEGER32VAL;
+ break;
+
+ case ASN_UNSIGNED:
+ tmpul = 2;
+ col = COLUMN_NLMLOGVARIABLEUNSIGNED32VAL;
+ break;
+
+ case ASN_COUNTER:
+ tmpul = 1;
+ col = COLUMN_NLMLOGVARIABLECOUNTER32VAL;
+ break;
+
+ case ASN_TIMETICKS:
+ tmpul = 3;
+ col = COLUMN_NLMLOGVARIABLETIMETICKSVAL;
+ break;
+
+ case ASN_OCTET_STR:
+ tmpul = 6;
+ col = COLUMN_NLMLOGVARIABLEOCTETSTRINGVAL;
+ break;
+
+ case ASN_IPADDRESS:
+ tmpul = 5;
+ col = COLUMN_NLMLOGVARIABLEIPADDRESSVAL;
+ break;
+
+ case ASN_COUNTER64:
+ tmpul = 8;
+ col = COLUMN_NLMLOGVARIABLECOUNTER64VAL;
+ break;
+
+ case ASN_OPAQUE:
+ tmpul = 9;
+ col = COLUMN_NLMLOGVARIABLEOPAQUEVAL;
+ break;
+
+ default:
+ /*
+ * unsupported
+ */
+ DEBUGMSGTL(("notification_log",
+ "skipping type %d\n", vptr->type));
+ (void)netsnmp_table_dataset_delete_row(myrow);
+ continue;
+ }
+ netsnmp_set_row_column(myrow, COLUMN_NLMLOGVARIABLEVALUETYPE,
+ ASN_INTEGER, & tmpul,
+ sizeof(tmpul));
+ netsnmp_set_row_column(myrow, col, vptr->type,
+ vptr->val.string, vptr->val_len);
+ DEBUGMSGTL(("notification_log",
+ "adding a row to the variables table\n"));
+ netsnmp_table_dataset_add_row(nlmLogVarTable, myrow);
+ }
+ }
+
+ if (pdu != orig_pdu)
+ snmp_free_pdu( pdu );
+
+ /*
+ * store the row
+ */
+ netsnmp_table_dataset_add_row(nlmLogTable, row);
+
+ check_log_size(0, NULL);
+ DEBUGMSGTL(("notification_log", "done logging something\n"));
+}