void snmp_enable_syslog_ident(const char *ident, const int facility) { netsnmp_log_handler *logh; int found = 0; int enable = 1; #ifdef WIN32 HANDLE eventlog_h; #else void *eventlog_h = NULL; #endif snmp_disable_syslog(); /* only one syslog at a time */ #ifdef WIN32 eventlog_h = OpenEventLog(NULL, ident); if (eventlog_h == NULL) { /* * Hmmm..... * Maybe disable this handler, and log the error ? */ fprintf(stderr, "Could not open event log for %s. " "Last error: 0x%x\n", ident, GetLastError()); enable = 0; } #else openlog(snmp_log_syslogname(ident), LOG_CONS | LOG_PID, facility); #endif for (logh = logh_head; logh; logh = logh->next) if (logh->type == NETSNMP_LOGHANDLER_SYSLOG) { logh->magic = (void*)eventlog_h; logh->imagic = enable; /* syslog open */ if (logh->enabled && (0 == enable)) netsnmp_disable_this_loghandler(logh); else if ((0 == logh->enabled) && enable) netsnmp_enable_this_loghandler(logh); found = 1; } if (!found) { logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_SYSLOG, LOG_DEBUG ); if (logh) { logh->magic = (void*)eventlog_h; logh->token = strdup(ident); logh->imagic = enable; /* syslog open */ if (logh->enabled && (0 == enable)) netsnmp_disable_this_loghandler(logh); else if ((0 == logh->enabled) && enable) netsnmp_enable_this_loghandler(logh); } } }
netsnmp_log_handler * netsnmp_register_loghandler( int type, int priority ) { netsnmp_log_handler *logh; logh = SNMP_MALLOC_TYPEDEF(netsnmp_log_handler); if (!logh) return NULL; DEBUGMSGT(("logging:register", "registering log type %d with pri %d\n", type, priority)); if (priority > LOG_DEBUG) { DEBUGMSGT(("logging:register", " limiting pri %d to %d\n", priority, LOG_DEBUG)); priority = LOG_DEBUG; } logh->type = type; switch ( type ) { case NETSNMP_LOGHANDLER_STDOUT: logh->imagic = 1; logh->handler = log_handler_stdouterr; break; #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_STDIO case NETSNMP_LOGHANDLER_STDERR: logh->handler = log_handler_stdouterr; break; #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */ #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_FILE case NETSNMP_LOGHANDLER_FILE: logh->handler = log_handler_file; logh->imagic = 1; break; #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_FILE */ #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG case NETSNMP_LOGHANDLER_SYSLOG: logh->handler = log_handler_syslog; break; #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */ case NETSNMP_LOGHANDLER_CALLBACK: logh->handler = log_handler_callback; break; case NETSNMP_LOGHANDLER_NONE: logh->handler = log_handler_null; break; default: free(logh); return NULL; } logh->priority = priority; netsnmp_enable_this_loghandler(logh); netsnmp_add_loghandler( logh ); return logh; }
int netsnmp_enable_loghandler( const char *token ) { netsnmp_log_handler *logh; logh = netsnmp_find_loghandler( token ); if (!logh) return 0; netsnmp_enable_this_loghandler(logh); return 1; }
void snmp_enable_calllog(void) /* XXX - or take a callback routine ??? */ { netsnmp_log_handler *logh; int found = 0; for (logh = logh_head; logh; logh = logh->next) if (logh->type == NETSNMP_LOGHANDLER_CALLBACK) { netsnmp_enable_this_loghandler(logh); found = 1; } if (!found) { logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_CALLBACK, LOG_DEBUG ); if (logh) logh->token = strdup("callback"); } }
void netsnmp_enable_filelog(netsnmp_log_handler *logh, int dont_zero_log) { FILE *logfile; if (!logh) return; if (!logh->magic) { logfile = fopen(logh->token, dont_zero_log ? "a" : "w"); if (!logfile) { snmp_log_perror(logh->token); return; } logh->magic = (void*)logfile; netsnmp_set_line_buffering(logfile); } netsnmp_enable_this_loghandler(logh); }
netsnmp_log_handler * netsnmp_register_loghandler( int type, int priority ) { netsnmp_log_handler *logh; logh = SNMP_MALLOC_TYPEDEF(netsnmp_log_handler); if (!logh) return NULL; DEBUGMSGT(("logging:register", "registering log type %d with pri %d\n", type, priority)); logh->type = type; switch ( type ) { case NETSNMP_LOGHANDLER_STDOUT: logh->imagic = 1; /* fallthrough */ case NETSNMP_LOGHANDLER_STDERR: logh->handler = log_handler_stdouterr; break; case NETSNMP_LOGHANDLER_FILE: logh->handler = log_handler_file; logh->imagic = 1; break; case NETSNMP_LOGHANDLER_SYSLOG: logh->handler = log_handler_syslog; break; case NETSNMP_LOGHANDLER_CALLBACK: logh->handler = log_handler_callback; break; case NETSNMP_LOGHANDLER_NONE: logh->handler = log_handler_null; break; default: free(logh); return NULL; } logh->priority = priority; netsnmp_enable_this_loghandler(logh); netsnmp_add_loghandler( logh ); return logh; }
/* used in the perl modules and ip-mib/ipv4InterfaceTable/ipv4InterfaceTable_subagent.c */ void snmp_enable_stderrlog(void) { netsnmp_log_handler *logh; int found = 0; for (logh = logh_head; logh; logh = logh->next) if (logh->type == NETSNMP_LOGHANDLER_STDOUT || logh->type == NETSNMP_LOGHANDLER_STDERR) { netsnmp_enable_this_loghandler(logh); found = 1; } if (!found) { logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_STDERR, LOG_DEBUG ); if (logh) logh->token = strdup("stderr"); } }
int handle_nsLoggingTable(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { long temp; netsnmp_request_info *request = NULL; netsnmp_table_request_info *table_info = NULL; netsnmp_log_handler *logh = NULL; netsnmp_variable_list *idx = NULL; switch (reqinfo->mode) { case MODE_GET: for (request=requests; request; request=request->next) { if (request->processed != 0) continue; logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case NSLOGGING_TYPE: if (!logh) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } temp = logh->type; snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char*)&temp, sizeof(temp)); break; case NSLOGGING_MAXLEVEL: if (!logh) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } temp = logh->pri_max; snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char*)&temp, sizeof(temp)); break; case NSLOGGING_STATUS: if (!logh) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } temp = (logh->type ? (logh->enabled ? RS_ACTIVE: RS_NOTINSERVICE) : RS_NOTREADY); snmp_set_var_typed_value(request->requestvb, ASN_INTEGER, (u_char*)&temp, sizeof(temp)); break; default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); continue; } } break; #ifndef NETSNMP_NO_WRITE_SUPPORT case MODE_SET_RESERVE1: for (request=requests; request; request=request->next) { if ( request->status != 0 ) { return SNMP_ERR_NOERROR; /* Already got an error */ } logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case NSLOGGING_TYPE: if ( request->requestvb->type != ASN_INTEGER ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); return SNMP_ERR_WRONGTYPE; } if (*request->requestvb->val.integer < 0 ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE); return SNMP_ERR_WRONGVALUE; } /* * It's OK to create a new logging entry * (either in one go, or built up using createAndWait) * but it's not possible to change the type of an entry * once it's been created. */ if (logh && logh->type) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE); return SNMP_ERR_NOTWRITABLE; } break; case NSLOGGING_MAXLEVEL: if ( request->requestvb->type != ASN_INTEGER ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); return SNMP_ERR_WRONGTYPE; } if (*request->requestvb->val.integer < 0 || *request->requestvb->val.integer > 7 ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE); return SNMP_ERR_WRONGVALUE; } break; case NSLOGGING_STATUS: if ( request->requestvb->type != ASN_INTEGER ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); return SNMP_ERR_WRONGTYPE; } switch ( *request->requestvb->val.integer ) { case RS_ACTIVE: case RS_NOTINSERVICE: /* * Can only work on existing rows */ if (!logh) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_INCONSISTENTVALUE; } break; case RS_CREATEANDWAIT: case RS_CREATEANDGO: /* * Can only work with new rows */ if (logh) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_INCONSISTENTVALUE; } /* * Normally, we'd create the row at a later stage * (probably during the RESERVE2 or ACTION passes) * * But we need to check that the values are * consistent during the ACTION pass (which is the * latest that an error can be safely handled), * so the values all need to be set up before this * (i.e. during the RESERVE2 pass) * So the new row needs to be created before that * in order to have somewhere to put them. * * That's why we're doing this here. */ idx = table_info->indexes; logh = netsnmp_register_loghandler( /* not really, but we need a valid type */ NETSNMP_LOGHANDLER_STDOUT, *idx->val.integer); if (!logh) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); /* ??? */ return SNMP_ERR_GENERR; } idx = idx->next_variable; logh->type = 0; logh->token = strdup((char *) idx->val.string); netsnmp_insert_iterator_context(request, (void*)logh); break; case RS_DESTROY: /* * Can work with new or existing rows */ break; case RS_NOTREADY: default: netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE); return SNMP_ERR_WRONGVALUE; } break; default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); return SNMP_NOSUCHOBJECT; } } break; case MODE_SET_RESERVE2: for (request=requests; request; request=request->next) { if ( request->status != 0 ) { return SNMP_ERR_NOERROR; /* Already got an error */ } logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case NSLOGGING_TYPE: /* * If we're creating a row using createAndGo, * we need to set the type early, so that we * can validate it in the ACTION pass. * * Remember that we need to be able to reverse this */ if ( logh ) logh->type = *request->requestvb->val.integer; break; /* * Don't need to handle nsLogToken or nsLogStatus in this pass */ } } break; case MODE_SET_ACTION: for (request=requests; request; request=request->next) { if (request->processed != 0) continue; if ( request->status != 0 ) { return SNMP_ERR_NOERROR; /* Already got an error */ } logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case NSLOGGING_STATUS: /* * This is where we can check the internal consistency * of the request. Basically, for a row to be marked * 'active', then there needs to be a valid type value. */ switch ( *request->requestvb->val.integer ) { case RS_ACTIVE: case RS_CREATEANDGO: if ( !logh || !logh->type ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); return SNMP_ERR_INCONSISTENTVALUE; } break; } break; /* * Don't need to handle nsLogToken or nsLogType in this pass */ } } break; case MODE_SET_FREE: case MODE_SET_UNDO: /* * If any resources were allocated in either of the * two RESERVE passes, they need to be released here, * and any assignments (in RESERVE2) reversed. * * Nothing additional will have been done during ACTION * so this same code can do for UNDO as well. */ for (request=requests; request; request=request->next) { if (request->processed != 0) continue; logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case NSLOGGING_TYPE: /* * If we've been setting the type, and the request * has failed, then revert to an unset type. * * We need to be careful here - if the reason it failed is * that the type was already set, then we shouldn't "undo" * the assignment (since it won't actually have been made). * * Check the current value against the 'new' one. If they're * the same, then this is probably a successful assignment, * and the failure was elsewhere, so we need to undo it. * (Or else there was an attempt to write the same value!) */ if ( logh && logh->type == *request->requestvb->val.integer ) logh->type = 0; break; case NSLOGGING_STATUS: temp = *request->requestvb->val.integer; if ( logh && ( temp == RS_CREATEANDGO || temp == RS_CREATEANDWAIT)) { netsnmp_remove_loghandler( logh ); } break; /* * Don't need to handle nsLogToken in this pass */ } } break; case MODE_SET_COMMIT: for (request=requests; request; request=request->next) { if (request->processed != 0) continue; if ( request->status != 0 ) { return SNMP_ERR_NOERROR; /* Already got an error */ } logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request); if (!logh) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_COMMITFAILED); return SNMP_ERR_COMMITFAILED; /* Shouldn't happen! */ } table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case NSLOGGING_MAXLEVEL: logh->pri_max = *request->requestvb->val.integer; break; case NSLOGGING_STATUS: switch (*request->requestvb->val.integer) { case RS_ACTIVE: case RS_CREATEANDGO: netsnmp_enable_this_loghandler(logh); break; case RS_NOTINSERVICE: case RS_CREATEANDWAIT: netsnmp_disable_this_loghandler(logh); break; case RS_DESTROY: netsnmp_remove_loghandler( logh ); break; } break; } } break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } return SNMP_ERR_NOERROR; }