Blame snmplib/lcd_time.c

Packit Service b38f0b
/*
Packit Service b38f0b
 * lcd_time.c
Packit Service b38f0b
 *
Packit Service b38f0b
 * XXX  Should etimelist entries with <0,0> time tuples be timed out?
Packit Service b38f0b
 * XXX  Need a routine to free the memory?  (Perhaps at shutdown?)
Packit Service b38f0b
 */
Packit Service b38f0b
Packit Service b38f0b
#include <net-snmp/net-snmp-config.h>
Packit Service b38f0b
#include <net-snmp/net-snmp-features.h>
Packit Service b38f0b
Packit Service b38f0b
#include <sys/types.h>
Packit Service b38f0b
#include <stdio.h>
Packit Service b38f0b
#ifdef HAVE_STDLIB_H
Packit Service b38f0b
#include <stdlib.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_STRING_H
Packit Service b38f0b
#include <string.h>
Packit Service b38f0b
#else
Packit Service b38f0b
#include <strings.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if TIME_WITH_SYS_TIME
Packit Service b38f0b
# include <sys/time.h>
Packit Service b38f0b
# include <time.h>
Packit Service b38f0b
#else
Packit Service b38f0b
# if HAVE_SYS_TIME_H
Packit Service b38f0b
#  include <sys/time.h>
Packit Service b38f0b
# else
Packit Service b38f0b
#  include <time.h>
Packit Service b38f0b
# endif
Packit Service b38f0b
#endif
Packit Service b38f0b
#ifdef HAVE_NETINET_IN_H
Packit Service b38f0b
#include <netinet/in.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#if HAVE_UNISTD_H
Packit Service b38f0b
#include <unistd.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
#if HAVE_DMALLOC_H
Packit Service b38f0b
#include <dmalloc.h>
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
#include <net-snmp/types.h>
Packit Service b38f0b
#include <net-snmp/output_api.h>
Packit Service b38f0b
#include <net-snmp/utilities.h>
Packit Service b38f0b
Packit Service b38f0b
#include <net-snmp/library/snmp_api.h>
Packit Service b38f0b
#include <net-snmp/library/callback.h>
Packit Service b38f0b
#include <net-snmp/library/snmp_secmod.h>
Packit Service b38f0b
#include <net-snmp/library/snmpusm.h>
Packit Service b38f0b
#include <net-snmp/library/lcd_time.h>
Packit Service b38f0b
#include <net-snmp/library/scapi.h>
Packit Service b38f0b
#include <net-snmp/library/snmpv3.h>
Packit Service b38f0b
Packit Service b38f0b
#include <net-snmp/library/transform_oids.h>
Packit Service b38f0b
Packit Service b38f0b
netsnmp_feature_child_of(usm_support, libnetsnmp)
Packit Service b38f0b
netsnmp_feature_child_of(usm_lcd_time, usm_support)
Packit Service b38f0b
Packit Service b38f0b
#ifndef NETSNMP_FEATURE_REMOVE_USM_LCD_TIME
Packit Service b38f0b
Packit Service b38f0b
/*
Packit Service b38f0b
 * Global static hashlist to contain Enginetime entries.
Packit Service b38f0b
 *
Packit Service b38f0b
 * New records are prepended to the appropriate list at the hash index.
Packit Service b38f0b
 */
