/src/net-snmp/snmplib/lcd_time.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * lcd_time.c | 
| 3 |  |  * | 
| 4 |  |  * XXX  Should etimelist entries with <0,0> time tuples be timed out? | 
| 5 |  |  * XXX  Need a routine to free the memory?  (Perhaps at shutdown?) | 
| 6 |  |  */ | 
| 7 |  |  | 
| 8 |  | #include <net-snmp/net-snmp-config.h> | 
| 9 |  | #include <net-snmp/net-snmp-features.h> | 
| 10 |  |  | 
| 11 |  | #include <sys/types.h> | 
| 12 |  | #include <stdio.h> | 
| 13 |  | #ifdef HAVE_STDLIB_H | 
| 14 |  | #include <stdlib.h> | 
| 15 |  | #endif | 
| 16 |  | #ifdef HAVE_STRING_H | 
| 17 |  | #include <string.h> | 
| 18 |  | #else | 
| 19 |  | #include <strings.h> | 
| 20 |  | #endif | 
| 21 |  | #ifdef TIME_WITH_SYS_TIME | 
| 22 |  | # include <sys/time.h> | 
| 23 |  | # include <time.h> | 
| 24 |  | #else | 
| 25 |  | # ifdef HAVE_SYS_TIME_H | 
| 26 |  | #  include <sys/time.h> | 
| 27 |  | # else | 
| 28 |  | #  include <time.h> | 
| 29 |  | # endif | 
| 30 |  | #endif | 
| 31 |  | #ifdef HAVE_NETINET_IN_H | 
| 32 |  | #include <netinet/in.h> | 
| 33 |  | #endif | 
| 34 |  |  | 
| 35 |  | #ifdef HAVE_UNISTD_H | 
| 36 |  | #include <unistd.h> | 
| 37 |  | #endif | 
| 38 |  |  | 
| 39 |  | #include <net-snmp/types.h> | 
| 40 |  | #include <net-snmp/output_api.h> | 
| 41 |  | #include <net-snmp/utilities.h> | 
| 42 |  |  | 
| 43 |  | #include <net-snmp/library/snmp_api.h> | 
| 44 |  | #include <net-snmp/library/callback.h> | 
| 45 |  | #include <net-snmp/library/snmp_secmod.h> | 
| 46 |  | #include <net-snmp/library/snmpusm.h> | 
| 47 |  | #include <net-snmp/library/lcd_time.h> | 
| 48 |  | #include <net-snmp/library/scapi.h> | 
| 49 |  | #include <net-snmp/library/snmpv3.h> | 
| 50 |  |  | 
| 51 |  | #include <net-snmp/library/transform_oids.h> | 
| 52 |  |  | 
| 53 |  | netsnmp_feature_child_of(usm_support, libnetsnmp); | 
| 54 |  | netsnmp_feature_child_of(usm_lcd_time, usm_support); | 
| 55 |  |  | 
| 56 |  | #ifndef NETSNMP_FEATURE_REMOVE_USM_LCD_TIME | 
| 57 |  |  | 
| 58 |  | /* | 
| 59 |  |  * Global static hashlist to contain Enginetime entries. | 
| 60 |  |  * | 
| 61 |  |  * New records are prepended to the appropriate list at the hash index. | 
| 62 |  |  */ | 
| 63 |  | static Enginetime etimelist[ETIMELIST_SIZE]; | 
| 64 |  |  | 
| 65 |  |  | 
| 66 |  |  | 
| 67 |  |  | 
| 68 |  | /*******************************************************************-o-****** | 
| 69 |  |  * get_enginetime | 
| 70 |  |  * | 
| 71 |  |  * Parameters: | 
| 72 |  |  *  *engineID | 
| 73 |  |  *   engineID_len | 
| 74 |  |  *  *engineboot | 
| 75 |  |  *  *engine_time | 
| 76 |  |  *       | 
| 77 |  |  * Returns: | 
| 78 |  |  *  SNMPERR_SUCCESS   Success -- when a record for engineID is found. | 
| 79 |  |  *  SNMPERR_GENERR    Otherwise. | 
| 80 |  |  * | 
| 81 |  |  * | 
| 82 |  |  * Lookup engineID and return the recorded values for the | 
| 83 |  |  * <engine_time, engineboot> tuple adjusted to reflect the estimated time | 
| 84 |  |  * at the engine in question. | 
| 85 |  |  * | 
| 86 |  |  * Special case: if engineID is NULL or if engineID_len is 0 then | 
| 87 |  |  * the time tuple is returned immediately as zero. | 
| 88 |  |  * | 
| 89 |  |  * XXX  What if timediff wraps?  >shrug< | 
| 90 |  |  * XXX  Then: you need to increment the boots value.  Now.  Detecting | 
| 91 |  |  *            this is another matter. | 
| 92 |  |  */ | 
| 93 |  | int | 
| 94 |  | get_enginetime(const u_char * engineID, | 
| 95 |  |                u_int engineID_len, | 
| 96 |  |                u_int * engineboot, | 
| 97 |  |                u_int * engine_time, u_int authenticated) | 
| 98 | 0 | { | 
| 99 | 0 |     int             rval = SNMPERR_SUCCESS; | 
| 100 | 0 |     int             timediff = 0; | 
| 101 | 0 |     Enginetime      e = NULL; | 
| 102 |  |  | 
| 103 |  |  | 
| 104 |  |  | 
| 105 |  |     /* | 
| 106 |  |      * Sanity check. | 
| 107 |  |      */ | 
| 108 | 0 |     if (!engine_time || !engineboot) { | 
| 109 | 0 |         QUITFUN(SNMPERR_GENERR, get_enginetime_quit); | 
| 110 | 0 |     } | 
| 111 |  |  | 
| 112 |  |  | 
| 113 |  |     /* | 
| 114 |  |      * Compute estimated current engine_time tuple at engineID if | 
| 115 |  |      * a record is cached for it. | 
| 116 |  |      */ | 
| 117 | 0 |     *engine_time = *engineboot = 0; | 
| 118 |  | 
 | 
| 119 | 0 |     if (!engineID || (engineID_len <= 0)) { | 
| 120 | 0 |         QUITFUN(SNMPERR_GENERR, get_enginetime_quit); | 
| 121 | 0 |     } | 
| 122 |  |  | 
| 123 | 0 |     if (!(e = search_enginetime_list(engineID, engineID_len))) { | 
| 124 | 0 |         QUITFUN(SNMPERR_GENERR, get_enginetime_quit); | 
| 125 | 0 |     } | 
| 126 | 0 | #ifdef LCD_TIME_SYNC_OPT | 
| 127 | 0 |     if (!authenticated || e->authenticatedFlag) { | 
| 128 | 0 | #endif | 
| 129 | 0 |         *engine_time = e->engineTime; | 
| 130 | 0 |         *engineboot = e->engineBoot; | 
| 131 |  | 
 | 
| 132 | 0 |        timediff = (int) (snmpv3_local_snmpEngineTime() - e->lastReceivedEngineTime); | 
| 133 |  | 
 | 
| 134 | 0 | #ifdef LCD_TIME_SYNC_OPT | 
| 135 | 0 |     } | 
| 136 | 0 | #endif | 
| 137 |  | 
 | 
| 138 | 0 |     if (timediff > (int) (ENGINETIME_MAX - *engine_time)) { | 
| 139 | 0 |         *engine_time = (timediff - (ENGINETIME_MAX - *engine_time)); | 
| 140 |  |  | 
| 141 |  |         /* | 
| 142 |  |          * FIX -- move this check up... should not change anything | 
| 143 |  |          * * if engineboot is already locked.  ??? | 
| 144 |  |          */ | 
| 145 | 0 |         if (*engineboot < ENGINEBOOT_MAX) { | 
| 146 | 0 |             *engineboot += 1; | 
| 147 | 0 |         } | 
| 148 |  | 
 | 
| 149 | 0 |     } else { | 
| 150 | 0 |         *engine_time += timediff; | 
| 151 | 0 |     } | 
| 152 |  | 
 | 
| 153 | 0 |     DEBUGMSGTL(("lcd_get_enginetime", "engineID ")); | 
| 154 | 0 |     DEBUGMSGHEX(("lcd_get_enginetime", engineID, engineID_len)); | 
| 155 | 0 |     DEBUGMSG(("lcd_get_enginetime", ": boots=%d, time=%d\n", *engineboot, | 
| 156 | 0 |               *engine_time)); | 
| 157 |  | 
 | 
| 158 | 0 |   get_enginetime_quit: | 
| 159 | 0 |     return rval; | 
| 160 |  | 
 | 
| 161 | 0 | }                               /* end get_enginetime() */ | 
| 162 |  |  | 
| 163 |  | /*******************************************************************-o-****** | 
| 164 |  |  * get_enginetime | 
| 165 |  |  * | 
| 166 |  |  * Parameters: | 
| 167 |  |  *  *engineID | 
| 168 |  |  *   engineID_len | 
| 169 |  |  *  *engineboot | 
| 170 |  |  *  *engine_time | 
| 171 |  |  *       | 
| 172 |  |  * Returns: | 
| 173 |  |  *  SNMPERR_SUCCESS   Success -- when a record for engineID is found. | 
| 174 |  |  *  SNMPERR_GENERR    Otherwise. | 
| 175 |  |  * | 
| 176 |  |  * | 
| 177 |  |  * Lookup engineID and return the recorded values for the | 
| 178 |  |  * <engine_time, engineboot> tuple adjusted to reflect the estimated time | 
| 179 |  |  * at the engine in question. | 
| 180 |  |  * | 
| 181 |  |  * Special case: if engineID is NULL or if engineID_len is 0 then | 
| 182 |  |  * the time tuple is returned immediately as zero. | 
| 183 |  |  * | 
| 184 |  |  * XXX  What if timediff wraps?  >shrug< | 
| 185 |  |  * XXX  Then: you need to increment the boots value.  Now.  Detecting | 
| 186 |  |  *            this is another matter. | 
| 187 |  |  */ | 
| 188 |  | int | 
| 189 |  | get_enginetime_ex(u_char * engineID, | 
| 190 |  |                   u_int engineID_len, | 
| 191 |  |                   u_int * engineboot, | 
| 192 |  |                   u_int * engine_time, | 
| 193 |  |                   u_int * last_engine_time, u_int authenticated) | 
| 194 | 0 | { | 
| 195 | 0 |     int             rval = SNMPERR_SUCCESS; | 
| 196 | 0 |     int             timediff = 0; | 
| 197 | 0 |     Enginetime      e = NULL; | 
| 198 |  |  | 
| 199 |  |  | 
| 200 |  |  | 
| 201 |  |     /* | 
| 202 |  |      * Sanity check. | 
| 203 |  |      */ | 
| 204 | 0 |     if (!engine_time || !engineboot || !last_engine_time) { | 
| 205 | 0 |         QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit); | 
| 206 | 0 |     } | 
| 207 |  |  | 
| 208 |  |  | 
| 209 |  |     /* | 
| 210 |  |      * Compute estimated current engine_time tuple at engineID if | 
| 211 |  |      * a record is cached for it. | 
| 212 |  |      */ | 
| 213 | 0 |     *last_engine_time = *engine_time = *engineboot = 0; | 
| 214 |  | 
 | 
