net-snmp 5.7
agent_sysORTable.c
00001 #include <net-snmp/net-snmp-config.h>
00002 #if HAVE_STDLIB_H
00003 #include <stdlib.h>
00004 #endif
00005 #if HAVE_STRING_H
00006 #include <string.h>
00007 #else
00008 #include <strings.h>
00009 #endif
00010 #include <stddef.h>
00011 
00012 #include <net-snmp/net-snmp-includes.h>
00013 #include <net-snmp/agent/net-snmp-agent-includes.h>
00014 #include <net-snmp/agent/agent_callbacks.h>
00015 #include <net-snmp/agent/agent_sysORTable.h>
00016 #include <net-snmp/agent/sysORTable.h>
00017 
00018 typedef struct data_node_s {
00019     struct sysORTable data;
00020     struct data_node_s* next;
00021     struct data_node_s* prev;
00022 }* data_node;
00023 
00024 static data_node table = NULL;
00025 
00026 static void
00027 erase(data_node entry)
00028 {
00029     entry->data.OR_uptime = netsnmp_get_agent_uptime();
00030     DEBUGMSGTL(("agent/sysORTable", "UNREG_SYSOR %p\n", &entry->data));
00031     snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREG_SYSOR,
00032                         &entry->data);
00033     free(entry->data.OR_oid);
00034     free(entry->data.OR_descr);
00035     if (entry->next == entry)
00036         table = NULL;
00037     else {
00038         entry->next->prev = entry->prev;
00039         entry->prev->next = entry->next;
00040         if (entry == table)
00041             table = entry->next;
00042     }
00043     free(entry);
00044 }
00045 
00046 void
00047 netsnmp_sysORTable_foreach(void (*f)(const struct sysORTable*, void*), void* c)
00048 {
00049     DEBUGMSGTL(("agent/sysORTable", "foreach(%p, %p)\n", f, c));
00050     if(table) {
00051         data_node run = table;
00052         do {
00053             data_node tmp = run;
00054             run = run->next;
00055             f(&tmp->data, c);
00056         } while(table && run != table);
00057     }
00058 }
00059 
00060 int
00061 register_sysORTable_sess(oid * oidin,
00062                          size_t oidlen,
00063                          const char *descr, netsnmp_session * ss)
00064 {
00065     data_node entry;
00066 
00067     DEBUGMSGTL(("agent/sysORTable", "registering: "));
00068     DEBUGMSGOID(("agent/sysORTable", oidin, oidlen));
00069     DEBUGMSG(("agent/sysORTable", ", session %p\n", ss));
00070 
00071     entry = (data_node)calloc(1, sizeof(struct data_node_s));
00072     if (entry == NULL) {
00073         DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new entry\n"));
00074         return SYS_ORTABLE_REGISTRATION_FAILED;
00075     }
00076 
00077     entry->data.OR_descr = strdup(descr);
00078     if (entry->data.OR_descr == NULL) {
00079         DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new sysORDescr\n"));
00080         free(entry);
00081         return SYS_ORTABLE_REGISTRATION_FAILED;
00082     }
00083 
00084     entry->data.OR_oid = (oid *) malloc(sizeof(oid) * oidlen);
00085     if (entry->data.OR_oid == NULL) {
00086         DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new sysORID\n"));
00087         free(entry->data.OR_descr);
00088         free(entry);
00089         return SYS_ORTABLE_REGISTRATION_FAILED;
00090     }
00091 
00092     memcpy(entry->data.OR_oid, oidin, sizeof(oid) * oidlen);
00093     entry->data.OR_oidlen = oidlen;
00094     entry->data.OR_sess = ss;
00095 
00096     if(table) {
00097         entry->next = table;
00098         entry->prev = table->prev;
00099         table->prev->next = entry;
00100         table->prev = entry;
00101     } else
00102         table = entry->next = entry->prev = entry;
00103 
00104     entry->data.OR_uptime = netsnmp_get_agent_uptime();
00105 
00106     snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
00107                         SNMPD_CALLBACK_REG_SYSOR, &entry->data);
00108 
00109     return SYS_ORTABLE_REGISTERED_OK;
00110 }
00111 
00112 int
00113 register_sysORTable(oid * oidin, size_t oidlen, const char *descr)
00114 {
00115     return register_sysORTable_sess(oidin, oidlen, descr, NULL);
00116 }
00117 
00118 int
00119 unregister_sysORTable_sess(oid * oidin,
00120                            size_t oidlen, netsnmp_session * ss)
00121 {
00122     int any_unregistered = 0;
00123 
00124     DEBUGMSGTL(("agent/sysORTable", "sysORTable unregistering: "));
00125     DEBUGMSGOID(("agent/sysORTable", oidin, oidlen));
00126     DEBUGMSG(("agent/sysORTable", ", session %p\n", ss));
00127 
00128     if(table) {
00129         data_node run = table;
00130         do {
00131             data_node tmp = run;
00132             run = run->next;
00133             if (tmp->data.OR_sess == ss &&
00134                 snmp_oid_compare(oidin, oidlen,
00135                                  tmp->data.OR_oid, tmp->data.OR_oidlen) == 0) {
00136                 erase(tmp);
00137                 any_unregistered = 1;
00138             }
00139         } while(table && run != table);
00140     }
00141 
00142     if (any_unregistered) {
00143         DEBUGMSGTL(("agent/sysORTable", "unregistering successfull\n"));
00144         return SYS_ORTABLE_UNREGISTERED_OK;
00145     } else {
00146         DEBUGMSGTL(("agent/sysORTable", "unregistering failed\n"));
00147         return SYS_ORTABLE_NO_SUCH_REGISTRATION;
00148     }
00149 }
00150 
00151 
00152 int
00153 unregister_sysORTable(oid * oidin, size_t oidlen)
00154 {
00155     return unregister_sysORTable_sess(oidin, oidlen, NULL);
00156 }
00157 
00158 
00159 void
00160 unregister_sysORTable_by_session(netsnmp_session * ss)
00161 {
00162     DEBUGMSGTL(("agent/sysORTable",
00163                 "sysORTable unregistering session %p\n", ss));
00164 
00165    if(table) {
00166         data_node run = table;
00167         do {
00168             data_node tmp = run;
00169             run = run->next;
00170             if (((ss->flags & SNMP_FLAGS_SUBSESSION) &&
00171                  tmp->data.OR_sess == ss) ||
00172                 (!(ss->flags & SNMP_FLAGS_SUBSESSION) && tmp->data.OR_sess &&
00173                  tmp->data.OR_sess->subsession == ss))
00174                 erase(tmp);
00175         } while(table && run != table);
00176     }
00177 
00178     DEBUGMSGTL(("agent/sysORTable",
00179                 "sysORTable unregistering session %p done\n", ss));
00180 }
00181 
00182 static int
00183 register_sysOR_callback(int majorID, int minorID, void *serverarg,
00184                         void *clientarg)
00185 {
00186     struct sysORTable *parms = (struct sysORTable *) serverarg;
00187 
00188     return register_sysORTable_sess(parms->OR_oid, parms->OR_oidlen,
00189                                     parms->OR_descr, parms->OR_sess);
00190 }
00191 
00192 static int
00193 unregister_sysOR_by_session_callback(int majorID, int minorID,
00194                                      void *serverarg, void *clientarg)
00195 {
00196     netsnmp_session *session = (netsnmp_session *) serverarg;
00197 
00198     unregister_sysORTable_by_session(session);
00199 
00200     return 0;
00201 }
00202 
00203 static int
00204 unregister_sysOR_callback(int majorID, int minorID, void *serverarg,
00205                           void *clientarg)
00206 {
00207     struct sysORTable *parms = (struct sysORTable *) serverarg;
00208 
00209     return unregister_sysORTable_sess(parms->OR_oid,
00210                                       parms->OR_oidlen,
00211                                       parms->OR_sess);
00212 }
00213 
00214 void
00215 init_agent_sysORTable(void)
00216 {
00217     DEBUGMSGTL(("agent/sysORTable", "init_agent_sysORTable\n"));
00218 
00219     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
00220                            SNMPD_CALLBACK_REQ_REG_SYSOR,
00221                            register_sysOR_callback, NULL);
00222     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
00223                            SNMPD_CALLBACK_REQ_UNREG_SYSOR,
00224                            unregister_sysOR_callback, NULL);
00225     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
00226                            SNMPD_CALLBACK_REQ_UNREG_SYSOR_SESS,
00227                            unregister_sysOR_by_session_callback, NULL);
00228 }
00229 
00230 void
00231 shutdown_agent_sysORTable(void)
00232 {
00233     DEBUGMSGTL(("agent/sysORTable", "shutdown_sysORTable\n"));
00234     while(table)
00235         erase(table);
00236 }