Packit Service b38f0b
static Enginetime etimelist[ETIMELIST_SIZE];
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
/*******************************************************************-o-******
Packit Service b38f0b
 * get_enginetime
Packit Service b38f0b
 *
Packit Service b38f0b
 * Parameters:
Packit Service b38f0b
 *	*engineID
Packit Service b38f0b
 *	 engineID_len
Packit Service b38f0b
 *	*engineboot
Packit Service b38f0b
 *	*engine_time
Packit Service b38f0b
 *      
Packit Service b38f0b
 * Returns:
Packit Service b38f0b
 *	SNMPERR_SUCCESS		Success -- when a record for engineID is found.
Packit Service b38f0b
 *	SNMPERR_GENERR		Otherwise.
Packit Service b38f0b
 *
Packit Service b38f0b
 *
Packit Service b38f0b
 * Lookup engineID and return the recorded values for the
Packit Service b38f0b
 * <engine_time, engineboot> tuple adjusted to reflect the estimated time
Packit Service b38f0b
 * at the engine in question.
Packit Service b38f0b
 *
Packit Service b38f0b
 * Special case: if engineID is NULL or if engineID_len is 0 then
Packit Service b38f0b
 * the time tuple is returned immediately as zero.
Packit Service b38f0b
 *
Packit Service b38f0b
 * XXX	What if timediff wraps?  >shrug<
Packit Service b38f0b
 * XXX  Then: you need to increment the boots value.  Now.  Detecting
Packit Service b38f0b
 *            this is another matter.
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
get_enginetime(const u_char * engineID,
Packit Service b38f0b
               u_int engineID_len,
Packit Service b38f0b
               u_int * engineboot,
Packit Service b38f0b
               u_int * engine_time, u_int authenticated)
Packit Service b38f0b
{
Packit Service b38f0b
    int             rval = SNMPERR_SUCCESS;
Packit Service b38f0b
    int             timediff = 0;
Packit Service b38f0b
    Enginetime      e = NULL;
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Sanity check.
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!engine_time || !engineboot) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, get_enginetime_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Compute estimated current engine_time tuple at engineID if
Packit Service b38f0b
     * a record is cached for it.
Packit Service b38f0b
     */
Packit Service b38f0b
    *engine_time = *engineboot = 0;
Packit Service b38f0b
Packit Service b38f0b
    if (!engineID || (engineID_len <= 0)) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, get_enginetime_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    if (!(e = search_enginetime_list(engineID, engineID_len))) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, get_enginetime_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
#ifdef LCD_TIME_SYNC_OPT
Packit Service b38f0b
    if (!authenticated || e->authenticatedFlag) {
Packit Service b38f0b
#endif
Packit Service b38f0b
        *engine_time = e->engineTime;
Packit Service b38f0b
        *engineboot = e->engineBoot;
Packit Service b38f0b
Packit Service b38f0b
       timediff = (int) (snmpv3_local_snmpEngineTime() - e->lastReceivedEngineTime);
Packit Service b38f0b
Packit Service b38f0b
#ifdef LCD_TIME_SYNC_OPT
Packit Service b38f0b
    }
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
    if (timediff > (int) (ENGINETIME_MAX - *engine_time)) {
Packit Service b38f0b
        *engine_time = (timediff - (ENGINETIME_MAX - *engine_time));
Packit Service b38f0b
Packit Service b38f0b
        /*
Packit Service b38f0b
         * FIX -- move this check up... should not change anything
Packit Service b38f0b
         * * if engineboot is already locked.  ???
Packit Service b38f0b
         */
Packit Service b38f0b
        if (*engineboot < ENGINEBOOT_MAX) {
Packit Service b38f0b
            *engineboot += 1;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
    } else {
Packit Service b38f0b
        *engine_time += timediff;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("lcd_get_enginetime", "engineID "));
Packit Service b38f0b
    DEBUGMSGHEX(("lcd_get_enginetime", engineID, engineID_len));
Packit Service b38f0b
    DEBUGMSG(("lcd_get_enginetime", ": boots=%d, time=%d\n", *engineboot,
Packit Service b38f0b
              *engine_time));
Packit Service b38f0b
Packit Service b38f0b
  get_enginetime_quit:
Packit Service b38f0b
    return rval;
Packit Service b38f0b
Packit Service b38f0b
}                               /* end get_enginetime() */
Packit Service b38f0b
Packit Service b38f0b
/*******************************************************************-o-******
Packit Service b38f0b
 * get_enginetime
Packit Service b38f0b
 *
Packit Service b38f0b
 * Parameters:
Packit Service b38f0b
 *	*engineID
Packit Service b38f0b
 *	 engineID_len
Packit Service b38f0b
 *	*engineboot
Packit Service b38f0b
 *	*engine_time
Packit Service b38f0b
 *      
Packit Service b38f0b
 * Returns:
Packit Service b38f0b
 *	SNMPERR_SUCCESS		Success -- when a record for engineID is found.
Packit Service b38f0b
 *	SNMPERR_GENERR		Otherwise.
Packit Service b38f0b
 *
Packit Service b38f0b
 *
Packit Service b38f0b
 * Lookup engineID and return the recorded values for the
Packit Service b38f0b
 * <engine_time, engineboot> tuple adjusted to reflect the estimated time
Packit Service b38f0b
 * at the engine in question.
Packit Service b38f0b
 *
Packit Service b38f0b
 * Special case: if engineID is NULL or if engineID_len is 0 then
Packit Service b38f0b
 * the time tuple is returned immediately as zero.
Packit Service b38f0b
 *
Packit Service b38f0b
 * XXX	What if timediff wraps?  >shrug<
Packit Service b38f0b
 * XXX  Then: you need to increment the boots value.  Now.  Detecting
Packit Service b38f0b
 *            this is another matter.
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
get_enginetime_ex(u_char * engineID,
Packit Service b38f0b
                  u_int engineID_len,
Packit Service b38f0b
                  u_int * engineboot,
Packit Service b38f0b
                  u_int * engine_time,
Packit Service b38f0b
                  u_int * last_engine_time, u_int authenticated)
Packit Service b38f0b
{
Packit Service b38f0b
    int             rval = SNMPERR_SUCCESS;
Packit Service b38f0b
    int             timediff = 0;
Packit Service b38f0b
    Enginetime      e = NULL;
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Sanity check.
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!engine_time || !engineboot || !last_engine_time) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Compute estimated current engine_time tuple at engineID if
Packit Service b38f0b
     * a record is cached for it.
Packit Service b38f0b
     */
