00001 /* 00002 * mib.c 00003 * 00004 * $Id$ 00005 * 00006 * Update: 1998-07-17 <jhy@gsu.edu> 00007 * Added print_oid_report* functions. 00008 * 00009 */ 00010 /* Portions of this file are subject to the following copyrights. See 00011 * the Net-SNMP's COPYING file for more details and other copyrights 00012 * that may apply: 00013 */ 00014 /********************************************************************** 00015 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University 00016 00017 All Rights Reserved 00018 00019 Permission to use, copy, modify, and distribute this software and its 00020 documentation for any purpose and without fee is hereby granted, 00021 provided that the above copyright notice appear in all copies and that 00022 both that copyright notice and this permission notice appear in 00023 supporting documentation, and that the name of CMU not be 00024 used in advertising or publicity pertaining to distribution of the 00025 software without specific, written prior permission. 00026 00027 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 00028 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 00029 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 00030 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 00031 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 00032 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 00033 SOFTWARE. 00034 ******************************************************************/ 00035 /* 00036 * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. 00037 * Use is subject to license terms specified in the COPYING file 00038 * distributed with the Net-SNMP package. 00039 */ 00040 #include <net-snmp/net-snmp-config.h> 00041 00042 #include <stdio.h> 00043 #include <ctype.h> 00044 #include <sys/types.h> 00045 00046 #if HAVE_DIRENT_H 00047 # include <dirent.h> 00048 # define NAMLEN(dirent) strlen((dirent)->d_name) 00049 #else 00050 # define dirent direct 00051 # define NAMLEN(dirent) (dirent)->d_namlen 00052 # if HAVE_SYS_NDIR_H 00053 # include <sys/ndir.h> 00054 # endif 00055 # if HAVE_SYS_DIR_H 00056 # include <sys/dir.h> 00057 # endif 00058 # if HAVE_NDIR_H 00059 # include <ndir.h> 00060 # endif 00061 #endif 00062 00063 #if HAVE_NETINET_IN_H 00064 #include <netinet/in.h> 00065 #endif 00066 #if TIME_WITH_SYS_TIME 00067 # ifdef WIN32 00068 # include <sys/timeb.h> 00069 # else 00070 # include <sys/time.h> 00071 # endif 00072 # include <time.h> 00073 #else 00074 # if HAVE_SYS_TIME_H 00075 # include <sys/time.h> 00076 # else 00077 # include <time.h> 00078 # endif 00079 #endif 00080 #if HAVE_STRING_H 00081 #include <string.h> 00082 #else 00083 #include <strings.h> 00084 #endif 00085 #if HAVE_STDLIB_H 00086 #include <stdlib.h> 00087 #endif 00088 #if HAVE_SYS_SELECT_H 00089 #include <sys/select.h> 00090 #endif 00091 00092 #if HAVE_WINSOCK_H 00093 #include <winsock.h> 00094 #endif 00095 00096 #if HAVE_DMALLOC_H 00097 #include <dmalloc.h> 00098 #endif 00099 00100 #include <net-snmp/types.h> 00101 #include <net-snmp/output_api.h> 00102 #include <net-snmp/config_api.h> 00103 #include <net-snmp/utilities.h> 00104 00105 #include <net-snmp/library/asn1.h> 00106 #include <net-snmp/library/snmp_api.h> 00107 #include <net-snmp/library/mib.h> 00108 #include <net-snmp/library/parse.h> 00109 #include <net-snmp/library/int64.h> 00110 #include <net-snmp/library/snmp_client.h> 00111 00118 static char *uptimeString(u_long, char *, size_t); 00119 00120 static struct tree *_get_realloc_symbol(const oid * objid, size_t objidlen, 00121 struct tree *subtree, 00122 u_char ** buf, size_t * buf_len, 00123 size_t * out_len, 00124 int allow_realloc, 00125 int *buf_overflow, 00126 struct index_list *in_dices, 00127 size_t * end_of_known); 00128 00129 static int print_tree_node(u_char ** buf, size_t * buf_len, 00130 size_t * out_len, int allow_realloc, 00131 struct tree *tp, int width); 00132 static void handle_mibdirs_conf(const char *token, char *line); 00133 static void handle_mibs_conf(const char *token, char *line); 00134 static void handle_mibfile_conf(const char *token, char *line); 00135 00136 static void _oid_finish_printing(const oid * objid, size_t objidlen, 00137 u_char ** buf, size_t * buf_len, 00138 size_t * out_len, 00139 int allow_realloc, int *buf_overflow); 00140 00141 /* 00142 * helper functions for get_module_node 00143 */ 00144 static int node_to_oid(struct tree *, oid *, size_t *); 00145 #ifndef NETSNMP_DISABLE_MIB_LOADING 00146 static int _add_strings_to_oid(struct tree *, char *, 00147 oid *, size_t *, size_t); 00148 #else 00149 static int _add_strings_to_oid(void *, char *, 00150 oid *, size_t *, size_t); 00151 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 00152 00153 #ifndef NETSNMP_DISABLE_MIB_LOADING 00154 extern struct tree *tree_head; 00155 static struct tree *tree_top; 00156 00157 struct tree *Mib; /* Backwards compatibility */ 00158 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 00159 00160 oid RFC1213_MIB[] = { 1, 3, 6, 1, 2, 1 }; 00161 static char Standard_Prefix[] = ".1.3.6.1.2.1"; 00162 00163 /* 00164 * Set default here as some uses of read_objid require valid pointer. 00165 */ 00166 static char *Prefix = &Standard_Prefix[0]; 00167 typedef struct _PrefixList { 00168 const char *str; 00169 int len; 00170 } *PrefixListPtr, PrefixList; 00171 00172 /* 00173 * Here are the prefix strings. 00174 * Note that the first one finds the value of Prefix or Standard_Prefix. 00175 * Any of these MAY start with period; all will NOT end with period. 00176 * Period is added where needed. See use of Prefix in this module. 00177 */ 00178 PrefixList mib_prefixes[] = { 00179 {&Standard_Prefix[0]}, /* placeholder for Prefix data */ 00180 {".iso.org.dod.internet.mgmt.mib-2"}, 00181 {".iso.org.dod.internet.experimental"}, 00182 {".iso.org.dod.internet.private"}, 00183 {".iso.org.dod.internet.snmpParties"}, 00184 {".iso.org.dod.internet.snmpSecrets"}, 00185 {NULL, 0} /* end of list */ 00186 }; 00187 00188 enum inet_address_type { 00189 IPV4 = 1, 00190 IPV6 = 2, 00191 IPV4Z = 3, 00192 IPV6Z = 4, 00193 DNS = 16 00194 }; 00195 00196 00207 static char * 00208 uptimeString(u_long timeticks, char *buf, size_t buflen) 00209 { 00210 int centisecs, seconds, minutes, hours, days; 00211 00212 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS)) { 00213 snprintf(buf, buflen, "%lu", timeticks); 00214 return buf; 00215 } 00216 00217 00218 centisecs = timeticks % 100; 00219 timeticks /= 100; 00220 days = timeticks / (60 * 60 * 24); 00221 timeticks %= (60 * 60 * 24); 00222 00223 hours = timeticks / (60 * 60); 00224 timeticks %= (60 * 60); 00225 00226 minutes = timeticks / 60; 00227 seconds = timeticks % 60; 00228 00229 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) 00230 snprintf(buf, buflen, "%d:%d:%02d:%02d.%02d", 00231 days, hours, minutes, seconds, centisecs); 00232 else { 00233 if (days == 0) { 00234 snprintf(buf, buflen, "%d:%02d:%02d.%02d", 00235 hours, minutes, seconds, centisecs); 00236 } else if (days == 1) { 00237 snprintf(buf, buflen, "%d day, %d:%02d:%02d.%02d", 00238 days, hours, minutes, seconds, centisecs); 00239 } else { 00240 snprintf(buf, buflen, "%d days, %d:%02d:%02d.%02d", 00241 days, hours, minutes, seconds, centisecs); 00242 } 00243 } 00244 return buf; 00245 } 00246 00247 00248 00257 static void 00258 sprint_char(char *buf, const u_char ch) 00259 { 00260 if (isprint(ch) || isspace(ch)) { 00261 sprintf(buf, "%c", (int) ch); 00262 } else { 00263 sprintf(buf, "."); 00264 } 00265 } 00266 00267 00268 00288 int 00289 _sprint_hexstring_line(u_char ** buf, size_t * buf_len, size_t * out_len, 00290 int allow_realloc, const u_char * cp, size_t line_len) 00291 { 00292 const u_char *tp; 00293 const u_char *cp2 = cp; 00294 size_t lenleft = line_len; 00295 00296 /* 00297 * Make sure there's enough room for the hex output.... 00298 */ 00299 while ((*out_len + line_len*3+1) >= *buf_len) { 00300 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 00301 return 0; 00302 } 00303 } 00304 00305 /* 00306 * .... and display the hex values themselves.... 00307 */ 00308 for (; lenleft >= 8; lenleft-=8) { 00309 sprintf((char *) (*buf + *out_len), 00310 "%02X %02X %02X %02X %02X %02X %02X %02X ", cp[0], cp[1], 00311 cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); 00312 *out_len += strlen((char *) (*buf + *out_len)); 00313 cp += 8; 00314 } 00315 for (; lenleft > 0; lenleft--) { 00316 sprintf((char *) (*buf + *out_len), "%02X ", *cp++); 00317 *out_len += strlen((char *) (*buf + *out_len)); 00318 } 00319 00320 /* 00321 * .... plus (optionally) do the same for the ASCII equivalent. 00322 */ 00323 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_HEX_TEXT)) { 00324 while ((*out_len + line_len+5) >= *buf_len) { 00325 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 00326 return 0; 00327 } 00328 } 00329 sprintf((char *) (*buf + *out_len), " ["); 00330 *out_len += strlen((char *) (*buf + *out_len)); 00331 for (tp = cp2; tp < cp; tp++) { 00332 sprint_char((char *) (*buf + *out_len), *tp); 00333 (*out_len)++; 00334 } 00335 sprintf((char *) (*buf + *out_len), "]"); 00336 *out_len += strlen((char *) (*buf + *out_len)); 00337 } 00338 return 1; 00339 } 00340 00341 int 00342 sprint_realloc_hexstring(u_char ** buf, size_t * buf_len, size_t * out_len, 00343 int allow_realloc, const u_char * cp, size_t len) 00344 { 00345 int line_len = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 00346 NETSNMP_DS_LIB_HEX_OUTPUT_LENGTH); 00347 if (!line_len) 00348 line_len=len; 00349 00350 for (; (int)len > line_len; len -= line_len) { 00351 if(!_sprint_hexstring_line(buf, buf_len, out_len, allow_realloc, cp, line_len)) 00352 return 0; 00353 *(*buf + (*out_len)++) = '\n'; 00354 *(*buf + *out_len) = 0; 00355 cp += line_len; 00356 } 00357 if(!_sprint_hexstring_line(buf, buf_len, out_len, allow_realloc, cp, len)) 00358 return 0; 00359 *(*buf + *out_len) = 0; 00360 return 1; 00361 } 00362 00363 00364 00384 int 00385 sprint_realloc_asciistring(u_char ** buf, size_t * buf_len, 00386 size_t * out_len, int allow_realloc, 00387 const u_char * cp, size_t len) 00388 { 00389 int i; 00390 00391 for (i = 0; i < (int) len; i++) { 00392 if (isprint(*cp) || isspace(*cp)) { 00393 if (*cp == '\\' || *cp == '"') { 00394 if ((*out_len >= *buf_len) && 00395 !(allow_realloc && snmp_realloc(buf, buf_len))) { 00396 return 0; 00397 } 00398 *(*buf + (*out_len)++) = '\\'; 00399 } 00400 if ((*out_len >= *buf_len) && 00401 !(allow_realloc && snmp_realloc(buf, buf_len))) { 00402 return 0; 00403 } 00404 *(*buf + (*out_len)++) = *cp++; 00405 } else { 00406 if ((*out_len >= *buf_len) && 00407 !(allow_realloc && snmp_realloc(buf, buf_len))) { 00408 return 0; 00409 } 00410 *(*buf + (*out_len)++) = '.'; 00411 cp++; 00412 } 00413 } 00414 if ((*out_len >= *buf_len) && 00415 !(allow_realloc && snmp_realloc(buf, buf_len))) { 00416 return 0; 00417 } 00418 *(*buf + *out_len) = '\0'; 00419 return 1; 00420 } 00421 00444 int 00445 sprint_realloc_octet_string(u_char ** buf, size_t * buf_len, 00446 size_t * out_len, int allow_realloc, 00447 const netsnmp_variable_list * var, 00448 const struct enum_list *enums, const char *hint, 00449 const char *units) 00450 { 00451 size_t saved_out_len = *out_len; 00452 const char *saved_hint = hint; 00453 int hex = 0, x = 0; 00454 u_char *cp; 00455 int output_format, len_needed; 00456 00457 if ((var->type != ASN_OCTET_STR) && 00458 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 00459 const char str[] = "Wrong Type (should be OCTET STRING): "; 00460 if (snmp_cstrcat 00461 (buf, buf_len, out_len, allow_realloc, str)) { 00462 return sprint_realloc_by_type(buf, buf_len, out_len, 00463 allow_realloc, var, NULL, NULL, 00464 NULL); 00465 } else { 00466 return 0; 00467 } 00468 } 00469 00470 00471 if (hint) { 00472 int repeat, width = 1; 00473 long value; 00474 char code = 'd', separ = 0, term = 0, ch, intbuf[16]; 00475 u_char *ecp; 00476 00477 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 00478 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "STRING: ")) { 00479 return 0; 00480 } 00481 } 00482 cp = var->val.string; 00483 ecp = cp + var->val_len; 00484 00485 while (cp < ecp) { 00486 repeat = 1; 00487 if (*hint) { 00488 if (*hint == '*') { 00489 repeat = *cp++; 00490 hint++; 00491 } 00492 width = 0; 00493 while ('0' <= *hint && *hint <= '9') 00494 width = (width * 10) + (*hint++ - '0'); 00495 code = *hint++; 00496 if ((ch = *hint) && ch != '*' && (ch < '0' || ch > '9') 00497 && (width != 0 00498 || (ch != 'x' && ch != 'd' && ch != 'o'))) 00499 separ = *hint++; 00500 else 00501 separ = 0; 00502 if ((ch = *hint) && ch != '*' && (ch < '0' || ch > '9') 00503 && (width != 0 00504 || (ch != 'x' && ch != 'd' && ch != 'o'))) 00505 term = *hint++; 00506 else 00507 term = 0; 00508 if (width == 0) /* Handle malformed hint strings */ 00509 width = 1; 00510 } 00511 00512 while (repeat && cp < ecp) { 00513 value = 0; 00514 if (code != 'a' && code != 't') { 00515 for (x = 0; x < width; x++) { 00516 value = value * 256 + *cp++; 00517 } 00518 } 00519 switch (code) { 00520 case 'x': 00521 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 00522 NETSNMP_DS_LIB_2DIGIT_HEX_OUTPUT) 00523 && value < 16) { 00524 sprintf(intbuf, "0%lx", value); 00525 } else { 00526 sprintf(intbuf, "%lx", value); 00527 } 00528 if (!snmp_cstrcat 00529 (buf, buf_len, out_len, allow_realloc, intbuf)) { 00530 return 0; 00531 } 00532 break; 00533 case 'd': 00534 sprintf(intbuf, "%ld", value); 00535 if (!snmp_cstrcat 00536 (buf, buf_len, out_len, allow_realloc, intbuf)) { 00537 return 0; 00538 } 00539 break; 00540 case 'o': 00541 sprintf(intbuf, "%lo", value); 00542 if (!snmp_cstrcat 00543 (buf, buf_len, out_len, allow_realloc, intbuf)) { 00544 return 0; 00545 } 00546 break; 00547 case 't': /* new in rfc 3411 */ 00548 case 'a': 00549 /* A string hint gives the max size - we may not need this much */ 00550 len_needed = SNMP_MIN( width, ecp-cp ); 00551 while ((*out_len + len_needed + 1) >= *buf_len) { 00552 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 00553 return 0; 00554 } 00555 } 00556 for (x = 0; x < width && cp < ecp; x++) { 00557 *(*buf + *out_len) = *cp++; 00558 (*out_len)++; 00559 } 00560 *(*buf + *out_len) = '\0'; 00561 break; 00562 default: 00563 *out_len = saved_out_len; 00564 if (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 00565 "(Bad hint ignored: ") 00566 && snmp_cstrcat(buf, buf_len, out_len, 00567 allow_realloc, saved_hint) 00568 && snmp_cstrcat(buf, buf_len, out_len, 00569 allow_realloc, ") ")) { 00570 return sprint_realloc_octet_string(buf, buf_len, 00571 out_len, 00572 allow_realloc, 00573 var, enums, 00574 NULL, NULL); 00575 } else { 00576 return 0; 00577 } 00578 } 00579 00580 if (cp < ecp && separ) { 00581 while ((*out_len + 1) >= *buf_len) { 00582 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 00583 return 0; 00584 } 00585 } 00586 *(*buf + *out_len) = separ; 00587 (*out_len)++; 00588 *(*buf + *out_len) = '\0'; 00589 } 00590 repeat--; 00591 } 00592 00593 if (term && cp < ecp) { 00594 while ((*out_len + 1) >= *buf_len) { 00595 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 00596 return 0; 00597 } 00598 } 00599 *(*buf + *out_len) = term; 00600 (*out_len)++; 00601 *(*buf + *out_len) = '\0'; 00602 } 00603 } 00604 00605 if (units) { 00606 return (snmp_cstrcat 00607 (buf, buf_len, out_len, allow_realloc, " ") 00608 && snmp_cstrcat(buf, buf_len, out_len, allow_realloc, units)); 00609 } 00610 if ((*out_len >= *buf_len) && 00611 !(allow_realloc && snmp_realloc(buf, buf_len))) { 00612 return 0; 00613 } 00614 *(*buf + *out_len) = '\0'; 00615 00616 return 1; 00617 } 00618 00619 output_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT); 00620 if (0 == output_format) { 00621 output_format = NETSNMP_STRING_OUTPUT_GUESS; 00622 } 00623 switch (output_format) { 00624 case NETSNMP_STRING_OUTPUT_GUESS: 00625 hex = 0; 00626 for (cp = var->val.string, x = 0; x < (int) var->val_len; x++, cp++) { 00627 if (!isprint(*cp) && !isspace(*cp)) { 00628 hex = 1; 00629 } 00630 } 00631 break; 00632 00633 case NETSNMP_STRING_OUTPUT_ASCII: 00634 hex = 0; 00635 break; 00636 00637 case NETSNMP_STRING_OUTPUT_HEX: 00638 hex = 1; 00639 break; 00640 } 00641 00642 if (var->val_len == 0) { 00643 return snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\"\""); 00644 } 00645 00646 if (hex) { 00647 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 00648 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\"")) { 00649 return 0; 00650 } 00651 } else { 00652 if (!snmp_cstrcat 00653 (buf, buf_len, out_len, allow_realloc, "Hex-STRING: ")) { 00654 return 0; 00655 } 00656 } 00657 00658 if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc, 00659 var->val.string, var->val_len)) { 00660 return 0; 00661 } 00662 00663 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 00664 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\"")) { 00665 return 0; 00666 } 00667 } 00668 } else { 00669 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 00670 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 00671 "STRING: ")) { 00672 return 0; 00673 } 00674 } 00675 if (!snmp_cstrcat 00676 (buf, buf_len, out_len, allow_realloc, "\"")) { 00677 return 0; 00678 } 00679 if (!sprint_realloc_asciistring 00680 (buf, buf_len, out_len, allow_realloc, var->val.string, 00681 var->val_len)) { 00682 return 0; 00683 } 00684 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\"")) { 00685 return 0; 00686 } 00687 } 00688 00689 if (units) { 00690 return (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " ") 00691 && snmp_cstrcat(buf, buf_len, out_len, allow_realloc, units)); 00692 } 00693 return 1; 00694 } 00695 00696 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00697 00720 int 00721 sprint_realloc_float(u_char ** buf, size_t * buf_len, 00722 size_t * out_len, int allow_realloc, 00723 const netsnmp_variable_list * var, 00724 const struct enum_list *enums, 00725 const char *hint, const char *units) 00726 { 00727 if ((var->type != ASN_OPAQUE_FLOAT) && 00728 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 00729 if (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 00730 "Wrong Type (should be Float): ")) { 00731 return sprint_realloc_by_type(buf, buf_len, out_len, 00732 allow_realloc, var, NULL, NULL, 00733 NULL); 00734 } else { 00735 return 0; 00736 } 00737 } 00738 00739 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 00740 if (!snmp_cstrcat 00741 (buf, buf_len, out_len, allow_realloc, "Opaque: Float: ")) { 00742 return 0; 00743 } 00744 } 00745 00746 00747 /* 00748 * How much space needed for max. length float? 128 is overkill. 00749 */ 00750 00751 while ((*out_len + 128 + 1) >= *buf_len) { 00752 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 00753 return 0; 00754 } 00755 } 00756 00757 sprintf((char *) (*buf + *out_len), "%f", *var->val.floatVal); 00758 *out_len += strlen((char *) (*buf + *out_len)); 00759 00760 if (units) { 00761 return (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " ") 00762 && snmp_cstrcat(buf, buf_len, out_len, allow_realloc, units)); 00763 } 00764 return 1; 00765 } 00766 00767 00790 int 00791 sprint_realloc_double(u_char ** buf, size_t * buf_len, 00792 size_t * out_len, int allow_realloc, 00793 const netsnmp_variable_list * var, 00794 const struct enum_list *enums, 00795 const char *hint, const char *units) 00796 { 00797 if ((var->type != ASN_OPAQUE_DOUBLE) && 00798 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 00799 if (snmp_cstrcat 00800 (buf, buf_len, out_len, allow_realloc, 00801 "Wrong Type (should be Double): ")) { 00802 return sprint_realloc_by_type(buf, buf_len, out_len, 00803 allow_realloc, var, NULL, NULL, 00804 NULL); 00805 } else { 00806 return 0; 00807 } 00808 } 00809 00810 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 00811 if (!snmp_cstrcat 00812 (buf, buf_len, out_len, allow_realloc, "Opaque: Float: ")) { 00813 return 0; 00814 } 00815 } 00816 00817 /* 00818 * How much space needed for max. length double? 128 is overkill. 00819 */ 00820 00821 while ((*out_len + 128 + 1) >= *buf_len) { 00822 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 00823 return 0; 00824 } 00825 } 00826 00827 sprintf((char *) (*buf + *out_len), "%f", *var->val.doubleVal); 00828 *out_len += strlen((char *) (*buf + *out_len)); 00829 00830 if (units) { 00831 return (snmp_cstrcat 00832 (buf, buf_len, out_len, allow_realloc, " ") 00833 && snmp_cstrcat(buf, buf_len, out_len, allow_realloc, units)); 00834 } 00835 return 1; 00836 } 00837 00838 #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ 00839 00840 00863 int 00864 sprint_realloc_counter64(u_char ** buf, size_t * buf_len, size_t * out_len, 00865 int allow_realloc, 00866 const netsnmp_variable_list * var, 00867 const struct enum_list *enums, 00868 const char *hint, const char *units) 00869 { 00870 char a64buf[I64CHARSZ + 1]; 00871 00872 if ((var->type != ASN_COUNTER64 00873 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00874 && var->type != ASN_OPAQUE_COUNTER64 00875 && var->type != ASN_OPAQUE_I64 && var->type != ASN_OPAQUE_U64 00876 #endif 00877 ) && (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 00878 if (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 00879 "Wrong Type (should be Counter64): ")) { 00880 return sprint_realloc_by_type(buf, buf_len, out_len, 00881 allow_realloc, var, NULL, NULL, 00882 NULL); 00883 } else { 00884 return 0; 00885 } 00886 } 00887 00888 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 00889 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00890 if (var->type != ASN_COUNTER64) { 00891 if (!snmp_cstrcat 00892 (buf, buf_len, out_len, allow_realloc, "Opaque: ")) { 00893 return 0; 00894 } 00895 } 00896 #endif 00897 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00898 switch (var->type) { 00899 case ASN_OPAQUE_U64: 00900 if (!snmp_cstrcat 00901 (buf, buf_len, out_len, allow_realloc, "UInt64: ")) { 00902 return 0; 00903 } 00904 break; 00905 case ASN_OPAQUE_I64: 00906 if (!snmp_cstrcat 00907 (buf, buf_len, out_len, allow_realloc, "Int64: ")) { 00908 return 0; 00909 } 00910 break; 00911 case ASN_COUNTER64: 00912 case ASN_OPAQUE_COUNTER64: 00913 #endif 00914 if (!snmp_cstrcat 00915 (buf, buf_len, out_len, allow_realloc, "Counter64: ")) { 00916 return 0; 00917 } 00918 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00919 } 00920 #endif 00921 } 00922 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00923 if (var->type == ASN_OPAQUE_I64) { 00924 printI64(a64buf, var->val.counter64); 00925 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, a64buf)) { 00926 return 0; 00927 } 00928 } else { 00929 #endif 00930 printU64(a64buf, var->val.counter64); 00931 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, a64buf)) { 00932 return 0; 00933 } 00934 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00935 } 00936 #endif 00937 00938 if (units) { 00939 return (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " ") 00940 && snmp_cstrcat(buf, buf_len, out_len, allow_realloc, units)); 00941 } 00942 return 1; 00943 } 00944 00945 00966 int 00967 sprint_realloc_opaque(u_char ** buf, size_t * buf_len, 00968 size_t * out_len, int allow_realloc, 00969 const netsnmp_variable_list * var, 00970 const struct enum_list *enums, 00971 const char *hint, const char *units) 00972 { 00973 if ((var->type != ASN_OPAQUE 00974 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00975 && var->type != ASN_OPAQUE_COUNTER64 00976 && var->type != ASN_OPAQUE_U64 00977 && var->type != ASN_OPAQUE_I64 00978 && var->type != ASN_OPAQUE_FLOAT && var->type != ASN_OPAQUE_DOUBLE 00979 #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ 00980 ) && (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 00981 if (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 00982 "Wrong Type (should be Opaque): ")) { 00983 return sprint_realloc_by_type(buf, buf_len, out_len, 00984 allow_realloc, var, NULL, NULL, 00985 NULL); 00986 } else { 00987 return 0; 00988 } 00989 } 00990 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00991 switch (var->type) { 00992 case ASN_OPAQUE_COUNTER64: 00993 case ASN_OPAQUE_U64: 00994 case ASN_OPAQUE_I64: 00995 return sprint_realloc_counter64(buf, buf_len, out_len, 00996 allow_realloc, var, enums, hint, 00997 units); 00998 break; 00999 01000 case ASN_OPAQUE_FLOAT: 01001 return sprint_realloc_float(buf, buf_len, out_len, allow_realloc, 01002 var, enums, hint, units); 01003 break; 01004 01005 case ASN_OPAQUE_DOUBLE: 01006 return sprint_realloc_double(buf, buf_len, out_len, allow_realloc, 01007 var, enums, hint, units); 01008 break; 01009 01010 case ASN_OPAQUE: 01011 #endif 01012 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01013 u_char str[] = "OPAQUE: "; 01014 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01015 return 0; 01016 } 01017 } 01018 if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc, 01019 var->val.string, var->val_len)) { 01020 return 0; 01021 } 01022 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 01023 } 01024 #endif 01025 if (units) { 01026 return (snmp_strcat 01027 (buf, buf_len, out_len, allow_realloc, 01028 (const u_char *) " ") 01029 && snmp_strcat(buf, buf_len, out_len, allow_realloc, 01030 (const u_char *) units)); 01031 } 01032 return 1; 01033 } 01034 01035 01056 int 01057 sprint_realloc_object_identifier(u_char ** buf, size_t * buf_len, 01058 size_t * out_len, int allow_realloc, 01059 const netsnmp_variable_list * var, 01060 const struct enum_list *enums, 01061 const char *hint, const char *units) 01062 { 01063 int buf_overflow = 0; 01064 01065 if ((var->type != ASN_OBJECT_ID) && 01066 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01067 u_char str[] = 01068 "Wrong Type (should be OBJECT IDENTIFIER): "; 01069 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01070 return sprint_realloc_by_type(buf, buf_len, out_len, 01071 allow_realloc, var, NULL, NULL, 01072 NULL); 01073 } else { 01074 return 0; 01075 } 01076 } 01077 01078 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01079 u_char str[] = "OID: "; 01080 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01081 return 0; 01082 } 01083 } 01084 01085 netsnmp_sprint_realloc_objid_tree(buf, buf_len, out_len, allow_realloc, 01086 &buf_overflow, 01087 (oid *) (var->val.objid), 01088 var->val_len / sizeof(oid)); 01089 01090 if (buf_overflow) { 01091 return 0; 01092 } 01093 01094 if (units) { 01095 return (snmp_strcat 01096 (buf, buf_len, out_len, allow_realloc, 01097 (const u_char *) " ") 01098 && snmp_strcat(buf, buf_len, out_len, allow_realloc, 01099 (const u_char *) units)); 01100 } 01101 return 1; 01102 } 01103 01104 01105 01126 int 01127 sprint_realloc_timeticks(u_char ** buf, size_t * buf_len, size_t * out_len, 01128 int allow_realloc, 01129 const netsnmp_variable_list * var, 01130 const struct enum_list *enums, 01131 const char *hint, const char *units) 01132 { 01133 char timebuf[40]; 01134 01135 if ((var->type != ASN_TIMETICKS) && 01136 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01137 u_char str[] = "Wrong Type (should be Timeticks): "; 01138 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01139 return sprint_realloc_by_type(buf, buf_len, out_len, 01140 allow_realloc, var, NULL, NULL, 01141 NULL); 01142 } else { 01143 return 0; 01144 } 01145 } 01146 01147 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS)) { 01148 char str[16]; 01149 sprintf(str, "%lu", *(u_long *) var->val.integer); 01150 if (!snmp_strcat 01151 (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) { 01152 return 0; 01153 } 01154 return 1; 01155 } 01156 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01157 char str[32]; 01158 sprintf(str, "Timeticks: (%lu) ", *(u_long *) var->val.integer); 01159 if (!snmp_strcat 01160 (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) { 01161 return 0; 01162 } 01163 } 01164 uptimeString(*(u_long *) (var->val.integer), timebuf, sizeof(timebuf)); 01165 if (!snmp_strcat 01166 (buf, buf_len, out_len, allow_realloc, (const u_char *) timebuf)) { 01167 return 0; 01168 } 01169 if (units) { 01170 return (snmp_strcat 01171 (buf, buf_len, out_len, allow_realloc, 01172 (const u_char *) " ") 01173 && snmp_strcat(buf, buf_len, out_len, allow_realloc, 01174 (const u_char *) units)); 01175 } 01176 return 1; 01177 } 01178 01179 01200 int 01201 sprint_realloc_hinted_integer(u_char ** buf, size_t * buf_len, 01202 size_t * out_len, int allow_realloc, 01203 long val, const char decimaltype, 01204 const char *hint, const char *units) 01205 { 01206 char fmt[10] = "%l@", tmp[256]; 01207 int shift, len; 01208 01209 if (hint[1] == '-') { 01210 shift = atoi(hint + 2); 01211 } else { 01212 shift = 0; 01213 } 01214 01215 if (hint[0] == 'd') { 01216 /* 01217 * We might *actually* want a 'u' here. 01218 */ 01219 fmt[2] = decimaltype; 01220 } else { 01221 /* 01222 * DISPLAY-HINT character is 'b', 'o', or 'x'. 01223 */ 01224 fmt[2] = hint[0]; 01225 } 01226 01227 sprintf(tmp, fmt, val); 01228 if (shift != 0) { 01229 len = strlen(tmp); 01230 if (shift <= len) { 01231 tmp[len + 1] = 0; 01232 while (shift--) { 01233 tmp[len] = tmp[len - 1]; 01234 len--; 01235 } 01236 tmp[len] = '.'; 01237 } else { 01238 tmp[shift + 1] = 0; 01239 while (shift) { 01240 if (len-- > 0) { 01241 tmp[shift] = tmp[len]; 01242 } else { 01243 tmp[shift] = '0'; 01244 } 01245 shift--; 01246 } 01247 tmp[0] = '.'; 01248 } 01249 } 01250 return snmp_strcat(buf, buf_len, out_len, allow_realloc, (u_char *)tmp); 01251 } 01252 01253 01274 int 01275 sprint_realloc_integer(u_char ** buf, size_t * buf_len, size_t * out_len, 01276 int allow_realloc, 01277 const netsnmp_variable_list * var, 01278 const struct enum_list *enums, 01279 const char *hint, const char *units) 01280 { 01281 char *enum_string = NULL; 01282 01283 if ((var->type != ASN_INTEGER) && 01284 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01285 u_char str[] = "Wrong Type (should be INTEGER): "; 01286 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01287 return sprint_realloc_by_type(buf, buf_len, out_len, 01288 allow_realloc, var, NULL, NULL, 01289 NULL); 01290 } else { 01291 return 0; 01292 } 01293 } 01294 for (; enums; enums = enums->next) { 01295 if (enums->value == *var->val.integer) { 01296 enum_string = enums->label; 01297 break; 01298 } 01299 } 01300 01301 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01302 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, 01303 (const u_char *) "INTEGER: ")) { 01304 return 0; 01305 } 01306 } 01307 01308 if (enum_string == NULL || 01309 netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) { 01310 if (hint) { 01311 if (!(sprint_realloc_hinted_integer(buf, buf_len, out_len, 01312 allow_realloc, 01313 *var->val.integer, 'd', 01314 hint, units))) { 01315 return 0; 01316 } 01317 } else { 01318 char str[16]; 01319 sprintf(str, "%ld", *var->val.integer); 01320 if (!snmp_strcat 01321 (buf, buf_len, out_len, allow_realloc, 01322 (const u_char *) str)) { 01323 return 0; 01324 } 01325 } 01326 } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01327 if (!snmp_strcat 01328 (buf, buf_len, out_len, allow_realloc, 01329 (const u_char *) enum_string)) { 01330 return 0; 01331 } 01332 } else { 01333 char str[16]; 01334 sprintf(str, "(%ld)", *var->val.integer); 01335 if (!snmp_strcat 01336 (buf, buf_len, out_len, allow_realloc, 01337 (const u_char *) enum_string)) { 01338 return 0; 01339 } 01340 if (!snmp_strcat 01341 (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) { 01342 return 0; 01343 } 01344 } 01345 01346 if (units) { 01347 return (snmp_strcat 01348 (buf, buf_len, out_len, allow_realloc, 01349 (const u_char *) " ") 01350 && snmp_strcat(buf, buf_len, out_len, allow_realloc, 01351 (const u_char *) units)); 01352 } 01353 return 1; 01354 } 01355 01356 01377 int 01378 sprint_realloc_uinteger(u_char ** buf, size_t * buf_len, size_t * out_len, 01379 int allow_realloc, 01380 const netsnmp_variable_list * var, 01381 const struct enum_list *enums, 01382 const char *hint, const char *units) 01383 { 01384 char *enum_string = NULL; 01385 01386 if ((var->type != ASN_UINTEGER) && 01387 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01388 u_char str[] = "Wrong Type (should be UInteger32): "; 01389 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01390 return sprint_realloc_by_type(buf, buf_len, out_len, 01391 allow_realloc, var, NULL, NULL, 01392 NULL); 01393 } else { 01394 return 0; 01395 } 01396 } 01397 01398 for (; enums; enums = enums->next) { 01399 if (enums->value == *var->val.integer) { 01400 enum_string = enums->label; 01401 break; 01402 } 01403 } 01404 01405 if (enum_string == NULL || 01406 netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) { 01407 if (hint) { 01408 if (!(sprint_realloc_hinted_integer(buf, buf_len, out_len, 01409 allow_realloc, 01410 *var->val.integer, 'u', 01411 hint, units))) { 01412 return 0; 01413 } 01414 } else { 01415 char str[16]; 01416 sprintf(str, "%lu", *var->val.integer); 01417 if (!snmp_strcat 01418 (buf, buf_len, out_len, allow_realloc, 01419 (const u_char *) str)) { 01420 return 0; 01421 } 01422 } 01423 } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01424 if (!snmp_strcat 01425 (buf, buf_len, out_len, allow_realloc, 01426 (const u_char *) enum_string)) { 01427 return 0; 01428 } 01429 } else { 01430 char str[16]; 01431 sprintf(str, "(%lu)", *var->val.integer); 01432 if (!snmp_strcat 01433 (buf, buf_len, out_len, allow_realloc, 01434 (const u_char *) enum_string)) { 01435 return 0; 01436 } 01437 if (!snmp_strcat 01438 (buf, buf_len, out_len, allow_realloc, (const u_char *) str)) { 01439 return 0; 01440 } 01441 } 01442 01443 if (units) { 01444 return (snmp_strcat 01445 (buf, buf_len, out_len, allow_realloc, 01446 (const u_char *) " ") 01447 && snmp_strcat(buf, buf_len, out_len, allow_realloc, 01448 (const u_char *) units)); 01449 } 01450 return 1; 01451 } 01452 01453 01474 int 01475 sprint_realloc_gauge(u_char ** buf, size_t * buf_len, size_t * out_len, 01476 int allow_realloc, 01477 const netsnmp_variable_list * var, 01478 const struct enum_list *enums, 01479 const char *hint, const char *units) 01480 { 01481 char tmp[32]; 01482 01483 if ((var->type != ASN_GAUGE) && 01484 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01485 u_char str[] = 01486 "Wrong Type (should be Gauge32 or Unsigned32): "; 01487 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01488 return sprint_realloc_by_type(buf, buf_len, out_len, 01489 allow_realloc, var, NULL, NULL, 01490 NULL); 01491 } else { 01492 return 0; 01493 } 01494 } 01495 01496 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01497 u_char str[] = "Gauge32: "; 01498 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01499 return 0; 01500 } 01501 } 01502 if (hint) { 01503 if (!sprint_realloc_hinted_integer(buf, buf_len, out_len, 01504 allow_realloc, 01505 *var->val.integer, 'u', hint, 01506 units)) { 01507 return 0; 01508 } 01509 } else { 01510 sprintf(tmp, "%lu", *var->val.integer); 01511 if (!snmp_strcat 01512 (buf, buf_len, out_len, allow_realloc, (const u_char *) tmp)) { 01513 return 0; 01514 } 01515 } 01516 if (units) { 01517 return (snmp_strcat 01518 (buf, buf_len, out_len, allow_realloc, 01519 (const u_char *) " ") 01520 && snmp_strcat(buf, buf_len, out_len, allow_realloc, 01521 (const u_char *) units)); 01522 } 01523 return 1; 01524 } 01525 01526 01547 int 01548 sprint_realloc_counter(u_char ** buf, size_t * buf_len, size_t * out_len, 01549 int allow_realloc, 01550 const netsnmp_variable_list * var, 01551 const struct enum_list *enums, 01552 const char *hint, const char *units) 01553 { 01554 char tmp[32]; 01555 01556 if ((var->type != ASN_COUNTER) && 01557 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01558 u_char str[] = "Wrong Type (should be Counter32): "; 01559 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01560 return sprint_realloc_by_type(buf, buf_len, out_len, 01561 allow_realloc, var, NULL, NULL, 01562 NULL); 01563 } else { 01564 return 0; 01565 } 01566 } 01567 01568 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01569 u_char str[] = "Counter32: "; 01570 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01571 return 0; 01572 } 01573 } 01574 sprintf(tmp, "%lu", *var->val.integer); 01575 if (!snmp_strcat 01576 (buf, buf_len, out_len, allow_realloc, (const u_char *) tmp)) { 01577 return 0; 01578 } 01579 if (units) { 01580 return (snmp_strcat 01581 (buf, buf_len, out_len, allow_realloc, 01582 (const u_char *) " ") 01583 && snmp_strcat(buf, buf_len, out_len, allow_realloc, 01584 (const u_char *) units)); 01585 } 01586 return 1; 01587 } 01588 01589 01610 int 01611 sprint_realloc_networkaddress(u_char ** buf, size_t * buf_len, 01612 size_t * out_len, int allow_realloc, 01613 const netsnmp_variable_list * var, 01614 const struct enum_list *enums, const char *hint, 01615 const char *units) 01616 { 01617 size_t i; 01618 01619 if ((var->type != ASN_IPADDRESS) && 01620 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01621 u_char str[] = "Wrong Type (should be NetworkAddress): "; 01622 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01623 return sprint_realloc_by_type(buf, buf_len, out_len, 01624 allow_realloc, var, NULL, NULL, 01625 NULL); 01626 } else { 01627 return 0; 01628 } 01629 } 01630 01631 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01632 u_char str[] = "Network Address: "; 01633 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01634 return 0; 01635 } 01636 } 01637 01638 while ((*out_len + (var->val_len * 3) + 2) >= *buf_len) { 01639 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 01640 return 0; 01641 } 01642 } 01643 01644 for (i = 0; i < var->val_len; i++) { 01645 sprintf((char *) (*buf + *out_len), "%02X", var->val.string[i]); 01646 *out_len += 2; 01647 if (i < var->val_len - 1) { 01648 *(*buf + *out_len) = ':'; 01649 (*out_len)++; 01650 } 01651 } 01652 return 1; 01653 } 01654 01655 01676 int 01677 sprint_realloc_ipaddress(u_char ** buf, size_t * buf_len, size_t * out_len, 01678 int allow_realloc, 01679 const netsnmp_variable_list * var, 01680 const struct enum_list *enums, 01681 const char *hint, const char *units) 01682 { 01683 u_char *ip = var->val.string; 01684 01685 if ((var->type != ASN_IPADDRESS) && 01686 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01687 u_char str[] = "Wrong Type (should be IpAddress): "; 01688 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01689 return sprint_realloc_by_type(buf, buf_len, out_len, 01690 allow_realloc, var, NULL, NULL, 01691 NULL); 01692 } else { 01693 return 0; 01694 } 01695 } 01696 01697 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01698 u_char str[] = "IpAddress: "; 01699 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01700 return 0; 01701 } 01702 } 01703 while ((*out_len + 17) >= *buf_len) { 01704 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 01705 return 0; 01706 } 01707 } 01708 if (ip) 01709 sprintf((char *) (*buf + *out_len), "%d.%d.%d.%d", 01710 ip[0], ip[1], ip[2], ip[3]); 01711 *out_len += strlen((char *) (*buf + *out_len)); 01712 return 1; 01713 } 01714 01715 01736 int 01737 sprint_realloc_null(u_char ** buf, size_t * buf_len, size_t * out_len, 01738 int allow_realloc, 01739 const netsnmp_variable_list * var, 01740 const struct enum_list *enums, 01741 const char *hint, const char *units) 01742 { 01743 if ((var->type != ASN_NULL) && 01744 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01745 u_char str[] = "Wrong Type (should be NULL): "; 01746 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01747 return sprint_realloc_by_type(buf, buf_len, out_len, 01748 allow_realloc, var, NULL, NULL, 01749 NULL); 01750 } else { 01751 return 0; 01752 } 01753 } else { 01754 u_char str[] = "NULL"; 01755 return snmp_strcat(buf, buf_len, out_len, allow_realloc, str); 01756 } 01757 } 01758 01759 01780 int 01781 sprint_realloc_bitstring(u_char ** buf, size_t * buf_len, size_t * out_len, 01782 int allow_realloc, 01783 const netsnmp_variable_list * var, 01784 const struct enum_list *enums, 01785 const char *hint, const char *units) 01786 { 01787 int len, bit; 01788 u_char *cp; 01789 char *enum_string; 01790 01791 if ((var->type != ASN_BIT_STR && var->type != ASN_OCTET_STR) && 01792 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01793 u_char str[] = "Wrong Type (should be BITS): "; 01794 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01795 return sprint_realloc_by_type(buf, buf_len, out_len, 01796 allow_realloc, var, NULL, NULL, 01797 NULL); 01798 } else { 01799 return 0; 01800 } 01801 } 01802 01803 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01804 u_char str[] = "\""; 01805 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01806 return 0; 01807 } 01808 } else { 01809 u_char str[] = "BITS: "; 01810 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01811 return 0; 01812 } 01813 } 01814 if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc, 01815 var->val.bitstring, var->val_len)) { 01816 return 0; 01817 } 01818 01819 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01820 u_char str[] = "\""; 01821 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01822 return 0; 01823 } 01824 } else { 01825 cp = var->val.bitstring; 01826 for (len = 0; len < (int) var->val_len; len++) { 01827 for (bit = 0; bit < 8; bit++) { 01828 if (*cp & (0x80 >> bit)) { 01829 enum_string = NULL; 01830 for (; enums; enums = enums->next) { 01831 if (enums->value == (len * 8) + bit) { 01832 enum_string = enums->label; 01833 break; 01834 } 01835 } 01836 if (enum_string == NULL || 01837 netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 01838 NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) { 01839 char str[16]; 01840 sprintf(str, "%d ", (len * 8) + bit); 01841 if (!snmp_strcat 01842 (buf, buf_len, out_len, allow_realloc, 01843 (const u_char *) str)) { 01844 return 0; 01845 } 01846 } else { 01847 char str[16]; 01848 sprintf(str, "(%d) ", (len * 8) + bit); 01849 if (!snmp_strcat 01850 (buf, buf_len, out_len, allow_realloc, 01851 (const u_char *) enum_string)) { 01852 return 0; 01853 } 01854 if (!snmp_strcat 01855 (buf, buf_len, out_len, allow_realloc, 01856 (const u_char *) str)) { 01857 return 0; 01858 } 01859 } 01860 } 01861 } 01862 cp++; 01863 } 01864 } 01865 return 1; 01866 } 01867 01868 int 01869 sprint_realloc_nsapaddress(u_char ** buf, size_t * buf_len, 01870 size_t * out_len, int allow_realloc, 01871 const netsnmp_variable_list * var, 01872 const struct enum_list *enums, const char *hint, 01873 const char *units) 01874 { 01875 if ((var->type != ASN_NSAP) && 01876 (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { 01877 u_char str[] = "Wrong Type (should be NsapAddress): "; 01878 if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01879 return sprint_realloc_by_type(buf, buf_len, out_len, 01880 allow_realloc, var, NULL, NULL, 01881 NULL); 01882 } else { 01883 return 0; 01884 } 01885 } 01886 01887 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 01888 u_char str[] = "NsapAddress: "; 01889 if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { 01890 return 0; 01891 } 01892 } 01893 01894 return sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc, 01895 var->val.string, var->val_len); 01896 } 01897 01898 01919 int 01920 sprint_realloc_badtype(u_char ** buf, size_t * buf_len, size_t * out_len, 01921 int allow_realloc, 01922 const netsnmp_variable_list * var, 01923 const struct enum_list *enums, 01924 const char *hint, const char *units) 01925 { 01926 u_char str[] = "Variable has bad type"; 01927 01928 return snmp_strcat(buf, buf_len, out_len, allow_realloc, str); 01929 } 01930 01931 01932 01954 int 01955 sprint_realloc_by_type(u_char ** buf, size_t * buf_len, size_t * out_len, 01956 int allow_realloc, 01957 const netsnmp_variable_list * var, 01958 const struct enum_list *enums, 01959 const char *hint, const char *units) 01960 { 01961 DEBUGMSGTL(("output", "sprint_by_type, type %d\n", var->type)); 01962 01963 switch (var->type) { 01964 case ASN_INTEGER: 01965 return sprint_realloc_integer(buf, buf_len, out_len, allow_realloc, 01966 var, enums, hint, units); 01967 case ASN_OCTET_STR: 01968 return sprint_realloc_octet_string(buf, buf_len, out_len, 01969 allow_realloc, var, enums, hint, 01970 units); 01971 case ASN_BIT_STR: 01972 return sprint_realloc_bitstring(buf, buf_len, out_len, 01973 allow_realloc, var, enums, hint, 01974 units); 01975 case ASN_OPAQUE: 01976 return sprint_realloc_opaque(buf, buf_len, out_len, allow_realloc, 01977 var, enums, hint, units); 01978 case ASN_OBJECT_ID: 01979 return sprint_realloc_object_identifier(buf, buf_len, out_len, 01980 allow_realloc, var, enums, 01981 hint, units); 01982 case ASN_TIMETICKS: 01983 return sprint_realloc_timeticks(buf, buf_len, out_len, 01984 allow_realloc, var, enums, hint, 01985 units); 01986 case ASN_GAUGE: 01987 return sprint_realloc_gauge(buf, buf_len, out_len, allow_realloc, 01988 var, enums, hint, units); 01989 case ASN_COUNTER: 01990 return sprint_realloc_counter(buf, buf_len, out_len, allow_realloc, 01991 var, enums, hint, units); 01992 case ASN_IPADDRESS: 01993 return sprint_realloc_ipaddress(buf, buf_len, out_len, 01994 allow_realloc, var, enums, hint, 01995 units); 01996 case ASN_NULL: 01997 return sprint_realloc_null(buf, buf_len, out_len, allow_realloc, 01998 var, enums, hint, units); 01999 case ASN_UINTEGER: 02000 return sprint_realloc_uinteger(buf, buf_len, out_len, 02001 allow_realloc, var, enums, hint, 02002 units); 02003 case ASN_COUNTER64: 02004 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 02005 case ASN_OPAQUE_U64: 02006 case ASN_OPAQUE_I64: 02007 case ASN_OPAQUE_COUNTER64: 02008 #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ 02009 return sprint_realloc_counter64(buf, buf_len, out_len, 02010 allow_realloc, var, enums, hint, 02011 units); 02012 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 02013 case ASN_OPAQUE_FLOAT: 02014 return sprint_realloc_float(buf, buf_len, out_len, allow_realloc, 02015 var, enums, hint, units); 02016 case ASN_OPAQUE_DOUBLE: 02017 return sprint_realloc_double(buf, buf_len, out_len, allow_realloc, 02018 var, enums, hint, units); 02019 #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ 02020 default: 02021 DEBUGMSGTL(("sprint_by_type", "bad type: %d\n", var->type)); 02022 return sprint_realloc_badtype(buf, buf_len, out_len, allow_realloc, 02023 var, enums, hint, units); 02024 } 02025 } 02026 02027 02028 #ifndef NETSNMP_DISABLE_MIB_LOADING 02029 02034 struct tree * 02035 get_tree_head(void) 02036 { 02037 return (tree_head); 02038 } 02039 02040 static char *confmibdir = NULL; 02041 static char *confmibs = NULL; 02042 02043 static void 02044 handle_mibdirs_conf(const char *token, char *line) 02045 { 02046 char *ctmp; 02047 02048 if (confmibdir) { 02049 if ((*line == '+') || (*line == '-')) { 02050 ctmp = (char *) malloc(strlen(confmibdir) + strlen(line) + 2); 02051 if (!ctmp) { 02052 DEBUGMSGTL(("read_config:initmib", 02053 "mibdir conf malloc failed")); 02054 return; 02055 } 02056 if(*line++ == '+') 02057 sprintf(ctmp, "%s%c%s", confmibdir, ENV_SEPARATOR_CHAR, line); 02058 else 02059 sprintf(ctmp, "%s%c%s", line, ENV_SEPARATOR_CHAR, confmibdir); 02060 } else { 02061 ctmp = strdup(line); 02062 if (!ctmp) { 02063 DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed")); 02064 return; 02065 } 02066 } 02067 SNMP_FREE(confmibdir); 02068 } else { 02069 ctmp = strdup(line); 02070 if (!ctmp) { 02071 DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed")); 02072 return; 02073 } 02074 } 02075 confmibdir = ctmp; 02076 DEBUGMSGTL(("read_config:initmib", "using mibdirs: %s\n", confmibdir)); 02077 } 02078 02079 static void 02080 handle_mibs_conf(const char *token, char *line) 02081 { 02082 char *ctmp; 02083 02084 if (confmibs) { 02085 if ((*line == '+') || (*line == '-')) { 02086 ctmp = (char *) malloc(strlen(confmibs) + strlen(line) + 2); 02087 if (!ctmp) { 02088 DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed")); 02089 return; 02090 } 02091 if(*line++ == '+') 02092 sprintf(ctmp, "%s%c%s", confmibs, ENV_SEPARATOR_CHAR, line); 02093 else 02094 sprintf(ctmp, "%s%c%s", line, ENV_SEPARATOR_CHAR, confmibdir); 02095 } else { 02096 ctmp = strdup(line); 02097 if (!ctmp) { 02098 DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed")); 02099 return; 02100 } 02101 } 02102 SNMP_FREE(confmibs); 02103 } else { 02104 ctmp = strdup(line); 02105 if (!ctmp) { 02106 DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed")); 02107 return; 02108 } 02109 } 02110 confmibs = ctmp; 02111 DEBUGMSGTL(("read_config:initmib", "using mibs: %s\n", confmibs)); 02112 } 02113 02114 02115 static void 02116 handle_mibfile_conf(const char *token, char *line) 02117 { 02118 DEBUGMSGTL(("read_config:initmib", "reading mibfile: %s\n", line)); 02119 read_mib(line); 02120 } 02121 #endif 02122 02123 static void 02124 handle_print_numeric(const char *token, char *line) 02125 { 02126 const char *value; 02127 char *st; 02128 02129 value = strtok_r(line, " \t\n", &st); 02130 if (value && ( 02131 (strcasecmp(value, "yes") == 0) || 02132 (strcasecmp(value, "true") == 0) || 02133 (*value == '1') )) { 02134 02135 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, 02136 NETSNMP_OID_OUTPUT_NUMERIC); 02137 } 02138 } 02139 02140 char * 02141 snmp_out_toggle_options(char *options) 02142 { 02143 while (*options) { 02144 switch (*options++) { 02145 case '0': 02146 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, 02147 NETSNMP_DS_LIB_2DIGIT_HEX_OUTPUT); 02148 break; 02149 case 'a': 02150 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT, 02151 NETSNMP_STRING_OUTPUT_ASCII); 02152 break; 02153 case 'b': 02154 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS); 02155 break; 02156 case 'e': 02157 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM); 02158 break; 02159 case 'E': 02160 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES); 02161 break; 02162 case 'f': 02163 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, 02164 NETSNMP_OID_OUTPUT_FULL); 02165 break; 02166 case 'n': 02167 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, 02168 NETSNMP_OID_OUTPUT_NUMERIC); 02169 break; 02170 case 'q': 02171 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT); 02172 break; 02173 case 'Q': 02174 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT, 1); 02175 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT); 02176 break; 02177 case 's': 02178 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, 02179 NETSNMP_OID_OUTPUT_SUFFIX); 02180 break; 02181 case 'S': 02182 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, 02183 NETSNMP_OID_OUTPUT_MODULE); 02184 break; 02185 case 't': 02186 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS); 02187 break; 02188 case 'T': 02189 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_HEX_TEXT); 02190 break; 02191 case 'u': 02192 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, 02193 NETSNMP_OID_OUTPUT_UCD); 02194 break; 02195 case 'U': 02196 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PRINT_UNITS); 02197 break; 02198 case 'v': 02199 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE); 02200 break; 02201 case 'x': 02202 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT, 02203 NETSNMP_STRING_OUTPUT_HEX); 02204 break; 02205 case 'X': 02206 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX); 02207 break; 02208 default: 02209 return options - 1; 02210 } 02211 } 02212 return NULL; 02213 } 02214 02215 void 02216 snmp_out_toggle_options_usage(const char *lead, FILE * outf) 02217 { 02218 fprintf(outf, "%s0: print leading 0 for single-digit hex characters\n", lead); 02219 fprintf(outf, "%sa: print all strings in ascii format\n", lead); 02220 fprintf(outf, "%sb: do not break OID indexes down\n", lead); 02221 fprintf(outf, "%se: print enums numerically\n", lead); 02222 fprintf(outf, "%sE: escape quotes in string indices\n", lead); 02223 fprintf(outf, "%sf: print full OIDs on output\n", lead); 02224 fprintf(outf, "%sn: print OIDs numerically\n", lead); 02225 fprintf(outf, "%sq: quick print for easier parsing\n", lead); 02226 fprintf(outf, "%sQ: quick print with equal-signs\n", lead); /* @@JDW */ 02227 fprintf(outf, "%ss: print only last symbolic element of OID\n", lead); 02228 fprintf(outf, "%sS: print MIB module-id plus last element\n", lead); 02229 fprintf(outf, "%st: print timeticks unparsed as numeric integers\n", 02230 lead); 02231 fprintf(outf, 02232 "%sT: print human-readable text along with hex strings\n", 02233 lead); 02234 fprintf(outf, "%su: print OIDs using UCD-style prefix suppression\n", 02235 lead); 02236 fprintf(outf, "%sU: don't print units\n", lead); 02237 fprintf(outf, "%sv: print values only (not OID = value)\n", lead); 02238 fprintf(outf, "%sx: print all strings in hex format\n", lead); 02239 fprintf(outf, "%sX: extended index format\n", lead); 02240 } 02241 02242 char * 02243 snmp_in_options(char *optarg, int argc, char *const *argv) 02244 { 02245 char *cp; 02246 02247 for (cp = optarg; *cp; cp++) { 02248 switch (*cp) { 02249 case 'b': 02250 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_REGEX_ACCESS); 02251 break; 02252 case 'R': 02253 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_RANDOM_ACCESS); 02254 break; 02255 case 'r': 02256 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_CHECK_RANGE); 02257 break; 02258 case 'h': 02259 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NO_DISPLAY_HINT); 02260 break; 02261 case 'u': 02262 netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_READ_UCD_STYLE_OID); 02263 break; 02264 case 's': 02265 /* What if argc/argv are null ? */ 02266 if (!*(++cp)) 02267 cp = argv[optind++]; 02268 netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 02269 NETSNMP_DS_LIB_OIDSUFFIX, 02270 cp); 02271 return NULL; 02272 02273 case 'S': 02274 /* What if argc/argv are null ? */ 02275 if (!*(++cp)) 02276 cp = argv[optind++]; 02277 netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 02278 NETSNMP_DS_LIB_OIDPREFIX, 02279 cp); 02280 return NULL; 02281 02282 default: 02283 /* 02284 * Here? Or in snmp_parse_args? 02285 snmp_log(LOG_ERR, "Unknown input option passed to -I: %c.\n", *cp); 02286 */ 02287 return cp; 02288 } 02289 } 02290 return NULL; 02291 } 02292 02293 char * 02294 snmp_in_toggle_options(char *options) 02295 { 02296 return snmp_in_options( options, 0, NULL ); 02297 } 02298 02299 02307 void 02308 snmp_in_toggle_options_usage(const char *lead, FILE * outf) 02309 { 02310 fprintf(outf, "%sb: do best/regex matching to find a MIB node\n", lead); 02311 fprintf(outf, "%sh: don't apply DISPLAY-HINTs\n", lead); 02312 fprintf(outf, "%sr: do not check values for range/type legality\n", lead); 02313 fprintf(outf, "%sR: do random access to OID labels\n", lead); 02314 fprintf(outf, 02315 "%su: top-level OIDs must have '.' prefix (UCD-style)\n", lead); 02316 fprintf(outf, 02317 "%ss SUFFIX: Append all textual OIDs with SUFFIX before parsing\n", 02318 lead); 02319 fprintf(outf, 02320 "%sS PREFIX: Prepend all textual OIDs with PREFIX before parsing\n", 02321 lead); 02322 } 02323 02324 /*** 02325 * 02326 */ 02327 void 02328 register_mib_handlers(void) 02329 { 02330 #ifndef NETSNMP_DISABLE_MIB_LOADING 02331 register_prenetsnmp_mib_handler("snmp", "mibdirs", 02332 handle_mibdirs_conf, NULL, 02333 "[mib-dirs|+mib-dirs|-mib-dirs]"); 02334 register_prenetsnmp_mib_handler("snmp", "mibs", 02335 handle_mibs_conf, NULL, 02336 "[mib-tokens|+mib-tokens]"); 02337 register_config_handler("snmp", "mibfile", 02338 handle_mibfile_conf, NULL, "mibfile-to-read"); 02339 /* 02340 * register the snmp.conf configuration handlers for default 02341 * parsing behaviour 02342 */ 02343 02344 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "showMibErrors", 02345 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_ERRORS); 02346 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "commentToEOL", /* Describes actual behaviour */ 02347 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_COMMENT_TERM); 02348 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "strictCommentTerm", /* Backward compatibility */ 02349 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_COMMENT_TERM); 02350 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "mibAllowUnderline", 02351 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_PARSE_LABEL); 02352 netsnmp_ds_register_premib(ASN_INTEGER, "snmp", "mibWarningLevel", 02353 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_WARNINGS); 02354 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "mibReplaceWithLatest", 02355 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_REPLACE); 02356 #endif 02357 02358 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "printNumericEnums", 02359 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM); 02360 register_prenetsnmp_mib_handler("snmp", "printNumericOids", 02361 handle_print_numeric, NULL, "(1|yes|true|0|no|false)"); 02362 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "escapeQuotes", 02363 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES); 02364 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "dontBreakdownOids", 02365 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS); 02366 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "quickPrinting", 02367 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT); 02368 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "numericTimeticks", 02369 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS); 02370 netsnmp_ds_register_premib(ASN_INTEGER, "snmp", "oidOutputFormat", 02371 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); 02372 netsnmp_ds_register_premib(ASN_INTEGER, "snmp", "suffixPrinting", 02373 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); 02374 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "extendedIndex", 02375 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX); 02376 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "printHexText", 02377 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_HEX_TEXT); 02378 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "printValueOnly", 02379 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE); 02380 netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "dontPrintUnits", 02381 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PRINT_UNITS); 02382 netsnmp_ds_register_premib(ASN_INTEGER, "snmp", "hexOutputLength", 02383 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HEX_OUTPUT_LENGTH); 02384 } 02385 02386 #ifndef NETSNMP_DISABLE_MIB_LOADING 02387 /* 02388 * function : netsnmp_set_mib_directory 02389 * - This function sets the string of the directories 02390 * from which the MIB modules will be searched or 02391 * loaded. 02392 * arguments: const char *dir, which are the directories 02393 * from which the MIB modules will be searched or 02394 * loaded. 02395 * returns : - 02396 */ 02397 void 02398 netsnmp_set_mib_directory(const char *dir) 02399 { 02400 const char *newdir; 02401 char *olddir, *tmpdir = NULL; 02402 02403 DEBUGTRACE; 02404 if (NULL == dir) { 02405 return; 02406 } 02407 02408 olddir = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 02409 NETSNMP_DS_LIB_MIBDIRS); 02410 if (olddir) { 02411 if ((*dir == '+') || (*dir == '-')) { 02413 tmpdir = (char *)malloc(strlen(dir) + strlen(olddir) + 2); 02414 if (!tmpdir) { 02415 DEBUGMSGTL(("read_config:initmib", "set mibdir malloc failed")); 02416 return; 02417 } 02418 if (*dir++ == '+') 02419 sprintf(tmpdir, "%s%c%s", olddir, ENV_SEPARATOR_CHAR, dir); 02420 else 02421 sprintf(tmpdir, "%s%c%s", dir, ENV_SEPARATOR_CHAR, olddir); 02422 newdir = tmpdir; 02423 } else { 02424 newdir = dir; 02425 } 02426 } else { 02428 newdir = ((*dir == '+') ? ++dir : dir); 02429 } 02430 netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIBDIRS, 02431 newdir); 02432 02434 if (tmpdir == newdir) { 02435 SNMP_FREE(tmpdir); 02436 } 02437 } 02438 02439 /* 02440 * function : netsnmp_get_mib_directory 02441 * - This function returns a string of the directories 02442 * from which the MIB modules will be searched or 02443 * loaded. 02444 * If the value still does not exists, it will be made 02445 * from the evironment variable 'MIBDIRS' and/or the 02446 * default. 02447 * arguments: - 02448 * returns : char * of the directories in which the MIB modules 02449 * will be searched/loaded. 02450 */ 02451 02452 char * 02453 netsnmp_get_mib_directory(void) 02454 { 02455 char *dir; 02456 02457 DEBUGTRACE; 02458 dir = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIBDIRS); 02459 if (dir == NULL) { 02460 DEBUGMSGTL(("get_mib_directory", "no mib directories set\n")); 02461 02463 dir = netsnmp_getenv("MIBDIRS"); 02464 if (dir == NULL) { 02465 DEBUGMSGTL(("get_mib_directory", "no mib directories set by environment\n")); 02467 if (confmibdir == NULL) { 02468 DEBUGMSGTL(("get_mib_directory", "no mib directories set by config\n")); 02469 netsnmp_set_mib_directory(NETSNMP_DEFAULT_MIBDIRS); 02470 } 02471 else if ((*confmibdir == '+') || (*confmibdir == '-')) { 02472 DEBUGMSGTL(("get_mib_directory", "mib directories set by config (but added)\n")); 02473 netsnmp_set_mib_directory(NETSNMP_DEFAULT_MIBDIRS); 02474 netsnmp_set_mib_directory(confmibdir); 02475 } 02476 else { 02477 DEBUGMSGTL(("get_mib_directory", "mib directories set by config\n")); 02478 netsnmp_set_mib_directory(confmibdir); 02479 } 02480 } else if ((*dir == '+') || (*dir == '-')) { 02481 DEBUGMSGTL(("get_mib_directory", "mib directories set by environment (but added)\n")); 02482 netsnmp_set_mib_directory(NETSNMP_DEFAULT_MIBDIRS); 02483 netsnmp_set_mib_directory(dir); 02484 } else { 02485 DEBUGMSGTL(("get_mib_directory", "mib directories set by environment\n")); 02486 netsnmp_set_mib_directory(dir); 02487 } 02488 dir = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIBDIRS); 02489 } 02490 DEBUGMSGTL(("get_mib_directory", "mib directories set '%s'\n", dir)); 02491 return(dir); 02492 } 02493 02494 /* 02495 * function : netsnmp_fixup_mib_directory 02496 * arguments: - 02497 * returns : - 02498 */ 02499 void 02500 netsnmp_fixup_mib_directory(void) 02501 { 02502 char *homepath = netsnmp_getenv("HOME"); 02503 char *mibpath = netsnmp_get_mib_directory(); 02504 char *oldmibpath = NULL; 02505 char *ptr_home; 02506 char *new_mibpath; 02507 02508 DEBUGTRACE; 02509 if (homepath && mibpath) { 02510 DEBUGMSGTL(("fixup_mib_directory", "mib directories '%s'\n", mibpath)); 02511 while ((ptr_home = strstr(mibpath, "$HOME"))) { 02512 new_mibpath = (char *)malloc(strlen(mibpath) - strlen("$HOME") + 02513 strlen(homepath)+1); 02514 if (new_mibpath) { 02515 *ptr_home = 0; /* null out the spot where we stop copying */ 02516 sprintf(new_mibpath, "%s%s%s", mibpath, homepath, 02517 ptr_home + strlen("$HOME")); 02519 mibpath = new_mibpath; 02520 if (oldmibpath != NULL) { 02521 SNMP_FREE(oldmibpath); 02522 } 02523 oldmibpath = new_mibpath; 02524 } else { 02525 break; 02526 } 02527 } 02528 02529 netsnmp_set_mib_directory(mibpath); 02530 02531 /* The above copies the mibpath for us, so... */ 02532 02533 if (oldmibpath != NULL) { 02534 SNMP_FREE(oldmibpath); 02535 } 02536 02537 } 02538 02539 } 02540 02546 void 02547 netsnmp_init_mib(void) 02548 { 02549 const char *prefix; 02550 char *env_var, *entry; 02551 PrefixListPtr pp = &mib_prefixes[0]; 02552 char *st = NULL; 02553 02554 if (Mib) 02555 return; 02556 netsnmp_init_mib_internals(); 02557 02558 /* 02559 * Initialise the MIB directory/ies 02560 */ 02561 netsnmp_fixup_mib_directory(); 02562 env_var = strdup(netsnmp_get_mib_directory()); 02563 netsnmp_mibindex_load(); 02564 02565 DEBUGMSGTL(("init_mib", 02566 "Seen MIBDIRS: Looking in '%s' for mib dirs ...\n", 02567 env_var)); 02568 02569 entry = strtok_r(env_var, ENV_SEPARATOR, &st); 02570 while (entry) { 02571 add_mibdir(entry); 02572 entry = strtok_r(NULL, ENV_SEPARATOR, &st); 02573 } 02574 SNMP_FREE(env_var); 02575 02576 env_var = netsnmp_getenv("MIBFILES"); 02577 if (env_var != NULL) { 02578 if (*env_var == '+') 02579 entry = strtok_r(env_var+1, ENV_SEPARATOR, &st); 02580 else 02581 entry = strtok_r(env_var, ENV_SEPARATOR, &st); 02582 while (entry) { 02583 add_mibfile(entry, NULL, NULL); 02584 entry = strtok_r(NULL, ENV_SEPARATOR, &st); 02585 } 02586 } 02587 02588 netsnmp_init_mib_internals(); 02589 02590 /* 02591 * Read in any modules or mibs requested 02592 */ 02593 02594 env_var = netsnmp_getenv("MIBS"); 02595 if (env_var == NULL) { 02596 if (confmibs != NULL) 02597 env_var = strdup(confmibs); 02598 else 02599 env_var = strdup(NETSNMP_DEFAULT_MIBS); 02600 } else { 02601 env_var = strdup(env_var); 02602 } 02603 if (env_var && ((*env_var == '+') || (*env_var == '-'))) { 02604 entry = 02605 (char *) malloc(strlen(NETSNMP_DEFAULT_MIBS) + strlen(env_var) + 2); 02606 if (!entry) { 02607 DEBUGMSGTL(("init_mib", "env mibs malloc failed")); 02608 SNMP_FREE(env_var); 02609 return; 02610 } else { 02611 if (*env_var == '+') 02612 sprintf(entry, "%s%c%s", NETSNMP_DEFAULT_MIBS, ENV_SEPARATOR_CHAR, 02613 env_var+1); 02614 else 02615 sprintf(entry, "%s%c%s", env_var+1, ENV_SEPARATOR_CHAR, 02616 NETSNMP_DEFAULT_MIBS ); 02617 } 02618 SNMP_FREE(env_var); 02619 env_var = entry; 02620 } 02621 02622 DEBUGMSGTL(("init_mib", 02623 "Seen MIBS: Looking in '%s' for mib files ...\n", 02624 env_var)); 02625 entry = strtok_r(env_var, ENV_SEPARATOR, &st); 02626 while (entry) { 02627 if (strcasecmp(entry, DEBUG_ALWAYS_TOKEN) == 0) { 02628 read_all_mibs(); 02629 } else if (strstr(entry, "/") != NULL) { 02630 read_mib(entry); 02631 } else { 02632 netsnmp_read_module(entry); 02633 } 02634 entry = strtok_r(NULL, ENV_SEPARATOR, &st); 02635 } 02636 adopt_orphans(); 02637 SNMP_FREE(env_var); 02638 02639 env_var = netsnmp_getenv("MIBFILES"); 02640 if (env_var != NULL) { 02641 if ((*env_var == '+') || (*env_var == '-')) { 02642 #ifdef NETSNMP_DEFAULT_MIBFILES 02643 entry = 02644 (char *) malloc(strlen(NETSNMP_DEFAULT_MIBFILES) + 02645 strlen(env_var) + 2); 02646 if (!entry) { 02647 DEBUGMSGTL(("init_mib", "env mibfiles malloc failed")); 02648 } else { 02649 if (*env_var++ == '+') 02650 sprintf(entry, "%s%c%s", NETSNMP_DEFAULT_MIBFILES, ENV_SEPARATOR_CHAR, 02651 env_var ); 02652 else 02653 sprintf(entry, "%s%c%s", env_var, ENV_SEPARATOR_CHAR, 02654 NETSNMP_DEFAULT_MIBFILES ); 02655 } 02656 SNMP_FREE(env_var); 02657 env_var = entry; 02658 #else 02659 env_var = strdup(env_var + 1); 02660 #endif 02661 } else { 02662 env_var = strdup(env_var); 02663 } 02664 } else { 02665 #ifdef NETSNMP_DEFAULT_MIBFILES 02666 env_var = strdup(NETSNMP_DEFAULT_MIBFILES); 02667 #endif 02668 } 02669 02670 if (env_var != NULL) { 02671 DEBUGMSGTL(("init_mib", 02672 "Seen MIBFILES: Looking in '%s' for mib files ...\n", 02673 env_var)); 02674 entry = strtok_r(env_var, ENV_SEPARATOR, &st); 02675 while (entry) { 02676 read_mib(entry); 02677 entry = strtok_r(NULL, ENV_SEPARATOR, &st); 02678 } 02679 SNMP_FREE(env_var); 02680 } 02681 02682 prefix = netsnmp_getenv("PREFIX"); 02683 02684 if (!prefix) 02685 prefix = Standard_Prefix; 02686 02687 Prefix = (char *) malloc(strlen(prefix) + 2); 02688 if (!Prefix) 02689 DEBUGMSGTL(("init_mib", "Prefix malloc failed")); 02690 else 02691 strcpy(Prefix, prefix); 02692 02693 DEBUGMSGTL(("init_mib", 02694 "Seen PREFIX: Looking in '%s' for prefix ...\n", Prefix)); 02695 02696 /* 02697 * remove trailing dot 02698 */ 02699 if (Prefix) { 02700 env_var = &Prefix[strlen(Prefix) - 1]; 02701 if (*env_var == '.') 02702 *env_var = '\0'; 02703 } 02704 02705 pp->str = Prefix; /* fixup first mib_prefix entry */ 02706 /* 02707 * now that the list of prefixes is built, save each string length. 02708 */ 02709 while (pp->str) { 02710 pp->len = strlen(pp->str); 02711 pp++; 02712 } 02713 02714 Mib = tree_head; /* Backwards compatibility */ 02715 tree_top = (struct tree *) calloc(1, sizeof(struct tree)); 02716 /* 02717 * XX error check ? 02718 */ 02719 if (tree_top) { 02720 tree_top->label = strdup("(top)"); 02721 tree_top->child_list = tree_head; 02722 } 02723 } 02724 02725 #ifndef NETSNMP_NO_LEGACY_DEFINITIONS 02726 void 02727 init_mib(void) 02728 { 02729 netsnmp_init_mib(); 02730 } 02731 #endif 02732 02733 02734 /* 02735 * Handle MIB indexes centrally 02736 */ 02737 static int _mibindex = 0; /* Last index in use */ 02738 static int _mibindex_max = 0; /* Size of index array */ 02739 char **_mibindexes = NULL; 02740 02741 int _mibindex_add( const char *dirname, int i ); 02742 void 02743 netsnmp_mibindex_load( void ) 02744 { 02745 DIR *dir; 02746 struct dirent *file; 02747 FILE *fp; 02748 char tmpbuf[ 300]; 02749 char tmpbuf2[300]; 02750 int i; 02751 char *cp; 02752 02753 /* 02754 * Open the MIB index directory, or create it (empty) 02755 */ 02756 snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes", 02757 get_persistent_directory()); 02758 tmpbuf[sizeof(tmpbuf)-1] = 0; 02759 dir = opendir( tmpbuf ); 02760 if ( dir == NULL ) { 02761 DEBUGMSGTL(("mibindex", "load: (new)\n")); 02762 mkdirhier( tmpbuf, NETSNMP_AGENT_DIRECTORY_MODE, 0); 02763 return; 02764 } 02765 02766 /* 02767 * Create a list of which directory each file refers to 02768 */ 02769 while ((file = readdir( dir ))) { 02770 if ( !isdigit(file->d_name[0])) 02771 continue; 02772 i = atoi( file->d_name ); 02773 02774 snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d", 02775 get_persistent_directory(), i ); 02776 tmpbuf[sizeof(tmpbuf)-1] = 0; 02777 fp = fopen( tmpbuf, "r" ); 02778 cp = fgets( tmpbuf2, sizeof(tmpbuf2), fp ); 02779 if ( !cp ) { 02780 DEBUGMSGTL(("mibindex", "Empty MIB index (%d)\n", i)); 02781 fclose(fp); 02782 continue; 02783 } 02784 tmpbuf2[strlen(tmpbuf2)-1] = 0; 02785 DEBUGMSGTL(("mibindex", "load: (%d) %s\n", i, tmpbuf2)); 02786 (void)_mibindex_add( tmpbuf2+4, i ); /* Skip 'DIR ' */ 02787 fclose( fp ); 02788 } 02789 closedir( dir ); 02790 } 02791 02792 char * 02793 netsnmp_mibindex_lookup( const char *dirname ) 02794 { 02795 int i; 02796 static char tmpbuf[300]; 02797 02798 for (i=0; i<_mibindex; i++) { 02799 if ( _mibindexes[i] && 02800 strcmp( _mibindexes[i], dirname ) == 0) { 02801 snprintf(tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d", 02802 get_persistent_directory(), i); 02803 tmpbuf[sizeof(tmpbuf)-1] = 0; 02804 DEBUGMSGTL(("mibindex", "lookup: %s (%d) %s\n", dirname, i, tmpbuf )); 02805 return tmpbuf; 02806 } 02807 } 02808 DEBUGMSGTL(("mibindex", "lookup: (none)\n")); 02809 return NULL; 02810 } 02811 02812 int 02813 _mibindex_add( const char *dirname, int i ) 02814 { 02815 char **cpp; 02816 02817 DEBUGMSGTL(("mibindex", "add: %s (%d)\n", dirname, i )); 02818 if ( i == -1 ) 02819 i = _mibindex++; 02820 if ( i >= _mibindex_max ) { 02821 /* 02822 * If the index array is full (or non-exitent) 02823 * then expand (or create) it 02824 */ 02825 cpp = (char **)malloc( (10+i) * sizeof(char*)); 02826 if ( _mibindexes ) { 02827 memcpy( cpp, _mibindexes, _mibindex * sizeof(char*)); 02828 free(_mibindexes); 02829 } 02830 _mibindexes = cpp; 02831 _mibindex_max = i+10; 02832 } 02833 DEBUGMSGTL(("mibindex", "add: %d/%d/%d\n", i, _mibindex, _mibindex_max )); 02834 02835 _mibindexes[ i ] = strdup( dirname ); 02836 if ( i >= _mibindex ) 02837 _mibindex = i+1; 02838 02839 return i; 02840 } 02841 02842 FILE * 02843 netsnmp_mibindex_new( const char *dirname ) 02844 { 02845 FILE *fp; 02846 char tmpbuf[300]; 02847 char *cp; 02848 int i; 02849 02850 cp = netsnmp_mibindex_lookup( dirname ); 02851 if (!cp) { 02852 i = _mibindex_add( dirname, -1 ); 02853 snprintf( tmpbuf, sizeof(tmpbuf), "%s/mib_indexes/%d", 02854 get_persistent_directory(), i ); 02855 tmpbuf[sizeof(tmpbuf)-1] = 0; 02856 cp = tmpbuf; 02857 } 02858 DEBUGMSGTL(("mibindex", "new: %s (%s)\n", dirname, cp )); 02859 fp = fopen( cp, "w" ); 02860 if (fp) 02861 fprintf( fp, "DIR %s\n", dirname ); 02862 return fp; 02863 } 02864 02865 02869 void 02870 shutdown_mib(void) 02871 { 02872 unload_all_mibs(); 02873 if (tree_top) { 02874 if (tree_top->label) 02875 SNMP_FREE(tree_top->label); 02876 SNMP_FREE(tree_top); 02877 tree_top = NULL; 02878 } 02879 tree_head = NULL; 02880 Mib = NULL; 02881 if (_mibindexes) { 02882 int i; 02883 for (i = 0; i < _mibindex; ++i) 02884 SNMP_FREE(_mibindexes[i]); 02885 free(_mibindexes); 02886 _mibindex = 0; 02887 _mibindex_max = 0; 02888 _mibindexes = NULL; 02889 } 02890 if (Prefix != NULL && Prefix != &Standard_Prefix[0]) 02891 SNMP_FREE(Prefix); 02892 if (Prefix) 02893 Prefix = NULL; 02894 SNMP_FREE(confmibs); 02895 SNMP_FREE(confmibdir); 02896 } 02897 02903 void 02904 print_mib(FILE * fp) 02905 { 02906 print_subtree(fp, tree_head, 0); 02907 } 02908 02909 void 02910 print_ascii_dump(FILE * fp) 02911 { 02912 fprintf(fp, "dump DEFINITIONS ::= BEGIN\n"); 02913 print_ascii_dump_tree(fp, tree_head, 0); 02914 fprintf(fp, "END\n"); 02915 } 02916 02917 02924 void 02925 set_function(struct tree *subtree) 02926 { 02927 subtree->printer = NULL; 02928 switch (subtree->type) { 02929 case TYPE_OBJID: 02930 subtree->printomat = sprint_realloc_object_identifier; 02931 break; 02932 case TYPE_OCTETSTR: 02933 subtree->printomat = sprint_realloc_octet_string; 02934 break; 02935 case TYPE_INTEGER: 02936 subtree->printomat = sprint_realloc_integer; 02937 break; 02938 case TYPE_INTEGER32: 02939 subtree->printomat = sprint_realloc_integer; 02940 break; 02941 case TYPE_NETADDR: 02942 subtree->printomat = sprint_realloc_networkaddress; 02943 break; 02944 case TYPE_IPADDR: 02945 subtree->printomat = sprint_realloc_ipaddress; 02946 break; 02947 case TYPE_COUNTER: 02948 subtree->printomat = sprint_realloc_counter; 02949 break; 02950 case TYPE_GAUGE: 02951 subtree->printomat = sprint_realloc_gauge; 02952 break; 02953 case TYPE_TIMETICKS: 02954 subtree->printomat = sprint_realloc_timeticks; 02955 break; 02956 case TYPE_OPAQUE: 02957 subtree->printomat = sprint_realloc_opaque; 02958 break; 02959 case TYPE_NULL: 02960 subtree->printomat = sprint_realloc_null; 02961 break; 02962 case TYPE_BITSTRING: 02963 subtree->printomat = sprint_realloc_bitstring; 02964 break; 02965 case TYPE_NSAPADDRESS: 02966 subtree->printomat = sprint_realloc_nsapaddress; 02967 break; 02968 case TYPE_COUNTER64: 02969 subtree->printomat = sprint_realloc_counter64; 02970 break; 02971 case TYPE_UINTEGER: 02972 subtree->printomat = sprint_realloc_uinteger; 02973 break; 02974 case TYPE_UNSIGNED32: 02975 subtree->printomat = sprint_realloc_gauge; 02976 break; 02977 case TYPE_OTHER: 02978 default: 02979 subtree->printomat = sprint_realloc_by_type; 02980 break; 02981 } 02982 } 02983 02984 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 02985 03001 int 03002 read_objid(const char *input, oid * output, size_t * out_len) 03003 { /* number of subid's in "output" */ 03004 #ifndef NETSNMP_DISABLE_MIB_LOADING 03005 struct tree *root = tree_top; 03006 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03007 char buf[SPRINT_MAX_LEN]; 03008 int ret, max_out_len; 03009 char *name, ch; 03010 const char *cp; 03011 03012 cp = input; 03013 while ((ch = *cp)) { 03014 if (('0' <= ch && ch <= '9') 03015 || ('a' <= ch && ch <= 'z') 03016 || ('A' <= ch && ch <= 'Z') 03017 || ch == '-') 03018 cp++; 03019 else 03020 break; 03021 } 03022 #ifndef NETSNMP_DISABLE_MIB_LOADING 03023 if (ch == ':') 03024 return get_node(input, output, out_len); 03025 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03026 03027 if (*input == '.') 03028 input++; 03029 #ifndef NETSNMP_DISABLE_MIB_LOADING 03030 else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_READ_UCD_STYLE_OID)) { 03031 /* 03032 * get past leading '.', append '.' to Prefix. 03033 */ 03034 if (*Prefix == '.') 03035 strncpy(buf, Prefix + 1, sizeof(buf)-1); 03036 else 03037 strncpy(buf, Prefix, sizeof(buf)-1); 03038 buf[ sizeof(buf)-1 ] = 0; 03039 strcat(buf, "."); 03040 buf[ sizeof(buf)-1 ] = 0; 03041 strncat(buf, input, sizeof(buf)-strlen(buf)); 03042 buf[ sizeof(buf)-1 ] = 0; 03043 input = buf; 03044 } 03045 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03046 03047 #ifndef NETSNMP_DISABLE_MIB_LOADING 03048 if ((root == NULL) && (tree_head != NULL)) { 03049 root = tree_head; 03050 } 03051 else if (root == NULL) { 03052 SET_SNMP_ERROR(SNMPERR_NOMIB); 03053 *out_len = 0; 03054 return 0; 03055 } 03056 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03057 name = strdup(input); 03058 max_out_len = *out_len; 03059 *out_len = 0; 03060 #ifndef NETSNMP_DISABLE_MIB_LOADING 03061 if ((ret = 03062 _add_strings_to_oid(root, name, output, out_len, 03063 max_out_len)) <= 0) 03064 #else 03065 if ((ret = 03066 _add_strings_to_oid(NULL, name, output, out_len, 03067 max_out_len)) <= 0) 03068 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03069 { 03070 if (ret == 0) 03071 ret = SNMPERR_UNKNOWN_OBJID; 03072 SET_SNMP_ERROR(ret); 03073 SNMP_FREE(name); 03074 return 0; 03075 } 03076 SNMP_FREE(name); 03077 03078 return 1; 03079 } 03080 03084 void 03085 netsnmp_sprint_realloc_objid(u_char ** buf, size_t * buf_len, 03086 size_t * out_len, int allow_realloc, 03087 int *buf_overflow, 03088 const oid * objid, size_t objidlen) 03089 { 03090 u_char *tbuf = NULL, *cp = NULL; 03091 size_t tbuf_len = 256, tout_len = 0; 03092 int tbuf_overflow = 0; 03093 int output_format; 03094 03095 if ((tbuf = (u_char *) calloc(tbuf_len, 1)) == NULL) { 03096 tbuf_overflow = 1; 03097 } else { 03098 *tbuf = '.'; 03099 tout_len = 1; 03100 } 03101 03102 _oid_finish_printing(objid, objidlen, 03103 &tbuf, &tbuf_len, &tout_len, 03104 allow_realloc, &tbuf_overflow); 03105 03106 if (tbuf_overflow) { 03107 if (!*buf_overflow) { 03108 snmp_strcat(buf, buf_len, out_len, allow_realloc, tbuf); 03109 *buf_overflow = 1; 03110 } 03111 SNMP_FREE(tbuf); 03112 return; 03113 } 03114 03115 output_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); 03116 if (0 == output_format) { 03117 output_format = NETSNMP_OID_OUTPUT_NUMERIC; 03118 } 03119 switch (output_format) { 03120 case NETSNMP_OID_OUTPUT_FULL: 03121 case NETSNMP_OID_OUTPUT_NUMERIC: 03122 case NETSNMP_OID_OUTPUT_SUFFIX: 03123 case NETSNMP_OID_OUTPUT_MODULE: 03124 cp = tbuf; 03125 break; 03126 03127 case NETSNMP_OID_OUTPUT_NONE: 03128 default: 03129 cp = NULL; 03130 } 03131 03132 if (!*buf_overflow && 03133 !snmp_strcat(buf, buf_len, out_len, allow_realloc, cp)) { 03134 *buf_overflow = 1; 03135 } 03136 SNMP_FREE(tbuf); 03137 } 03138 03142 #ifdef NETSNMP_DISABLE_MIB_LOADING 03143 void 03144 netsnmp_sprint_realloc_objid_tree(u_char ** buf, size_t * buf_len, 03145 size_t * out_len, int allow_realloc, 03146 int *buf_overflow, 03147 const oid * objid, size_t objidlen) 03148 { 03149 netsnmp_sprint_realloc_objid(buf, buf_len, out_len, allow_realloc, 03150 buf_overflow, objid, objidlen); 03151 } 03152 #else 03153 struct tree * 03154 netsnmp_sprint_realloc_objid_tree(u_char ** buf, size_t * buf_len, 03155 size_t * out_len, int allow_realloc, 03156 int *buf_overflow, 03157 const oid * objid, size_t objidlen) 03158 { 03159 u_char *tbuf = NULL, *cp = NULL; 03160 size_t tbuf_len = 512, tout_len = 0; 03161 struct tree *subtree = tree_head; 03162 size_t midpoint_offset = 0; 03163 int tbuf_overflow = 0; 03164 int output_format; 03165 03166 if ((tbuf = (u_char *) calloc(tbuf_len, 1)) == NULL) { 03167 tbuf_overflow = 1; 03168 } else { 03169 *tbuf = '.'; 03170 tout_len = 1; 03171 } 03172 03173 subtree = _get_realloc_symbol(objid, objidlen, subtree, 03174 &tbuf, &tbuf_len, &tout_len, 03175 allow_realloc, &tbuf_overflow, NULL, 03176 &midpoint_offset); 03177 03178 if (tbuf_overflow) { 03179 if (!*buf_overflow) { 03180 snmp_strcat(buf, buf_len, out_len, allow_realloc, tbuf); 03181 *buf_overflow = 1; 03182 } 03183 SNMP_FREE(tbuf); 03184 return subtree; 03185 } 03186 03187 output_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); 03188 if (0 == output_format) { 03189 output_format = NETSNMP_OID_OUTPUT_MODULE; 03190 } 03191 switch (output_format) { 03192 case NETSNMP_OID_OUTPUT_FULL: 03193 case NETSNMP_OID_OUTPUT_NUMERIC: 03194 cp = tbuf; 03195 break; 03196 03197 case NETSNMP_OID_OUTPUT_SUFFIX: 03198 case NETSNMP_OID_OUTPUT_MODULE: 03199 for (cp = tbuf; *cp; cp++); 03200 03201 if (midpoint_offset != 0) { 03202 cp = tbuf + midpoint_offset - 2; /* beyond the '.' */ 03203 } else { 03204 while (cp >= tbuf) { 03205 if (isalpha(*cp)) { 03206 break; 03207 } 03208 cp--; 03209 } 03210 } 03211 03212 while (cp >= tbuf) { 03213 if (*cp == '.') { 03214 break; 03215 } 03216 cp--; 03217 } 03218 03219 cp++; 03220 03221 if ((NETSNMP_OID_OUTPUT_MODULE == output_format) 03222 && cp > tbuf) { 03223 char modbuf[256] = { 0 }, *mod = 03224 module_name(subtree->modid, modbuf); 03225 03226 /* 03227 * Don't add the module ID if it's just numeric (i.e. we couldn't look 03228 * it up properly. 03229 */ 03230 03231 if (!*buf_overflow && modbuf[0] != '#') { 03232 if (!snmp_strcat 03233 (buf, buf_len, out_len, allow_realloc, 03234 (const u_char *) mod) 03235 || !snmp_strcat(buf, buf_len, out_len, allow_realloc, 03236 (const u_char *) "::")) { 03237 *buf_overflow = 1; 03238 } 03239 } 03240 } 03241 break; 03242 03243 case NETSNMP_OID_OUTPUT_UCD: 03244 { 03245 PrefixListPtr pp = &mib_prefixes[0]; 03246 size_t ilen, tlen; 03247 const char *testcp; 03248 03249 cp = tbuf; 03250 tlen = strlen((char *) tbuf); 03251 03252 while (pp->str) { 03253 ilen = pp->len; 03254 testcp = pp->str; 03255 03256 if ((tlen > ilen) && memcmp(tbuf, testcp, ilen) == 0) { 03257 cp += (ilen + 1); 03258 break; 03259 } 03260 pp++; 03261 } 03262 break; 03263 } 03264 03265 case NETSNMP_OID_OUTPUT_NONE: 03266 default: 03267 cp = NULL; 03268 } 03269 03270 if (!*buf_overflow && 03271 !snmp_strcat(buf, buf_len, out_len, allow_realloc, cp)) { 03272 *buf_overflow = 1; 03273 } 03274 SNMP_FREE(tbuf); 03275 return subtree; 03276 } 03277 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03278 03279 int 03280 sprint_realloc_objid(u_char ** buf, size_t * buf_len, 03281 size_t * out_len, int allow_realloc, 03282 const oid * objid, size_t objidlen) 03283 { 03284 int buf_overflow = 0; 03285 03286 netsnmp_sprint_realloc_objid_tree(buf, buf_len, out_len, allow_realloc, 03287 &buf_overflow, objid, objidlen); 03288 return !buf_overflow; 03289 } 03290 03291 int 03292 snprint_objid(char *buf, size_t buf_len, 03293 const oid * objid, size_t objidlen) 03294 { 03295 size_t out_len = 0; 03296 03297 if (sprint_realloc_objid((u_char **) & buf, &buf_len, &out_len, 0, 03298 objid, objidlen)) { 03299 return (int) out_len; 03300 } else { 03301 return -1; 03302 } 03303 } 03304 03311 void 03312 print_objid(const oid * objid, size_t objidlen) 03313 { /* number of subidentifiers */ 03314 fprint_objid(stdout, objid, objidlen); 03315 } 03316 03317 03325 void 03326 fprint_objid(FILE * f, const oid * objid, size_t objidlen) 03327 { /* number of subidentifiers */ 03328 u_char *buf = NULL; 03329 size_t buf_len = 256, out_len = 0; 03330 int buf_overflow = 0; 03331 03332 if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) { 03333 fprintf(f, "[TRUNCATED]\n"); 03334 return; 03335 } else { 03336 netsnmp_sprint_realloc_objid_tree(&buf, &buf_len, &out_len, 1, 03337 &buf_overflow, objid, objidlen); 03338 if (buf_overflow) { 03339 fprintf(f, "%s [TRUNCATED]\n", buf); 03340 } else { 03341 fprintf(f, "%s\n", buf); 03342 } 03343 } 03344 03345 SNMP_FREE(buf); 03346 } 03347 03348 int 03349 sprint_realloc_variable(u_char ** buf, size_t * buf_len, 03350 size_t * out_len, int allow_realloc, 03351 const oid * objid, size_t objidlen, 03352 const netsnmp_variable_list * variable) 03353 { 03354 int buf_overflow = 0; 03355 03356 #ifndef NETSNMP_DISABLE_MIB_LOADING 03357 struct tree *subtree = tree_head; 03358 03359 subtree = 03360 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03361 netsnmp_sprint_realloc_objid_tree(buf, buf_len, out_len, 03362 allow_realloc, &buf_overflow, 03363 objid, objidlen); 03364 03365 if (buf_overflow) { 03366 return 0; 03367 } 03368 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE)) { 03369 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { 03370 if (!snmp_strcat 03371 (buf, buf_len, out_len, allow_realloc, 03372 (const u_char *) " = ")) { 03373 return 0; 03374 } 03375 } else { 03376 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { 03377 if (!snmp_strcat 03378 (buf, buf_len, out_len, allow_realloc, 03379 (const u_char *) " ")) { 03380 return 0; 03381 } 03382 } else { 03383 if (!snmp_strcat 03384 (buf, buf_len, out_len, allow_realloc, 03385 (const u_char *) " = ")) { 03386 return 0; 03387 } 03388 } /* end if-else NETSNMP_DS_LIB_QUICK_PRINT */ 03389 } /* end if-else NETSNMP_DS_LIB_QUICKE_PRINT */ 03390 } else { 03391 *out_len = 0; 03392 } 03393 03394 if (variable->type == SNMP_NOSUCHOBJECT) { 03395 return snmp_strcat(buf, buf_len, out_len, allow_realloc, 03396 (const u_char *) 03397 "No Such Object available on this agent at this OID"); 03398 } else if (variable->type == SNMP_NOSUCHINSTANCE) { 03399 return snmp_strcat(buf, buf_len, out_len, allow_realloc, 03400 (const u_char *) 03401 "No Such Instance currently exists at this OID"); 03402 } else if (variable->type == SNMP_ENDOFMIBVIEW) { 03403 return snmp_strcat(buf, buf_len, out_len, allow_realloc, 03404 (const u_char *) 03405 "No more variables left in this MIB View (It is past the end of the MIB tree)"); 03406 #ifndef NETSNMP_DISABLE_MIB_LOADING 03407 } else if (subtree) { 03408 const char *units = NULL; 03409 const char *hint = NULL; 03410 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 03411 NETSNMP_DS_LIB_DONT_PRINT_UNITS)) { 03412 units = subtree->units; 03413 } 03414 03415 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 03416 NETSNMP_DS_LIB_NO_DISPLAY_HINT)) { 03417 hint = subtree->hint; 03418 } 03419 03420 if (subtree->printomat) { 03421 return (*subtree->printomat) (buf, buf_len, out_len, 03422 allow_realloc, variable, 03423 subtree->enums, hint, 03424 units); 03425 } else { 03426 return sprint_realloc_by_type(buf, buf_len, out_len, 03427 allow_realloc, variable, 03428 subtree->enums, hint, 03429 units); 03430 } 03431 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03432 } else { 03433 /* 03434 * Handle rare case where tree is empty. 03435 */ 03436 return sprint_realloc_by_type(buf, buf_len, out_len, allow_realloc, 03437 variable, NULL, NULL, NULL); 03438 } 03439 } 03440 03441 int 03442 snprint_variable(char *buf, size_t buf_len, 03443 const oid * objid, size_t objidlen, 03444 const netsnmp_variable_list * variable) 03445 { 03446 size_t out_len = 0; 03447 03448 if (sprint_realloc_variable((u_char **) & buf, &buf_len, &out_len, 0, 03449 objid, objidlen, variable)) { 03450 return (int) out_len; 03451 } else { 03452 return -1; 03453 } 03454 } 03455 03463 void 03464 print_variable(const oid * objid, 03465 size_t objidlen, const netsnmp_variable_list * variable) 03466 { 03467 fprint_variable(stdout, objid, objidlen, variable); 03468 } 03469 03470 03479 void 03480 fprint_variable(FILE * f, 03481 const oid * objid, 03482 size_t objidlen, const netsnmp_variable_list * variable) 03483 { 03484 u_char *buf = NULL; 03485 size_t buf_len = 256, out_len = 0; 03486 03487 if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) { 03488 fprintf(f, "[TRUNCATED]\n"); 03489 return; 03490 } else { 03491 if (sprint_realloc_variable(&buf, &buf_len, &out_len, 1, 03492 objid, objidlen, variable)) { 03493 fprintf(f, "%s\n", buf); 03494 } else { 03495 fprintf(f, "%s [TRUNCATED]\n", buf); 03496 } 03497 } 03498 03499 SNMP_FREE(buf); 03500 } 03501 03502 int 03503 sprint_realloc_value(u_char ** buf, size_t * buf_len, 03504 size_t * out_len, int allow_realloc, 03505 const oid * objid, size_t objidlen, 03506 const netsnmp_variable_list * variable) 03507 { 03508 if (variable->type == SNMP_NOSUCHOBJECT) { 03509 return snmp_strcat(buf, buf_len, out_len, allow_realloc, 03510 (const u_char *) 03511 "No Such Object available on this agent at this OID"); 03512 } else if (variable->type == SNMP_NOSUCHINSTANCE) { 03513 return snmp_strcat(buf, buf_len, out_len, allow_realloc, 03514 (const u_char *) 03515 "No Such Instance currently exists at this OID"); 03516 } else if (variable->type == SNMP_ENDOFMIBVIEW) { 03517 return snmp_strcat(buf, buf_len, out_len, allow_realloc, 03518 (const u_char *) 03519 "No more variables left in this MIB View (It is past the end of the MIB tree)"); 03520 } else { 03521 #ifndef NETSNMP_DISABLE_MIB_LOADING 03522 const char *units = NULL; 03523 struct tree *subtree = tree_head; 03524 subtree = get_tree(objid, objidlen, subtree); 03525 if (subtree && !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 03526 NETSNMP_DS_LIB_DONT_PRINT_UNITS)) { 03527 units = subtree->units; 03528 } 03529 if (subtree) { 03530 if(subtree->printomat) { 03531 return (*subtree->printomat) (buf, buf_len, out_len, 03532 allow_realloc, variable, 03533 subtree->enums, subtree->hint, 03534 units); 03535 } else { 03536 return sprint_realloc_by_type(buf, buf_len, out_len, 03537 allow_realloc, variable, 03538 subtree->enums, subtree->hint, 03539 units); 03540 } 03541 } 03542 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 03543 return sprint_realloc_by_type(buf, buf_len, out_len, 03544 allow_realloc, variable, 03545 NULL, NULL, NULL); 03546 } 03547 } 03548 03549 int 03550 snprint_value(char *buf, size_t buf_len, 03551 const oid * objid, size_t objidlen, 03552 const netsnmp_variable_list * variable) 03553 { 03554 size_t out_len = 0; 03555 03556 if (sprint_realloc_value((u_char **) & buf, &buf_len, &out_len, 0, 03557 objid, objidlen, variable)) { 03558 return (int) out_len; 03559 } else { 03560 return -1; 03561 } 03562 } 03563 03564 void 03565 print_value(const oid * objid, 03566 size_t objidlen, const netsnmp_variable_list * variable) 03567 { 03568 fprint_value(stdout, objid, objidlen, variable); 03569 } 03570 03571 void 03572 fprint_value(FILE * f, 03573 const oid * objid, 03574 size_t objidlen, const netsnmp_variable_list * variable) 03575 { 03576 u_char *buf = NULL; 03577 size_t buf_len = 256, out_len = 0; 03578 03579 if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) { 03580 fprintf(f, "[TRUNCATED]\n"); 03581 return; 03582 } else { 03583 if (sprint_realloc_value(&buf, &buf_len, &out_len, 1, 03584 objid, objidlen, variable)) { 03585 fprintf(f, "%s\n", buf); 03586 } else { 03587 fprintf(f, "%s [TRUNCATED]\n", buf); 03588 } 03589 } 03590 03591 SNMP_FREE(buf); 03592 } 03593 03594 03602 int 03603 build_oid_segment(netsnmp_variable_list * var) 03604 { 03605 int i; 03606 03607 if (var->name && var->name != var->name_loc) 03608 SNMP_FREE(var->name); 03609 switch (var->type) { 03610 case ASN_INTEGER: 03611 case ASN_COUNTER: 03612 case ASN_GAUGE: 03613 case ASN_TIMETICKS: 03614 var->name_length = 1; 03615 var->name = var->name_loc; 03616 var->name[0] = *(var->val.integer); 03617 break; 03618 03619 case ASN_IPADDRESS: 03620 var->name_length = 4; 03621 var->name = var->name_loc; 03622 var->name[0] = 03623 (((unsigned int) *(var->val.integer)) & 0xff000000) >> 24; 03624 var->name[1] = 03625 (((unsigned int) *(var->val.integer)) & 0x00ff0000) >> 16; 03626 var->name[2] = 03627 (((unsigned int) *(var->val.integer)) & 0x0000ff00) >> 8; 03628 var->name[3] = 03629 (((unsigned int) *(var->val.integer)) & 0x000000ff); 03630 break; 03631 03632 case ASN_PRIV_IMPLIED_OBJECT_ID: 03633 var->name_length = var->val_len / sizeof(oid); 03634 if (var->name_length > (sizeof(var->name_loc) / sizeof(oid))) 03635 var->name = (oid *) malloc(sizeof(oid) * (var->name_length)); 03636 else 03637 var->name = var->name_loc; 03638 if (var->name == NULL) 03639 return SNMPERR_GENERR; 03640 03641 for (i = 0; i < (int) var->name_length; i++) 03642 var->name[i] = var->val.objid[i]; 03643 break; 03644 03645 case ASN_OBJECT_ID: 03646 var->name_length = var->val_len / sizeof(oid) + 1; 03647 if (var->name_length > (sizeof(var->name_loc) / sizeof(oid))) 03648 var->name = (oid *) malloc(sizeof(oid) * (var->name_length)); 03649 else 03650 var->name = var->name_loc; 03651 if (var->name == NULL) 03652 return SNMPERR_GENERR; 03653 03654 var->name[0] = var->name_length - 1; 03655 for (i = 0; i < (int) var->name_length - 1; i++) 03656 var->name[i + 1] = var->val.objid[i]; 03657 break; 03658 03659 case ASN_PRIV_IMPLIED_OCTET_STR: 03660 var->name_length = var->val_len; 03661 if (var->name_length > (sizeof(var->name_loc) / sizeof(oid))) 03662 var->name = (oid *) malloc(sizeof(oid) * (var->name_length)); 03663 else 03664 var->name = var->name_loc; 03665 if (var->name == NULL) 03666 return SNMPERR_GENERR; 03667 03668 for (i = 0; i < (int) var->val_len; i++) 03669 var->name[i] = (oid) var->val.string[i]; 03670 break; 03671 03672 case ASN_OPAQUE: 03673 case ASN_OCTET_STR: 03674 var->name_length = var->val_len + 1; 03675 if (var->name_length > (sizeof(var->name_loc) / sizeof(oid))) 03676 var->name = (oid *) malloc(sizeof(oid) * (var->name_length)); 03677 else 03678 var->name = var->name_loc; 03679 if (var->name == NULL) 03680 return SNMPERR_GENERR; 03681 03682 var->name[0] = (oid) var->val_len; 03683 for (i = 0; i < (int) var->val_len; i++) 03684 var->name[i + 1] = (oid) var->val.string[i]; 03685 break; 03686 03687 default: 03688 DEBUGMSGTL(("build_oid_segment", 03689 "invalid asn type: %d\n", var->type)); 03690 return SNMPERR_GENERR; 03691 } 03692 03693 if (var->name_length > MAX_OID_LEN) { 03694 DEBUGMSGTL(("build_oid_segment", 03695 "Something terribly wrong, namelen = %lu\n", 03696 (unsigned long)var->name_length)); 03697 return SNMPERR_GENERR; 03698 } 03699 03700 return SNMPERR_SUCCESS; 03701 } 03702 03703 03704 int 03705 build_oid_noalloc(oid * in, size_t in_len, size_t * out_len, 03706 oid * prefix, size_t prefix_len, 03707 netsnmp_variable_list * indexes) 03708 { 03709 netsnmp_variable_list *var; 03710 03711 if (prefix) { 03712 if (in_len < prefix_len) 03713 return SNMPERR_GENERR; 03714 memcpy(in, prefix, prefix_len * sizeof(oid)); 03715 *out_len = prefix_len; 03716 } else { 03717 *out_len = 0; 03718 } 03719 03720 for (var = indexes; var != NULL; var = var->next_variable) { 03721 if (build_oid_segment(var) != SNMPERR_SUCCESS) 03722 return SNMPERR_GENERR; 03723 if (var->name_length + *out_len <= in_len) { 03724 memcpy(&(in[*out_len]), var->name, 03725 sizeof(oid) * var->name_length); 03726 *out_len += var->name_length; 03727 } else { 03728 return SNMPERR_GENERR; 03729 } 03730 } 03731 03732 DEBUGMSGTL(("build_oid_noalloc", "generated: ")); 03733 DEBUGMSGOID(("build_oid_noalloc", in, *out_len)); 03734 DEBUGMSG(("build_oid_noalloc", "\n")); 03735 return SNMPERR_SUCCESS; 03736 } 03737 03738 int 03739 build_oid(oid ** out, size_t * out_len, 03740 oid * prefix, size_t prefix_len, netsnmp_variable_list * indexes) 03741 { 03742 oid tmpout[MAX_OID_LEN]; 03743 03744 /* 03745 * xxx-rks: inefficent. try only building segments to find index len: 03746 * for (var = indexes; var != NULL; var = var->next_variable) { 03747 * if (build_oid_segment(var) != SNMPERR_SUCCESS) 03748 * return SNMPERR_GENERR; 03749 * *out_len += var->name_length; 03750 * 03751 * then see if it fits in existing buffer, or realloc buffer. 03752 */ 03753 if (build_oid_noalloc(tmpout, sizeof(tmpout), out_len, 03754 prefix, prefix_len, indexes) != SNMPERR_SUCCESS) 03755 return SNMPERR_GENERR; 03756 03758 snmp_clone_mem((void **) out, (void *) tmpout, *out_len * sizeof(oid)); 03759 03760 return SNMPERR_SUCCESS; 03761 } 03762 03763 /* 03764 * vblist_out must contain a pre-allocated string of variables into 03765 * which indexes can be extracted based on the previously existing 03766 * types in the variable chain 03767 * returns: 03768 * SNMPERR_GENERR on error 03769 * SNMPERR_SUCCESS on success 03770 */ 03771 03772 int 03773 parse_oid_indexes(oid * oidIndex, size_t oidLen, 03774 netsnmp_variable_list * data) 03775 { 03776 netsnmp_variable_list *var = data; 03777 03778 while (var && oidLen > 0) { 03779 03780 if (parse_one_oid_index(&oidIndex, &oidLen, var, 0) != 03781 SNMPERR_SUCCESS) 03782 break; 03783 03784 var = var->next_variable; 03785 } 03786 03787 if (var != NULL || oidLen != 0) 03788 return SNMPERR_GENERR; 03789 return SNMPERR_SUCCESS; 03790 } 03791 03792 03793 int 03794 parse_one_oid_index(oid ** oidStart, size_t * oidLen, 03795 netsnmp_variable_list * data, int complete) 03796 { 03797 netsnmp_variable_list *var = data; 03798 oid tmpout[MAX_OID_LEN]; 03799 unsigned int i; 03800 unsigned int uitmp = 0; 03801 03802 oid *oidIndex = *oidStart; 03803 03804 if (var == NULL || ((*oidLen == 0) && (complete == 0))) 03805 return SNMPERR_GENERR; 03806 else { 03807 switch (var->type) { 03808 case ASN_INTEGER: 03809 case ASN_COUNTER: 03810 case ASN_GAUGE: 03811 case ASN_TIMETICKS: 03812 if (*oidLen) { 03813 snmp_set_var_value(var, (u_char *) oidIndex++, 03814 sizeof(long)); 03815 --(*oidLen); 03816 } else { 03817 snmp_set_var_value(var, (u_char *) oidLen, sizeof(long)); 03818 } 03819 DEBUGMSGTL(("parse_oid_indexes", 03820 "Parsed int(%d): %ld\n", var->type, 03821 *var->val.integer)); 03822 break; 03823 03824 case ASN_IPADDRESS: 03825 if ((4 > *oidLen) && (complete == 0)) 03826 return SNMPERR_GENERR; 03827 03828 for (i = 0; i < 4 && i < *oidLen; ++i) { 03829 if (oidIndex[i] > 255) { 03830 DEBUGMSGTL(("parse_oid_indexes", 03831 "illegal oid in index: %ld\n", oidIndex[0])); 03832 return SNMPERR_GENERR; /* sub-identifier too large */ 03833 } 03834 uitmp = uitmp + (oidIndex[i] << (8*(3-i))); 03835 } 03836 if (4 > (int) (*oidLen)) { 03837 oidIndex += *oidLen; 03838 (*oidLen) = 0; 03839 } else { 03840 oidIndex += 4; 03841 (*oidLen) -= 4; 03842 } 03843 uitmp = htonl(uitmp); /* put it in proper order for byte copies */ 03844 uitmp = 03845 snmp_set_var_value(var, (u_char *) &uitmp, 4); 03846 DEBUGMSGTL(("parse_oid_indexes", 03847 "Parsed ipaddr(%d): %d.%d.%d.%d\n", var->type, 03848 var->val.string[0], var->val.string[1], 03849 var->val.string[2], var->val.string[3])); 03850 break; 03851 03852 case ASN_OBJECT_ID: 03853 case ASN_PRIV_IMPLIED_OBJECT_ID: 03854 if (var->type == ASN_PRIV_IMPLIED_OBJECT_ID) { 03855 /* 03856 * might not be implied, might be fixed len. check if 03857 * caller set up val len, and use it if they did. 03858 */ 03859 if (0 == var->val_len) 03860 uitmp = *oidLen; 03861 else { 03862 DEBUGMSGTL(("parse_oid_indexes:fix", "fixed len oid\n")); 03863 uitmp = var->val_len; 03864 } 03865 } else { 03866 if (*oidLen) { 03867 uitmp = *oidIndex++; 03868 --(*oidLen); 03869 } else { 03870 uitmp = 0; 03871 } 03872 if ((uitmp > *oidLen) && (complete == 0)) 03873 return SNMPERR_GENERR; 03874 } 03875 03876 if (uitmp > MAX_OID_LEN) 03877 return SNMPERR_GENERR; /* too big and illegal */ 03878 03879 if (uitmp > *oidLen) { 03880 memcpy(tmpout, oidIndex, sizeof(oid) * (*oidLen)); 03881 memset(&tmpout[*oidLen], 0x00, 03882 sizeof(oid) * (uitmp - *oidLen)); 03883 snmp_set_var_value(var, (u_char *) tmpout, 03884 sizeof(oid) * uitmp); 03885 oidIndex += *oidLen; 03886 (*oidLen) = 0; 03887 } else { 03888 snmp_set_var_value(var, (u_char *) oidIndex, 03889 sizeof(oid) * uitmp); 03890 oidIndex += uitmp; 03891 (*oidLen) -= uitmp; 03892 } 03893 03894 DEBUGMSGTL(("parse_oid_indexes", "Parsed oid: ")); 03895 DEBUGMSGOID(("parse_oid_indexes", 03896 var->val.objid, var->val_len / sizeof(oid))); 03897 DEBUGMSG(("parse_oid_indexes", "\n")); 03898 break; 03899 03900 case ASN_OPAQUE: 03901 case ASN_OCTET_STR: 03902 case ASN_PRIV_IMPLIED_OCTET_STR: 03903 if (var->type == ASN_PRIV_IMPLIED_OCTET_STR) { 03904 /* 03905 * might not be implied, might be fixed len. check if 03906 * caller set up val len, and use it if they did. 03907 */ 03908 if (0 == var->val_len) 03909 uitmp = *oidLen; 03910 else { 03911 DEBUGMSGTL(("parse_oid_indexes:fix", "fixed len str\n")); 03912 uitmp = var->val_len; 03913 } 03914 } else { 03915 if (*oidLen) { 03916 uitmp = *oidIndex++; 03917 --(*oidLen); 03918 } else { 03919 uitmp = 0; 03920 } 03921 if ((uitmp > *oidLen) && (complete == 0)) 03922 return SNMPERR_GENERR; 03923 } 03924 03925 /* 03926 * we handle this one ourselves since we don't have 03927 * pre-allocated memory to copy from using 03928 * snmp_set_var_value() 03929 */ 03930 03931 if (uitmp == 0) 03932 break; /* zero length strings shouldn't malloc */ 03933 03934 if (uitmp > MAX_OID_LEN) 03935 return SNMPERR_GENERR; /* too big and illegal */ 03936 03937 /* 03938 * malloc by size+1 to allow a null to be appended. 03939 */ 03940 var->val_len = uitmp; 03941 var->val.string = (u_char *) calloc(1, uitmp + 1); 03942 if (var->val.string == NULL) 03943 return SNMPERR_GENERR; 03944 03945 if ((size_t)uitmp > (*oidLen)) { 03946 for (i = 0; i < *oidLen; ++i) 03947 var->val.string[i] = (u_char) * oidIndex++; 03948 for (i = *oidLen; i < uitmp; ++i) 03949 var->val.string[i] = '\0'; 03950 (*oidLen) = 0; 03951 } else { 03952 for (i = 0; i < uitmp; ++i) 03953 var->val.string[i] = (u_char) * oidIndex++; 03954 (*oidLen) -= uitmp; 03955 } 03956 var->val.string[uitmp] = '\0'; 03957 03958 DEBUGMSGTL(("parse_oid_indexes", 03959 "Parsed str(%d): %s\n", var->type, 03960 var->val.string)); 03961 break; 03962 03963 default: 03964 DEBUGMSGTL(("parse_oid_indexes", 03965 "invalid asn type: %d\n", var->type)); 03966 return SNMPERR_GENERR; 03967 } 03968 } 03969 (*oidStart) = oidIndex; 03970 return SNMPERR_SUCCESS; 03971 } 03972 03973 /* 03974 * dump_realloc_oid_to_inetaddress: 03975 * return 0 for failure, 03976 * return 1 for success, 03977 * return 2 for not handled 03978 */ 03979 03980 int 03981 dump_realloc_oid_to_inetaddress(const int addr_type, const oid * objid, size_t objidlen, 03982 u_char ** buf, size_t * buf_len, 03983 size_t * out_len, int allow_realloc, 03984 char quotechar) 03985 { 03986 if (buf) { 03987 int i, len; 03988 char intbuf[64], * p; 03989 unsigned char *zc; 03990 unsigned long zone; 03991 03992 memset(intbuf, 0, 64); 03993 03994 p = intbuf; 03995 *p = quotechar; 03996 p++; 03997 switch (addr_type) { 03998 case IPV4: 03999 case IPV4Z: 04000 if ((addr_type == IPV4 && objidlen != 4) || 04001 (addr_type == IPV4Z && objidlen != 8)) 04002 return 2; 04003 04004 len = sprintf(p, "%lu.%lu.%lu.%lu", objid[0], objid[1], objid[2], objid[3]); 04005 p += len; 04006 if (addr_type == IPV4Z) { 04007 zc = (unsigned char*)&zone; 04008 zc[0] = (u_char)(objid[4]); 04009 zc[1] = (u_char)(objid[5]); 04010 zc[2] = (u_char)(objid[6]); 04011 zc[3] = (u_char)(objid[7]); 04012 zone = ntohl(zone); 04013 len = sprintf(p, "%%%lu", zone); 04014 p += len; 04015 } 04016 04017 break; 04018 04019 case IPV6: 04020 case IPV6Z: 04021 if ((addr_type == IPV6 && objidlen != 16) || 04022 (addr_type == IPV6Z && objidlen != 20)) 04023 return 2; 04024 04025 len = 0; 04026 for (i = 0; i < 16; i ++) { 04027 len = snprintf(p, 4, "%02lx:", objid[i]); 04028 p += len; 04029 } 04030 p-- ; /* do not include the last ':' */ 04031 04032 if (addr_type == IPV6Z) { 04033 zc = (unsigned char*)&zone; 04034 zc[0] = (u_char)(objid[16]); 04035 zc[1] = (u_char)(objid[17]); 04036 zc[2] = (u_char)(objid[18]); 04037 zc[3] = (u_char)(objid[19]); 04038 zone = ntohl(zone); 04039 len = sprintf(p, "%%%lu", zone); 04040 p += len; 04041 } 04042 04043 break; 04044 04045 case DNS: 04046 default: 04047 /* DNS can just be handled by dump_realloc_oid_to_string() */ 04048 return 2; 04049 } 04050 04051 *p = quotechar; 04052 04053 return snmp_strcat(buf, buf_len, out_len, allow_realloc, 04054 (const u_char *) intbuf); 04055 } 04056 return 1; 04057 } 04058 04059 int 04060 dump_realloc_oid_to_string(const oid * objid, size_t objidlen, 04061 u_char ** buf, size_t * buf_len, 04062 size_t * out_len, int allow_realloc, 04063 char quotechar) 04064 { 04065 if (buf) { 04066 int i, alen; 04067 04068 for (i = 0, alen = 0; i < (int) objidlen; i++) { 04069 oid tst = objid[i]; 04070 if ((tst > 254) || (!isprint(tst))) { 04071 tst = (oid) '.'; 04072 } 04073 04074 if (alen == 0) { 04075 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) { 04076 while ((*out_len + 2) >= *buf_len) { 04077 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 04078 return 0; 04079 } 04080 } 04081 *(*buf + *out_len) = '\\'; 04082 (*out_len)++; 04083 } 04084 while ((*out_len + 2) >= *buf_len) { 04085 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 04086 return 0; 04087 } 04088 } 04089 *(*buf + *out_len) = quotechar; 04090 (*out_len)++; 04091 } 04092 04093 while ((*out_len + 2) >= *buf_len) { 04094 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 04095 return 0; 04096 } 04097 } 04098 *(*buf + *out_len) = (char) tst; 04099 (*out_len)++; 04100 alen++; 04101 } 04102 04103 if (alen) { 04104 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) { 04105 while ((*out_len + 2) >= *buf_len) { 04106 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 04107 return 0; 04108 } 04109 } 04110 *(*buf + *out_len) = '\\'; 04111 (*out_len)++; 04112 } 04113 while ((*out_len + 2) >= *buf_len) { 04114 if (!(allow_realloc && snmp_realloc(buf, buf_len))) { 04115 return 0; 04116 } 04117 } 04118 *(*buf + *out_len) = quotechar; 04119 (*out_len)++; 04120 } 04121 04122 *(*buf + *out_len) = '\0'; 04123 } 04124 04125 return 1; 04126 } 04127 04128 void 04129 _oid_finish_printing(const oid * objid, size_t objidlen, 04130 u_char ** buf, size_t * buf_len, size_t * out_len, 04131 int allow_realloc, int *buf_overflow) { 04132 char intbuf[64]; 04133 if (*buf != NULL && *(*buf + *out_len - 1) != '.') { 04134 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04135 allow_realloc, 04136 (const u_char *) ".")) { 04137 *buf_overflow = 1; 04138 } 04139 } 04140 04141 while (objidlen-- > 0) { /* output rest of name, uninterpreted */ 04142 sprintf(intbuf, "%lu.", *objid++); 04143 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04144 allow_realloc, 04145 (const u_char *) intbuf)) { 04146 *buf_overflow = 1; 04147 } 04148 } 04149 04150 if (*buf != NULL) { 04151 *(*buf + *out_len - 1) = '\0'; /* remove trailing dot */ 04152 *out_len = *out_len - 1; 04153 } 04154 } 04155 04156 #ifndef NETSNMP_DISABLE_MIB_LOADING 04157 static struct tree * 04158 _get_realloc_symbol(const oid * objid, size_t objidlen, 04159 struct tree *subtree, 04160 u_char ** buf, size_t * buf_len, size_t * out_len, 04161 int allow_realloc, int *buf_overflow, 04162 struct index_list *in_dices, size_t * end_of_known) 04163 { 04164 struct tree *return_tree = NULL; 04165 int extended_index = 04166 netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX); 04167 int output_format = 04168 netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); 04169 char intbuf[64]; 04170 04171 if (!objid || !buf) { 04172 return NULL; 04173 } 04174 04175 for (; subtree; subtree = subtree->next_peer) { 04176 if (*objid == subtree->subid) { 04177 while (subtree->next_peer && subtree->next_peer->subid == *objid) 04178 subtree = subtree->next_peer; 04179 if (subtree->indexes) { 04180 in_dices = subtree->indexes; 04181 } else if (subtree->augments) { 04182 struct tree *tp2 = 04183 find_tree_node(subtree->augments, -1); 04184 if (tp2) { 04185 in_dices = tp2->indexes; 04186 } 04187 } 04188 04189 if (!strncmp(subtree->label, ANON, ANON_LEN) || 04190 (NETSNMP_OID_OUTPUT_NUMERIC == output_format)) { 04191 sprintf(intbuf, "%lu", subtree->subid); 04192 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04193 allow_realloc, 04194 (const u_char *) 04195 intbuf)) { 04196 *buf_overflow = 1; 04197 } 04198 } else { 04199 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04200 allow_realloc, 04201 (const u_char *) 04202 subtree->label)) { 04203 *buf_overflow = 1; 04204 } 04205 } 04206 04207 if (objidlen > 1) { 04208 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04209 allow_realloc, 04210 (const u_char *) ".")) { 04211 *buf_overflow = 1; 04212 } 04213 04214 return_tree = _get_realloc_symbol(objid + 1, objidlen - 1, 04215 subtree->child_list, 04216 buf, buf_len, out_len, 04217 allow_realloc, 04218 buf_overflow, in_dices, 04219 end_of_known); 04220 } 04221 04222 if (return_tree != NULL) { 04223 return return_tree; 04224 } else { 04225 return subtree; 04226 } 04227 } 04228 } 04229 04230 04231 if (end_of_known) { 04232 *end_of_known = *out_len; 04233 } 04234 04235 /* 04236 * Subtree not found. 04237 */ 04238 04239 while (in_dices && (objidlen > 0) && 04240 (NETSNMP_OID_OUTPUT_NUMERIC != output_format) && 04241 !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS)) { 04242 size_t numids; 04243 struct tree *tp; 04244 04245 tp = find_tree_node(in_dices->ilabel, -1); 04246 04247 if (!tp) { 04248 /* 04249 * Can't find an index in the mib tree. Bail. 04250 */ 04251 goto finish_it; 04252 } 04253 04254 if (extended_index) { 04255 if (*buf != NULL && *(*buf + *out_len - 1) == '.') { 04256 (*out_len)--; 04257 } 04258 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04259 allow_realloc, 04260 (const u_char *) "[")) { 04261 *buf_overflow = 1; 04262 } 04263 } 04264 04265 switch (tp->type) { 04266 case TYPE_OCTETSTR: 04267 if (extended_index && tp->hint) { 04268 netsnmp_variable_list var; 04269 u_char buffer[1024]; 04270 int i; 04271 04272 memset(&var, 0, sizeof var); 04273 if (in_dices->isimplied) { 04274 numids = objidlen; 04275 if (numids > objidlen) 04276 goto finish_it; 04277 } else if (tp->ranges && !tp->ranges->next 04278 && tp->ranges->low == tp->ranges->high) { 04279 numids = tp->ranges->low; 04280 if (numids > objidlen) 04281 goto finish_it; 04282 } else { 04283 numids = *objid; 04284 if (numids >= objidlen) 04285 goto finish_it; 04286 objid++; 04287 objidlen--; 04288 } 04289 if (numids > objidlen) 04290 goto finish_it; 04291 for (i = 0; i < (int) numids; i++) 04292 buffer[i] = (u_char) objid[i]; 04293 var.type = ASN_OCTET_STR; 04294 var.val.string = buffer; 04295 var.val_len = numids; 04296 if (!*buf_overflow) { 04297 if (!sprint_realloc_octet_string(buf, buf_len, out_len, 04298 allow_realloc, &var, 04299 NULL, tp->hint, 04300 NULL)) { 04301 *buf_overflow = 1; 04302 } 04303 } 04304 } else if (in_dices->isimplied) { 04305 numids = objidlen; 04306 if (numids > objidlen) 04307 goto finish_it; 04308 04309 if (!*buf_overflow) { 04310 if (!dump_realloc_oid_to_string 04311 (objid, numids, buf, buf_len, out_len, 04312 allow_realloc, '\'')) { 04313 *buf_overflow = 1; 04314 } 04315 } 04316 } else if (tp->ranges && !tp->ranges->next 04317 && tp->ranges->low == tp->ranges->high) { 04318 /* 04319 * a fixed-length octet string 04320 */ 04321 numids = tp->ranges->low; 04322 if (numids > objidlen) 04323 goto finish_it; 04324 04325 if (!*buf_overflow) { 04326 if (!dump_realloc_oid_to_string 04327 (objid, numids, buf, buf_len, out_len, 04328 allow_realloc, '\'')) { 04329 *buf_overflow = 1; 04330 } 04331 } 04332 } else { 04333 numids = (size_t) * objid + 1; 04334 if (numids > objidlen) 04335 goto finish_it; 04336 if (numids == 1) { 04337 if (netsnmp_ds_get_boolean 04338 (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) { 04339 if (!*buf_overflow 04340 && !snmp_strcat(buf, buf_len, out_len, 04341 allow_realloc, 04342 (const u_char *) "\\")) { 04343 *buf_overflow = 1; 04344 } 04345 } 04346 if (!*buf_overflow 04347 && !snmp_strcat(buf, buf_len, out_len, 04348 allow_realloc, 04349 (const u_char *) "\"")) { 04350 *buf_overflow = 1; 04351 } 04352 if (netsnmp_ds_get_boolean 04353 (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) { 04354 if (!*buf_overflow 04355 && !snmp_strcat(buf, buf_len, out_len, 04356 allow_realloc, 04357 (const u_char *) "\\")) { 04358 *buf_overflow = 1; 04359 } 04360 } 04361 if (!*buf_overflow 04362 && !snmp_strcat(buf, buf_len, out_len, 04363 allow_realloc, 04364 (const u_char *) "\"")) { 04365 *buf_overflow = 1; 04366 } 04367 } else { 04368 if (!*buf_overflow) { 04369 struct tree * next_peer; 04370 int normal_handling = 1; 04371 04372 if (tp->next_peer) { 04373 next_peer = tp->next_peer; 04374 } 04375 04376 /* Try handling the InetAddress in the OID, in case of failure, 04377 * use the normal_handling. 04378 */ 04379 if (tp->next_peer && 04380 tp->tc_index != -1 && 04381 next_peer->tc_index != -1 && 04382 strcmp(get_tc_descriptor(tp->tc_index), "InetAddress") == 0 && 04383 strcmp(get_tc_descriptor(next_peer->tc_index), 04384 "InetAddressType") == 0 ) { 04385 04386 int ret; 04387 int addr_type = *(objid - 1); 04388 04389 ret = dump_realloc_oid_to_inetaddress(addr_type, 04390 objid + 1, numids - 1, buf, buf_len, out_len, 04391 allow_realloc, '"'); 04392 if (ret != 2) { 04393 normal_handling = 0; 04394 if (ret == 0) { 04395 *buf_overflow = 1; 04396 } 04397 04398 } 04399 } 04400 if (normal_handling && !dump_realloc_oid_to_string 04401 (objid + 1, numids - 1, buf, buf_len, out_len, 04402 allow_realloc, '"')) { 04403 *buf_overflow = 1; 04404 } 04405 } 04406 } 04407 } 04408 objid += numids; 04409 objidlen -= numids; 04410 break; 04411 04412 case TYPE_INTEGER32: 04413 case TYPE_UINTEGER: 04414 case TYPE_UNSIGNED32: 04415 case TYPE_GAUGE: 04416 case TYPE_INTEGER: 04417 if (tp->enums) { 04418 struct enum_list *ep = tp->enums; 04419 while (ep && ep->value != (int) (*objid)) { 04420 ep = ep->next; 04421 } 04422 if (ep) { 04423 if (!*buf_overflow 04424 && !snmp_strcat(buf, buf_len, out_len, 04425 allow_realloc, 04426 (const u_char *) ep->label)) { 04427 *buf_overflow = 1; 04428 } 04429 } else { 04430 sprintf(intbuf, "%lu", *objid); 04431 if (!*buf_overflow 04432 && !snmp_strcat(buf, buf_len, out_len, 04433 allow_realloc, 04434 (const u_char *) intbuf)) { 04435 *buf_overflow = 1; 04436 } 04437 } 04438 } else { 04439 sprintf(intbuf, "%lu", *objid); 04440 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04441 allow_realloc, 04442 (const u_char *) 04443 intbuf)) { 04444 *buf_overflow = 1; 04445 } 04446 } 04447 objid++; 04448 objidlen--; 04449 break; 04450 04451 case TYPE_OBJID: 04452 if (in_dices->isimplied) { 04453 numids = objidlen; 04454 } else { 04455 numids = (size_t) * objid + 1; 04456 } 04457 if (numids > objidlen) 04458 goto finish_it; 04459 if (extended_index) { 04460 if (in_dices->isimplied) { 04461 if (!*buf_overflow 04462 && !netsnmp_sprint_realloc_objid_tree(buf, buf_len, 04463 out_len, 04464 allow_realloc, 04465 buf_overflow, 04466 objid, 04467 numids)) { 04468 *buf_overflow = 1; 04469 } 04470 } else { 04471 if (!*buf_overflow 04472 && !netsnmp_sprint_realloc_objid_tree(buf, buf_len, 04473 out_len, 04474 allow_realloc, 04475 buf_overflow, 04476 objid + 1, 04477 numids - 04478 1)) { 04479 *buf_overflow = 1; 04480 } 04481 } 04482 } else { 04483 _get_realloc_symbol(objid, numids, NULL, buf, buf_len, 04484 out_len, allow_realloc, buf_overflow, 04485 NULL, NULL); 04486 } 04487 objid += (numids); 04488 objidlen -= (numids); 04489 break; 04490 04491 case TYPE_IPADDR: 04492 if (objidlen < 4) 04493 goto finish_it; 04494 sprintf(intbuf, "%lu.%lu.%lu.%lu", 04495 objid[0], objid[1], objid[2], objid[3]); 04496 objid += 4; 04497 objidlen -= 4; 04498 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04499 allow_realloc, 04500 (const u_char *) intbuf)) { 04501 *buf_overflow = 1; 04502 } 04503 break; 04504 04505 case TYPE_NETADDR:{ 04506 oid ntype = *objid++; 04507 04508 objidlen--; 04509 sprintf(intbuf, "%lu.", ntype); 04510 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04511 allow_realloc, 04512 (const u_char *) 04513 intbuf)) { 04514 *buf_overflow = 1; 04515 } 04516 04517 if (ntype == 1 && objidlen >= 4) { 04518 sprintf(intbuf, "%lu.%lu.%lu.%lu", 04519 objid[0], objid[1], objid[2], objid[3]); 04520 if (!*buf_overflow 04521 && !snmp_strcat(buf, buf_len, out_len, 04522 allow_realloc, 04523 (const u_char *) intbuf)) { 04524 *buf_overflow = 1; 04525 } 04526 objid += 4; 04527 objidlen -= 4; 04528 } else { 04529 goto finish_it; 04530 } 04531 } 04532 break; 04533 04534 case TYPE_NSAPADDRESS: 04535 default: 04536 goto finish_it; 04537 break; 04538 } 04539 04540 if (extended_index) { 04541 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04542 allow_realloc, 04543 (const u_char *) "]")) { 04544 *buf_overflow = 1; 04545 } 04546 } else { 04547 if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len, 04548 allow_realloc, 04549 (const u_char *) ".")) { 04550 *buf_overflow = 1; 04551 } 04552 } 04553 in_dices = in_dices->next; 04554 } 04555 04556 finish_it: 04557 _oid_finish_printing(objid, objidlen, 04558 buf, buf_len, out_len, 04559 allow_realloc, buf_overflow); 04560 return NULL; 04561 } 04562 04563 struct tree * 04564 get_tree(const oid * objid, size_t objidlen, struct tree *subtree) 04565 { 04566 struct tree *return_tree = NULL; 04567 04568 for (; subtree; subtree = subtree->next_peer) { 04569 if (*objid == subtree->subid) 04570 goto found; 04571 } 04572 04573 return NULL; 04574 04575 found: 04576 while (subtree->next_peer && subtree->next_peer->subid == *objid) 04577 subtree = subtree->next_peer; 04578 if (objidlen > 1) 04579 return_tree = 04580 get_tree(objid + 1, objidlen - 1, subtree->child_list); 04581 if (return_tree != NULL) 04582 return return_tree; 04583 else 04584 return subtree; 04585 } 04586 04592 void 04593 print_description(oid * objid, size_t objidlen, /* number of subidentifiers */ 04594 int width) 04595 { 04596 fprint_description(stdout, objid, objidlen, width); 04597 } 04598 04599 04608 void 04609 fprint_description(FILE * f, oid * objid, size_t objidlen, 04610 int width) 04611 { 04612 u_char *buf = NULL; 04613 size_t buf_len = 256, out_len = 0; 04614 04615 if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) { 04616 fprintf(f, "[TRUNCATED]\n"); 04617 return; 04618 } else { 04619 if (!sprint_realloc_description(&buf, &buf_len, &out_len, 1, 04620 objid, objidlen, width)) { 04621 fprintf(f, "%s [TRUNCATED]\n", buf); 04622 } else { 04623 fprintf(f, "%s\n", buf); 04624 } 04625 } 04626 04627 SNMP_FREE(buf); 04628 } 04629 04630 int 04631 snprint_description(char *buf, size_t buf_len, 04632 oid * objid, size_t objidlen, int width) 04633 { 04634 size_t out_len = 0; 04635 04636 if (sprint_realloc_description((u_char **) & buf, &buf_len, &out_len, 0, 04637 objid, objidlen, width)) { 04638 return (int) out_len; 04639 } else { 04640 return -1; 04641 } 04642 } 04643 04644 int 04645 sprint_realloc_description(u_char ** buf, size_t * buf_len, 04646 size_t * out_len, int allow_realloc, 04647 oid * objid, size_t objidlen, int width) 04648 { 04649 struct tree *tp = get_tree(objid, objidlen, tree_head); 04650 struct tree *subtree = tree_head; 04651 int pos, len; 04652 char tmpbuf[128]; 04653 const char *cp; 04654 04655 if (NULL == tp) 04656 return 0; 04657 04658 if (tp->type <= TYPE_SIMPLE_LAST) 04659 cp = " OBJECT-TYPE"; 04660 else 04661 switch (tp->type) { 04662 case TYPE_TRAPTYPE: 04663 cp = " TRAP-TYPE"; 04664 break; 04665 case TYPE_NOTIFTYPE: 04666 cp = " NOTIFICATION-TYPE"; 04667 break; 04668 case TYPE_OBJGROUP: 04669 cp = " OBJECT-GROUP"; 04670 break; 04671 case TYPE_AGENTCAP: 04672 cp = " AGENT-CAPABILITIES"; 04673 break; 04674 case TYPE_MODID: 04675 cp = " MODULE-IDENTITY"; 04676 break; 04677 case TYPE_OBJIDENTITY: 04678 cp = " OBJECT-IDENTITY"; 04679 break; 04680 case TYPE_MODCOMP: 04681 cp = " MODULE-COMPLIANCE"; 04682 break; 04683 default: 04684 sprintf(tmpbuf, " type_%d", tp->type); 04685 cp = tmpbuf; 04686 } 04687 04688 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tp->label) || 04689 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, cp) || 04690 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n")) { 04691 return 0; 04692 } 04693 if (!print_tree_node(buf, buf_len, out_len, allow_realloc, tp, width)) 04694 return 0; 04695 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "::= {")) 04696 return 0; 04697 pos = 5; 04698 while (objidlen > 1) { 04699 for (; subtree; subtree = subtree->next_peer) { 04700 if (*objid == subtree->subid) { 04701 while (subtree->next_peer && subtree->next_peer->subid == *objid) 04702 subtree = subtree->next_peer; 04703 if (strncmp(subtree->label, ANON, ANON_LEN)) { 04704 snprintf(tmpbuf, sizeof(tmpbuf), " %s(%lu)", subtree->label, subtree->subid); 04705 tmpbuf[ sizeof(tmpbuf)-1 ] = 0; 04706 } else 04707 sprintf(tmpbuf, " %lu", subtree->subid); 04708 len = strlen(tmpbuf); 04709 if (pos + len + 2 > width) { 04710 if (!snmp_cstrcat(buf, buf_len, out_len, 04711 allow_realloc, "\n ")) 04712 return 0; 04713 pos = 5; 04714 } 04715 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tmpbuf)) 04716 return 0; 04717 pos += len; 04718 objid++; 04719 objidlen--; 04720 break; 04721 } 04722 } 04723 if (subtree) 04724 subtree = subtree->child_list; 04725 else 04726 break; 04727 } 04728 while (objidlen > 1) { 04729 sprintf(tmpbuf, " %lu", *objid); 04730 len = strlen(tmpbuf); 04731 if (pos + len + 2 > width) { 04732 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n ")) 04733 return 0; 04734 pos = 5; 04735 } 04736 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tmpbuf)) 04737 return 0; 04738 pos += len; 04739 objid++; 04740 objidlen--; 04741 } 04742 sprintf(tmpbuf, " %lu }", *objid); 04743 len = strlen(tmpbuf); 04744 if (pos + len + 2 > width) { 04745 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n ")) 04746 return 0; 04747 pos = 5; 04748 } 04749 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tmpbuf)) 04750 return 0; 04751 return 1; 04752 } 04753 04754 static int 04755 print_tree_node(u_char ** buf, size_t * buf_len, 04756 size_t * out_len, int allow_realloc, 04757 struct tree *tp, int width) 04758 { 04759 const char *cp; 04760 char str[MAXTOKEN]; 04761 int i, prevmod, pos, len; 04762 04763 if (tp) { 04764 module_name(tp->modid, str); 04765 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " -- FROM\t") || 04766 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, str)) 04767 return 0; 04768 pos = 16+strlen(str); 04769 for (i = 1, prevmod = tp->modid; i < tp->number_modules; i++) { 04770 if (prevmod != tp->module_list[i]) { 04771 module_name(tp->module_list[i], str); 04772 len = strlen(str); 04773 if (pos + len + 2 > width) { 04774 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04775 ",\n --\t\t")) 04776 return 0; 04777 pos = 16; 04778 } 04779 else { 04780 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, ", ")) 04781 return 0; 04782 pos += 2; 04783 } 04784 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, str)) 04785 return 0; 04786 pos += len; 04787 } 04788 prevmod = tp->module_list[i]; 04789 } 04790 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n")) 04791 return 0; 04792 if (tp->tc_index != -1) { 04793 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04794 " -- TEXTUAL CONVENTION ") || 04795 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04796 get_tc_descriptor(tp->tc_index)) || 04797 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n")) 04798 return 0; 04799 } 04800 switch (tp->type) { 04801 case TYPE_OBJID: 04802 cp = "OBJECT IDENTIFIER"; 04803 break; 04804 case TYPE_OCTETSTR: 04805 cp = "OCTET STRING"; 04806 break; 04807 case TYPE_INTEGER: 04808 cp = "INTEGER"; 04809 break; 04810 case TYPE_NETADDR: 04811 cp = "NetworkAddress"; 04812 break; 04813 case TYPE_IPADDR: 04814 cp = "IpAddress"; 04815 break; 04816 case TYPE_COUNTER: 04817 cp = "Counter32"; 04818 break; 04819 case TYPE_GAUGE: 04820 cp = "Gauge32"; 04821 break; 04822 case TYPE_TIMETICKS: 04823 cp = "TimeTicks"; 04824 break; 04825 case TYPE_OPAQUE: 04826 cp = "Opaque"; 04827 break; 04828 case TYPE_NULL: 04829 cp = "NULL"; 04830 break; 04831 case TYPE_COUNTER64: 04832 cp = "Counter64"; 04833 break; 04834 case TYPE_BITSTRING: 04835 cp = "BITS"; 04836 break; 04837 case TYPE_NSAPADDRESS: 04838 cp = "NsapAddress"; 04839 break; 04840 case TYPE_UINTEGER: 04841 cp = "UInteger32"; 04842 break; 04843 case TYPE_UNSIGNED32: 04844 cp = "Unsigned32"; 04845 break; 04846 case TYPE_INTEGER32: 04847 cp = "Integer32"; 04848 break; 04849 default: 04850 cp = NULL; 04851 break; 04852 } 04853 #if NETSNMP_ENABLE_TESTING_CODE 04854 if (!cp && (tp->ranges || tp->enums)) { /* ranges without type ? */ 04855 sprintf(str, "?0 with %s %s ?", 04856 tp->ranges ? "Range" : "", tp->enums ? "Enum" : ""); 04857 cp = str; 04858 } 04859 #endif /* NETSNMP_ENABLE_TESTING_CODE */ 04860 if (cp) 04861 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04862 " SYNTAX\t") || 04863 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, cp)) 04864 return 0; 04865 if (tp->ranges) { 04866 struct range_list *rp = tp->ranges; 04867 int first = 1; 04868 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " (")) 04869 return 0; 04870 while (rp) { 04871 if (rp->low == rp->high) 04872 sprintf(str, "%s%d", (first ? "" : " | "), rp->low ); 04873 else 04874 sprintf(str, "%s%d..%d", (first ? "" : " | "), 04875 rp->low, rp->high); 04876 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, str)) 04877 return 0; 04878 if (first) 04879 first = 0; 04880 rp = rp->next; 04881 } 04882 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, ") ")) 04883 return 0; 04884 } 04885 if (tp->enums) { 04886 struct enum_list *ep = tp->enums; 04887 int first = 1; 04888 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " {")) 04889 return 0; 04890 pos = 16 + strlen(cp) + 2; 04891 while (ep) { 04892 if (first) 04893 first = 0; 04894 else 04895 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, ", ")) 04896 return 0; 04897 snprintf(str, sizeof(str), "%s(%d)", ep->label, ep->value); 04898 str[ sizeof(str)-1 ] = 0; 04899 len = strlen(str); 04900 if (pos + len + 2 > width) { 04901 if (!snmp_cstrcat(buf, buf_len, out_len, 04902 allow_realloc, "\n\t\t ")) 04903 return 0; 04904 pos = 18; 04905 } 04906 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, str)) 04907 return 0; 04908 pos += len + 2; 04909 ep = ep->next; 04910 } 04911 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "} ")) 04912 return 0; 04913 } 04914 if (cp) 04915 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n")) 04916 return 0; 04917 if (tp->hint) 04918 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04919 " DISPLAY-HINT\t\"") || 04920 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tp->hint) || 04921 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\"\n")) 04922 return 0; 04923 if (tp->units) 04924 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04925 " UNITS\t\t\"") || 04926 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tp->units) || 04927 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\"\n")) 04928 return 0; 04929 switch (tp->access) { 04930 case MIB_ACCESS_READONLY: 04931 cp = "read-only"; 04932 break; 04933 case MIB_ACCESS_READWRITE: 04934 cp = "read-write"; 04935 break; 04936 case MIB_ACCESS_WRITEONLY: 04937 cp = "write-only"; 04938 break; 04939 case MIB_ACCESS_NOACCESS: 04940 cp = "not-accessible"; 04941 break; 04942 case MIB_ACCESS_NOTIFY: 04943 cp = "accessible-for-notify"; 04944 break; 04945 case MIB_ACCESS_CREATE: 04946 cp = "read-create"; 04947 break; 04948 case 0: 04949 cp = NULL; 04950 break; 04951 default: 04952 sprintf(str, "access_%d", tp->access); 04953 cp = str; 04954 } 04955 if (cp) 04956 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04957 " MAX-ACCESS\t") || 04958 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, cp) || 04959 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n")) 04960 return 0; 04961 switch (tp->status) { 04962 case MIB_STATUS_MANDATORY: 04963 cp = "mandatory"; 04964 break; 04965 case MIB_STATUS_OPTIONAL: 04966 cp = "optional"; 04967 break; 04968 case MIB_STATUS_OBSOLETE: 04969 cp = "obsolete"; 04970 break; 04971 case MIB_STATUS_DEPRECATED: 04972 cp = "deprecated"; 04973 break; 04974 case MIB_STATUS_CURRENT: 04975 cp = "current"; 04976 break; 04977 case 0: 04978 cp = NULL; 04979 break; 04980 default: 04981 sprintf(str, "status_%d", tp->status); 04982 cp = str; 04983 } 04984 #if NETSNMP_ENABLE_TESTING_CODE 04985 if (!cp && (tp->indexes)) { /* index without status ? */ 04986 sprintf(str, "?0 with %s ?", tp->indexes ? "Index" : ""); 04987 cp = str; 04988 } 04989 #endif /* NETSNMP_ENABLE_TESTING_CODE */ 04990 if (cp) 04991 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04992 " STATUS\t") || 04993 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, cp) || 04994 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n")) 04995 return 0; 04996 if (tp->augments) 04997 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 04998 " AUGMENTS\t{ ") || 04999 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tp->augments) || 05000 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " }\n")) 05001 return 0; 05002 if (tp->indexes) { 05003 struct index_list *ip = tp->indexes; 05004 int first = 1; 05005 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 05006 " INDEX\t\t{ ")) 05007 return 0; 05008 pos = 16 + 2; 05009 while (ip) { 05010 if (first) 05011 first = 0; 05012 else 05013 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, ", ")) 05014 return 0; 05015 snprintf(str, sizeof(str), "%s%s", 05016 ip->isimplied ? "IMPLIED " : "", 05017 ip->ilabel); 05018 str[ sizeof(str)-1 ] = 0; 05019 len = strlen(str); 05020 if (pos + len + 2 > width) { 05021 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\n\t\t ")) 05022 return 0; 05023 pos = 16 + 2; 05024 } 05025 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, str)) 05026 return 0; 05027 pos += len + 2; 05028 ip = ip->next; 05029 } 05030 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " }\n")) 05031 return 0; 05032 } 05033 if (tp->varbinds) { 05034 struct varbind_list *vp = tp->varbinds; 05035 int first = 1; 05036 05037 if (tp->type == TYPE_TRAPTYPE) { 05038 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 05039 " VARIABLES\t{ ")) 05040 return 0; 05041 } else { 05042 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 05043 " OBJECTS\t{ ")) 05044 return 0; 05045 } 05046 pos = 16 + 2; 05047 while (vp) { 05048 if (first) 05049 first = 0; 05050 else 05051 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, ", ")) 05052 return 0; 05053 snprintf(str, sizeof(str), "%s", vp->vblabel); 05054 str[ sizeof(str)-1 ] = 0; 05055 len = strlen(str); 05056 if (pos + len + 2 > width) { 05057 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 05058 "\n\t\t ")) 05059 return 0; 05060 pos = 16 + 2; 05061 } 05062 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, str)) 05063 return 0; 05064 pos += len + 2; 05065 vp = vp->next; 05066 } 05067 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " }\n")) 05068 return 0; 05069 } 05070 if (tp->description) 05071 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 05072 " DESCRIPTION\t\"") || 05073 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tp->description) || 05074 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "\"\n")) 05075 return 0; 05076 if (tp->defaultValue) 05077 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, 05078 " DEFVAL\t{ ") || 05079 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, tp->defaultValue) || 05080 !snmp_cstrcat(buf, buf_len, out_len, allow_realloc, " }\n")) 05081 return 0; 05082 } else 05083 if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, "No description\n")) 05084 return 0; 05085 return 1; 05086 } 05087 05088 int 05089 get_module_node(const char *fname, 05090 const char *module, oid * objid, size_t * objidlen) 05091 { 05092 int modid, rc = 0; 05093 struct tree *tp; 05094 char *name, *cp; 05095 05096 if (!strcmp(module, "ANY")) 05097 modid = -1; 05098 else { 05099 netsnmp_read_module(module); 05100 modid = which_module(module); 05101 if (modid == -1) 05102 return 0; 05103 } 05104 05105 /* 05106 * Isolate the first component of the name ... 05107 */ 05108 name = strdup(fname); 05109 cp = strchr(name, '.'); 05110 if (cp != NULL) { 05111 *cp = '\0'; 05112 cp++; 05113 } 05114 /* 05115 * ... and locate it in the tree. 05116 */ 05117 tp = find_tree_node(name, modid); 05118 if (tp) { 05119 size_t maxlen = *objidlen; 05120 05121 /* 05122 * Set the first element of the object ID 05123 */ 05124 if (node_to_oid(tp, objid, objidlen)) { 05125 rc = 1; 05126 05127 /* 05128 * If the name requested was more than one element, 05129 * tag on the rest of the components 05130 */ 05131 if (cp != NULL) 05132 rc = _add_strings_to_oid(tp, cp, objid, objidlen, maxlen); 05133 } 05134 } 05135 05136 SNMP_FREE(name); 05137 return (rc); 05138 } 05139 05140 05158 static int 05159 node_to_oid(struct tree *tp, oid * objid, size_t * objidlen) 05160 { 05161 int numids, lenids; 05162 oid *op; 05163 05164 if (!tp || !objid || !objidlen) 05165 return 0; 05166 05167 lenids = (int) *objidlen; 05168 op = objid + lenids; /* points after the last element */ 05169 05170 for (numids = 0; tp; tp = tp->parent, numids++) { 05171 if (numids >= lenids) 05172 continue; 05173 --op; 05174 *op = tp->subid; 05175 } 05176 05177 *objidlen = (size_t) numids; 05178 if (numids > lenids) { 05179 return 0; 05180 } 05181 05182 if (numids < lenids) 05183 memmove(objid, op, numids * sizeof(oid)); 05184 05185 return (numids); 05186 } 05187 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 05188 05189 /* 05190 * Replace \x with x stop at eos_marker 05191 * return NULL if eos_marker not found 05192 */ 05193 static char *_apply_escapes(char *src, char eos_marker) 05194 { 05195 char *dst; 05196 int backslash = 0; 05197 05198 dst = src; 05199 while (*src) { 05200 if (backslash) { 05201 backslash = 0; 05202 *dst++ = *src; 05203 } else { 05204 if (eos_marker == *src) break; 05205 if ('\\' == *src) { 05206 backslash = 1; 05207 } else { 05208 *dst++ = *src; 05209 } 05210 } 05211 src++; 05212 } 05213 if (!*src) { 05214 /* never found eos_marker */ 05215 return NULL; 05216 } else { 05217 *dst = 0; 05218 return src; 05219 } 05220 } 05221 05222 static int 05223 #ifndef NETSNMP_DISABLE_MIB_LOADING 05224 _add_strings_to_oid(struct tree *tp, char *cp, 05225 oid * objid, size_t * objidlen, size_t maxlen) 05226 #else 05227 _add_strings_to_oid(void *tp, char *cp, 05228 oid * objid, size_t * objidlen, size_t maxlen) 05229 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 05230 { 05231 oid subid; 05232 int len_index = 1000000; 05233 #ifndef NETSNMP_DISABLE_MIB_LOADING 05234 struct tree *tp2 = NULL; 05235 struct index_list *in_dices = NULL; 05236 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 05237 char *fcp, *ecp, *cp2 = NULL; 05238 char doingquote; 05239 int len = -1, pos = -1; 05240 #ifndef NETSNMP_DISABLE_MIB_LOADING 05241 int check = 05242 !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_CHECK_RANGE); 05243 int do_hint = !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NO_DISPLAY_HINT); 05244 05245 while (cp && tp && tp->child_list) { 05246 fcp = cp; 05247 tp2 = tp->child_list; 05248 /* 05249 * Isolate the next entry 05250 */ 05251 cp2 = strchr(cp, '.'); 05252 if (cp2) 05253 *cp2++ = '\0'; 05254 05255 /* 05256 * Search for the appropriate child 05257 */ 05258 if (isdigit(*cp)) { 05259 subid = strtoul(cp, &ecp, 0); 05260 if (*ecp) 05261 goto bad_id; 05262 while (tp2 && tp2->subid != subid) 05263 tp2 = tp2->next_peer; 05264 } else { 05265 while (tp2 && strcmp(tp2->label, fcp)) 05266 tp2 = tp2->next_peer; 05267 if (!tp2) 05268 goto bad_id; 05269 subid = tp2->subid; 05270 } 05271 if (*objidlen >= maxlen) 05272 goto bad_id; 05273 while (tp2 && tp2->next_peer && tp2->next_peer->subid == subid) 05274 tp2 = tp2->next_peer; 05275 objid[*objidlen] = subid; 05276 (*objidlen)++; 05277 05278 cp = cp2; 05279 if (!tp2) 05280 break; 05281 tp = tp2; 05282 } 05283 05284 if (tp && !tp->child_list) { 05285 if ((tp2 = tp->parent)) { 05286 if (tp2->indexes) 05287 in_dices = tp2->indexes; 05288 else if (tp2->augments) { 05289 tp2 = find_tree_node(tp2->augments, -1); 05290 if (tp2) 05291 in_dices = tp2->indexes; 05292 } 05293 } 05294 tp = NULL; 05295 } 05296 05297 while (cp && in_dices) { 05298 fcp = cp; 05299 05300 tp = find_tree_node(in_dices->ilabel, -1); 05301 if (!tp) 05302 break; 05303 switch (tp->type) { 05304 case TYPE_INTEGER: 05305 case TYPE_INTEGER32: 05306 case TYPE_UINTEGER: 05307 case TYPE_UNSIGNED32: 05308 case TYPE_TIMETICKS: 05309 /* 05310 * Isolate the next entry 05311 */ 05312 cp2 = strchr(cp, '.'); 05313 if (cp2) 05314 *cp2++ = '\0'; 05315 if (isdigit(*cp)) { 05316 subid = strtoul(cp, &ecp, 0); 05317 if (*ecp) 05318 goto bad_id; 05319 } else { 05320 if (tp->enums) { 05321 struct enum_list *ep = tp->enums; 05322 while (ep && strcmp(ep->label, cp)) 05323 ep = ep->next; 05324 if (!ep) 05325 goto bad_id; 05326 subid = ep->value; 05327 } else 05328 goto bad_id; 05329 } 05330 if (check && tp->ranges) { 05331 struct range_list *rp = tp->ranges; 05332 int ok = 0; 05333 if (tp->type == TYPE_INTEGER || 05334 tp->type == TYPE_INTEGER32) { 05335 while (!ok && rp) { 05336 if ((rp->low <= (int) subid) 05337 && ((int) subid <= rp->high)) 05338 ok = 1; 05339 else 05340 rp = rp->next; 05341 } 05342 } else { /* check unsigned range */ 05343 while (!ok && rp) { 05344 if (((unsigned int)rp->low <= subid) 05345 && (subid <= (unsigned int)rp->high)) 05346 ok = 1; 05347 else 05348 rp = rp->next; 05349 } 05350 } 05351 if (!ok) 05352 goto bad_id; 05353 } 05354 if (*objidlen >= maxlen) 05355 goto bad_id; 05356 objid[*objidlen] = subid; 05357 (*objidlen)++; 05358 break; 05359 case TYPE_IPADDR: 05360 if (*objidlen + 4 > maxlen) 05361 goto bad_id; 05362 for (subid = 0; cp && subid < 4; subid++) { 05363 fcp = cp; 05364 cp2 = strchr(cp, '.'); 05365 if (cp2) 05366 *cp2++ = 0; 05367 objid[*objidlen] = strtoul(cp, &ecp, 0); 05368 if (*ecp) 05369 goto bad_id; 05370 if (check && objid[*objidlen] > 255) 05371 goto bad_id; 05372 (*objidlen)++; 05373 cp = cp2; 05374 } 05375 break; 05376 case TYPE_OCTETSTR: 05377 if (tp->ranges && !tp->ranges->next 05378 && tp->ranges->low == tp->ranges->high) 05379 len = tp->ranges->low; 05380 else 05381 len = -1; 05382 pos = 0; 05383 if (*cp == '"' || *cp == '\'') { 05384 doingquote = *cp++; 05385 /* 05386 * insert length if requested 05387 */ 05388 if (!in_dices->isimplied && len == -1) { 05389 if (doingquote == '\'') { 05390 snmp_set_detail 05391 ("'-quote is for fixed length strings"); 05392 return 0; 05393 } 05394 if (*objidlen >= maxlen) 05395 goto bad_id; 05396 len_index = *objidlen; 05397 (*objidlen)++; 05398 } else if (doingquote == '"') { 05399 snmp_set_detail 05400 ("\"-quote is for variable length strings"); 05401 return 0; 05402 } 05403 05404 cp2 = _apply_escapes(cp, doingquote); 05405 if (!cp2) goto bad_id; 05406 else { 05407 unsigned char *new_val; 05408 int new_val_len; 05409 int parsed_hint = 0; 05410 const char *parsed_value; 05411 05412 if (do_hint && tp->hint) { 05413 parsed_value = parse_octet_hint(tp->hint, cp, 05414 &new_val, &new_val_len); 05415 parsed_hint = parsed_value == NULL; 05416 } 05417 if (parsed_hint) { 05418 int i; 05419 for (i = 0; i < new_val_len; i++) { 05420 if (*objidlen >= maxlen) goto bad_id; 05421 objid[ *objidlen ] = new_val[i]; 05422 (*objidlen)++; 05423 pos++; 05424 } 05425 SNMP_FREE(new_val); 05426 } else { 05427 while(*cp) { 05428 if (*objidlen >= maxlen) goto bad_id; 05429 objid[ *objidlen ] = *cp++; 05430 (*objidlen)++; 05431 pos++; 05432 } 05433 } 05434 } 05435 05436 cp2++; 05437 if (!*cp2) 05438 cp2 = NULL; 05439 else if (*cp2 != '.') 05440 goto bad_id; 05441 else 05442 cp2++; 05443 if (check) { 05444 if (len == -1) { 05445 struct range_list *rp = tp->ranges; 05446 int ok = 0; 05447 while (rp && !ok) 05448 if (rp->low <= pos && pos <= rp->high) 05449 ok = 1; 05450 else 05451 rp = rp->next; 05452 if (!ok) 05453 goto bad_id; 05454 if (!in_dices->isimplied) 05455 objid[len_index] = pos; 05456 } else if (pos != len) 05457 goto bad_id; 05458 } 05459 else if (len == -1 && !in_dices->isimplied) 05460 objid[len_index] = pos; 05461 } else { 05462 if (!in_dices->isimplied && len == -1) { 05463 fcp = cp; 05464 cp2 = strchr(cp, '.'); 05465 if (cp2) 05466 *cp2++ = 0; 05467 len = strtoul(cp, &ecp, 0); 05468 if (*ecp) 05469 goto bad_id; 05470 if (*objidlen + len + 1 >= maxlen) 05471 goto bad_id; 05472 objid[*objidlen] = len; 05473 (*objidlen)++; 05474 cp = cp2; 05475 } 05476 while (len && cp) { 05477 fcp = cp; 05478 cp2 = strchr(cp, '.'); 05479 if (cp2) 05480 *cp2++ = 0; 05481 objid[*objidlen] = strtoul(cp, &ecp, 0); 05482 if (*ecp) 05483 goto bad_id; 05484 if (check && objid[*objidlen] > 255) 05485 goto bad_id; 05486 (*objidlen)++; 05487 len--; 05488 cp = cp2; 05489 } 05490 } 05491 break; 05492 case TYPE_OBJID: 05493 in_dices = NULL; 05494 cp2 = cp; 05495 break; 05496 case TYPE_NETADDR: 05497 fcp = cp; 05498 cp2 = strchr(cp, '.'); 05499 if (cp2) 05500 *cp2++ = 0; 05501 subid = strtoul(cp, &ecp, 0); 05502 if (*ecp) 05503 goto bad_id; 05504 if (*objidlen + 1 >= maxlen) 05505 goto bad_id; 05506 objid[*objidlen] = subid; 05507 (*objidlen)++; 05508 cp = cp2; 05509 if (subid == 1) { 05510 for (len = 0; cp && len < 4; len++) { 05511 fcp = cp; 05512 cp2 = strchr(cp, '.'); 05513 if (cp2) 05514 *cp2++ = 0; 05515 subid = strtoul(cp, &ecp, 0); 05516 if (*ecp) 05517 goto bad_id; 05518 if (*objidlen + 1 >= maxlen) 05519 goto bad_id; 05520 if (check && subid > 255) 05521 goto bad_id; 05522 objid[*objidlen] = subid; 05523 (*objidlen)++; 05524 cp = cp2; 05525 } 05526 } 05527 else { 05528 in_dices = NULL; 05529 } 05530 break; 05531 default: 05532 snmp_log(LOG_ERR, "Unexpected index type: %d %s %s\n", 05533 tp->type, in_dices->ilabel, cp); 05534 in_dices = NULL; 05535 cp2 = cp; 05536 break; 05537 } 05538 cp = cp2; 05539 if (in_dices) 05540 in_dices = in_dices->next; 05541 } 05542 05543 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 05544 while (cp) { 05545 fcp = cp; 05546 switch (*cp) { 05547 case '0': 05548 case '1': 05549 case '2': 05550 case '3': 05551 case '4': 05552 case '5': 05553 case '6': 05554 case '7': 05555 case '8': 05556 case '9': 05557 cp2 = strchr(cp, '.'); 05558 if (cp2) 05559 *cp2++ = 0; 05560 subid = strtoul(cp, &ecp, 0); 05561 if (*ecp) 05562 goto bad_id; 05563 if (*objidlen >= maxlen) 05564 goto bad_id; 05565 objid[*objidlen] = subid; 05566 (*objidlen)++; 05567 break; 05568 case '"': 05569 case '\'': 05570 doingquote = *cp++; 05571 /* 05572 * insert length if requested 05573 */ 05574 if (doingquote == '"') { 05575 if (*objidlen >= maxlen) 05576 goto bad_id; 05577 objid[*objidlen] = len = strchr(cp, doingquote) - cp; 05578 (*objidlen)++; 05579 } 05580 05581 if (!cp) 05582 goto bad_id; 05583 while (*cp && *cp != doingquote) { 05584 if (*objidlen >= maxlen) 05585 goto bad_id; 05586 objid[*objidlen] = *cp++; 05587 (*objidlen)++; 05588 } 05589 cp2 = cp + 1; 05590 if (!*cp2) 05591 cp2 = NULL; 05592 else if (*cp2 == '.') 05593 cp2++; 05594 else 05595 goto bad_id; 05596 break; 05597 default: 05598 goto bad_id; 05599 } 05600 cp = cp2; 05601 } 05602 return 1; 05603 05604 bad_id: 05605 { 05606 char buf[256]; 05607 #ifndef NETSNMP_DISABLE_MIB_LOADING 05608 if (in_dices) 05609 snprintf(buf, sizeof(buf), "Index out of range: %s (%s)", 05610 fcp, in_dices->ilabel); 05611 else if (tp) 05612 snprintf(buf, sizeof(buf), "Sub-id not found: %s -> %s", tp->label, fcp); 05613 else 05614 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 05615 snprintf(buf, sizeof(buf), "%s", fcp); 05616 buf[ sizeof(buf)-1 ] = 0; 05617 05618 snmp_set_detail(buf); 05619 } 05620 return 0; 05621 } 05622 05623 05624 #ifndef NETSNMP_DISABLE_MIB_LOADING 05625 05628 int 05629 get_wild_node(const char *name, oid * objid, size_t * objidlen) 05630 { 05631 struct tree *tp = find_best_tree_node(name, tree_head, NULL); 05632 if (!tp) 05633 return 0; 05634 return get_node(tp->label, objid, objidlen); 05635 } 05636 05637 int 05638 get_node(const char *name, oid * objid, size_t * objidlen) 05639 { 05640 const char *cp; 05641 char ch; 05642 int res; 05643 05644 cp = name; 05645 while ((ch = *cp)) 05646 if (('0' <= ch && ch <= '9') 05647 || ('a' <= ch && ch <= 'z') 05648 || ('A' <= ch && ch <= 'Z') 05649 || ch == '-') 05650 cp++; 05651 else 05652 break; 05653 if (ch != ':') 05654 if (*name == '.') 05655 res = get_module_node(name + 1, "ANY", objid, objidlen); 05656 else 05657 res = get_module_node(name, "ANY", objid, objidlen); 05658 else { 05659 char *module; 05660 /* 05661 * requested name is of the form 05662 * "module:subidentifier" 05663 */ 05664 module = (char *) malloc((size_t) (cp - name + 1)); 05665 if (!module) 05666 return SNMPERR_GENERR; 05667 memcpy(module, name, (size_t) (cp - name)); 05668 module[cp - name] = 0; 05669 cp++; /* cp now point to the subidentifier */ 05670 if (*cp == ':') 05671 cp++; 05672 05673 /* 05674 * 'cp' and 'name' *do* go that way round! 05675 */ 05676 res = get_module_node(cp, module, objid, objidlen); 05677 SNMP_FREE(module); 05678 } 05679 if (res == 0) { 05680 SET_SNMP_ERROR(SNMPERR_UNKNOWN_OBJID); 05681 } 05682 05683 return res; 05684 } 05685 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 05686 05687 #ifdef testing 05688 05689 main(int argc, char *argv[]) 05690 { 05691 oid objid[MAX_OID_LEN]; 05692 int objidlen = MAX_OID_LEN; 05693 int count; 05694 netsnmp_variable_list variable; 05695 05696 netsnmp_init_mib(); 05697 if (argc < 2) 05698 print_subtree(stdout, tree_head, 0); 05699 variable.type = ASN_INTEGER; 05700 variable.val.integer = 3; 05701 variable.val_len = 4; 05702 for (argc--; argc; argc--, argv++) { 05703 objidlen = MAX_OID_LEN; 05704 printf("read_objid(%s) = %d\n", 05705 argv[1], read_objid(argv[1], objid, &objidlen)); 05706 for (count = 0; count < objidlen; count++) 05707 printf("%d.", objid[count]); 05708 printf("\n"); 05709 print_variable(objid, objidlen, &variable); 05710 } 05711 } 05712 05713 #endif /* testing */ 05714 05715 #ifndef NETSNMP_DISABLE_MIB_LOADING 05716 /* 05717 * initialize: no peers included in the report. 05718 */ 05719 void 05720 clear_tree_flags(register struct tree *tp) 05721 { 05722 for (; tp; tp = tp->next_peer) { 05723 tp->reported = 0; 05724 if (tp->child_list) 05725 clear_tree_flags(tp->child_list); 05726 /*RECURSE*/} 05727 } 05728 05729 /* 05730 * Update: 1998-07-17 <jhy@gsu.edu> 05731 * Added print_oid_report* functions. 05732 */ 05733 static int print_subtree_oid_report_labeledoid = 0; 05734 static int print_subtree_oid_report_oid = 0; 05735 static int print_subtree_oid_report_symbolic = 0; 05736 static int print_subtree_oid_report_mibchildoid = 0; 05737 static int print_subtree_oid_report_suffix = 0; 05738 05739 /* 05740 * These methods recurse. 05741 */ 05742 static void print_parent_labeledoid(FILE *, struct tree *); 05743 static void print_parent_oid(FILE *, struct tree *); 05744 static void print_parent_mibchildoid(FILE *, struct tree *); 05745 static void print_parent_label(FILE *, struct tree *); 05746 static void print_subtree_oid_report(FILE *, struct tree *, int); 05747 05748 05749 void 05750 print_oid_report(FILE * fp) 05751 { 05752 struct tree *tp; 05753 clear_tree_flags(tree_head); 05754 for (tp = tree_head; tp; tp = tp->next_peer) 05755 print_subtree_oid_report(fp, tp, 0); 05756 } 05757 05758 void 05759 print_oid_report_enable_labeledoid(void) 05760 { 05761 print_subtree_oid_report_labeledoid = 1; 05762 } 05763 05764 void 05765 print_oid_report_enable_oid(void) 05766 { 05767 print_subtree_oid_report_oid = 1; 05768 } 05769 05770 void 05771 print_oid_report_enable_suffix(void) 05772 { 05773 print_subtree_oid_report_suffix = 1; 05774 } 05775 05776 void 05777 print_oid_report_enable_symbolic(void) 05778 { 05779 print_subtree_oid_report_symbolic = 1; 05780 } 05781 05782 void 05783 print_oid_report_enable_mibchildoid(void) 05784 { 05785 print_subtree_oid_report_mibchildoid = 1; 05786 } 05787 05788 /* 05789 * helper methods for print_subtree_oid_report() 05790 * each one traverses back up the node tree 05791 * until there is no parent. Then, the label combination 05792 * is output, such that the parent is displayed first. 05793 * 05794 * Warning: these methods are all recursive. 05795 */ 05796 05797 static void 05798 print_parent_labeledoid(FILE * f, struct tree *tp) 05799 { 05800 if (tp) { 05801 if (tp->parent) { 05802 print_parent_labeledoid(f, tp->parent); 05803 /*RECURSE*/} 05804 fprintf(f, ".%s(%lu)", tp->label, tp->subid); 05805 } 05806 } 05807 05808 static void 05809 print_parent_oid(FILE * f, struct tree *tp) 05810 { 05811 if (tp) { 05812 if (tp->parent) { 05813 print_parent_oid(f, tp->parent); 05814 /*RECURSE*/} 05815 fprintf(f, ".%lu", tp->subid); 05816 } 05817 } 05818 05819 05820 static void print_parent_mibchildoid(FILE * f, struct tree *tp) 05821 { 05822 static struct tree *temp; 05823 unsigned long elems[100]; 05824 int elem_cnt = 0; 05825 int i = 0; 05826 temp = tp; 05827 if (temp) { 05828 while (temp->parent) { 05829 elems[elem_cnt++] = temp->subid; 05830 temp = temp->parent; 05831 } 05832 elems[elem_cnt++] = temp->subid; 05833 } 05834 for (i = elem_cnt - 1; i >= 0; i--) { 05835 if (i == elem_cnt - 1) { 05836 fprintf(f, "%lu", elems[i]); 05837 } else { 05838 fprintf(f, ".%lu", elems[i]); 05839 } 05840 } 05841 } 05842 05843 static void 05844 print_parent_label(FILE * f, struct tree *tp) 05845 { 05846 if (tp) { 05847 if (tp->parent) { 05848 print_parent_label(f, tp->parent); 05849 /*RECURSE*/} 05850 fprintf(f, ".%s", tp->label); 05851 } 05852 } 05853 05865 static void 05866 print_subtree_oid_report(FILE * f, struct tree *tree, int count) 05867 { 05868 struct tree *tp; 05869 05870 count++; 05871 05872 /* 05873 * sanity check 05874 */ 05875 if (!tree) { 05876 return; 05877 } 05878 05879 /* 05880 * find the not reported peer with the lowest sub-identifier. 05881 * if no more, break the loop and cleanup. 05882 * set "reported" flag, and create report for this peer. 05883 * recurse using the children of this peer, if any. 05884 */ 05885 while (1) { 05886 register struct tree *ntp; 05887 05888 tp = NULL; 05889 for (ntp = tree->child_list; ntp; ntp = ntp->next_peer) { 05890 if (ntp->reported) 05891 continue; 05892 05893 if (!tp || (tp->subid > ntp->subid)) 05894 tp = ntp; 05895 } 05896 if (!tp) 05897 break; 05898 05899 tp->reported = 1; 05900 05901 if (print_subtree_oid_report_labeledoid) { 05902 print_parent_labeledoid(f, tp); 05903 fprintf(f, "\n"); 05904 } 05905 if (print_subtree_oid_report_oid) { 05906 print_parent_oid(f, tp); 05907 fprintf(f, "\n"); 05908 } 05909 if (print_subtree_oid_report_symbolic) { 05910 print_parent_label(f, tp); 05911 fprintf(f, "\n"); 05912 } 05913 if (print_subtree_oid_report_mibchildoid) { 05914 fprintf(f, "\"%s\"\t", tp->label); 05915 fprintf(f, "\t\t\""); 05916 print_parent_mibchildoid(f, tp); 05917 fprintf(f, "\"\n"); 05918 } 05919 if (print_subtree_oid_report_suffix) { 05920 int i; 05921 for (i = 0; i < count; i++) 05922 fprintf(f, " "); 05923 fprintf(f, "%s(%ld) type=%d", tp->label, tp->subid, tp->type); 05924 if (tp->tc_index != -1) 05925 fprintf(f, " tc=%d", tp->tc_index); 05926 if (tp->hint) 05927 fprintf(f, " hint=%s", tp->hint); 05928 if (tp->units) 05929 fprintf(f, " units=%s", tp->units); 05930 05931 fprintf(f, "\n"); 05932 } 05933 print_subtree_oid_report(f, tp, count); 05934 /*RECURSE*/} 05935 } 05936 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 05937 05938 05951 char * 05952 uptime_string(u_long timeticks, char *buf) 05953 { 05954 return uptime_string_n( timeticks, buf, 40); 05955 } 05956 05957 char * 05958 uptime_string_n(u_long timeticks, char *buf, size_t buflen) 05959 { 05960 uptimeString(timeticks, buf, buflen); 05961 #ifdef CMU_COMPATIBLE 05962 { 05963 char *cp = strrchr(buf, '.'); 05964 if (cp) 05965 *cp = '\0'; 05966 } 05967 #endif 05968 return buf; 05969 } 05970 05986 oid * 05987 snmp_parse_oid(const char *argv, oid * root, size_t * rootlen) 05988 { 05989 size_t savlen = *rootlen; 05990 static size_t tmpbuf_len = 0; 05991 static char *tmpbuf; 05992 const char *suffix, *prefix; 05993 05994 suffix = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 05995 NETSNMP_DS_LIB_OIDSUFFIX); 05996 prefix = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 05997 NETSNMP_DS_LIB_OIDPREFIX); 05998 if ((suffix && suffix[0]) || (prefix && prefix[0])) { 05999 if (!suffix) 06000 suffix = ""; 06001 if (!prefix) 06002 prefix = ""; 06003 if ((strlen(suffix) + strlen(prefix) + strlen(argv) + 2) > tmpbuf_len) { 06004 tmpbuf_len = strlen(suffix) + strlen(argv) + strlen(prefix) + 2; 06005 tmpbuf = (char *)realloc(tmpbuf, tmpbuf_len); 06006 } 06007 snprintf(tmpbuf, tmpbuf_len, "%s%s%s%s", prefix, argv, 06008 ((suffix[0] == '.' || suffix[0] == '\0') ? "" : "."), 06009 suffix); 06010 argv = tmpbuf; 06011 DEBUGMSGTL(("snmp_parse_oid","Parsing: %s\n",argv)); 06012 } 06013 06014 #ifndef NETSNMP_DISABLE_MIB_LOADING 06015 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_RANDOM_ACCESS) 06016 || strchr(argv, ':')) { 06017 if (get_node(argv, root, rootlen)) { 06018 return root; 06019 } 06020 } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_REGEX_ACCESS)) { 06021 clear_tree_flags(tree_head); 06022 if (get_wild_node(argv, root, rootlen)) { 06023 return root; 06024 } 06025 } else { 06026 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 06027 if (read_objid(argv, root, rootlen)) { 06028 return root; 06029 } 06030 #ifndef NETSNMP_DISABLE_MIB_LOADING 06031 *rootlen = savlen; 06032 if (get_node(argv, root, rootlen)) { 06033 return root; 06034 } 06035 *rootlen = savlen; 06036 DEBUGMSGTL(("parse_oid", "wildly parsing\n")); 06037 clear_tree_flags(tree_head); 06038 if (get_wild_node(argv, root, rootlen)) { 06039 return root; 06040 } 06041 } 06042 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 06043 return NULL; 06044 } 06045 06046 #ifndef NETSNMP_DISABLE_MIB_LOADING 06047 /* 06048 * Use DISPLAY-HINT to parse a value into an octet string. 06049 * 06050 * note that "1d1d", "11" could have come from an octet string that 06051 * looked like { 1, 1 } or an octet string that looked like { 11 } 06052 * because of this, it's doubtful that anyone would use such a display 06053 * string. Therefore, the parser ignores this case. 06054 */ 06055 06056 struct parse_hints { 06057 int length; 06058 int repeat; 06059 int format; 06060 int separator; 06061 int terminator; 06062 unsigned char *result; 06063 int result_max; 06064 int result_len; 06065 }; 06066 06067 static void parse_hints_reset(struct parse_hints *ph) 06068 { 06069 ph->length = 0; 06070 ph->repeat = 0; 06071 ph->format = 0; 06072 ph->separator = 0; 06073 ph->terminator = 0; 06074 } 06075 06076 static void parse_hints_ctor(struct parse_hints *ph) 06077 { 06078 parse_hints_reset(ph); 06079 ph->result = NULL; 06080 ph->result_max = 0; 06081 ph->result_len = 0; 06082 } 06083 06084 static int parse_hints_add_result_octet(struct parse_hints *ph, unsigned char octet) 06085 { 06086 if (!(ph->result_len < ph->result_max)) { 06087 ph->result_max = ph->result_len + 32; 06088 if (!ph->result) { 06089 ph->result = (unsigned char *)malloc(ph->result_max); 06090 } else { 06091 ph->result = (unsigned char *)realloc(ph->result, ph->result_max); 06092 } 06093 } 06094 06095 if (!ph->result) { 06096 return 0; /* failed */ 06097 } 06098 06099 ph->result[ph->result_len++] = octet; 06100 return 1; /* success */ 06101 } 06102 06103 static int parse_hints_parse(struct parse_hints *ph, const char **v_in_out) 06104 { 06105 const char *v = *v_in_out; 06106 char *nv; 06107 int base; 06108 int repeats = 0; 06109 int repeat_fixup = ph->result_len; 06110 06111 if (ph->repeat) { 06112 if (!parse_hints_add_result_octet(ph, 0)) { 06113 return 0; 06114 } 06115 } 06116 do { 06117 base = 0; 06118 switch (ph->format) { 06119 case 'x': base += 6; /* fall through */ 06120 case 'd': base += 2; /* fall through */ 06121 case 'o': base += 8; /* fall through */ 06122 { 06123 int i; 06124 unsigned long number = strtol(v, &nv, base); 06125 if (nv == v) return 0; 06126 v = nv; 06127 for (i = 0; i < ph->length; i++) { 06128 int shift = 8 * (ph->length - 1 - i); 06129 if (!parse_hints_add_result_octet(ph, (u_char)(number >> shift) )) { 06130 return 0; /* failed */ 06131 } 06132 } 06133 } 06134 break; 06135 06136 case 'a': 06137 { 06138 int i; 06139 06140 for (i = 0; i < ph->length && *v; i++) { 06141 if (!parse_hints_add_result_octet(ph, *v++)) { 06142 return 0; /* failed */ 06143 } 06144 } 06145 } 06146 break; 06147 } 06148 06149 repeats++; 06150 06151 if (ph->separator && *v) { 06152 if (*v == ph->separator) { 06153 v++; 06154 } else { 06155 return 0; /* failed */ 06156 } 06157 } 06158 06159 if (ph->terminator) { 06160 if (*v == ph->terminator) { 06161 v++; 06162 break; 06163 } 06164 } 06165 } while (ph->repeat && *v); 06166 if (ph->repeat) { 06167 ph->result[repeat_fixup] = repeats; 06168 } 06169 06170 *v_in_out = v; 06171 return 1; 06172 } 06173 06174 static void parse_hints_length_add_digit(struct parse_hints *ph, int digit) 06175 { 06176 ph->length *= 10; 06177 ph->length += digit - '0'; 06178 } 06179 06180 const char *parse_octet_hint(const char *hint, const char *value, unsigned char **new_val, int *new_val_len) 06181 { 06182 const char *h = hint; 06183 const char *v = value; 06184 struct parse_hints ph; 06185 int retval = 1; 06186 /* See RFC 1443 */ 06187 enum { 06188 HINT_1_2, 06189 HINT_2_3, 06190 HINT_1_2_4, 06191 HINT_1_2_5 06192 } state = HINT_1_2; 06193 06194 parse_hints_ctor(&ph); 06195 while (*h && *v && retval) { 06196 switch (state) { 06197 case HINT_1_2: 06198 if ('*' == *h) { 06199 ph.repeat = 1; 06200 state = HINT_2_3; 06201 } else if (isdigit(*h)) { 06202 parse_hints_length_add_digit(&ph, *h); 06203 state = HINT_2_3; 06204 } else { 06205 return v; /* failed */ 06206 } 06207 break; 06208 06209 case HINT_2_3: 06210 if (isdigit(*h)) { 06211 parse_hints_length_add_digit(&ph, *h); 06212 /* state = HINT_2_3 */ 06213 } else if ('x' == *h || 'd' == *h || 'o' == *h || 'a' == *h) { 06214 ph.format = *h; 06215 state = HINT_1_2_4; 06216 } else { 06217 return v; /* failed */ 06218 } 06219 break; 06220 06221 case HINT_1_2_4: 06222 if ('*' == *h) { 06223 retval = parse_hints_parse(&ph, &v); 06224 parse_hints_reset(&ph); 06225 06226 ph.repeat = 1; 06227 state = HINT_2_3; 06228 } else if (isdigit(*h)) { 06229 retval = parse_hints_parse(&ph, &v); 06230 parse_hints_reset(&ph); 06231 06232 parse_hints_length_add_digit(&ph, *h); 06233 state = HINT_2_3; 06234 } else { 06235 ph.separator = *h; 06236 state = HINT_1_2_5; 06237 } 06238 break; 06239 06240 case HINT_1_2_5: 06241 if ('*' == *h) { 06242 retval = parse_hints_parse(&ph, &v); 06243 parse_hints_reset(&ph); 06244 06245 ph.repeat = 1; 06246 state = HINT_2_3; 06247 } else if (isdigit(*h)) { 06248 retval = parse_hints_parse(&ph, &v); 06249 parse_hints_reset(&ph); 06250 06251 parse_hints_length_add_digit(&ph, *h); 06252 state = HINT_2_3; 06253 } else { 06254 ph.terminator = *h; 06255 06256 retval = parse_hints_parse(&ph, &v); 06257 parse_hints_reset(&ph); 06258 06259 state = HINT_1_2; 06260 } 06261 break; 06262 } 06263 h++; 06264 } 06265 while (*v && retval) { 06266 retval = parse_hints_parse(&ph, &v); 06267 } 06268 if (retval) { 06269 *new_val = ph.result; 06270 *new_val_len = ph.result_len; 06271 } else { 06272 if (ph.result) { 06273 SNMP_FREE(ph.result); 06274 } 06275 *new_val = NULL; 06276 *new_val_len = 0; 06277 } 06278 return retval ? NULL : v; 06279 } 06280 #endif /* NETSNMP_DISABLE_MIB_LOADING */ 06281 06282 #ifdef test_display_hint 06283 06284 int main(int argc, const char **argv) 06285 { 06286 const char *hint; 06287 const char *value; 06288 unsigned char *new_val; 06289 int new_val_len; 06290 char *r; 06291 06292 if (argc < 3) { 06293 fprintf(stderr, "usage: dh <hint> <value>\n"); 06294 exit(2); 06295 } 06296 hint = argv[1]; 06297 value = argv[2]; 06298 r = parse_octet_hint(hint, value, &new_val, &new_val_len); 06299 printf("{\"%s\", \"%s\"}: \n\t", hint, value); 06300 if (r) { 06301 *r = 0; 06302 printf("returned failed\n"); 06303 printf("value syntax error at: %s\n", value); 06304 } 06305 else { 06306 int i; 06307 printf("returned success\n"); 06308 for (i = 0; i < new_val_len; i++) { 06309 int c = new_val[i] & 0xFF; 06310 printf("%02X(%c) ", c, isprint(c) ? c : ' '); 06311 } 06312 SNMP_FREE(new_val); 06313 } 06314 printf("\n"); 06315 exit(0); 06316 } 06317 06318 #endif /* test_display_hint */ 06319 06320 u_char 06321 mib_to_asn_type(int mib_type) 06322 { 06323 switch (mib_type) { 06324 case TYPE_OBJID: 06325 return ASN_OBJECT_ID; 06326 06327 case TYPE_OCTETSTR: 06328 return ASN_OCTET_STR; 06329 06330 case TYPE_NETADDR: 06331 case TYPE_IPADDR: 06332 return ASN_IPADDRESS; 06333 06334 case TYPE_INTEGER32: 06335 case TYPE_INTEGER: 06336 return ASN_INTEGER; 06337 06338 case TYPE_COUNTER: 06339 return ASN_COUNTER; 06340 06341 case TYPE_GAUGE: 06342 return ASN_GAUGE; 06343 06344 case TYPE_TIMETICKS: 06345 return ASN_TIMETICKS; 06346 06347 case TYPE_OPAQUE: 06348 return ASN_OPAQUE; 06349 06350 case TYPE_NULL: 06351 return ASN_NULL; 06352 06353 case TYPE_COUNTER64: 06354 return ASN_COUNTER64; 06355 06356 case TYPE_BITSTRING: 06357 return ASN_BIT_STR; 06358 06359 case TYPE_UINTEGER: 06360 case TYPE_UNSIGNED32: 06361 return ASN_UNSIGNED; 06362 06363 case TYPE_NSAPADDRESS: 06364 return ASN_NSAP; 06365 06366 } 06367 return -1; 06368 } 06369 06380 int 06381 netsnmp_str2oid(const char *S, oid * O, int L) 06382 { 06383 const char *c = S; 06384 oid *o = &O[1]; 06385 06386 --L; /* leave room for length prefix */ 06387 06388 for (; *c && L; --L, ++o, ++c) 06389 *o = *c; 06390 06391 /* 06392 * make sure we got to the end of the string 06393 */ 06394 if (*c != 0) 06395 return 1; 06396 06397 /* 06398 * set the length of the oid 06399 */ 06400 *O = c - S; 06401 06402 return 0; 06403 } 06404 06415 int 06416 netsnmp_oid2chars(char *C, int L, const oid * O) 06417 { 06418 char *c = C; 06419 const oid *o = &O[1]; 06420 06421 if (L < (int)*O) 06422 return 1; 06423 06424 L = *O; 06425 for (; L; --L, ++o, ++c) { 06426 if (*o > 0xFF) 06427 return 1; 06428 *c = (char)*o; 06429 } 06430 return 0; 06431 } 06432 06443 int 06444 netsnmp_oid2str(char *S, int L, oid * O) 06445 { 06446 int rc; 06447 06448 if (L <= (int)*O) 06449 return 1; 06450 06451 rc = netsnmp_oid2chars(S, L, O); 06452 if (rc) 06453 return 1; 06454 06455 S[ *O ] = 0; 06456 06457 return 0; 06458 } 06459 06460 int 06461 snprint_by_type(char *buf, size_t buf_len, 06462 netsnmp_variable_list * var, 06463 const struct enum_list *enums, 06464 const char *hint, const char *units) 06465 { 06466 size_t out_len = 0; 06467 if (sprint_realloc_by_type((u_char **) & buf, &buf_len, &out_len, 0, 06468 var, enums, hint, units)) 06469 return (int) out_len; 06470 else 06471 return -1; 06472 } 06473 06474 int 06475 snprint_hexstring(char *buf, size_t buf_len, const u_char * cp, size_t len) 06476 { 06477 size_t out_len = 0; 06478 if (sprint_realloc_hexstring((u_char **) & buf, &buf_len, &out_len, 0, 06479 cp, len)) 06480 return (int) out_len; 06481 else 06482 return -1; 06483 } 06484 06485 int 06486 snprint_asciistring(char *buf, size_t buf_len, 06487 const u_char * cp, size_t len) 06488 { 06489 size_t out_len = 0; 06490 if (sprint_realloc_asciistring 06491 ((u_char **) & buf, &buf_len, &out_len, 0, cp, len)) 06492 return (int) out_len; 06493 else 06494 return -1; 06495 } 06496 06497 int 06498 snprint_octet_string(char *buf, size_t buf_len, 06499 const netsnmp_variable_list * var, const struct enum_list *enums, 06500 const char *hint, const char *units) 06501 { 06502 size_t out_len = 0; 06503 if (sprint_realloc_octet_string 06504 ((u_char **) & buf, &buf_len, &out_len, 0, var, enums, hint, 06505 units)) 06506 return (int) out_len; 06507 else 06508 return -1; 06509 } 06510 06511 int 06512 snprint_opaque(char *buf, size_t buf_len, 06513 const netsnmp_variable_list * var, const struct enum_list *enums, 06514 const char *hint, const char *units) 06515 { 06516 size_t out_len = 0; 06517 if (sprint_realloc_opaque((u_char **) & buf, &buf_len, &out_len, 0, 06518 var, enums, hint, units)) 06519 return (int) out_len; 06520 else 06521 return -1; 06522 } 06523 06524 int 06525 snprint_object_identifier(char *buf, size_t buf_len, 06526 const netsnmp_variable_list * var, 06527 const struct enum_list *enums, const char *hint, 06528 const char *units) 06529 { 06530 size_t out_len = 0; 06531 if (sprint_realloc_object_identifier 06532 ((u_char **) & buf, &buf_len, &out_len, 0, var, enums, hint, 06533 units)) 06534 return (int) out_len; 06535 else 06536 return -1; 06537 } 06538 06539 int 06540 snprint_timeticks(char *buf, size_t buf_len, 06541 const netsnmp_variable_list * var, const struct enum_list *enums, 06542 const char *hint, const char *units) 06543 { 06544 size_t out_len = 0; 06545 if (sprint_realloc_timeticks((u_char **) & buf, &buf_len, &out_len, 0, 06546 var, enums, hint, units)) 06547 return (int) out_len; 06548 else 06549 return -1; 06550 } 06551 06552 int 06553 snprint_hinted_integer(char *buf, size_t buf_len, 06554 long val, const char *hint, const char *units) 06555 { 06556 size_t out_len = 0; 06557 if (sprint_realloc_hinted_integer 06558 ((u_char **) & buf, &buf_len, &out_len, 0, val, 'd', hint, units)) 06559 return (int) out_len; 06560 else 06561 return -1; 06562 } 06563 06564 int 06565 snprint_integer(char *buf, size_t buf_len, 06566 const netsnmp_variable_list * var, const struct enum_list *enums, 06567 const char *hint, const char *units) 06568 { 06569 size_t out_len = 0; 06570 if (sprint_realloc_integer((u_char **) & buf, &buf_len, &out_len, 0, 06571 var, enums, hint, units)) 06572 return (int) out_len; 06573 else 06574 return -1; 06575 } 06576 06577 int 06578 snprint_uinteger(char *buf, size_t buf_len, 06579 const netsnmp_variable_list * var, const struct enum_list *enums, 06580 const char *hint, const char *units) 06581 { 06582 size_t out_len = 0; 06583 if (sprint_realloc_uinteger((u_char **) & buf, &buf_len, &out_len, 0, 06584 var, enums, hint, units)) 06585 return (int) out_len; 06586 else 06587 return -1; 06588 } 06589 06590 int 06591 snprint_gauge(char *buf, size_t buf_len, 06592 const netsnmp_variable_list * var, const struct enum_list *enums, 06593 const char *hint, const char *units) 06594 { 06595 size_t out_len = 0; 06596 if (sprint_realloc_gauge((u_char **) & buf, &buf_len, &out_len, 0, 06597 var, enums, hint, units)) 06598 return (int) out_len; 06599 else 06600 return -1; 06601 } 06602 06603 int 06604 snprint_counter(char *buf, size_t buf_len, 06605 const netsnmp_variable_list * var, const struct enum_list *enums, 06606 const char *hint, const char *units) 06607 { 06608 size_t out_len = 0; 06609 if (sprint_realloc_counter((u_char **) & buf, &buf_len, &out_len, 0, 06610 var, enums, hint, units)) 06611 return (int) out_len; 06612 else 06613 return -1; 06614 } 06615 06616 int 06617 snprint_networkaddress(char *buf, size_t buf_len, 06618 const netsnmp_variable_list * var, 06619 const struct enum_list *enums, const char *hint, 06620 const char *units) 06621 { 06622 size_t out_len = 0; 06623 if (sprint_realloc_networkaddress 06624 ((u_char **) & buf, &buf_len, &out_len, 0, var, enums, hint, 06625 units)) 06626 return (int) out_len; 06627 else 06628 return -1; 06629 } 06630 06631 int 06632 snprint_ipaddress(char *buf, size_t buf_len, 06633 const netsnmp_variable_list * var, const struct enum_list *enums, 06634 const char *hint, const char *units) 06635 { 06636 size_t out_len = 0; 06637 if (sprint_realloc_ipaddress((u_char **) & buf, &buf_len, &out_len, 0, 06638 var, enums, hint, units)) 06639 return (int) out_len; 06640 else 06641 return -1; 06642 } 06643 06644 int 06645 snprint_null(char *buf, size_t buf_len, 06646 const netsnmp_variable_list * var, const struct enum_list *enums, 06647 const char *hint, const char *units) 06648 { 06649 size_t out_len = 0; 06650 if (sprint_realloc_null((u_char **) & buf, &buf_len, &out_len, 0, 06651 var, enums, hint, units)) 06652 return (int) out_len; 06653 else 06654 return -1; 06655 } 06656 06657 int 06658 snprint_bitstring(char *buf, size_t buf_len, 06659 const netsnmp_variable_list * var, const struct enum_list *enums, 06660 const char *hint, const char *units) 06661 { 06662 size_t out_len = 0; 06663 if (sprint_realloc_bitstring((u_char **) & buf, &buf_len, &out_len, 0, 06664 var, enums, hint, units)) 06665 return (int) out_len; 06666 else 06667 return -1; 06668 } 06669 06670 int 06671 snprint_nsapaddress(char *buf, size_t buf_len, 06672 const netsnmp_variable_list * var, const struct enum_list *enums, 06673 const char *hint, const char *units) 06674 { 06675 size_t out_len = 0; 06676 if (sprint_realloc_nsapaddress 06677 ((u_char **) & buf, &buf_len, &out_len, 0, var, enums, hint, 06678 units)) 06679 return (int) out_len; 06680 else 06681 return -1; 06682 } 06683 06684 int 06685 snprint_counter64(char *buf, size_t buf_len, 06686 const netsnmp_variable_list * var, const struct enum_list *enums, 06687 const char *hint, const char *units) 06688 { 06689 size_t out_len = 0; 06690 if (sprint_realloc_counter64((u_char **) & buf, &buf_len, &out_len, 0, 06691 var, enums, hint, units)) 06692 return (int) out_len; 06693 else 06694 return -1; 06695 } 06696 06697 int 06698 snprint_badtype(char *buf, size_t buf_len, 06699 const netsnmp_variable_list * var, const struct enum_list *enums, 06700 const char *hint, const char *units) 06701 { 06702 size_t out_len = 0; 06703 if (sprint_realloc_badtype((u_char **) & buf, &buf_len, &out_len, 0, 06704 var, enums, hint, units)) 06705 return (int) out_len; 06706 else 06707 return -1; 06708 } 06709 06710 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 06711 int 06712 snprint_float(char *buf, size_t buf_len, 06713 const netsnmp_variable_list * var, const struct enum_list *enums, 06714 const char *hint, const char *units) 06715 { 06716 size_t out_len = 0; 06717 if (sprint_realloc_float((u_char **) & buf, &buf_len, &out_len, 0, 06718 var, enums, hint, units)) 06719 return (int) out_len; 06720 else 06721 return -1; 06722 } 06723 06724 int 06725 snprint_double(char *buf, size_t buf_len, 06726 const netsnmp_variable_list * var, const struct enum_list *enums, 06727 const char *hint, const char *units) 06728 { 06729 size_t out_len = 0; 06730 if (sprint_realloc_double((u_char **) & buf, &buf_len, &out_len, 0, 06731 var, enums, hint, units)) 06732 return (int) out_len; 06733 else 06734 return -1; 06735 } 06736 #endif 06737
Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.