lcd_time.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:14k
- /*
- * lcd_time.c
- *
- * XXX Should etimelist entries with <0,0> time tuples be timed out?
- * XXX Need a routine to free the memory? (Perhaps at shutdown?)
- */
- #include <net-snmp/net-snmp-config.h>
- #include <sys/types.h>
- #if HAVE_WINSOCK_H
- #include <winsock.h>
- #endif
- #include <stdio.h>
- #ifdef HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #if TIME_WITH_SYS_TIME
- # ifdef WIN32
- # include <sys/timeb.h>
- # else
- # include <sys/time.h>
- # endif
- # include <time.h>
- #else
- # if HAVE_SYS_TIME_H
- # include <sys/time.h>
- # else
- # include <time.h>
- # endif
- #endif
- #ifdef HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #if HAVE_DMALLOC_H
- #include <dmalloc.h>
- #endif
- #include <net-snmp/types.h>
- #include <net-snmp/output_api.h>
- #include <net-snmp/utilities.h>
- #include <net-snmp/library/snmp_api.h>
- #include <net-snmp/library/callback.h>
- #include <net-snmp/library/snmp_secmod.h>
- #include <net-snmp/library/snmpusm.h>
- #include <net-snmp/library/lcd_time.h>
- #include <net-snmp/library/scapi.h>
- #include <net-snmp/library/snmpv3.h>
- #include <net-snmp/library/transform_oids.h>
- /*
- * Global static hashlist to contain Enginetime entries.
- *
- * New records are prepended to the appropriate list at the hash index.
- */
- static Enginetime etimelist[ETIMELIST_SIZE];
- /*******************************************************************-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=%dn", *engineboot,
- *engine_time));
- get_enginetime_quit:
- return rval;
- } /* end get_enginetime() */
- /*******************************************************************-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_ex(u_char * engineID,
- u_int engineID_len,
- u_int * engineboot,
- u_int * engine_time,
- u_int * last_engine_time, u_int authenticated)
- {
- int rval = SNMPERR_SUCCESS;
- time_t timediff = 0;
- Enginetime e = NULL;
- /*
- * Sanity check.
- */
- if (!engine_time || !engineboot || !last_engine_time) {
- QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit);
- }
- /*
- * Compute estimated current engine_time tuple at engineID if
- * a record is cached for it.
- */
- *last_engine_time = *engine_time = *engineboot = 0;
- if (!engineID || (engineID_len <= 0)) {
- QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit);
- }
- if (!(e = search_enginetime_list(engineID, engineID_len))) {
- QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit);
- }
- #ifdef LCD_TIME_SYNC_OPT
- if (!authenticated || e->authenticatedFlag) {
- #endif
- *last_engine_time = *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_ex", "engineID "));
- DEBUGMSGHEX(("lcd_get_enginetime_ex", engineID, engineID_len));
- DEBUGMSG(("lcd_get_enginetime_ex", ": boots=%d, time=%dn",
- *engineboot, *engine_time));
- get_enginetime_ex_quit:
- return rval;
- } /* end get_enginetime_ex() */
- void free_enginetime(unsigned char *engineID, size_t engineID_len)
- {
- Enginetime e = NULL;
- int rval = 0;
- rval = hash_engineID(engineID, engineID_len);
- if (rval < 0)
- return;
- e = etimelist[rval];
- while (e != NULL) {
- etimelist[rval] = e->next;
- SNMP_FREE(e->engineID);
- SNMP_FREE(e);
- e = etimelist[rval];
- }
- }
- /*******************************************************************-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=%dn", 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() */
- /*******************************************************************-o-******
- * hash_engineID
- *
- * Parameters:
- * *engineID
- * engineID_len
- *
- * Returns:
- * >0 etimelist index for this engineID.
- * SNMPERR_GENERR Error.
- *
- *
- * Use a cheap hash to build an index into the etimelist. Method is
- * to hash the engineID, then split the hash into u_int's and add them up
- * and modulo the size of the list.
- *
- */
- int
- hash_engineID(u_char * engineID, u_int engineID_len)
- {
- int rval = SNMPERR_GENERR;
- size_t buf_len = SNMP_MAXBUF;
- u_int additive = 0;
- u_char *bufp, buf[SNMP_MAXBUF];
- void *context = NULL;
- /*
- * Sanity check.
- */
- if (!engineID || (engineID_len <= 0)) {
- QUITFUN(SNMPERR_GENERR, hash_engineID_quit);
- }
- /*
- * Hash engineID into a list index.
- */
- #ifndef DISABLE_MD5
- rval = sc_hash(usmHMACMD5AuthProtocol,
- sizeof(usmHMACMD5AuthProtocol) / sizeof(oid),
- engineID, engineID_len, buf, &buf_len);
- #else
- rval = sc_hash(usmHMACSHA1AuthProtocol,
- sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid),
- engineID, engineID_len, buf, &buf_len);
- #endif
- QUITFUN(rval, hash_engineID_quit);
- for (bufp = buf; (bufp - buf) < (int) buf_len; bufp += 4) {
- additive += (u_int) * bufp;
- }
- hash_engineID_quit:
- SNMP_FREE(context);
- memset(buf, 0, SNMP_MAXBUF);
- return (rval < 0) ? rval : (additive % ETIMELIST_SIZE);
- } /* end hash_engineID() */
- #ifdef SNMP_TESTING_CODE
- /*******************************************************************-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 SNMP_TESTING_CODE
- if (!(s = dump_snmpEngineID(e->engineID, &buflen))) {
- #endif
- binary_to_hex(e->engineID, e->engineID_len, &s);
- #ifdef SNMP_TESTING_CODE
- }
- #endif
- DEBUGMSGTL(("dump_etimelist", "%sn", 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() */
- /*******************************************************************-o-******
- * dump_etimelist
- */
- void
- dump_etimelist(void)
- {
- int iindex = -1, count = 0;
- Enginetime e;
- DEBUGMSGTL(("dump_etimelist", "n"));
- while (++iindex < ETIMELIST_SIZE) {
- DEBUGMSG(("dump_etimelist", "[%d]", iindex));
- count = 0;
- e = etimelist[iindex];
- while (e) {
- dump_etimelist_entry(e, count++);
- e = e->next;
- }
- if (count > 0) {
- DEBUGMSG(("dump_etimelist", "n"));
- }
- } /* endwhile */
- DEBUGMSG(("dump_etimelist", "n"));
- } /* end dump_etimelist() */
- #endif /* SNMP_TESTING_CODE */