Coverage Report

Created: 2023-06-07 06:42

/src/net-snmp/snmplib/snmp_debug.c
Line
Count
Source (jump to first uncovered line)
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
#include <net-snmp/net-snmp-config.h>
13
14
#define SYSLOG_NAMES
15
16
#include <limits.h>
17
#include <stdio.h>
18
#ifndef HAVE_PRIORITYNAMES
19
#include <errno.h>
20
#endif
21
#ifdef HAVE_STDLIB_H
22
#include <stdlib.h>
23
#endif
24
#ifdef HAVE_STRING_H
25
#include <string.h>
26
#else
27
#include <strings.h>
28
#endif
29
#include <sys/types.h>
30
#ifdef HAVE_NETINET_IN_H
31
#include <netinet/in.h>
32
#endif
33
#include <stdarg.h>
34
35
#ifdef HAVE_UNISTD_H
36
#include <unistd.h>
37
#endif
38
39
#ifdef HAVE_PRIORITYNAMES
40
#include <sys/syslog.h>
41
#endif
42
43
#include <net-snmp/types.h>
44
#include <net-snmp/output_api.h>
45
#include <net-snmp/library/snmp_debug.h>        /* For this file's "internal" definitions */
46
#include <net-snmp/config_api.h>
47
#include <net-snmp/utilities.h>
48
49
#include <net-snmp/library/mib.h>
50
#include <net-snmp/library/snmp_api.h>
51
#include <net-snmp/library/snmp_assert.h>
52
53
0
#define SNMP_DEBUG_DISABLED           0
54
0
#define SNMP_DEBUG_ACTIVE             1
55
#define SNMP_DEBUG_EXCLUDED           2
56
57
#ifndef NETSNMP_NO_DEBUGGING
58
59
static int      dodebug = NETSNMP_ALWAYS_DEBUG;
60
int             debug_num_tokens = 0;
61
static int      debug_print_everything = 0;
62
#ifndef NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL
63
static int      debug_log_level = LOG_DEBUG;
64
#else
65
#define debug_log_level LOG_DEBUG
66
#endif /* NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL */
67
68
netsnmp_token_descr dbg_tokens[MAX_DEBUG_TOKENS];
69
70
/*
71
 * Number of spaces to indent debug output. Valid range is [0,INT_MAX]
72
 */
