1 /*
2  * Portions of this file are subject to the following copyright(s).  See
3  * the Net-SNMP's COPYING file for more details and other copyrights
4  * that may apply:
5  *
6  * Portions of this file are copyrighted by:
7  * Copyright (c) 2016 VMware, 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 
12 #ifndef SNMP_DEBUG_H
13 #define SNMP_DEBUG_H
14 
15 #include <net-snmp/library/netsnmp-attribute-format.h>
16 
17 #ifdef __cplusplus
18 extern          "C" {
19 #endif
20 
21     /*
22      * snmp_debug.h:
23      *
24      * - prototypes for snmp debugging routines.
25      * - easy to use macros to wrap around the functions.  This also provides
26      * the ability to remove debugging code easily from the applications at
27      * compile time.
28      */
29 
30     /*
31      * These functions should not be used, if at all possible.  Instead, use
32      * the macros below.
33      */
34     NETSNMP_IMPORT
35     void            debugmsg(const char *token, const char *format, ...)
36                         NETSNMP_ATTRIBUTE_FORMAT(printf, 2, 3);
37     NETSNMP_IMPORT
38     void            debugmsgtoken(const char *token, const char *format,
39                                   ...)
40                         NETSNMP_ATTRIBUTE_FORMAT(printf, 2, 3);
41     NETSNMP_IMPORT
42     void            debug_combo_nc(const char *token, const char *format,
43                                    ...)
44                         NETSNMP_ATTRIBUTE_FORMAT(printf, 2, 3);
45     NETSNMP_IMPORT
46     void            debugmsg_oid(const char *token, const oid * theoid,
47                                  size_t len);
48     NETSNMP_IMPORT
49     void            debugmsg_suboid(const char *token, const oid * theoid,
50                                     size_t len);
51     NETSNMP_IMPORT
52     void            debugmsg_var(const char *token,
53                                  netsnmp_variable_list * var);
54     NETSNMP_IMPORT
55     void            debugmsg_oidrange(const char *token,
56                                       const oid * theoid, size_t len,
57                                       size_t var_subid, oid range_ubound);
58     NETSNMP_IMPORT
59     void            debugmsg_hex(const char *token, const u_char * thedata,
60                                  size_t len);
61     NETSNMP_IMPORT
62     void            debugmsg_hextli(const char *token, const u_char * thedata,
63                                     size_t len);
64     NETSNMP_IMPORT
65     void            debug_indent_add(int amount);
66     NETSNMP_IMPORT
67     void            debug_indent_reset(void);
68     NETSNMP_IMPORT
69     int             debug_indent_get(void);
70     NETSNMP_IMPORT
71     void            debug_indent_reset(void);
72     /*
73      * What is said above is true for this function as well. Further this
74      * function is deprecated and only provided for backwards compatibility.
75      * Please use "%*s", debug_indent_get(), "" if you used this one before.
76      */
77     NETSNMP_IMPORT
78     const char     *debug_indent(void);
79 
80     /*
81      * Use these macros instead of the functions above to allow them to be
82      * re-defined at compile time to NOP for speed optimization.
83      *
84      * They need to be called enclosing all the arguments in a single set of ()s.
85      * Example:
86      * DEBUGMSGTL(("token", "debugging of something %s related\n", "snmp"));
87      *
88      * Usage:
89      * All of the functions take a "token" argument that helps determine when
90      * the output in question should be printed.  See the snmpcmd.1 manual page
91      * on the -D flag to turn on/off output for a given token on the command line.
92      *
93      * DEBUGMSG((token, format, ...)):      equivalent to printf(format, ...)
94      * (if "token" debugging output
95      * is requested by the user)
96      *
97      * DEBUGMSGT((token, format, ...)):     equivalent to DEBUGMSG, but prints
98      * "token: " at the beginning of the
99      * line for you.
100      *
101      * DEBUGTRACE                           Insert this token anywhere you want
102      * tracing output displayed when the
103      * "trace" debugging token is selected.
104      *
105      * DEBUGMSGL((token, format, ...)):     equivalent to DEBUGMSG, but includes
106      * DEBUGTRACE debugging line just before
107      * yours.
108      *
109      * DEBUGMSGTL((token, format, ...)):    Same as DEBUGMSGL and DEBUGMSGT
110      * combined.
111      *
112      * Important:
113      * It is considered best if you use DEBUGMSGTL() everywhere possible, as it
114      * gives the nicest format output and provides tracing support just before
115      * every debugging statement output.
116      *
117      * To print multiple pieces to a single line in one call, use:
118      *
119      * DEBUGMSGTL(("token", "line part 1"));
120      * DEBUGMSG  (("token", " and part 2\n"));
121      *
122      * to get:
123      *
124      * token: line part 1 and part 2
125      *
126      * as debugging output.
127      *
128      *
129      * Each of these macros also have a version with a suffix of '_NC'. The
130      * NC suffix stands for 'No Check', which means that no check will be
131      * performed to see if debug is enabled or if the token has been turned
132      * on. These NC versions are intended for use within a DEBUG_IF {} block,
133      * where the debug/token check has already been performed.
134      */
135 
136 #ifndef NETSNMP_NO_DEBUGGING       /* make sure we're wanted */
137 
138     /*
139      * define two macros : one macro with, one without,
140      *                     a test if debugging is enabled.
141      *
142      * Generally, use the macro with _DBG_IF_
143      */
144 
145 /******************* Start private macros ************************/
146 #define _DBG_IF_            snmp_get_do_debugging()
147 #define DEBUGIF(x)         if (_DBG_IF_ && debug_is_token_registered(x) == SNMPERR_SUCCESS)
148 
149 #define __DBGMSGT(x)     debugmsgtoken x,  debugmsg x
150 #define __DBGMSG_NC(x)   debugmsg x
151 #define __DBGMSGT_NC(x)  debug_combo_nc x
152 #define __DBGMSGL_NC(x)  __DBGTRACE; debugmsg x
153 #define __DBGMSGTL_NC(x) __DBGTRACE; debug_combo_nc x
154 
155 #ifdef  NETSNMP_FUNCTION
156 #define __DBGTRACE       __DBGMSGT(("trace","%s(): %s, %d:\n",\
157 				NETSNMP_FUNCTION,__FILE__,__LINE__))
158 #define __DBGTRACETOK(x) __DBGMSGT((x,"%s(): %s, %d:\n",       \
159                                     NETSNMP_FUNCTION,__FILE__,__LINE__))
160 #else
161 #define __DBGTRACE       __DBGMSGT(("trace"," %s, %d:\n", __FILE__,__LINE__))
162 #define __DBGTRACETOK(x) __DBGMSGT((x," %s, %d:\n", __FILE__,__LINE__))
163 #endif
164 
165 #define __DBGMSGL(x)     __DBGTRACE, debugmsg x
166 #define __DBGMSGTL(x)    __DBGTRACE, debugmsgtoken x, debugmsg x
167 #define __DBGMSGOID(x)     debugmsg_oid x
168 #define __DBGMSGSUBOID(x)  debugmsg_suboid x
169 #define __DBGMSGVAR(x)     debugmsg_var x
170 #define __DBGMSGOIDRANGE(x) debugmsg_oidrange x
171 #define __DBGMSGHEX(x)     debugmsg_hex x
172 #define __DBGMSGHEXTLI(x)  debugmsg_hextli x
173 #define __DBGINDENT()      debug_indent_get()
174 #define __DBGINDENTADD(x)  debug_indent_add(x)
175 #define __DBGINDENTMORE()  debug_indent_add(2)
176 #define __DBGINDENTLESS()  debug_indent_add(-2)
177 #define __DBGPRINTINDENT(token) __DBGMSGTL((token, "%*s", __DBGINDENT(), ""))
178 
179 #define __DBGDUMPHEADER(token,x) \
180         __DBGPRINTINDENT("dumph_" token); \
181         debugmsg("dumph_" token,x); \
182         if (debug_is_token_registered("dumpx" token) == SNMPERR_SUCCESS ||    \
183             debug_is_token_registered("dumpv" token) == SNMPERR_SUCCESS ||    \
184             (debug_is_token_registered("dumpx_" token) != SNMPERR_SUCCESS &&  \
185              debug_is_token_registered("dumpv_" token) != SNMPERR_SUCCESS)) { \
186             debugmsg("dumph_" token,"\n"); \
187         } else { \
188             debugmsg("dumph_" token,"  "); \
189         } \
190         __DBGINDENTMORE()
191 
192 #define __DBGDUMPSECTION(token,x) \
193         __DBGPRINTINDENT("dumph_" token); \
194         debugmsg("dumph_" token,"%s\n",x);\
195         __DBGINDENTMORE()
196 
197 #define __DBGDUMPSETUP(token,buf,len) \
198         debugmsg("dumpx" token, "dumpx_%s:%*s", token, __DBGINDENT(), ""); \
199         __DBGMSGHEX(("dumpx_" token,buf,len)); \
200         if (debug_is_token_registered("dumpv" token) == SNMPERR_SUCCESS || \
201             debug_is_token_registered("dumpv_" token) != SNMPERR_SUCCESS) { \
202             debugmsg("dumpx_" token,"\n"); \
203         } else { \
204             debugmsg("dumpx_" token,"  "); \
205         } \
206         debugmsg("dumpv" token, "dumpv_%s:%*s", token, __DBGINDENT(), "");
207 
208 /******************* End   private macros ************************/
209 /*****************************************************************/
210 #endif /* NETSNMP_NO_DEBUGGING */
211 
212 #ifdef __cplusplus
213 }
214 #endif
215 
216     /* Public macros moved to top-level API header file */
217 #include <net-snmp/output_api.h>
218 
219 #ifdef __cplusplus
220 extern          "C" {
221 #endif
222 
223     void            snmp_debug_init(void);
224     void            snmp_debug_shutdown(void);
225 
226 #define MAX_DEBUG_TOKENS 256
227 #define MAX_DEBUG_TOKEN_LEN 128
228 #define DEBUG_TOKEN_DELIMITER ","
229 #define DEBUG_ALWAYS_TOKEN "all"
230 
231 #ifndef NETSNMP_NO_DEBUGGING
232 
233 /*
234  * internal:
235  * You probably shouldn't be using this information unless the word
236  * "expert" applies to you.  I know it looks tempting.
237  */
238 typedef struct netsnmp_token_descr_s {
239     char *token_name;
240     char  enabled;
241 } netsnmp_token_descr;
242 
243 NETSNMP_IMPORT int                 debug_num_tokens;
244 NETSNMP_IMPORT netsnmp_token_descr dbg_tokens[MAX_DEBUG_TOKENS];
245 
246 #endif /* NETSNMP_NO_DEBUGGING */
247 
248 #ifdef __cplusplus
249 }
250 #endif
251 #endif                          /* SNMP_DEBUG_H */
252