Packit Service b38f0b
    *last_engine_time = *engine_time = *engineboot = 0;
Packit Service b38f0b
Packit Service b38f0b
    if (!engineID || (engineID_len <= 0)) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    if (!(e = search_enginetime_list(engineID, engineID_len))) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
#ifdef LCD_TIME_SYNC_OPT
Packit Service b38f0b
    if (!authenticated || e->authenticatedFlag) {
Packit Service b38f0b
#endif
Packit Service b38f0b
        *last_engine_time = *engine_time = e->engineTime;
Packit Service b38f0b
        *engineboot = e->engineBoot;
Packit Service b38f0b
Packit Service b38f0b
       timediff = (int) (snmpv3_local_snmpEngineTime() - e->lastReceivedEngineTime);
Packit Service b38f0b
Packit Service b38f0b
#ifdef LCD_TIME_SYNC_OPT
Packit Service b38f0b
    }
Packit Service b38f0b
#endif
Packit Service b38f0b
Packit Service b38f0b
    if (timediff > (int) (ENGINETIME_MAX - *engine_time)) {
Packit Service b38f0b
        *engine_time = (timediff - (ENGINETIME_MAX - *engine_time));
Packit Service b38f0b
Packit Service b38f0b
        /*
Packit Service b38f0b
         * FIX -- move this check up... should not change anything
Packit Service b38f0b
         * * if engineboot is already locked.  ???
Packit Service b38f0b
         */
Packit Service b38f0b
        if (*engineboot < ENGINEBOOT_MAX) {
Packit Service b38f0b
            *engineboot += 1;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
    } else {
Packit Service b38f0b
        *engine_time += timediff;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("lcd_get_enginetime_ex", "engineID "));
Packit Service b38f0b
    DEBUGMSGHEX(("lcd_get_enginetime_ex", engineID, engineID_len));
Packit Service b38f0b
    DEBUGMSG(("lcd_get_enginetime_ex", ": boots=%d, time=%d\n",
Packit Service b38f0b
              *engineboot, *engine_time));
Packit Service b38f0b
Packit Service b38f0b
  get_enginetime_ex_quit:
Packit Service b38f0b
    return rval;
Packit Service b38f0b
Packit Service b38f0b
}                               /* end get_enginetime_ex() */
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
void free_enginetime(unsigned char *engineID, size_t engineID_len)
Packit Service b38f0b
{
Packit Service b38f0b
    Enginetime      e = NULL;
Packit Service b38f0b
    int             rval = 0;
Packit Service b38f0b
Packit Service b38f0b
    rval = hash_engineID(engineID, engineID_len);
Packit Service b38f0b
    if (rval < 0)
Packit Service b38f0b
	return;
Packit Service b38f0b
Packit Service b38f0b
    e = etimelist[rval];
Packit Service b38f0b
Packit Service b38f0b
    while (e != NULL) {
Packit Service b38f0b
	etimelist[rval] = e->next;
Packit Service b38f0b
	SNMP_FREE(e->engineID);
Packit Service b38f0b
	SNMP_FREE(e);
Packit Service b38f0b
	e = etimelist[rval];
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
/*******************************************************************-o-****
Packit Service b38f0b
**
Packit Service b38f0b
 * free_etimelist
Packit Service b38f0b
 *
Packit Service b38f0b
 * Parameters:
Packit Service b38f0b
 *   None
Packit Service b38f0b
 *      
Packit Service b38f0b
 * Returns:
Packit Service b38f0b
 *   void
Packit Service b38f0b
 *
Packit Service b38f0b
 *
Packit Service b38f0b
 * Free all of the memory used by entries in the etimelist.
Packit Service b38f0b
 *
Packit Service b38f0b
 */
Packit Service b38f0b
void free_etimelist(void)
Packit Service b38f0b
{
Packit Service b38f0b
     int index = 0;
Packit Service b38f0b
     Enginetime e = NULL;
Packit Service b38f0b
     Enginetime nextE = NULL;
Packit Service b38f0b
Packit Service b38f0b
     for( ; index < ETIMELIST_SIZE; ++index)
Packit Service b38f0b
     {
Packit Service b38f0b
           e = etimelist[index];
Packit Service b38f0b
Packit Service b38f0b
           while(e != NULL)
Packit Service b38f0b
           {
Packit Service b38f0b
                 nextE = e->next;
Packit Service b38f0b
                 SNMP_FREE(e->engineID);
Packit Service b38f0b
                 SNMP_FREE(e);
Packit Service b38f0b
                 e = nextE;
Packit Service b38f0b
           }
Packit Service b38f0b
Packit Service b38f0b
           etimelist[index] = NULL;
Packit Service b38f0b
     }
Packit Service b38f0b
     return;
Packit Service b38f0b
}
Packit Service b38f0b
Packit Service b38f0b
/*******************************************************************-o-******
Packit Service b38f0b
 * set_enginetime
Packit Service b38f0b
 *
Packit Service b38f0b
 * Parameters:
Packit Service b38f0b
 *	*engineID
Packit Service b38f0b
 *	 engineID_len
Packit Service b38f0b
 *	 engineboot
Packit Service b38f0b
 *	 engine_time
Packit Service b38f0b
 *      
Packit Service b38f0b
 * Returns:
Packit Service b38f0b
 *	SNMPERR_SUCCESS		Success.
Packit Service b38f0b
 *	SNMPERR_GENERR		Otherwise.
Packit Service b38f0b
 *
Packit Service b38f0b
 *
Packit Service b38f0b
 * Lookup engineID and store the given <engine_time, engineboot> tuple
Packit Service b38f0b
 * and then stamp the record with a consistent source of local time.
Packit Service b38f0b
 * If the engineID record does not exist, create one.
Packit Service b38f0b
 *
Packit Service b38f0b
 * Special case: engineID is NULL or engineID_len is 0 defines an engineID
Packit Service b38f0b
 * that is "always set."
Packit Service b38f0b
 *
Packit Service b38f0b
 * XXX	"Current time within the local engine" == time(NULL)...
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
set_enginetime(const u_char * engineID,
Packit Service b38f0b
               u_int engineID_len,
Packit Service b38f0b
               u_int engineboot, u_int engine_time, u_int authenticated)
Packit Service b38f0b
{
Packit Service b38f0b
    int             rval = SNMPERR_SUCCESS, iindex;
Packit Service b38f0b
    Enginetime      e = NULL;
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Sanity check.
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!engineID || (engineID_len <= 0)) {
Packit Service b38f0b
        return rval;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Store the given <engine_time, engineboot> tuple in the record
Packit Service b38f0b
     * for engineID.  Create a new record if necessary.
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!(e = search_enginetime_list(engineID, engineID_len))) {
Packit Service b38f0b
        if ((iindex = hash_engineID(engineID, engineID_len)) < 0) {
Packit Service b38f0b
            QUITFUN(SNMPERR_GENERR, set_enginetime_quit);
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        e = (Enginetime) calloc(1, sizeof(*e));
Packit Service b38f0b
Packit Service b38f0b
        e->next = etimelist[iindex];
Packit Service b38f0b
        etimelist[iindex] = e;
Packit Service b38f0b
Packit Service b38f0b
        e->engineID = (u_char *) calloc(1, engineID_len);
Packit Service b38f0b
        memcpy(e->engineID, engineID, engineID_len);
Packit Service b38f0b
Packit Service b38f0b
        e->engineID_len = engineID_len;
Packit Service b38f0b
    }
Packit Service b38f0b
#ifdef LCD_TIME_SYNC_OPT
Packit Service b38f0b
    if (authenticated || !e->authenticatedFlag) {
Packit Service b38f0b
        e->authenticatedFlag = authenticated;
Packit Service b38f0b
#else
Packit Service b38f0b
    if (authenticated) {
Packit Service b38f0b
#endif
Packit Service b38f0b
        e->engineTime = engine_time;
Packit Service b38f0b
        e->engineBoot = engineboot;
Packit Service b38f0b
        e->lastReceivedEngineTime = snmpv3_local_snmpEngineTime();
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    e = NULL;                   /* Indicates a successful update. */
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("lcd_set_enginetime", "engineID "));
Packit Service b38f0b
    DEBUGMSGHEX(("lcd_set_enginetime", engineID, engineID_len));
Packit Service b38f0b
    DEBUGMSG(("lcd_set_enginetime", ": boots=%d, time=%d\n", engineboot,
Packit Service b38f0b
              engine_time));
Packit Service b38f0b
Packit Service b38f0b
  set_enginetime_quit:
Packit Service b38f0b
    SNMP_FREE(e);
Packit Service b38f0b
Packit Service b38f0b
    return rval;
Packit Service b38f0b
Packit Service b38f0b
}                               /* end set_enginetime() */
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
/*******************************************************************-o-******
Packit Service b38f0b
 * search_enginetime_list
Packit Service b38f0b
 *
Packit Service b38f0b
 * Parameters:
Packit Service b38f0b
 *	*engineID
Packit Service b38f0b
 *	 engineID_len
Packit Service b38f0b
 *      
Packit Service b38f0b
 * Returns:
Packit Service b38f0b
 *	Pointer to a etimelist record with engineID <engineID>  -OR-
Packit Service b38f0b
 *	NULL if no record exists.
Packit Service b38f0b
 *
Packit Service b38f0b
 *
Packit Service b38f0b
 * Search etimelist for an entry with engineID.
Packit Service b38f0b
 *
Packit Service b38f0b
 * ASSUMES that no engineID will have more than one record in the list.
Packit Service b38f0b
 */