73
static int debugindent = 0;
74
75
int
76
debug_indent_get(void)
77
10.8k
{
78
10.8k
    return debugindent;
79
10.8k
}
80
81
const char*
82
debug_indent(void)
83
0
{
84
0
    static const char SPACES[] = "                                        "
85
0
        "                                        ";
86
87
0
    if ((sizeof(SPACES) - 1) < (unsigned int)debugindent) {
88
0
        snmp_log(LOG_ERR, "Too deep indentation for debug_indent. "
89
0
                 "Consider using \"%%*s\", debug_indent_get(), \"\" instead.");
90
0
        return SPACES;
91
0
    }
92
0
    return &SPACES[sizeof(SPACES) - 1 - debugindent];
93
0
}
94
95
void
96
debug_indent_add(int amount)
97
5.44k
{
98
5.44k
    if (-debugindent <= amount && amount <= INT_MAX - debugindent)
99
5.44k
  debugindent += amount;
100
5.44k
    netsnmp_assert( debugindent >= 0 ); /* no negative indents */
101
5.44k
}
102
103
NETSNMP_IMPORT void
104
debug_config_register_tokens(const char *configtoken, char *tokens);
105
106
void
107
debug_indent_reset(void)
108
0
{
109
0
    if (debugindent != 0)
110
0
        DEBUGMSGTL(("dump_indent","indent reset from %d\n", debugindent));
111
0
    debugindent = 0;
112
0
}
113
114
void
115
debug_config_register_tokens(const char *configtoken, char *tokens)
116
0
{
117
0
    debug_register_tokens(tokens);
118
0
}
119
120
NETSNMP_IMPORT void
121
debug_config_turn_on_debugging(const char *configtoken, char *line);
122
123
void
124
debug_config_turn_on_debugging(const char *configtoken, char *line)
125
0
{
126
0
    snmp_set_do_debugging(atoi(line));
127
0
}
128
129
#ifndef NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL
130
131
void
132
netsnmp_set_debug_log_level(int val)
133
0
{
134
0
    if (val < LOG_EMERG)
135
0
        val = LOG_EMERG;
136
0
    else if (val > LOG_DEBUG)
137
0
        val = LOG_DEBUG;
138
0
    debug_log_level = val;
139
0
}
140
141
int
142
netsnmp_get_debug_log_level(void)
143
0
{
144
0
    return debug_log_level;
145
0
}
146
147
static void
148
debug_config_debug_log_level(const char *configtoken, char *line)
149
0
{
150
#ifndef HAVE_PRIORITYNAMES
151
    static const struct strval_s {
152
        const char *c_name;
153
        int         c_val;
154
    } prioritynames[] = {
155
        { "alert", LOG_ALERT },
156
        { "crit", LOG_CRIT },
157
        { "debug", LOG_DEBUG },
158
        { "emerg", LOG_EMERG },
159
        { "err", LOG_ERR },
160
        { "info", LOG_INFO },
161
        { "notice", LOG_NOTICE },
162
        { "warning", LOG_WARNING },
163
        { NULL, 0 }
164
    };
165
#endif
166
0
    int i = 0, len_l, len_p;
167
168
0
    len_l = strlen(line);
169
0
    for(;prioritynames[i].c_name;++i) {
170
0
        len_p = strlen(prioritynames[i].c_name);
171
0
        if ((len_p != len_l) ||
172
0
            (strcasecmp(line,prioritynames[i].c_name) != 0))
173
0
            continue;
174
0
        netsnmp_set_debug_log_level(prioritynames[i].c_val);
175
0
        return;
176
0
    }
177
0
    config_perror("unknown debug log level, using debug");
178
0
    netsnmp_set_debug_log_level(LOG_DEBUG);
179
0
}
180
#endif /* NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL */
181
182
void
183
debug_register_tokens(const char *tokens)
184
0
{
185
0
    char           *newp, *cp;
186
0
    char           *st = NULL;
187
0
    int             status;
188
189
0
    if (tokens == NULL || *tokens == 0)
190
0
        return;
191
192
0
    newp = strdup(tokens);      /* strtok_r messes it up */
193
0
    if (!newp)
194
0
        return;
195
0
    cp = strtok_r(newp, DEBUG_TOKEN_DELIMITER, &st);
196
0
    while (cp) {
197
0
        if (strlen(cp) < MAX_DEBUG_TOKEN_LEN) {
198
0
            if (strcasecmp(cp, DEBUG_ALWAYS_TOKEN) == 0) {
199
0
                debug_print_everything = 1;
200
0
            } else if (debug_num_tokens < MAX_DEBUG_TOKENS) {
201
0
                if ('-' == *cp) {
202
0
                    ++cp;
203
0
                    status = SNMP_DEBUG_DISABLED;
204
0
                }
205
0
                else
206
0
                    status = SNMP_DEBUG_ACTIVE;
207
0
                dbg_tokens[debug_num_tokens].token_name = strdup(cp);
208
0
                dbg_tokens[debug_num_tokens++].enabled  = status;
209
0
                snmp_log(LOG_NOTICE, "registered debug token %s, %d\n", cp, status);
210
0
            } else {
211
0
                snmp_log(LOG_NOTICE, "Unable to register debug token %s\n", cp);
212
0
            }
213
0
        } else {
214
0
            snmp_log(LOG_NOTICE, "Debug token %s over length\n", cp);
215
0
        }
216
0
        cp = strtok_r(NULL, DEBUG_TOKEN_DELIMITER, &st);
217
0
    }
218
0
    free(newp);
219
0
}
220
221
/*
222
 * Print all registered tokens along with their current status
223
 */
224
void
225
0
debug_print_registered_tokens(void) {
226
0
    int i;
227
228
0
    snmp_log(LOG_INFO, "%d tokens registered :\n", debug_num_tokens);
229
0
    for (i=0; i<debug_num_tokens; i++) {
230
0
        snmp_log( LOG_INFO, "%d) %s : %d\n",
231
0
                 i, dbg_tokens [i].token_name, dbg_tokens [i].enabled);
232
0
    }
233
0
}
234
235
236
/*
237
 * Enable logs on a given token
238
 */
