blob: e4a84385c5b7973d60700ba597a22271de3c9339 [file] [log] [blame]
/* 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.
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/debug_handler.h>
/** @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_register_handler_by_name("debug", netsnmp_get_debug_handler());
}
/** @} */