Packit Service b38f0b
Enginetime
Packit Service b38f0b
search_enginetime_list(const u_char * engineID, u_int engineID_len)
Packit Service b38f0b
{
Packit Service b38f0b
    int             rval = SNMPERR_SUCCESS;
Packit Service b38f0b
    Enginetime      e = NULL;
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Sanity check.
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!engineID || (engineID_len <= 0)) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, search_enginetime_list_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Find the entry for engineID if there be one.
Packit Service b38f0b
     */
Packit Service b38f0b
    rval = hash_engineID(engineID, engineID_len);
Packit Service b38f0b
    if (rval < 0) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, search_enginetime_list_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
    e = etimelist[rval];
Packit Service b38f0b
Packit Service b38f0b
    for ( /*EMPTY*/; e; e = e->next) {
Packit Service b38f0b
        if ((engineID_len == e->engineID_len)
Packit Service b38f0b
            && !memcmp(e->engineID, engineID, engineID_len)) {
Packit Service b38f0b
            break;
Packit Service b38f0b
        }
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
  search_enginetime_list_quit:
Packit Service b38f0b
    return e;
Packit Service b38f0b
Packit Service b38f0b
}                               /* end search_enginetime_list() */
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
/*******************************************************************-o-******
Packit Service b38f0b
 * hash_engineID
Packit Service b38f0b
 *
Packit Service b38f0b
 * Parameters:
Packit Service b38f0b
 *	*engineID
Packit Service b38f0b
 *	 engineID_len
Packit Service b38f0b
 *      
Packit Service b38f0b
 * Returns:
Packit Service b38f0b
 *	>0			etimelist index for this engineID.
Packit Service b38f0b
 *	SNMPERR_GENERR		Error.
Packit Service b38f0b
 *	
Packit Service b38f0b
 * 
Packit Service b38f0b
 * Use a cheap hash to build an index into the etimelist.  Method is 
Packit Service b38f0b
 * to hash the engineID, then split the hash into u_int's and add them up
Packit Service b38f0b
 * and modulo the size of the list.
Packit Service b38f0b
 *
Packit Service b38f0b
 */