239
int
240
0
debug_enable_token_logs (const char *token) {
241
0
    int i;
242
243
    /* debugging flag is on or off */
244
0
    if (!dodebug)
245
0
        return SNMPERR_GENERR;
246
247
0
    if (debug_num_tokens == 0 || debug_print_everything) {
248
        /* no tokens specified, print everything */
249
0
        return SNMPERR_SUCCESS;
250
0
    } else {
251
0
        for(i=0; i < debug_num_tokens; i++) {
252
0
            if (dbg_tokens[i].token_name &&
253
0
                strncmp(dbg_tokens[i].token_name, token,
254
0
                        strlen(dbg_tokens[i].token_name)) == 0) {
255
0
                dbg_tokens[i].enabled = SNMP_DEBUG_ACTIVE;
256
0
                return SNMPERR_SUCCESS;
257
0
            }
258
0
        }
259
0
    }
260
0
    return SNMPERR_GENERR;
261
0
}
262
263
/*
264
 * Diable logs on a given token
265
 */
266
int
267
0
debug_disable_token_logs (const char *token) {
268
0
    int i;
269
270
    /* debugging flag is on or off */
271
0
    if (!dodebug)
272
0
        return SNMPERR_GENERR;
273
274
0
    if (debug_num_tokens == 0 || debug_print_everything) {
275
        /* no tokens specified, print everything */
276
0
        return SNMPERR_SUCCESS;
277
0
    } else {
278
0
        for(i=0; i < debug_num_tokens; i++) {
279
0
            if (strncmp(dbg_tokens[i].token_name, token, 
280
0
                  strlen(dbg_tokens[i].token_name)) == 0) {
281
0
                dbg_tokens[i].enabled = SNMP_DEBUG_DISABLED;
282
0
                return SNMPERR_SUCCESS;
283
0
            }
284
0
        }
285
0
    }
286
0
    return SNMPERR_GENERR;
287
0
}
288
289
/*
290
 * debug_is_token_registered(char *TOKEN):
291
 *
292
 * returns SNMPERR_SUCCESS
293
 * or SNMPERR_GENERR
294
 *
295
 * if TOKEN has been registered and debugging support is turned on.
296
 */
297
int
298
debug_is_token_registered(const char *token)
299
0
{
300
0
    int             i, rc;
301
302
    /*
303
     * debugging flag is on or off
304
     */
305
0
    if (!dodebug)
306
0
        return SNMPERR_GENERR;
307
308
0
    if (debug_num_tokens == 0 || debug_print_everything) {
309
        /*
310
         * no tokens specified, print everything
311
         */
312
0
        return SNMPERR_SUCCESS;
313
0
    }
314
0
    else
315
0
        rc = SNMPERR_GENERR; /* ! found = err */
316
317
0
    for (i = 0; i < debug_num_tokens; i++) {
318
0
        if (SNMP_DEBUG_DISABLED == dbg_tokens[i].enabled)
319
0
            continue;
320
0
        if (dbg_tokens[i].token_name &&
321
0
            strncmp(dbg_tokens[i].token_name, token,
322
0
                    strlen(dbg_tokens[i].token_name)) == 0) {
323
0
            if (SNMP_DEBUG_ACTIVE == dbg_tokens[i].enabled)
324
0
                return SNMPERR_SUCCESS; /* active */
325
0
            else
326
0
                return SNMPERR_GENERR; /* excluded */
327
0
        }
328
0
    }
329
0
    return rc;
330
0
}
331
332
void
333
debugmsg(const char *token, const char *format, ...)
334
0
{
335
0
    if (debug_is_token_registered(token) == SNMPERR_SUCCESS) {
336
0
  va_list         debugargs;
337
338
0
  va_start(debugargs, format);
339
0
  snmp_vlog(debug_log_level, format, debugargs);
340
0
  va_end(debugargs);
341
0
    }
342
0
}
343
344
void
345
debugmsg_oid(const char *token, const oid * theoid, size_t len)
346
0
{
347
0
    u_char         *buf = NULL;
348
0
    size_t          buf_len = 0, out_len = 0;
349
350
0
    if (sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid, len)) {
351
0
        if (buf != NULL) {
352
0
            debugmsg(token, "%s", buf);
353
0
        }
354
0
    } else {
355
0
        if (buf != NULL) {
356
0
            debugmsg(token, "%s [TRUNCATED]", buf);
357
0
        }
358
0
    }
