1133211Sharti/*
2159063Sharti * Copyright (C) 2004-2006
3133211Sharti * 	Hartmut Brandt.
4133211Sharti * 	All rights reserved.
5133211Sharti *
6128237Sharti * Author: Harti Brandt <harti@freebsd.org>
7133211Sharti *
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.
16133211Sharti *
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) {
129128237Sharti			pindent(level);
130128237Sharti			printf("(%u", n->oid[level]);
131128237Sharti			n1 = smiGetNodeByOID(level + 1, n->oid);
132128237Sharti			printf(" ");
133128237Sharti			print_name(n1);
134128237Sharti			printf("\n");
135128237Sharti		}
136128237Sharti		level++;
137128237Sharti	}
138128237Sharti	return (level);
139128237Sharti}
140128237Sharti
141128237Shartistatic const char *const type_names[] = {
142128237Sharti	[SMI_BASETYPE_UNKNOWN] =	"UNKNOWN_TYPE",
143128237Sharti	[SMI_BASETYPE_INTEGER32] =	"INTEGER",
144128237Sharti	[SMI_BASETYPE_OCTETSTRING] =	"OCTETSTRING",
145128237Sharti	[SMI_BASETYPE_OBJECTIDENTIFIER] =	"OID",
146128237Sharti	[SMI_BASETYPE_UNSIGNED32] =	"UNSIGNED32",
147128237Sharti	[SMI_BASETYPE_INTEGER64] =	"INTEGER64",
148128237Sharti	[SMI_BASETYPE_UNSIGNED64] =	"UNSIGNED64",
149128237Sharti	[SMI_BASETYPE_FLOAT32] =	"FLOAT32",
150128237Sharti	[SMI_BASETYPE_FLOAT64] =	"FLOAT64",
151128237Sharti	[SMI_BASETYPE_FLOAT128] =	"FLOAT128",
152159063Sharti	[SMI_BASETYPE_ENUM] =	"ENUM",
153128237Sharti	[SMI_BASETYPE_BITS] =	"BITS",
154128237Sharti};
155128237Sharti
156128237Shartistatic const char *const type_map[] = {
157128237Sharti	"Gauge32",	"GAUGE",
158128237Sharti	"Gauge",	"GAUGE",
159128237Sharti	"TimeTicks",	"TIMETICKS",
160128237Sharti	"Counter32",	"COUNTER",
161128237Sharti	"Counter",	"COUNTER",
162128237Sharti	"Counter64",	"COUNTER64",
163128237Sharti	"Integer32",	"INTEGER32",
164128237Sharti	"IpAddress",	"IPADDRESS",
165128237Sharti	NULL
166128237Sharti};
167128237Sharti
168128237Shartistatic void
169159063Shartiprint_enum(SmiType *t)
170159063Sharti{
171159063Sharti	SmiNamedNumber *nnum;
172159063Sharti
173159063Sharti	printf(" (");
174159063Sharti	for (nnum = smiGetFirstNamedNumber(t); nnum != NULL;
175159063Sharti	    nnum = smiGetNextNamedNumber(nnum))
176159063Sharti		printf(" %ld %s", nnum->value.value.integer32, nnum->name);
177159063Sharti	printf(" )");
178159063Sharti}
179159063Sharti
180159063Shartistatic void
181128237Shartiprint_type(SmiNode *n)
182128237Sharti{
183128237Sharti	SmiType *type;
184128237Sharti	u_int m;
185128237Sharti
186128237Sharti	type = smiGetNodeType(n);
187128237Sharti	assert(type != NULL);
188128237Sharti
189128237Sharti	if (type->name != NULL) {
190128237Sharti		for (m = 0; type_map[m] != NULL; m += 2)
191128237Sharti			if (strcmp(type_map[m], type->name) == 0) {
192128237Sharti				printf("%s", type_map[m + 1]);
193128237Sharti				return;
194128237Sharti			}
195128237Sharti	}
196128237Sharti	printf("%s", type_names[type->basetype]);
197159063Sharti
198159063Sharti	if (type->basetype == SMI_BASETYPE_ENUM ||
199159063Sharti	    type->basetype == SMI_BASETYPE_BITS)
200159063Sharti		print_enum(type);
201159063Sharti
202159063Sharti	else if (type->basetype == SMI_BASETYPE_OCTETSTRING &&
203159063Sharti	    type->name != NULL)
204159063Sharti		printf(" | %s", type->name);
205128237Sharti}
206128237Sharti
207128237Shartistatic void
208128237Shartiprint_access(SmiAccess a)
209128237Sharti{
210128237Sharti	if (a == SMI_ACCESS_READ_ONLY)
211128237Sharti		printf(" GET");
212128237Sharti	else if (a == SMI_ACCESS_READ_WRITE)
213128237Sharti		printf(" GET SET");
214128237Sharti}
215128237Sharti
216128237Shartistatic void
217128237Shartiprint_scalar(SmiNode *n, u_int level)
218128237Sharti{
219128237Sharti	SmiNode *p;
220128237Sharti
221128237Sharti	assert (n->nodekind == SMI_NODEKIND_SCALAR);
222128237Sharti
223128237Sharti	save_node(n);
224128237Sharti
225128237Sharti	pindent(level);
226128237Sharti	printf("(%u ", n->oid[level]);
227128237Sharti	print_name(n);
228128237Sharti	printf(" ");
229128237Sharti	print_type(n);
230128237Sharti
231128237Sharti	/* generate the operation from the parent node name */
232128237Sharti	p = smiGetParentNode(n);
233128237Sharti	printf(" op_%s", p->name);
234128237Sharti
235128237Sharti	print_access(n->access);
236128237Sharti
237128237Sharti	printf(")\n");
238128237Sharti}
239128237Sharti
240128237Shartistatic void
241128237Shartiprint_notification(SmiNode *n, u_int level)
242128237Sharti{
243128237Sharti
244128237Sharti	assert (n->nodekind == SMI_NODEKIND_NOTIFICATION);
245128237Sharti
246128237Sharti	save_node(n);
247128237Sharti
248128237Sharti	pindent(level);
249128237Sharti	printf("(%u ", n->oid[level]);
250128237Sharti	print_name(n);
251128237Sharti	printf(" OID");
252128237Sharti
253128237Sharti	printf(" op_%s)\n", n->name);
254128237Sharti}
255128237Sharti
256128237Shartistatic void
257128237Shartiprint_col(SmiNode *n, u_int level)
258128237Sharti{
259128237Sharti	assert (n->nodekind == SMI_NODEKIND_COLUMN);
260128237Sharti
261128237Sharti	save_node(n);
262128237Sharti
263128237Sharti	pindent(level);
264128237Sharti	printf("(%u ", n->oid[level]);
265128237Sharti	print_name(n);
266128237Sharti	printf(" ");
267128237Sharti	print_type(n);
268128237Sharti	print_access(n->access);
269128237Sharti	printf(")\n");
270128237Sharti}
271128237Sharti
272128237Shartistatic void
273128237Shartiprint_index(SmiNode *row)
274128237Sharti{
275128237Sharti	SmiElement *e;
276128237Sharti
277128237Sharti	e = smiGetFirstElement(row);
278128237Sharti	while (e != NULL) {
279128237Sharti		printf(" ");
280128237Sharti		print_type(smiGetElementNode(e));
281128237Sharti		e = smiGetNextElement(e);
282128237Sharti	}
283128237Sharti}
284128237Sharti
285128237Shartistatic void
286128237Shartiprint_table(SmiNode *n, u_int level)
287128237Sharti{
288128237Sharti	SmiNode *row, *col, *rel;
289128237Sharti
290128237Sharti	assert (n->nodekind == SMI_NODEKIND_TABLE);
291128237Sharti
292128237Sharti	save_node(n);
293128237Sharti
294128237Sharti	pindent(level);
295128237Sharti	printf("(%u ", n->oid[level]);
296128237Sharti	print_name(n);
297128237Sharti	printf("\n");
298128237Sharti
299128237Sharti	row = smiGetFirstChildNode(n);
300128237Sharti	if (row->nodekind != SMI_NODEKIND_ROW)
301128237Sharti		errx(1, "%s: kind %u, not row", __func__, row->nodekind);
302128237Sharti
303128237Sharti	save_node(n);
304128237Sharti
305128237Sharti	pindent(level + 1);
306128237Sharti	printf("(%u ", row->oid[level + 1]);
307128237Sharti	print_name(row);
308128237Sharti	printf(" :");
309128237Sharti
310128237Sharti	/* index */
311128237Sharti	rel = smiGetRelatedNode(row);
312128237Sharti	switch (row->indexkind) {
313128237Sharti
314128237Sharti	  case SMI_INDEX_INDEX:
315128237Sharti		print_index(row);
316128237Sharti		break;
317128237Sharti
318128237Sharti	  case SMI_INDEX_AUGMENT:
319128237Sharti		if (rel == NULL)
320128237Sharti			errx(1, "%s: cannot find augemented table", row->name);
321128237Sharti		print_index(rel);
322128237Sharti		break;
323128237Sharti
324128237Sharti	  default:
325128237Sharti		errx(1, "%s: cannot handle index kind %u", row->name,
326128237Sharti		    row->indexkind);
327128237Sharti	}
328128237Sharti
329128237Sharti	printf(" op_%s", n->name);
330128237Sharti	printf("\n");
331128237Sharti
332128237Sharti	col = smiGetFirstChildNode(row);
333128237Sharti	while (col != NULL) {
334128237Sharti		print_col(col, level + 2);
335128237Sharti		col = smiGetNextChildNode(col);
336128237Sharti	}
337128237Sharti	pindent(level + 1);
338128237Sharti	printf(")\n");
339128237Sharti
340128237Sharti	pindent(level);
341128237Sharti	printf(")\n");
342128237Sharti}
343128237Sharti
344128237Shartistatic void
345128237Shartiprint_it(SmiNode *n, u_int level)
346128237Sharti{
347128237Sharti	switch (n->nodekind) {
348128237Sharti
349128237Sharti	  case SMI_NODEKIND_NODE:
350128237Sharti		print_node(n, level);
351128237Sharti		break;
352128237Sharti
353128237Sharti	  case SMI_NODEKIND_SCALAR:
354128237Sharti		print_scalar(n, level);
355128237Sharti		break;
356128237Sharti
357128237Sharti	  case SMI_NODEKIND_TABLE:
358128237Sharti		print_table(n, level);
359128237Sharti		break;
360128237Sharti
361128237Sharti	  case SMI_NODEKIND_COMPLIANCE:
362128237Sharti	  case SMI_NODEKIND_GROUP:
363128237Sharti		save_node(n);
364128237Sharti		break;
365128237Sharti
366128237Sharti	  case SMI_NODEKIND_NOTIFICATION:
367128237Sharti		print_notification(n, level);
368128237Sharti		break;
369128237Sharti
370128237Sharti	  default:
371128237Sharti		errx(1, "cannot handle %u nodes", n->nodekind);
372128237Sharti	}
373128237Sharti}
374128237Sharti
375128237Shartistatic void
376128237Shartiprint_node(SmiNode *n, u_int level)
377128237Sharti{
378128237Sharti	assert (n->nodekind == SMI_NODEKIND_NODE);
379128237Sharti
380128237Sharti	save_node(n);
381128237Sharti
382128237Sharti	pindent(level);
383128237Sharti	printf("(%u ", n->oid[level]);
384128237Sharti	print_name(n);
385128237Sharti	printf("\n");
386128237Sharti
387128237Sharti	n = smiGetFirstChildNode(n);
388128237Sharti	while (n != NULL) {
389128237Sharti		print_it(n, level + 1);
390128237Sharti		n = smiGetNextChildNode(n);
391128237Sharti	}
392128237Sharti	pindent(level);
393128237Sharti	printf(")\n");
394128237Sharti}
395128237Sharti
396159063Shartistatic void
397159063Shartisave_typdef(char *name)
398159063Sharti{
399159063Sharti	struct tdef *t;
400159063Sharti	t = malloc(sizeof(struct tdef));
401159063Sharti
402159063Sharti	if (t == NULL)
403159063Sharti		err(1, NULL);
404159063Sharti
405159063Sharti	memset(t, 0 , sizeof(struct tdef));
406159063Sharti	t->name = name;
407159063Sharti	SLIST_INSERT_HEAD(&tdefs, t, link);
408159063Sharti}
409159063Sharti
410159063Shartistatic void
411159063Shartitdefs_cleanup(void)
412159063Sharti{
413159063Sharti	struct tdef *t;
414159063Sharti
415159063Sharti	while ((t = SLIST_FIRST(&tdefs)) != NULL) {
416159063Sharti		SLIST_REMOVE_HEAD(&tdefs, link);
417159063Sharti		free(t);
418159063Sharti	}
419159063Sharti}
420159063Sharti
421159063Shartistatic void
422159063Shartiprint_enum_typedef(SmiType *t)
423159063Sharti{
424159063Sharti	SmiNamedNumber *nnum;
425159063Sharti
426159063Sharti	for (nnum = smiGetFirstNamedNumber(t); nnum != NULL;
427159063Sharti	    nnum = smiGetNextNamedNumber(nnum)) {
428159063Sharti		printf("\t%ld %s\n" , nnum->value.value.integer32, nnum->name);
429159063Sharti	}
430159063Sharti}
431159063Sharti
432159063Shartistatic void
433159063Shartiprint_stype(SmiNode *n)
434159063Sharti{
435159063Sharti	SmiType *type;
436159063Sharti	struct tdef *t = NULL;
437159063Sharti
438159063Sharti	type = smiGetNodeType(n);
439159063Sharti	assert(type != NULL);
440159063Sharti
441159063Sharti	if (type->basetype == SMI_BASETYPE_ENUM) {
442159063Sharti		if (do_typedef == 'e' && type->name != NULL) {
443159063Sharti			SLIST_FOREACH(t, &tdefs, link) {
444159063Sharti				if (strcmp(t->name, type->name) == 0)
445159063Sharti					return;
446159063Sharti			}
447159063Sharti			save_typdef(type->name);
448159063Sharti			printf("typedef %s ENUM (\n", type->name);
449159063Sharti		} else if (do_typedef == 'E' && type->name == NULL)
450159063Sharti			printf("typedef %sType ENUM (\n", n->name);
451159063Sharti		else
452159063Sharti			return;
453159063Sharti
454159063Sharti		print_enum_typedef(type);
455159063Sharti		printf(")\n\n");
456159063Sharti
457159063Sharti	} else if (type->basetype == SMI_BASETYPE_BITS) {
458159063Sharti		if (do_typedef == 'e' && type->name != NULL) {
459159063Sharti			SLIST_FOREACH(t, &tdefs, link) {
460159063Sharti				if (strcmp(t->name, type->name) == 0)
461159063Sharti					return;
462159063Sharti			}
463159063Sharti			save_typdef(type->name);
464159063Sharti			printf("typedef %s BITS (\n", type->name);
465159063Sharti		} else if (do_typedef == 'E' && type->name == NULL)
466159063Sharti			printf("typedef %sType BITS (\n", n->name);
467159063Sharti		else
468159063Sharti			return;
469159063Sharti
470159063Sharti		print_enum_typedef(type);
471159063Sharti		printf(")\n\n");
472159063Sharti	}
473159063Sharti}
474159063Sharti
475159063Shartistatic void
476159063Shartiprint_typdefs(SmiNode *n)
477159063Sharti{
478159063Sharti	SmiNode *p;
479159063Sharti
480159063Sharti	p = n;
481159063Sharti	n = smiGetFirstChildNode(n);
482159063Sharti	while (n != NULL) {
483159063Sharti		switch (n->nodekind) {
484159063Sharti		  case SMI_NODEKIND_SCALAR:
485159063Sharti		  case SMI_NODEKIND_COLUMN:
486159063Sharti			print_stype(n);
487159063Sharti			break;
488159063Sharti		  case SMI_NODEKIND_COMPLIANCE:
489159063Sharti	  	  case SMI_NODEKIND_GROUP:
490159063Sharti			save_node(n);
491159063Sharti			return;
492159063Sharti		  default:
493159063Sharti			break;
494159063Sharti		}
495159063Sharti		n = smiGetNextChildNode(n);
496159063Sharti	}
497159063Sharti
498159063Sharti	save_node(p);
499159063Sharti}
500159063Sharti
501128237Shartiint
502128237Shartimain(int argc, char *argv[])
503128237Sharti{
504128237Sharti	int opt;
505128237Sharti	int flags;
506128237Sharti	SmiModule **mods;
507128237Sharti	char *name;
508128237Sharti	SmiNode *n, *last;
509128237Sharti	u_int level;
510128237Sharti	long u;
511128237Sharti	char *end;
512128237Sharti
513128237Sharti	smiInit(NULL);
514128237Sharti
515159063Sharti	while ((opt = getopt(argc, argv, "c:Eeh")) != -1)
516128237Sharti		switch (opt) {
517128237Sharti
518128237Sharti		  case 'c':
519128237Sharti			errno = 0;
520128237Sharti			u = strtol(optarg, &end, 10);
521128237Sharti			if (errno != 0)
522128237Sharti				err(1, "argument to -c");
523128237Sharti			if (*end != '\0')
524128237Sharti				err(1, "%s: not a number", optarg);
525128237Sharti			if (u < 0 || u > 5)
526128237Sharti				err(1, "%s: out of range", optarg);
527128237Sharti			cut = (u_int)u;
528128237Sharti			break;
529128237Sharti
530159063Sharti		  case 'E':
531159063Sharti			do_typedef = 'E';
532159063Sharti			break;
533159063Sharti
534159063Sharti		  case 'e':
535159063Sharti			do_typedef = 'e';
536159063Sharti			break;
537159063Sharti
538128237Sharti		  case 'h':
539128237Sharti			fprintf(stderr, usgtxt);
540128237Sharti			exit(0);
541128237Sharti		}
542128237Sharti
543128237Sharti	argc -= optind;
544128237Sharti	argv += optind;
545128237Sharti
546128237Sharti	flags = smiGetFlags();
547128237Sharti	flags |= SMI_FLAG_ERRORS;
548128237Sharti	smiSetFlags(flags);
549128237Sharti
550128237Sharti	mods = malloc(sizeof(mods[0]) * argc);
551128237Sharti	if (mods == NULL)
552128237Sharti		err(1, NULL);
553128237Sharti
554128237Sharti	for (opt = 0; opt < argc; opt++) {
555128237Sharti		if ((name = smiLoadModule(argv[opt])) == NULL)
556128237Sharti			err(1, "%s: cannot load", argv[opt]);
557128237Sharti		mods[opt] = smiGetModule(name);
558128237Sharti	}
559128237Sharti	level = 0;
560128237Sharti	last = NULL;
561128237Sharti	for (opt = 0; opt < argc; opt++) {
562128237Sharti		n = smiGetFirstNode(mods[opt], SMI_NODEKIND_ANY);
563128237Sharti		for (;;) {
564159063Sharti			if (do_typedef == 0) {
565159063Sharti				level = open_node(n, level, &last);
566159063Sharti				print_it(n, level);
567159063Sharti				last = n;
568159063Sharti			} else
569159063Sharti				print_typdefs(n);
570128237Sharti
571128237Sharti			if (last_node == NULL ||
572128237Sharti			    (n = smiGetNextNode(last_node, SMI_NODEKIND_ANY))
573128237Sharti			    == NULL)
574128237Sharti				break;
575128237Sharti		}
576128237Sharti	}
577159063Sharti	if (last != NULL && do_typedef == 0)
578159063Sharti		level = close_node(last->oidlen - 1, level - 1);
579159063Sharti	else if (do_typedef != 0)
580159063Sharti		tdefs_cleanup();
581159063Sharti
582128237Sharti	return (0);
583128237Sharti}
584