1 #include <net-snmp/net-snmp-config.h>
2 #if HAVE_STDLIB_H
3 #include <stdlib.h>
4 #endif
5 #if HAVE_STRING_H
6 #include <string.h>
7 #else
8 #include <strings.h>
9 #endif
10 #include <stddef.h>
11
12 #include <net-snmp/net-snmp-includes.h>
13 #include <net-snmp/agent/net-snmp-agent-includes.h>
14 #include <net-snmp/agent/agent_callbacks.h>
15 #include <net-snmp/agent/agent_sysORTable.h>
16 #include <net-snmp/agent/sysORTable.h>
17
18 typedef struct data_node_s {
19 struct sysORTable data;
20 struct data_node_s* next;
21 struct data_node_s* prev;
22 }* data_node;
23
24 static data_node table = NULL;
25
26 static void
erase(data_node entry)27 erase(data_node entry)
28 {
29 entry->data.OR_uptime = netsnmp_get_agent_uptime();
30 DEBUGMSGTL(("agent/sysORTable", "UNREG_SYSOR %p\n", &entry->data));
31 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_UNREG_SYSOR,
32 &entry->data);
33 free(entry->data.OR_oid);
34 free(entry->data.OR_descr);
35 if (entry->next == entry)
36 table = NULL;
37 else {
38 entry->next->prev = entry->prev;
39 entry->prev->next = entry->next;
40 if (entry == table)
41 table = entry->next;
42 }
43 free(entry);
44 }
45
46 void
netsnmp_sysORTable_foreach(void (* f)(const struct sysORTable *,void *),void * c)47 netsnmp_sysORTable_foreach(void (*f)(const struct sysORTable*, void*), void* c)
48 {
49 DEBUGMSGTL(("agent/sysORTable", "foreach(%p, %p)\n", f, c));
50 if(table) {
51 data_node run = table;
52 do {
53 data_node tmp = run;
54 run = run->next;
55 f(&tmp->data, c);
56 } while(table && run != table);
57 }
58 }
59
60 int
register_sysORTable_sess(oid * oidin,size_t oidlen,const char * descr,netsnmp_session * ss)61 register_sysORTable_sess(oid * oidin,
62 size_t oidlen,
63 const char *descr, netsnmp_session * ss)
64 {
65 data_node entry;
66
67 DEBUGMSGTL(("agent/sysORTable", "registering: "));
68 DEBUGMSGOID(("agent/sysORTable", oidin, oidlen));
69 DEBUGMSG(("agent/sysORTable", ", session %p\n", ss));
70
71 entry = (data_node)calloc(1, sizeof(struct data_node_s));
72 if (entry == NULL) {
73 DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new entry\n"));
74 return SYS_ORTABLE_REGISTRATION_FAILED;
75 }
76
77 entry->data.OR_descr = strdup(descr);
78 if (entry->data.OR_descr == NULL) {
79 DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new sysORDescr\n"));
80 free(entry);
81 return SYS_ORTABLE_REGISTRATION_FAILED;
82 }
83
84 entry->data.OR_oid = (oid *) malloc(sizeof(oid) * oidlen);
85 if (entry->data.OR_oid == NULL) {
86 DEBUGMSGTL(("agent/sysORTable", "Failed to allocate new sysORID\n"));
87 free(entry->data.OR_descr);
88 free(entry);
89 return SYS_ORTABLE_REGISTRATION_FAILED;
90 }
91
92 memcpy(entry->data.OR_oid, oidin, sizeof(oid) * oidlen);
93 entry->data.OR_oidlen = oidlen;
94 entry->data.OR_sess = ss;
95
96 if(table) {
97 entry->next = table;
98 entry->prev = table->prev;
99 table->prev->next = entry;
100 table->prev = entry;
101 } else
102 table = entry->next = entry->prev = entry;
103
104 entry->data.OR_uptime = netsnmp_get_agent_uptime();
105
106 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
107 SNMPD_CALLBACK_REG_SYSOR, &entry->data);
108
109 return SYS_ORTABLE_REGISTERED_OK;
110 }
111
112 int
register_sysORTable(oid * oidin,size_t oidlen,const char * descr)113 register_sysORTable(oid * oidin, size_t oidlen, const char *descr)
114 {
115 return register_sysORTable_sess(oidin, oidlen, descr, NULL);
116 }
117
118 int
unregister_sysORTable_sess(oid * oidin,size_t oidlen,netsnmp_session * ss)119 unregister_sysORTable_sess(oid * oidin,
120 size_t oidlen, netsnmp_session * ss)
121 {
122 int any_unregistered = 0;
123
124 DEBUGMSGTL(("agent/sysORTable", "sysORTable unregistering: "));
125 DEBUGMSGOID(("agent/sysORTable", oidin, oidlen));
126 DEBUGMSG(("agent/sysORTable", ", session %p\n", ss));
127
128 if(table) {
129 data_node run = table;
130 do {
131 data_node tmp = run;
132 run = run->next;
133 if (tmp->data.OR_sess == ss &&
134 snmp_oid_compare(oidin, oidlen,
135 tmp->data.OR_oid, tmp->data.OR_oidlen) == 0) {
136 erase(tmp);
137 any_unregistered = 1;
138 }
139 } while(table && run != table);
140 }
141
142 if (any_unregistered) {
143 DEBUGMSGTL(("agent/sysORTable", "unregistering successfull\n"));
144 return SYS_ORTABLE_UNREGISTERED_OK;
145 } else {
146 DEBUGMSGTL(("agent/sysORTable", "unregistering failed\n"));
147 return SYS_ORTABLE_NO_SUCH_REGISTRATION;
148 }
149 }
150
151
152 int
unregister_sysORTable(oid * oidin,size_t oidlen)153 unregister_sysORTable(oid * oidin, size_t oidlen)
154 {
155 return unregister_sysORTable_sess(oidin, oidlen, NULL);
156 }
157
158
159 void
unregister_sysORTable_by_session(netsnmp_session * ss)160 unregister_sysORTable_by_session(netsnmp_session * ss)
161 {
162 DEBUGMSGTL(("agent/sysORTable",
163 "sysORTable unregistering session %p\n", ss));
164
165 if(table) {
166 data_node run = table;
167 do {
168 data_node tmp = run;
169 run = run->next;
170 if (((ss->flags & SNMP_FLAGS_SUBSESSION) &&
171 tmp->data.OR_sess == ss) ||
172 (!(ss->flags & SNMP_FLAGS_SUBSESSION) && tmp->data.OR_sess &&
173 tmp->data.OR_sess->subsession == ss))
174 erase(tmp);
175 } while(table && run != table);
176 }
177
178 DEBUGMSGTL(("agent/sysORTable",
179 "sysORTable unregistering session %p done\n", ss));
180 }
181
182 static int
register_sysOR_callback(int majorID,int minorID,void * serverarg,void * clientarg)183 register_sysOR_callback(int majorID, int minorID, void *serverarg,
184 void *clientarg)
185 {
186 struct sysORTable *parms = (struct sysORTable *) serverarg;
187
188 return register_sysORTable_sess(parms->OR_oid, parms->OR_oidlen,
189 parms->OR_descr, parms->OR_sess);
190 }
191
192 static int
unregister_sysOR_by_session_callback(int majorID,int minorID,void * serverarg,void * clientarg)193 unregister_sysOR_by_session_callback(int majorID, int minorID,
194 void *serverarg, void *clientarg)
195 {
196 netsnmp_session *session = (netsnmp_session *) serverarg;
197
198 unregister_sysORTable_by_session(session);
199
200 return 0;
201 }
202
203 static int
unregister_sysOR_callback(int majorID,int minorID,void * serverarg,void * clientarg)204 unregister_sysOR_callback(int majorID, int minorID, void *serverarg,
205 void *clientarg)
206 {
207 struct sysORTable *parms = (struct sysORTable *) serverarg;
208
209 return unregister_sysORTable_sess(parms->OR_oid,
210 parms->OR_oidlen,
211 parms->OR_sess);
212 }
213
214 void
init_agent_sysORTable(void)215 init_agent_sysORTable(void)
216 {
217 DEBUGMSGTL(("agent/sysORTable", "init_agent_sysORTable\n"));
218
219 snmp_register_callback(SNMP_CALLBACK_APPLICATION,
220 SNMPD_CALLBACK_REQ_REG_SYSOR,
221 register_sysOR_callback, NULL);
222 snmp_register_callback(SNMP_CALLBACK_APPLICATION,
223 SNMPD_CALLBACK_REQ_UNREG_SYSOR,
224 unregister_sysOR_callback, NULL);
225 snmp_register_callback(SNMP_CALLBACK_APPLICATION,
226 SNMPD_CALLBACK_REQ_UNREG_SYSOR_SESS,
227 unregister_sysOR_by_session_callback, NULL);
228 }
229
230 void
shutdown_agent_sysORTable(void)231 shutdown_agent_sysORTable(void)
232 {
233 DEBUGMSGTL(("agent/sysORTable", "shutdown_sysORTable\n"));
234 while(table)
235 erase(table);
236 }
237