359
360
0
    if (buf != NULL) {
361
0
        free(buf);
362
0
    }
363
0
}
364
365
void
366
debugmsg_suboid(const char *token, const oid * theoid, size_t len)
367
0
{
368
0
    u_char         *buf = NULL;
369
0
    size_t          buf_len = 0, out_len = 0;
370
0
    int             buf_overflow = 0;
371
372
0
    netsnmp_sprint_realloc_objid(&buf, &buf_len, &out_len, 1,
373
0
                                 &buf_overflow, theoid, len);
374
0
    if(buf_overflow) {
375
0
        if (buf != NULL) {
376
0
            debugmsg(token, "%s [TRUNCATED]", buf);
377
0
        }
378
0
    } else {
379
0
        if (buf != NULL) {
380
0
            debugmsg(token, "%s", buf);
381
0
        }
382
0
    }
383
384
0
    if (buf != NULL) {
385
0
        free(buf);
386
0
    }
387
0
}
388
389
void
390
debugmsg_var(const char *token, netsnmp_variable_list * var)
391
0
{
392
0
    u_char         *buf = NULL;
393
0
    size_t          buf_len = 0, out_len = 0;
394
395
0
    if (var == NULL || token == NULL) {
396
0
        return;
397
0
    }
398
399
0
    if (sprint_realloc_variable(&buf, &buf_len, &out_len, 1,
400
0
                                var->name, var->name_length, var)) {
401
0
        if (buf != NULL) {
402
0
            debugmsg(token, "%s", buf);
403
0
        }
404
0
    } else {
405
0
        if (buf != NULL) {
406
0
            debugmsg(token, "%s [TRUNCATED]", buf);
407
0
        }
408
0
    }
409
410
0
    if (buf != NULL) {
411
0
        free(buf);
412
0
    }
413
0
}
414
415
void
416
debugmsg_oidrange(const char *token, const oid * theoid, size_t len,
417
                  size_t var_subid, oid range_ubound)
418
0
{
419
0
    u_char         *buf = NULL;
420
0
    size_t          buf_len = 0, out_len = 0, i = 0;
421
0
    int             rc = 0;
422
423
0
    if (var_subid == 0) {
424
0
        rc = sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid,
425
0
                                  len);
426
0
    } else {
427
0
        char            tmpbuf[128];
428
        /* XXX - ? check for 0 == var_subid -1 ? */
429
0
        rc = sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid,
430
0
                                  var_subid-1);  /* Adjust for C's 0-based array indexing */
431
0
        if (rc) {
432
0
            sprintf(tmpbuf, ".%" NETSNMP_PRIo "u--%" NETSNMP_PRIo "u",
433
0
                    theoid[var_subid - 1], range_ubound);
434
0
            rc = snmp_cstrcat(&buf, &buf_len, &out_len, 1, tmpbuf);
435
0
            if (rc) {
436
0
                for (i = var_subid; i < len; i++) {
437
0
                    sprintf(tmpbuf, ".%" NETSNMP_PRIo "u", theoid[i]);
438
0
                    if (!snmp_cstrcat(&buf, &buf_len, &out_len, 1, tmpbuf)) {
439
0
                        break;
440
0
                    }
441
0
                }
442
0
            }
443
0
        }
444
0
    }
445
446
447
0
    if (buf != NULL) {
448
0
        debugmsg(token, "%s%s", buf, rc ? "" : " [TRUNCATED]");
449
0
        free(buf);
450
0
    }
