summaryrefslogtreecommitdiff
path: root/include/net-snmp/library/snmp_debug.h
blob: a3969f6e5adf97f34e6e091446a2da4ad039fd2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#ifndef SNMP_DEBUG_H
#define SNMP_DEBUG_H

#ifdef __cplusplus
extern          "C" {
#endif

    /*
     * snmp_debug.h:
     * 
     * - prototypes for snmp debugging routines.
     * - easy to use macros to wrap around the functions.  This also provides
     * the ability to remove debugging code easily from the applications at
     * compile time.
     */


#if !defined(__GNUC__) || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
#define NETSNMP_ATTRIBUTE_FORMAT(type, formatArg, firstArg)
#else
#define NETSNMP_ATTRIBUTE_FORMAT(type, formatArg, firstArg) \
  __attribute__((__format__( __ ## type ## __, formatArg, firstArg )))
#endif

    /*
     * These functions should not be used, if at all possible.  Instead, use
     * the macros below. 
     */
    NETSNMP_IMPORT
    void            debugmsg(const char *token, const char *format, ...)
                        NETSNMP_ATTRIBUTE_FORMAT(printf, 2, 3);
    NETSNMP_IMPORT
    void            debugmsgtoken(const char *token, const char *format,
                                  ...)
                        NETSNMP_ATTRIBUTE_FORMAT(printf, 2, 3);
    void            debug_combo_nc(const char *token, const char *format,
                                   ...)
                        NETSNMP_ATTRIBUTE_FORMAT(printf, 2, 3);

#undef NETSNMP_ATTRIBUTE_FORMAT

    NETSNMP_IMPORT
    void            debugmsg_oid(const char *token, const oid * theoid,
                                 size_t len);
    NETSNMP_IMPORT
    void            debugmsg_suboid(const char *token, const oid * theoid,
                                    size_t len);
    NETSNMP_IMPORT
    void            debugmsg_var(const char *token,
                                 netsnmp_variable_list * var);
    NETSNMP_IMPORT
    void            debugmsg_oidrange(const char *token,
                                      const oid * theoid, size_t len,
                                      size_t var_subid, oid range_ubound);
    NETSNMP_IMPORT
    void            debugmsg_hex(const char *token, const u_char * thedata,
                                 size_t len);
    NETSNMP_IMPORT
    void            debugmsg_hextli(const char *token, const u_char * thedata,
                                    size_t len);
    NETSNMP_IMPORT
    void            debug_indent_add(int amount);
    NETSNMP_IMPORT
    int             debug_indent_get(void);
    /*
     * What is said above is true for this function as well. Further this
     * function is deprecated and only provided for backwards compatibility.
     * Please use "%*s", debug_indent_get(), "" if you used this one before.
     */
    NETSNMP_IMPORT
    const char     *debug_indent(void);

    /*
     * Use these macros instead of the functions above to allow them to be
     * re-defined at compile time to NOP for speed optimization.
     * 
     * They need to be called enclosing all the arguments in a single set of ()s.
     * Example:
     * DEBUGMSGTL(("token", "debugging of something %s related\n", "snmp"));
     * 
     * Usage:
     * All of the functions take a "token" argument that helps determine when
     * the output in question should be printed.  See the snmpcmd.1 manual page
     * on the -D flag to turn on/off output for a given token on the command line.
     * 
     * DEBUGMSG((token, format, ...)):      equivalent to printf(format, ...)
     * (if "token" debugging output
     * is requested by the user)
     * 
     * DEBUGMSGT((token, format, ...)):     equivalent to DEBUGMSG, but prints
     * "token: " at the beginning of the
     * line for you.
     * 
     * DEBUGTRACE                           Insert this token anywhere you want
     * tracing output displayed when the
     * "trace" debugging token is selected.
     * 
     * DEBUGMSGL((token, format, ...)):     equivalent to DEBUGMSG, but includes
     * DEBUGTRACE debugging line just before
     * yours.
     * 
     * DEBUGMSGTL((token, format, ...)):    Same as DEBUGMSGL and DEBUGMSGT
     * combined.
     * 
     * Important:
     * It is considered best if you use DEBUGMSGTL() everywhere possible, as it
     * gives the nicest format output and provides tracing support just before
     * every debugging statement output.
     * 
     * To print multiple pieces to a single line in one call, use:
     * 
     * DEBUGMSGTL(("token", "line part 1"));
     * DEBUGMSG  (("token", " and part 2\n"));
     * 
     * to get:
     * 
     * token: line part 1 and part 2
     * 
     * as debugging output.
     *
     *
     * Each of these macros also have a version with a suffix of '_NC'. The
     * NC suffix stands for 'No Check', which means that no check will be
     * performed to see if debug is enabled or if the token has been turned
     * on. These NC versions are intended for use within a DEBUG_IF {} block,
     * where the debug/token check has already been performed.
     */

#ifndef NETSNMP_NO_DEBUGGING       /* make sure we're wanted */

    /*
     * define two macros : one macro with, one without,
     *                     a test if debugging is enabled.
     * 
     * Generally, use the macro with _DBG_IF_
     */

/******************* Start private macros ************************/
#define _DBG_IF_            snmp_get_do_debugging()
#define DEBUGIF(x)         if (_DBG_IF_ && debug_is_token_registered(x) == SNMPERR_SUCCESS)

#define __DBGMSGT(x)     debugmsgtoken x,  debugmsg x
#define __DBGMSG_NC(x)   debugmsg x
#define __DBGMSGT_NC(x)  debug_combo_nc x
#define __DBGMSGL_NC(x)  __DBGTRACE; debugmsg x
#define __DBGMSGTL_NC(x) __DBGTRACE; debug_combo_nc x

#ifdef  NETSNMP_FUNCTION
#define __DBGTRACE       __DBGMSGT(("trace","%s(): %s, %d:\n",\
				NETSNMP_FUNCTION,__FILE__,__LINE__))
#define __DBGTRACETOK(x) __DBGMSGT((x,"%s(): %s, %d:\n",       \
                                    NETSNMP_FUNCTION,__FILE__,__LINE__))
