/*-------------------------------------------------------------------------- podunk_rr.c - code to extend UCD-SNMP agent for PODUNK-RR-MIB Compiled inside the ucd-snmp source tree To extend this MIB with another variable in an existing table or row, no editing of this file is required; just run mib2h.pl again and recompile. To extend this MIB with another table or row (or scalar row), edit this file to add a section for that table or row. (Yeah, that should be automated by mib2h.pl. So FIXME.) --------------------------------------------------------------------------*/ /* I'd rather include the following two .h files within fsubagent_utils.h * and podunk_rr.h, which need types they define, but doing that seems to * cause problems (config.h doesn't protect itself against multiple inclusion). * Looks like standard practice in ucd-snmp code is that all .c files * first include these two .h files, and other .h files assume those have * already been included? */ #include "config.h" #include "mibincl.h" /* prototype for this module's public entry point */ #include "podunk_rr.h" /* generic helper stuff from ucd-snmp */ #include "util_funcs.h" /* specific helper stuff for fsubagent */ #include "dprint.h" #include "fsubagent_utils.h" /* everything below this point is more or less custom-coded for * the PODUNK-RR-MIB demo, but could probably be generated by * mib2h.pl, it's that predictable. */ /* Output of mib2h.pl < PODUNK-RR-MIB.txt */ #include "podunk_rr_mib.h" /* system includes come last, to prove above .h files stand on their own */ #include #include #include #include /* data file written by application being monitored, read by this module */ #define SHARED_FNAME "podunk_rr.fsa" /* um, should come from mib2h.pl but doesn't */ #define ENTERPRISES_OID 1,3,6,1,4,1 /* Each row or table needs a pointer, a wrapper function with prototype, * an init function, and a macro defining all its variables. * The wrapper functions that just supply the missing row or array pointer, * then call the real accessor. * The init function for this module will invoke PODUNK_RR_INIT, * a macro generated by mib2h.pl that calls all the table/row init functions. */ /*---------------- begin table/row definitions ---------------*/ /*------ fleetStatus (a scalar row) -------*/ static fsubagentRow *g_row_fleetStatus = NULL; static FindVarMethod handle_fleetStatus; static unsigned char *handle_fleetStatus( struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { DPRINT(("handle_fleetStatus:\n")); return fsubagent_utils_getFromScalarRow(g_row_fleetStatus, vp, name, length, exact, var_len, write_method); } static void init_fleetStatus() { static const struct variable2 vars_fleetStatus[] = { PODUNK_RR_VARS_fleetStatus }; /* the full OID */ static oid x_oid_fleetStatus[]={ ENTERPRISES_OID, PODUNK_RR_podunk,PODUNK_RR_fleet, PODUNK_RR_fleetStatus}; /* just the part of the OID below this module's root */ static int oid_fleetStatus[] = { PODUNK_RR_fleetStatus, fsubagent_END}; g_row_fleetStatus = fsubagent_createScalarRow(fsubagent_utils_subagent, oid_fleetStatus, PODUNK_RR_fleetStatus_FORMAT); REGISTER_MIB("podunk_rr-fleetStatus", vars_fleetStatus, variable2, x_oid_fleetStatus); } /*------ trainEntry -------*/ static fsubagentArray *g_arr_trainEntry = NULL; static FindVarMethod handle_trainEntry; static unsigned char * handle_trainEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { DPRINT(("handle_trainEntry:\n")); return fsubagent_utils_getFromTable1(g_arr_trainEntry, vp, name, length, exact, var_len, write_method); } static void init_trainEntry() { static const struct variable2 vars_trainEntry[] = { PODUNK_RR_VARS_trainEntry }; static oid x_oid_trainEntry[]={ ENTERPRISES_OID, PODUNK_RR_podunk, PODUNK_RR_fleet, PODUNK_RR_trainTable, PODUNK_RR_trainEntry}; static int oid_trainEntry[] = { PODUNK_RR_trainTable, PODUNK_RR_trainEntry, fsubagent_END}; g_arr_trainEntry = fsubagent_createArray(fsubagent_utils_subagent, oid_trainEntry, PODUNK_RR_trainEntry_FORMAT); REGISTER_MIB("podunk_rr-trainEntry", vars_trainEntry, variable2, x_oid_trainEntry); } /*------ carEntry -------*/ static fsubagentArray2 *g_arr2_carEntry = NULL; static FindVarMethod handle_carEntry; static unsigned char *handle_carEntry( struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { DPRINT(("handle_carEntry:\n")); return fsubagent_utils_getFromTable2(g_arr2_carEntry, vp, name, length, exact, var_len, write_method); } static void init_carEntry() { static const struct variable2 vars_carEntry[] = { PODUNK_RR_VARS_carEntry }; static oid x_oid_carEntry[]= {ENTERPRISES_OID, PODUNK_RR_podunk, PODUNK_RR_fleet, PODUNK_RR_carTable, PODUNK_RR_carEntry}; static int oid_carEntry[] = {PODUNK_RR_carTable, PODUNK_RR_carEntry, fsubagent_END}; g_arr2_carEntry = fsubagent_createArray2(fsubagent_utils_subagent, oid_carEntry, PODUNK_RR_carEntry_FORMAT); REGISTER_MIB("podunk_rr-carEntry", vars_carEntry, variable2, x_oid_carEntry); } /*---------------- end table/row definitions ---------------*/ /* Event handler for snmpd configuration changes. * May be called during startup of snmpd. */ void onRefreshTime(const char *name, char *value) { fsubagent_utils_cacheSeconds = atoi(value); DPRINT(("onRefreshTime: setting fsubagent_utils_cacheSeconds to %d\n", fsubagent_utils_cacheSeconds)); } /* * Initialization routine called by snmpd when it starts up. * The name of this function must be init_ followed by the carname of this * .c car. * Don't confuse this with the init_ routines above, which are private * to this module. */ void init_podunk_rr(void) { /* Get ready to handle snmpd.conf config file settings */ snmpd_register_config_handler("cacheSeconds", onRefreshTime, NULL, "How many seconds to cache " SHARED_FNAME); /* Create the object that will read the MIB variables from disk */ fsubagent_utils_subagent = fsubagent_new(); /* Initialize all the rows & tables by calling the init_* routines * defined above. * This is a macro generated by mib2h.pl that calls init_xxx for * every table and scalar row 'xxx' in the MIB. * The linker will remind us if we forget to hand-code an init routine. */ PODUNK_RR_INIT; DPRINT(("init_podunk_rr: filename %s\n", SHARED_FNAME)); fsubagent_setFilename(fsubagent_utils_subagent, SHARED_FNAME); /* Load the data file for the first time. */ fsubagent_utils_update(TRUE); }