451
0
}
452
453
void
454
debugmsg_hex(const char *token, const u_char * thedata, size_t len)
455
0
{
456
0
    u_char         *buf = NULL;
457
0
    size_t          buf_len = 0, out_len = 0;
458
459
0
    if (sprint_realloc_hexstring
460
0
        (&buf, &buf_len, &out_len, 1, thedata, len)) {
461
0
        if (buf != NULL) {
462
0
            debugmsg(token, "%s", buf);
463
0
        }
464
0
    } else {
465
0
        if (buf != NULL) {
466
0
            debugmsg(token, "%s [TRUNCATED]", buf);
467
0
        }
468
0
    }
469
470
0
    if (buf != NULL) {
471
0
        free(buf);
472
0
    }
473
0
}
474
475
void
476
debugmsg_hextli(const char *token, const u_char * thedata, size_t len)
477
0
{
478
0
    char            buf[SPRINT_MAX_LEN], token2[SPRINT_MAX_LEN];
479
0
    u_char         *b3 = NULL;
480
0
    size_t          b3_len = 0, o3_len = 0;
481
0
    int             incr;
482
0
    sprintf(token2, "dumpx_%s", token);
483
484
    /*
485
     * XX tracing lines removed from this function DEBUGTRACE; 
486
     */
487
0
    DEBUGIF(token2) {
488
0
        for (incr = 16; len > 0; len -= incr, thedata += incr) {
489
0
            if ((int) len < incr) {
490
0
                incr = len;
491
0
            }
492
            /*
493
             * XXnext two lines were DEBUGPRINTINDENT(token);
494
             */
495
0
            sprintf(buf, "dumpx%s", token);
496
0
            debugmsg(buf, "%s: %*s", token2, debug_indent_get(), "");
497
0
            if (sprint_realloc_hexstring
498
0
                (&b3, &b3_len, &o3_len, 1, thedata, incr)) {
499
0
                if (b3 != NULL) {
500
0
                    debugmsg(token2, "%s", b3);
501
0
                }
502
0
            } else {
503
0
                if (b3 != NULL) {
504
0
                    debugmsg(token2, "%s [TRUNCATED]", b3);
505
0
                }
506
0
            }
507
0
            o3_len = 0;
508
0
        }
509
0
    }
510
0
    if (b3 != NULL) {
511
0
        free(b3);
512
0
    }
513
0
}
514
515
void
516
debugmsgtoken(const char *token, const char *format, ...)
517
0
{
518
0
    va_list         debugargs;
519
520
0
    va_start(debugargs, format);
521
0
    debugmsg(token, "%s: ", token);
522
0
    va_end(debugargs);
523
0
}
524
525
void
526
debug_combo_nc(const char *token, const char *format, ...)
527
0
{
528
0
    va_list         debugargs;
529
530
0
    va_start(debugargs, format);
531
0
    snmp_log(debug_log_level, "%s: ", token);
532
0
    snmp_vlog(debug_log_level, format, debugargs);
533
0
    va_end(debugargs);
534
0
}
535
536
/*
537
 * for speed, these shouldn't be in default_storage space 
538
 */
539
void
540
snmp_set_do_debugging(int val)
541
0
{
542
0
    dodebug = val;
543
0
}
544
545
int
546
snmp_get_do_debugging(void)
547
1.16M
{
548
1.16M
    return dodebug;
549
1.16M
}
550
551
void
552
snmp_set_do_debugoutputall(int val)
553
0
{
554
0
    debug_print_everything = val;
555
0
}
556
557
int
558
snmp_get_do_debugoutputall(void)
559
0
{
560
0
    return debug_print_everything;
561
0
}
562
563
void
564
snmp_debug_shutdown(void)
565
0
{
566
0
    int i;
567
568
0
    for (i = 0; i < debug_num_tokens; i++)
569
0
       SNMP_FREE(dbg_tokens[i].token_name);
570
0
}
571
572
#else /* ! NETSNMP_NO_DEBUGGING */
573
574
int debug_indent_get(void) { return 0; }
575
576
const char* debug_indent(void) { return ""; }
577
578
void debug_indent_add(int amount)
579
{ }
580
581
NETSNMP_IMPORT void
582
debug_config_register_tokens(const char *configtoken, char *tokens);
583
584
void
585
debug_indent_reset(void)
586
{ }
587
588
void
589
debug_config_register_tokens(const char *configtoken, char *tokens)
590
{ }
591
592
#ifndef NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL
593
static void
594
debug_config_debug_log_level(const char *configtoken NETSNMP_ATTRIBUTE_UNUSED,
595
                             char *tokens NETSNMP_ATTRIBUTE_UNUSED)