Packit Service b38f0b
int
Packit Service b38f0b
hash_engineID(const u_char * engineID, u_int engineID_len)
Packit Service b38f0b
{
Packit Service b38f0b
    int             rval = SNMPERR_GENERR;
Packit Service b38f0b
    size_t          buf_len = SNMP_MAXBUF;
Packit Service b38f0b
    u_int           additive = 0;
Packit Service b38f0b
    u_char         *bufp, buf[SNMP_MAXBUF];
Packit Service b38f0b
    void           *context = NULL;
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Sanity check.
Packit Service b38f0b
     */
Packit Service b38f0b
    if (!engineID || (engineID_len <= 0)) {
Packit Service b38f0b
        QUITFUN(SNMPERR_GENERR, hash_engineID_quit);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    /*
Packit Service b38f0b
     * Hash engineID into a list index.
Packit Service b38f0b
     */
Packit Service b38f0b
#ifndef NETSNMP_DISABLE_MD5
Packit Service b38f0b
    rval = sc_hash(usmHMACMD5AuthProtocol,
Packit Service b38f0b
                   sizeof(usmHMACMD5AuthProtocol) / sizeof(oid),
Packit Service b38f0b
                   engineID, engineID_len, buf, &buf_len);
Packit Service b38f0b
    if (rval == SNMPERR_SC_NOT_CONFIGURED) {
Packit Service b38f0b
        /* fall back to sha1 */
Packit Service b38f0b
        rval = sc_hash(usmHMACSHA1AuthProtocol,
Packit Service b38f0b
                   sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid),
Packit Service b38f0b
                   engineID, engineID_len, buf, &buf_len);
Packit Service b38f0b
    }
Packit Service b38f0b
#else
Packit Service b38f0b
    rval = sc_hash(usmHMACSHA1AuthProtocol,
Packit Service b38f0b
                   sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid),
Packit Service b38f0b
                   engineID, engineID_len, buf, &buf_len);
