1 #include <net-snmp/net-snmp-config.h>
2 #include <net-snmp/net-snmp-features.h>
3
4 #include <sys/types.h>
5 #if HAVE_NETINET_IN_H
6 #include <netinet/in.h>
7 #endif
8 #if HAVE_NETDB_H
9 #include <netdb.h>
10 #endif
11
12 #include <net-snmp/net-snmp-includes.h>
13 #include <net-snmp/agent/net-snmp-agent-includes.h>
14
15 #include <net-snmp/agent/ds_agent.h>
16 #include <net-snmp/agent/instance.h>
17 #include <net-snmp/agent/table.h>
18 #include <net-snmp/agent/table_data.h>
19 #include <net-snmp/agent/table_dataset.h>
20 #include "net-snmp/agent/sysORTable.h"
21 #include "notification_log.h"
22
23 netsnmp_feature_require(register_ulong_instance_context);
24 netsnmp_feature_require(register_read_only_counter32_instance_context);
25 netsnmp_feature_require(delete_table_data_set);
26 netsnmp_feature_require(table_dataset);
27 netsnmp_feature_require(date_n_time);
28
29 /*
30 * column number definitions for table nlmLogTable
31 */
32
33 #define COLUMN_NLMLOGINDEX 1
34 #define COLUMN_NLMLOGTIME 2
35 #define COLUMN_NLMLOGDATEANDTIME 3
36 #define COLUMN_NLMLOGENGINEID 4
37 #define COLUMN_NLMLOGENGINETADDRESS 5
38 #define COLUMN_NLMLOGENGINETDOMAIN 6
39 #define COLUMN_NLMLOGCONTEXTENGINEID 7
40 #define COLUMN_NLMLOGCONTEXTNAME 8
41 #define COLUMN_NLMLOGNOTIFICATIONID 9
42
43 /*
44 * column number definitions for table nlmLogVariableTable
45 */
46 #define COLUMN_NLMLOGVARIABLEINDEX 1
47 #define COLUMN_NLMLOGVARIABLEID 2
48 #define COLUMN_NLMLOGVARIABLEVALUETYPE 3
49 #define COLUMN_NLMLOGVARIABLECOUNTER32VAL 4
50 #define COLUMN_NLMLOGVARIABLEUNSIGNED32VAL 5
51 #define COLUMN_NLMLOGVARIABLETIMETICKSVAL 6
52 #define COLUMN_NLMLOGVARIABLEINTEGER32VAL 7
53 #define COLUMN_NLMLOGVARIABLEOCTETSTRINGVAL 8
54 #define COLUMN_NLMLOGVARIABLEIPADDRESSVAL 9
55 #define COLUMN_NLMLOGVARIABLEOIDVAL 10
56 #define COLUMN_NLMLOGVARIABLECOUNTER64VAL 11
57 #define COLUMN_NLMLOGVARIABLEOPAQUEVAL 12
58
59 static u_long num_received = 0;
60 static u_long num_deleted = 0;
61
62 static u_long max_logged = 1000; /* goes against the mib default of infinite */
63 static u_long max_age = 1440; /* 1440 = 24 hours, which is the mib default */
64
65 static netsnmp_table_data_set *nlmLogTable;
66 static netsnmp_table_data_set *nlmLogVarTable;
67
68 static oid nlm_module_oid[] = { SNMP_OID_MIB2, 92 }; /* NOTIFICATION-LOG-MIB::notificationLogMIB */
69
70 static void
netsnmp_notif_log_remove_oldest(int count)71 netsnmp_notif_log_remove_oldest(int count)
72 {
73 netsnmp_table_row *deleterow, *tmprow, *deletevarrow;
74
75 DEBUGMSGTL(("notification_log", "deleting %d log entry(s)\n", count));
76
77 deleterow = netsnmp_table_data_set_get_first_row(nlmLogTable);
78 for (; count && deleterow; deleterow = tmprow, --count) {
79 /*
80 * delete contained varbinds
81 * xxx-rks: note that this assumes that only the default
82 * log is used (ie for the first nlmLogTable row, the
83 * first nlmLogVarTable rows will be the right ones).
84 * the right thing to do would be to do a find based on
85 * the nlmLogTable oid.
86 */
87 DEBUGMSGTL(("9:notification_log", " deleting notification\n"));
88 DEBUGIF("9:notification_log") {
89 DEBUGMSGTL(("9:notification_log",
90 " base oid:"));
91 DEBUGMSGOID(("9:notification_log", deleterow->index_oid,
92 deleterow->index_oid_len));
93 DEBUGMSG(("9:notification_log", "\n"));
94 }
95 deletevarrow = netsnmp_table_data_set_get_first_row(nlmLogVarTable);
96 for (; deletevarrow; deletevarrow = tmprow) {
97
98 tmprow = netsnmp_table_data_set_get_next_row(nlmLogVarTable,
99 deletevarrow);
100
101 DEBUGIF("9:notification_log") {
102 DEBUGMSGTL(("9:notification_log",
103 " :"));
104 DEBUGMSGOID(("9:notification_log", deletevarrow->index_oid,
105 deletevarrow->index_oid_len));
106 DEBUGMSG(("9:notification_log", "\n"));
107 }
108 if ((deleterow->index_oid_len == deletevarrow->index_oid_len - 1) &&
109 snmp_oid_compare(deleterow->index_oid,
110 deleterow->index_oid_len,
111 deletevarrow->index_oid,
112 deleterow->index_oid_len) == 0) {
113 DEBUGMSGTL(("9:notification_log", " deleting varbind\n"));
114 netsnmp_table_dataset_remove_and_delete_row(nlmLogVarTable,
115 deletevarrow);
116 }
117 else
118 break;
119 }
120
121 /*
122 * delete the master row
123 */
124 tmprow = netsnmp_table_data_set_get_next_row(nlmLogTable, deleterow);
125 netsnmp_table_dataset_remove_and_delete_row(nlmLogTable,
126 deleterow);
127 num_deleted++;
128 }
129 /** should have deleted all of them */
130 netsnmp_assert(0 == count);
131 }
132
133 static void
check_log_size(unsigned int clientreg,void * clientarg)134 check_log_size(unsigned int clientreg, void *clientarg)
135 {
136 netsnmp_table_row *row;
137 netsnmp_table_data_set_storage *data;
138 u_long count = 0;
139 u_long uptime;
140
141 uptime = netsnmp_get_agent_uptime();
142
143 if (!nlmLogTable || !nlmLogTable->table ) {
144 DEBUGMSGTL(("notification_log", "missing log table\n"));
145 return;
146 }
147
148 /*
149 * check max allowed count
150 */
151 count = netsnmp_table_set_num_rows(nlmLogTable);
152 DEBUGMSGTL(("notification_log",
153 "logged notifications %lu; max %lu\n",
154 count, max_logged));
155 if (count > max_logged) {
156 count = count - max_logged;
157 DEBUGMSGTL(("notification_log", "removing %lu extra notifications\n",
158 count));
159 netsnmp_notif_log_remove_oldest(count);
160 }
161
162 /*
163 * check max age
164 */
165 if (0 == max_age)
166 return;
167 count = 0;
168 for (row = netsnmp_table_data_set_get_first_row(nlmLogTable);
169 row;
170 row = netsnmp_table_data_set_get_next_row(nlmLogTable, row)) {
171
172 data = (netsnmp_table_data_set_storage *) row->data;
173 data = netsnmp_table_data_set_find_column(data, COLUMN_NLMLOGTIME);
174
175 if (uptime < ((u_long)(*(data->data.integer) + max_age * 100 * 60)))
176 break;
177 ++count;
178 }
179
180 if (count) {
181 DEBUGMSGTL(("notification_log", "removing %lu expired notifications\n",
182 count));
183 netsnmp_notif_log_remove_oldest(count);
184 }
185 }
186
187
188 /** Initialize the nlmLogVariableTable table by defining its contents and how it's structured */
189 static void
initialize_table_nlmLogVariableTable(const char * context)190 initialize_table_nlmLogVariableTable(const char * context)
191 {
192 static oid nlmLogVariableTable_oid[] =
193 { 1, 3, 6, 1, 2, 1, 92, 1, 3, 2 };
194 size_t nlmLogVariableTable_oid_len =
195 OID_LENGTH(nlmLogVariableTable_oid);
196 netsnmp_table_data_set *table_set;
197 netsnmp_handler_registration *reginfo;
198
199 /*
200 * create the table structure itself
201 */
202 table_set = netsnmp_create_table_data_set("nlmLogVariableTable");
203 nlmLogVarTable = table_set;
204 nlmLogVarTable->table->store_indexes = 1;
205
206 /***************************************************
207 * Adding indexes
208 */
209 /*
210 * declaring the nlmLogName index
211 */
212 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
213 "adding index nlmLogName of type ASN_OCTET_STR to table nlmLogVariableTable\n"));
214 netsnmp_table_dataset_add_index(table_set, ASN_OCTET_STR);
215 /*
216 * declaring the nlmLogIndex index
217 */
218 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
219 "adding index nlmLogIndex of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
220 netsnmp_table_dataset_add_index(table_set, ASN_UNSIGNED);
221 /*
222 * declaring the nlmLogVariableIndex index
223 */
224 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
225 "adding index nlmLogVariableIndex of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
226 netsnmp_table_dataset_add_index(table_set, ASN_UNSIGNED);
227
228 /*
229 * adding column nlmLogVariableID of type ASN_OBJECT_ID and access of
230 * ReadOnly
231 */
232 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
233 "adding column nlmLogVariableID (#2) of type ASN_OBJECT_ID to table nlmLogVariableTable\n"));
234 netsnmp_table_set_add_default_row(table_set, COLUMN_NLMLOGVARIABLEID,
235 ASN_OBJECT_ID, 0, NULL, 0);
236 /*
237 * adding column nlmLogVariableValueType of type ASN_INTEGER and
238 * access of ReadOnly
239 */
240 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
241 "adding column nlmLogVariableValueType (#3) of type ASN_INTEGER to table nlmLogVariableTable\n"));
242 netsnmp_table_set_add_default_row(table_set,
243 COLUMN_NLMLOGVARIABLEVALUETYPE,
244 ASN_INTEGER, 0, NULL, 0);
245 /*
246 * adding column nlmLogVariableCounter32Val of type ASN_COUNTER and
247 * access of ReadOnly
248 */
249 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
250 "adding column nlmLogVariableCounter32Val (#4) of type ASN_COUNTER to table nlmLogVariableTable\n"));
251 netsnmp_table_set_add_default_row(table_set,
252 COLUMN_NLMLOGVARIABLECOUNTER32VAL,
253 ASN_COUNTER, 0, NULL, 0);
254 /*
255 * adding column nlmLogVariableUnsigned32Val of type ASN_UNSIGNED and
256 * access of ReadOnly
257 */
258 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
259 "adding column nlmLogVariableUnsigned32Val (#5) of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
260 netsnmp_table_set_add_default_row(table_set,
261 COLUMN_NLMLOGVARIABLEUNSIGNED32VAL,
262 ASN_UNSIGNED, 0, NULL, 0);
263 /*
264 * adding column nlmLogVariableTimeTicksVal of type ASN_TIMETICKS and
265 * access of ReadOnly
266 */
267 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
268 "adding column nlmLogVariableTimeTicksVal (#6) of type ASN_TIMETICKS to table nlmLogVariableTable\n"));
269 netsnmp_table_set_add_default_row(table_set,
270 COLUMN_NLMLOGVARIABLETIMETICKSVAL,
271 ASN_TIMETICKS, 0, NULL, 0);
272 /*
273 * adding column nlmLogVariableInteger32Val of type ASN_INTEGER and
274 * access of ReadOnly
275 */
276 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
277 "adding column nlmLogVariableInteger32Val (#7) of type ASN_INTEGER to table nlmLogVariableTable\n"));
278 netsnmp_table_set_add_default_row(table_set,
279 COLUMN_NLMLOGVARIABLEINTEGER32VAL,
280 ASN_INTEGER, 0, NULL, 0);
281 /*
282 * adding column nlmLogVariableOctetStringVal of type ASN_OCTET_STR
283 * and access of ReadOnly
284 */
285 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
286 "adding column nlmLogVariableOctetStringVal (#8) of type ASN_OCTET_STR to table nlmLogVariableTable\n"));
287 netsnmp_table_set_add_default_row(table_set,
288 COLUMN_NLMLOGVARIABLEOCTETSTRINGVAL,
289 ASN_OCTET_STR, 0, NULL, 0);
290 /*
291 * adding column nlmLogVariableIpAddressVal of type ASN_IPADDRESS and
292 * access of ReadOnly
293 */
294 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
295 "adding column nlmLogVariableIpAddressVal (#9) of type ASN_IPADDRESS to table nlmLogVariableTable\n"));
296 netsnmp_table_set_add_default_row(table_set,
297 COLUMN_NLMLOGVARIABLEIPADDRESSVAL,
298 ASN_IPADDRESS, 0, NULL, 0);
299 /*
300 * adding column nlmLogVariableOidVal of type ASN_OBJECT_ID and access
301 * of ReadOnly
302 */
303 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
304 "adding column nlmLogVariableOidVal (#10) of type ASN_OBJECT_ID to table nlmLogVariableTable\n"));
305 netsnmp_table_set_add_default_row(table_set,
306 COLUMN_NLMLOGVARIABLEOIDVAL,
307 ASN_OBJECT_ID, 0, NULL, 0);
308 /*
309 * adding column nlmLogVariableCounter64Val of type ASN_COUNTER64 and
310 * access of ReadOnly
311 */
312 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
313 "adding column nlmLogVariableCounter64Val (#11) of type ASN_COUNTER64 to table nlmLogVariableTable\n"));
314 netsnmp_table_set_add_default_row(table_set,
315 COLUMN_NLMLOGVARIABLECOUNTER64VAL,
316 ASN_COUNTER64, 0, NULL, 0);
317 /*
318 * adding column nlmLogVariableOpaqueVal of type ASN_OPAQUE and access
319 * of ReadOnly
320 */
321 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
322 "adding column nlmLogVariableOpaqueVal (#12) of type ASN_OPAQUE to table nlmLogVariableTable\n"));
323 netsnmp_table_set_add_default_row(table_set,
324 COLUMN_NLMLOGVARIABLEOPAQUEVAL,
325 ASN_OPAQUE, 0, NULL, 0);
326
327 /*
328 * registering the table with the master agent
329 */
330 /*
331 * note: if you don't need a subhandler to deal with any aspects of
332 * the request, change nlmLogVariableTable_handler to "NULL"
333 */
334 reginfo =
335 netsnmp_create_handler_registration ("nlmLogVariableTable",
336 NULL,
337 nlmLogVariableTable_oid,
338 nlmLogVariableTable_oid_len,
339 HANDLER_CAN_RWRITE);
340 if (NULL != context)
341 reginfo->contextName = strdup(context);
342 netsnmp_register_table_data_set(reginfo, table_set, NULL);
343 }
344
345 /** Initialize the nlmLogTable table by defining its contents and how it's structured */
346 static void
initialize_table_nlmLogTable(const char * context)347 initialize_table_nlmLogTable(const char * context)
348 {
349 static oid nlmLogTable_oid[] = { 1, 3, 6, 1, 2, 1, 92, 1, 3, 1 };
350 size_t nlmLogTable_oid_len = OID_LENGTH(nlmLogTable_oid);
351 netsnmp_handler_registration *reginfo;
352
353 /*
354 * create the table structure itself
355 */
356 nlmLogTable = netsnmp_create_table_data_set("nlmLogTable");
357
358 /***************************************************
359 * Adding indexes
360 */
361 /*
362 * declaring the nlmLogIndex index
363 */
364 DEBUGMSGTL(("initialize_table_nlmLogTable",
365 "adding index nlmLogName of type ASN_OCTET_STR to table nlmLogTable\n"));
366 netsnmp_table_dataset_add_index(nlmLogTable, ASN_OCTET_STR);
367
368 DEBUGMSGTL(("initialize_table_nlmLogTable",
369 "adding index nlmLogIndex of type ASN_UNSIGNED to table nlmLogTable\n"));
370 netsnmp_table_dataset_add_index(nlmLogTable, ASN_UNSIGNED);
371
372 /*
373 * adding column nlmLogTime of type ASN_TIMETICKS and access of
374 * ReadOnly
375 */
376 DEBUGMSGTL(("initialize_table_nlmLogTable",
377 "adding column nlmLogTime (#2) of type ASN_TIMETICKS to table nlmLogTable\n"));
378 netsnmp_table_set_add_default_row(nlmLogTable, COLUMN_NLMLOGTIME,
379 ASN_TIMETICKS, 0, NULL, 0);
380 /*
381 * adding column nlmLogDateAndTime of type ASN_OCTET_STR and access of
382 * ReadOnly
383 */
384 DEBUGMSGTL(("initialize_table_nlmLogTable",
385 "adding column nlmLogDateAndTime (#3) of type ASN_OCTET_STR to table nlmLogTable\n"));
386 netsnmp_table_set_add_default_row(nlmLogTable,
387 COLUMN_NLMLOGDATEANDTIME,
388 ASN_OCTET_STR, 0, NULL, 0);
389 /*
390 * adding column nlmLogEngineID of type ASN_OCTET_STR and access of
391 * ReadOnly
392 */
393 DEBUGMSGTL(("initialize_table_nlmLogTable",
394 "adding column nlmLogEngineID (#4) of type ASN_OCTET_STR to table nlmLogTable\n"));
395 netsnmp_table_set_add_default_row(nlmLogTable, COLUMN_NLMLOGENGINEID,
396 ASN_OCTET_STR, 0, NULL, 0);
397 /*
398 * adding column nlmLogEngineTAddress of type ASN_OCTET_STR and access
399 * of ReadOnly
400 */
401 DEBUGMSGTL(("initialize_table_nlmLogTable",
402 "adding column nlmLogEngineTAddress (#5) of type ASN_OCTET_STR to table nlmLogTable\n"));
403 netsnmp_table_set_add_default_row(nlmLogTable,
404 COLUMN_NLMLOGENGINETADDRESS,
405 ASN_OCTET_STR, 0, NULL, 0);
406 /*
407 * adding column nlmLogEngineTDomain of type ASN_OBJECT_ID and access
408 * of ReadOnly
409 */
410 DEBUGMSGTL(("initialize_table_nlmLogTable",
411 "adding column nlmLogEngineTDomain (#6) of type ASN_OBJECT_ID to table nlmLogTable\n"));
412 netsnmp_table_set_add_default_row(nlmLogTable,
413 COLUMN_NLMLOGENGINETDOMAIN,
414 ASN_OBJECT_ID, 0, NULL, 0);
415 /*
416 * adding column nlmLogContextEngineID of type ASN_OCTET_STR and
417 * access of ReadOnly
418 */
419 DEBUGMSGTL(("initialize_table_nlmLogTable",
420 "adding column nlmLogContextEngineID (#7) of type ASN_OCTET_STR to table nlmLogTable\n"));
421 netsnmp_table_set_add_default_row(nlmLogTable,
422 COLUMN_NLMLOGCONTEXTENGINEID,
423 ASN_OCTET_STR, 0, NULL, 0);
424 /*
425 * adding column nlmLogContextName of type ASN_OCTET_STR and access of
426 * ReadOnly
427 */
428 DEBUGMSGTL(("initialize_table_nlmLogTable",
429 "adding column nlmLogContextName (#8) of type ASN_OCTET_STR to table nlmLogTable\n"));
430 netsnmp_table_set_add_default_row(nlmLogTable,
431 COLUMN_NLMLOGCONTEXTNAME,
432 ASN_OCTET_STR, 0, NULL, 0);
433 /*
434 * adding column nlmLogNotificationID of type ASN_OBJECT_ID and access
435 * of ReadOnly
436 */
437 DEBUGMSGTL(("initialize_table_nlmLogTable",
438 "adding column nlmLogNotificationID (#9) of type ASN_OBJECT_ID to table nlmLogTable\n"));
439 netsnmp_table_set_add_default_row(nlmLogTable,
440 COLUMN_NLMLOGNOTIFICATIONID,
441 ASN_OBJECT_ID, 0, NULL, 0);
442
443 /*
444 * registering the table with the master agent
445 */
446 /*
447 * note: if you don't need a subhandler to deal with any aspects of
448 * the request, change nlmLogTable_handler to "NULL"
449 */
450 reginfo =
451 netsnmp_create_handler_registration("nlmLogTable", NULL,
452 nlmLogTable_oid,
453 nlmLogTable_oid_len,
454 HANDLER_CAN_RWRITE);
455 if (NULL != context)
456 reginfo->contextName = strdup(context);
457 netsnmp_register_table_data_set(reginfo, nlmLogTable, NULL);
458
459 /*
460 * hmm... 5 minutes seems like a reasonable time to check for out
461 * dated notification logs right?
462 */
463 snmp_alarm_register(300, SA_REPEAT, check_log_size, NULL);
464 }
465
466 static int
notification_log_config_handler(netsnmp_mib_handler * handler,netsnmp_handler_registration * reginfo,netsnmp_agent_request_info * reqinfo,netsnmp_request_info * requests)467 notification_log_config_handler(netsnmp_mib_handler *handler,
468 netsnmp_handler_registration *reginfo,
469 netsnmp_agent_request_info *reqinfo,
470 netsnmp_request_info *requests)
471 {
472 /*
473 *this handler exists only to act as a trigger when the
474 * configuration variables get set to a value and thus
475 * notifications must be possibly deleted from our archives.
476 */
477 #ifndef NETSNMP_NO_WRITE_SUPPORT
478 if (reqinfo->mode == MODE_SET_COMMIT)
479 check_log_size(0, NULL);
480 #endif /* !NETSNMP_NO_WRITE_SUPPORT */
481 return SNMP_ERR_NOERROR;
482 }
483
484 void
init_notification_log(void)485 init_notification_log(void)
486 {
487 static oid my_nlmStatsGlobalNotificationsLogged_oid[] =
488 { 1, 3, 6, 1, 2, 1, 92, 1, 2, 1, 0 };
489 static oid my_nlmStatsGlobalNotificationsBumped_oid[] =
490 { 1, 3, 6, 1, 2, 1, 92, 1, 2, 2, 0 };
491 static oid my_nlmConfigGlobalEntryLimit_oid[] =
492 { 1, 3, 6, 1, 2, 1, 92, 1, 1, 1, 0 };
493 static oid my_nlmConfigGlobalAgeOut_oid[] =
494 { 1, 3, 6, 1, 2, 1, 92, 1, 1, 2, 0 };
495 char * context;
496 char * apptype;
497
498 context = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
499 NETSNMP_DS_NOTIF_LOG_CTX);
500
501 DEBUGMSGTL(("notification_log", "registering with '%s' context\n",
502 SNMP_STRORNULL(context)));
503
504 /*
505 * static variables
506 */
507 netsnmp_register_read_only_counter32_instance_context
508 ("nlmStatsGlobalNotificationsLogged",
509 my_nlmStatsGlobalNotificationsLogged_oid,
510 OID_LENGTH(my_nlmStatsGlobalNotificationsLogged_oid),
511 &num_received, NULL, context);
512
513 netsnmp_register_read_only_counter32_instance_context
514 ("nlmStatsGlobalNotificationsBumped",
515 my_nlmStatsGlobalNotificationsBumped_oid,
516 OID_LENGTH(my_nlmStatsGlobalNotificationsBumped_oid),
517 &num_deleted, NULL, context);
518
519 netsnmp_register_ulong_instance_context("nlmConfigGlobalEntryLimit",
520 my_nlmConfigGlobalEntryLimit_oid,
521 OID_LENGTH
522 (my_nlmConfigGlobalEntryLimit_oid),
523 &max_logged,
524 notification_log_config_handler,
525 context);
526
527 netsnmp_register_ulong_instance_context("nlmConfigGlobalAgeOut",
528 my_nlmConfigGlobalAgeOut_oid,
529 OID_LENGTH
530 (my_nlmConfigGlobalAgeOut_oid),
531 &max_age,
532 notification_log_config_handler,
533 context);
534
535 /*
536 * tables
537 */
538 initialize_table_nlmLogVariableTable(context);
539 initialize_table_nlmLogTable(context);
540
541 /*
542 * disable flag
543 */
544 apptype = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
545 NETSNMP_DS_LIB_APPTYPE);
546 netsnmp_ds_register_config(ASN_BOOLEAN, apptype, "dontRetainLogs",
547 NETSNMP_DS_APPLICATION_ID,
548 NETSNMP_DS_AGENT_DONT_RETAIN_NOTIFICATIONS);
549 netsnmp_ds_register_config(ASN_BOOLEAN, apptype, "doNotRetainNotificationLogs",
550 NETSNMP_DS_APPLICATION_ID,
551 NETSNMP_DS_AGENT_DONT_RETAIN_NOTIFICATIONS);
552 #if 0
553 /* xxx-rks: config for max size; should be peristent too, & tied to mib */
554 netsnmp_ds_register_config(ASN_INTEGER,
555 netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
556 NETSNMP_DS_LIB_APPTYPE),
557 "notificationLogMax",
558 NETSNMP_DS_APPLICATION_ID,
559 NETSNMP_DS_AGENT_NOTIF_LOG_MAX);
560 #endif
561
562 REGISTER_SYSOR_ENTRY(nlm_module_oid,
563 "The MIB module for logging SNMP Notifications.");
564 }
565
566 void
shutdown_notification_log(void)567 shutdown_notification_log(void)
568 {
569 max_logged = 0;
570 check_log_size(0, NULL);
571 netsnmp_delete_table_data_set(nlmLogTable);
572 nlmLogTable = NULL;
573
574 UNREGISTER_SYSOR_ENTRY(nlm_module_oid);
575 }
576
577 void
log_notification(netsnmp_pdu * pdu,netsnmp_transport * transport)578 log_notification(netsnmp_pdu *pdu, netsnmp_transport *transport)
579 {
580 long tmpl;
581 netsnmp_table_row *row;
582
583 static u_long default_num = 0;
584
585 static oid snmptrapoid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
586 size_t snmptrapoid_len = OID_LENGTH(snmptrapoid);
587 netsnmp_variable_list *vptr;
588 u_char *logdate;
589 size_t logdate_size;
590 time_t timetnow;
591
592 u_long vbcount = 0;
593 u_long tmpul;
594 int col;
595 netsnmp_pdu *orig_pdu = pdu;
596
597 if (!nlmLogVarTable
598 || netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
599 NETSNMP_DS_APP_DONT_LOG)) {
600 return;
601 }
602
603 DEBUGMSGTL(("notification_log", "logging something\n"));
604 row = netsnmp_create_table_data_row();
605
606 ++num_received;
607 default_num++;
608
609 /*
610 * indexes to the table
611 */
612 netsnmp_table_row_add_index(row, ASN_OCTET_STR, "default",
613 strlen("default"));
614 netsnmp_table_row_add_index(row, ASN_UNSIGNED, &default_num,
615 sizeof(default_num));
616
617 /*
618 * add the data
619 */
620 tmpl = netsnmp_get_agent_uptime();
621 netsnmp_set_row_column(row, COLUMN_NLMLOGTIME, ASN_TIMETICKS,
622 &tmpl, sizeof(tmpl));
623 time(&timetnow);
624 logdate = date_n_time(&timetnow, &logdate_size);
625 netsnmp_set_row_column(row, COLUMN_NLMLOGDATEANDTIME, ASN_OCTET_STR,
626 logdate, logdate_size);
627 netsnmp_set_row_column(row, COLUMN_NLMLOGENGINEID, ASN_OCTET_STR,
628 pdu->securityEngineID,
629 pdu->securityEngineIDLen);
630 if (transport && transport->domain == netsnmpUDPDomain) {
631 /*
632 * check for the udp domain
633 */
634 struct sockaddr_in *addr =
635 (struct sockaddr_in *) pdu->transport_data;
636 if (addr) {
637 char buf[sizeof(in_addr_t) +
638 sizeof(addr->sin_port)];
639 in_addr_t locaddr = htonl(addr->sin_addr.s_addr);
640 u_short portnum = htons(addr->sin_port);
641 memcpy(buf, &locaddr, sizeof(in_addr_t));
642 memcpy(buf + sizeof(in_addr_t), &portnum,
643 sizeof(addr->sin_port));
644 netsnmp_set_row_column(row, COLUMN_NLMLOGENGINETADDRESS,
645 ASN_OCTET_STR, buf,
646 sizeof(in_addr_t) +
647 sizeof(addr->sin_port));
648 }
649 }
650 if (transport)
651 netsnmp_set_row_column(row, COLUMN_NLMLOGENGINETDOMAIN,
652 ASN_OBJECT_ID,
653 transport->domain,
654 sizeof(oid) * transport->domain_length);
655 netsnmp_set_row_column(row, COLUMN_NLMLOGCONTEXTENGINEID,
656 ASN_OCTET_STR, pdu->contextEngineID,
657 pdu->contextEngineIDLen);
658 netsnmp_set_row_column(row, COLUMN_NLMLOGCONTEXTNAME, ASN_OCTET_STR,
659 pdu->contextName, pdu->contextNameLen);
660
661 if (pdu->command == SNMP_MSG_TRAP)
662 pdu = convert_v1pdu_to_v2(orig_pdu);
663 for (vptr = pdu->variables; vptr; vptr = vptr->next_variable) {
664 if (snmp_oid_compare(snmptrapoid, snmptrapoid_len,
665 vptr->name, vptr->name_length) == 0) {
666 netsnmp_set_row_column(row, COLUMN_NLMLOGNOTIFICATIONID,
667 ASN_OBJECT_ID, vptr->val.string,
668 vptr->val_len);
669 } else {
670 netsnmp_table_row *myrow;
671 myrow = netsnmp_create_table_data_row();
672
673 /*
674 * indexes to the table
675 */
676 netsnmp_table_row_add_index(myrow, ASN_OCTET_STR, "default",
677 strlen("default"));
678 netsnmp_table_row_add_index(myrow, ASN_UNSIGNED, &default_num,
679 sizeof(default_num));
680 vbcount++;
681 netsnmp_table_row_add_index(myrow, ASN_UNSIGNED, &vbcount,
682 sizeof(vbcount));
683
684 /*
685 * OID
686 */
687 netsnmp_set_row_column(myrow, COLUMN_NLMLOGVARIABLEID,
688 ASN_OBJECT_ID, vptr->name,
689 vptr->name_length * sizeof(oid));
690
691 /*
692 * value
693 */
694 switch (vptr->type) {
695 case ASN_OBJECT_ID:
696 tmpul = 7;
697 col = COLUMN_NLMLOGVARIABLEOIDVAL;
698 break;
699
700 case ASN_INTEGER:
701 tmpul = 4;
702 col = COLUMN_NLMLOGVARIABLEINTEGER32VAL;
703 break;
704
705 case ASN_UNSIGNED:
706 tmpul = 2;
707 col = COLUMN_NLMLOGVARIABLEUNSIGNED32VAL;
708 break;
709
710 case ASN_COUNTER:
711 tmpul = 1;
712 col = COLUMN_NLMLOGVARIABLECOUNTER32VAL;
713 break;
714
715 case ASN_TIMETICKS:
716 tmpul = 3;
717 col = COLUMN_NLMLOGVARIABLETIMETICKSVAL;
718 break;
719
720 case ASN_OCTET_STR:
721 tmpul = 6;
722 col = COLUMN_NLMLOGVARIABLEOCTETSTRINGVAL;
723 break;
724
725 case ASN_IPADDRESS:
726 tmpul = 5;
727 col = COLUMN_NLMLOGVARIABLEIPADDRESSVAL;
728 break;
729
730 case ASN_COUNTER64:
731 tmpul = 8;
732 col = COLUMN_NLMLOGVARIABLECOUNTER64VAL;
733 break;
734
735 case ASN_OPAQUE:
736 tmpul = 9;
737 col = COLUMN_NLMLOGVARIABLEOPAQUEVAL;
738 break;
739
740 default:
741 /*
742 * unsupported
743 */
744 DEBUGMSGTL(("notification_log",
745 "skipping type %d\n", vptr->type));
746 (void)netsnmp_table_dataset_delete_row(myrow);
747 continue;
748 }
749 netsnmp_set_row_column(myrow, COLUMN_NLMLOGVARIABLEVALUETYPE,
750 ASN_INTEGER, & tmpul,
751 sizeof(tmpul));
752 netsnmp_set_row_column(myrow, col, vptr->type,
753 vptr->val.string, vptr->val_len);
754 DEBUGMSGTL(("notification_log",
755 "adding a row to the variables table\n"));
756 netsnmp_table_dataset_add_row(nlmLogVarTable, myrow);
757 }
758 }
759
760 if (pdu != orig_pdu)
761 snmp_free_pdu( pdu );
762
763 /*
764 * store the row
765 */
766 netsnmp_table_dataset_add_row(nlmLogTable, row);
767
768 check_log_size(0, NULL);
769 DEBUGMSGTL(("notification_log", "done logging something\n"));
770 }
771