/src/net-snmp/agent/helpers/debug_handler.c
Line | Count | Source |
1 | | /* Portions of this file are subject to the following copyright(s). See |
2 | | * the Net-SNMP's COPYING file for more details and other copyrights |
3 | | * that may apply: |
4 | | */ |
5 | | /* |
6 | | * Portions of this file are copyrighted by: |
7 | | * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. |
8 | | * Use is subject to license terms specified in the COPYING file |
9 | | * distributed with the Net-SNMP package. |
10 | | * |
11 | | * Portions of this file are copyrighted by: |
12 | | * Copyright (c) 2016 VMware, Inc. All rights reserved. |
13 | | * Use is subject to license terms specified in the COPYING file |
14 | | * distributed with the Net-SNMP package. |
15 | | */ |
16 | | #include <net-snmp/net-snmp-config.h> |
17 | | #include <net-snmp/net-snmp-includes.h> |
18 | | #include <net-snmp/agent/net-snmp-agent-includes.h> |
19 | | |
20 | | #include <net-snmp/agent/debug_handler.h> |
21 | | |
22 | | /** @defgroup debug debug |
23 | | * Print out debugging information about the handler chain being called. |
24 | | * This is a useful module for run-time |
25 | | * debugging of requests as the pass this handler in a calling chain. |
26 | | * All debugging output is done via the standard debugging routines |
27 | | * with a token name of "helper:debug", so use the -Dhelper:debug |
28 | | * command line flag to see the output when running the snmpd |
29 | | * daemon. It's not recommended you compile this into a handler chain |
30 | | * during compile time, but instead use the "injectHandler" token in |
31 | | * the snmpd.conf file (or similar) to add it to the chain later: |
32 | | * |
33 | | * injectHandler debug my_module_name |
34 | | * |
35 | | * to see an example output, try: |
36 | | * |
37 | | * injectHandler debug mibII/system |
38 | | * |
39 | | * and then run snmpwalk on the "system" group. |
40 | | * |
41 | | * @ingroup utilities |
42 | | * @{ |
43 | | */ |
44 | | |
45 | | /** returns a debug handler that can be injected into a given |
46 | | * handler chain. |
47 | | */ |
48 | | netsnmp_mib_handler * |
49 | | netsnmp_get_debug_handler(void) |
50 | 3.36k | { |
51 | 3.36k | return netsnmp_create_handler("debug", netsnmp_debug_helper); |
52 | 3.36k | } |
53 | | |
54 | | #ifdef NETSNMP_NO_DEBUGGING |
55 | | |
56 | | #define debug_print_requests(x) |
57 | | |
58 | | #else /* NETSNMP_NO_DEBUGGING */ |
59 | | |
60 | | /** @internal debug print variables in a chain */ |
61 | | static void |
62 | | debug_print_requests(netsnmp_request_info *requests) |
63 | 0 | { |
64 | 0 | netsnmp_request_info *request; |
65 | |
|
66 | 0 | for (request = requests; request; request = request->next) { |
67 | 0 | DEBUGMSGTL(("helper:debug", " #%2d: ", request->index)); |
68 | 0 | DEBUGMSGVAR(("helper:debug", request->requestvb)); |
69 | 0 | DEBUGMSG(("helper:debug", "\n")); |
70 | |
|
71 | 0 | if (request->processed) |
72 | 0 | DEBUGMSGTL(("helper:debug", " [processed]\n")); |
73 | 0 | if (request->delegated) |
74 | 0 | DEBUGMSGTL(("helper:debug", " [delegated]\n")); |
75 | 0 | if (request->status) |
76 | 0 | DEBUGMSGTL(("helper:debug", " [status = %d]\n", |
77 | 0 | request->status)); |
78 | 0 | if (request->parent_data) { |
79 | 0 | netsnmp_data_list *lst; |
80 | 0 | DEBUGMSGTL(("helper:debug", " [parent data =")); |
81 | 0 | for (lst = request->parent_data; lst; lst = lst->next) { |
82 | 0 | DEBUGMSG(("helper:debug", " %s", lst->name)); |
83 | 0 | } |
84 | 0 | DEBUGMSG(("helper:debug", "]\n")); |
85 | 0 | } |
86 | 0 | } |
87 | 0 | } |
88 | | |
89 | | #endif /* NETSNMP_NO_DEBUGGING */ |
90 | | |
91 | | /** @internal Implements the debug handler */ |
92 | | int |
93 | | netsnmp_debug_helper(netsnmp_mib_handler *handler, |
94 | | netsnmp_handler_registration *reginfo, |
95 | | netsnmp_agent_request_info *reqinfo, |
96 | | netsnmp_request_info *requests) |
97 | 0 | { |
98 | 0 | int ret; |
99 | |
|
100 | 0 | DEBUGIF("helper:debug") { |
101 | 0 | netsnmp_mib_handler *hptr; |
102 | 0 | char *cp; |
103 | 0 | int i, count; |
104 | |
|
105 | 0 | DEBUGMSGTL(("helper:debug", "Entering Debugging Helper:\n")); |
106 | 0 | DEBUGMSGTL(("helper:debug", " Handler Registration Info:\n")); |
107 | 0 | DEBUGMSGTL(("helper:debug", " Name: %s\n", |
108 | 0 | reginfo->handlerName)); |
109 | 0 | DEBUGMSGTL(("helper:debug", " Context: %s\n", |
110 | 0 | SNMP_STRORNULL(reginfo->contextName))); |
111 | 0 | DEBUGMSGTL(("helper:debug", " Base OID: ")); |
112 | 0 | DEBUGMSGOID(("helper:debug", reginfo->rootoid, reginfo->rootoid_len)); |
113 | 0 | DEBUGMSG(("helper:debug", "\n")); |
114 | |
|
115 | 0 | DEBUGMSGTL(("helper:debug", " Modes: 0x%x = ", |
116 | 0 | reginfo->modes)); |
117 | 0 | for (count = 0, i = reginfo->modes; i; i = i >> 1, count++) { |
118 | 0 | if (i & 0x01) { |
119 | 0 | cp = se_find_label_in_slist("handler_can_mode", |
120 | 0 | 0x01 << count); |
121 | 0 | DEBUGMSG(("helper:debug", "%s | ", SNMP_STRORNULL(cp))); |
122 | 0 | } |
123 | 0 | } |
124 | 0 | DEBUGMSG(("helper:debug", "\n")); |
125 | |
|
126 | 0 | DEBUGMSGTL(("helper:debug", " Priority: %d\n", |
127 | 0 | reginfo->priority)); |
128 | |
|
129 | 0 | DEBUGMSGTL(("helper:debug", " Handler Calling Chain:\n")); |
130 | 0 | DEBUGMSGTL(("helper:debug", " ")); |
131 | 0 | for (hptr = reginfo->handler; hptr; hptr = hptr->next) { |
132 | 0 | DEBUGMSG(("helper:debug", " -> %s", hptr->handler_name)); |
133 | 0 | if (hptr->myvoid) |
134 | 0 | DEBUGMSG(("helper:debug", " [myvoid = %p]", hptr->myvoid)); |
135 | 0 | } |
136 | 0 | DEBUGMSG(("helper:debug", "\n")); |
137 | |
|
138 | 0 | DEBUGMSGTL(("helper:debug", " Request information:\n")); |
139 | 0 | DEBUGMSGTL(("helper:debug", " Mode: %s (%d = 0x%x)\n", |
140 | 0 | se_find_label_in_slist("agent_mode", reqinfo->mode), |
141 | 0 | reqinfo->mode, reqinfo->mode)); |
142 | 0 | DEBUGMSGTL(("helper:debug", " Request Variables:\n")); |
143 | 0 | debug_print_requests(requests); |
144 | |
|
145 | 0 | DEBUGMSGTL(("helper:debug", " --- calling next handler --- \n")); |
146 | 0 | } |
147 | |
|
148 | 0 | ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); |
149 | |
|
150 | 0 | DEBUGIF("helper:debug") { |
151 | 0 | DEBUGMSGTL(("helper:debug", " Results:\n")); |
152 | 0 | DEBUGMSGTL(("helper:debug", " Returned code: %d\n", ret)); |
153 | 0 | DEBUGMSGTL(("helper:debug", " Returned Variables:\n")); |
154 | 0 | debug_print_requests(requests); |
155 | |
|
156 | 0 | DEBUGMSGTL(("helper:debug", "Exiting Debugging Helper:\n")); |
157 | 0 | } |
158 | |
|
159 | 0 | return ret; |
160 | 0 | } |
161 | | |
162 | | /** initializes the debug helper which then registers a debug |
163 | | * handler as a run-time injectable handler for configuration file |
164 | | * use. |
165 | | */ |
166 | | void |
167 | | netsnmp_init_debug_helper(void) |
168 | 3.36k | { |
169 | 3.36k | netsnmp_mib_handler *handler = netsnmp_get_debug_handler(); |
170 | 3.36k | if (!handler) { |
171 | 0 | snmp_log(LOG_ERR, "could not create debug handler\n"); |
172 | 0 | return; |
173 | 0 | } |
174 | 3.36k | netsnmp_register_handler_by_name("debug", handler); |
175 | 3.36k | } |
176 | | /** @} */ |