/* Portions of this file are subject to the following copyright(s). See * the Net-SNMP's COPYING file for more details and other copyrights * that may apply: */ /* * Portions of this file are copyrighted by: * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms specified in the COPYING file * distributed with the Net-SNMP package. * * Portions of this file are copyrighted by: * Copyright (c) 2016 VMware, Inc. All rights reserved. * Use is subject to license terms specified in the COPYING file * distributed with the Net-SNMP package. */ #include #include #include #include /** @defgroup debug debug * Print out debugging information about the handler chain being called. * This is a useful module for run-time * debugging of requests as the pass this handler in a calling chain. * All debugging output is done via the standard debugging routines * with a token name of "helper:debug", so use the -Dhelper:debug * command line flag to see the output when running the snmpd * demon. It's not recommended you compile this into a handler chain * during compile time, but instead use the "injectHandler" token in * the snmpd.conf file (or similar) to add it to the chain later: * * injectHandler debug my_module_name * * to see an example output, try: * * injectHandler debug mibII/system * * and then run snmpwalk on the "system" group. * * @ingroup utilities * @{ */ /** returns a debug handler that can be injected into a given * handler chain. */ netsnmp_mib_handler * netsnmp_get_debug_handler(void) { return netsnmp_create_handler("debug", netsnmp_debug_helper); } #ifdef NETSNMP_NO_DEBUGGING #define debug_print_requests(x) #else /* NETSNMP_NO_DEBUGGING */ /** @internal debug print variables in a chain */ static void debug_print_requests(netsnmp_request_info *requests) { netsnmp_request_info *request; for (request = requests; request; request = request->next) { DEBUGMSGTL(("helper:debug", " #%2d: ", request->index)); DEBUGMSGVAR(("helper:debug", request->requestvb)); DEBUGMSG(("helper:debug", "\n")); if (request->processed) DEBUGMSGTL(("helper:debug", " [processed]\n")); if (request->delegated) DEBUGMSGTL(("helper:debug", " [delegated]\n")); if (request->status) DEBUGMSGTL(("helper:debug", " [status = %d]\n", request->status)); if (request->parent_data) { netsnmp_data_list *lst; DEBUGMSGTL(("helper:debug", " [parent data =")); for (lst = request->parent_data; lst; lst = lst->next) { DEBUGMSG(("helper:debug", " %s", lst->name)); } DEBUGMSG(("helper:debug", "]\n")); } } } #endif /* NETSNMP_NO_DEBUGGING */ /** @internal Implements the debug handler */ int netsnmp_debug_helper(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { int ret; DEBUGIF("helper:debug") { netsnmp_mib_handler *hptr; char *cp; int i, count; DEBUGMSGTL(("helper:debug", "Entering Debugging Helper:\n")); DEBUGMSGTL(("helper:debug", " Handler Registration Info:\n")); DEBUGMSGTL(("helper:debug", " Name: %s\n", reginfo->handlerName)); DEBUGMSGTL(("helper:debug", " Context: %s\n", SNMP_STRORNULL(reginfo->contextName))); DEBUGMSGTL(("helper:debug", " Base OID: ")); DEBUGMSGOID(("helper:debug", reginfo->rootoid, reginfo->rootoid_len)); DEBUGMSG(("helper:debug", "\n")); DEBUGMSGTL(("helper:debug", " Modes: 0x%x = ", reginfo->modes)); for (count = 0, i = reginfo->modes; i; i = i >> 1, count++) { if (i & 0x01) { cp = se_find_label_in_slist("handler_can_mode", 0x01 << count); DEBUGMSG(("helper:debug", "%s | ", SNMP_STRORNULL(cp))); } } DEBUGMSG(("helper:debug", "\n")); DEBUGMSGTL(("helper:debug", " Priority: %d\n", reginfo->priority)); DEBUGMSGTL(("helper:debug", " Handler Calling Chain:\n")); DEBUGMSGTL(("helper:debug", " ")); for (hptr = reginfo->handler; hptr; hptr = hptr->next) { DEBUGMSG(("helper:debug", " -> %s", hptr->handler_name)); if (hptr->myvoid) DEBUGMSG(("helper:debug", " [myvoid = %p]", hptr->myvoid)); } DEBUGMSG(("helper:debug", "\n")); DEBUGMSGTL(("helper:debug", " Request information:\n")); DEBUGMSGTL(("helper:debug", " Mode: %s (%d = 0x%x)\n", se_find_label_in_slist("agent_mode", reqinfo->mode), reqinfo->mode, reqinfo->mode)); DEBUGMSGTL(("helper:debug", " Request Variables:\n")); debug_print_requests(requests); DEBUGMSGTL(("helper:debug", " --- calling next handler --- \n")); } ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); DEBUGIF("helper:debug") { DEBUGMSGTL(("helper:debug", " Results:\n")); DEBUGMSGTL(("helper:debug", " Returned code: %d\n", ret)); DEBUGMSGTL(("helper:debug", " Returned Variables:\n")); debug_print_requests(requests); DEBUGMSGTL(("helper:debug", "Exiting Debugging Helper:\n")); } return ret; } /** initializes the debug helper which then registers a debug * handler as a run-time injectable handler for configuration file * use. */ void netsnmp_init_debug_helper(void) { netsnmp_mib_handler *handler = netsnmp_get_debug_handler(); if (!handler) { snmp_log(LOG_ERR, "could not create debug handler\n"); return; } netsnmp_register_handler_by_name("debug", handler); } /** @} */