Packit Service b38f0b
#endif
Packit Service b38f0b
    QUITFUN(rval, hash_engineID_quit);
Packit Service b38f0b
Packit Service b38f0b
    for (bufp = buf; (bufp - buf) < (int) buf_len; bufp += 4) {
Packit Service b38f0b
        additive += (u_int) * bufp;
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
  hash_engineID_quit:
Packit Service b38f0b
    SNMP_FREE(context);
Packit Service b38f0b
    memset(buf, 0, SNMP_MAXBUF);
Packit Service b38f0b
Packit Service b38f0b
    return (rval < 0) ? rval : (int)(additive % ETIMELIST_SIZE);
Packit Service b38f0b
Packit Service b38f0b
}                               /* end hash_engineID() */
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
#ifdef NETSNMP_ENABLE_TESTING_CODE
Packit Service b38f0b
/*******************************************************************-o-******
Packit Service b38f0b
 * dump_etimelist_entry
Packit Service b38f0b
 *
Packit Service b38f0b
 * Parameters:
Packit Service b38f0b
 *	e
Packit Service b38f0b
 *	count
Packit Service b38f0b
 */
Packit Service b38f0b
void
Packit Service b38f0b
dump_etimelist_entry(Enginetime e, int count)
Packit Service b38f0b
{
Packit Service b38f0b
    size_t          buflen;
Packit Service b38f0b
    char            tabs[SNMP_MAXBUF], *t = tabs, *s;
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    count += 1;
Packit Service b38f0b
    while (count--) {
Packit Service b38f0b
        t += sprintf(t, "  ");
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    buflen = e->engineID_len;
Packit Service b38f0b
    if (!(s = dump_snmpEngineID(e->engineID, &buflen))) {
Packit Service b38f0b
        binary_to_hex(e->engineID, e->engineID_len, &s);
Packit Service b38f0b
    }
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("dump_etimelist", "%s\n", tabs));
Packit Service b38f0b
    DEBUGMSGTL(("dump_etimelist", "%s%s (len=%d) <%d,%d>\n", tabs,
Packit Service b38f0b
                s, e->engineID_len, e->engineTime, e->engineBoot));
Packit Service b38f0b
    DEBUGMSGTL(("dump_etimelist", "%s%ld (%ld)", tabs,
Packit Service b38f0b
                e->lastReceivedEngineTime,
Packit Service b38f0b
                snmpv3_local_snmpEngineTime() - e->lastReceivedEngineTime));
Packit Service b38f0b
Packit Service b38f0b
    SNMP_FREE(s);
Packit Service b38f0b
Packit Service b38f0b
}                               /* end dump_etimelist_entry() */
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
/*******************************************************************-o-******
Packit Service b38f0b
 * dump_etimelist
Packit Service b38f0b
 */
