summaryrefslogtreecommitdiff
path: root/agent/agent_sysORTable.c
diff options
context:
space:
mode:
authorHideki Yamane <henrich@debian.org>2014-03-30 19:38:48 +0900
committerHideki Yamane <henrich@debian.org>2014-03-30 19:38:48 +0900
commit7769a9595c3da9a35f31b42451b1f6c3ed4004fa (patch)
tree009bf8fd68af6bb1129e07dd8c1ed205010d81f8 /agent/agent_sysORTable.c
parent2e7891b0311204e0ecd5dc4a4334df01f3a6a1b4 (diff)
downloadpkg-net-snmp-7769a9595c3da9a35f31b42451b1f6c3ed4004fa.tar.gz
Imported Upstream version 5.7.2~dfsg
Diffstat (limited to 'agent/agent_sysORTable.c')
-rw-r--r--agent/agent_sysORTable.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/agent/agent_sysORTable.c b/agent/agent_sysORTable.c
new file mode 100644
index 0000000..f628060
--- /dev/null
+++ b/agent/agent_sysORTable.c
@@ -0,0 +1,236 @@
+#include <net-snmp/net-snmp-config.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stddef.h>
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <net-snmp/agent/agent_callbacks.h>
+#include <net-snmp/agent/agent_sysORTable.h>
+#include <net-snmp/agent/sysORTable.h>
+
+typedef struct data_node_s {
+ struct sysORTable data;
+ struct data_node_s* next;
+ struct data_node_s* prev;
+}* data_node;
+
+static data_node table = NULL;
+
+static void
+erase(data_node entry)
+{
+ entry->data.OR_uptime = netsnmp_get_agent_uptime();
+ DEBUGMSGTL(("agent/sysORTable", "UNREG_SYSOR %p\n", &entry->data));
+ snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREG_SYSOR,
+ &entry->data);
+ free(entry->data.OR_oid);
+ free(entry->data.OR_descr);
+ if (entry->next == entry)
+ table = NULL;
+ else {
+ entry->next->prev = entry->prev;
+ entry->prev->next = entry->next;
+ if (entry == table)
+ table = entry->next;
+ }
+ free(entry);
+}
+
+void
+netsnmp_sysORTable_foreach(void (*f)(const struct sysORTable*, void*), void* c)
+{
+ DEBUGMSGTL(("agent/sysORTable", "foreach(%p, %p)\n", f, c));
+ if(table) {
+ data_node run = table;
+ do {
+ data_node tmp = run;
+ run = run->next;
+ f(&tmp->data, c);
+ } while(table && run != table);
+ }
+}
+
+int
+register_sysORTable_sess(oid * oidin,
+ size_t oidlen,
+ const char *descr, netsnmp_session * ss)
+{
+ data_node entry;
+
+ DEBUGMSGTL(("agent/sysORTable", "registering: "));
+ DEBUGMSGOID(("agent/sysORTable", oidin, oidlen));
+ DEBUGMSG(("agent/sysORTable", ", session %p\n", ss));
+
+ entry = (data_node)calloc(1, sizeof(struct data_node_s));
+ if (entry == NULL) {
+ DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new entry\n"));
+ return SYS_ORTABLE_REGISTRATION_FAILED;
+ }
+
+ entry->data.OR_descr = strdup(descr);
+ if (entry->data.OR_descr == NULL) {
+ DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new sysORDescr\n"));
+ free(entry);
+ return SYS_ORTABLE_REGISTRATION_FAILED;
+ }
+
+ entry->data.OR_oid = (oid *) malloc(sizeof(oid) * oidlen);
+ if (entry->data.OR_oid == NULL) {
+ DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new sysORID\n"));
+ free(entry->data.OR_descr);
+ free(entry);
+ return SYS_ORTABLE_REGISTRATION_FAILED;
+ }
+
+ memcpy(entry->data.OR_oid, oidin, sizeof(oid) * oidlen);
+ entry->data.OR_oidlen = oidlen;
+ entry->data.OR_sess = ss;
+
+ if(table) {
+ entry->next = table;
+ entry->prev = table->prev;
+ table->prev->next = entry;
+ table->prev = entry;
+ } else
+ table = entry->next = entry->prev = entry;
+
+ entry->data.OR_uptime = netsnmp_get_agent_uptime();
+
+ snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
+ SNMPD_CALLBACK_REG_SYSOR, &entry->data);
+
+ return SYS_ORTABLE_REGISTERED_OK;
+}
+
+int
+register_sysORTable(oid * oidin, size_t oidlen, const char *descr)
+{
+ return register_sysORTable_sess(oidin, oidlen, descr, NULL);
+}
+
+int
+unregister_sysORTable_sess(oid * oidin,
+ size_t oidlen, netsnmp_session * ss)
+{
+ int any_unregistered = 0;
+
+ DEBUGMSGTL(("agent/sysORTable", "sysORTable unregistering: "));
+ DEBUGMSGOID(("agent/sysORTable", oidin, oidlen));
+ DEBUGMSG(("agent/sysORTable", ", session %p\n", ss));
+
+ if(table) {
+ data_node run = table;
+ do {
+ data_node tmp = run;
+ run = run->next;
+ if (tmp->data.OR_sess == ss &&
+ snmp_oid_compare(oidin, oidlen,
+ tmp->data.OR_oid, tmp->data.OR_oidlen) == 0) {
+ erase(tmp);
+ any_unregistered = 1;
+ }
+ } while(table && run != table);
+ }
+
+ if (any_unregistered) {
+ DEBUGMSGTL(("agent/sysORTable", "unregistering successfull\n"));
+ return SYS_ORTABLE_UNREGISTERED_OK;
+ } else {
+ DEBUGMSGTL(("agent/sysORTable", "unregistering failed\n"));
+ return SYS_ORTABLE_NO_SUCH_REGISTRATION;
+ }
+}
+
+
+int
+unregister_sysORTable(oid * oidin, size_t oidlen)
+{
+ return unregister_sysORTable_sess(oidin, oidlen, NULL);
+}
+
+
+void
+unregister_sysORTable_by_session(netsnmp_session * ss)
+{
+ DEBUGMSGTL(("agent/sysORTable",
+ "sysORTable unregistering session %p\n", ss));
+
+ if(table) {
+ data_node run = table;
+ do {
+ data_node tmp = run;
+ run = run->next;
+ if (((ss->flags & SNMP_FLAGS_SUBSESSION) &&
+ tmp->data.OR_sess == ss) ||
+ (!(ss->flags & SNMP_FLAGS_SUBSESSION) && tmp->data.OR_sess &&
+ tmp->data.OR_sess->subsession == ss))
+ erase(tmp);
+ } while(table && run != table);
+ }
+
+ DEBUGMSGTL(("agent/sysORTable",
+ "sysORTable unregistering session %p done\n", ss));
+}
+
+static int
+register_sysOR_callback(int majorID, int minorID, void *serverarg,
+ void *clientarg)
+{
+ struct sysORTable *parms = (struct sysORTable *) serverarg;
+
+ return register_sysORTable_sess(parms->OR_oid, parms->OR_oidlen,
+ parms->OR_descr, parms->OR_sess);
+}
+
+static int
+unregister_sysOR_by_session_callback(int majorID, int minorID,
+ void *serverarg, void *clientarg)
+{
+ netsnmp_session *session = (netsnmp_session *) serverarg;
+
+ unregister_sysORTable_by_session(session);
+
+ return 0;
+}
+
+static int
+unregister_sysOR_callback(int majorID, int minorID, void *serverarg,
+ void *clientarg)
+{
+ struct sysORTable *parms = (struct sysORTable *) serverarg;
+
+ return unregister_sysORTable_sess(parms->OR_oid,
+ parms->OR_oidlen,
+ parms->OR_sess);
+}
+
+void
+init_agent_sysORTable(void)
+{
+ DEBUGMSGTL(("agent/sysORTable", "init_agent_sysORTable\n"));
+
+ snmp_register_callback(SNMP_CALLBACK_APPLICATION,
+ SNMPD_CALLBACK_REQ_REG_SYSOR,
+ register_sysOR_callback, NULL);
+ snmp_register_callback(SNMP_CALLBACK_APPLICATION,
+ SNMPD_CALLBACK_REQ_UNREG_SYSOR,
+ unregister_sysOR_callback, NULL);
+ snmp_register_callback(SNMP_CALLBACK_APPLICATION,
+ SNMPD_CALLBACK_REQ_UNREG_SYSOR_SESS,
+ unregister_sysOR_by_session_callback, NULL);
+}
+
+void
+shutdown_agent_sysORTable(void)
+{
+ DEBUGMSGTL(("agent/sysORTable", "shutdown_sysORTable\n"));
+ while(table)
+ erase(table);
+}