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