1 #include <net-snmp/net-snmp-config.h>
5 #include <netinet/in.h>
11 #include <net-snmp/net-snmp-includes.h>
12 #include <net-snmp/agent/net-snmp-agent-includes.h>
13 #include <net-snmp/agent/instance.h>
14 #include <net-snmp/agent/table.h>
15 #include <net-snmp/agent/table_data.h>
16 #include <net-snmp/agent/table_dataset.h>
17 #include "notification_log.h"
19 extern u_long num_received;
20 u_long num_deleted = 0;
22 u_long max_logged = 1000; /* goes against the mib default of infinite */
23 u_long max_age = 1440; /* 24 hours, which is the mib default */
25 netsnmp_table_data_set *nlmLogTable;
26 netsnmp_table_data_set *nlmLogVarTable;
29 check_log_size(unsigned int clientreg, void *clientarg)
31 netsnmp_table_row *row, *deleterow, *tmprow, *deletevarrow;
32 netsnmp_table_data_set_storage *data;
37 gettimeofday(&now, NULL);
38 tmpl = netsnmp_timeval_uptime(&now);
40 for (row = nlmLogTable->table->first_row; row; row = row->next) {
42 * check max allowed count
45 if (max_logged && count == max_logged)
52 data = (netsnmp_table_data_set_storage *) row->data;
53 data = netsnmp_table_data_set_find_column(data, COLUMN_NLMLOGTIME);
55 if (max_age && tmpl > (*(data->data.integer) + max_age * 100 * 60))
63 * we've reached the limit, so keep looping but start deleting
66 for (deleterow = nlmLogTable->table->first_row, row = row->next; row;
68 DEBUGMSGTL(("notification_log", "deleting a log entry\n"));
71 * delete contained varbinds
73 for (deletevarrow = nlmLogVarTable->table->first_row;
74 deletevarrow; deletevarrow = tmprow) {
76 tmprow = deletevarrow->next;
78 if (deleterow->index_oid_len ==
79 deletevarrow->index_oid_len - 1 &&
80 snmp_oid_compare(deleterow->index_oid,
81 deleterow->index_oid_len,
82 deletevarrow->index_oid,
83 deleterow->index_oid_len) == 0) {
84 netsnmp_table_dataset_remove_and_delete_row(nlmLogVarTable,
90 * delete the master row
92 tmprow = deleterow->next;
93 netsnmp_table_dataset_remove_and_delete_row(nlmLogTable,
98 * XXX: delete vars from it's table
104 /** Initialize the nlmLogVariableTable table by defining it's contents and how it's structured */
106 initialize_table_nlmLogVariableTable(void)
108 static oid nlmLogVariableTable_oid[] =
109 { 1, 3, 6, 1, 2, 1, 92, 1, 3, 2 };
110 size_t nlmLogVariableTable_oid_len =
111 OID_LENGTH(nlmLogVariableTable_oid);
112 netsnmp_table_data_set *table_set;
115 * create the table structure itself
117 table_set = netsnmp_create_table_data_set("nlmLogVariableTable");
118 nlmLogVarTable = table_set;
119 nlmLogVarTable->table->store_indexes = 1;
121 /***************************************************
125 * declaring the nlmLogName index
127 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
128 "adding index nlmLogName of type ASN_OCTET_STR to table nlmLogVariableTable\n"));
129 netsnmp_table_dataset_add_index(table_set, ASN_OCTET_STR);
131 * declaring the nlmLogIndex index
133 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
134 "adding index nlmLogIndex of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
135 netsnmp_table_dataset_add_index(table_set, ASN_UNSIGNED);
137 * declaring the nlmLogVariableIndex index
139 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
140 "adding index nlmLogVariableIndex of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
141 netsnmp_table_dataset_add_index(table_set, ASN_UNSIGNED);
144 * adding column nlmLogVariableIndex of type ASN_UNSIGNED and access
147 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
148 "adding column nlmLogVariableIndex (#1) of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
149 netsnmp_table_set_add_default_row(table_set,
150 COLUMN_NLMLOGVARIABLEINDEX,
151 ASN_UNSIGNED, 0, NULL, 0);
153 * adding column nlmLogVariableID of type ASN_OBJECT_ID and access of
156 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
157 "adding column nlmLogVariableID (#2) of type ASN_OBJECT_ID to table nlmLogVariableTable\n"));
158 netsnmp_table_set_add_default_row(table_set, COLUMN_NLMLOGVARIABLEID,
159 ASN_OBJECT_ID, 0, NULL, 0);
161 * adding column nlmLogVariableValueType of type ASN_INTEGER and
164 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
165 "adding column nlmLogVariableValueType (#3) of type ASN_INTEGER to table nlmLogVariableTable\n"));
166 netsnmp_table_set_add_default_row(table_set,
167 COLUMN_NLMLOGVARIABLEVALUETYPE,
168 ASN_INTEGER, 0, NULL, 0);
170 * adding column nlmLogVariableCounter32Val of type ASN_COUNTER and
173 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
174 "adding column nlmLogVariableCounter32Val (#4) of type ASN_COUNTER to table nlmLogVariableTable\n"));
175 netsnmp_table_set_add_default_row(table_set,
176 COLUMN_NLMLOGVARIABLECOUNTER32VAL,
177 ASN_COUNTER, 0, NULL, 0);
179 * adding column nlmLogVariableUnsigned32Val of type ASN_UNSIGNED and
182 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
183 "adding column nlmLogVariableUnsigned32Val (#5) of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
184 netsnmp_table_set_add_default_row(table_set,
185 COLUMN_NLMLOGVARIABLEUNSIGNED32VAL,
186 ASN_UNSIGNED, 0, NULL, 0);
188 * adding column nlmLogVariableTimeTicksVal of type ASN_TIMETICKS and
191 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
192 "adding column nlmLogVariableTimeTicksVal (#6) of type ASN_TIMETICKS to table nlmLogVariableTable\n"));
193 netsnmp_table_set_add_default_row(table_set,
194 COLUMN_NLMLOGVARIABLETIMETICKSVAL,
195 ASN_TIMETICKS, 0, NULL, 0);
197 * adding column nlmLogVariableInteger32Val of type ASN_INTEGER and
200 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
201 "adding column nlmLogVariableInteger32Val (#7) of type ASN_INTEGER to table nlmLogVariableTable\n"));
202 netsnmp_table_set_add_default_row(table_set,
203 COLUMN_NLMLOGVARIABLEINTEGER32VAL,
204 ASN_INTEGER, 0, NULL, 0);
206 * adding column nlmLogVariableOctetStringVal of type ASN_OCTET_STR
207 * and access of ReadOnly
209 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
210 "adding column nlmLogVariableOctetStringVal (#8) of type ASN_OCTET_STR to table nlmLogVariableTable\n"));
211 netsnmp_table_set_add_default_row(table_set,
212 COLUMN_NLMLOGVARIABLEOCTETSTRINGVAL,
213 ASN_OCTET_STR, 0, NULL, 0);
215 * adding column nlmLogVariableIpAddressVal of type ASN_IPADDRESS and
218 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
219 "adding column nlmLogVariableIpAddressVal (#9) of type ASN_IPADDRESS to table nlmLogVariableTable\n"));
220 netsnmp_table_set_add_default_row(table_set,
221 COLUMN_NLMLOGVARIABLEIPADDRESSVAL,
222 ASN_IPADDRESS, 0, NULL, 0);
224 * adding column nlmLogVariableOidVal of type ASN_OBJECT_ID and access
227 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
228 "adding column nlmLogVariableOidVal (#10) of type ASN_OBJECT_ID to table nlmLogVariableTable\n"));
229 netsnmp_table_set_add_default_row(table_set,
230 COLUMN_NLMLOGVARIABLEOIDVAL,
231 ASN_OBJECT_ID, 0, NULL, 0);
233 * adding column nlmLogVariableCounter64Val of type ASN_COUNTER64 and
236 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
237 "adding column nlmLogVariableCounter64Val (#11) of type ASN_COUNTER64 to table nlmLogVariableTable\n"));
238 netsnmp_table_set_add_default_row(table_set,
239 COLUMN_NLMLOGVARIABLECOUNTER64VAL,
240 ASN_COUNTER64, 0, NULL, 0);
242 * adding column nlmLogVariableOpaqueVal of type ASN_OPAQUE and access
245 DEBUGMSGTL(("initialize_table_nlmLogVariableTable",
246 "adding column nlmLogVariableOpaqueVal (#12) of type ASN_OPAQUE to table nlmLogVariableTable\n"));
247 netsnmp_table_set_add_default_row(table_set,
248 COLUMN_NLMLOGVARIABLEOPAQUEVAL,
249 ASN_OPAQUE, 0, NULL, 0);
252 * registering the table with the master agent
255 * note: if you don't need a subhandler to deal with any aspects of
256 * the request, change nlmLogVariableTable_handler to "NULL"
258 netsnmp_register_table_data_set(netsnmp_create_handler_registration
259 ("nlmLogVariableTable",
260 nlmLogVariableTable_handler,
261 nlmLogVariableTable_oid,
262 nlmLogVariableTable_oid_len,
263 HANDLER_CAN_RWRITE), table_set, NULL);
266 /** Initialize the nlmLogTable table by defining it's contents and how it's structured */
268 initialize_table_nlmLogTable(void)
270 static oid nlmLogTable_oid[] = { 1, 3, 6, 1, 2, 1, 92, 1, 3, 1 };
271 size_t nlmLogTable_oid_len = OID_LENGTH(nlmLogTable_oid);
274 * create the table structure itself
276 nlmLogTable = netsnmp_create_table_data_set("nlmLogTable");
278 /***************************************************
282 * declaring the nlmLogIndex index
284 DEBUGMSGTL(("initialize_table_nlmLogTable",
285 "adding index nlmLogName of type ASN_OCTET_STR to table nlmLogTable\n"));
286 netsnmp_table_dataset_add_index(nlmLogTable, ASN_OCTET_STR);
288 DEBUGMSGTL(("initialize_table_nlmLogTable",
289 "adding index nlmLogIndex of type ASN_UNSIGNED to table nlmLogTable\n"));
290 netsnmp_table_dataset_add_index(nlmLogTable, ASN_UNSIGNED);
293 * adding column nlmLogTime of type ASN_TIMETICKS and access of
296 DEBUGMSGTL(("initialize_table_nlmLogTable",
297 "adding column nlmLogTime (#2) of type ASN_TIMETICKS to table nlmLogTable\n"));
298 netsnmp_table_set_add_default_row(nlmLogTable, COLUMN_NLMLOGTIME,
299 ASN_TIMETICKS, 0, NULL, 0);
301 * adding column nlmLogDateAndTime of type ASN_OCTET_STR and access of
304 DEBUGMSGTL(("initialize_table_nlmLogTable",
305 "adding column nlmLogDateAndTime (#3) of type ASN_OCTET_STR to table nlmLogTable\n"));
306 netsnmp_table_set_add_default_row(nlmLogTable,
307 COLUMN_NLMLOGDATEANDTIME,
308 ASN_OCTET_STR, 0, NULL, 0);
310 * adding column nlmLogEngineID of type ASN_OCTET_STR and access of
313 DEBUGMSGTL(("initialize_table_nlmLogTable",
314 "adding column nlmLogEngineID (#4) of type ASN_OCTET_STR to table nlmLogTable\n"));
315 netsnmp_table_set_add_default_row(nlmLogTable, COLUMN_NLMLOGENGINEID,
316 ASN_OCTET_STR, 0, NULL, 0);
318 * adding column nlmLogEngineTAddress of type ASN_OCTET_STR and access
321 DEBUGMSGTL(("initialize_table_nlmLogTable",
322 "adding column nlmLogEngineTAddress (#5) of type ASN_OCTET_STR to table nlmLogTable\n"));
323 netsnmp_table_set_add_default_row(nlmLogTable,
324 COLUMN_NLMLOGENGINETADDRESS,
325 ASN_OCTET_STR, 0, NULL, 0);
327 * adding column nlmLogEngineTDomain of type ASN_OBJECT_ID and access
330 DEBUGMSGTL(("initialize_table_nlmLogTable",
331 "adding column nlmLogEngineTDomain (#6) of type ASN_OBJECT_ID to table nlmLogTable\n"));
332 netsnmp_table_set_add_default_row(nlmLogTable,
333 COLUMN_NLMLOGENGINETDOMAIN,
334 ASN_OBJECT_ID, 0, NULL, 0);
336 * adding column nlmLogContextEngineID of type ASN_OCTET_STR and
339 DEBUGMSGTL(("initialize_table_nlmLogTable",
340 "adding column nlmLogContextEngineID (#7) of type ASN_OCTET_STR to table nlmLogTable\n"));
341 netsnmp_table_set_add_default_row(nlmLogTable,
342 COLUMN_NLMLOGCONTEXTENGINEID,
343 ASN_OCTET_STR, 0, NULL, 0);
345 * adding column nlmLogContextName of type ASN_OCTET_STR and access of
348 DEBUGMSGTL(("initialize_table_nlmLogTable",
349 "adding column nlmLogContextName (#8) of type ASN_OCTET_STR to table nlmLogTable\n"));
350 netsnmp_table_set_add_default_row(nlmLogTable,
351 COLUMN_NLMLOGCONTEXTNAME,
352 ASN_OCTET_STR, 0, NULL, 0);
354 * adding column nlmLogNotificationID of type ASN_OBJECT_ID and access
357 DEBUGMSGTL(("initialize_table_nlmLogTable",
358 "adding column nlmLogNotificationID (#9) of type ASN_OBJECT_ID to table nlmLogTable\n"));
359 netsnmp_table_set_add_default_row(nlmLogTable,
360 COLUMN_NLMLOGNOTIFICATIONID,
361 ASN_OBJECT_ID, 0, NULL, 0);
364 * registering the table with the master agent
367 * note: if you don't need a subhandler to deal with any aspects of
368 * the request, change nlmLogTable_handler to "NULL"
370 netsnmp_register_table_data_set(netsnmp_create_handler_registration
371 ("nlmLogTable", nlmLogTable_handler,
372 nlmLogTable_oid, nlmLogTable_oid_len,
373 HANDLER_CAN_RWRITE), nlmLogTable,
377 * hmm... 5 minutes seems like a reasonable time to check for out
378 * dated notification logs right?
380 snmp_alarm_register(300, SA_REPEAT, check_log_size, NULL);
384 notification_log_config_handler(netsnmp_mib_handler *handler,
385 netsnmp_handler_registration *reginfo,
386 netsnmp_agent_request_info *reqinfo,
387 netsnmp_request_info *requests)
390 *this handler exists only to act as a trigger when the
391 * configuration variables get set to a value and thus
392 * notifications must be possibly deleted from our archives.
394 if (reqinfo->mode == MODE_SET_COMMIT)
395 check_log_size(0, NULL);
396 return SNMP_ERR_NOERROR;
400 init_notification_log(void)
402 static oid my_nlmStatsGlobalNotificationsLogged_oid[] =
403 { 1, 3, 6, 1, 2, 1, 92, 1, 2, 1, 0 };
404 static oid my_nlmStatsGlobalNotificationsBumped_oid[] =
405 { 1, 3, 6, 1, 2, 1, 92, 1, 2, 2, 0 };
406 static oid my_nlmConfigGlobalEntryLimit_oid[] =
407 { 1, 3, 6, 1, 2, 1, 92, 1, 1, 1, 0 };
408 static oid my_nlmConfigGlobalAgeOut_oid[] =
409 { 1, 3, 6, 1, 2, 1, 92, 1, 1, 2, 0 };
414 netsnmp_register_read_only_counter32_instance
415 ("nlmStatsGlobalNotificationsLogged",
416 my_nlmStatsGlobalNotificationsLogged_oid,
417 OID_LENGTH(my_nlmStatsGlobalNotificationsLogged_oid),
418 &num_received, NULL);
420 netsnmp_register_read_only_counter32_instance
421 ("nlmStatsGlobalNotificationsBumped",
422 my_nlmStatsGlobalNotificationsBumped_oid,
423 OID_LENGTH(my_nlmStatsGlobalNotificationsBumped_oid),
426 netsnmp_register_ulong_instance("nlmConfigGlobalEntryLimit",
427 my_nlmConfigGlobalEntryLimit_oid,
429 (my_nlmConfigGlobalEntryLimit_oid),
431 notification_log_config_handler);
433 netsnmp_register_ulong_instance("nlmConfigGlobalAgeOut",
434 my_nlmConfigGlobalAgeOut_oid,
436 (my_nlmConfigGlobalAgeOut_oid),
438 notification_log_config_handler);
443 initialize_table_nlmLogTable();
444 initialize_table_nlmLogVariableTable();
449 netsnmp_ds_register_config(ASN_BOOLEAN, "snmptrapd", "dontRetainLogs",
450 NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_APP_DONT_LOG);
453 u_long default_num = 0;
456 log_notification(struct hostent *host, netsnmp_pdu *pdu,
457 netsnmp_transport *transport)
461 netsnmp_table_row *row;
463 static oid snmptrapoid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
464 size_t snmptrapoid_len = OID_LENGTH(snmptrapoid);
465 netsnmp_variable_list *vptr;
474 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
475 NETSNMP_DS_APP_DONT_LOG)) {
479 DEBUGMSGTL(("log_notification", "logging something\n"));
480 row = netsnmp_create_table_data_row();
485 * indexes to the table
487 netsnmp_table_row_add_index(row, ASN_OCTET_STR, "default",
489 netsnmp_table_row_add_index(row, ASN_UNSIGNED, &default_num,
490 sizeof(default_num));
495 gettimeofday(&now, NULL);
496 tmpl = netsnmp_timeval_uptime(&now);
497 netsnmp_set_row_column(row, COLUMN_NLMLOGTIME, ASN_TIMETICKS,
498 (u_char *) & tmpl, sizeof(tmpl));
500 logdate = date_n_time(&timetnow, &logdate_size);
501 netsnmp_set_row_column(row, COLUMN_NLMLOGDATEANDTIME, ASN_OCTET_STR,
502 logdate, logdate_size);
503 netsnmp_set_row_column(row, COLUMN_NLMLOGENGINEID, ASN_OCTET_STR,
504 pdu->securityEngineID,
505 pdu->securityEngineIDLen);
506 if (transport && transport->domain == netsnmpUDPDomain) {
508 * lame way to check for the udp domain
511 * no, it is the correct way to do it -- jbpn
513 struct sockaddr_in *addr =
514 (struct sockaddr_in *) pdu->transport_data;
516 char buf[sizeof(in_addr_t) +
517 sizeof(addr->sin_port)];
518 in_addr_t locaddr = htonl(addr->sin_addr.s_addr);
519 u_short portnum = htons(addr->sin_port);
520 memcpy(buf, &locaddr, sizeof(in_addr_t));
521 memcpy(buf + sizeof(in_addr_t), &portnum,
522 sizeof(addr->sin_port));
523 netsnmp_set_row_column(row, COLUMN_NLMLOGENGINETADDRESS,
526 sizeof(addr->sin_port));
529 netsnmp_set_row_column(row, COLUMN_NLMLOGENGINETDOMAIN, ASN_OBJECT_ID,
530 (const u_char *) transport->domain,
531 sizeof(oid) * transport->domain_length);
532 netsnmp_set_row_column(row, COLUMN_NLMLOGCONTEXTENGINEID,
533 ASN_OCTET_STR, pdu->contextEngineID,
534 pdu->contextEngineIDLen);
535 netsnmp_set_row_column(row, COLUMN_NLMLOGCONTEXTNAME, ASN_OCTET_STR,
536 pdu->contextName, pdu->contextNameLen);
537 for (vptr = pdu->variables; vptr; vptr = vptr->next_variable) {
538 if (snmp_oid_compare(snmptrapoid, snmptrapoid_len,
539 vptr->name, vptr->name_length) == 0) {
540 netsnmp_set_row_column(row, COLUMN_NLMLOGNOTIFICATIONID,
541 ASN_OBJECT_ID, vptr->val.string,
545 netsnmp_table_row *myrow;
546 myrow = netsnmp_create_table_data_row();
549 * indexes to the table
551 netsnmp_table_row_add_index(myrow, ASN_OCTET_STR, "default",
553 netsnmp_table_row_add_index(myrow, ASN_UNSIGNED, &default_num,
554 sizeof(default_num));
556 netsnmp_table_row_add_index(myrow, ASN_UNSIGNED, &vbcount,
562 netsnmp_set_row_column(myrow, COLUMN_NLMLOGVARIABLEID,
563 ASN_OBJECT_ID, (u_char *) vptr->name,
564 vptr->name_length * sizeof(oid));
569 switch (vptr->type) {
572 col = COLUMN_NLMLOGVARIABLEOIDVAL;
577 col = COLUMN_NLMLOGVARIABLEINTEGER32VAL;
582 col = COLUMN_NLMLOGVARIABLEUNSIGNED32VAL;
587 col = COLUMN_NLMLOGVARIABLECOUNTER32VAL;
592 col = COLUMN_NLMLOGVARIABLETIMETICKSVAL;
597 col = COLUMN_NLMLOGVARIABLEOCTETSTRINGVAL;
604 DEBUGMSGTL(("log_notification",
605 "skipping type %d\n", vptr->type));
608 netsnmp_set_row_column(myrow, COLUMN_NLMLOGVARIABLEVALUETYPE,
609 ASN_INTEGER, (u_char *) & tmpul,
611 netsnmp_set_row_column(myrow, col, vptr->type,
612 vptr->val.string, vptr->val_len);
613 DEBUGMSGTL(("log_notification",
614 "adding a row to the variables table\n"));
615 netsnmp_table_dataset_add_row(nlmLogVarTable, myrow);
622 netsnmp_table_dataset_add_row(nlmLogTable, row);
624 check_log_size(0, NULL);
625 DEBUGMSGTL(("log_notification", "done logging something\n"));
628 /** handles requests for the nlmLogTable table, if anything else needs to be done */
630 nlmLogTable_handler(netsnmp_mib_handler *handler,
631 netsnmp_handler_registration *reginfo,
632 netsnmp_agent_request_info *reqinfo,
633 netsnmp_request_info *requests)
636 * perform anything here that you need to do. The requests have
637 * already been processed by the master table_dataset handler, but
638 * this gives you chance to act on the request in some other way if
641 return SNMP_ERR_NOERROR;
644 /** handles requests for the nlmLogVariableTable table, if anything else needs to be done */
646 nlmLogVariableTable_handler(netsnmp_mib_handler *handler,
647 netsnmp_handler_registration *reginfo,
648 netsnmp_agent_request_info *reqinfo,
649 netsnmp_request_info *requests)
652 * perform anything here that you need to do. The requests have
653 * already been processed by the master table_dataset handler, but
654 * this gives you chance to act on the request in some other way if
657 return SNMP_ERR_NOERROR;