/*******************************************************************-o-****** * dump_etimelist_entry * * Parameters: * e * count */ void dump_etimelist_entry(Enginetime e, int count) { u_int buflen; char tabs[SNMP_MAXBUF], *t = tabs, *s; count += 1; while (count--) { t += sprintf(t, " "); } buflen = e->engineID_len; #ifdef NETSNMP_ENABLE_TESTING_CODE if (!(s = dump_snmpEngineID(e->engineID, &buflen))) { #endif binary_to_hex(e->engineID, e->engineID_len, &s); #ifdef NETSNMP_ENABLE_TESTING_CODE } #endif DEBUGMSGTL(("dump_etimelist", "%s\n", tabs)); DEBUGMSGTL(("dump_etimelist", "%s%s (len=%d) <%d,%d>\n", tabs, s, e->engineID_len, e->engineTime, e->engineBoot)); DEBUGMSGTL(("dump_etimelist", "%s%ld (%ld)", tabs, e->lastReceivedEngineTime, snmpv3_local_snmpEngineTime() - e->lastReceivedEngineTime)); SNMP_FREE(s); } /* end dump_etimelist_entry() */
/* * merely call */ void get_enginetime_alarm(unsigned int regnum, void *clientargs) { /* we do this every so (rarely) often just to make sure we watch wrapping of the times() output */ snmpv3_local_snmpEngineTime(); }
int init_snmpv3_post_config(int majorid, int minorid, void *serverarg, void *clientarg) { int engineIDLen; u_char *c_engineID; c_engineID = snmpv3_generate_engineID(&engineIDLen); if ( engineIDLen < 0 ) { /* Somethine went wrong - help! */ return SNMPERR_GENERR; } /* if our engineID has changed at all, the boots record must be set to 1 */ if (engineIDLen != (int)oldEngineIDLength || oldEngineID == NULL || c_engineID == NULL || memcmp(oldEngineID, c_engineID, engineIDLen) != 0) { engineBoots = 1; } /* set our local engineTime in the LCD timing cache */ set_enginetime(c_engineID, engineIDLen, snmpv3_local_snmpEngineBoots(), snmpv3_local_snmpEngineTime(), TRUE); free(c_engineID); return SNMPERR_SUCCESS; }
u_char *var_snmpEngine (struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { /* * variables we may use later */ static long long_ret; static unsigned char engineID[SNMP_MAXBUF]; *write_method = (WriteMethod *) 0; /* assume it isnt writable for the time being */ *var_len = sizeof (long_ret); /* assume an integer and change later if not */ if (header_generic (vp, name, length, exact, var_len, write_method)) return NULL; /* * this is where we do the value assignments for the mib results. */ switch (vp->magic) { case SNMPENGINEID: *var_len = snmpv3_get_engineID (engineID, SNMP_MAXBUF); /* * XXX Set ERROR_MSG() upon error? */ return (unsigned char *) engineID; case SNMPENGINEBOOTS: #ifndef NETSNMP_NO_WRITE_SUPPORT #ifdef NETSNMP_ENABLE_TESTING_CODE *write_method = write_engineBoots; #endif /* NETSNMP_ENABLE_TESTING_CODE */ #endif /* !NETSNMP_NO_WRITE_SUPPORT */ long_ret = snmpv3_local_snmpEngineBoots (); return (unsigned char *) &long_ret; case SNMPENGINETIME: #ifndef NETSNMP_NO_WRITE_SUPPORT #ifdef NETSNMP_ENABLE_TESTING_CODE *write_method = write_engineTime; #endif /* NETSNMP_ENABLE_TESTING_CODE */ #endif /* !NETSNMP_NO_WRITE_SUPPORT */ long_ret = snmpv3_local_snmpEngineTime (); return (unsigned char *) &long_ret; case SNMPENGINEMAXMESSAGESIZE: long_ret = 1500; return (unsigned char *) &long_ret; default: DEBUGMSGTL (("snmpd", "unknown sub-id %d in var_snmpEngine\n", vp->magic)); } return NULL; }
/* * write_engineBoots(): * * This is technically not writable a writable mib object, but we * allow it so we can run some time synchronization tests. */ int write_engineBoots (int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { /* * variables we may use later */ static long long_ret; size_t size; int bigsize = SNMP_MAXBUF_MEDIUM; u_char engineIDBuf[SNMP_MAXBUF_MEDIUM]; int engineIDBufLen = 0; if (var_val_type != ASN_INTEGER) { DEBUGMSGTL (("snmpEngine", "write to engineBoots not ASN_INTEGER\n")); return SNMP_ERR_WRONGTYPE; } if (var_val_len > sizeof (long_ret)) { DEBUGMSGTL (("snmpEngine", "write to engineBoots: bad length\n")); return SNMP_ERR_WRONGLENGTH; } long_ret = *((long *) var_val); if (action == COMMIT) { engineIDBufLen = snmpv3_get_engineID (engineIDBuf, SNMP_MAXBUF_MEDIUM); /* * set our local engineTime in the LCD timing cache */ snmpv3_set_engineBootsAndTime (long_ret, snmpv3_local_snmpEngineTime ()); set_enginetime (engineIDBuf, engineIDBufLen, snmpv3_local_snmpEngineBoots (), snmpv3_local_snmpEngineTime (), TRUE); } return SNMP_ERR_NOERROR; }
/*******************************************************************-o-****** * get_enginetime * * Parameters: * *engineID * engineID_len * *engineboot * *engine_time * * Returns: * SNMPERR_SUCCESS Success -- when a record for engineID is found. * SNMPERR_GENERR Otherwise. * * * Lookup engineID and return the recorded values for the * <engine_time, engineboot> tuple adjusted to reflect the estimated time * at the engine in question. * * Special case: if engineID is NULL or if engineID_len is 0 then * the time tuple is returned immediately as zero. * * XXX What if timediff wraps? >shrug< * XXX Then: you need to increment the boots value. Now. Detecting * this is another matter. */ int get_enginetime(u_char * engineID, u_int engineID_len, u_int * engineboot, u_int * engine_time, u_int authenticated) { int rval = SNMPERR_SUCCESS; time_t timediff = 0; Enginetime e = NULL; /* * Sanity check. */ if (!engine_time || !engineboot) { QUITFUN(SNMPERR_GENERR, get_enginetime_quit); } /* * Compute estimated current engine_time tuple at engineID if * a record is cached for it. */ *engine_time = *engineboot = 0; if (!engineID || (engineID_len <= 0)) { QUITFUN(SNMPERR_GENERR, get_enginetime_quit); } if (!(e = search_enginetime_list(engineID, engineID_len))) { QUITFUN(SNMPERR_GENERR, get_enginetime_quit); } #ifdef LCD_TIME_SYNC_OPT if (!authenticated || e->authenticatedFlag) { #endif *engine_time = e->engineTime; *engineboot = e->engineBoot; timediff = snmpv3_local_snmpEngineTime() - e->lastReceivedEngineTime; #ifdef LCD_TIME_SYNC_OPT } #endif if (timediff > (int) (ENGINETIME_MAX - *engine_time)) { *engine_time = (timediff - (ENGINETIME_MAX - *engine_time)); /* * FIX -- move this check up... should not change anything * * if engineboot is already locked. ??? */ if (*engineboot < ENGINEBOOT_MAX) { *engineboot += 1; } } else { *engine_time += timediff; } DEBUGMSGTL(("lcd_get_enginetime", "engineID ")); DEBUGMSGHEX(("lcd_get_enginetime", engineID, engineID_len)); DEBUGMSG(("lcd_get_enginetime", ": boots=%d, time=%d\n", *engineboot, *engine_time)); get_enginetime_quit: return rval; } /* end get_enginetime() */
/*******************************************************************-o-****** * set_enginetime * * Parameters: * *engineID * engineID_len * engineboot * engine_time * * Returns: * SNMPERR_SUCCESS Success. * SNMPERR_GENERR Otherwise. * * * Lookup engineID and store the given <engine_time, engineboot> tuple * and then stamp the record with a consistent source of local time. * If the engineID record does not exist, create one. * * Special case: engineID is NULL or engineID_len is 0 defines an engineID * that is "always set." * * XXX "Current time within the local engine" == time(NULL)... */ int set_enginetime(u_char * engineID, u_int engineID_len, u_int engineboot, u_int engine_time, u_int authenticated) { int rval = SNMPERR_SUCCESS, iindex; Enginetime e = NULL; /* * Sanity check. */ if (!engineID || (engineID_len <= 0)) { return rval; } /* * Store the given <engine_time, engineboot> tuple in the record * for engineID. Create a new record if necessary. */ if (!(e = search_enginetime_list(engineID, engineID_len))) { if ((iindex = hash_engineID(engineID, engineID_len)) < 0) { QUITFUN(SNMPERR_GENERR, set_enginetime_quit); } e = (Enginetime) calloc(1, sizeof(*e)); e->next = etimelist[iindex]; etimelist[iindex] = e; e->engineID = (u_char *) calloc(1, engineID_len); memcpy(e->engineID, engineID, engineID_len); e->engineID_len = engineID_len; } #ifdef LCD_TIME_SYNC_OPT if (authenticated || !e->authenticatedFlag) { e->authenticatedFlag = authenticated; #else if (authenticated) { #endif e->engineTime = engine_time; e->engineBoot = engineboot; e->lastReceivedEngineTime = snmpv3_local_snmpEngineTime(); } e = NULL; /* Indicates a successful update. */ DEBUGMSGTL(("lcd_set_enginetime", "engineID ")); DEBUGMSGHEX(("lcd_set_enginetime", engineID, engineID_len)); DEBUGMSG(("lcd_set_enginetime", ": boots=%d, time=%d\n", engineboot, engine_time)); set_enginetime_quit: SNMP_FREE(e); return rval; } /* end set_enginetime() */ /*******************************************************************-o-****** * search_enginetime_list * * Parameters: * *engineID * engineID_len * * Returns: * Pointer to a etimelist record with engineID <engineID> -OR- * NULL if no record exists. * * * Search etimelist for an entry with engineID. * * ASSUMES that no engineID will have more than one record in the list. */ Enginetime search_enginetime_list(u_char * engineID, u_int engineID_len) { int rval = SNMPERR_SUCCESS; Enginetime e = NULL; /* * Sanity check. */ if (!engineID || (engineID_len <= 0)) { QUITFUN(SNMPERR_GENERR, search_enginetime_list_quit); } /* * Find the entry for engineID if there be one. */ rval = hash_engineID(engineID, engineID_len); if (rval < 0) { QUITFUN(SNMPERR_GENERR, search_enginetime_list_quit); } e = etimelist[rval]; for ( /*EMPTY*/; e; e = e->next) { if ((engineID_len == e->engineID_len) && !memcmp(e->engineID, engineID, engineID_len)) { break; } } search_enginetime_list_quit: return e; } /* end search_enginetime_list() */