4
* $Id: mib.c,v 5.47.2.9 2004/02/17 13:54:52 slif Exp $
6
* Update: 1998-07-17 <jhy@gsu.edu>
7
* Added print_oid_report* functions.
10
/* Portions of this file are subject to the following copyrights. See
11
* the Net-SNMP's COPYING file for more details and other copyrights
14
/**********************************************************************
15
Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
19
Permission to use, copy, modify, and distribute this software and its
20
documentation for any purpose and without fee is hereby granted,
21
provided that the above copyright notice appear in all copies and that
22
both that copyright notice and this permission notice appear in
23
supporting documentation, and that the name of CMU not be
24
used in advertising or publicity pertaining to distribution of the
25
software without specific, written prior permission.
27
CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
28
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
29
CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
30
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
31
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
32
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
34
******************************************************************/
36
* Copyright ļæ½ 2003 Sun Microsystems, Inc. All rights reserved.
37
* Use is subject to license terms specified in the COPYING file
38
* distributed with the Net-SNMP package.
40
#include <net-snmp/net-snmp-config.h>
44
#include <sys/types.h>
46
#include <netinet/in.h>
48
#if TIME_WITH_SYS_TIME
50
# include <sys/timeb.h>
52
# include <sys/time.h>
57
# include <sys/time.h>
71
#include <sys/select.h>
82
#include <net-snmp/types.h>
83
#include <net-snmp/output_api.h>
84
#include <net-snmp/config_api.h>
85
#include <net-snmp/utilities.h>
87
#include <net-snmp/library/asn1.h>
88
#include <net-snmp/library/snmp_api.h>
89
#include <net-snmp/library/mib.h>
90
#include <net-snmp/library/parse.h>
91
#include <net-snmp/library/int64.h>
92
#include <net-snmp/library/snmp_client.h>
94
/** @defgroup mib_utilities mib parsing and datatype manipulation routines.
100
static char *uptimeString(u_long, char *);
102
static struct tree *_get_realloc_symbol(const oid * objid, size_t objidlen,
103
struct tree *subtree,
104
u_char ** buf, size_t * buf_len,
108
struct index_list *in_dices,
109
size_t * end_of_known);
111
static int print_tree_node(u_char ** buf, size_t * buf_len,
112
size_t * out_len, int allow_realloc,
113
struct tree *tp, int width);
114
static void handle_mibdirs_conf(const char *token, char *line);
115
static void handle_mibs_conf(const char *token, char *line);
116
static void handle_mibfile_conf(const char *token, char *line);
118
static void _oid_finish_printing(const oid * objid, size_t objidlen,
119
u_char ** buf, size_t * buf_len,
121
int allow_realloc, int *buf_overflow);
124
* helper functions for get_module_node
126
static int node_to_oid(struct tree *, oid *, size_t *);
127
#ifndef DISABLE_MIB_LOADING
128
static int _add_strings_to_oid(struct tree *, char *,
129
oid *, size_t *, size_t);
131
static int _add_strings_to_oid(void *, char *,
132
oid *, size_t *, size_t);
133
#endif /* DISABLE_MIB_LOADING */
135
#ifndef DISABLE_MIB_LOADING
136
extern struct tree *tree_head;
137
static struct tree *tree_top;
139
struct tree *Mib; /* Backwards compatibility */
140
#endif /* DISABLE_MIB_LOADING */
142
oid RFC1213_MIB[] = { 1, 3, 6, 1, 2, 1 };
143
static char Standard_Prefix[] = ".1.3.6.1.2.1";
146
* Set default here as some uses of read_objid require valid pointer.
148
static char *Prefix = &Standard_Prefix[0];
149
typedef struct _PrefixList {
152
} *PrefixListPtr, PrefixList;
155
* Here are the prefix strings.
156
* Note that the first one finds the value of Prefix or Standard_Prefix.
157
* Any of these MAY start with period; all will NOT end with period.
158
* Period is added where needed. See use of Prefix in this module.
160
PrefixList mib_prefixes[] = {
161
{&Standard_Prefix[0]}, /* placeholder for Prefix data */
162
{".iso.org.dod.internet.mgmt.mib-2"},
163
{".iso.org.dod.internet.experimental"},
164
{".iso.org.dod.internet.private"},
165
{".iso.org.dod.internet.snmpParties"},
166
{".iso.org.dod.internet.snmpSecrets"},
167
{NULL, 0} /* end of list */
173
* Converts timeticks to hours, minutes, seconds string.
175
* @param timeticks The timeticks to convert.
176
* @param buf Buffer to write to, has to be at
177
* least 40 Bytes large.
179
* @return The buffer.
182
uptimeString(u_long timeticks, char *buf)
184
int centisecs, seconds, minutes, hours, days;
186
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS)) {
187
sprintf(buf, "%lu", timeticks);
192
centisecs = timeticks % 100;
194
days = timeticks / (60 * 60 * 24);
195
timeticks %= (60 * 60 * 24);
197
hours = timeticks / (60 * 60);
198
timeticks %= (60 * 60);
200
minutes = timeticks / 60;
201
seconds = timeticks % 60;
203
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT))
204
sprintf(buf, "%d:%d:%02d:%02d.%02d",
205
days, hours, minutes, seconds, centisecs);
208
sprintf(buf, "%d:%02d:%02d.%02d",
209
hours, minutes, seconds, centisecs);
210
} else if (days == 1) {
211
sprintf(buf, "%d day, %d:%02d:%02d.%02d",
212
days, hours, minutes, seconds, centisecs);
214
sprintf(buf, "%d days, %d:%02d:%02d.%02d",
215
days, hours, minutes, seconds, centisecs);
225
* Prints the character pointed to if in human-readable ASCII range,
226
* otherwise prints a dot.
228
* @param buf Buffer to print the character to.
229
* @param ch Character to print.
232
sprint_char(char *buf, const u_char ch)
235
sprintf(buf, "%c", (int) ch);
244
* Prints a hexadecimal string into a buffer.
246
* The characters pointed by *cp are encoded as hexadecimal string.
248
* If allow_realloc is true the buffer will be (re)allocated to fit in the
249
* needed size. (Note: *buf may change due to this.)
251
* @param buf address of the buffer to print to.
252
* @param buf_len address to an integer containing the size of buf.
253
* @param out_len incremented by the number of characters printed.
254
* @param allow_realloc if not zero reallocate the buffer to fit the
256
* @param cp the array of characters to encode.
257
* @param len the array length of cp.
259
* @return 1 on success, or 0 on failure (out of memory, or buffer to
260
* small when not allowed to realloc.)
263
sprint_realloc_hexstring(u_char ** buf, size_t * buf_len, size_t * out_len,
264
int allow_realloc, const u_char * cp, size_t len)
269
for (; len >= 16; len -= 16) {
270
while ((*out_len + 50) >= *buf_len) {
271
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
276
sprintf((char *) (*buf + *out_len),
277
"%02X %02X %02X %02X %02X %02X %02X %02X ", cp[0], cp[1],
278
cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
279
*out_len += strlen((char *) (*buf + *out_len));
281
sprintf((char *) (*buf + *out_len),
282
"%02X %02X %02X %02X %02X %02X %02X %02X", cp[0], cp[1],
283
cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
284
*out_len += strlen((char *) (*buf + *out_len));
287
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_HEX_TEXT)) {
288
while ((*out_len + 21) >= *buf_len) {
289
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
293
sprintf((char *) (*buf + *out_len), " [");
294
*out_len += strlen((char *) (*buf + *out_len));
295
for (tp = cp - 16; tp < cp; tp++) {
296
sprint_char((char *) (*buf + *out_len), *tp);
299
sprintf((char *) (*buf + *out_len), "]");
300
*out_len += strlen((char *) (*buf + *out_len));
303
while ((*out_len + 2) >= *buf_len) {
304
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
308
*(*buf + (*out_len)++) = '\n';
309
*(*buf + *out_len) = 0;
314
for (; len > 0; len--) {
315
while ((*out_len + 4) >= *buf_len) {
316
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
320
sprintf((char *) (*buf + *out_len), "%02X ", *cp++);
321
*out_len += strlen((char *) (*buf + *out_len));
325
&& netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_HEX_TEXT)) {
326
while ((*out_len + 5 + lenleft) >= *buf_len) {
327
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
331
sprintf((char *) (*buf + *out_len), " [");
332
*out_len += strlen((char *) (*buf + *out_len));
333
for (tp = cp - lenleft; tp < cp; tp++) {
334
sprint_char((char *) (*buf + *out_len), *tp);
337
sprintf((char *) (*buf + *out_len), "]");
338
*out_len += strlen((char *) (*buf + *out_len));
346
* Prints an ascii string into a buffer.
348
* The characters pointed by *cp are encoded as an ascii string.
350
* If allow_realloc is true the buffer will be (re)allocated to fit in the
351
* needed size. (Note: *buf may change due to this.)
353
* @param buf address of the buffer to print to.
354
* @param buf_len address to an integer containing the size of buf.
355
* @param out_len incremented by the number of characters printed.
356
* @param allow_realloc if not zero reallocate the buffer to fit the
358
* @param cp the array of characters to encode.
359
* @param len the array length of cp.
361
* @return 1 on success, or 0 on failure (out of memory, or buffer to
362
* small when not allowed to realloc.)
365
sprint_realloc_asciistring(u_char ** buf, size_t * buf_len,
366
size_t * out_len, int allow_realloc,
367
const u_char * cp, size_t len)
371
for (i = 0; i < (int) len; i++) {
373
if (*cp == '\\' || *cp == '"') {
374
if ((*out_len >= *buf_len) &&
375
!(allow_realloc && snmp_realloc(buf, buf_len))) {
378
*(*buf + (*out_len)++) = '\\';
380
if ((*out_len >= *buf_len) &&
381
!(allow_realloc && snmp_realloc(buf, buf_len))) {
384
*(*buf + (*out_len)++) = *cp++;
386
if ((*out_len >= *buf_len) &&
387
!(allow_realloc && snmp_realloc(buf, buf_len))) {
390
*(*buf + (*out_len)++) = '.';
394
if ((*out_len >= *buf_len) &&
395
!(allow_realloc && snmp_realloc(buf, buf_len))) {
398
*(*buf + *out_len) = '\0';
403
* Prints an octet string into a buffer.
405
* The variable var is encoded as octet string.
407
* If allow_realloc is true the buffer will be (re)allocated to fit in the
408
* needed size. (Note: *buf may change due to this.)
410
* @param buf Address of the buffer to print to.
411
* @param buf_len Address to an integer containing the size of buf.
412
* @param out_len Incremented by the number of characters printed.
413
* @param allow_realloc if not zero reallocate the buffer to fit the
415
* @param var The variable to encode.
416
* @param enums The enumeration ff this variable is enumerated. may be NULL.
417
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
418
* See RFC 1903 Section 3.1 for details. may be NULL.
419
* @param units Contents of the UNITS clause of the MIB. may be NULL.
421
* @return 1 on success, or 0 on failure (out of memory, or buffer to
422
* small when not allowed to realloc.)
425
sprint_realloc_octet_string(u_char ** buf, size_t * buf_len,
426
size_t * out_len, int allow_realloc,
427
const netsnmp_variable_list * var,
428
const struct enum_list *enums, const char *hint,
431
size_t saved_out_len = *out_len;
432
const char *saved_hint = hint;
437
if ((var->type != ASN_OCTET_STR) &&
438
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
439
const char str[] = "Wrong Type (should be OCTET STRING): ";
441
(buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
442
return sprint_realloc_by_type(buf, buf_len, out_len,
443
allow_realloc, var, NULL, NULL,
452
int repeat, width = 1;
454
char code = 'd', separ = 0, term = 0, ch, intbuf[16];
457
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
458
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
459
(const u_char *) "STRING: ")) {
463
cp = var->val.string;
464
ecp = cp + var->val_len;
474
while ('0' <= *hint && *hint <= '9')
475
width = (width * 10) + (*hint++ - '0');
477
if ((ch = *hint) && ch != '*' && (ch < '0' || ch > '9')
479
|| (ch != 'x' && ch != 'd' && ch != 'o')))
483
if ((ch = *hint) && ch != '*' && (ch < '0' || ch > '9')
485
|| (ch != 'x' && ch != 'd' && ch != 'o')))
493
while (repeat && cp < ecp) {
495
if (code != 'a' && code != 't') {
496
for (x = 0; x < width; x++) {
497
value = value * 256 + *cp++;
502
sprintf(intbuf, "%lx", value);
504
(buf, buf_len, out_len, allow_realloc,
505
(u_char *) intbuf)) {
510
sprintf(intbuf, "%ld", value);
512
(buf, buf_len, out_len, allow_realloc,
513
(u_char *) intbuf)) {
518
sprintf(intbuf, "%lo", value);
520
(buf, buf_len, out_len, allow_realloc,
521
(u_char *) intbuf)) {
525
case 't': /* new in rfc 3411 */
527
while ((*out_len + width + 1) >= *buf_len) {
528
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
532
for (x = 0; x < width && cp < ecp; x++) {
533
*(*buf + *out_len) = *cp++;
536
*(*buf + *out_len) = '\0';
539
*out_len = saved_out_len;
540
if (snmp_strcat(buf, buf_len, out_len, allow_realloc,
541
(const u_char *) "(Bad hint ignored: ")
542
&& snmp_strcat(buf, buf_len, out_len,
544
(const u_char *) saved_hint)
545
&& snmp_strcat(buf, buf_len, out_len,
547
(const u_char *) ") ")) {
548
return sprint_realloc_octet_string(buf, buf_len,
558
if (cp < ecp && separ) {
559
while ((*out_len + 1) >= *buf_len) {
560
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
564
*(*buf + *out_len) = separ;
566
*(*buf + *out_len) = '\0';
571
if (term && cp < ecp) {
572
while ((*out_len + 1) >= *buf_len) {
573
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
577
*(*buf + *out_len) = term;
579
*(*buf + *out_len) = '\0';
585
(buf, buf_len, out_len, allow_realloc,
586
(const u_char *) " ")
587
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
588
(const u_char *) units));
590
if ((*out_len >= *buf_len) &&
591
!(allow_realloc && snmp_realloc(buf, buf_len))) {
594
*(*buf + *out_len) = '\0';
599
output_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT);
600
if (0 == output_format) {
601
output_format = NETSNMP_STRING_OUTPUT_GUESS;
603
switch (output_format) {
604
case NETSNMP_STRING_OUTPUT_GUESS:
606
for (cp = var->val.string, x = 0; x < (int) var->val_len; x++, cp++) {
607
if (!isprint(*cp) && !isspace(*cp)) {
613
case NETSNMP_STRING_OUTPUT_ASCII:
617
case NETSNMP_STRING_OUTPUT_HEX:
622
if (var->val_len == 0) {
623
return snmp_strcat(buf, buf_len, out_len, allow_realloc,
624
(const u_char *) "\"\"");
628
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
630
(buf, buf_len, out_len, allow_realloc,
631
(const u_char *) "\"")) {
636
(buf, buf_len, out_len, allow_realloc,
637
(const u_char *) "Hex-STRING: ")) {
642
if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc,
643
var->val.string, var->val_len)) {
647
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
649
(buf, buf_len, out_len, allow_realloc,
650
(const u_char *) "\"")) {
655
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
656
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
657
(const u_char *) "STRING: ")) {
662
(buf, buf_len, out_len, allow_realloc,
663
(const u_char *) "\"")) {
666
if (!sprint_realloc_asciistring
667
(buf, buf_len, out_len, allow_realloc, var->val.string,
672
(buf, buf_len, out_len, allow_realloc,
673
(const u_char *) "\"")) {
680
(buf, buf_len, out_len, allow_realloc,
681
(const u_char *) " ")
682
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
683
(const u_char *) units));
688
#ifdef OPAQUE_SPECIAL_TYPES
691
* Prints a float into a buffer.
693
* The variable var is encoded as a floating point value.
695
* If allow_realloc is true the buffer will be (re)allocated to fit in the
696
* needed size. (Note: *buf may change due to this.)
698
* @param buf Address of the buffer to print to.
699
* @param buf_len Address to an integer containing the size of buf.
700
* @param out_len Incremented by the number of characters printed.
701
* @param allow_realloc if not zero reallocate the buffer to fit the
703
* @param var The variable to encode.
704
* @param enums The enumeration ff this variable is enumerated. may be NULL.
705
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
706
* See RFC 1903 Section 3.1 for details. may be NULL.
707
* @param units Contents of the UNITS clause of the MIB. may be NULL.
709
* @return 1 on success, or 0 on failure (out of memory, or buffer to
710
* small when not allowed to realloc.)
713
sprint_realloc_float(u_char ** buf, size_t * buf_len,
714
size_t * out_len, int allow_realloc,
715
const netsnmp_variable_list * var,
716
const struct enum_list *enums,
717
const char *hint, const char *units)
719
if ((var->type != ASN_OPAQUE_FLOAT) &&
720
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
721
u_char str[] = "Wrong Type (should be Float): ";
722
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
723
return sprint_realloc_by_type(buf, buf_len, out_len,
724
allow_realloc, var, NULL, NULL,
731
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
733
(buf, buf_len, out_len, allow_realloc,
734
(const u_char *) "Opaque: Float: ")) {
741
* How much space needed for max. length float? 128 is overkill.
744
while ((*out_len + 128 + 1) >= *buf_len) {
745
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
750
sprintf((char *) (*buf + *out_len), "%f", *var->val.floatVal);
751
*out_len += strlen((char *) (*buf + *out_len));
755
(buf, buf_len, out_len, allow_realloc,
756
(const u_char *) " ")
757
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
758
(const u_char *) units));
765
* Prints a double into a buffer.
767
* The variable var is encoded as a double precision floating point value.
769
* If allow_realloc is true the buffer will be (re)allocated to fit in the
770
* needed size. (Note: *buf may change due to this.)
772
* @param buf Address of the buffer to print to.
773
* @param buf_len Address to an integer containing the size of buf.
774
* @param out_len Incremented by the number of characters printed.
775
* @param allow_realloc if not zero reallocate the buffer to fit the
777
* @param var The variable to encode.
778
* @param enums The enumeration ff this variable is enumerated. may be NULL.
779
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
780
* See RFC 1903 Section 3.1 for details. may be NULL.
781
* @param units Contents of the UNITS clause of the MIB. may be NULL.
783
* @return 1 on success, or 0 on failure (out of memory, or buffer to
784
* small when not allowed to realloc.)
787
sprint_realloc_double(u_char ** buf, size_t * buf_len,
788
size_t * out_len, int allow_realloc,
789
const netsnmp_variable_list * var,
790
const struct enum_list *enums,
791
const char *hint, const char *units)
793
if ((var->type != ASN_OPAQUE_DOUBLE) &&
794
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
795
const char str[] = "Wrong Type (should be Double): ";
797
(buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
798
return sprint_realloc_by_type(buf, buf_len, out_len,
799
allow_realloc, var, NULL, NULL,
806
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
808
(buf, buf_len, out_len, allow_realloc,
809
(const u_char *) "Opaque: Float: ")) {
815
* How much space needed for max. length double? 128 is overkill.
818
while ((*out_len + 128 + 1) >= *buf_len) {
819
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
824
sprintf((char *) (*buf + *out_len), "%f", *var->val.doubleVal);
825
*out_len += strlen((char *) (*buf + *out_len));
829
(buf, buf_len, out_len, allow_realloc,
830
(const u_char *) " ")
831
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
832
(const u_char *) units));
837
#endif /* OPAQUE_SPECIAL_TYPES */
841
* Prints a counter into a buffer.
843
* The variable var is encoded as a counter value.
845
* If allow_realloc is true the buffer will be (re)allocated to fit in the
846
* needed size. (Note: *buf may change due to this.)
848
* @param buf Address of the buffer to print to.
849
* @param buf_len Address to an integer containing the size of buf.
850
* @param out_len Incremented by the number of characters printed.
851
* @param allow_realloc if not zero reallocate the buffer to fit the
853
* @param var The variable to encode.
854
* @param enums The enumeration ff this variable is enumerated. may be NULL.
855
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
856
* See RFC 1903 Section 3.1 for details. may be NULL.
857
* @param units Contents of the UNITS clause of the MIB. may be NULL.
859
* @return 1 on success, or 0 on failure (out of memory, or buffer to
860
* small when not allowed to realloc.)
863
sprint_realloc_counter64(u_char ** buf, size_t * buf_len, size_t * out_len,
865
const netsnmp_variable_list * var,
866
const struct enum_list *enums,
867
const char *hint, const char *units)
869
char a64buf[I64CHARSZ + 1];
871
if ((var->type != ASN_COUNTER64
872
#ifdef OPAQUE_SPECIAL_TYPES
873
&& var->type != ASN_OPAQUE_COUNTER64
874
&& var->type != ASN_OPAQUE_I64 && var->type != ASN_OPAQUE_U64
876
) && (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
877
u_char str[] = "Wrong Type (should be Counter64): ";
878
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
879
return sprint_realloc_by_type(buf, buf_len, out_len,
880
allow_realloc, var, NULL, NULL,
887
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
888
#ifdef OPAQUE_SPECIAL_TYPES
889
if (var->type != ASN_COUNTER64) {
891
(buf, buf_len, out_len, allow_realloc,
892
(const u_char *) "Opaque: ")) {
897
#ifdef OPAQUE_SPECIAL_TYPES
901
(buf, buf_len, out_len, allow_realloc,
902
(const u_char *) "UInt64: ")) {
908
(buf, buf_len, out_len, allow_realloc,
909
(const u_char *) "Int64: ")) {
914
case ASN_OPAQUE_COUNTER64:
917
(buf, buf_len, out_len, allow_realloc,
918
(const u_char *) "Counter64: ")) {
921
#ifdef OPAQUE_SPECIAL_TYPES
925
#ifdef OPAQUE_SPECIAL_TYPES
926
if (var->type == ASN_OPAQUE_I64) {
927
printI64(a64buf, var->val.counter64);
929
(buf, buf_len, out_len, allow_realloc,
930
(const u_char *) a64buf)) {
935
printU64(a64buf, var->val.counter64);
937
(buf, buf_len, out_len, allow_realloc,
938
(const u_char *) a64buf)) {
941
#ifdef OPAQUE_SPECIAL_TYPES
947
(buf, buf_len, out_len, allow_realloc,
948
(const u_char *) " ")
949
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
950
(const u_char *) units));
957
* Prints an object identifier into a buffer.
959
* If allow_realloc is true the buffer will be (re)allocated to fit in the
960
* needed size. (Note: *buf may change due to this.)
962
* @param buf Address of the buffer to print to.
963
* @param buf_len Address to an integer containing the size of buf.
964
* @param out_len Incremented by the number of characters printed.
965
* @param allow_realloc if not zero reallocate the buffer to fit the
967
* @param var The variable to encode.
968
* @param enums The enumeration ff this variable is enumerated. may be NULL.
969
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
970
* See RFC 1903 Section 3.1 for details. may be NULL.
971
* @param units Contents of the UNITS clause of the MIB. may be NULL.
973
* @return 1 on success, or 0 on failure (out of memory, or buffer to
974
* small when not allowed to realloc.)
977
sprint_realloc_opaque(u_char ** buf, size_t * buf_len,
978
size_t * out_len, int allow_realloc,
979
const netsnmp_variable_list * var,
980
const struct enum_list *enums,
981
const char *hint, const char *units)
983
if ((var->type != ASN_OPAQUE
984
#ifdef OPAQUE_SPECIAL_TYPES
985
&& var->type != ASN_OPAQUE_COUNTER64
986
&& var->type != ASN_OPAQUE_U64
987
&& var->type != ASN_OPAQUE_I64
988
&& var->type != ASN_OPAQUE_FLOAT && var->type != ASN_OPAQUE_DOUBLE
989
#endif /* OPAQUE_SPECIAL_TYPES */
990
) && (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
991
u_char str[] = "Wrong Type (should be Opaque): ";
992
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
993
return sprint_realloc_by_type(buf, buf_len, out_len,
994
allow_realloc, var, NULL, NULL,
1000
#ifdef OPAQUE_SPECIAL_TYPES
1001
switch (var->type) {
1002
case ASN_OPAQUE_COUNTER64:
1003
case ASN_OPAQUE_U64:
1004
case ASN_OPAQUE_I64:
1005
return sprint_realloc_counter64(buf, buf_len, out_len,
1006
allow_realloc, var, enums, hint,
1010
case ASN_OPAQUE_FLOAT:
1011
return sprint_realloc_float(buf, buf_len, out_len, allow_realloc,
1012
var, enums, hint, units);
1015
case ASN_OPAQUE_DOUBLE:
1016
return sprint_realloc_double(buf, buf_len, out_len, allow_realloc,
1017
var, enums, hint, units);
1022
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1023
u_char str[] = "OPAQUE: ";
1024
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1028
if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc,
1029
var->val.string, var->val_len)) {
1032
#ifdef OPAQUE_SPECIAL_TYPES
1037
(buf, buf_len, out_len, allow_realloc,
1038
(const u_char *) " ")
1039
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
1040
(const u_char *) units));
1047
* Prints an object identifier into a buffer.
1049
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1050
* needed size. (Note: *buf may change due to this.)
1052
* @param buf Address of the buffer to print to.
1053
* @param buf_len Address to an integer containing the size of buf.
1054
* @param out_len Incremented by the number of characters printed.
1055
* @param allow_realloc if not zero reallocate the buffer to fit the
1057
* @param var The variable to encode.
1058
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1059
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1060
* See RFC 1903 Section 3.1 for details. may be NULL.
1061
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1063
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1064
* small when not allowed to realloc.)
1067
sprint_realloc_object_identifier(u_char ** buf, size_t * buf_len,
1068
size_t * out_len, int allow_realloc,
1069
const netsnmp_variable_list * var,
1070
const struct enum_list *enums,
1071
const char *hint, const char *units)
1073
int buf_overflow = 0;
1075
if ((var->type != ASN_OBJECT_ID) &&
1076
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1078
"Wrong Type (should be OBJECT IDENTIFIER): ";
1079
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1080
return sprint_realloc_by_type(buf, buf_len, out_len,
1081
allow_realloc, var, NULL, NULL,
1088
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1089
u_char str[] = "OID: ";
1090
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1095
netsnmp_sprint_realloc_objid_tree(buf, buf_len, out_len, allow_realloc,
1097
(oid *) (var->val.objid),
1098
var->val_len / sizeof(oid));
1106
(buf, buf_len, out_len, allow_realloc,
1107
(const u_char *) " ")
1108
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
1109
(const u_char *) units));
1117
* Prints a timetick variable into a buffer.
1119
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1120
* needed size. (Note: *buf may change due to this.)
1122
* @param buf Address of the buffer to print to.
1123
* @param buf_len Address to an integer containing the size of buf.
1124
* @param out_len Incremented by the number of characters printed.
1125
* @param allow_realloc if not zero reallocate the buffer to fit the
1127
* @param var The variable to encode.
1128
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1129
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1130
* See RFC 1903 Section 3.1 for details. may be NULL.
1131
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1133
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1134
* small when not allowed to realloc.)
1137
sprint_realloc_timeticks(u_char ** buf, size_t * buf_len, size_t * out_len,
1139
const netsnmp_variable_list * var,
1140
const struct enum_list *enums,
1141
const char *hint, const char *units)
1145
if ((var->type != ASN_TIMETICKS) &&
1146
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1147
u_char str[] = "Wrong Type (should be Timeticks): ";
1148
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1149
return sprint_realloc_by_type(buf, buf_len, out_len,
1150
allow_realloc, var, NULL, NULL,
1157
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS)) {
1159
sprintf(str, "%lu", *(u_long *) var->val.integer);
1161
(buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
1166
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1168
sprintf(str, "Timeticks: (%lu) ", *(u_long *) var->val.integer);
1170
(buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
1174
uptimeString(*(u_long *) (var->val.integer), timebuf);
1176
(buf, buf_len, out_len, allow_realloc, (const u_char *) timebuf)) {
1181
(buf, buf_len, out_len, allow_realloc,
1182
(const u_char *) " ")
1183
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
1184
(const u_char *) units));
1191
* Prints an integer according to the hint into a buffer.
1193
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1194
* needed size. (Note: *buf may change due to this.)
1196
* @param buf Address of the buffer to print to.
1197
* @param buf_len Address to an integer containing the size of buf.
1198
* @param out_len Incremented by the number of characters printed.
1199
* @param allow_realloc if not zero reallocate the buffer to fit the
1201
* @param var The variable to encode.
1202
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1203
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1204
* See RFC 1903 Section 3.1 for details. may _NOT_ be NULL.
1205
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1207
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1208
* small when not allowed to realloc.)
1211
sprint_realloc_hinted_integer(u_char ** buf, size_t * buf_len,
1212
size_t * out_len, int allow_realloc,
1213
long val, const char decimaltype,
1214
const char *hint, const char *units)
1216
char fmt[10] = "%l@", tmp[256];
1219
if (hint[1] == '-') {
1220
shift = atoi(hint + 2);
1225
if (hint[0] == 'd') {
1227
* We might *actually* want a 'u' here.
1229
fmt[2] = decimaltype;
1232
* DISPLAY-HINT character is 'b', 'o', or 'x'.
1237
sprintf(tmp, fmt, val);
1243
tmp[len] = tmp[len - 1];
1251
tmp[shift] = tmp[len];
1260
return snmp_strcat(buf, buf_len, out_len, allow_realloc, tmp);
1265
* Prints an integer into a buffer.
1267
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1268
* needed size. (Note: *buf may change due to this.)
1270
* @param buf Address of the buffer to print to.
1271
* @param buf_len Address to an integer containing the size of buf.
1272
* @param out_len Incremented by the number of characters printed.
1273
* @param allow_realloc if not zero reallocate the buffer to fit the
1275
* @param var The variable to encode.
1276
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1277
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1278
* See RFC 1903 Section 3.1 for details. may be NULL.
1279
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1281
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1282
* small when not allowed to realloc.)
1285
sprint_realloc_integer(u_char ** buf, size_t * buf_len, size_t * out_len,
1287
const netsnmp_variable_list * var,
1288
const struct enum_list *enums,
1289
const char *hint, const char *units)
1291
char *enum_string = NULL;
1293
if ((var->type != ASN_INTEGER) &&
1294
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1295
u_char str[] = "Wrong Type (should be INTEGER): ";
1296
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1297
return sprint_realloc_by_type(buf, buf_len, out_len,
1298
allow_realloc, var, NULL, NULL,
1304
for (; enums; enums = enums->next) {
1305
if (enums->value == *var->val.integer) {
1306
enum_string = enums->label;
1311
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1312
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
1313
(const u_char *) "INTEGER: ")) {
1318
if (enum_string == NULL ||
1319
netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) {
1321
if (!(sprint_realloc_hinted_integer(buf, buf_len, out_len,
1323
*var->val.integer, 'd',
1329
sprintf(str, "%ld", *var->val.integer);
1331
(buf, buf_len, out_len, allow_realloc,
1332
(const u_char *) str)) {
1336
} else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1338
(buf, buf_len, out_len, allow_realloc,
1339
(const u_char *) enum_string)) {
1344
sprintf(str, "(%ld)", *var->val.integer);
1346
(buf, buf_len, out_len, allow_realloc,
1347
(const u_char *) enum_string)) {
1351
(buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
1358
(buf, buf_len, out_len, allow_realloc,
1359
(const u_char *) " ")
1360
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
1361
(const u_char *) units));
1368
* Prints an unsigned integer into a buffer.
1370
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1371
* needed size. (Note: *buf may change due to this.)
1373
* @param buf Address of the buffer to print to.
1374
* @param buf_len Address to an integer containing the size of buf.
1375
* @param out_len Incremented by the number of characters printed.
1376
* @param allow_realloc if not zero reallocate the buffer to fit the
1378
* @param var The variable to encode.
1379
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1380
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1381
* See RFC 1903 Section 3.1 for details. may be NULL.
1382
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1384
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1385
* small when not allowed to realloc.)
1388
sprint_realloc_uinteger(u_char ** buf, size_t * buf_len, size_t * out_len,
1390
const netsnmp_variable_list * var,
1391
const struct enum_list *enums,
1392
const char *hint, const char *units)
1394
char *enum_string = NULL;
1396
if ((var->type != ASN_UINTEGER) &&
1397
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1398
u_char str[] = "Wrong Type (should be UInteger32): ";
1399
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1400
return sprint_realloc_by_type(buf, buf_len, out_len,
1401
allow_realloc, var, NULL, NULL,
1408
for (; enums; enums = enums->next) {
1409
if (enums->value == *var->val.integer) {
1410
enum_string = enums->label;
1415
if (enum_string == NULL ||
1416
netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) {
1418
if (!(sprint_realloc_hinted_integer(buf, buf_len, out_len,
1420
*var->val.integer, 'u',
1426
sprintf(str, "%lu", *var->val.integer);
1428
(buf, buf_len, out_len, allow_realloc,
1429
(const u_char *) str)) {
1433
} else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1435
(buf, buf_len, out_len, allow_realloc,
1436
(const u_char *) enum_string)) {
1441
sprintf(str, "(%lu)", *var->val.integer);
1443
(buf, buf_len, out_len, allow_realloc,
1444
(const u_char *) enum_string)) {
1448
(buf, buf_len, out_len, allow_realloc, (const u_char *) str)) {
1455
(buf, buf_len, out_len, allow_realloc,
1456
(const u_char *) " ")
1457
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
1458
(const u_char *) units));
1465
* Prints a gauge value into a buffer.
1467
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1468
* needed size. (Note: *buf may change due to this.)
1470
* @param buf Address of the buffer to print to.
1471
* @param buf_len Address to an integer containing the size of buf.
1472
* @param out_len Incremented by the number of characters printed.
1473
* @param allow_realloc if not zero reallocate the buffer to fit the
1475
* @param var The variable to encode.
1476
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1477
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1478
* See RFC 1903 Section 3.1 for details. may be NULL.
1479
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1481
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1482
* small when not allowed to realloc.)
1485
sprint_realloc_gauge(u_char ** buf, size_t * buf_len, size_t * out_len,
1487
const netsnmp_variable_list * var,
1488
const struct enum_list *enums,
1489
const char *hint, const char *units)
1493
if ((var->type != ASN_GAUGE) &&
1494
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1496
"Wrong Type (should be Gauge32 or Unsigned32): ";
1497
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1498
return sprint_realloc_by_type(buf, buf_len, out_len,
1499
allow_realloc, var, NULL, NULL,
1506
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1507
u_char str[] = "Gauge32: ";
1508
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1513
if (!sprint_realloc_hinted_integer(buf, buf_len, out_len,
1515
*var->val.integer, 'u', hint,
1520
sprintf(tmp, "%lu", *var->val.integer);
1522
(buf, buf_len, out_len, allow_realloc, (const u_char *) tmp)) {
1528
(buf, buf_len, out_len, allow_realloc,
1529
(const u_char *) " ")
1530
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
1531
(const u_char *) units));
1538
* Prints a counter value into a buffer.
1540
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1541
* needed size. (Note: *buf may change due to this.)
1543
* @param buf Address of the buffer to print to.
1544
* @param buf_len Address to an integer containing the size of buf.
1545
* @param out_len Incremented by the number of characters printed.
1546
* @param allow_realloc if not zero reallocate the buffer to fit the
1548
* @param var The variable to encode.
1549
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1550
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1551
* See RFC 1903 Section 3.1 for details. may be NULL.
1552
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1554
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1555
* small when not allowed to realloc.)
1558
sprint_realloc_counter(u_char ** buf, size_t * buf_len, size_t * out_len,
1560
const netsnmp_variable_list * var,
1561
const struct enum_list *enums,
1562
const char *hint, const char *units)
1566
if ((var->type != ASN_COUNTER) &&
1567
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1568
u_char str[] = "Wrong Type (should be Counter32): ";
1569
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1570
return sprint_realloc_by_type(buf, buf_len, out_len,
1571
allow_realloc, var, NULL, NULL,
1578
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1579
u_char str[] = "Counter32: ";
1580
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1584
sprintf(tmp, "%lu", *var->val.integer);
1586
(buf, buf_len, out_len, allow_realloc, (const u_char *) tmp)) {
1591
(buf, buf_len, out_len, allow_realloc,
1592
(const u_char *) " ")
1593
&& snmp_strcat(buf, buf_len, out_len, allow_realloc,
1594
(const u_char *) units));
1601
* Prints a network address into a buffer.
1603
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1604
* needed size. (Note: *buf may change due to this.)
1606
* @param buf Address of the buffer to print to.
1607
* @param buf_len Address to an integer containing the size of buf.
1608
* @param out_len Incremented by the number of characters printed.
1609
* @param allow_realloc if not zero reallocate the buffer to fit the
1611
* @param var The variable to encode.
1612
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1613
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1614
* See RFC 1903 Section 3.1 for details. may be NULL.
1615
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1617
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1618
* small when not allowed to realloc.)
1621
sprint_realloc_networkaddress(u_char ** buf, size_t * buf_len,
1622
size_t * out_len, int allow_realloc,
1623
const netsnmp_variable_list * var,
1624
const struct enum_list *enums, const char *hint,
1629
if ((var->type != ASN_IPADDRESS) &&
1630
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1631
u_char str[] = "Wrong Type (should be NetworkAddress): ";
1632
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1633
return sprint_realloc_by_type(buf, buf_len, out_len,
1634
allow_realloc, var, NULL, NULL,
1641
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1642
u_char str[] = "Network Address: ";
1643
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1648
while ((*out_len + (var->val_len * 3) + 2) >= *buf_len) {
1649
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
1654
for (i = 0; i < var->val_len; i++) {
1655
sprintf((char *) (*buf + *out_len), "%02X", var->val.string[i]);
1657
if (i < var->val_len - 1) {
1658
*(*buf + *out_len) = ':';
1667
* Prints an ip-address into a buffer.
1669
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1670
* needed size. (Note: *buf may change due to this.)
1672
* @param buf Address of the buffer to print to.
1673
* @param buf_len Address to an integer containing the size of buf.
1674
* @param out_len Incremented by the number of characters printed.
1675
* @param allow_realloc if not zero reallocate the buffer to fit the
1677
* @param var The variable to encode.
1678
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1679
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1680
* See RFC 1903 Section 3.1 for details. may be NULL.
1681
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1683
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1684
* small when not allowed to realloc.)
1687
sprint_realloc_ipaddress(u_char ** buf, size_t * buf_len, size_t * out_len,
1689
const netsnmp_variable_list * var,
1690
const struct enum_list *enums,
1691
const char *hint, const char *units)
1693
u_char *ip = var->val.string;
1695
if ((var->type != ASN_IPADDRESS) &&
1696
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1697
u_char str[] = "Wrong Type (should be IpAddress): ";
1698
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1699
return sprint_realloc_by_type(buf, buf_len, out_len,
1700
allow_realloc, var, NULL, NULL,
1707
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1708
u_char str[] = "IpAddress: ";
1709
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1713
while ((*out_len + 17) >= *buf_len) {
1714
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
1719
sprintf((char *) (*buf + *out_len), "%d.%d.%d.%d",
1720
ip[0], ip[1], ip[2], ip[3]);
1721
*out_len += strlen((char *) (*buf + *out_len));
1727
* Prints a null value into a buffer.
1729
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1730
* needed size. (Note: *buf may change due to this.)
1732
* @param buf Address of the buffer to print to.
1733
* @param buf_len Address to an integer containing the size of buf.
1734
* @param out_len Incremented by the number of characters printed.
1735
* @param allow_realloc if not zero reallocate the buffer to fit the
1737
* @param var The variable to encode.
1738
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1739
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1740
* See RFC 1903 Section 3.1 for details. may be NULL.
1741
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1743
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1744
* small when not allowed to realloc.)
1747
sprint_realloc_null(u_char ** buf, size_t * buf_len, size_t * out_len,
1749
const netsnmp_variable_list * var,
1750
const struct enum_list *enums,
1751
const char *hint, const char *units)
1753
if ((var->type != ASN_NULL) &&
1754
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1755
u_char str[] = "Wrong Type (should be NULL): ";
1756
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1757
return sprint_realloc_by_type(buf, buf_len, out_len,
1758
allow_realloc, var, NULL, NULL,
1764
u_char str[] = "NULL";
1765
return snmp_strcat(buf, buf_len, out_len, allow_realloc, str);
1771
* Prints a bit string into a buffer.
1773
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1774
* needed size. (Note: *buf may change due to this.)
1776
* @param buf Address of the buffer to print to.
1777
* @param buf_len Address to an integer containing the size of buf.
1778
* @param out_len Incremented by the number of characters printed.
1779
* @param allow_realloc if not zero reallocate the buffer to fit the
1781
* @param var The variable to encode.
1782
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1783
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1784
* See RFC 1903 Section 3.1 for details. may be NULL.
1785
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1787
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1788
* small when not allowed to realloc.)
1791
sprint_realloc_bitstring(u_char ** buf, size_t * buf_len, size_t * out_len,
1793
const netsnmp_variable_list * var,
1794
const struct enum_list *enums,
1795
const char *hint, const char *units)
1801
if ((var->type != ASN_BIT_STR && var->type != ASN_OCTET_STR) &&
1802
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1803
u_char str[] = "Wrong Type (should be BITS): ";
1804
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1805
return sprint_realloc_by_type(buf, buf_len, out_len,
1806
allow_realloc, var, NULL, NULL,
1813
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1814
u_char str[] = "\"";
1815
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1819
u_char str[] = "BITS: ";
1820
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1824
if (!sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc,
1825
var->val.bitstring, var->val_len)) {
1829
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1830
u_char str[] = "\"";
1831
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1835
cp = var->val.bitstring;
1836
for (len = 0; len < (int) var->val_len; len++) {
1837
for (bit = 0; bit < 8; bit++) {
1838
if (*cp & (0x80 >> bit)) {
1840
for (; enums; enums = enums->next) {
1841
if (enums->value == (len * 8) + bit) {
1842
enum_string = enums->label;
1846
if (enum_string == NULL ||
1847
netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
1848
NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM)) {
1850
sprintf(str, "%d ", (len * 8) + bit);
1852
(buf, buf_len, out_len, allow_realloc,
1853
(const u_char *) str)) {
1858
sprintf(str, "(%d) ", (len * 8) + bit);
1860
(buf, buf_len, out_len, allow_realloc,
1861
(const u_char *) enum_string)) {
1865
(buf, buf_len, out_len, allow_realloc,
1866
(const u_char *) str)) {
1879
sprint_realloc_nsapaddress(u_char ** buf, size_t * buf_len,
1880
size_t * out_len, int allow_realloc,
1881
const netsnmp_variable_list * var,
1882
const struct enum_list *enums, const char *hint,
1885
if ((var->type != ASN_NSAP) &&
1886
(!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
1887
u_char str[] = "Wrong Type (should be NsapAddress): ";
1888
if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1889
return sprint_realloc_by_type(buf, buf_len, out_len,
1890
allow_realloc, var, NULL, NULL,
1897
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
1898
u_char str[] = "NsapAddress: ";
1899
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) {
1904
return sprint_realloc_hexstring(buf, buf_len, out_len, allow_realloc,
1905
var->val.string, var->val_len);
1910
* Fallback routine for a bad type, prints "Variable has bad type" into a buffer.
1912
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1913
* needed size. (Note: *buf may change due to this.)
1915
* @param buf Address of the buffer to print to.
1916
* @param buf_len Address to an integer containing the size of buf.
1917
* @param out_len Incremented by the number of characters printed.
1918
* @param allow_realloc if not zero reallocate the buffer to fit the
1920
* @param var The variable to encode.
1921
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1922
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1923
* See RFC 1903 Section 3.1 for details. may be NULL.
1924
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1926
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1927
* small when not allowed to realloc.)
1930
sprint_realloc_badtype(u_char ** buf, size_t * buf_len, size_t * out_len,
1932
const netsnmp_variable_list * var,
1933
const struct enum_list *enums,
1934
const char *hint, const char *units)
1936
u_char str[] = "Variable has bad type";
1938
return snmp_strcat(buf, buf_len, out_len, allow_realloc, str);
1944
* Universal print routine, prints a variable into a buffer according to the variable
1947
* If allow_realloc is true the buffer will be (re)allocated to fit in the
1948
* needed size. (Note: *buf may change due to this.)
1950
* @param buf Address of the buffer to print to.
1951
* @param buf_len Address to an integer containing the size of buf.
1952
* @param out_len Incremented by the number of characters printed.
1953
* @param allow_realloc if not zero reallocate the buffer to fit the
1955
* @param var The variable to encode.
1956
* @param enums The enumeration ff this variable is enumerated. may be NULL.
1957
* @param hint Contents of the DISPLAY-HINT clause of the MIB.
1958
* See RFC 1903 Section 3.1 for details. may be NULL.
1959
* @param units Contents of the UNITS clause of the MIB. may be NULL.
1961
* @return 1 on success, or 0 on failure (out of memory, or buffer to
1962
* small when not allowed to realloc.)
1965
sprint_realloc_by_type(u_char ** buf, size_t * buf_len, size_t * out_len,
1967
const netsnmp_variable_list * var,
1968
const struct enum_list *enums,
1969
const char *hint, const char *units)
1971
DEBUGMSGTL(("output", "sprint_by_type, type %d\n", var->type));
1973
switch (var->type) {
1975
return sprint_realloc_integer(buf, buf_len, out_len, allow_realloc,
1976
var, enums, hint, units);
1978
return sprint_realloc_octet_string(buf, buf_len, out_len,
1979
allow_realloc, var, enums, hint,
1982
return sprint_realloc_bitstring(buf, buf_len, out_len,
1983
allow_realloc, var, enums, hint,
1986
return sprint_realloc_opaque(buf, buf_len, out_len, allow_realloc,
1987
var, enums, hint, units);
1989
return sprint_realloc_object_identifier(buf, buf_len, out_len,
1990
allow_realloc, var, enums,
1993
return sprint_realloc_timeticks(buf, buf_len, out_len,
1994
allow_realloc, var, enums, hint,
1997
return sprint_realloc_gauge(buf, buf_len, out_len, allow_realloc,
1998
var, enums, hint, units);
2000
return sprint_realloc_counter(buf, buf_len, out_len, allow_realloc,
2001
var, enums, hint, units);
2003
return sprint_realloc_ipaddress(buf, buf_len, out_len,
2004
allow_realloc, var, enums, hint,
2007
return sprint_realloc_null(buf, buf_len, out_len, allow_realloc,
2008
var, enums, hint, units);
2010
return sprint_realloc_uinteger(buf, buf_len, out_len,
2011
allow_realloc, var, enums, hint,
2014
#ifdef OPAQUE_SPECIAL_TYPES
2015
case ASN_OPAQUE_U64:
2016
case ASN_OPAQUE_I64:
2017
case ASN_OPAQUE_COUNTER64:
2018
#endif /* OPAQUE_SPECIAL_TYPES */
2019
return sprint_realloc_counter64(buf, buf_len, out_len,
2020
allow_realloc, var, enums, hint,
2022
#ifdef OPAQUE_SPECIAL_TYPES
2023
case ASN_OPAQUE_FLOAT:
2024
return sprint_realloc_float(buf, buf_len, out_len, allow_realloc,
2025
var, enums, hint, units);
2026
case ASN_OPAQUE_DOUBLE:
2027
return sprint_realloc_double(buf, buf_len, out_len, allow_realloc,
2028
var, enums, hint, units);
2029
#endif /* OPAQUE_SPECIAL_TYPES */
2031
DEBUGMSGTL(("sprint_by_type", "bad type: %d\n", var->type));
2032
return sprint_realloc_badtype(buf, buf_len, out_len, allow_realloc,
2033
var, enums, hint, units);
2038
#ifndef DISABLE_MIB_LOADING
2040
* Retrieves the tree head.
2042
* @return the tree head.
2050
static char *confmibdir = NULL;
2051
static char *confmibs = NULL;
2054
handle_mibdirs_conf(const char *token, char *line)
2059
ctmp = (char *) malloc(strlen(confmibdir) + strlen(line) + 2);
2061
DEBUGMSGTL(("read_config:initmib", "mibdir conf malloc failed"));
2066
sprintf(ctmp, "%s%c%s", confmibdir, ENV_SEPARATOR_CHAR, line);
2067
SNMP_FREE(confmibdir);
2070
confmibdir = strdup(line);
2072
DEBUGMSGTL(("read_config:initmib", "using mibdirs: %s\n", confmibdir));
2076
handle_mibs_conf(const char *token, char *line)
2081
ctmp = (char *) malloc(strlen(confmibs) + strlen(line) + 2);
2083
DEBUGMSGTL(("read_config:initmib", "mibs conf malloc failed"));
2088
sprintf(ctmp, "%s%c%s", confmibs, ENV_SEPARATOR_CHAR, line);
2089
SNMP_FREE(confmibs);
2092
confmibs = strdup(line);
2094
DEBUGMSGTL(("read_config:initmib", "using mibs: %s\n", confmibs));
2099
handle_mibfile_conf(const char *token, char *line)
2101
DEBUGMSGTL(("read_config:initmib", "reading mibfile: %s\n", line));
2107
handle_print_numeric(const char *token, char *line)
2111
value = strtok(line, " \t\n");
2112
if ((strcasecmp(value, "yes") == 0) ||
2113
(strcasecmp(value, "true") == 0) ||
2116
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
2117
NETSNMP_OID_OUTPUT_NUMERIC);
2122
snmp_out_toggle_options(char *options)
2125
switch (*options++) {
2127
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT,
2128
NETSNMP_STRING_OUTPUT_ASCII);
2131
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS);
2134
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM);
2137
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES);
2140
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
2141
NETSNMP_OID_OUTPUT_FULL);
2144
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
2145
NETSNMP_OID_OUTPUT_NUMERIC);
2148
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT);
2151
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT, 1);
2152
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT);
2155
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
2156
NETSNMP_OID_OUTPUT_SUFFIX);
2159
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
2160
NETSNMP_OID_OUTPUT_MODULE);
2163
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS);
2166
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_HEX_TEXT);
2169
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
2170
NETSNMP_OID_OUTPUT_UCD);
2173
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PRINT_UNITS);
2176
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE);
2179
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_STRING_OUTPUT_FORMAT,
2180
NETSNMP_STRING_OUTPUT_HEX);
2183
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX);
2193
snmp_out_toggle_options_usage(const char *lead, FILE * outf)
2195
fprintf(outf, "%sa: print all strings in ascii format\n", lead);
2196
fprintf(outf, "%sb: do not break OID indexes down\n", lead);
2197
fprintf(outf, "%se: print enums numerically\n", lead);
2198
fprintf(outf, "%sE: escape quotes in string indices\n", lead);
2199
fprintf(outf, "%sf: print full OIDs on output\n", lead);
2200
fprintf(outf, "%sn: print OIDs numerically\n", lead);
2201
fprintf(outf, "%sq: quick print for easier parsing\n", lead);
2202
fprintf(outf, "%sQ: quick print with equal-signs\n", lead); /* @@JDW */
2203
fprintf(outf, "%ss: print only last symbolic element of OID\n", lead);
2204
fprintf(outf, "%sS: print MIB module-id plus last element\n", lead);
2205
fprintf(outf, "%st: print timeticks unparsed as numeric integers\n",
2208
"%sT: print human-readable text along with hex strings\n",
2210
fprintf(outf, "%su: print OIDs using UCD-style prefix suppression\n",
2212
fprintf(outf, "%sU: don't print units\n", lead);
2213
fprintf(outf, "%sv: print values only (not OID = value)\n", lead);
2214
fprintf(outf, "%sx: print all strings in hex format\n", lead);
2215
fprintf(outf, "%sX: extended index format\n", lead);
2219
snmp_in_options(char *optarg, int argc, char *const *argv)
2223
for (cp = optarg; *cp; cp++) {
2226
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_REGEX_ACCESS);
2229
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_RANDOM_ACCESS);
2232
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_CHECK_RANGE);
2235
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NO_DISPLAY_HINT);
2238
netsnmp_ds_toggle_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_READ_UCD_STYLE_OID);
2241
/* What if argc/argv are null ? */
2243
cp = argv[optind++];
2244
netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
2245
NETSNMP_DS_LIB_OIDSUFFIX,
2250
/* What if argc/argv are null ? */
2252
cp = argv[optind++];
2253
netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
2254
NETSNMP_DS_LIB_OIDPREFIX,
2260
* Here? Or in snmp_parse_args?
2261
snmp_log(LOG_ERR, "Unknown input option passed to -I: %c.\n", *cp);
2270
snmp_in_toggle_options(char *options)
2272
return snmp_in_options( options, 0, NULL );
2277
* Prints out a help usage for the in* toggle options.
2279
* @param lead The lead to print for every line.
2280
* @param outf The file descriptor to write to.
2284
snmp_in_toggle_options_usage(const char *lead, FILE * outf)
2286
fprintf(outf, "%sb: do best/regex matching to find a MIB node\n", lead);
2287
fprintf(outf, "%sh: don't apply DISPLAY-HINTs\n", lead);
2288
fprintf(outf, "%sr: do not check values for range/type legality\n", lead);
2289
fprintf(outf, "%sR: do random access to OID labels\n", lead);
2291
"%su: top-level OIDs must have '.' prefix (UCD-style)\n", lead);
2293
"%ss SUFFIX: Append all textual OIDs with SUFFIX before parsing\n",
2296
"%sS PREFIX: Prepend all textual OIDs with PREFIX before parsing\n",
2304
register_mib_handlers(void)
2306
#ifndef DISABLE_MIB_LOADING
2307
register_prenetsnmp_mib_handler("snmp", "mibdirs",
2308
handle_mibdirs_conf, NULL,
2309
"[mib-dirs|+mib-dirs]");
2310
register_prenetsnmp_mib_handler("snmp", "mibs",
2311
handle_mibs_conf, NULL,
2312
"[mib-tokens|+mib-tokens]");
2313
register_config_handler("snmp", "mibfile",
2314
handle_mibfile_conf, NULL, "mibfile-to-read");
2316
* register the snmp.conf configuration handlers for default
2320
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "showMibErrors",
2321
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_ERRORS);
2322
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "strictCommentTerm",
2323
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_COMMENT_TERM);
2324
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "mibAllowUnderline",
2325
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_PARSE_LABEL);
2326
netsnmp_ds_register_premib(ASN_INTEGER, "snmp", "mibWarningLevel",
2327
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_WARNINGS);
2328
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "mibReplaceWithLatest",
2329
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_REPLACE);
2332
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "printNumericEnums",
2333
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM);
2334
register_prenetsnmp_mib_handler("snmp", "printNumericOids",
2335
handle_print_numeric, NULL, "(1|yes|true|0|no|false)");
2336
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "escapeQuotes",
2337
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES);
2338
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "dontBreakdownOids",
2339
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS);
2340
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "quickPrinting",
2341
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT);
2342
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "numericTimeticks",
2343
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS);
2344
netsnmp_ds_register_premib(ASN_INTEGER, "snmp", "oidOutputFormat",
2345
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
2346
netsnmp_ds_register_premib(ASN_INTEGER, "snmp", "suffixPrinting",
2347
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
2348
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "extendedIndex",
2349
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX);
2350
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "printHexText",
2351
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_HEX_TEXT);
2352
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "printValueOnly",
2353
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE);
2354
netsnmp_ds_register_premib(ASN_BOOLEAN, "snmp", "dontPrintUnits",
2355
NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PRINT_UNITS);
2358
#ifndef DISABLE_MIB_LOADING
2360
* function : netsnmp_set_mib_directory
2361
* - This function sets the string of the directories
2362
* from which the MIB modules will be searched or
2364
* arguments: const char *dir, which are the directories
2365
* from which the MIB modules will be searched or
2370
netsnmp_set_mib_directory(const char *dir)
2373
char *olddir, *tmpdir = NULL;
2380
olddir = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
2381
NETSNMP_DS_LIB_MIBDIRS);
2384
/** New dir starts with '+', thus we add it. */
2385
tmpdir = malloc(strlen(dir) + strlen(olddir) + 2);
2387
DEBUGMSGTL(("read_config:initmib", "set mibdir malloc failed"));
2390
sprintf(tmpdir, "%s%c%s", ++dir, ENV_SEPARATOR_CHAR, olddir);
2396
/** If dir starts with '+' skip '+' it. */
2397
newdir = ((*dir == '+') ? ++dir : dir);
2399
netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIBDIRS,
2402
/** set_string calls strdup, so if we allocated memory, free it */
2403
if (tmpdir == newdir) {
2409
* function : netsnmp_get_mib_directory
2410
* - This function returns a string of the directories
2411
* from which the MIB modules will be searched or
2413
* If the value still does not exists, it will be made
2414
* from the evironment variable 'MIBDIRS' and/or the
2417
* returns : char * of the directories in which the MIB modules
2418
* will be searched/loaded.
2422
netsnmp_get_mib_directory(void)
2427
dir = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIBDIRS);
2429
DEBUGMSGTL(("get_mib_directory", "no mib directories set\n"));
2431
/** Check if the environment variable is set */
2432
dir = getenv("MIBDIRS");
2434
DEBUGMSGTL(("get_mib_directory", "no mib directories set by environment\n"));
2435
/** Not set use hard coded path */
2436
if (confmibdir == NULL) {
2437
DEBUGMSGTL(("get_mib_directory", "no mib directories set by config\n"));
2438
netsnmp_set_mib_directory(DEFAULT_MIBDIRS);
2440
else if (*confmibdir == '+') {
2441
DEBUGMSGTL(("get_mib_directory", "mib directories set by config (but added)\n"));
2442
netsnmp_set_mib_directory(DEFAULT_MIBDIRS);
2443
netsnmp_set_mib_directory(confmibdir);
2446
DEBUGMSGTL(("get_mib_directory", "mib directories set by config\n"));
2447
netsnmp_set_mib_directory(confmibdir);
2449
} else if (*dir == '+') {
2450
DEBUGMSGTL(("get_mib_directory", "mib directories set by environment (but added)\n"));
2451
netsnmp_set_mib_directory(DEFAULT_MIBDIRS);
2452
netsnmp_set_mib_directory(dir);
2454
DEBUGMSGTL(("get_mib_directory", "mib directories set by environment\n"));
2455
netsnmp_set_mib_directory(dir);
2457
dir = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIBDIRS);
2459
DEBUGMSGTL(("get_mib_directory", "mib directories set '%s'\n", dir));
2464
* function : netsnmp_fixup_mib_directory
2469
netsnmp_fixup_mib_directory(void)
2471
char *homepath = getenv("HOME");
2472
char *mibpath = netsnmp_get_mib_directory();
2473
char *oldmibpath = NULL;
2478
if (homepath && mibpath) {
2479
DEBUGMSGTL(("fixup_mib_directory", "mib directories '%s'\n", mibpath));
2480
while ((ptr_home = strstr(mibpath, "$HOME"))) {
2481
new_mibpath = (char *)malloc(strlen(mibpath) - strlen("$HOME") +
2482
strlen(homepath)+1);
2484
*ptr_home = 0; /* null out the spot where we stop copying */
2485
sprintf(new_mibpath, "%s%s%s", mibpath, homepath,
2486
ptr_home + strlen("$HOME"));
2487
/** swap in the new value and repeat */
2488
mibpath = new_mibpath;
2489
if (oldmibpath != NULL) {
2490
SNMP_FREE(oldmibpath);
2492
oldmibpath = new_mibpath;
2498
netsnmp_set_mib_directory(mibpath);
2500
/* The above copies the mibpath for us, so... */
2502
if (oldmibpath != NULL) {
2503
SNMP_FREE(oldmibpath);
2511
* Initialises the mib reader.
2513
* Reads in all settings from the environment.
2519
char *env_var, *entry;
2520
PrefixListPtr pp = &mib_prefixes[0];
2524
init_mib_internals();
2527
* Initialise the MIB directory/ies
2529
netsnmp_fixup_mib_directory();
2530
env_var = strdup(netsnmp_get_mib_directory());
2532
DEBUGMSGTL(("init_mib",
2533
"Seen MIBDIRS: Looking in '%s' for mib dirs ...\n",
2536
entry = strtok(env_var, ENV_SEPARATOR);
2539
entry = strtok(NULL, ENV_SEPARATOR);
2543
init_mib_internals();
2546
* Read in any modules or mibs requested
2549
env_var = getenv("MIBS");
2550
if (env_var == NULL) {
2551
if (confmibs != NULL)
2552
env_var = strdup(confmibs);
2554
env_var = strdup(DEFAULT_MIBS);
2556
env_var = strdup(env_var);
2558
if (env_var && *env_var == '+') {
2560
(char *) malloc(strlen(DEFAULT_MIBS) + strlen(env_var) + 2);
2562
DEBUGMSGTL(("init_mib", "env mibs malloc failed"));
2565
sprintf(entry, "%s%c%s", DEFAULT_MIBS, ENV_SEPARATOR_CHAR,
2571
DEBUGMSGTL(("init_mib",
2572
"Seen MIBS: Looking in '%s' for mib files ...\n",
2574
entry = strtok(env_var, ENV_SEPARATOR);
2576
if (strcasecmp(entry, DEBUG_ALWAYS_TOKEN) == 0) {
2578
} else if (strstr(entry, "/") != 0) {
2583
entry = strtok(NULL, ENV_SEPARATOR);
2588
env_var = getenv("MIBFILES");
2589
if (env_var != NULL) {
2590
if (*env_var == '+') {
2591
#ifdef DEFAULT_MIBFILES
2593
(char *) malloc(strlen(DEFAULT_MIBFILES) +
2594
strlen(env_var) + 2);
2596
DEBUGMSGTL(("init_mib", "env mibfiles malloc failed"));
2598
sprintf(entry, "%s%c%s", DEFAULT_MIBFILES, ENV_SEPARATOR_CHAR,
2603
env_var = strdup(env_var + 1);
2606
env_var = strdup(env_var);
2609
#ifdef DEFAULT_MIBFILES
2610
env_var = strdup(DEFAULT_MIBFILES);
2615
DEBUGMSGTL(("init_mib",
2616
"Seen MIBFILES: Looking in '%s' for mib files ...\n",
2618
entry = strtok(env_var, ENV_SEPARATOR);
2621
entry = strtok(NULL, ENV_SEPARATOR);
2626
prefix = getenv("PREFIX");
2629
prefix = Standard_Prefix;
2631
Prefix = (char *) malloc(strlen(prefix) + 2);
2633
DEBUGMSGTL(("init_mib", "Prefix malloc failed"));
2635
strcpy(Prefix, prefix);
2637
DEBUGMSGTL(("init_mib",
2638
"Seen PREFIX: Looking in '%s' for prefix ...\n", Prefix));
2641
* remove trailing dot
2644
env_var = &Prefix[strlen(Prefix) - 1];
2645
if (*env_var == '.')
2649
pp->str = Prefix; /* fixup first mib_prefix entry */
2651
* now that the list of prefixes is built, save each string length.
2654
pp->len = strlen(pp->str);
2658
Mib = tree_head; /* Backwards compatibility */
2659
tree_top = (struct tree *) calloc(1, sizeof(struct tree));
2664
tree_top->label = strdup("(top)");
2665
tree_top->child_list = tree_head;
2677
if (tree_top->label)
2678
SNMP_FREE(tree_top->label);
2679
SNMP_FREE(tree_top);
2684
if (Prefix != NULL && Prefix != &Standard_Prefix[0])
2691
* Prints the MIBs to the file fp.
2693
* @param fp The file descriptor to print to.
2696
print_mib(FILE * fp)
2698
print_subtree(fp, tree_head, 0);
2702
print_ascii_dump(FILE * fp)
2704
fprintf(fp, "dump DEFINITIONS ::= BEGIN\n");
2705
print_ascii_dump_tree(fp, tree_head, 0);
2706
fprintf(fp, "END\n");
2711
* Set's the printing function printomat in a subtree according
2714
* @param subtree The subtree to set.
2717
set_function(struct tree *subtree)
2719
subtree->printer = NULL;
2720
switch (subtree->type) {
2722
subtree->printomat = sprint_realloc_object_identifier;
2725
subtree->printomat = sprint_realloc_octet_string;
2728
subtree->printomat = sprint_realloc_integer;
2730
case TYPE_INTEGER32:
2731
subtree->printomat = sprint_realloc_integer;
2734
subtree->printomat = sprint_realloc_networkaddress;
2737
subtree->printomat = sprint_realloc_ipaddress;
2740
subtree->printomat = sprint_realloc_counter;
2743
subtree->printomat = sprint_realloc_gauge;
2745
case TYPE_TIMETICKS:
2746
subtree->printomat = sprint_realloc_timeticks;
2749
subtree->printomat = sprint_realloc_opaque;
2752
subtree->printomat = sprint_realloc_null;
2754
case TYPE_BITSTRING:
2755
subtree->printomat = sprint_realloc_bitstring;
2757
case TYPE_NSAPADDRESS:
2758
subtree->printomat = sprint_realloc_nsapaddress;
2760
case TYPE_COUNTER64:
2761
subtree->printomat = sprint_realloc_counter64;
2764
subtree->printomat = sprint_realloc_uinteger;
2766
case TYPE_UNSIGNED32:
2767
subtree->printomat = sprint_realloc_gauge;
2771
subtree->printomat = sprint_realloc_by_type;
2776
#endif /* DISABLE_MIB_LOADING */
2779
* Reads an object identifier from an input string into internal OID form.
2781
* When called, out_len must hold the maximum length of the output array.
2783
* @param input the input string.
2784
* @param output the oid wirte.
2785
* @param out_len number of subid's in output.
2787
* @return 1 if successful.
2789
* If an error occurs, this function returns 0 and MAY set snmp_errno.
2790
* snmp_errno is NOT set if SET_SNMP_ERROR evaluates to nothing.
2791
* This can make multi-threaded use a tiny bit more robust.
2794
read_objid(const char *input, oid * output, size_t * out_len)
2795
{ /* number of subid's in "output" */
2796
#ifndef DISABLE_MIB_LOADING
2797
struct tree *root = tree_top;
2798
#endif /* DISABLE_MIB_LOADING */
2799
char buf[SPRINT_MAX_LEN];
2800
int ret, max_out_len;
2805
while ((ch = *cp)) {
2806
if (('0' <= ch && ch <= '9')
2807
|| ('a' <= ch && ch <= 'z')
2808
|| ('A' <= ch && ch <= 'Z')
2814
#ifndef DISABLE_MIB_LOADING
2816
return get_node(input, output, out_len);
2817
#endif /* DISABLE_MIB_LOADING */
2821
#ifndef DISABLE_MIB_LOADING
2822
else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_READ_UCD_STYLE_OID)) {
2824
* get past leading '.', append '.' to Prefix.
2827
strncpy(buf, Prefix + 1, sizeof(buf)-1);
2829
strncpy(buf, Prefix, sizeof(buf)-1);
2830
buf[ sizeof(buf)-1 ] = 0;
2832
buf[ sizeof(buf)-1 ] = 0;
2833
strncat(buf, input, sizeof(buf)-strlen(buf));
2834
buf[ sizeof(buf)-1 ] = 0;
2837
#endif /* DISABLE_MIB_LOADING */
2839
#ifndef DISABLE_MIB_LOADING
2841
SET_SNMP_ERROR(SNMPERR_NOMIB);
2845
#endif /* DISABLE_MIB_LOADING */
2846
name = strdup(input);
2847
max_out_len = *out_len;
2849
#ifndef DISABLE_MIB_LOADING
2851
_add_strings_to_oid(root, name, output, out_len,
2855
_add_strings_to_oid(NULL, name, output, out_len,
2857
#endif /* DISABLE_MIB_LOADING */
2860
ret = SNMPERR_UNKNOWN_OBJID;
2861
SET_SNMP_ERROR(ret);
2874
netsnmp_sprint_realloc_objid(u_char ** buf, size_t * buf_len,
2875
size_t * out_len, int allow_realloc,
2877
const oid * objid, size_t objidlen)
2879
u_char *tbuf = NULL, *cp = NULL;
2880
size_t tbuf_len = 256, tout_len = 0;
2881
int tbuf_overflow = 0;
2884
if ((tbuf = (u_char *) calloc(tbuf_len, 1)) == NULL) {
2891
_oid_finish_printing(objid, objidlen,
2892
&tbuf, &tbuf_len, &tout_len,
2893
allow_realloc, &tbuf_overflow);
2895
if (tbuf_overflow) {
2896
if (!*buf_overflow) {
2897
snmp_strcat(buf, buf_len, out_len, allow_realloc, tbuf);
2904
output_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
2905
if (0 == output_format) {
2906
output_format = NETSNMP_OID_OUTPUT_NUMERIC;
2908
switch (output_format) {
2909
case NETSNMP_OID_OUTPUT_FULL:
2910
case NETSNMP_OID_OUTPUT_NUMERIC:
2911
case NETSNMP_OID_OUTPUT_SUFFIX:
2912
case NETSNMP_OID_OUTPUT_MODULE:
2916
case NETSNMP_OID_OUTPUT_NONE:
2921
if (!*buf_overflow &&
2922
!snmp_strcat(buf, buf_len, out_len, allow_realloc, cp)) {
2931
#ifdef DISABLE_MIB_LOADING
2933
netsnmp_sprint_realloc_objid_tree(u_char ** buf, size_t * buf_len,
2934
size_t * out_len, int allow_realloc,
2936
const oid * objid, size_t objidlen)
2938
netsnmp_sprint_realloc_objid(buf, buf_len, out_len, allow_realloc,
2939
buf_overflow, objid, objidlen);
2943
netsnmp_sprint_realloc_objid_tree(u_char ** buf, size_t * buf_len,
2944
size_t * out_len, int allow_realloc,
2946
const oid * objid, size_t objidlen)
2948
u_char *tbuf = NULL, *cp = NULL;
2949
size_t tbuf_len = 256, tout_len = 0;
2950
struct tree *subtree = tree_head;
2951
size_t midpoint_offset = 0;
2952
int tbuf_overflow = 0;
2955
if ((tbuf = (u_char *) calloc(tbuf_len, 1)) == NULL) {
2962
subtree = _get_realloc_symbol(objid, objidlen, subtree,
2963
&tbuf, &tbuf_len, &tout_len,
2964
allow_realloc, &tbuf_overflow, NULL,
2967
if (tbuf_overflow) {
2968
if (!*buf_overflow) {
2969
snmp_strcat(buf, buf_len, out_len, allow_realloc, tbuf);
2976
output_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
2977
if (0 == output_format) {
2978
output_format = NETSNMP_OID_OUTPUT_MODULE;
2980
switch (output_format) {
2981
case NETSNMP_OID_OUTPUT_FULL:
2982
case NETSNMP_OID_OUTPUT_NUMERIC:
2986
case NETSNMP_OID_OUTPUT_SUFFIX:
2987
case NETSNMP_OID_OUTPUT_MODULE:
2988
for (cp = tbuf; *cp; cp++);
2990
if (midpoint_offset != 0) {
2991
cp = tbuf + midpoint_offset - 2; /* beyond the '.' */
2993
while (cp >= tbuf) {
3001
while (cp >= tbuf) {
3010
if ((NETSNMP_OID_OUTPUT_MODULE == output_format)
3012
char modbuf[256] = { 0 }, *mod =
3013
module_name(subtree->modid, modbuf);
3016
* Don't add the module ID if it's just numeric (i.e. we couldn't look
3020
if (!*buf_overflow && modbuf[0] != '#') {
3022
(buf, buf_len, out_len, allow_realloc,
3023
(const u_char *) mod)
3024
|| !snmp_strcat(buf, buf_len, out_len, allow_realloc,
3025
(const u_char *) "::")) {
3032
case NETSNMP_OID_OUTPUT_UCD:
3034
PrefixListPtr pp = &mib_prefixes[0];
3039
tlen = strlen((char *) tbuf);
3045
if ((tlen > ilen) && memcmp(tbuf, testcp, ilen) == 0) {
3054
case NETSNMP_OID_OUTPUT_NONE:
3059
if (!*buf_overflow &&
3060
!snmp_strcat(buf, buf_len, out_len, allow_realloc, cp)) {
3066
#endif /* DISABLE_MIB_LOADING */
3069
sprint_realloc_objid(u_char ** buf, size_t * buf_len,
3070
size_t * out_len, int allow_realloc,
3071
const oid * objid, size_t objidlen)
3073
int buf_overflow = 0;
3075
netsnmp_sprint_realloc_objid_tree(buf, buf_len, out_len, allow_realloc,
3076
&buf_overflow, objid, objidlen);
3077
return !buf_overflow;
3081
snprint_objid(char *buf, size_t buf_len,
3082
const oid * objid, size_t objidlen)
3086
if (sprint_realloc_objid((u_char **) & buf, &buf_len, &out_len, 0,
3088
return (int) out_len;
3095
* Prints an oid to stdout.
3097
* @param objid The oid to print
3098
* @param objidlen The length of oidid.
3101
print_objid(const oid * objid, size_t objidlen)
3102
{ /* number of subidentifiers */
3103
fprint_objid(stdout, objid, objidlen);
3108
* Prints an oid to a file descriptor.
3110
* @param f The file descriptor to print to.
3111
* @param objid The oid to print
3112
* @param objidlen The length of oidid.
3115
fprint_objid(FILE * f, const oid * objid, size_t objidlen)
3116
{ /* number of subidentifiers */
3118
size_t buf_len = 256, out_len = 0;
3119
int buf_overflow = 0;
3121
if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) {
3122
fprintf(f, "[TRUNCATED]\n");
3125
netsnmp_sprint_realloc_objid_tree(&buf, &buf_len, &out_len, 1,
3126
&buf_overflow, objid, objidlen);
3128
fprintf(f, "%s [TRUNCATED]\n", buf);
3130
fprintf(f, "%s\n", buf);
3138
sprint_realloc_variable(u_char ** buf, size_t * buf_len,
3139
size_t * out_len, int allow_realloc,
3140
const oid * objid, size_t objidlen,
3141
const netsnmp_variable_list * variable)
3143
int buf_overflow = 0;
3145
#ifndef DISABLE_MIB_LOADING
3146
struct tree *subtree = tree_head;
3149
#endif /* DISABLE_MIB_LOADING */
3150
netsnmp_sprint_realloc_objid_tree(buf, buf_len, out_len,
3151
allow_realloc, &buf_overflow,
3157
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE)) {
3158
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) {
3160
(buf, buf_len, out_len, allow_realloc,
3161
(const u_char *) " = ")) {
3165
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) {
3167
(buf, buf_len, out_len, allow_realloc,
3168
(const u_char *) " ")) {
3173
(buf, buf_len, out_len, allow_realloc,
3174
(const u_char *) " = ")) {
3177
} /* end if-else NETSNMP_DS_LIB_QUICK_PRINT */
3178
} /* end if-else NETSNMP_DS_LIB_QUICKE_PRINT */
3183
if (variable->type == SNMP_NOSUCHOBJECT) {
3184
return snmp_strcat(buf, buf_len, out_len, allow_realloc,
3186
"No Such Object available on this agent at this OID");
3187
} else if (variable->type == SNMP_NOSUCHINSTANCE) {
3188
return snmp_strcat(buf, buf_len, out_len, allow_realloc,
3190
"No Such Instance currently exists at this OID");
3191
} else if (variable->type == SNMP_ENDOFMIBVIEW) {
3192
return snmp_strcat(buf, buf_len, out_len, allow_realloc,
3194
"No more variables left in this MIB View (It is past the end of the MIB tree)");
3195
#ifndef DISABLE_MIB_LOADING
3196
} else if (subtree) {
3197
const char *units = NULL;
3198
if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
3199
NETSNMP_DS_LIB_DONT_PRINT_UNITS)) {
3200
units = subtree->units;
3202
if (subtree->printomat) {
3203
return (*subtree->printomat) (buf, buf_len, out_len,
3204
allow_realloc, variable,
3205
subtree->enums, subtree->hint,
3208
return sprint_realloc_by_type(buf, buf_len, out_len,
3209
allow_realloc, variable,
3210
subtree->enums, subtree->hint,
3213
#endif /* DISABLE_MIB_LOADING */
3216
* Handle rare case where tree is empty.
3218
return sprint_realloc_by_type(buf, buf_len, out_len, allow_realloc,
3224
snprint_variable(char *buf, size_t buf_len,
3225
const oid * objid, size_t objidlen,
3226
const netsnmp_variable_list * variable)
3230
if (sprint_realloc_variable((u_char **) & buf, &buf_len, &out_len, 0,
3231
objid, objidlen, variable)) {
3232
return (int) out_len;
3239
* Prints a variable to stdout.
3241
* @param objid The object id.
3242
* @param objidlen The length of teh object id.
3243
* @param variable The variable to print.
3246
print_variable(const oid * objid,
3247
size_t objidlen, const netsnmp_variable_list * variable)
3249
fprint_variable(stdout, objid, objidlen, variable);
3254
* Prints a variable to a file descriptor.
3256
* @param f The file descriptor to print to.
3257
* @param objid The object id.
3258
* @param objidlen The length of teh object id.
3259
* @param variable The variable to print.
3262
fprint_variable(FILE * f,
3264
size_t objidlen, const netsnmp_variable_list * variable)
3267
size_t buf_len = 256, out_len = 0;
3269
if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) {
3270
fprintf(f, "[TRUNCATED]\n");
3273
if (sprint_realloc_variable(&buf, &buf_len, &out_len, 1,
3274
objid, objidlen, variable)) {
3275
fprintf(f, "%s\n", buf);
3277
fprintf(f, "%s [TRUNCATED]\n", buf);
3285
sprint_realloc_value(u_char ** buf, size_t * buf_len,
3286
size_t * out_len, int allow_realloc,
3287
const oid * objid, size_t objidlen,
3288
const netsnmp_variable_list * variable)
3290
#ifndef DISABLE_MIB_LOADING
3291
struct tree *subtree = tree_head;
3292
#endif /* DISABLE_MIB_LOADING */
3294
if (variable->type == SNMP_NOSUCHOBJECT) {
3295
return snmp_strcat(buf, buf_len, out_len, allow_realloc,
3297
"No Such Object available on this agent at this OID");
3298
} else if (variable->type == SNMP_NOSUCHINSTANCE) {
3299
return snmp_strcat(buf, buf_len, out_len, allow_realloc,
3301
"No Such Instance currently exists at this OID");
3302
} else if (variable->type == SNMP_ENDOFMIBVIEW) {
3303
return snmp_strcat(buf, buf_len, out_len, allow_realloc,
3305
"No more variables left in this MIB View (It is past the end of the MIB tree)");
3307
#ifndef DISABLE_MIB_LOADING
3308
const char *units = NULL;
3309
subtree = get_tree(objid, objidlen, subtree);
3310
if (subtree && !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
3311
NETSNMP_DS_LIB_DONT_PRINT_UNITS)) {
3312
units = subtree->units;
3314
if (subtree && subtree->printomat) {
3315
return (*subtree->printomat) (buf, buf_len, out_len,
3316
allow_realloc, variable,
3317
subtree->enums, subtree->hint,
3320
return sprint_realloc_by_type(buf, buf_len, out_len,
3321
allow_realloc, variable,
3322
subtree->enums, subtree->hint,
3326
return sprint_realloc_by_type(buf, buf_len, out_len,
3327
allow_realloc, variable,
3329
#endif /* DISABLE_MIB_LOADING */
3334
snprint_value(char *buf, size_t buf_len,
3335
const oid * objid, size_t objidlen,
3336
const netsnmp_variable_list * variable)
3340
if (sprint_realloc_value((u_char **) & buf, &buf_len, &out_len, 0,
3341
objid, objidlen, variable)) {
3342
return (int) out_len;
3349
print_value(const oid * objid,
3350
size_t objidlen, const netsnmp_variable_list * variable)
3352
fprint_value(stdout, objid, objidlen, variable);
3356
fprint_value(FILE * f,
3358
size_t objidlen, const netsnmp_variable_list * variable)
3361
size_t buf_len = 256, out_len = 0;
3363
if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) {
3364
fprintf(f, "[TRUNCATED]\n");
3367
if (sprint_realloc_value(&buf, &buf_len, &out_len, 1,
3368
objid, objidlen, variable)) {
3369
fprintf(f, "%s\n", buf);
3371
fprintf(f, "%s [TRUNCATED]\n", buf);
3380
* Takes the value in VAR and turns it into an OID segment in var->name.
3382
* @param var The variable.
3384
* @return SNMPERR_SUCCESS or SNMPERR_GENERR
3387
build_oid_segment(netsnmp_variable_list * var)
3391
if (var->name && var->name != var->name_loc)
3392
SNMP_FREE(var->name);
3393
switch (var->type) {
3398
var->name_length = 1;
3399
var->name = var->name_loc;
3400
var->name[0] = *(var->val.integer);
3404
var->name_length = 4;
3405
var->name = var->name_loc;
3407
(((unsigned int) *(var->val.integer)) & 0xff000000) >> 24;
3409
(((unsigned int) *(var->val.integer)) & 0x00ff0000) >> 16;
3411
(((unsigned int) *(var->val.integer)) & 0x0000ff00) >> 8;
3413
(((unsigned int) *(var->val.integer)) & 0x000000ff);
3416
case ASN_PRIV_IMPLIED_OBJECT_ID:
3417
var->name_length = var->val_len / sizeof(oid);
3418
if (var->name_length > (sizeof(var->name_loc) / sizeof(oid)))
3419
var->name = (oid *) malloc(sizeof(oid) * (var->name_length));
3421
var->name = var->name_loc;
3422
if (var->name == NULL)
3423
return SNMPERR_GENERR;
3425
for (i = 0; i < (int) var->name_length; i++)
3426
var->name[i] = var->val.objid[i];
3430
var->name_length = var->val_len / sizeof(oid) + 1;
3431
if (var->name_length > (sizeof(var->name_loc) / sizeof(oid)))
3432
var->name = (oid *) malloc(sizeof(oid) * (var->name_length));
3434
var->name = var->name_loc;
3435
if (var->name == NULL)
3436
return SNMPERR_GENERR;
3438
var->name[0] = var->name_length - 1;
3439
for (i = 0; i < (int) var->name_length - 1; i++)
3440
var->name[i + 1] = var->val.objid[i];
3443
case ASN_PRIV_IMPLIED_OCTET_STR:
3444
var->name_length = var->val_len;
3445
if (var->name_length > (sizeof(var->name_loc) / sizeof(oid)))
3446
var->name = (oid *) malloc(sizeof(oid) * (var->name_length));
3448
var->name = var->name_loc;
3449
if (var->name == NULL)
3450
return SNMPERR_GENERR;
3452
for (i = 0; i < (int) var->val_len; i++)
3453
var->name[i] = (oid) var->val.string[i];
3458
var->name_length = var->val_len + 1;
3459
if (var->name_length > (sizeof(var->name_loc) / sizeof(oid)))
3460
var->name = (oid *) malloc(sizeof(oid) * (var->name_length));
3462
var->name = var->name_loc;
3463
if (var->name == NULL)
3464
return SNMPERR_GENERR;
3466
var->name[0] = (oid) var->val_len;
3467
for (i = 0; i < (int) var->val_len; i++)
3468
var->name[i + 1] = (oid) var->val.string[i];
3472
DEBUGMSGTL(("build_oid_segment",
3473
"invalid asn type: %d\n", var->type));
3474
return SNMPERR_GENERR;
3477
if (var->name_length > MAX_OID_LEN) {
3478
DEBUGMSGTL(("build_oid_segment",
3479
"Something terribly wrong, namelen = %d\n",
3481
return SNMPERR_GENERR;
3484
return SNMPERR_SUCCESS;
3489
build_oid_noalloc(oid * in, size_t in_len, size_t * out_len,
3490
oid * prefix, size_t prefix_len,
3491
netsnmp_variable_list * indexes)
3493
netsnmp_variable_list *var;
3496
if (in_len < prefix_len)
3497
return SNMPERR_GENERR;
3498
memcpy(in, prefix, prefix_len * sizeof(oid));
3499
*out_len = prefix_len;
3504
for (var = indexes; var != NULL; var = var->next_variable) {
3505
if (build_oid_segment(var) != SNMPERR_SUCCESS)
3506
return SNMPERR_GENERR;
3507
if (var->name_length + *out_len < in_len) {
3508
memcpy(&(in[*out_len]), var->name,
3509
sizeof(oid) * var->name_length);
3510
*out_len += var->name_length;
3512
return SNMPERR_GENERR;
3516
DEBUGMSGTL(("build_oid_noalloc", "generated: "));
3517
DEBUGMSGOID(("build_oid_noalloc", in, *out_len));
3518
DEBUGMSG(("build_oid_noalloc", "\n"));
3519
return SNMPERR_SUCCESS;
3523
build_oid(oid ** out, size_t * out_len,
3524
oid * prefix, size_t prefix_len, netsnmp_variable_list * indexes)
3526
oid tmpout[MAX_OID_LEN];
3529
* xxx-rks: inefficent. try only building segments to find index len:
3530
* for (var = indexes; var != NULL; var = var->next_variable) {
3531
* if (build_oid_segment(var) != SNMPERR_SUCCESS)
3532
* return SNMPERR_GENERR;
3533
* *out_len += var->name_length;
3535
* then see if it fits in existing buffer, or realloc buffer.
3537
if (build_oid_noalloc(tmpout, sizeof(tmpout), out_len,
3538
prefix, prefix_len, indexes) != SNMPERR_SUCCESS)
3539
return SNMPERR_GENERR;
3541
/** xxx-rks: should free previous value? */
3542
snmp_clone_mem((void **) out, (void *) tmpout, *out_len * sizeof(oid));
3544
return SNMPERR_SUCCESS;
3548
* vblist_out must contain a pre-allocated string of variables into
3549
* which indexes can be extracted based on the previously existing
3550
* types in the variable chain
3552
* SNMPERR_GENERR on error
3553
* SNMPERR_SUCCESS on success
3557
parse_oid_indexes(oid * oidIndex, size_t oidLen,
3558
netsnmp_variable_list * data)
3560
netsnmp_variable_list *var = data;
3562
while (var && oidLen > 0) {
3564
if (parse_one_oid_index(&oidIndex, &oidLen, var, 0) !=
3568
var = var->next_variable;
3571
if (var != NULL || oidLen != 0)
3572
return SNMPERR_GENERR;
3573
return SNMPERR_SUCCESS;
3578
parse_one_oid_index(oid ** oidStart, size_t * oidLen,
3579
netsnmp_variable_list * data, int complete)
3581
netsnmp_variable_list *var = data;
3582
oid tmpout[MAX_OID_LEN];
3584
unsigned int uitmp = 0;
3586
oid *oidIndex = *oidStart;
3588
if (var == NULL || ((*oidLen == 0) && (complete == 0)))
3589
return SNMPERR_GENERR;
3591
switch (var->type) {
3597
snmp_set_var_value(var, (u_char *) oidIndex++,
3601
snmp_set_var_value(var, (u_char *) oidLen, sizeof(long));
3603
DEBUGMSGTL(("parse_oid_indexes",
3604
"Parsed int(%d): %d\n", var->type,
3605
*var->val.integer));
3609
if ((4 > *oidLen) && (complete == 0))
3610
return SNMPERR_GENERR;
3612
for (i = 0; i < 4 && i < *oidLen; ++i) {
3613
if (oidIndex[i] > 255) {
3614
DEBUGMSGTL(("parse_oid_indexes",
3615
"illegal oid in index: %d\n", oidIndex[0]));
3616
return SNMPERR_GENERR; /* sub-identifier too large */
3618
uitmp = uitmp + (oidIndex[i] << (8*(3-i)));
3620
if (4 > (int) (*oidLen)) {
3621
oidIndex += *oidLen;
3628
snmp_set_var_value(var, (u_char *) &uitmp, 4);
3629
DEBUGMSGTL(("parse_oid_indexes",
3630
"Parsed ipaddr(%d): %d.%d.%d.%d\n", var->type,
3631
var->val.string[0], var->val.string[1],
3632
var->val.string[2], var->val.string[3]));
3636
case ASN_PRIV_IMPLIED_OBJECT_ID:
3637
if (var->type == ASN_PRIV_IMPLIED_OBJECT_ID) {
3641
uitmp = *oidIndex++;
3646
if ((uitmp > *oidLen) && (complete == 0))
3647
return SNMPERR_GENERR;
3650
if (uitmp > MAX_OID_LEN)
3651
return SNMPERR_GENERR; /* too big and illegal */
3653
if (uitmp > *oidLen) {
3654
memcpy(tmpout, oidIndex, sizeof(oid) * (*oidLen));
3655
memset(&tmpout[*oidLen], 0x00,
3656
sizeof(oid) * (uitmp - *oidLen));
3657
snmp_set_var_value(var, (u_char *) tmpout,
3658
sizeof(oid) * uitmp);
3659
oidIndex += *oidLen;
3662
snmp_set_var_value(var, (u_char *) oidIndex,
3663
sizeof(oid) * uitmp);
3668
DEBUGMSGTL(("parse_oid_indexes", "Parsed oid: "));
3669
DEBUGMSGOID(("parse_oid_indexes",
3670
var->val.objid, var->val_len / sizeof(oid)));
3671
DEBUGMSG(("parse_oid_indexes", "\n"));
3676
case ASN_PRIV_IMPLIED_OCTET_STR:
3677
if (var->type == ASN_PRIV_IMPLIED_OCTET_STR) {
3681
uitmp = *oidIndex++;
3686
if ((uitmp > *oidLen) && (complete == 0))
3687
return SNMPERR_GENERR;
3691
* we handle this one ourselves since we don't have
3692
* pre-allocated memory to copy from using
3693
* snmp_set_var_value()
3697
break; /* zero length strings shouldn't malloc */
3699
if (uitmp > MAX_OID_LEN)
3700
return SNMPERR_GENERR; /* too big and illegal */
3703
* malloc by size+1 to allow a null to be appended.
3705
var->val_len = uitmp;
3706
var->val.string = (u_char *) calloc(1, uitmp + 1);
3707
if (var->val.string == NULL)
3708
return SNMPERR_GENERR;
3710
if (uitmp > (int) (*oidLen)) {
3711
for (i = 0; i < *oidLen; ++i)
3712
var->val.string[i] = (u_char) * oidIndex++;
3713
for (i = 0; i < uitmp; ++i)
3714
var->val.string[i] = '\0';
3717
for (i = 0; i < uitmp; ++i)
3718
var->val.string[i] = (u_char) * oidIndex++;
3721
var->val.string[uitmp] = '\0';
3723
DEBUGMSGTL(("parse_oid_indexes",
3724
"Parsed str(%d): %s\n", var->type,
3729
DEBUGMSGTL(("parse_oid_indexes",
3730
"invalid asn type: %d\n", var->type));
3731
return SNMPERR_GENERR;
3734
(*oidStart) = oidIndex;
3735
return SNMPERR_SUCCESS;
3739
dump_realloc_oid_to_string(const oid * objid, size_t objidlen,
3740
u_char ** buf, size_t * buf_len,
3741
size_t * out_len, int allow_realloc,
3747
for (i = 0, alen = 0; i < (int) objidlen; i++) {
3749
if ((tst > 254) || (!isprint(tst))) {
3754
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) {
3755
while ((*out_len + 2) >= *buf_len) {
3756
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
3760
*(*buf + *out_len) = '\\';
3763
while ((*out_len + 2) >= *buf_len) {
3764
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
3768
*(*buf + *out_len) = quotechar;
3772
while ((*out_len + 2) >= *buf_len) {
3773
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
3777
*(*buf + *out_len) = (char) tst;
3783
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) {
3784
while ((*out_len + 2) >= *buf_len) {
3785
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
3789
*(*buf + *out_len) = '\\';
3792
while ((*out_len + 2) >= *buf_len) {
3793
if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
3797
*(*buf + *out_len) = quotechar;
3801
*(*buf + *out_len) = '\0';
3808
_oid_finish_printing(const oid * objid, size_t objidlen,
3809
u_char ** buf, size_t * buf_len, size_t * out_len,
3810
int allow_realloc, int *buf_overflow) {
3812
if (*buf != NULL && *(*buf + *out_len - 1) != '.') {
3813
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
3815
(const u_char *) ".")) {
3820
while (objidlen-- > 0) { /* output rest of name, uninterpreted */
3821
sprintf(intbuf, "%lu.", *objid++);
3822
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
3824
(const u_char *) intbuf)) {
3830
*(*buf + *out_len - 1) = '\0'; /* remove trailing dot */
3834
#ifndef DISABLE_MIB_LOADING
3835
static struct tree *
3836
_get_realloc_symbol(const oid * objid, size_t objidlen,
3837
struct tree *subtree,
3838
u_char ** buf, size_t * buf_len, size_t * out_len,
3839
int allow_realloc, int *buf_overflow,
3840
struct index_list *in_dices, size_t * end_of_known)
3842
struct tree *return_tree = NULL;
3843
int extended_index =
3844
netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_EXTENDED_INDEX);
3846
netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
3849
if (!objid || !buf) {
3853
for (; subtree; subtree = subtree->next_peer) {
3854
if (*objid == subtree->subid) {
3855
while (subtree->next_peer && subtree->next_peer->subid == *objid)
3856
subtree = subtree->next_peer;
3857
if (subtree->indexes) {
3858
in_dices = subtree->indexes;
3859
} else if (subtree->augments) {
3861
find_tree_node(subtree->augments, -1);
3863
in_dices = tp2->indexes;
3867
if (!strncmp(subtree->label, ANON, ANON_LEN) ||
3868
(NETSNMP_OID_OUTPUT_NUMERIC == output_format)) {
3869
sprintf(intbuf, "%lu", subtree->subid);
3870
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
3877
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
3886
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
3888
(const u_char *) ".")) {
3892
return_tree = _get_realloc_symbol(objid + 1, objidlen - 1,
3893
subtree->child_list,
3894
buf, buf_len, out_len,
3896
buf_overflow, in_dices,
3900
if (return_tree != NULL) {
3910
*end_of_known = *out_len;
3914
* Subtree not found.
3917
while (in_dices && (objidlen > 0) &&
3918
(NETSNMP_OID_OUTPUT_NUMERIC != output_format) &&
3919
!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS)) {
3923
tp = find_tree_node(in_dices->ilabel, -1);
3927
* Can't find an index in the mib tree. Bail.
3932
if (extended_index) {
3933
if (*buf != NULL && *(*buf + *out_len - 1) == '.') {
3936
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
3938
(const u_char *) "[")) {
3945
if (extended_index && tp->hint) {
3946
netsnmp_variable_list var;
3947
u_char buffer[1024];
3950
memset(&var, 0, sizeof var);
3951
if (in_dices->isimplied) {
3953
if (numids > objidlen)
3955
} else if (tp->ranges && !tp->ranges->next
3956
&& tp->ranges->low == tp->ranges->high) {
3957
numids = tp->ranges->low;
3958
if (numids > objidlen)
3962
if (numids >= objidlen)
3967
if (numids > objidlen)
3969
for (i = 0; i < (int) numids; i++)
3970
buffer[i] = (u_char) objid[i];
3971
var.type = ASN_OCTET_STR;
3972
var.val.string = buffer;
3973
var.val_len = numids;
3974
if (!*buf_overflow) {
3975
if (!sprint_realloc_octet_string(buf, buf_len, out_len,
3976
allow_realloc, &var,
3982
} else if (in_dices->isimplied) {
3984
if (numids > objidlen)
3987
if (!*buf_overflow) {
3988
if (!dump_realloc_oid_to_string
3989
(objid, numids, buf, buf_len, out_len,
3990
allow_realloc, '\'')) {
3994
} else if (tp->ranges && !tp->ranges->next
3995
&& tp->ranges->low == tp->ranges->high) {
3997
* a fixed-length object string
3999
numids = tp->ranges->low;
4000
if (numids > objidlen)
4003
if (!*buf_overflow) {
4004
if (!dump_realloc_oid_to_string
4005
(objid, numids, buf, buf_len, out_len,
4006
allow_realloc, '\'')) {
4011
numids = (size_t) * objid + 1;
4012
if (numids > objidlen)
4015
if (netsnmp_ds_get_boolean
4016
(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) {
4018
&& !snmp_strcat(buf, buf_len, out_len,
4020
(const u_char *) "\\")) {
4025
&& !snmp_strcat(buf, buf_len, out_len,
4027
(const u_char *) "\"")) {
4030
if (netsnmp_ds_get_boolean
4031
(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_ESCAPE_QUOTES)) {
4033
&& !snmp_strcat(buf, buf_len, out_len,
4035
(const u_char *) "\\")) {
4040
&& !snmp_strcat(buf, buf_len, out_len,
4042
(const u_char *) "\"")) {
4046
if (!*buf_overflow) {
4047
if (!dump_realloc_oid_to_string
4048
(objid + 1, numids - 1, buf, buf_len, out_len,
4049
allow_realloc, '"')) {
4059
case TYPE_INTEGER32:
4061
case TYPE_UNSIGNED32:
4065
struct enum_list *ep = tp->enums;
4066
while (ep && ep->value != (int) (*objid)) {
4071
&& !snmp_strcat(buf, buf_len, out_len,
4073
(const u_char *) ep->label)) {
4077
sprintf(intbuf, "%lu", *objid);
4079
&& !snmp_strcat(buf, buf_len, out_len,
4081
(const u_char *) intbuf)) {
4086
sprintf(intbuf, "%lu", *objid);
4087
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
4099
if (in_dices->isimplied) {
4102
numids = (size_t) * objid + 1;
4104
if (numids > objidlen)
4106
if (extended_index) {
4107
if (in_dices->isimplied) {
4109
&& !netsnmp_sprint_realloc_objid_tree(buf, buf_len,
4119
&& !netsnmp_sprint_realloc_objid_tree(buf, buf_len,
4130
_get_realloc_symbol(objid, numids, NULL, buf, buf_len,
4131
out_len, allow_realloc, buf_overflow,
4135
objidlen -= (numids);
4141
sprintf(intbuf, "%lu.%lu.%lu.%lu",
4142
objid[0], objid[1], objid[2], objid[3]);
4145
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
4147
(const u_char *) intbuf)) {
4153
oid ntype = *objid++;
4156
sprintf(intbuf, "%lu.", ntype);
4157
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
4164
if (ntype == 1 && objidlen >= 4) {
4165
sprintf(intbuf, "%lu.%lu.%lu.%lu",
4166
objid[0], objid[1], objid[2], objid[3]);
4168
&& !snmp_strcat(buf, buf_len, out_len,
4170
(const u_char *) intbuf)) {
4181
case TYPE_NSAPADDRESS:
4187
if (extended_index) {
4188
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
4190
(const u_char *) "]")) {
4194
if (!*buf_overflow && !snmp_strcat(buf, buf_len, out_len,
4196
(const u_char *) ".")) {
4200
in_dices = in_dices->next;
4204
_oid_finish_printing(objid, objidlen,
4205
buf, buf_len, out_len,
4206
allow_realloc, buf_overflow);
4211
* Clone of get_symbol that doesn't take a buffer argument.
4216
get_tree(const oid * objid, size_t objidlen, struct tree *subtree)
4218
struct tree *return_tree = NULL;
4220
for (; subtree; subtree = subtree->next_peer) {
4221
if (*objid == subtree->subid)
4228
while (subtree->next_peer && subtree->next_peer->subid == *objid)
4229
subtree = subtree->next_peer;
4232
get_tree(objid + 1, objidlen - 1, subtree->child_list);
4233
if (return_tree != NULL)
4240
* Prints on oid description on stdout.
4242
* @see fprint_description
4245
print_description(oid * objid, size_t objidlen, /* number of subidentifiers */
4248
fprint_description(stdout, objid, objidlen, width);
4253
* Prints on oid description into a file descriptor.
4255
* @param f The file descriptor to print to.
4256
* @param objid The object identifier.
4257
* @param objidlen The object id length.
4258
* @param width Number of subidentifiers.
4261
fprint_description(FILE * f, oid * objid, size_t objidlen,
4265
size_t buf_len = 256, out_len = 0;
4267
if ((buf = (u_char *) calloc(buf_len, 1)) == NULL) {
4268
fprintf(f, "[TRUNCATED]\n");
4271
if (!sprint_realloc_description(&buf, &buf_len, &out_len, 1,
4272
objid, objidlen, width)) {
4273
fprintf(f, "%s [TRUNCATED]\n", buf);
4275
fprintf(f, "%s\n", buf);
4283
snprint_description(char *buf, size_t buf_len,
4284
oid * objid, size_t objidlen, int width)
4288
if (sprint_realloc_description((u_char **) & buf, &buf_len, &out_len, 0,
4289
objid, objidlen, width)) {
4290
return (int) out_len;
4297
sprint_realloc_description(u_char ** buf, size_t * buf_len,
4298
size_t * out_len, int allow_realloc,
4299
oid * objid, size_t objidlen, int width)
4301
struct tree *tp = get_tree(objid, objidlen, tree_head);
4302
struct tree *subtree = tree_head;
4307
if (tp->type <= TYPE_SIMPLE_LAST)
4308
cp = " OBJECT-TYPE";
4314
case TYPE_NOTIFTYPE:
4315
cp = " NOTIFICATION-TYPE";
4318
cp = " OBJECT-GROUP";
4321
cp = " AGENT-CAPABILITIES";
4324
cp = " MODULE-IDENTITY";
4327
cp = " MODULE-COMPLIANCE";
4330
sprintf(tmpbuf, " type_%d", tp->type);
4334
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, tp->label) ||
4335
!snmp_strcat(buf, buf_len, out_len, allow_realloc, cp) ||
4336
!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n")) {
4339
if (!print_tree_node(buf, buf_len, out_len, allow_realloc, tp, width))
4341
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, "::= {"))
4344
while (objidlen > 1) {
4345
for (; subtree; subtree = subtree->next_peer) {
4346
if (*objid == subtree->subid) {
4347
while (subtree->next_peer && subtree->next_peer->subid == *objid)
4348
subtree = subtree->next_peer;
4349
if (strncmp(subtree->label, ANON, ANON_LEN)) {
4350
snprintf(tmpbuf, sizeof(tmpbuf), " %s(%lu)", subtree->label, subtree->subid);
4351
tmpbuf[ sizeof(tmpbuf)-1 ] = 0;
4353
sprintf(tmpbuf, " %lu", subtree->subid);
4354
len = strlen(tmpbuf);
4355
if (pos + len + 2 > width) {
4356
if (!snmp_strcat(buf, buf_len, out_len,
4357
allow_realloc, "\n "))
4361
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, tmpbuf))
4370
subtree = subtree->child_list;
4374
while (objidlen > 1) {
4375
sprintf(tmpbuf, " %lu", *objid);
4376
len = strlen(tmpbuf);
4377
if (pos + len + 2 > width) {
4378
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n "))
4382
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, tmpbuf))
4388
sprintf(tmpbuf, " %lu }", *objid);
4389
len = strlen(tmpbuf);
4390
if (pos + len + 2 > width) {
4391
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n "))
4395
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, tmpbuf))
4401
print_tree_node(u_char ** buf, size_t * buf_len,
4402
size_t * out_len, int allow_realloc,
4403
struct tree *tp, int width)
4407
int i, prevmod, pos, len;
4410
module_name(tp->modid, str);
4411
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, " -- FROM\t") ||
4412
!snmp_strcat(buf, buf_len, out_len, allow_realloc, str))
4414
pos = 16+strlen(str);
4415
for (i = 1, prevmod = tp->modid; i < tp->number_modules; i++) {
4416
if (prevmod != tp->module_list[i]) {
4417
module_name(tp->module_list[i], str);
4419
if (pos + len + 2 > width) {
4420
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4426
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, ", "))
4430
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str))
4434
prevmod = tp->module_list[i];
4436
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n"))
4438
if (tp->tc_index != -1) {
4439
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4440
" -- TEXTUAL CONVENTION ") ||
4441
!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4442
get_tc_descriptor(tp->tc_index)) ||
4443
!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n"))
4448
cp = "OBJECT IDENTIFIER";
4451
cp = "OCTET STRING";
4457
cp = "NetworkAddress";
4468
case TYPE_TIMETICKS:
4477
case TYPE_COUNTER64:
4480
case TYPE_BITSTRING:
4483
case TYPE_NSAPADDRESS:
4489
case TYPE_UNSIGNED32:
4492
case TYPE_INTEGER32:
4499
#if SNMP_TESTING_CODE
4500
if (!cp && (tp->ranges || tp->enums)) { /* ranges without type ? */
4501
sprintf(str, "?0 with %s %s ?",
4502
tp->ranges ? "Range" : "", tp->enums ? "Enum" : "");
4505
#endif /* SNMP_TESTING_CODE */
4507
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4509
!snmp_strcat(buf, buf_len, out_len, allow_realloc, cp))
4512
struct range_list *rp = tp->ranges;
4514
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, " ("))
4517
if (rp->low == rp->high)
4518
sprintf(str, "%s%d", (first ? "" : " | "), rp->low );
4520
sprintf(str, "%s%d..%d", (first ? "" : " | "),
4522
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str))
4528
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, ") "))
4532
struct enum_list *ep = tp->enums;
4534
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, " {"))
4536
pos = 16 + strlen(cp) + 2;
4541
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, ", "))
4543
snprintf(str, sizeof(str), "%s(%d)", ep->label, ep->value);
4544
str[ sizeof(str)-1 ] = 0;
4546
if (pos + len + 2 > width) {
4547
if (!snmp_strcat(buf, buf_len, out_len,
4548
allow_realloc, "\n\t\t "))
4552
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str))
4557
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, "} "))
4561
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n"))
4564
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4565
" DISPLAY-HINT\t\"") ||
4566
!snmp_strcat(buf, buf_len, out_len, allow_realloc, tp->hint) ||
4567
!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\"\n"))
4570
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4572
!snmp_strcat(buf, buf_len, out_len, allow_realloc, tp->hint) ||
4573
!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\"\n"))
4575
switch (tp->access) {
4576
case MIB_ACCESS_READONLY:
4579
case MIB_ACCESS_READWRITE:
4582
case MIB_ACCESS_WRITEONLY:
4585
case MIB_ACCESS_NOACCESS:
4586
cp = "not-accessible";
4588
case MIB_ACCESS_NOTIFY:
4589
cp = "accessible-for-notify";
4591
case MIB_ACCESS_CREATE:
4598
sprintf(str, "access_%d", tp->access);
4602
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4604
!snmp_strcat(buf, buf_len, out_len, allow_realloc, cp) ||
4605
!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n"))
4607
switch (tp->status) {
4608
case MIB_STATUS_MANDATORY:
4611
case MIB_STATUS_OPTIONAL:
4614
case MIB_STATUS_OBSOLETE:
4617
case MIB_STATUS_DEPRECATED:
4620
case MIB_STATUS_CURRENT:
4627
sprintf(str, "status_%d", tp->status);
4630
#if SNMP_TESTING_CODE
4631
if (!cp && (tp->indexes)) { /* index without status ? */
4632
sprintf(str, "?0 with %s ?", tp->indexes ? "Index" : "");
4635
#endif /* SNMP_TESTING_CODE */
4637
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4639
!snmp_strcat(buf, buf_len, out_len, allow_realloc, cp) ||
4640
!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n"))
4643
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4645
!snmp_strcat(buf, buf_len, out_len, allow_realloc, tp->augments) ||
4646
!snmp_strcat(buf, buf_len, out_len, allow_realloc, " }\n"))
4649
struct index_list *ip = tp->indexes;
4651
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4659
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, ", "))
4661
snprintf(str, sizeof(str), "%s%s",
4662
ip->isimplied ? "IMPLIED " : "",
4664
str[ sizeof(str)-1 ] = 0;
4666
if (pos + len + 2 > width) {
4667
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\n\t\t "))
4671
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str))
4676
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, " }\n"))
4680
struct varbind_list *vp = tp->varbinds;
4683
if (tp->type == TYPE_TRAPTYPE) {
4684
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4688
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4697
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, ", "))
4699
snprintf(str, sizeof(str), "%s", vp->vblabel);
4700
str[ sizeof(str)-1 ] = 0;
4702
if (pos + len + 2 > width) {
4703
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4708
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str))
4713
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, " }\n"))
4716
if (tp->description)
4717
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4718
" DESCRIPTION\t\"") ||
4719
!snmp_strcat(buf, buf_len, out_len, allow_realloc, tp->description) ||
4720
!snmp_strcat(buf, buf_len, out_len, allow_realloc, "\"\n"))
4722
if (tp->defaultValue)
4723
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
4725
!snmp_strcat(buf, buf_len, out_len, allow_realloc, tp->defaultValue) ||
4726
!snmp_strcat(buf, buf_len, out_len, allow_realloc, " }\n"))
4729
if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, "No description\n"))
4735
get_module_node(const char *fname,
4736
const char *module, oid * objid, size_t * objidlen)
4742
if (!strcmp(module, "ANY"))
4745
read_module(module);
4746
modid = which_module(module);
4752
* Isolate the first component of the name ...
4754
name = strdup(fname);
4755
cp = strchr(name, '.');
4761
* ... and locate it in the tree.
4763
tp = find_tree_node(name, modid);
4765
size_t maxlen = *objidlen;
4768
* Set the first element of the object ID
4770
if (node_to_oid(tp, objid, objidlen)) {
4774
* If the name requested was more than one element,
4775
* tag on the rest of the components
4778
rc = _add_strings_to_oid(tp, cp, objid, objidlen, maxlen);
4790
* Populates the object identifier from a node in the MIB hierarchy.
4791
* Builds up the object ID, working backwards,
4792
* starting from the end of the objid buffer.
4793
* When the top of the MIB tree is reached, the buffer is adjusted.
4795
* The buffer length is set to the number of subidentifiers
4796
* for the object identifier associated with the MIB node.
4798
* @return the number of subidentifiers copied.
4800
* If 0 is returned, the objid buffer is too small,
4801
* and the buffer contents are indeterminate.
4802
* The buffer length can be used to create a larger buffer.
4805
node_to_oid(struct tree *tp, oid * objid, size_t * objidlen)
4810
if (!tp || !objid || !objidlen)
4813
lenids = (int) *objidlen;
4814
op = objid + lenids; /* points after the last element */
4816
for (numids = 0; tp; tp = tp->parent, numids++) {
4817
if (numids >= lenids)
4823
*objidlen = (size_t) numids;
4824
if (numids > lenids) {
4828
if (numids < lenids)
4829
memmove(objid, op, numids * sizeof(oid));
4833
#endif /* DISABLE_MIB_LOADING */
4836
* Replace \x with x stop at eos_marker
4837
* return NULL if eos_marker not found
4839
static char *_apply_escapes(char *src, char eos_marker)
4850
if (eos_marker == *src) break;
4860
/* never found eos_marker */
4869
#ifndef DISABLE_MIB_LOADING
4870
_add_strings_to_oid(struct tree *tp, char *cp,
4871
oid * objid, size_t * objidlen, size_t maxlen)
4873
_add_strings_to_oid(void *tp, char *cp,
4874
oid * objid, size_t * objidlen, size_t maxlen)
4875
#endif /* DISABLE_MIB_LOADING */
4878
int len_index = 1000000;
4879
#ifndef DISABLE_MIB_LOADING
4880
struct tree *tp2 = NULL;
4881
struct index_list *in_dices = NULL;
4882
#endif /* DISABLE_MIB_LOADING */
4883
char *fcp, *ecp, *cp2 = NULL;
4885
int len = -1, pos = -1;
4886
#ifndef DISABLE_MIB_LOADING
4888
!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_CHECK_RANGE);
4889
int do_hint = !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NO_DISPLAY_HINT);
4891
while (cp && tp && tp->child_list) {
4893
tp2 = tp->child_list;
4895
* Isolate the next entry
4897
cp2 = strchr(cp, '.');
4902
* Search for the appropriate child
4905
subid = strtoul(cp, &ecp, 0);
4908
while (tp2 && tp2->subid != subid)
4909
tp2 = tp2->next_peer;
4911
while (tp2 && strcmp(tp2->label, fcp))
4912
tp2 = tp2->next_peer;
4917
if (*objidlen >= maxlen)
4919
while (tp2 && tp2->next_peer && tp2->next_peer->subid == subid)
4920
tp2 = tp2->next_peer;
4921
objid[*objidlen] = subid;
4930
if (tp && !tp->child_list) {
4931
if ((tp2 = tp->parent)) {
4933
in_dices = tp2->indexes;
4934
else if (tp2->augments) {
4935
tp2 = find_tree_node(tp2->augments, -1);
4937
in_dices = tp2->indexes;
4943
while (cp && in_dices) {
4946
tp = find_tree_node(in_dices->ilabel, -1);
4951
case TYPE_INTEGER32:
4953
case TYPE_UNSIGNED32:
4954
case TYPE_TIMETICKS:
4956
* Isolate the next entry
4958
cp2 = strchr(cp, '.');
4962
subid = strtoul(cp, &ecp, 0);
4967
struct enum_list *ep = tp->enums;
4968
while (ep && strcmp(ep->label, cp))
4976
if (check && tp->ranges) {
4977
struct range_list *rp = tp->ranges;
4980
if ((rp->low <= (int) subid)
4981
&& ((int) subid <= rp->high))
4988
if (*objidlen >= maxlen)
4990
objid[*objidlen] = subid;
4994
if (*objidlen + 4 > maxlen)
4996
for (subid = 0; cp && subid < 4; subid++) {
4998
cp2 = strchr(cp, '.');
5001
objid[*objidlen] = strtoul(cp, &ecp, 0);
5004
if (check && objid[*objidlen] > 255)
5011
if (tp->ranges && !tp->ranges->next
5012
&& tp->ranges->low == tp->ranges->high)
5013
len = tp->ranges->low;
5017
if (*cp == '"' || *cp == '\'') {
5020
* insert length if requested
5022
if (!in_dices->isimplied && len == -1) {
5023
if (doingquote == '\'') {
5025
("'-quote is for fixed length strings");
5028
if (*objidlen >= maxlen)
5030
len_index = *objidlen;
5032
} else if (doingquote == '"') {
5034
("\"-quote is for variable length strings");
5038
cp2 = _apply_escapes(cp, doingquote);
5039
if (!cp2) goto bad_id;
5041
unsigned char *new_val;
5043
int parsed_hint = 0;
5044
const char *parsed_value;
5046
if (do_hint && tp->hint) {
5047
parsed_value = parse_octet_hint(tp->hint, cp,
5048
&new_val, &new_val_len);
5049
parsed_hint = parsed_value == NULL;
5053
for (i = 0; i < new_val_len; i++) {
5054
if (*objidlen >= maxlen) goto bad_id;
5055
objid[ *objidlen ] = new_val[i];
5062
if (*objidlen >= maxlen) goto bad_id;
5063
objid[ *objidlen ] = *cp++;
5073
else if (*cp2 != '.')
5079
struct range_list *rp = tp->ranges;
5082
if (rp->low <= pos && pos <= rp->high)
5088
if (!in_dices->isimplied)
5089
objid[len_index] = pos;
5090
} else if (pos != len)
5093
else if (len == -1 && !in_dices->isimplied)
5094
objid[len_index] = pos;
5096
if (!in_dices->isimplied && len == -1) {
5098
cp2 = strchr(cp, '.');
5101
len = strtoul(cp, &ecp, 0);
5104
if (*objidlen + len + 1 >= maxlen)
5106
objid[*objidlen] = len;
5112
cp2 = strchr(cp, '.');
5115
objid[*objidlen] = strtoul(cp, &ecp, 0);
5118
if (check && objid[*objidlen] > 255)
5132
cp2 = strchr(cp, '.');
5135
subid = strtoul(cp, &ecp, 0);
5138
if (*objidlen + 1 >= maxlen)
5140
objid[*objidlen] = subid;
5144
for (len = 0; len < 4; len++) {
5146
cp2 = strchr(cp, '.');
5149
subid = strtoul(cp, &ecp, 0);
5152
if (*objidlen + 1 >= maxlen)
5156
objid[*objidlen++] = subid;
5167
snmp_log(LOG_ERR, "Unexpected index type: %d %s %s\n",
5168
tp->type, in_dices->ilabel, cp);
5175
in_dices = in_dices->next;
5178
#endif /* DISABLE_MIB_LOADING */
5192
cp2 = strchr(cp, '.');
5195
subid = strtoul(cp, &ecp, 0);
5198
if (*objidlen >= maxlen)
5200
objid[*objidlen] = subid;
5207
* insert length if requested
5209
if (doingquote == '"') {
5210
if (*objidlen >= maxlen)
5212
objid[*objidlen] = len = strchr(cp, doingquote) - cp;
5216
while (*cp && *cp != doingquote) {
5217
if (*objidlen >= maxlen)
5219
objid[*objidlen] = *cp++;
5227
else if (*cp2 == '.')
5242
#ifndef DISABLE_MIB_LOADING
5244
snprintf(buf, sizeof(buf), "Index out of range: %s (%s)",
5245
fcp, in_dices->ilabel);
5247
snprintf(buf, sizeof(buf), "Sub-id not found: %s -> %s", tp->label, fcp);
5249
#endif /* DISABLE_MIB_LOADING */
5250
snprintf(buf, sizeof(buf), "%s", fcp);
5251
buf[ sizeof(buf)-1 ] = 0;
5253
snmp_set_detail(buf);
5259
#ifndef DISABLE_MIB_LOADING
5261
* @see comments on find_best_tree_node for usage after first time.
5264
get_wild_node(const char *name, oid * objid, size_t * objidlen)
5266
struct tree *tp = find_best_tree_node(name, tree_head, NULL);
5269
return get_node(tp->label, objid, objidlen);
5273
get_node(const char *name, oid * objid, size_t * objidlen)
5281
if (('0' <= ch && ch <= '9')
5282
|| ('a' <= ch && ch <= 'z')
5283
|| ('A' <= ch && ch <= 'Z')
5290
res = get_module_node(name + 1, "ANY", objid, objidlen);
5292
res = get_module_node(name, "ANY", objid, objidlen);
5296
* requested name is of the form
5297
* "module:subidentifier"
5299
module = (char *) malloc((size_t) (cp - name + 1));
5301
return SNMPERR_GENERR;
5302
memcpy(module, name, (size_t) (cp - name));
5303
module[cp - name] = 0;
5304
cp++; /* cp now point to the subidentifier */
5309
* 'cp' and 'name' *do* go that way round!
5311
res = get_module_node(cp, module, objid, objidlen);
5315
SET_SNMP_ERROR(SNMPERR_UNKNOWN_OBJID);
5320
#endif /* DISABLE_MIB_LOADING */
5324
main(int argc, char *argv[])
5326
oid objid[MAX_OID_LEN];
5327
int objidlen = MAX_OID_LEN;
5329
netsnmp_variable_list variable;
5333
print_subtree(stdout, tree_head, 0);
5334
variable.type = ASN_INTEGER;
5335
variable.val.integer = 3;
5336
variable.val_len = 4;
5337
for (argc--; argc; argc--, argv++) {
5338
objidlen = MAX_OID_LEN;
5339
printf("read_objid(%s) = %d\n",
5340
argv[1], read_objid(argv[1], objid, &objidlen));
5341
for (count = 0; count < objidlen; count++)
5342
printf("%d.", objid[count]);
5344
print_variable(objid, objidlen, &variable);
5348
#endif /* testing */
5350
#ifndef DISABLE_MIB_LOADING
5352
* initialize: no peers included in the report.
5355
clear_tree_flags(register struct tree *tp)
5357
for (; tp; tp = tp->next_peer) {
5360
clear_tree_flags(tp->child_list);
5365
* Update: 1998-07-17 <jhy@gsu.edu>
5366
* Added print_oid_report* functions.
5368
static int print_subtree_oid_report_labeledoid = 0;
5369
static int print_subtree_oid_report_oid = 0;
5370
static int print_subtree_oid_report_symbolic = 0;
5371
static int print_subtree_oid_report_suffix = 0;
5374
* These methods recurse.
5376
static void print_parent_labeledoid(FILE *, struct tree *);
5377
static void print_parent_oid(FILE *, struct tree *);
5378
static void print_parent_label(FILE *, struct tree *);
5379
static void print_subtree_oid_report(FILE *, struct tree *, int);
5383
print_oid_report(FILE * fp)
5386
clear_tree_flags(tree_head);
5387
for (tp = tree_head; tp; tp = tp->next_peer)
5388
print_subtree_oid_report(fp, tp, 0);
5392
print_oid_report_enable_labeledoid(void)
5394
print_subtree_oid_report_labeledoid = 1;
5398
print_oid_report_enable_oid(void)
5400
print_subtree_oid_report_oid = 1;
5404
print_oid_report_enable_suffix(void)
5406
print_subtree_oid_report_suffix = 1;
5410
print_oid_report_enable_symbolic(void)
5412
print_subtree_oid_report_symbolic = 1;
5416
* helper methods for print_subtree_oid_report()
5417
* each one traverses back up the node tree
5418
* until there is no parent. Then, the label combination
5419
* is output, such that the parent is displayed first.
5421
* Warning: these methods are all recursive.
5425
print_parent_labeledoid(FILE * f, struct tree *tp)
5429
print_parent_labeledoid(f, tp->parent);
5431
fprintf(f, ".%s(%lu)", tp->label, tp->subid);
5436
print_parent_oid(FILE * f, struct tree *tp)
5440
print_parent_oid(f, tp->parent);
5442
fprintf(f, ".%lu", tp->subid);
5447
print_parent_label(FILE * f, struct tree *tp)
5451
print_parent_label(f, tp->parent);
5453
fprintf(f, ".%s", tp->label);
5459
* This methods generates variations on the original print_subtree() report.
5460
* Traverse the tree depth first, from least to greatest sub-identifier.
5461
* Warning: this methods recurses and calls methods that recurse.
5463
* @param f File descriptor to print to.
5469
print_subtree_oid_report(FILE * f, struct tree *tree, int count)
5483
* find the not reported peer with the lowest sub-identifier.
5484
* if no more, break the loop and cleanup.
5485
* set "reported" flag, and create report for this peer.
5486
* recurse using the children of this peer, if any.
5489
register struct tree *ntp;
5492
for (ntp = tree->child_list; ntp; ntp = ntp->next_peer) {
5496
if (!tp || (tp->subid > ntp->subid))
5504
if (print_subtree_oid_report_labeledoid) {
5505
print_parent_labeledoid(f, tp);
5508
if (print_subtree_oid_report_oid) {
5509
print_parent_oid(f, tp);
5512
if (print_subtree_oid_report_symbolic) {
5513
print_parent_label(f, tp);
5516
if (print_subtree_oid_report_suffix) {
5518
for (i = 0; i < count; i++)
5520
fprintf(f, "%s(%ld) type=%d", tp->label, tp->subid, tp->type);
5521
if (tp->tc_index != -1)
5522
fprintf(f, " tc=%d", tp->tc_index);
5524
fprintf(f, " hint=%s", tp->hint);
5526
fprintf(f, " units=%s", tp->units);
5530
print_subtree_oid_report(f, tp, count);
5533
#endif /* DISABLE_MIB_LOADING */
5537
* Converts timeticks to hours, minutes, seconds string.
5538
* CMU compatible does not show centiseconds.
5540
* @param timeticks The timeticks to convert.
5541
* @param buf Buffer to write to, has to be at
5542
* least 40 Bytes large.
5544
* @return The buffer
5549
uptime_string(u_long timeticks, char *buf)
5551
uptimeString(timeticks, buf);
5552
#ifdef CMU_COMPATIBLE
5554
char *cp = strrchr(buf, '.');
5563
* Given a string, parses an oid out of it (if possible).
5564
* It will try to parse it based on predetermined configuration if
5565
* present or by every method possible otherwise.
5566
* If a suffix has been registered using NETSNMP_DS_LIB_OIDSUFFIX, it
5567
* will be appended to the input string before processing.
5569
* @param argv The OID to string parse
5570
* @param root An OID array where the results are stored.
5571
* @param rootlen The max length of the array going in and the data
5572
* length coming out.
5574
* @return The root oid pointer if successful, or NULL otherwise.
5578
snmp_parse_oid(const char *argv, oid * root, size_t * rootlen)
5580
size_t savlen = *rootlen;
5581
static size_t tmpbuf_len = 0;
5582
static char *tmpbuf;
5583
const char *suffix, *prefix;
5585
suffix = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
5586
NETSNMP_DS_LIB_OIDSUFFIX);
5587
prefix = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
5588
NETSNMP_DS_LIB_OIDPREFIX);
5589
if ((suffix && suffix[0]) || (prefix && prefix[0])) {
5594
if ((strlen(suffix) + strlen(prefix) + strlen(argv) + 2) > tmpbuf_len) {
5595
tmpbuf_len = strlen(suffix) + strlen(argv) + strlen(prefix) + 2;
5596
tmpbuf = realloc(tmpbuf, tmpbuf_len);
5598
snprintf(tmpbuf, tmpbuf_len, "%s%s%s%s", prefix, argv,
5599
((suffix[0] == '.' || suffix[0] == '\0') ? "" : "."),
5602
DEBUGMSGTL(("snmp_parse_oid","Parsing: %s\n",argv));
5605
#ifndef DISABLE_MIB_LOADING
5606
if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_RANDOM_ACCESS)
5607
|| strchr(argv, ':')) {
5608
if (get_node(argv, root, rootlen)) {
5611
} else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_REGEX_ACCESS)) {
5612
clear_tree_flags(tree_head);
5613
if (get_wild_node(argv, root, rootlen)) {
5617
#endif /* DISABLE_MIB_LOADING */
5618
if (read_objid(argv, root, rootlen)) {
5621
#ifndef DISABLE_MIB_LOADING
5623
if (get_node(argv, root, rootlen)) {
5627
DEBUGMSGTL(("parse_oid", "wildly parsing\n"));
5628
clear_tree_flags(tree_head);
5629
if (get_wild_node(argv, root, rootlen)) {
5633
#endif /* DISABLE_MIB_LOADING */
5637
#ifndef DISABLE_MIB_LOADING
5639
* Use DISPLAY-HINT to parse a value into an octet string.
5641
* note that "1d1d", "11" could have come from an octet string that
5642
* looked like { 1, 1 } or an octet string that looked like { 11 }
5643
* because of this, it's doubtful that anyone would use such a display
5644
* string. Therefore, the parser ignores this case.
5647
struct parse_hints {
5653
unsigned char *result;
5658
static void parse_hints_reset(struct parse_hints *ph)
5667
static void parse_hints_ctor(struct parse_hints *ph)
5669
parse_hints_reset(ph);
5675
static int parse_hints_add_result_octet(struct parse_hints *ph, unsigned char octet)
5677
if (!(ph->result_len < ph->result_max)) {
5678
ph->result_max = ph->result_len + 32;
5680
ph->result = (unsigned char *)malloc(ph->result_max);
5682
ph->result = (unsigned char *)realloc(ph->result, ph->result_max);
5687
return 0; /* failed */
5690
ph->result[ph->result_len++] = octet;
5691
return 1; /* success */
5694
static int parse_hints_parse(struct parse_hints *ph, const char **v_in_out)
5696
const char *v = *v_in_out;
5700
int repeat_fixup = ph->result_len;
5703
if (!parse_hints_add_result_octet(ph, 0)) {
5709
switch (ph->format) {
5710
case 'x': base += 6; /* fall through */
5711
case 'd': base += 2; /* fall through */
5712
case 'o': base += 8; /* fall through */
5715
unsigned long number = strtol(v, &nv, base);
5716
if (nv == v) return 0;
5718
for (i = 0; i < ph->length; i++) {
5719
int shift = 8 * (ph->length - 1 - i);
5720
if (!parse_hints_add_result_octet(ph, (u_char)(number >> shift) )) {
5721
return 0; /* failed */
5731
for (i = 0; i < ph->length && *v; i++) {
5732
if (!parse_hints_add_result_octet(ph, *v++)) {
5733
return 0; /* failed */
5742
if (ph->separator && *v) {
5743
if (*v == ph->separator) {
5746
return 0; /* failed */
5750
if (ph->terminator) {
5751
if (*v == ph->terminator) {
5756
} while (ph->repeat && *v);
5758
ph->result[repeat_fixup] = repeats;
5765
static void parse_hints_length_add_digit(struct parse_hints *ph, int digit)
5768
ph->length += digit - '0';
5771
const char *parse_octet_hint(const char *hint, const char *value, unsigned char **new_val, int *new_val_len)
5773
const char *h = hint;
5774
const char *v = value;
5775
struct parse_hints ph;
5785
parse_hints_ctor(&ph);
5786
while (*h && *v && retval) {
5792
} else if (isdigit(*h)) {
5793
parse_hints_length_add_digit(&ph, *h);
5796
return v; /* failed */
5802
parse_hints_length_add_digit(&ph, *h);
5803
/* state = HINT_2_3 */
5804
} else if ('x' == *h || 'd' == *h || 'o' == *h || 'a' == *h) {
5808
return v; /* failed */
5814
retval = parse_hints_parse(&ph, &v);
5815
parse_hints_reset(&ph);
5819
} else if (isdigit(*h)) {
5820
retval = parse_hints_parse(&ph, &v);
5821
parse_hints_reset(&ph);
5823
parse_hints_length_add_digit(&ph, *h);
5833
retval = parse_hints_parse(&ph, &v);
5834
parse_hints_reset(&ph);
5838
} else if (isdigit(*h)) {
5839
retval = parse_hints_parse(&ph, &v);
5840
parse_hints_reset(&ph);
5842
parse_hints_length_add_digit(&ph, *h);
5847
retval = parse_hints_parse(&ph, &v);
5848
parse_hints_reset(&ph);
5856
while (*v && retval) {
5857
retval = parse_hints_parse(&ph, &v);
5860
*new_val = ph.result;
5861
*new_val_len = ph.result_len;
5864
SNMP_FREE(ph.result);
5869
return retval ? NULL : v;
5871
#endif /* DISABLE_MIB_LOADING */
5873
#ifdef test_display_hint
5875
int main(int argc, const char **argv)
5879
unsigned char *new_val;
5884
fprintf(stderr, "usage: dh <hint> <value>\n");
5889
r = parse_octet_hint(hint, value, &new_val, &new_val_len);
5890
printf("{\"%s\", \"%s\"}: \n\t", hint, value);
5893
printf("returned failed\n");
5894
printf("value syntax error at: %s\n", value);
5898
printf("returned success\n");
5899
for (i = 0; i < new_val_len; i++) {
5900
int c = new_val[i] & 0xFF;
5901
printf("%02X(%c) ", c, isprint(c) ? c : ' ');
5909
#endif /* test_display_hint */
5912
mib_to_asn_type(int mib_type)
5916
return ASN_OBJECT_ID;
5919
return ASN_OCTET_STR;
5923
return ASN_IPADDRESS;
5925
case TYPE_INTEGER32:
5935
case TYPE_TIMETICKS:
5936
return ASN_TIMETICKS;
5944
case TYPE_COUNTER64:
5945
return ASN_COUNTER64;
5947
case TYPE_BITSTRING:
5951
case TYPE_UNSIGNED32:
5952
return ASN_UINTEGER;
5954
case TYPE_NSAPADDRESS:
5962
* Converts a string to its OID form.
5963
* in example "hello" = 5 . 'h' . 'e' . 'l' . 'l' . 'o'
5965
* @param S The string.
5967
* @param L The length of the oid.
5969
* @return 0 on Sucess, 1 on failure.
5972
netsnmp_str2oid(const char *S, oid * O, int L)
5977
--L; /* leave room for length prefix */
5979
for (; *c && L; --L, ++o, ++c)
5983
* make sure we got to the end of the string
5989
* set the length of the oid
5997
* Converts an OID to its character form.
5998
* in example 5 . 1 . 2 . 3 . 4 . 5 = 12345
6000
* @param C The character buffer.
6001
* @param L The length of the buffer.
6004
* @return 0 on Sucess, 1 on failure.
6007
netsnmp_oid2chars(char *C, int L, const oid * O)
6010
const oid *o = &O[1];
6015
L = *O; /** length */
6016
for (; L; --L, ++o, ++c) {
6025
* Converts an OID to its string form.
6026
* in example 5 . 'h' . 'e' . 'l' . 'l' . 'o' = "hello\0" (null terminated)
6028
* @param S The character string buffer.
6029
* @param L The length of the string buffer.
6032
* @return 0 on Sucess, 1 on failure.
6035
netsnmp_oid2str(char *S, int L, oid * O)
6042
rc = netsnmp_oid2chars(S, L, O);
6052
snprint_by_type(char *buf, size_t buf_len,
6053
netsnmp_variable_list * var,
6054
const struct enum_list *enums,
6055
const char *hint, const char *units)
6058
if (sprint_realloc_by_type((u_char **) & buf, &buf_len, &out_len, 0,
6059
var, enums, hint, units))
6060
return (int) out_len;
6066
snprint_hexstring(char *buf, size_t buf_len, const u_char * cp, size_t len)
6069
if (sprint_realloc_hexstring((u_char **) & buf, &buf_len, &out_len, 0,
6071
return (int) out_len;
6077
snprint_asciistring(char *buf, size_t buf_len,
6078
const u_char * cp, size_t len)
6081
if (sprint_realloc_asciistring
6082
((u_char **) & buf, &buf_len, &out_len, 0, cp, len))
6083
return (int) out_len;
6089
snprint_octet_string(char *buf, size_t buf_len,
6090
const netsnmp_variable_list * var, const struct enum_list *enums,
6091
const char *hint, const char *units)
6094
if (sprint_realloc_octet_string
6095
((u_char **) & buf, &buf_len, &out_len, 0, var, enums, hint,
6097
return (int) out_len;
6103
snprint_opaque(char *buf, size_t buf_len,
6104
const netsnmp_variable_list * var, const struct enum_list *enums,
6105
const char *hint, const char *units)
6108
if (sprint_realloc_opaque((u_char **) & buf, &buf_len, &out_len, 0,
6109
var, enums, hint, units))
6110
return (int) out_len;
6116
snprint_object_identifier(char *buf, size_t buf_len,
6117
const netsnmp_variable_list * var,
6118
const struct enum_list *enums, const char *hint,
6122
if (sprint_realloc_object_identifier
6123
((u_char **) & buf, &buf_len, &out_len, 0, var, enums, hint,
6125
return (int) out_len;
6131
snprint_timeticks(char *buf, size_t buf_len,
6132
const netsnmp_variable_list * var, const struct enum_list *enums,
6133
const char *hint, const char *units)
6136
if (sprint_realloc_timeticks((u_char **) & buf, &buf_len, &out_len, 0,
6137
var, enums, hint, units))
6138
return (int) out_len;
6144
snprint_hinted_integer(char *buf, size_t buf_len,
6145
long val, const char *hint, const char *units)
6148
if (sprint_realloc_hinted_integer
6149
((u_char **) & buf, &buf_len, &out_len, 0, val, 'd', hint, units))
6150
return (int) out_len;
6156
snprint_integer(char *buf, size_t buf_len,
6157
const netsnmp_variable_list * var, const struct enum_list *enums,
6158
const char *hint, const char *units)
6161
if (sprint_realloc_integer((u_char **) & buf, &buf_len, &out_len, 0,
6162
var, enums, hint, units))
6163
return (int) out_len;
6169
snprint_uinteger(char *buf, size_t buf_len,
6170
const netsnmp_variable_list * var, const struct enum_list *enums,
6171
const char *hint, const char *units)
6174
if (sprint_realloc_uinteger((u_char **) & buf, &buf_len, &out_len, 0,
6175
var, enums, hint, units))
6176
return (int) out_len;
6182
snprint_gauge(char *buf, size_t buf_len,
6183
const netsnmp_variable_list * var, const struct enum_list *enums,
6184
const char *hint, const char *units)
6187
if (sprint_realloc_gauge((u_char **) & buf, &buf_len, &out_len, 0,
6188
var, enums, hint, units))
6189
return (int) out_len;
6195
snprint_counter(char *buf, size_t buf_len,
6196
const netsnmp_variable_list * var, const struct enum_list *enums,
6197
const char *hint, const char *units)
6200
if (sprint_realloc_counter((u_char **) & buf, &buf_len, &out_len, 0,
6201
var, enums, hint, units))
6202
return (int) out_len;
6208
snprint_networkaddress(char *buf, size_t buf_len,
6209
const netsnmp_variable_list * var,
6210
const struct enum_list *enums, const char *hint,
6214
if (sprint_realloc_networkaddress
6215
((u_char **) & buf, &buf_len, &out_len, 0, var, enums, hint,
6217
return (int) out_len;
6223
snprint_ipaddress(char *buf, size_t buf_len,
6224
const netsnmp_variable_list * var, const struct enum_list *enums,
6225
const char *hint, const char *units)
6228
if (sprint_realloc_ipaddress((u_char **) & buf, &buf_len, &out_len, 0,
6229
var, enums, hint, units))
6230
return (int) out_len;
6236
snprint_null(char *buf, size_t buf_len,
6237
const netsnmp_variable_list * var, const struct enum_list *enums,
6238
const char *hint, const char *units)
6241
if (sprint_realloc_null((u_char **) & buf, &buf_len, &out_len, 0,
6242
var, enums, hint, units))
6243
return (int) out_len;
6249
snprint_bitstring(char *buf, size_t buf_len,
6250
const netsnmp_variable_list * var, const struct enum_list *enums,
6251
const char *hint, const char *units)
6254
if (sprint_realloc_bitstring((u_char **) & buf, &buf_len, &out_len, 0,
6255
var, enums, hint, units))
6256
return (int) out_len;
6262
snprint_nsapaddress(char *buf, size_t buf_len,
6263
const netsnmp_variable_list * var, const struct enum_list *enums,
6264
const char *hint, const char *units)
6267
if (sprint_realloc_nsapaddress
6268
((u_char **) & buf, &buf_len, &out_len, 0, var, enums, hint,
6270
return (int) out_len;
6276
snprint_counter64(char *buf, size_t buf_len,
6277
const netsnmp_variable_list * var, const struct enum_list *enums,
6278
const char *hint, const char *units)
6281
if (sprint_realloc_counter64((u_char **) & buf, &buf_len, &out_len, 0,
6282
var, enums, hint, units))
6283
return (int) out_len;
6289
snprint_badtype(char *buf, size_t buf_len,
6290
const netsnmp_variable_list * var, const struct enum_list *enums,
6291
const char *hint, const char *units)
6294
if (sprint_realloc_badtype((u_char **) & buf, &buf_len, &out_len, 0,
6295
var, enums, hint, units))
6296
return (int) out_len;
6301
#ifdef OPAQUE_SPECIAL_TYPES
6303
snprint_float(char *buf, size_t buf_len,
6304
const netsnmp_variable_list * var, const struct enum_list *enums,
6305
const char *hint, const char *units)
6308
if (sprint_realloc_float((u_char **) & buf, &buf_len, &out_len, 0,
6309
var, enums, hint, units))
6310
return (int) out_len;
6316
snprint_double(char *buf, size_t buf_len,
6317
const netsnmp_variable_list * var, const struct enum_list *enums,
6318
const char *hint, const char *units)
6321
if (sprint_realloc_double((u_char **) & buf, &buf_len, &out_len, 0,
6322
var, enums, hint, units))
6323
return (int) out_len;