1 /*
2 * snmptranslate.c - report or translate info about oid from mibs
3 *
4 * Update: 1998-07-17 <jhy@gsu.edu>
5 * Added support for dumping alternate oid reports (-t and -T options).
6 * Added more detailed (useful?) usage info.
7 */
8 /************************************************************************
9 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
10
11 All Rights Reserved
12
13 Permission to use, copy, modify, and distribute this software and its
14 documentation for any purpose and without fee is hereby granted,
15 provided that the above copyright notice appear in all copies and that
16 both that copyright notice and this permission notice appear in
17 supporting documentation, and that the name of CMU not be
18 used in advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
22 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
23 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
24 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
25 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27 SOFTWARE.
28 ******************************************************************/
29
30
31 #include <net-snmp/net-snmp-config.h>
32
33 #if HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
36 #if HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39 #if HAVE_STRING_H
40 #include <string.h>
41 #else
42 #include <strings.h>
43 #endif
44 #include <sys/types.h>
45 #if HAVE_SYS_SELECT_H
46 #include <sys/select.h>
47 #endif
48 #if HAVE_NETINET_IN_H
49 #include <netinet/in.h>
50 #endif
51 #include <stdio.h>
52 #include <ctype.h>
53 #include <net-snmp/utilities.h>
54 #include <net-snmp/config_api.h>
55 #include <net-snmp/output_api.h>
56 #include <net-snmp/mib_api.h>
57
58 int show_all_matched_objects(FILE *, const char *, oid *,
59 size_t *, int, int);
60
61 void
usage(void)62 usage(void)
63 {
64 fprintf(stderr, "USAGE: snmptranslate [OPTIONS] OID [OID]...\n\n");
65 fprintf(stderr, " Version: %s\n", netsnmp_get_version());
66 fprintf(stderr, " Web: http://www.net-snmp.org/\n");
67 fprintf(stderr,
68 " Email: net-snmp-coders@lists.sourceforge.net\n\nOPTIONS:\n");
69
70 fprintf(stderr, " -h\t\t\tdisplay this help message\n");
71 fprintf(stderr, " -V\t\t\tdisplay package version number\n");
72 fprintf(stderr,
73 " -m MIB[" ENV_SEPARATOR "...]\t\tload given list of MIBs (ALL loads everything)\n");
74 fprintf(stderr,
75 " -M DIR[" ENV_SEPARATOR "...]\t\tlook in given list of directories for MIBs\n");
76 fprintf(stderr,
77 " -D[TOKEN[,...]]\tturn on debugging output for the specified TOKENs\n\t\t\t (ALL gives extremely verbose debugging output)\n");
78 fprintf(stderr, " -w WIDTH\t\tset width of tree and detail output\n");
79 fprintf(stderr,
80 " -T TRANSOPTS\t\tSet various options controlling report produced:\n");
81 fprintf(stderr,
82 "\t\t\t B: print all matching objects for a regex search\n");
83 fprintf(stderr, "\t\t\t d: print full details of the given OID\n");
84 fprintf(stderr, "\t\t\t p: print tree format symbol table\n");
85 fprintf(stderr, "\t\t\t a: print ASCII format symbol table\n");
86 fprintf(stderr, "\t\t\t l: enable labeled OID report\n");
87 fprintf(stderr, "\t\t\t o: enable OID report\n");
88 fprintf(stderr, "\t\t\t s: enable dotted symbolic report\n");
89 fprintf(stderr, "\t\t\t z: enable MIB child OID report\n");
90 fprintf(stderr,
91 "\t\t\t t: enable alternate format symbolic suffix report\n");
92 #ifndef NETSNMP_DISABLE_MIB_LOADING
93 fprintf(stderr,
94 " -P MIBOPTS\t\tToggle various defaults controlling mib parsing:\n");
95 snmp_mib_toggle_options_usage("\t\t\t ", stderr);
96 #endif /* NETSNMP_DISABLE_MIB_LOADING */
97 fprintf(stderr,
98 " -O OUTOPTS\t\tToggle various defaults controlling output display:\n");
99 snmp_out_toggle_options_usage("\t\t\t ", stderr);
100 fprintf(stderr,
101 " -I INOPTS\t\tToggle various defaults controlling input parsing:\n");
102 snmp_in_toggle_options_usage("\t\t\t ", stderr);
103 fprintf(stderr,
104 " -L LOGOPTS\t\tToggle various defaults controlling logging:\n");
105 snmp_log_options_usage("\t\t\t ", stderr);
106 }
107
108 /**
109 * For every line on stdin, assume that it is either a plain OID
110 * or snmpwalk/snmpget output:
111 * mib-2.1.2.3.4
112 * -or-
113 * mib-2.1.2.3.4 = INTEGER: 5
114 *
115 * Replace the OID with its translation.
116 * If translation fails, just output the original string.
117 */
118 #define MAX_LINE_TEMP 10240
119 void
process_stdin(void)120 process_stdin(void)
121 {
122 char buf[MAX_LINE_TEMP];
123 oid name[MAX_OID_LEN];
124 size_t name_length;
125
126 while ( NULL != fgets( buf, sizeof( buf ), stdin ) ) {
127 char delim = ' ';
128 char *nl = strchr(buf, '\n');
129 char *rest = strchr(buf, delim);
130
131 if (nl != NULL) {
132 *nl = '\0';
133 } /* else too-long line: output will look weird. Too bad. */
134 if (rest == NULL) {
135 delim = '\t';
136 rest = strchr(buf, delim);
137 }
138 if (rest != NULL) {
139 *rest++ = '\0';
140 }
141 name_length = MAX_OID_LEN;
142 /*
143 * If it's not the whole line, only try to process buffer
144 * longer than 5 characters.
145 * The idea is to avoid false positives including, e.g.,
146 * a hex dump.
147 */
148 if ( !(rest && strlen( buf ) <= 5) &&
149 read_objid( buf, name, &name_length )) {
150 char objbuf[MAX_LINE_TEMP];
151 snprint_objid( objbuf, MAX_LINE_TEMP, name, name_length );
152 fputs( objbuf, stdout );
153 } else {
154 fputs( buf, stdout );
155 }
156 /*
157 * For future improvement: if delim == ' ' && rest && *rest == '='
158 * see if rest looks like snmpget/snmpwalk output
159 * and handle it in the context of the given node
160 */
161 if (rest) {
162 fputc( delim, stdout );
163 fputs( rest, stdout );
164 }
165 fputc( '\n', stdout );
166 }
167 }
168
169 int
main(int argc,char * argv[])170 main(int argc, char *argv[])
171 {
172 int arg;
173 char *current_name = NULL, *cp = NULL;
174 oid name[MAX_OID_LEN];
175 size_t name_length;
176 int description = 0;
177 int print = 0;
178 int find_all = 0;
179 int width = 1000000;
180 int exit_code = 1;
181 netsnmp_session dummy;
182
183 SOCK_STARTUP;
184
185 /*
186 * usage: snmptranslate name
187 */
188 snmp_sess_init(&dummy);
189 while ((arg = getopt(argc, argv, "Vhm:M:w:D:P:T:O:I:L:")) != EOF) {
190 switch (arg) {
191 case 'h':
192 usage();
193 goto out;
194
195 case 'm':
196 setenv("MIBS", optarg, 1);
197 break;
198 case 'M':
199 setenv("MIBDIRS", optarg, 1);
200 break;
201 case 'D':
202 debug_register_tokens(optarg);
203 snmp_set_do_debugging(1);
204 break;
205 case 'V':
206 fprintf(stderr, "NET-SNMP version: %s\n",
207 netsnmp_get_version());
208 exit_code = 0;
209 goto out;
210 break;
211 case 'w':
212 width = atoi(optarg);
213 if (width <= 0) {
214 fprintf(stderr, "Invalid width specification: %s\n", optarg);
215 goto out;
216 }
217 break;
218 #ifndef NETSNMP_DISABLE_MIB_LOADING
219 case 'P':
220 cp = snmp_mib_toggle_options(optarg);
221 if (cp != NULL) {
222 fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
223 usage();
224 goto out;
225 }
226 break;
227 #endif /* NETSNMP_DISABLE_MIB_LOADING */
228 case 'O':
229 cp = snmp_out_toggle_options(optarg);
230 if (cp != NULL) {
231 fprintf(stderr, "Unknown OID option to -O: %c.\n", *cp);
232 usage();
233 goto out;
234 }
235 break;
236 case 'I':
237 cp = snmp_in_toggle_options(optarg);
238 if (cp != NULL) {
239 fprintf(stderr, "Unknown OID option to -I: %c.\n", *cp);
240 usage();
241 goto out;
242 }
243 break;
244 case 'T':
245 for (cp = optarg; *cp; cp++) {
246 switch (*cp) {
247 #ifndef NETSNMP_DISABLE_MIB_LOADING
248 case 'l':
249 print = 3;
250 print_oid_report_enable_labeledoid();
251 break;
252 case 'o':
253 print = 3;
254 print_oid_report_enable_oid();
255 break;
256 case 's':
257 print = 3;
258 print_oid_report_enable_symbolic();
259 break;
260 case 't':
261 print = 3;
262 print_oid_report_enable_suffix();
263 break;
264 case 'z':
265 print = 3;
266 print_oid_report_enable_mibchildoid();
267 break;
268 #endif /* NETSNMP_DISABLE_MIB_LOADING */
269 case 'd':
270 description = 1;
271 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
272 NETSNMP_DS_LIB_SAVE_MIB_DESCRS, 1);
273 break;
274 case 'B':
275 find_all = 1;
276 break;
277 case 'p':
278 print = 1;
279 break;
280 case 'a':
281 print = 2;
282 break;
283 default:
284 fprintf(stderr, "Invalid -T<lostpad> character: %c\n",
285 *cp);
286 usage();
287 goto out;
288 }
289 }
290 break;
291 case 'L':
292 if (snmp_log_options(optarg, argc, argv) < 0)
293 goto out;
294 break;
295 default:
296 fprintf(stderr, "invalid option: -%c\n", arg);
297 usage();
298 goto out;
299 }
300 }
301
302 init_snmp(NETSNMP_APPLICATION_CONFIG_TYPE);
303
304 if (optind < argc)
305 current_name = argv[optind];
306
307 if (current_name == NULL) {
308 switch (print) {
309 default:
310 usage();
311 goto out;
312 #ifndef NETSNMP_DISABLE_MIB_LOADING
313 case 1:
314 print_mib_tree(stdout, get_tree_head(), width);
315 break;
316 case 2:
317 print_ascii_dump(stdout);
318 break;
319 case 3:
320 print_oid_report(stdout);
321 break;
322 #endif /* NETSNMP_DISABLE_MIB_LOADING */
323 }
324 exit_code = 0;
325 goto out;
326 }
327
328 do {
329 if ( strcmp( current_name, "-" ) == 0 && ( print == 0 ) ) {
330 process_stdin();
331 current_name = argv[++optind];
332 continue;
333 }
334
335 name_length = MAX_OID_LEN;
336 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
337 NETSNMP_DS_LIB_RANDOM_ACCESS)) {
338 #ifndef NETSNMP_DISABLE_MIB_LOADING
339 if (!get_node(current_name, name, &name_length)) {
340 #endif /* NETSNMP_DISABLE_MIB_LOADING */
341 fprintf(stderr, "Unknown object identifier: %s\n",
342 current_name);
343 exit_code = 2;
344 goto out;
345 #ifndef NETSNMP_DISABLE_MIB_LOADING
346 }
347 #endif /* NETSNMP_DISABLE_MIB_LOADING */
348 } else if (find_all) {
349 if (0 == show_all_matched_objects(stdout, current_name,
350 name, &name_length,
351 description, width)) {
352 fprintf(stderr,
353 "Unable to find a matching object identifier for \"%s\"\n",
354 current_name);
355 goto out;
356 }
357 break;
358 } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
359 NETSNMP_DS_LIB_REGEX_ACCESS)) {
360 #ifndef NETSNMP_DISABLE_MIB_LOADING
361 if (0 == get_wild_node(current_name, name, &name_length)) {
362 #endif /* NETSNMP_DISABLE_MIB_LOADING */
363 fprintf(stderr,
364 "Unable to find a matching object identifier for \"%s\"\n",
365 current_name);
366 goto out;
367 #ifndef NETSNMP_DISABLE_MIB_LOADING
368 }
369 #endif /* NETSNMP_DISABLE_MIB_LOADING */
370 } else {
371 if (!read_objid(current_name, name, &name_length)) {
372 snmp_perror(current_name);
373 exit_code = 2;
374 goto out;
375 }
376 }
377
378
379 if (print == 1) {
380 #ifndef NETSNMP_DISABLE_MIB_LOADING
381 struct tree *tp;
382 tp = get_tree(name, name_length, get_tree_head());
383 if (tp == NULL) {
384 #endif /* NETSNMP_DISABLE_MIB_LOADING */
385 snmp_log(LOG_ERR,
386 "Unable to find a matching object identifier for \"%s\"\n",
387 current_name);
388 goto out;
389 #ifndef NETSNMP_DISABLE_MIB_LOADING
390 }
391 print_mib_tree(stdout, tp, width);
392 #endif /* NETSNMP_DISABLE_MIB_LOADING */
393 } else {
394 print_objid(name, name_length);
395 if (description) {
396 #ifndef NETSNMP_DISABLE_MIB_LOADING
397 print_description(name, name_length, width);
398 #endif /* NETSNMP_DISABLE_MIB_LOADING */
399 }
400 }
401 current_name = argv[++optind];
402 if (current_name != NULL)
403 printf("\n");
404 } while (optind < argc);
405
406 exit_code = 0;
407
408 out:
409 SOCK_CLEANUP;
410 return exit_code;
411 }
412
413 /*
414 * Show all object identifiers that match the pattern.
415 */
416
417 int
show_all_matched_objects(FILE * fp,const char * patmatch,oid * name,size_t * name_length,int f_desc,int width)418 show_all_matched_objects(FILE * fp, const char *patmatch, oid * name, size_t * name_length, int f_desc, /* non-zero if descriptions should be shown */
419 int width)
420 {
421 int result = 0, count = 0;
422 size_t savlen = *name_length;
423 #ifndef NETSNMP_DISABLE_MIB_LOADING
424 clear_tree_flags(get_tree_head());
425 #endif /* NETSNMP_DISABLE_MIB_LOADING */
426
427 while (1) {
428 *name_length = savlen;
429 #ifndef NETSNMP_DISABLE_MIB_LOADING
430 result = get_wild_node(patmatch, name, name_length);
431 #endif /* NETSNMP_DISABLE_MIB_LOADING */
432 if (!result)
433 break;
434 count++;
435
436 fprint_objid(fp, name, *name_length);
437 #ifndef NETSNMP_DISABLE_MIB_LOADING
438 if (f_desc)
439 fprint_description(fp, name, *name_length, width);
440 #endif /* NETSNMP_DISABLE_MIB_LOADING */
441 }
442
443 return (count);
444 }
445