| 215 | 0 |     if (!engineID || (engineID_len <= 0)) { | 
| 216 | 0 |         QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit); | 
| 217 | 0 |     } | 
| 218 |  |  | 
| 219 | 0 |     if (!(e = search_enginetime_list(engineID, engineID_len))) { | 
| 220 | 0 |         QUITFUN(SNMPERR_GENERR, get_enginetime_ex_quit); | 
| 221 | 0 |     } | 
| 222 | 0 | #ifdef LCD_TIME_SYNC_OPT | 
| 223 | 0 |     if (!authenticated || e->authenticatedFlag) { | 
| 224 | 0 | #endif | 
| 225 | 0 |         *last_engine_time = *engine_time = e->engineTime; | 
| 226 | 0 |         *engineboot = e->engineBoot; | 
| 227 |  | 
 | 
| 228 | 0 |        timediff = (int) (snmpv3_local_snmpEngineTime() - e->lastReceivedEngineTime); | 
| 229 |  | 
 | 
| 230 | 0 | #ifdef LCD_TIME_SYNC_OPT | 
| 231 | 0 |     } | 
| 232 | 0 | #endif | 
| 233 |  | 
 | 
| 234 | 0 |     if (timediff > (int) (ENGINETIME_MAX - *engine_time)) { | 
| 235 | 0 |         *engine_time = (timediff - (ENGINETIME_MAX - *engine_time)); | 
| 236 |  |  | 
| 237 |  |         /* | 
| 238 |  |          * FIX -- move this check up... should not change anything | 
| 239 |  |          * * if engineboot is already locked.  ??? | 
| 240 |  |          */ | 
| 241 | 0 |         if (*engineboot < ENGINEBOOT_MAX) { | 
| 242 | 0 |             *engineboot += 1; | 
| 243 | 0 |         } | 
| 244 |  | 
 | 
| 245 | 0 |     } else { | 
| 246 | 0 |         *engine_time += timediff; | 
| 247 | 0 |     } | 
| 248 |  | 
 | 
