net-snmp 5.7
|
00001 #include <net-snmp/net-snmp-config.h> 00002 00003 #include <limits.h> 00004 #include <stdio.h> 00005 #if HAVE_STDLIB_H 00006 #include <stdlib.h> 00007 #endif 00008 #if HAVE_STRING_H 00009 #include <string.h> 00010 #else 00011 #include <strings.h> 00012 #endif 00013 #include <sys/types.h> 00014 #if HAVE_NETINET_IN_H 00015 #include <netinet/in.h> 00016 #endif 00017 #include <stdarg.h> 00018 00019 #if HAVE_UNISTD_H 00020 #include <unistd.h> 00021 #endif 00022 #if HAVE_DMALLOC_H 00023 #include <dmalloc.h> 00024 #endif 00025 00026 #include <net-snmp/types.h> 00027 #include <net-snmp/output_api.h> 00028 #include <net-snmp/library/snmp_debug.h> /* For this file's "internal" definitions */ 00029 #include <net-snmp/config_api.h> 00030 #include <net-snmp/utilities.h> 00031 00032 #include <net-snmp/library/mib.h> 00033 #include <net-snmp/library/snmp_api.h> 00034 00035 #define SNMP_DEBUG_DISABLED 0 00036 #define SNMP_DEBUG_ACTIVE 1 00037 #define SNMP_DEBUG_EXCLUDED 2 00038 00039 #ifndef NETSNMP_NO_DEBUGGING 00040 00041 static int dodebug = NETSNMP_ALWAYS_DEBUG; 00042 int debug_num_tokens = 0; 00043 static int debug_print_everything = 0; 00044 00045 netsnmp_token_descr dbg_tokens[MAX_DEBUG_TOKENS]; 00046 00047 /* 00048 * Number of spaces to indent debug outpur. Valid range is [0,INT_MAX] 00049 */ 00050 static int debugindent = 0; 00051 00052 int 00053 debug_indent_get(void) 00054 { 00055 return debugindent; 00056 } 00057 00058 const char* 00059 debug_indent(void) 00060 { 00061 #define SPACES " " \ 00062 " " 00063 if ((sizeof(SPACES) - 1) < (unsigned int)debugindent) { 00064 snmp_log(LOG_ERR, "Too deep indentation for debug_indent. " 00065 "Consider using \"%%*s\", debug_indent_get(), \"\" instead."); 00066 return SPACES; 00067 } 00068 return SPACES + sizeof(SPACES) - 1 - debugindent; 00069 #undef SPACES 00070 } 00071 00072 void 00073 debug_indent_add(int amount) 00074 { 00075 if (-debugindent <= amount && amount <= INT_MAX - debugindent) 00076 debugindent += amount; 00077 } 00078 00079 NETSNMP_IMPORT void 00080 debug_config_register_tokens(const char *configtoken, char *tokens); 00081 00082 void 00083 debug_config_register_tokens(const char *configtoken, char *tokens) 00084 { 00085 debug_register_tokens(tokens); 00086 } 00087 00088 NETSNMP_IMPORT void 00089 debug_config_turn_on_debugging(const char *configtoken, char *line); 00090 00091 void 00092 debug_config_turn_on_debugging(const char *configtoken, char *line) 00093 { 00094 snmp_set_do_debugging(atoi(line)); 00095 } 00096 00097 void 00098 debug_register_tokens(const char *tokens) 00099 { 00100 char *newp, *cp; 00101 char *st = NULL; 00102 int status; 00103 00104 if (tokens == NULL || *tokens == 0) 00105 return; 00106 00107 newp = strdup(tokens); /* strtok_r messes it up */ 00108 cp = strtok_r(newp, DEBUG_TOKEN_DELIMITER, &st); 00109 while (cp) { 00110 if (strlen(cp) < MAX_DEBUG_TOKEN_LEN) { 00111 if (strcasecmp(cp, DEBUG_ALWAYS_TOKEN) == 0) { 00112 debug_print_everything = 1; 00113 } else if (debug_num_tokens < MAX_DEBUG_TOKENS) { 00114 if ('-' == *cp) { 00115 ++cp; 00116 status = SNMP_DEBUG_EXCLUDED; 00117 } 00118 else 00119 status = SNMP_DEBUG_ACTIVE; 00120 dbg_tokens[debug_num_tokens].token_name = strdup(cp); 00121 dbg_tokens[debug_num_tokens++].enabled = status; 00122 snmp_log(LOG_NOTICE, "registered debug token %s, %d\n", cp, status); 00123 } else { 00124 snmp_log(LOG_NOTICE, "Unable to register debug token %s\n", cp); 00125 } 00126 } else { 00127 snmp_log(LOG_NOTICE, "Debug token %s over length\n", cp); 00128 } 00129 cp = strtok_r(NULL, DEBUG_TOKEN_DELIMITER, &st); 00130 } 00131 free(newp); 00132 } 00133 00134 /* 00135 * Print all registered tokens along with their current status 00136 */ 00137 void 00138 debug_print_registered_tokens(void) { 00139 int i; 00140 00141 snmp_log(LOG_INFO, "%d tokens registered :\n", debug_num_tokens); 00142 for (i=0; i<debug_num_tokens; i++) { 00143 snmp_log( LOG_INFO, "%d) %s : %d\n", 00144 i, dbg_tokens [i].token_name, dbg_tokens [i].enabled); 00145 } 00146 } 00147 00148 00149 /* 00150 * Enable logs on a given token 00151 */ 00152 int 00153 debug_enable_token_logs (const char *token) { 00154 int i; 00155 00156 /* debugging flag is on or off */ 00157 if (!dodebug) 00158 return SNMPERR_GENERR; 00159 00160 if (debug_num_tokens == 0 || debug_print_everything) { 00161 /* no tokens specified, print everything */ 00162 return SNMPERR_SUCCESS; 00163 } else { 00164 for(i=0; i < debug_num_tokens; i++) { 00165 if (dbg_tokens[i].token_name && 00166 strncmp(dbg_tokens[i].token_name, token, 00167 strlen(dbg_tokens[i].token_name)) == 0) { 00168 dbg_tokens[i].enabled = SNMP_DEBUG_ACTIVE; 00169 return SNMPERR_SUCCESS; 00170 } 00171 } 00172 } 00173 return SNMPERR_GENERR; 00174 } 00175 00176 /* 00177 * Diable logs on a given token 00178 */ 00179 int 00180 debug_disable_token_logs (const char *token) { 00181 int i; 00182 00183 /* debugging flag is on or off */ 00184 if (!dodebug) 00185 return SNMPERR_GENERR; 00186 00187 if (debug_num_tokens == 0 || debug_print_everything) { 00188 /* no tokens specified, print everything */ 00189 return SNMPERR_SUCCESS; 00190 } else { 00191 for(i=0; i < debug_num_tokens; i++) { 00192 if (strncmp(dbg_tokens[i].token_name, token, 00193 strlen(dbg_tokens[i].token_name)) == 0) { 00194 dbg_tokens[i].enabled = SNMP_DEBUG_DISABLED; 00195 return SNMPERR_SUCCESS; 00196 } 00197 } 00198 } 00199 return SNMPERR_GENERR; 00200 } 00201 00202 /* 00203 * debug_is_token_registered(char *TOKEN): 00204 * 00205 * returns SNMPERR_SUCCESS 00206 * or SNMPERR_GENERR 00207 * 00208 * if TOKEN has been registered and debugging support is turned on. 00209 */ 00210 int 00211 debug_is_token_registered(const char *token) 00212 { 00213 int i, rc; 00214 00215 /* 00216 * debugging flag is on or off 00217 */ 00218 if (!dodebug) 00219 return SNMPERR_GENERR; 00220 00221 if (debug_num_tokens == 0 || debug_print_everything) { 00222 /* 00223 * no tokens specified, print everything 00224 */ 00225 return SNMPERR_SUCCESS; 00226 } 00227 else 00228 rc = SNMPERR_GENERR; /* ! found = err */ 00229 00230 for (i = 0; i < debug_num_tokens; i++) { 00231 if (SNMP_DEBUG_DISABLED == dbg_tokens[i].enabled) 00232 continue; 00233 if (dbg_tokens[i].token_name && 00234 strncmp(dbg_tokens[i].token_name, token, 00235 strlen(dbg_tokens[i].token_name)) == 0) { 00236 if (SNMP_DEBUG_ACTIVE == dbg_tokens[i].enabled) 00237 return SNMPERR_SUCCESS; /* active */ 00238 else 00239 return SNMPERR_GENERR; /* excluded */ 00240 } 00241 } 00242 return rc; 00243 } 00244 00245 void 00246 debugmsg(const char *token, const char *format, ...) 00247 { 00248 if (debug_is_token_registered(token) == SNMPERR_SUCCESS) { 00249 va_list debugargs; 00250 00251 va_start(debugargs, format); 00252 snmp_vlog(LOG_DEBUG, format, debugargs); 00253 va_end(debugargs); 00254 } 00255 } 00256 00257 void 00258 debugmsg_oid(const char *token, const oid * theoid, size_t len) 00259 { 00260 u_char *buf = NULL; 00261 size_t buf_len = 0, out_len = 0; 00262 00263 if (sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid, len)) { 00264 if (buf != NULL) { 00265 debugmsg(token, "%s", buf); 00266 } 00267 } else { 00268 if (buf != NULL) { 00269 debugmsg(token, "%s [TRUNCATED]", buf); 00270 } 00271 } 00272 00273 if (buf != NULL) { 00274 free(buf); 00275 } 00276 } 00277 00278 void 00279 debugmsg_suboid(const char *token, const oid * theoid, size_t len) 00280 { 00281 u_char *buf = NULL; 00282 size_t buf_len = 0, out_len = 0; 00283 int buf_overflow = 0; 00284 00285 netsnmp_sprint_realloc_objid(&buf, &buf_len, &out_len, 1, 00286 &buf_overflow, theoid, len); 00287 if(buf_overflow) { 00288 if (buf != NULL) { 00289 debugmsg(token, "%s [TRUNCATED]", buf); 00290 } 00291 } else { 00292 if (buf != NULL) { 00293 debugmsg(token, "%s", buf); 00294 } 00295 } 00296 00297 if (buf != NULL) { 00298 free(buf); 00299 } 00300 } 00301 00302 void 00303 debugmsg_var(const char *token, netsnmp_variable_list * var) 00304 { 00305 u_char *buf = NULL; 00306 size_t buf_len = 0, out_len = 0; 00307 00308 if (var == NULL || token == NULL) { 00309 return; 00310 } 00311 00312 if (sprint_realloc_variable(&buf, &buf_len, &out_len, 1, 00313 var->name, var->name_length, var)) { 00314 if (buf != NULL) { 00315 debugmsg(token, "%s", buf); 00316 } 00317 } else { 00318 if (buf != NULL) { 00319 debugmsg(token, "%s [TRUNCATED]", buf); 00320 } 00321 } 00322 00323 if (buf != NULL) { 00324 free(buf); 00325 } 00326 } 00327 00328 void 00329 debugmsg_oidrange(const char *token, const oid * theoid, size_t len, 00330 size_t var_subid, oid range_ubound) 00331 { 00332 u_char *buf = NULL; 00333 size_t buf_len = 0, out_len = 0, i = 0; 00334 int rc = 0; 00335 00336 if (var_subid == 0) { 00337 rc = sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid, 00338 len); 00339 } else { 00340 char tmpbuf[128]; 00341 /* XXX - ? check for 0 == var_subid -1 ? */ 00342 rc = sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid, 00343 var_subid-1); /* Adjust for C's 0-based array indexing */ 00344 if (rc) { 00345 sprintf(tmpbuf, ".%" NETSNMP_PRIo "u--%" NETSNMP_PRIo "u", 00346 theoid[var_subid - 1], range_ubound); 00347 rc = snmp_cstrcat(&buf, &buf_len, &out_len, 1, tmpbuf); 00348 if (rc) { 00349 for (i = var_subid; i < len; i++) { 00350 sprintf(tmpbuf, ".%" NETSNMP_PRIo "u", theoid[i]); 00351 if (!snmp_cstrcat(&buf, &buf_len, &out_len, 1, tmpbuf)) { 00352 break; 00353 } 00354 } 00355 } 00356 } 00357 } 00358 00359 00360 if (buf != NULL) { 00361 debugmsg(token, "%s%s", buf, rc ? "" : " [TRUNCATED]"); 00362 free(buf); 00363 } 00364 } 00365 00366 void 00367 debugmsg_hex(const char *token, const u_char * thedata, size_t len) 00368 { 00369 u_char *buf = NULL; 00370 size_t buf_len = 0, out_len = 0; 00371 00372 if (sprint_realloc_hexstring 00373 (&buf, &buf_len, &out_len, 1, thedata, len)) { 00374 if (buf != NULL) { 00375 debugmsg(token, "%s", buf); 00376 } 00377 } else { 00378 if (buf != NULL) { 00379 debugmsg(token, "%s [TRUNCATED]", buf); 00380 } 00381 } 00382 00383 if (buf != NULL) { 00384 free(buf); 00385 } 00386 } 00387 00388 void 00389 debugmsg_hextli(const char *token, const u_char * thedata, size_t len) 00390 { 00391 char buf[SPRINT_MAX_LEN], token2[SPRINT_MAX_LEN]; 00392 u_char *b3 = NULL; 00393 size_t b3_len = 0, o3_len = 0; 00394 int incr; 00395 sprintf(token2, "dumpx_%s", token); 00396 00397 /* 00398 * XX tracing lines removed from this function DEBUGTRACE; 00399 */ 00400 DEBUGIF(token2) { 00401 for (incr = 16; len > 0; len -= incr, thedata += incr) { 00402 if ((int) len < incr) { 00403 incr = len; 00404 } 00405 /* 00406 * XXnext two lines were DEBUGPRINTINDENT(token); 00407 */ 00408 sprintf(buf, "dumpx%s", token); 00409 debugmsg(buf, "%s: %*s", token2, debug_indent_get(), ""); 00410 if (sprint_realloc_hexstring 00411 (&b3, &b3_len, &o3_len, 1, thedata, incr)) { 00412 if (b3 != NULL) { 00413 debugmsg(token2, "%s", b3); 00414 } 00415 } else { 00416 if (b3 != NULL) { 00417 debugmsg(token2, "%s [TRUNCATED]", b3); 00418 } 00419 } 00420 o3_len = 0; 00421 } 00422 } 00423 if (b3 != NULL) { 00424 free(b3); 00425 } 00426 } 00427 00428 void 00429 debugmsgtoken(const char *token, const char *format, ...) 00430 { 00431 va_list debugargs; 00432 00433 va_start(debugargs, format); 00434 debugmsg(token, "%s: ", token); 00435 va_end(debugargs); 00436 } 00437 00438 void 00439 debug_combo_nc(const char *token, const char *format, ...) 00440 { 00441 va_list debugargs; 00442 00443 va_start(debugargs, format); 00444 snmp_log(LOG_DEBUG, "%s: ", token); 00445 snmp_vlog(LOG_DEBUG, format, debugargs); 00446 va_end(debugargs); 00447 } 00448 00449 /* 00450 * for speed, these shouldn't be in default_storage space 00451 */ 00452 void 00453 snmp_set_do_debugging(int val) 00454 { 00455 dodebug = val; 00456 } 00457 00458 int 00459 snmp_get_do_debugging(void) 00460 { 00461 return dodebug; 00462 } 00463 00464 #else /* ! NETSNMP_NO_DEBUGGING */ 00465 00466 #if __GNUC__ > 2 00467 #define UNUSED __attribute__((unused)) 00468 #else 00469 #define UNUSED 00470 #endif 00471 00472 int debug_indent_get(void) { return 0; } 00473 00474 const char* debug_indent(void) { return ""; } 00475 00476 void debug_indent_add(int amount UNUSED) { } 00477 00478 NETSNMP_IMPORT void 00479 debug_config_register_tokens(const char *configtoken, char *tokens); 00480 00481 void 00482 debug_config_register_tokens(const char *configtoken UNUSED, 00483 char *tokens UNUSED) 00484 { } 00485 00486 NETSNMP_IMPORT void 00487 debug_config_turn_on_debugging(const char *configtoken, char *line); 00488 00489 void 00490 debug_config_turn_on_debugging(const char *configtoken UNUSED, 00491 char *line UNUSED) 00492 { } 00493 00494 void 00495 debug_register_tokens(const char *tokens UNUSED) 00496 { } 00497 00498 void 00499 debug_print_registered_tokens(void) 00500 { } 00501 00502 00503 int 00504 debug_enable_token_logs (const char *token UNUSED) 00505 { return SNMPERR_GENERR; } 00506 00507 int 00508 debug_disable_token_logs (const char *token UNUSED) 00509 { return SNMPERR_GENERR; } 00510 00511 int 00512 debug_is_token_registered(const char *token UNUSED) 00513 { return SNMPERR_GENERR; } 00514 00515 void 00516 debugmsg(const char *token UNUSED, const char *format UNUSED, ...) 00517 { } 00518 00519 void 00520 debugmsg_oid(const char *token UNUSED, const oid * theoid UNUSED, 00521 size_t len UNUSED) 00522 { } 00523 00524 void 00525 debugmsg_suboid(const char *token UNUSED, const oid * theoid UNUSED, 00526 size_t len UNUSED) 00527 { } 00528 00529 void 00530 debugmsg_var(const char *token UNUSED, netsnmp_variable_list * var UNUSED) 00531 { } 00532 00533 void 00534 debugmsg_oidrange(const char *token UNUSED, const oid * theoid UNUSED, 00535 size_t len UNUSED, size_t var_subid UNUSED, 00536 oid range_ubound UNUSED) 00537 { } 00538 00539 void 00540 debugmsg_hex(const char *token UNUSED, const u_char * thedata UNUSED, 00541 size_t len UNUSED) 00542 { } 00543 00544 void 00545 debugmsg_hextli(const char *token UNUSED, const u_char * thedata UNUSED, 00546 size_t len UNUSED) 00547 { } 00548 00549 void 00550 debugmsgtoken(const char *token UNUSED, const char *format UNUSED, ...) 00551 { } 00552 00553 void 00554 debug_combo_nc(const char *token UNUSED, const char *format UNUSED, ...) 00555 { } 00556 00557 void 00558 snmp_set_do_debugging(int val UNUSED) 00559 { } 00560 00561 int 00562 snmp_get_do_debugging(void) 00563 { 00564 return 0; 00565 } 00566 00567 #endif /* NETSNMP_NO_DEBUGGING */ 00568 00569 void 00570 snmp_debug_init(void) 00571 { 00572 register_prenetsnmp_mib_handler("snmp", "doDebugging", 00573 debug_config_turn_on_debugging, NULL, 00574 "(1|0)"); 00575 register_prenetsnmp_mib_handler("snmp", "debugTokens", 00576 debug_config_register_tokens, NULL, 00577 "token[,token...]"); 00578 }