596
{ }
597
598
NETSNMP_IMPORT void
599
netsnmp_set_debug_log_level(int val NETSNMP_ATTRIBUTE_UNUSED)
600
{ }
601
602
NETSNMP_IMPORT int
603
netsnmp_get_debug_log_level(void)
604
{
605
    return 0;
606
}
607
#endif /* NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL */
608
609
NETSNMP_IMPORT void
610
debug_config_turn_on_debugging(const char *configtoken, char *line);
611
612
void
613
debug_config_turn_on_debugging(const char *configtokenu, char *line)
614
{ }
615
616
void
617
debug_register_tokens(const char *tokens)
618
{ }
619
620
void
621
debug_print_registered_tokens(void)
622
{ }
623
624
625
int
626
debug_enable_token_logs (const char *token)
627
{
628
    return SNMPERR_GENERR;
629
}
630
631
int
632
debug_disable_token_logs (const char *token)
633
{
634
    return SNMPERR_GENERR;
635
}
636
637
int
638
debug_is_token_registered(const char *token)
639
{
640
    return SNMPERR_GENERR;
641
}
642
643
void
644
debugmsg(const char *token, const char *format, ...)
645
{ }
646
647
void debugmsg_oid(const char *token, const oid * theoid, size_t len)
648
{ }
649
650
void
651
debugmsg_suboid(const char *token, const oid * theoid, size_t len)
652
{ }
653
654
void
655
debugmsg_var(const char *token, netsnmp_variable_list * var)
656
{ }
657
658
void
659
debugmsg_oidrange(const char *token, const oid * theoid, size_t len,
660
                  size_t var_subid, oid range_ubound)
661
{ }
662
663
void
664
debugmsg_hex(const char *token, const u_char * thedata, size_t len)
665
{ }
666
667
void
668
debugmsg_hextli(const char *token, const u_char * thedata, size_t len)
669
{ }
670
671
void
672
debugmsgtoken(const char *token, const char *format, ...)
673
{ }
674
675
void
676
debug_combo_nc(const char *token, const char *format, ...)
677
{ }
678
679
void
680
snmp_set_do_debugging(int val)
681
{ }
682
683
int
684
snmp_get_do_debugging(void)
685
{
686
    return 0;
687
}
688
689
void
690
snmp_set_do_debugoutputall(int val)
691
{ }
692
693
int
694
snmp_get_do_debugoutputall(void)
695
{
696
    return 0;
697
}
698
699
void
700
snmp_debug_shutdown(void)
701
{  }
702
703
#endif /* NETSNMP_NO_DEBUGGING */
704
705
#ifdef HAVE_WOLFSSL_WOLFCRYPT_LOGGING_H
706
#include <wolfssl/options.h>
707
#include <wolfssl/wolfcrypt/logging.h>
708
709
static void snmp_log_wolfssl_msg(const int logLevel NETSNMP_ATTRIBUTE_UNUSED,
710
                                 const char* const msg)
711
{
712
    DEBUGMSGTL(("snmp_openssl", msg, "\n"));
713
}
714
#endif
715
716
void
717
snmp_debug_init(void)
718
0
{
719
#ifdef HAVE_WOLFSSL_WOLFCRYPT_LOGGING_H
720
    wolfSSL_Debugging_ON();
721
    wolfSSL_SetLoggingCb(snmp_log_wolfssl_msg);
722
#endif
723
724
0
    register_prenetsnmp_mib_handler("snmp", "doDebugging",
725
0
                                    debug_config_turn_on_debugging, NULL,
726
0
                                    "(1|0)");
727
0
    register_prenetsnmp_mib_handler("snmp", "debugTokens",
728
0
                                    debug_config_register_tokens, NULL,
729
0
                                    "token[,token...]");
730
0
#ifndef NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL
731
0
    register_prenetsnmp_mib_handler("snmp", "debugLogLevel",
732
0
                                    debug_config_debug_log_level, NULL,
733
0
                                    "(emerg|alert|crit|err|warning|notice|info|debug)");
734
0
#endif /* NETSNMP_DISABLE_DYNAMIC_LOG_LEVEL */
735
0
}
736