Packit Service b38f0b
void
Packit Service b38f0b
dump_etimelist(void)
Packit Service b38f0b
{
Packit Service b38f0b
    int             iindex = -1, count = 0;
Packit Service b38f0b
    Enginetime      e;
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSGTL(("dump_etimelist", "\n"));
Packit Service b38f0b
Packit Service b38f0b
    while (++iindex < ETIMELIST_SIZE) {
Packit Service b38f0b
        DEBUGMSG(("dump_etimelist", "[%d]", iindex));
Packit Service b38f0b
Packit Service b38f0b
        count = 0;
Packit Service b38f0b
        e = etimelist[iindex];
Packit Service b38f0b
Packit Service b38f0b
        while (e) {
Packit Service b38f0b
            dump_etimelist_entry(e, count++);
Packit Service b38f0b
            e = e->next;
Packit Service b38f0b
        }
Packit Service b38f0b
Packit Service b38f0b
        if (count > 0) {
Packit Service b38f0b
            DEBUGMSG(("dump_etimelist", "\n"));
Packit Service b38f0b
        }
Packit Service b38f0b
    }                           /* endwhile */
Packit Service b38f0b
Packit Service b38f0b
    DEBUGMSG(("dump_etimelist", "\n"));
Packit Service b38f0b
Packit Service b38f0b
}                               /* end dump_etimelist() */
Packit Service b38f0b
#endif                          /* NETSNMP_ENABLE_TESTING_CODE */
Packit Service b38f0b
#endif /* NETSNMP_FEATURE_REMOVE_USM_LCD_TIME */