#else
#define __DBGTRACE       __DBGMSGT(("trace"," %s, %d:\n", __FILE__,__LINE__))
#define __DBGTRACETOK(x) __DBGMSGT((x," %s, %d:\n", __FILE__,__LINE__))
#endif

#define __DBGMSGL(x)     __DBGTRACE, debugmsg x
#define __DBGMSGTL(x)    __DBGTRACE, debugmsgtoken x, debugmsg x
#define __DBGMSGOID(x)     debugmsg_oid x
#define __DBGMSGSUBOID(x)  debugmsg_suboid x
#define __DBGMSGVAR(x)     debugmsg_var x
#define __DBGMSGOIDRANGE(x) debugmsg_oidrange x
#define __DBGMSGHEX(x)     debugmsg_hex x
#define __DBGMSGHEXTLI(x)  debugmsg_hextli x
#define __DBGINDENT()      debug_indent_get()
#define __DBGINDENTADD(x)  debug_indent_add(x)
#define __DBGINDENTMORE()  debug_indent_add(2)
#define __DBGINDENTLESS()  debug_indent_add(-2)
#define __DBGPRINTINDENT(token) __DBGMSGTL((token, "%*s", __DBGINDENT(), ""))

#define __DBGDUMPHEADER(token,x) \
        __DBGPRINTINDENT("dumph_" token); \
        debugmsg("dumph_" token,x); \
        if (debug_is_token_registered("dumpx" token) == SNMPERR_SUCCESS ||    \
            debug_is_token_registered("dumpv" token) == SNMPERR_SUCCESS ||    \
            (debug_is_token_registered("dumpx_" token) != SNMPERR_SUCCESS &&  \
             debug_is_token_registered("dumpv_" token) != SNMPERR_SUCCESS)) { \
            debugmsg("dumph_" token,"\n"); \
        } else { \
            debugmsg("dumph_" token,"  "); \
        } \
        __DBGINDENTMORE()

#define __DBGDUMPSECTION(token,x) \
        __DBGPRINTINDENT("dumph_" token); \
        debugmsg("dumph_" token,"%s\n",x);\
        __DBGINDENTMORE()

#define __DBGDUMPSETUP(token,buf,len) \
        debugmsg("dumpx" token, "dumpx_%s:%*s", token, __DBGINDENT(), ""); \
        __DBGMSGHEX(("dumpx_" token,buf,len)); \
        if (debug_is_token_registered("dumpv" token) == SNMPERR_SUCCESS || \
            debug_is_token_registered("dumpv_" token) != SNMPERR_SUCCESS) { \
            debugmsg("dumpx_" token,"\n"); \
        } else { \
            debugmsg("dumpx_" token,"  "); \
        } \
        debugmsg("dumpv" token, "dumpv_%s:%*s", token, __DBGINDENT(), "");

/******************* End   private macros ************************/
/*****************************************************************/
#endif /* NETSNMP_NO_DEBUGGING */

#ifdef __cplusplus
}
#endif

    /* Public macros moved to top-level API header file */
#include <net-snmp/output_api.h>

#ifdef __cplusplus
extern          "C" {
#endif

    void            snmp_debug_init(void);

#define MAX_DEBUG_TOKENS 256
#define MAX_DEBUG_TOKEN_LEN 128
#define DEBUG_TOKEN_DELIMITER ","
#define DEBUG_ALWAYS_TOKEN "all"

#ifndef NETSNMP_NO_DEBUGGING

/*
 * internal:
 * You probably shouldn't be using this information unless the word
 * "expert" applies to you.  I know it looks tempting.
 */
typedef struct netsnmp_token_descr_s {
    char *token_name;
    char  enabled;
} netsnmp_token_descr;

NETSNMP_IMPORT int                 debug_num_tokens;
NETSNMP_IMPORT netsnmp_token_descr dbg_tokens[MAX_DEBUG_TOKENS];

#endif /* NETSNMP_NO_DEBUGGING */

#ifdef __cplusplus
}
#endif
#endif                          /* SNMP_DEBUG_H */