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 #if HAVE_WINSOCK_H 00019 #include <winsock.h> 00020 #endif 00021 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 static int dodebug = NETSNMP_ALWAYS_DEBUG; 00040 int debug_num_tokens = 0; 00041 static int debug_print_everything = 0; 00042 00043 netsnmp_token_descr dbg_tokens[MAX_DEBUG_TOKENS]; 00044 00045 /* 00046 * Number of spaces to indent debug outpur. Valid range is [0,INT_MAX] 00047 */ 00048 static int debugindent = 0; 00049 00050 int 00051 debug_indent_get(void) 00052 { 00053 return debugindent; 00054 } 00055 00056 const char* 00057 debug_indent(void) 00058 { 00059 #define SPACES " " \ 00060 " " 00061 if ((sizeof(SPACES) - 1) < (unsigned int)debugindent) { 00062 snmp_log(LOG_ERR, "Too deep indentation for debug_indent. " 00063 "Consider using \"%%*s\", debug_indent_get(), \"\" instead."); 00064 return SPACES; 00065 } 00066 return SPACES + sizeof(SPACES) - 1 - debugindent; 00067 #undef SPACES 00068 } 00069 00070 void 00071 debug_indent_add(int amount) 00072 { 00073 if (-debugindent <= amount && amount <= INT_MAX - debugindent) 00074 debugindent += amount; 00075 } 00076 00077 void 00078 debug_config_register_tokens(const char *configtoken, char *tokens) 00079 { 00080 debug_register_tokens(tokens); 00081 } 00082 00083 void 00084 debug_config_turn_on_debugging(const char *configtoken, char *line) 00085 { 00086 snmp_set_do_debugging(atoi(line)); 00087 } 00088 00089 void 00090 snmp_debug_init(void) 00091 { 00092 register_prenetsnmp_mib_handler("snmp", "doDebugging", 00093 debug_config_turn_on_debugging, NULL, 00094 "(1|0)"); 00095 register_prenetsnmp_mib_handler("snmp", "debugTokens", 00096 debug_config_register_tokens, NULL, 00097 "token[,token...]"); 00098 } 00099 00100 void 00101 debug_register_tokens(char *tokens) 00102 { 00103 char *newp, *cp; 00104 char *st = NULL; 00105 int status; 00106 00107 if (tokens == NULL || *tokens == 0) 00108 return; 00109 00110 newp = strdup(tokens); /* strtok_r messes it up */ 00111 cp = strtok_r(newp, DEBUG_TOKEN_DELIMITER, &st); 00112 while (cp) { 00113 if (strlen(cp) < MAX_DEBUG_TOKEN_LEN) { 00114 if (strcasecmp(cp, DEBUG_ALWAYS_TOKEN) == 0) { 00115 debug_print_everything = 1; 00116 } else if (debug_num_tokens < MAX_DEBUG_TOKENS) { 00117 if ('-' == *cp) { 00118 ++cp; 00119 status = SNMP_DEBUG_EXCLUDED; 00120 } 00121 else 00122 status = SNMP_DEBUG_ACTIVE; 00123 dbg_tokens[debug_num_tokens].token_name = strdup(cp); 00124 dbg_tokens[debug_num_tokens++].enabled = status; 00125 snmp_log(LOG_NOTICE, "registered debug token %s, %d\n", cp, status); 00126 } else { 00127 snmp_log(LOG_NOTICE, "Unable to register debug token %s\n", cp); 00128 } 00129 } else { 00130 snmp_log(LOG_NOTICE, "Debug token %s over length\n", cp); 00131 } 00132 cp = strtok_r(NULL, DEBUG_TOKEN_DELIMITER, &st); 00133 } 00134 free(newp); 00135 } 00136 00137 00138 /* 00139 * Print all registered tokens along with their current status 00140 */ 00141 void 00142 debug_print_registered_tokens(void) { 00143 int i; 00144 00145 snmp_log(LOG_INFO, "%d tokens registered :\n", debug_num_tokens); 00146 for (i=0; i<debug_num_tokens; i++) { 00147 snmp_log( LOG_INFO, "%d) %s : %d\n", 00148 i, dbg_tokens [i].token_name, dbg_tokens [i].enabled); 00149 } 00150 } 00151 00152 00153 /* 00154 * Enable logs on a given token 00155 */ 00156 int 00157 debug_enable_token_logs (const char *token) { 00158 int i; 00159 00160 /* debugging flag is on or off */ 00161 if (!dodebug) 00162 return SNMPERR_GENERR; 00163 00164 if (debug_num_tokens == 0 || debug_print_everything) { 00165 /* no tokens specified, print everything */ 00166 return SNMPERR_SUCCESS; 00167 } else { 00168 for(i=0; i < debug_num_tokens; i++) { 00169 if (dbg_tokens[i].token_name && 00170 strncmp(dbg_tokens[i].token_name, token, 00171 strlen(dbg_tokens[i].token_name)) == 0) { 00172 dbg_tokens[i].enabled = SNMP_DEBUG_ACTIVE; 00173 return SNMPERR_SUCCESS; 00174 } 00175 } 00176 } 00177 return SNMPERR_GENERR; 00178 } 00179 00180 /* 00181 * Diable logs on a given token 00182 */ 00183 int 00184 debug_disable_token_logs (const char *token) { 00185 int i; 00186 00187 /* debugging flag is on or off */ 00188 if (!dodebug) 00189 return SNMPERR_GENERR; 00190 00191 if (debug_num_tokens == 0 || debug_print_everything) { 00192 /* no tokens specified, print everything */ 00193 return SNMPERR_SUCCESS; 00194 } else { 00195 for(i=0; i < debug_num_tokens; i++) { 00196 if (strncmp(dbg_tokens[i].token_name, token, 00197 strlen(dbg_tokens[i].token_name)) == 0) { 00198 dbg_tokens[i].enabled = SNMP_DEBUG_DISABLED; 00199 return SNMPERR_SUCCESS; 00200 } 00201 } 00202 } 00203 return SNMPERR_GENERR; 00204 } 00205 00206 00207 /* 00208 * debug_is_token_registered(char *TOKEN): 00209 * 00210 * returns SNMPERR_SUCCESS 00211 * or SNMPERR_GENERR 00212 * 00213 * if TOKEN has been registered and debugging support is turned on. 00214 */ 00215 int 00216 debug_is_token_registered(const char *token) 00217 { 00218 int i, rc; 00219 00220 /* 00221 * debugging flag is on or off 00222 */ 00223 if (!dodebug) 00224 return SNMPERR_GENERR; 00225 00226 if (debug_num_tokens == 0 || debug_print_everything) { 00227 /* 00228 * no tokens specified, print everything 00229 */ 00230 return SNMPERR_SUCCESS; 00231 } 00232 else 00233 rc = SNMPERR_GENERR; /* ! found = err */ 00234 00235 for (i = 0; i < debug_num_tokens; i++) { 00236 if (SNMP_DEBUG_DISABLED == dbg_tokens[i].enabled) 00237 continue; 00238 if (dbg_tokens[i].token_name && 00239 strncmp(dbg_tokens[i].token_name, token, 00240 strlen(dbg_tokens[i].token_name)) == 0) { 00241 if (SNMP_DEBUG_ACTIVE == dbg_tokens[i].enabled) 00242 return SNMPERR_SUCCESS; /* active */ 00243 else 00244 return SNMPERR_GENERR; /* excluded */ 00245 } 00246 } 00247 return rc; 00248 } 00249 00250 void 00251 debugmsg(const char *token, const char *format, ...) 00252 { 00253 if (debug_is_token_registered(token) == SNMPERR_SUCCESS) { 00254 va_list debugargs; 00255 00256 va_start(debugargs, format); 00257 snmp_vlog(LOG_DEBUG, format, debugargs); 00258 va_end(debugargs); 00259 } 00260 } 00261 00262 void 00263 debugmsg_oid(const char *token, const oid * theoid, size_t len) 00264 { 00265 u_char *buf = NULL; 00266 size_t buf_len = 0, out_len = 0; 00267 00268 if (sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid, len)) { 00269 if (buf != NULL) { 00270 debugmsg(token, "%s", buf); 00271 } 00272 } else { 00273 if (buf != NULL) { 00274 debugmsg(token, "%s [TRUNCATED]", buf); 00275 } 00276 } 00277 00278 if (buf != NULL) { 00279 free(buf); 00280 } 00281 } 00282 00283 void 00284 debugmsg_suboid(const char *token, const oid * theoid, size_t len) 00285 { 00286 u_char *buf = NULL; 00287 size_t buf_len = 0, out_len = 0; 00288 int buf_overflow = 0; 00289 00290 netsnmp_sprint_realloc_objid(&buf, &buf_len, &out_len, 1, 00291 &buf_overflow, theoid, len); 00292 if(buf_overflow) { 00293 if (buf != NULL) { 00294 debugmsg(token, "%s [TRUNCATED]", buf); 00295 } 00296 } else { 00297 if (buf != NULL) { 00298 debugmsg(token, "%s", buf); 00299 } 00300 } 00301 00302 if (buf != NULL) { 00303 free(buf); 00304 } 00305 } 00306 00307 void 00308 debugmsg_var(const char *token, netsnmp_variable_list * var) 00309 { 00310 u_char *buf = NULL; 00311 size_t buf_len = 0, out_len = 0; 00312 00313 if (var == NULL || token == NULL) { 00314 return; 00315 } 00316 00317 if (sprint_realloc_variable(&buf, &buf_len, &out_len, 1, 00318 var->name, var->name_length, var)) { 00319 if (buf != NULL) { 00320 debugmsg(token, "%s", buf); 00321 } 00322 } else { 00323 if (buf != NULL) { 00324 debugmsg(token, "%s [TRUNCATED]", buf); 00325 } 00326 } 00327 00328 if (buf != NULL) { 00329 free(buf); 00330 } 00331 } 00332 00333 void 00334 debugmsg_oidrange(const char *token, const oid * theoid, size_t len, 00335 size_t var_subid, oid range_ubound) 00336 { 00337 u_char *buf = NULL; 00338 size_t buf_len = 0, out_len = 0, i = 0; 00339 int rc = 0; 00340 00341 if (var_subid == 0) { 00342 rc = sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid, 00343 len); 00344 } else { 00345 char tmpbuf[128]; 00346 /* XXX - ? check for 0 == var_subid -1 ? */ 00347 rc = sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid, 00348 var_subid-1); /* Adjust for C's 0-based array indexing */ 00349 if (rc) { 00350 sprintf(tmpbuf, ".%lu--%lu", theoid[var_subid - 1], 00351 range_ubound); 00352 rc = snmp_cstrcat(&buf, &buf_len, &out_len, 1, tmpbuf); 00353 if (rc) { 00354 for (i = var_subid; i < len; i++) { 00355 sprintf(tmpbuf, ".%lu", theoid[i]); 00356 if (!snmp_cstrcat(&buf, &buf_len, &out_len, 1, tmpbuf)) { 00357 break; 00358 } 00359 } 00360 } 00361 } 00362 } 00363 00364 00365 if (buf != NULL) { 00366 debugmsg(token, "%s%s", buf, rc ? "" : " [TRUNCATED]"); 00367 free(buf); 00368 } 00369 } 00370 00371 void 00372 debugmsg_hex(const char *token, u_char * thedata, size_t len) 00373 { 00374 u_char *buf = NULL; 00375 size_t buf_len = 0, out_len = 0; 00376 00377 if (sprint_realloc_hexstring 00378 (&buf, &buf_len, &out_len, 1, thedata, len)) { 00379 if (buf != NULL) { 00380 debugmsg(token, "%s", buf); 00381 } 00382 } else { 00383 if (buf != NULL) { 00384 debugmsg(token, "%s [TRUNCATED]", buf); 00385 } 00386 } 00387 00388 if (buf != NULL) { 00389 free(buf); 00390 } 00391 } 00392 00393 void 00394 debugmsg_hextli(const char *token, u_char * thedata, size_t len) 00395 { 00396 char buf[SPRINT_MAX_LEN], token2[SPRINT_MAX_LEN]; 00397 u_char *b3 = NULL; 00398 size_t b3_len = 0, o3_len = 0; 00399 int incr; 00400 sprintf(token2, "dumpx_%s", token); 00401 00402 /* 00403 * XX tracing lines removed from this function DEBUGTRACE; 00404 */ 00405 DEBUGIF(token2) { 00406 for (incr = 16; len > 0; len -= incr, thedata += incr) { 00407 if ((int) len < incr) { 00408 incr = len; 00409 } 00410 /* 00411 * XXnext two lines were DEBUGPRINTINDENT(token); 00412 */ 00413 sprintf(buf, "dumpx%s", token); 00414 debugmsg(buf, "%s: %*s", token2, debug_indent_get(), ""); 00415 if (sprint_realloc_hexstring 00416 (&b3, &b3_len, &o3_len, 1, thedata, incr)) { 00417 if (b3 != NULL) { 00418 debugmsg(token2, "%s", b3); 00419 } 00420 } else { 00421 if (b3 != NULL) { 00422 debugmsg(token2, "%s [TRUNCATED]", b3); 00423 } 00424 } 00425 o3_len = 0; 00426 } 00427 } 00428 if (b3 != NULL) { 00429 free(b3); 00430 } 00431 } 00432 00433 void 00434 debugmsgtoken(const char *token, const char *format, ...) 00435 { 00436 va_list debugargs; 00437 00438 va_start(debugargs, format); 00439 debugmsg(token, "%s: ", token); 00440 va_end(debugargs); 00441 } 00442 00443 void 00444 debug_combo_nc(const char *token, const char *format, ...) 00445 { 00446 va_list debugargs; 00447 00448 va_start(debugargs, format); 00449 snmp_log(LOG_DEBUG, "%s: ", token); 00450 snmp_vlog(LOG_DEBUG, format, debugargs); 00451 va_end(debugargs); 00452 } 00453 00454 /* 00455 * for speed, these shouldn't be in default_storage space 00456 */ 00457 void 00458 snmp_set_do_debugging(int val) 00459 { 00460 dodebug = val; 00461 } 00462 00463 int 00464 snmp_get_do_debugging(void) 00465 { 00466 return dodebug; 00467 }
Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.