1310903Sngie/*
2159063Sharti * Copyright (C) 2004-2006
3133211Sharti * 	Hartmut Brandt.
4133211Sharti * 	All rights reserved.
5310903Sngie *
6128237Sharti * Author: Harti Brandt <harti@freebsd.org>
7310903Sngie *
8133211Sharti * Redistribution and use in source and binary forms, with or without
9133211Sharti * modification, are permitted provided that the following conditions
10133211Sharti * are met:
11133211Sharti * 1. Redistributions of source code must retain the above copyright
12133211Sharti *    notice, this list of conditions and the following disclaimer.
13128237Sharti * 2. Redistributions in binary form must reproduce the above copyright
14128237Sharti *    notice, this list of conditions and the following disclaimer in the
15128237Sharti *    documentation and/or other materials provided with the distribution.
16310903Sngie *
17133211Sharti * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18133211Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19133211Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20133211Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21133211Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22133211Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23133211Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24133211Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25133211Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26133211Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27133211Sharti * SUCH DAMAGE.
28128237Sharti *
29159063Sharti * $Begemot: gensnmpdef.c 383 2006-05-30 07:40:49Z brandt_h $
30128237Sharti */
31159063Sharti#include <sys/queue.h>
32159063Sharti
33128237Sharti#include <stdio.h>
34128237Sharti#include <stdlib.h>
35128237Sharti#include <string.h>
36128237Sharti#include <unistd.h>
37128237Sharti#include <errno.h>
38128237Sharti#include <err.h>
39128237Sharti#include <assert.h>
40128237Sharti#include <smi.h>
41128237Sharti
42128237Shartistatic const char usgtxt[] =
43159063Sharti"Usage: gensnmpdef [-hEe] [-c <cut>] MIB [MIB ...]\n"
44128237Sharti"Options:\n"
45128237Sharti"  -c	specify the number of initial sub-oids to cut from the oids\n"
46159063Sharti"  -E	extract named enum types. Print a typedef for all enums defined\n"
47159063Sharti"	in syntax clauses of normal objects. Suppress normal output.\n"
48159063Sharti"  -e	extract unnamed enum types. Print a typedef for all enums defined\n"
49159063Sharti"	as textual conventions. Suppress normal output.\n"
50128237Sharti"  -h	print this help\n"
51128237Sharti"MIBs are searched according to the libsmi(3) search rules and can\n"
52128237Sharti"be specified either by path or module name\n";
53128237Sharti
54128237Shartistatic SmiNode *last_node;
55128237Shartistatic u_int cut = 3;
56128237Sharti
57159063Shartistruct tdef {
58159063Sharti	char *name;
59159063Sharti	SLIST_ENTRY(tdef) link;
60159063Sharti};
61159063Sharti
62205729Santoinestatic SLIST_HEAD(, tdef) tdefs = SLIST_HEAD_INITIALIZER(tdefs);
63159063Shartistatic int do_typedef = 0;
64159063Sharti
65128237Shartistatic void print_node(SmiNode *n, u_int level);
66128237Sharti
67128237Shartistatic void
68128237Shartisave_node(SmiNode *n)
69128237Sharti{
70128237Sharti	if (n != NULL)
71128237Sharti		last_node = n;
72128237Sharti}
73128237Sharti
74128237Shartistatic void
75128237Shartipindent(u_int level)
76128237Sharti{
77128237Sharti	if (level >= cut)
78128237Sharti		printf("%*s", (level - cut) * 2, "");
79128237Sharti}
80128237Sharti
81128237Shartistatic void
82128237Shartiprint_name(SmiNode *n)
83128237Sharti{
84128237Sharti	char *p;
85128237Sharti
86128237Sharti	for (p = n->name; *p != '\0'; p++) {
87128237Sharti		if (*p == '-')
88128237Sharti			printf("_");
89128237Sharti		else
90128237Sharti			printf("%c", *p);
91128237Sharti	}
92128237Sharti}
93128237Sharti
94128237Shartistatic u_int
95128237Sharticlose_node(u_int n, u_int level)
96128237Sharti{
97128237Sharti	while (n--) {
98128237Sharti		pindent(level);
99128237Sharti		level--;
100128237Sharti		if (level >= cut)
101128237Sharti			printf(")\n");
102128237Sharti	}
103128237Sharti	return (level);
104128237Sharti}
105128237Sharti
106128237Shartistatic u_int
107128237Shartiopen_node(const SmiNode *n, u_int level, SmiNode **last)
108128237Sharti{
109128237Sharti	SmiNode *n1;
110128237Sharti	u_int i;
111128237Sharti
112128237Sharti	if (*last != NULL) {
113128237Sharti		for (i = 0; i < (*last)->oidlen - 1; i++) {
114128237Sharti			if (i >= n->oidlen) {
115128237Sharti				level = close_node((*last)->oidlen -
116128237Sharti				    n->oidlen, level);
117128237Sharti				break;
118128237Sharti			}
119128237Sharti			if ((*last)->oid[i] != n->oid[i])
120128237Sharti				break;
121128237Sharti		}
122128237Sharti		if (i < (*last)->oidlen - 1)
123128237Sharti			level = close_node((*last)->oidlen - 1 - i,
124128237Sharti			    level - 1) + 1;
125128237Sharti	}
126128237Sharti
127128237Sharti	while (level < n->oidlen - 1) {
128128237Sharti		if (level >= cut) {
129312098Sngie			n1 = smiGetNodeByOID(level + 1, n->oid);
130312098Sngie			if (n1 == NULL)
131312098Sngie				continue;
132128237Sharti			pindent(level);
133128237Sharti			printf("(%u", n->oid[level]);
134128237Sharti			printf(" ");
135128237Sharti			print_name(n1);
136128237Sharti			printf("\n");
137128237Sharti		}
138128237Sharti		level++;
139128237Sharti	}
140128237Sharti	return (level);
141128237Sharti}
142128237Sharti
143128237Shartistatic const char *const type_names[] = {
144128237Sharti	[SMI_BASETYPE_UNKNOWN] =	"UNKNOWN_TYPE",
145128237Sharti	[SMI_BASETYPE_INTEGER32] =	"INTEGER",
146128237Sharti	[SMI_BASETYPE_OCTETSTRING] =	"OCTETSTRING",
147128237Sharti	[SMI_BASETYPE_OBJECTIDENTIFIER] =	"OID",
148128237Sharti	[SMI_BASETYPE_UNSIGNED32] =	"UNSIGNED32",
149128237Sharti	[SMI_BASETYPE_INTEGER64] =	"INTEGER64",
150128237Sharti	[SMI_BASETYPE_UNSIGNED64] =	"UNSIGNED64",
151128237Sharti	[SMI_BASETYPE_FLOAT32] =	"FLOAT32",
152128237Sharti	[SMI_BASETYPE_FLOAT64] =	"FLOAT64",
153128237Sharti	[SMI_BASETYPE_FLOAT128] =	"FLOAT128",
154159063Sharti	[SMI_BASETYPE_ENUM] =	"ENUM",
155128237Sharti	[SMI_BASETYPE_BITS] =	"BITS",
156128237Sharti};
157128237Sharti
158128237Shartistatic const char *const type_map[] = {
159128237Sharti	"Gauge32",	"GAUGE",
160128237Sharti	"Gauge",	"GAUGE",
161128237Sharti	"TimeTicks",	"TIMETICKS",
162128237Sharti	"Counter32",	"COUNTER",
163128237Sharti	"Counter",	"COUNTER",
164128237Sharti	"Counter64",	"COUNTER64",
165128237Sharti	"Integer32",	"INTEGER32",
166128237Sharti	"IpAddress",	"IPADDRESS",
167128237Sharti	NULL
168128237Sharti};
169128237Sharti
170128237Shartistatic void
171159063Shartiprint_enum(SmiType *t)
172159063Sharti{
173159063Sharti	SmiNamedNumber *nnum;
174159063Sharti
175159063Sharti	printf(" (");
176159063Sharti	for (nnum = smiGetFirstNamedNumber(t); nnum != NULL;
177159063Sharti	    nnum = smiGetNextNamedNumber(nnum))
178159063Sharti		printf(" %ld %s", nnum->value.value.integer32, nnum->name);
179159063Sharti	printf(" )");
180159063Sharti}
181159063Sharti
182159063Shartistatic void
183128237Shartiprint_type(SmiNode *n)
184128237Sharti{
185128237Sharti	SmiType *type;
186128237Sharti	u_int m;
187128237Sharti
188128237Sharti	type = smiGetNodeType(n);
189128237Sharti	assert(type != NULL);
190128237Sharti
191128237Sharti	if (type->name != NULL) {
192128237Sharti		for (m = 0; type_map[m] != NULL; m += 2)
193128237Sharti			if (strcmp(type_map[m], type->name) == 0) {
194128237Sharti				printf("%s", type_map[m + 1]);
195128237Sharti				return;
196128237Sharti			}
197128237Sharti	}
198128237Sharti	printf("%s", type_names[type->basetype]);
199159063Sharti
200159063Sharti	if (type->basetype == SMI_BASETYPE_ENUM ||
201159063Sharti	    type->basetype == SMI_BASETYPE_BITS)
202159063Sharti		print_enum(type);
203159063Sharti
204159063Sharti	else if (type->basetype == SMI_BASETYPE_OCTETSTRING &&
205159063Sharti	    type->name != NULL)
206159063Sharti		printf(" | %s", type->name);
207128237Sharti}
208128237Sharti
209128237Shartistatic void
210128237Shartiprint_access(SmiAccess a)
211128237Sharti{
212128237Sharti	if (a == SMI_ACCESS_READ_ONLY)
213128237Sharti		printf(" GET");
214128237Sharti	else if (a == SMI_ACCESS_READ_WRITE)
215128237Sharti		printf(" GET SET");
216128237Sharti}
217128237Sharti
218128237Shartistatic void
219128237Shartiprint_scalar(SmiNode *n, u_int level)
220128237Sharti{
221128237Sharti	SmiNode *p;
222128237Sharti
223128237Sharti	assert (n->nodekind == SMI_NODEKIND_SCALAR);
224128237Sharti
225128237Sharti	save_node(n);
226128237Sharti
227128237Sharti	pindent(level);
228128237Sharti	printf("(%u ", n->oid[level]);
229128237Sharti	print_name(n);
230128237Sharti	printf(" ");
231128237Sharti	print_type(n);
232128237Sharti
233128237Sharti	/* generate the operation from the parent node name */
234128237Sharti	p = smiGetParentNode(n);
235128237Sharti	printf(" op_%s", p->name);
236128237Sharti
237128237Sharti	print_access(n->access);
238310903Sngie
239128237Sharti	printf(")\n");
240128237Sharti}
241128237Sharti
242128237Shartistatic void
243128237Shartiprint_notification(SmiNode *n, u_int level)
244128237Sharti{
245128237Sharti
246128237Sharti	assert (n->nodekind == SMI_NODEKIND_NOTIFICATION);
247128237Sharti
248128237Sharti	save_node(n);
249128237Sharti
250128237Sharti	pindent(level);
251128237Sharti	printf("(%u ", n->oid[level]);
252128237Sharti	print_name(n);
253128237Sharti	printf(" OID");
254128237Sharti
255128237Sharti	printf(" op_%s)\n", n->name);
256128237Sharti}
257128237Sharti
258128237Shartistatic void
259128237Shartiprint_col(SmiNode *n, u_int level)
260128237Sharti{
261128237Sharti	assert (n->nodekind == SMI_NODEKIND_COLUMN);
262128237Sharti
263128237Sharti	save_node(n);
264128237Sharti
265128237Sharti	pindent(level);
266128237Sharti	printf("(%u ", n->oid[level]);
267128237Sharti	print_name(n);
268128237Sharti	printf(" ");
269128237Sharti	print_type(n);
270128237Sharti	print_access(n->access);
271128237Sharti	printf(")\n");
272128237Sharti}
273128237Sharti
274128237Shartistatic void
275128237Shartiprint_index(SmiNode *row)
276128237Sharti{
277128237Sharti	SmiElement *e;
278128237Sharti
279128237Sharti	e = smiGetFirstElement(row);
280128237Sharti	while (e != NULL) {
281128237Sharti		printf(" ");
282128237Sharti		print_type(smiGetElementNode(e));
283128237Sharti		e = smiGetNextElement(e);
284128237Sharti	}
285128237Sharti}
286128237Sharti
287128237Shartistatic void
288128237Shartiprint_table(SmiNode *n, u_int level)
289128237Sharti{
290128237Sharti	SmiNode *row, *col, *rel;
291128237Sharti
292128237Sharti	assert (n->nodekind == SMI_NODEKIND_TABLE);
293128237Sharti
294128237Sharti	save_node(n);
295128237Sharti
296128237Sharti	pindent(level);
297128237Sharti	printf("(%u ", n->oid[level]);
298128237Sharti	print_name(n);
299128237Sharti	printf("\n");
300128237Sharti
301128237Sharti	row = smiGetFirstChildNode(n);
302128237Sharti	if (row->nodekind != SMI_NODEKIND_ROW)
303128237Sharti		errx(1, "%s: kind %u, not row", __func__, row->nodekind);
304128237Sharti
305128237Sharti	save_node(n);
306128237Sharti
307128237Sharti	pindent(level + 1);
308128237Sharti	printf("(%u ", row->oid[level + 1]);
309128237Sharti	print_name(row);
310128237Sharti	printf(" :");
311128237Sharti
312128237Sharti	/* index */
313128237Sharti	rel = smiGetRelatedNode(row);
314128237Sharti	switch (row->indexkind) {
315128237Sharti
316128237Sharti	  case SMI_INDEX_INDEX:
317128237Sharti		print_index(row);
318128237Sharti		break;
319128237Sharti
320128237Sharti	  case SMI_INDEX_AUGMENT:
321128237Sharti		if (rel == NULL)
322128237Sharti			errx(1, "%s: cannot find augemented table", row->name);
323128237Sharti		print_index(rel);
324128237Sharti		break;
325128237Sharti
326128237Sharti	  default:
327128237Sharti		errx(1, "%s: cannot handle index kind %u", row->name,
328128237Sharti		    row->indexkind);
329128237Sharti	}
330128237Sharti
331128237Sharti	printf(" op_%s", n->name);
332128237Sharti	printf("\n");
333128237Sharti
334128237Sharti	col = smiGetFirstChildNode(row);
335128237Sharti	while (col != NULL) {
336128237Sharti		print_col(col, level + 2);
337128237Sharti		col = smiGetNextChildNode(col);
338128237Sharti	}
339128237Sharti	pindent(level + 1);
340128237Sharti	printf(")\n");
341128237Sharti
342128237Sharti	pindent(level);
343128237Sharti	printf(")\n");
344128237Sharti}
345128237Sharti
346128237Shartistatic void
347128237Shartiprint_it(SmiNode *n, u_int level)
348128237Sharti{
349128237Sharti	switch (n->nodekind) {
350128237Sharti
351128237Sharti	  case SMI_NODEKIND_NODE:
352128237Sharti		print_node(n, level);
353128237Sharti		break;
354128237Sharti
355128237Sharti	  case SMI_NODEKIND_SCALAR:
356128237Sharti		print_scalar(n, level);
357128237Sharti		break;
358128237Sharti
359128237Sharti	  case SMI_NODEKIND_TABLE:
360128237Sharti		print_table(n, level);
361128237Sharti		break;
362128237Sharti
363128237Sharti	  case SMI_NODEKIND_COMPLIANCE:
364128237Sharti	  case SMI_NODEKIND_GROUP:
365128237Sharti		save_node(n);
366128237Sharti		break;
367128237Sharti
368128237Sharti	  case SMI_NODEKIND_NOTIFICATION:
369128237Sharti		print_notification(n, level);
370128237Sharti		break;
371128237Sharti
372128237Sharti	  default:
373128237Sharti		errx(1, "cannot handle %u nodes", n->nodekind);
374128237Sharti	}
375128237Sharti}
376128237Sharti
377128237Shartistatic void
378128237Shartiprint_node(SmiNode *n, u_int level)
379128237Sharti{
380128237Sharti	assert (n->nodekind == SMI_NODEKIND_NODE);
381128237Sharti
382128237Sharti	save_node(n);
383128237Sharti
384128237Sharti	pindent(level);
385128237Sharti	printf("(%u ", n->oid[level]);
386128237Sharti	print_name(n);
387128237Sharti	printf("\n");
388128237Sharti
389128237Sharti	n = smiGetFirstChildNode(n);
390128237Sharti	while (n != NULL) {
391128237Sharti		print_it(n, level + 1);
392128237Sharti		n = smiGetNextChildNode(n);
393128237Sharti	}
394128237Sharti	pindent(level);
395128237Sharti	printf(")\n");
396128237Sharti}
397128237Sharti
398159063Shartistatic void
399159063Shartisave_typdef(char *name)
400159063Sharti{
401159063Sharti	struct tdef *t;
402159063Sharti
403312098Sngie	t = calloc(1, sizeof(struct tdef));
404159063Sharti	if (t == NULL)
405159063Sharti		err(1, NULL);
406159063Sharti
407159063Sharti	t->name = name;
408159063Sharti	SLIST_INSERT_HEAD(&tdefs, t, link);
409159063Sharti}
410159063Sharti
411159063Shartistatic void
412159063Shartitdefs_cleanup(void)
413159063Sharti{
414159063Sharti	struct tdef *t;
415159063Sharti
416159063Sharti	while ((t = SLIST_FIRST(&tdefs)) != NULL) {
417159063Sharti		SLIST_REMOVE_HEAD(&tdefs, link);
418159063Sharti		free(t);
419159063Sharti	}
420159063Sharti}
421159063Sharti
422159063Shartistatic void
423159063Shartiprint_enum_typedef(SmiType *t)
424159063Sharti{
425159063Sharti	SmiNamedNumber *nnum;
426310903Sngie
427159063Sharti	for (nnum = smiGetFirstNamedNumber(t); nnum != NULL;
428159063Sharti	    nnum = smiGetNextNamedNumber(nnum)) {
429159063Sharti		printf("\t%ld %s\n" , nnum->value.value.integer32, nnum->name);
430159063Sharti	}
431159063Sharti}
432159063Sharti
433159063Shartistatic void
434159063Shartiprint_stype(SmiNode *n)
435159063Sharti{
436159063Sharti	SmiType *type;
437159063Sharti	struct tdef *t = NULL;
438310903Sngie
439159063Sharti	type = smiGetNodeType(n);
440159063Sharti	assert(type != NULL);
441310903Sngie
442159063Sharti	if (type->basetype == SMI_BASETYPE_ENUM) {
443159063Sharti		if (do_typedef == 'e' && type->name != NULL) {
444159063Sharti			SLIST_FOREACH(t, &tdefs, link) {
445159063Sharti				if (strcmp(t->name, type->name) == 0)
446159063Sharti					return;
447159063Sharti			}
448159063Sharti			save_typdef(type->name);
449159063Sharti			printf("typedef %s ENUM (\n", type->name);
450159063Sharti		} else if (do_typedef == 'E' && type->name == NULL)
451159063Sharti			printf("typedef %sType ENUM (\n", n->name);
452159063Sharti		else
453159063Sharti			return;
454310903Sngie
455159063Sharti		print_enum_typedef(type);
456159063Sharti		printf(")\n\n");
457159063Sharti
458159063Sharti	} else if (type->basetype == SMI_BASETYPE_BITS) {
459159063Sharti		if (do_typedef == 'e' && type->name != NULL) {
460159063Sharti			SLIST_FOREACH(t, &tdefs, link) {
461159063Sharti				if (strcmp(t->name, type->name) == 0)
462159063Sharti					return;
463159063Sharti			}
464159063Sharti			save_typdef(type->name);
465159063Sharti			printf("typedef %s BITS (\n", type->name);
466159063Sharti		} else if (do_typedef == 'E' && type->name == NULL)
467159063Sharti			printf("typedef %sType BITS (\n", n->name);
468159063Sharti		else
469159063Sharti			return;
470159063Sharti
471159063Sharti		print_enum_typedef(type);
472159063Sharti		printf(")\n\n");
473159063Sharti	}
474159063Sharti}
475159063Sharti
476159063Shartistatic void
477159063Shartiprint_typdefs(SmiNode *n)
478159063Sharti{
479159063Sharti	SmiNode *p;
480310903Sngie
481159063Sharti	p = n;
482159063Sharti	n = smiGetFirstChildNode(n);
483159063Sharti	while (n != NULL) {
484159063Sharti		switch (n->nodekind) {
485159063Sharti		  case SMI_NODEKIND_SCALAR:
486159063Sharti		  case SMI_NODEKIND_COLUMN:
487159063Sharti			print_stype(n);
488159063Sharti			break;
489159063Sharti		  case SMI_NODEKIND_COMPLIANCE:
490159063Sharti	  	  case SMI_NODEKIND_GROUP:
491159063Sharti			save_node(n);
492159063Sharti			return;
493159063Sharti		  default:
494159063Sharti			break;
495159063Sharti		}
496159063Sharti		n = smiGetNextChildNode(n);
497159063Sharti	}
498159063Sharti
499159063Sharti	save_node(p);
500159063Sharti}
501159063Sharti
502128237Shartiint
503128237Shartimain(int argc, char *argv[])
504128237Sharti{
505128237Sharti	int opt;
506128237Sharti	int flags;
507128237Sharti	SmiModule **mods;
508128237Sharti	char *name;
509128237Sharti	SmiNode *n, *last;
510128237Sharti	u_int level;
511128237Sharti	long u;
512128237Sharti	char *end;
513128237Sharti
514128237Sharti	smiInit(NULL);
515128237Sharti
516159063Sharti	while ((opt = getopt(argc, argv, "c:Eeh")) != -1)
517128237Sharti		switch (opt) {
518128237Sharti
519128237Sharti		  case 'c':
520128237Sharti			errno = 0;
521128237Sharti			u = strtol(optarg, &end, 10);
522128237Sharti			if (errno != 0)
523128237Sharti				err(1, "argument to -c");
524128237Sharti			if (*end != '\0')
525128237Sharti				err(1, "%s: not a number", optarg);
526128237Sharti			if (u < 0 || u > 5)
527128237Sharti				err(1, "%s: out of range", optarg);
528128237Sharti			cut = (u_int)u;
529128237Sharti			break;
530128237Sharti
531159063Sharti		  case 'E':
532159063Sharti			do_typedef = 'E';
533159063Sharti			break;
534159063Sharti
535159063Sharti		  case 'e':
536159063Sharti			do_typedef = 'e';
537159063Sharti			break;
538159063Sharti
539128237Sharti		  case 'h':
540128237Sharti			fprintf(stderr, usgtxt);
541128237Sharti			exit(0);
542128237Sharti		}
543128237Sharti
544128237Sharti	argc -= optind;
545128237Sharti	argv += optind;
546128237Sharti
547128237Sharti	flags = smiGetFlags();
548128237Sharti	flags |= SMI_FLAG_ERRORS;
549128237Sharti	smiSetFlags(flags);
550128237Sharti
551128237Sharti	mods = malloc(sizeof(mods[0]) * argc);
552128237Sharti	if (mods == NULL)
553128237Sharti		err(1, NULL);
554128237Sharti
555128237Sharti	for (opt = 0; opt < argc; opt++) {
556128237Sharti		if ((name = smiLoadModule(argv[opt])) == NULL)
557128237Sharti			err(1, "%s: cannot load", argv[opt]);
558128237Sharti		mods[opt] = smiGetModule(name);
559128237Sharti	}
560128237Sharti	level = 0;
561128237Sharti	last = NULL;
562128237Sharti	for (opt = 0; opt < argc; opt++) {
563312098Sngie		if (mods[opt] == NULL) /* smiGetModule failed above */
564312098Sngie			continue;
565128237Sharti		n = smiGetFirstNode(mods[opt], SMI_NODEKIND_ANY);
566312098Sngie		if (n == NULL)
567312098Sngie			continue;
568128237Sharti		for (;;) {
569159063Sharti			if (do_typedef == 0) {
570159063Sharti				level = open_node(n, level, &last);
571159063Sharti				print_it(n, level);
572159063Sharti				last = n;
573159063Sharti			} else
574159063Sharti				print_typdefs(n);
575128237Sharti
576128237Sharti			if (last_node == NULL ||
577128237Sharti			    (n = smiGetNextNode(last_node, SMI_NODEKIND_ANY))
578128237Sharti			    == NULL)
579128237Sharti				break;
580128237Sharti		}
581128237Sharti	}
582159063Sharti	if (last != NULL && do_typedef == 0)
583159063Sharti		level = close_node(last->oidlen - 1, level - 1);
584159063Sharti	else if (do_typedef != 0)
585159063Sharti		tdefs_cleanup();
586159063Sharti
587128237Sharti	return (0);
588128237Sharti}
589