| 249 | 0 |     DEBUGMSGTL(("lcd_get_enginetime_ex", "engineID ")); | 
| 250 | 0 |     DEBUGMSGHEX(("lcd_get_enginetime_ex", engineID, engineID_len)); | 
| 251 | 0 |     DEBUGMSG(("lcd_get_enginetime_ex", ": boots=%d, time=%d\n", | 
| 252 | 0 |               *engineboot, *engine_time)); | 
| 253 |  | 
 | 
| 254 | 0 |   get_enginetime_ex_quit: | 
| 255 | 0 |     return rval; | 
| 256 |  | 
 | 
| 257 | 0 | }                               /* end get_enginetime_ex() */ | 
| 258 |  |  | 
| 259 |  |  | 
| 260 |  | void free_enginetime(unsigned char *engineID, size_t engineID_len) | 
| 261 | 0 | { | 
| 262 | 0 |     Enginetime      e = NULL; | 
| 263 | 0 |     int             rval = 0; | 
| 264 |  | 
 | 
| 265 | 0 |     rval = hash_engineID(engineID, engineID_len); | 
| 266 | 0 |     if (rval < 0) | 
| 267 | 0 |   return; | 
| 268 |  |  | 
| 269 | 0 |     e = etimelist[rval]; | 
| 270 |  | 
 | 
| 271 | 0 |     while (e != NULL) { | 
| 272 | 0 |   etimelist[rval] = e->next; | 
| 273 | 0 |   SNMP_FREE(e->engineID); | 
| 274 | 0 |   SNMP_FREE(e); | 
| 275 | 0 |   e = etimelist[rval]; | 
| 276 | 0 |     } | 
| 277 |  | 
 | 
| 278 | 0 | } | 
| 279 |  |  | 
| 280 |  | /*******************************************************************-o-**** | 
| 281 |  | ** | 
| 282 |  |  * free_etimelist | 
| 283 |  |  * | 
| 284 |  |  * Parameters: | 
| 285 |  |  *   None | 
| 286 |  |  *       | 
| 287 |  |  * Returns: | 
| 288 |  |  *   void | 
| 289 |  |  * | 
| 290 |  |  * | 
| 291 |  |  * Free all of the memory used by entries in the etimelist. | 
| 292 |  |  * | 
| 293 |  |  */ | 
| 294 |  | void free_etimelist(void) | 
| 295 | 0 | { | 
| 296 | 0 |      int index = 0; | 
| 297 | 0 |      Enginetime e = NULL; | 
| 298 | 0 |      Enginetime nextE = NULL; | 
| 299 |  | 
 | 
| 300 | 0 |      for( ; index < ETIMELIST_SIZE; ++index) | 
| 301 | 0 |      { | 
| 302 | 0 |            e = etimelist[index]; | 
| 303 |  | 
 | 
| 304 | 0 |            while(e != NULL) | 
| 305 | 0 |            { | 
| 306 | 0 |                  nextE = e->next; | 
| 307 | 0 |                  SNMP_FREE(e->engineID); | 
| 308 | 0 |                  SNMP_FREE(e); | 
| 309 | 0 |                  e = nextE; | 
| 310 | 0 |            } | 
| 311 |  | 
 | 
| 312 | 0 |            etimelist[index] = NULL; | 
| 313 | 0 |      } | 
| 314 | 0 |      return; | 
| 315 | 0 | } | 
| 316 |  |  | 
| 317 |  | /*******************************************************************-o-****** | 
| 318 |  |  * set_enginetime | 
| 319 |  |  * | 
| 320 |  |  * Parameters: | 
| 321 |  |  *  *engineID | 
| 322 |  |  *   engineID_len | 
| 323 |  |  *   engineboot | 
| 324 |  |  *   engine_time | 
| 325 |  |  *       | 
| 326 |  |  * Returns: | 
| 327 |  |  *  SNMPERR_SUCCESS   Success. | 
| 328 |  |  *  SNMPERR_GENERR    Otherwise. | 
| 329 |  |  * | 
| 330 |  |  * | 
| 331 |  |  * Lookup engineID and store the given <engine_time, engineboot> tuple | 
| 332 |  |  * and then stamp the record with a consistent source of local time. | 
| 333 |  |  * If the engineID record does not exist, create one. | 
| 334 |  |  * | 
| 335 |  |  * Special case: engineID is NULL or engineID_len is 0 defines an engineID | 
| 336 |  |  * that is "always set." | 
| 337 |  |  * | 
| 338 |  |  * XXX  "Current time within the local engine" == time(NULL)... | 
| 339 |  |  */ | 
| 340 |  | int | 
| 341 |  | set_enginetime(const u_char * engineID, | 
| 342 |  |                u_int engineID_len, | 
| 343 |  |                u_int engineboot, u_int engine_time, u_int authenticated) | 
| 344 | 0 | { | 
| 345 | 0 |     int             rval = SNMPERR_SUCCESS, iindex; | 
| 346 | 0 |     Enginetime      e = NULL; | 
| 347 |  |  | 
| 348 |  |  | 
| 349 |  |  | 
| 350 |  |     /* | 
| 351 |  |      * Sanity check. | 
| 352 |  |      */ | 
| 353 | 0 |     if (!engineID || (engineID_len <= 0)) { | 
| 354 | 0 |         return rval; | 
| 355 | 0 |     } | 
| 356 |  |  | 
| 357 |  |  | 
| 358 |  |     /* | 
| 359 |  |      * Store the given <engine_time, engineboot> tuple in the record | 
| 360 |  |      * for engineID.  Create a new record if necessary. | 
| 361 |  |      */ | 
| 362 | 0 |     if (!(e = search_enginetime_list(engineID, engineID_len))) { | 
| 363 | 0 |         if ((iindex = hash_engineID(engineID, engineID_len)) < 0) { | 
| 364 | 0 |             QUITFUN(SNMPERR_GENERR, set_enginetime_quit); | 
| 365 | 0 |         } | 
| 366 |  |  | 
| 367 | 0 |         e = calloc(1, sizeof(*e)); | 
| 368 |  | 
 | 
| 369 | 0 |         e->next = etimelist[iindex]; | 
| 370 | 0 |         etimelist[iindex] = e; | 
| 371 |  | 
 | 
| 372 | 0 |         e->engineID = calloc(1, engineID_len); | 
| 373 | 0 |         memcpy(e->engineID, engineID, engineID_len); | 
| 374 |  | 
 | 
| 375 | 0 |         e->engineID_len = engineID_len; | 
| 376 | 0 |     } | 
| 377 | 0 | #ifdef LCD_TIME_SYNC_OPT | 
| 378 | 0 |     if (authenticated || !e->authenticatedFlag) { | 
| 379 | 0 |         e->authenticatedFlag = authenticated; | 
| 380 |  | #else | 
| 381 |  |     if (authenticated) { | 
| 382 |  | #endif | 
| 383 | 0 |         e->engineTime = engine_time; | 
| 384 | 0 |         e->engineBoot = engineboot; | 
| 385 | 0 |         e->lastReceivedEngineTime = snmpv3_local_snmpEngineTime(); | 
| 386 | 0 |     } | 
| 387 |  | 
 | 
| 388 | 0 |     e = NULL;                   /* Indicates a successful update. */ | 
| 389 |  | 
 | 
| 390 | 0 |     DEBUGMSGTL(("lcd_set_enginetime", "engineID ")); | 
| 391 | 0 |     DEBUGMSGHEX(("lcd_set_enginetime", engineID, engineID_len)); | 
| 392 | 0 |     DEBUGMSG(("lcd_set_enginetime", ": boots=%d, time=%d\n", engineboot, | 
| 393 | 0 |               engine_time)); | 
| 394 |  | 
 | 
| 395 | 0 |   set_enginetime_quit: | 
| 396 | 0 |     SNMP_FREE(e); | 
| 397 |  | 
 | 
| 398 | 0 |     return rval; | 
| 399 |  | 
 | 
| 400 | 0 | }                               /* end set_enginetime() */ | 
| 401 |  |  | 
| 402 |  |  | 
| 403 |  |  | 
| 404 |  |  | 
| 405 |  | /*******************************************************************-o-****** | 
| 406 |  |  * search_enginetime_list | 
| 407 |  |  * | 
| 408 |  |  * Parameters: | 
| 409 |  |  *  *engineID | 
| 410 |  |  *   engineID_len | 
| 411 |  |  *       | 
| 412 |  |  * Returns: | 
| 413 |  |  *  Pointer to a etimelist record with engineID <engineID>  -OR- | 
| 414 |  |  *  NULL if no record exists. | 
| 415 |  |  * | 
| 416 |  |  * | 
| 417 |  |  * Search etimelist for an entry with engineID. | 
| 418 |  |  * | 
| 419 |  |  * ASSUMES that no engineID will have more than one record in the list. | 
| 420 |  |  */ | 
| 421 |  | Enginetime | 
| 422 |  | search_enginetime_list(const u_char * engineID, u_int engineID_len) | 
| 423 | 0 | { | 
| 424 | 0 |     int             rval = SNMPERR_SUCCESS; | 
| 425 | 0 |     Enginetime      e = NULL; | 
| 426 |  |  | 
| 427 |  |  | 
| 428 |  |     /* | 
| 429 |  |      * Sanity check. | 
| 430 |  |      */ | 
| 431 | 0 |     if (!engineID || (engineID_len <= 0)) { | 
| 432 | 0 |         QUITFUN(SNMPERR_GENERR, search_enginetime_list_quit); | 
| 433 | 0 |     } | 
| 434 |  |  | 
| 435 |  |  | 
| 436 |  |     /* | 
| 437 |  |      * Find the entry for engineID if there be one. | 
| 438 |  |      */ | 
| 439 | 0 |     rval = hash_engineID(engineID, engineID_len); | 
| 440 | 0 |     if (rval < 0) { | 
| 441 | 0 |         QUITFUN(SNMPERR_GENERR, search_enginetime_list_quit); | 
| 442 | 0 |     } | 
| 443 | 0 |     e = etimelist[rval]; | 
| 444 |  | 
 | 
| 445 | 0 |     for ( /*EMPTY*/; e; e = e->next) { | 
| 446 | 0 |         if ((engineID_len == e->engineID_len) | 
| 447 | 0 |             && !memcmp(e->engineID, engineID, engineID_len)) { | 
| 448 | 0 |             break; | 
| 449 | 0 |         } | 
| 450 | 0 |     } | 
| 451 |  |  | 
| 452 |  | 
 | 
| 453 | 0 |   search_enginetime_list_quit: | 
| 454 | 0 |     return e; | 
| 455 |  | 
 | 
| 456 | 0 | }                               /* end search_enginetime_list() */ | 
| 457 |  |  | 
| 458 |  |  | 
| 459 |  |  | 
| 460 |  |  | 
| 461 |  |  | 
| 462 |  | /*******************************************************************-o-****** | 
| 463 |  |  * hash_engineID | 
| 464 |  |  * | 
| 465 |  |  * Parameters: | 
| 466 |  |  *  *engineID | 
| 467 |  |  *   engineID_len | 
| 468 |  |  *       | 
| 469 |  |  * Returns: | 
| 470 |  |  *  >0      etimelist index for this engineID. | 
| 471 |  |  *  SNMPERR_GENERR    Error. | 
| 472 |  |  *   | 
| 473 |  |  *  | 
| 474 |  |  * Use a cheap hash to build an index into the etimelist.  Method is  | 
| 475 |  |  * to hash the engineID, then split the hash into u_int's and add them up | 
| 476 |  |  * and modulo the size of the list. | 
| 477 |  |  * | 
| 478 |  |  */ | 
| 479 |  | int | 
| 480 |  | hash_engineID(const u_char * engineID, u_int engineID_len) | 
| 481 | 0 | { | 
| 482 | 0 |     int             rval = SNMPERR_GENERR; | 
| 483 | 0 |     size_t          buf_len = SNMP_MAXBUF; | 
| 484 | 0 |     u_int           additive = 0; | 
| 485 | 0 |     u_char         *bufp, buf[SNMP_MAXBUF]; | 
| 486 | 0 |     void           *context = NULL; | 
| 487 |  |  | 
| 488 |  |  | 
| 489 |  |  | 
| 490 |  |     /* | 
| 491 |  |      * Sanity check. | 
| 492 |  |      */ | 
| 493 | 0 |     if (!engineID || (engineID_len <= 0)) { | 
| 494 | 0 |         QUITFUN(SNMPERR_GENERR, hash_engineID_quit); | 
| 495 | 0 |     } | 
| 496 |  |  | 
| 497 |  |  | 
| 498 |  |     /* | 
| 499 |  |      * Hash engineID into a list index. | 
| 500 |  |      */ | 
| 501 | 0 | #ifndef NETSNMP_DISABLE_MD5 | 
| 502 | 0 |     rval = sc_hash(usmHMACMD5AuthProtocol, | 
| 503 | 0 |                    OID_LENGTH(usmHMACMD5AuthProtocol), | 
| 504 | 0 |                    engineID, engineID_len, buf, &buf_len); | 
| 505 | 0 |     if (rval == SNMPERR_SC_NOT_CONFIGURED) { | 
| 506 |  |         /* fall back to sha1 */ | 
| 507 | 0 |         rval = sc_hash(usmHMACSHA1AuthProtocol, | 
| 508 | 0 |                    OID_LENGTH(usmHMACSHA1AuthProtocol), | 
| 509 | 0 |                    engineID, engineID_len, buf, &buf_len); | 
| 510 | 0 |     } | 
| 511 |  | #else | 
| 512 |  |     rval = sc_hash(usmHMACSHA1AuthProtocol, | 
| 513 |  |                    OID_LENGTH(usmHMACSHA1AuthProtocol), | 
| 514 |  |                    engineID, engineID_len, buf, &buf_len); | 
| 515 |  | #endif | 
| 516 | 0 |     QUITFUN(rval, hash_engineID_quit); | 
| 517 |  | 
 | 
| 518 | 0 |     for (bufp = buf; (bufp - buf) < (int) buf_len; bufp += 4) { | 
| 519 | 0 |         additive += (u_int) * bufp; | 
| 520 | 0 |     } | 
| 521 |  | 
 | 
| 522 | 0 |   hash_engineID_quit: | 
| 523 | 0 |     SNMP_FREE(context); | 
| 524 | 0 |     memset(buf, 0, SNMP_MAXBUF); | 
| 525 |  | 
 | 
| 526 | 0 |     return (rval < 0) ? rval : (int)(additive % ETIMELIST_SIZE); | 
| 527 |  | 
 | 
| 528 | 0 | }                               /* end hash_engineID() */ | 
| 529 |  |  | 
| 530 |  |  | 
| 531 |  |  | 
| 532 |  |  | 
| 533 |  | #ifdef NETSNMP_ENABLE_TESTING_CODE | 
| 534 |  | /*******************************************************************-o-****** | 
| 535 |  |  * dump_etimelist_entry | 
| 536 |  |  * | 
| 537 |  |  * Parameters: | 
| 538 |  |  *  e | 
| 539 |  |  *  count | 
| 540 |  |  */ | 
| 541 |  | void | 
| 542 |  | dump_etimelist_entry(Enginetime e, int count) | 
| 543 |  | { | 
| 544 |  |     size_t          buflen; | 
| 545 |  |     char            tabs[SNMP_MAXBUF], *t = tabs, *s; | 
| 546 |  |  | 
| 547 |  |  | 
| 548 |  |  | 
| 549 |  |     count += 1; | 
| 550 |  |     while (count--) { | 
| 551 |  |         t += sprintf(t, "  "); | 
| 552 |  |     } | 
| 553 |  |  | 
| 554 |  |  | 
| 555 |  |     buflen = e->engineID_len; | 
| 556 |  |     if (!(s = dump_snmpEngineID(e->engineID, &buflen))) { | 
| 557 |  |         binary_to_hex(e->engineID, e->engineID_len, &s); | 
| 558 |  |     } | 
| 559 |  |  | 
| 560 |  |     DEBUGMSGTL(("dump_etimelist", "%s\n", tabs)); | 
| 561 |  |     DEBUGMSGTL(("dump_etimelist", "%s%s (len=%d) <%d,%d>\n", tabs, | 
| 562 |  |                 s, e->engineID_len, e->engineTime, e->engineBoot)); | 
| 563 |  |     DEBUGMSGTL(("dump_etimelist", "%s%ld (%ld)", tabs, | 
| 564 |  |                 e->lastReceivedEngineTime, | 
| 565 |  |                 snmpv3_local_snmpEngineTime() - e->lastReceivedEngineTime)); | 
| 566 |  |  | 
| 567 |  |     SNMP_FREE(s); | 
| 568 |  |  | 
| 569 |  | }                               /* end dump_etimelist_entry() */ | 
| 570 |  |  | 
| 571 |  |  | 
| 572 |  |  | 
| 573 |  |  | 
| 574 |  | /*******************************************************************-o-****** | 
| 575 |  |  * dump_etimelist | 
| 576 |  |  */ | 
| 577 |  | void | 
| 578 |  | dump_etimelist(void) | 
| 579 |  | { | 
| 580 |  |     int             iindex = -1, count = 0; | 
| 581 |  |     Enginetime      e; | 
| 582 |  |  | 
| 583 |  |  | 
| 584 |  |  | 
| 585 |  |     DEBUGMSGTL(("dump_etimelist", "\n")); | 
| 586 |  |  | 
| 587 |  |     while (++iindex < ETIMELIST_SIZE) { | 
| 588 |  |         DEBUGMSG(("dump_etimelist", "[%d]", iindex)); | 
| 589 |  |  | 
| 590 |  |         count = 0; | 
| 591 |  |         e = etimelist[iindex]; | 
| 592 |  |  | 
| 593 |  |         while (e) { | 
| 594 |  |             dump_etimelist_entry(e, count++); | 
| 595 |  |             e = e->next; | 
| 596 |  |         } | 
| 597 |  |  | 
| 598 |  |         if (count > 0) { | 
| 599 |  |             DEBUGMSG(("dump_etimelist", "\n")); | 
| 600 |  |         } | 
| 601 |  |     }                           /* endwhile */ | 
| 602 |  |  | 
| 603 |  |     DEBUGMSG(("dump_etimelist", "\n")); | 
| 604 |  |  | 
| 605 |  | }                               /* end dump_etimelist() */ | 
| 606 |  | #endif                          /* NETSNMP_ENABLE_TESTING_CODE */ | 
| 607 |  | #endif /* NETSNMP_FEATURE_REMOVE_USM_LCD_TIME */ |