net-snmp
5.4.1
|
00001 /* 00002 * tools.c 00003 */ 00004 00005 #define NETSNMP_TOOLS_C 1 /* dont re-define malloc wrappers here */ 00006 00007 #include <net-snmp/net-snmp-config.h> 00008 00009 #include <ctype.h> 00010 #include <stdio.h> 00011 #include <sys/types.h> 00012 #if TIME_WITH_SYS_TIME 00013 # ifdef WIN32 00014 # include <sys/timeb.h> 00015 # else 00016 # include <sys/time.h> 00017 # endif 00018 # include <time.h> 00019 #else 00020 # if HAVE_SYS_TIME_H 00021 # include <sys/time.h> 00022 # else 00023 # include <time.h> 00024 # endif 00025 #endif 00026 #ifdef HAVE_SYS_SOCKET_H 00027 #include <sys/socket.h> 00028 #endif 00029 #if HAVE_WINSOCK_H 00030 #include <winsock.h> 00031 #endif 00032 #ifdef HAVE_STDLIB_H 00033 #include <stdlib.h> 00034 #endif 00035 #if HAVE_STRING_H 00036 #include <string.h> 00037 #else 00038 #include <strings.h> 00039 #endif 00040 #ifdef HAVE_NETINET_IN_H 00041 #include <netinet/in.h> 00042 #endif 00043 #ifdef HAVE_ARPA_INET_H 00044 #include <arpa/inet.h> 00045 #endif 00046 #ifdef cygwin 00047 #include <windows.h> 00048 #endif 00049 00050 #if HAVE_DMALLOC_H 00051 #include <dmalloc.h> 00052 #endif 00053 00054 #include <net-snmp/types.h> 00055 #include <net-snmp/output_api.h> 00056 #include <net-snmp/utilities.h> 00057 #include <net-snmp/library/tools.h> /* for "internal" definitions */ 00058 00059 #include <net-snmp/library/snmp_api.h> 00060 #include <net-snmp/library/mib.h> 00061 #include <net-snmp/library/scapi.h> 00062 00063 #ifdef WIN32 00064 00067 char * netsnmp_strdup( const char * ptr) 00068 { 00069 return strdup(ptr); 00070 } 00074 void * netsnmp_calloc(size_t nmemb, size_t size) 00075 { 00076 return calloc(nmemb, size); 00077 } 00078 00082 void * netsnmp_malloc(size_t size) 00083 { 00084 return malloc(size); 00085 } 00086 00090 void * netsnmp_realloc( void * ptr, size_t size) 00091 { 00092 return realloc(ptr, size); 00093 } 00094 00099 void netsnmp_free( void * ptr) 00100 { 00101 if (ptr) 00102 free(ptr); 00103 } 00104 #endif /* WIN32 */ 00105 00120 int 00121 snmp_realloc(u_char ** buf, size_t * buf_len) 00122 { 00123 u_char *new_buf = NULL; 00124 size_t new_buf_len = 0; 00125 00126 if (buf == NULL) { 00127 return 0; 00128 } 00129 00130 if (*buf_len <= 255) { 00131 new_buf_len = *buf_len + 256; 00132 } else if (*buf_len > 255 && *buf_len <= 8191) { 00133 new_buf_len = *buf_len * 2; 00134 } else if (*buf_len > 8191) { 00135 new_buf_len = *buf_len + 8192; 00136 } 00137 00138 if (*buf == NULL) { 00139 new_buf = (u_char *) malloc(new_buf_len); 00140 } else { 00141 new_buf = (u_char *) realloc(*buf, new_buf_len); 00142 } 00143 00144 if (new_buf != NULL) { 00145 *buf = new_buf; 00146 *buf_len = new_buf_len; 00147 return 1; 00148 } else { 00149 return 0; 00150 } 00151 } 00152 00153 int 00154 snmp_strcat(u_char ** buf, size_t * buf_len, size_t * out_len, 00155 int allow_realloc, const u_char * s) 00156 { 00157 if (buf == NULL || buf_len == NULL || out_len == NULL) { 00158 return 0; 00159 } 00160 00161 if (s == NULL) { 00162 /* 00163 * Appending a NULL string always succeeds since it is a NOP. 00164 */ 00165 return 1; 00166 } 00167 00168 while ((*out_len + strlen((const char *) s) + 1) >= *buf_len) { 00169 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 00170 return 0; 00171 } 00172 } 00173 00174 strcpy((char *) (*buf + *out_len), (const char *) s); 00175 *out_len += strlen((char *) (*buf + *out_len)); 00176 return 1; 00177 } 00178 00184 void 00185 free_zero(void *buf, size_t size) 00186 { 00187 if (buf) { 00188 memset(buf, 0, size); 00189 free(buf); 00190 } 00191 00192 } /* end free_zero() */ 00193 00204 u_char * 00205 malloc_random(size_t * size) 00206 { 00207 int rval = SNMPERR_SUCCESS; 00208 u_char *buf = (u_char *) calloc(1, *size); 00209 00210 if (buf) { 00211 rval = sc_random(buf, size); 00212 00213 if (rval < 0) { 00214 free_zero(buf, *size); 00215 buf = NULL; 00216 } else { 00217 *size = rval; 00218 } 00219 } 00220 00221 return buf; 00222 00223 } /* end malloc_random() */ 00224 00235 int 00236 memdup(u_char ** to, const u_char * from, size_t size) 00237 { 00238 if (to == NULL) 00239 return SNMPERR_GENERR; 00240 if (from == NULL) { 00241 *to = NULL; 00242 return SNMPERR_SUCCESS; 00243 } 00244 if ((*to = (u_char *) malloc(size)) == NULL) 00245 return SNMPERR_GENERR; 00246 memcpy(*to, from, size); 00247 return SNMPERR_SUCCESS; 00248 00249 } /* end memdup() */ 00250 00254 char * 00255 netsnmp_strdup_and_null(const u_char * from, size_t from_len) 00256 { 00257 char *ret; 00258 00259 if (from_len == 0 || from[from_len - 1] != '\0') { 00260 ret = (char *)malloc(from_len + 1); 00261 if (!ret) 00262 return NULL; 00263 ret[from_len] = '\0'; 00264 } else { 00265 ret = (char *)malloc(from_len); 00266 if (!ret) 00267 return NULL; 00268 ret[from_len - 1] = '\0'; 00269 } 00270 memcpy(ret, from, from_len); 00271 return ret; 00272 } 00273 00286 u_int 00287 binary_to_hex(const u_char * input, size_t len, char **output) 00288 { 00289 u_int olen = (len * 2) + 1; 00290 char *s = (char *) calloc(1, olen), *op = s; 00291 const u_char *ip = input; 00292 00293 00294 while (ip - input < (int) len) { 00295 *op++ = VAL2HEX((*ip >> 4) & 0xf); 00296 *op++ = VAL2HEX(*ip & 0xf); 00297 ip++; 00298 } 00299 *op = '\0'; 00300 00301 *output = s; 00302 return olen; 00303 00304 } /* end binary_to_hex() */ 00305 00306 00307 00308 00323 int 00324 hex_to_binary2(const u_char * input, size_t len, char **output) 00325 { 00326 u_int olen = (len / 2) + (len % 2); 00327 char *s = (char *) calloc(1, (olen) ? olen : 1), *op = s; 00328 const u_char *ip = input; 00329 00330 00331 *output = NULL; 00332 *op = 0; 00333 if (len % 2) { 00334 if (!isxdigit(*ip)) 00335 goto hex_to_binary2_quit; 00336 *op++ = HEX2VAL(*ip); 00337 ip++; 00338 } 00339 00340 while (ip - input < (int) len) { 00341 if (!isxdigit(*ip)) 00342 goto hex_to_binary2_quit; 00343 *op = HEX2VAL(*ip) << 4; 00344 ip++; 00345 00346 if (!isxdigit(*ip)) 00347 goto hex_to_binary2_quit; 00348 *op++ += HEX2VAL(*ip); 00349 ip++; 00350 } 00351 00352 *output = s; 00353 return olen; 00354 00355 hex_to_binary2_quit: 00356 free_zero(s, olen); 00357 return -1; 00358 00359 } /* end hex_to_binary2() */ 00360 00361 int 00362 snmp_decimal_to_binary(u_char ** buf, size_t * buf_len, size_t * out_len, 00363 int allow_realloc, const char *decimal) 00364 { 00365 int subid = 0; 00366 const char *cp = decimal; 00367 00368 if (buf == NULL || buf_len == NULL || out_len == NULL 00369 || decimal == NULL) { 00370 return 0; 00371 } 00372 00373 while (*cp != '\0') { 00374 if (isspace((int) *cp) || *cp == '.') { 00375 cp++; 00376 continue; 00377 } 00378 if (!isdigit((int) *cp)) { 00379 return 0; 00380 } 00381 if ((subid = atoi(cp)) > 255) { 00382 return 0; 00383 } 00384 if ((*out_len >= *buf_len) && 00385 !(allow_realloc && snmp_realloc(buf, buf_len))) { 00386 return 0; 00387 } 00388 *(*buf + *out_len) = (u_char) subid; 00389 (*out_len)++; 00390 while (isdigit((int) *cp)) { 00391 cp++; 00392 } 00393 } 00394 return 1; 00395 } 00396 00424 int 00425 netsnmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * offset, 00426 int allow_realloc, const char *hex, const char *delim) 00427 { 00428 int subid = 0; 00429 const char *cp = hex; 00430 00431 if (buf == NULL || buf_len == NULL || offset == NULL || hex == NULL) { 00432 return 0; 00433 } 00434 00435 if ((*cp == '0') && ((*(cp + 1) == 'x') || (*(cp + 1) == 'X'))) { 00436 cp += 2; 00437 } 00438 00439 while (*cp != '\0') { 00440 if (!isxdigit((int) *cp) || 00441 !isxdigit((int) *(cp+1))) { 00442 if ((NULL != delim) && (NULL != strchr(delim, *cp))) { 00443 cp++; 00444 continue; 00445 } 00446 return 0; 00447 } 00448 if (sscanf(cp, "%2x", &subid) == 0) { 00449 return 0; 00450 } 00451 /* 00452 * if we dont' have enough space, realloc. 00453 * (snmp_realloc will adjust buf_len to new size) 00454 */ 00455 if ((*offset >= *buf_len) && 00456 !(allow_realloc && snmp_realloc(buf, buf_len))) { 00457 return 0; 00458 } 00459 *(*buf + *offset) = (u_char) subid; 00460 (*offset)++; 00461 if (*++cp == '\0') { 00462 /* 00463 * Odd number of hex digits is an error. 00464 */ 00465 return 0; 00466 } else { 00467 cp++; 00468 } 00469 } 00470 return 1; 00471 } 00472 00484 int 00485 snmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * offset, 00486 int allow_realloc, const char *hex) 00487 { 00488 return netsnmp_hex_to_binary(buf, buf_len, offset, allow_realloc, hex, " "); 00489 } 00490 00491 /*******************************************************************-o-****** 00492 * dump_chunk 00493 * 00494 * Parameters: 00495 * *title (May be NULL.) 00496 * *buf 00497 * size 00498 */ 00499 void 00500 dump_chunk(const char *debugtoken, const char *title, const u_char * buf, 00501 int size) 00502 { 00503 u_int printunit = 64; /* XXX Make global. */ 00504 char chunk[SNMP_MAXBUF], *s, *sp; 00505 00506 if (title && (*title != '\0')) { 00507 DEBUGMSGTL((debugtoken, "%s\n", title)); 00508 } 00509 00510 00511 memset(chunk, 0, SNMP_MAXBUF); 00512 size = binary_to_hex(buf, size, &s); 00513 sp = s; 00514 00515 while (size > 0) { 00516 if (size > (int) printunit) { 00517 strncpy(chunk, sp, printunit); 00518 chunk[printunit] = '\0'; 00519 DEBUGMSGTL((debugtoken, "\t%s\n", chunk)); 00520 } else { 00521 DEBUGMSGTL((debugtoken, "\t%s\n", sp)); 00522 } 00523 00524 sp += printunit; 00525 size -= printunit; 00526 } 00527 00528 00529 SNMP_FREE(s); 00530 00531 } /* end dump_chunk() */ 00532 00533 00534 00535 00536 /*******************************************************************-o-****** 00537 * dump_snmpEngineID 00538 * 00539 * Parameters: 00540 * *estring 00541 * *estring_len 00542 * 00543 * Returns: 00544 * Allocated memory pointing to a string of buflen char representing 00545 * a printf'able form of the snmpEngineID. 00546 * 00547 * -OR- NULL on error. 00548 * 00549 * 00550 * Translates the snmpEngineID TC into a printable string. From RFC 2271, 00551 * Section 5 (pp. 36-37): 00552 * 00553 * First bit: 0 Bit string structured by means non-SNMPv3. 00554 * 1 Structure described by SNMPv3 SnmpEngineID TC. 00555 * 00556 * Bytes 1-4: Enterprise ID. (High bit of first byte is ignored.) 00557 * 00558 * Byte 5: 0 (RESERVED by IANA.) 00559 * 1 IPv4 address. ( 4 octets) 00560 * 2 IPv6 address. ( 16 octets) 00561 * 3 MAC address. ( 6 octets) 00562 * 4 Locally defined text. (0-27 octets) 00563 * 5 Locally defined octets. (0-27 octets) 00564 * 6-127 (RESERVED for enterprise.) 00565 * 00566 * Bytes 6-32: (Determined by byte 5.) 00567 * 00568 * 00569 * Non-printable characters are given in hex. Text is given in quotes. 00570 * IP and MAC addresses are given in standard (UN*X) conventions. Sections 00571 * are comma separated. 00572 * 00573 * esp, remaining_len and s trace the state of the constructed buffer. 00574 * s will be defined if there is something to return, and it will point 00575 * to the end of the constructed buffer. 00576 * 00577 * 00578 * ASSUME "Text" means printable characters. 00579 * 00580 * XXX Must the snmpEngineID always have a minimum length of 12? 00581 * (Cf. part 2 of the TC definition.) 00582 * XXX Does not enforce upper-bound of 32 bytes. 00583 * XXX Need a switch to decide whether to use DNS name instead of a simple 00584 * IP address. 00585 * 00586 * FIX Use something other than snprint_hexstring which doesn't add 00587 * trailing spaces and (sometimes embedded) newlines... 00588 */ 00589 #ifdef NETSNMP_ENABLE_TESTING_CODE 00590 char * 00591 dump_snmpEngineID(const u_char * estring, size_t * estring_len) 00592 { 00593 #define eb(b) ( *(esp+b) & 0xff ) 00594 00595 int rval = SNMPERR_SUCCESS, gotviolation = 0, slen = 0; 00596 u_int remaining_len; 00597 00598 char buf[SNMP_MAXBUF], *s = NULL, *t; 00599 const u_char *esp = estring; 00600 00601 struct in_addr iaddr; 00602 00603 00604 00605 /* 00606 * Sanity check. 00607 */ 00608 if (!estring || (*estring_len <= 0)) { 00609 QUITFUN(SNMPERR_GENERR, dump_snmpEngineID_quit); 00610 } 00611 remaining_len = *estring_len; 00612 memset(buf, 0, SNMP_MAXBUF); 00613 00614 00615 00616 /* 00617 * Test first bit. Return immediately with a hex string, or 00618 * begin by formatting the enterprise ID. 00619 */ 00620 if (!(*esp & 0x80)) { 00621 snprint_hexstring(buf, SNMP_MAXBUF, esp, remaining_len); 00622 s = strchr(buf, '\0'); 00623 s -= 1; 00624 goto dump_snmpEngineID_quit; 00625 } 00626 00627 s = buf; 00628 s += sprintf(s, "enterprise %d, ", ((*(esp + 0) & 0x7f) << 24) | 00629 ((*(esp + 1) & 0xff) << 16) | 00630 ((*(esp + 2) & 0xff) << 8) | ((*(esp + 3) & 0xff))); 00631 /* 00632 * XXX Ick. 00633 */ 00634 00635 if (remaining_len < 5) { /* XXX Violating string. */ 00636 goto dump_snmpEngineID_quit; 00637 } 00638 00639 esp += 4; /* Incremented one more in the switch below. */ 00640 remaining_len -= 5; 00641 00642 00643 00644 /* 00645 * Act on the fifth byte. 00646 */ 00647 switch ((int) *esp++) { 00648 case 1: /* IPv4 address. */ 00649 00650 if (remaining_len < 4) 00651 goto dump_snmpEngineID_violation; 00652 memcpy(&iaddr.s_addr, esp, 4); 00653 00654 if (!(t = inet_ntoa(iaddr))) 00655 goto dump_snmpEngineID_violation; 00656 s += sprintf(s, "%s", t); 00657 00658 esp += 4; 00659 remaining_len -= 4; 00660 break; 00661 00662 case 2: /* IPv6 address. */ 00663 00664 if (remaining_len < 16) 00665 goto dump_snmpEngineID_violation; 00666 00667 s += sprintf(s, 00668 "%02X%02X %02X%02X %02X%02X %02X%02X::" 00669 "%02X%02X %02X%02X %02X%02X %02X%02X", 00670 eb(0), eb(1), eb(2), eb(3), 00671 eb(4), eb(5), eb(6), eb(7), 00672 eb(8), eb(9), eb(10), eb(11), 00673 eb(12), eb(13), eb(14), eb(15)); 00674 00675 esp += 16; 00676 remaining_len -= 16; 00677 break; 00678 00679 case 3: /* MAC address. */ 00680 00681 if (remaining_len < 6) 00682 goto dump_snmpEngineID_violation; 00683 00684 s += sprintf(s, "%02X:%02X:%02X:%02X:%02X:%02X", 00685 eb(0), eb(1), eb(2), eb(3), eb(4), eb(5)); 00686 00687 esp += 6; 00688 remaining_len -= 6; 00689 break; 00690 00691 case 4: /* Text. */ 00692 00693 /* 00694 * Doesn't exist on all (many) architectures 00695 */ 00696 /* 00697 * s += snprintf(s, remaining_len+3, "\"%s\"", esp); 00698 */ 00699 s += sprintf(s, "\"%s\"", esp); 00700 goto dump_snmpEngineID_quit; 00701 break; 00702 /*NOTREACHED*/ case 5: /* Octets. */ 00703 00704 snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)), 00705 esp, remaining_len); 00706 s = strchr(buf, '\0'); 00707 s -= 1; 00708 goto dump_snmpEngineID_quit; 00709 break; 00710 /*NOTREACHED*/ dump_snmpEngineID_violation: 00711 case 0: /* Violation of RESERVED, 00712 * * -OR- of expected length. 00713 */ 00714 gotviolation = 1; 00715 s += sprintf(s, "!!! "); 00716 00717 default: /* Unknown encoding. */ 00718 00719 if (!gotviolation) { 00720 s += sprintf(s, "??? "); 00721 } 00722 snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)), 00723 esp, remaining_len); 00724 s = strchr(buf, '\0'); 00725 s -= 1; 00726 00727 goto dump_snmpEngineID_quit; 00728 00729 } /* endswitch */ 00730 00731 00732 00733 /* 00734 * Cases 1-3 (IP and MAC addresses) should not have trailing 00735 * octets, but perhaps they do. Throw them in too. XXX 00736 */ 00737 if (remaining_len > 0) { 00738 s += sprintf(s, " (??? "); 00739 00740 snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)), 00741 esp, remaining_len); 00742 s = strchr(buf, '\0'); 00743 s -= 1; 00744 00745 s += sprintf(s, ")"); 00746 } 00747 00748 00749 00750 dump_snmpEngineID_quit: 00751 if (s) { 00752 slen = s - buf + 1; 00753 s = calloc(1, slen); 00754 memcpy(s, buf, (slen) - 1); 00755 } 00756 00757 memset(buf, 0, SNMP_MAXBUF); /* XXX -- Overkill? XXX: Yes! */ 00758 00759 return s; 00760 00761 #undef eb 00762 } /* end dump_snmpEngineID() */ 00763 #endif /* NETSNMP_ENABLE_TESTING_CODE */ 00764 00765 00770 marker_t 00771 atime_newMarker(void) 00772 { 00773 marker_t pm = (marker_t) calloc(1, sizeof(struct timeval)); 00774 gettimeofday((struct timeval *) pm, 0); 00775 return pm; 00776 } 00777 00781 void 00782 atime_setMarker(marker_t pm) 00783 { 00784 if (!pm) 00785 return; 00786 00787 gettimeofday((struct timeval *) pm, 0); 00788 } 00789 00790 00794 long 00795 atime_diff(marker_t first, marker_t second) 00796 { 00797 struct timeval *tv1, *tv2, diff; 00798 00799 tv1 = (struct timeval *) first; 00800 tv2 = (struct timeval *) second; 00801 00802 diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1; 00803 diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000; 00804 00805 return (diff.tv_sec * 1000 + diff.tv_usec / 1000); 00806 } 00807 00811 u_long 00812 uatime_diff(marker_t first, marker_t second) 00813 { 00814 struct timeval *tv1, *tv2, diff; 00815 00816 tv1 = (struct timeval *) first; 00817 tv2 = (struct timeval *) second; 00818 00819 diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1; 00820 diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000; 00821 00822 return (((u_long) diff.tv_sec) * 1000 + diff.tv_usec / 1000); 00823 } 00824 00829 u_long 00830 uatime_hdiff(marker_t first, marker_t second) 00831 { 00832 struct timeval *tv1, *tv2, diff; 00833 u_long res; 00834 00835 tv1 = (struct timeval *) first; 00836 tv2 = (struct timeval *) second; 00837 00838 diff.tv_sec = tv2->tv_sec - tv1->tv_sec - 1; 00839 diff.tv_usec = tv2->tv_usec - tv1->tv_usec + 1000000; 00840 00841 res = ((u_long) diff.tv_sec) * 100 + diff.tv_usec / 10000; 00842 return res; 00843 } 00844 00849 int 00850 atime_ready(marker_t pm, int deltaT) 00851 { 00852 marker_t now; 00853 long diff; 00854 if (!pm) 00855 return 0; 00856 00857 now = atime_newMarker(); 00858 00859 diff = atime_diff(pm, now); 00860 free(now); 00861 if (diff < deltaT) 00862 return 0; 00863 00864 return 1; 00865 } 00866 00871 int 00872 uatime_ready(marker_t pm, unsigned int deltaT) 00873 { 00874 marker_t now; 00875 u_long diff; 00876 if (!pm) 00877 return 0; 00878 00879 now = atime_newMarker(); 00880 00881 diff = uatime_diff(pm, now); 00882 free(now); 00883 if (diff < deltaT) 00884 return 0; 00885 00886 return 1; 00887 } 00888 00889 00890 /* 00891 * Time-related utility functions 00892 */ 00893 00897 int 00898 marker_tticks(marker_t pm) 00899 { 00900 int res; 00901 marker_t now = atime_newMarker(); 00902 00903 res = atime_diff(pm, now); 00904 free(now); 00905 return res / 10; /* atime_diff works in msec, not csec */ 00906 } 00907 00908 int 00909 timeval_tticks(struct timeval *tv) 00910 { 00911 return marker_tticks((marker_t) tv); 00912 } 00913 00926 char *netsnmp_getenv(const char *name) 00927 { 00928 #if !defined (WIN32) && !defined (cygwin) 00929 return (getenv(name)); 00930 #else 00931 char *temp = NULL; 00932 HKEY hKey; 00933 unsigned char * key_value = NULL; 00934 DWORD key_value_size = 0; 00935 DWORD key_value_type = 0; 00936 DWORD getenv_worked = 0; 00937 00938 DEBUGMSGTL(("read_config", "netsnmp_getenv called with name: %s\n",name)); 00939 00940 if (!(name)) 00941 return NULL; 00942 00943 /* Try environment variable first */ 00944 temp = getenv(name); 00945 if (temp) { 00946 getenv_worked = 1; 00947 DEBUGMSGTL(("read_config", "netsnmp_getenv will return from ENV: %s\n",temp)); 00948 } 00949 00950 /* Next try HKCU */ 00951 if (temp == NULL) 00952 { 00953 if (RegOpenKeyExA( 00954 HKEY_CURRENT_USER, 00955 "SOFTWARE\\Net-SNMP", 00956 0, 00957 KEY_QUERY_VALUE, 00958 &hKey) == ERROR_SUCCESS) { 00959 00960 if (RegQueryValueExA( 00961 hKey, 00962 name, 00963 NULL, 00964 &key_value_type, 00965 NULL, /* Just get the size */ 00966 &key_value_size) == ERROR_SUCCESS) { 00967 00968 if (key_value) 00969 SNMP_FREE(key_value); 00970 00971 /* Allocate memory needed +1 to allow RegQueryValueExA to NULL terminate the 00972 * string data in registry is missing one (which is unlikely). 00973 */ 00974 key_value = (char *) malloc((sizeof(char) * key_value_size)+sizeof(char)); 00975 00976 if (RegQueryValueExA( 00977 hKey, 00978 name, 00979 NULL, 00980 &key_value_type, 00981 key_value, 00982 &key_value_size) == ERROR_SUCCESS) { 00983 } 00984 temp = key_value; 00985 } 00986 RegCloseKey(hKey); 00987 if (temp) 00988 DEBUGMSGTL(("read_config", "netsnmp_getenv will return from HKCU: %s\n",temp)); 00989 } 00990 } 00991 00992 /* Next try HKLM */ 00993 if (temp == NULL) 00994 { 00995 if (RegOpenKeyExA( 00996 HKEY_LOCAL_MACHINE, 00997 "SOFTWARE\\Net-SNMP", 00998 0, 00999 KEY_QUERY_VALUE, 01000 &hKey) == ERROR_SUCCESS) { 01001 01002 if (RegQueryValueExA( 01003 hKey, 01004 name, 01005 NULL, 01006 &key_value_type, 01007 NULL, /* Just get the size */ 01008 &key_value_size) == ERROR_SUCCESS) { 01009 01010 if (key_value) 01011 SNMP_FREE(key_value); 01012 01013 /* Allocate memory needed +1 to allow RegQueryValueExA to NULL terminate the 01014 * string data in registry is missing one (which is unlikely). 01015 */ 01016 key_value = (char *) malloc((sizeof(char) * key_value_size)+sizeof(char)); 01017 01018 if (RegQueryValueExA( 01019 hKey, 01020 name, 01021 NULL, 01022 &key_value_type, 01023 key_value, 01024 &key_value_size) == ERROR_SUCCESS) { 01025 } 01026 temp = key_value; 01027 01028 } 01029 RegCloseKey(hKey); 01030 if (temp) 01031 DEBUGMSGTL(("read_config", "netsnmp_getenv will return from HKLM: %s\n",temp)); 01032 } 01033 } 01034 01035 if (temp && !getenv_worked) { 01036 setenv(name, temp, 1); 01037 SNMP_FREE(temp); 01038 } 01039 01040 DEBUGMSGTL(("read_config", "netsnmp_getenv returning: %s\n",getenv(name))); 01041 01042 return(getenv(name)); 01043 #endif 01044 } 01045 01046 /* 01047 * swap the order of an inet addr string 01048 */ 01049 int 01050 netsnmp_addrstr_hton(char *ptr, size_t len) 01051 { 01052 #ifndef WORDS_BIGENDIAN 01053 char tmp[8]; 01054 01055 if (8 == len) { 01056 tmp[0] = ptr[6]; 01057 tmp[1] = ptr[7]; 01058 tmp[2] = ptr[4]; 01059 tmp[3] = ptr[5]; 01060 tmp[4] = ptr[2]; 01061 tmp[5] = ptr[3]; 01062 tmp[6] = ptr[0]; 01063 tmp[7] = ptr[1]; 01064 memcpy (ptr, &tmp, 8); 01065 } 01066 else if (32 == len) { 01067 netsnmp_addrstr_hton(ptr , 8); 01068 netsnmp_addrstr_hton(ptr+8 , 8); 01069 netsnmp_addrstr_hton(ptr+16, 8); 01070 netsnmp_addrstr_hton(ptr+24, 8); 01071 } 01072 else 01073 return -1; 01074 #endif 01075 01076 return 0; 01077 }