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