[Midnightbsd-cvs] src: contrib/bsnmp: merge

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Nov 23 16:39:20 EST 2008


Log Message:
-----------
merge

Modified Files:
--------------
    src/contrib/bsnmp:
        FREEBSD-Xlist (r1.2 -> r1.3)
        NEWS (r1.2 -> r1.3)
    src/contrib/bsnmp/gensnmpdef:
        gensnmpdef.1 (r1.1.1.2 -> r1.2)
        gensnmpdef.c (r1.1.1.1 -> r1.2)
    src/contrib/bsnmp/gensnmptree:
        gensnmptree.1 (r1.2 -> r1.3)
        gensnmptree.c (r1.2 -> r1.3)
    src/contrib/bsnmp/lib:
        asn1.c (r1.2 -> r1.3)
        snmpclient.c (r1.2 -> r1.3)
    src/contrib/bsnmp/snmp_mibII:
        mibII.c (r1.2 -> r1.3)

-------------- next part --------------
Index: FREEBSD-Xlist
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/FREEBSD-Xlist,v
retrieving revision 1.2
retrieving revision 1.3
diff -L contrib/bsnmp/FREEBSD-Xlist -L contrib/bsnmp/FREEBSD-Xlist -u -r1.2 -r1.3
--- contrib/bsnmp/FREEBSD-Xlist
+++ contrib/bsnmp/FREEBSD-Xlist
@@ -1,4 +1,4 @@
-#$FreeBSD: src/contrib/bsnmp/FREEBSD-Xlist,v 1.3.2.1 2006/03/31 12:43:37 glebius Exp $
+#$FreeBSD: src/contrib/bsnmp/FREEBSD-Xlist,v 1.5 2006/03/13 09:30:26 harti Exp $
 */Makefile.in
 */acinclude.m4
 */aclocal.m4
Index: NEWS
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/NEWS,v
retrieving revision 1.2
retrieving revision 1.3
diff -L contrib/bsnmp/NEWS -L contrib/bsnmp/NEWS -u -r1.2 -r1.3
--- contrib/bsnmp/NEWS
+++ contrib/bsnmp/NEWS
@@ -1,3 +1,7 @@
+1.12a
+	Support for ENUM and BITS in gensnmp{tree,def}. Include directives
+	and typedefs.
+
 1.12
 	A couple of man page fixes from various submitters.
 
Index: gensnmpdef.c
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/gensnmpdef/gensnmpdef.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L contrib/bsnmp/gensnmpdef/gensnmpdef.c -L contrib/bsnmp/gensnmpdef/gensnmpdef.c -u -r1.1.1.1 -r1.2
--- contrib/bsnmp/gensnmpdef/gensnmpdef.c
+++ contrib/bsnmp/gensnmpdef/gensnmpdef.c
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2004
+ * Copyright (C) 2004-2006
  * 	Hartmut Brandt.
  * 	All rights reserved.
  * 
@@ -26,8 +26,10 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Begemot: bsnmp/gensnmpdef/gensnmpdef.c,v 1.3 2004/08/06 08:46:45 brandt Exp $
+ * $Begemot: gensnmpdef.c 383 2006-05-30 07:40:49Z brandt_h $
  */
+#include <sys/queue.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -38,9 +40,13 @@
 #include <smi.h>
 
 static const char usgtxt[] =
-"Usage: gensnmpdef [-h] [-c <cut>] MIB [MIB ...]\n"
+"Usage: gensnmpdef [-hEe] [-c <cut>] MIB [MIB ...]\n"
 "Options:\n"
 "  -c	specify the number of initial sub-oids to cut from the oids\n"
+"  -E	extract named enum types. Print a typedef for all enums defined\n"
+"	in syntax clauses of normal objects. Suppress normal output.\n"
+"  -e	extract unnamed enum types. Print a typedef for all enums defined\n"
+"	as textual conventions. Suppress normal output.\n"
 "  -h	print this help\n"
 "MIBs are searched according to the libsmi(3) search rules and can\n"
 "be specified either by path or module name\n";
@@ -48,6 +54,14 @@
 static SmiNode *last_node;
 static u_int cut = 3;
 
+struct tdef {
+	char *name;
+	SLIST_ENTRY(tdef) link;
+};
+
+static SLIST_HEAD(, tdef) tdefs = SLIST_HEAD_INITIALIZER(tdef);
+static int do_typedef = 0;
+
 static void print_node(SmiNode *n, u_int level);
 
 static void
@@ -135,7 +149,7 @@
 	[SMI_BASETYPE_FLOAT32] =	"FLOAT32",
 	[SMI_BASETYPE_FLOAT64] =	"FLOAT64",
 	[SMI_BASETYPE_FLOAT128] =	"FLOAT128",
-	[SMI_BASETYPE_ENUM] =	"INTEGER",
+	[SMI_BASETYPE_ENUM] =	"ENUM",
 	[SMI_BASETYPE_BITS] =	"BITS",
 };
 
@@ -152,6 +166,18 @@
 };
 
 static void
+print_enum(SmiType *t)
+{
+	SmiNamedNumber *nnum;
+
+	printf(" (");
+	for (nnum = smiGetFirstNamedNumber(t); nnum != NULL;
+	    nnum = smiGetNextNamedNumber(nnum))
+		printf(" %ld %s", nnum->value.value.integer32, nnum->name);
+	printf(" )");
+}
+
+static void
 print_type(SmiNode *n)
 {
 	SmiType *type;
@@ -168,6 +194,14 @@
 			}
 	}
 	printf("%s", type_names[type->basetype]);
+
+	if (type->basetype == SMI_BASETYPE_ENUM ||
+	    type->basetype == SMI_BASETYPE_BITS)
+		print_enum(type);
+
+	else if (type->basetype == SMI_BASETYPE_OCTETSTRING &&
+	    type->name != NULL)
+		printf(" | %s", type->name);
 }
 
 static void
@@ -359,6 +393,111 @@
 	printf(")\n");
 }
 
+static void
+save_typdef(char *name)
+{
+	struct tdef *t;
+	t = malloc(sizeof(struct tdef));
+
+	if (t == NULL)
+		err(1, NULL);
+
+	memset(t, 0 , sizeof(struct tdef));
+	t->name = name;
+	SLIST_INSERT_HEAD(&tdefs, t, link);
+}
+
+static void
+tdefs_cleanup(void)
+{
+	struct tdef *t;
+
+	while ((t = SLIST_FIRST(&tdefs)) != NULL) {
+		SLIST_REMOVE_HEAD(&tdefs, link);
+		free(t);
+	}
+}
+
+static void
+print_enum_typedef(SmiType *t)
+{
+	SmiNamedNumber *nnum;
+	
+	for (nnum = smiGetFirstNamedNumber(t); nnum != NULL;
+	    nnum = smiGetNextNamedNumber(nnum)) {
+		printf("\t%ld %s\n" , nnum->value.value.integer32, nnum->name);
+	}
+}
+
+static void
+print_stype(SmiNode *n)
+{
+	SmiType *type;
+	struct tdef *t = NULL;
+	
+	type = smiGetNodeType(n);
+	assert(type != NULL);
+	
+	if (type->basetype == SMI_BASETYPE_ENUM) {
+		if (do_typedef == 'e' && type->name != NULL) {
+			SLIST_FOREACH(t, &tdefs, link) {
+				if (strcmp(t->name, type->name) == 0)
+					return;
+			}
+			save_typdef(type->name);
+			printf("typedef %s ENUM (\n", type->name);
+		} else if (do_typedef == 'E' && type->name == NULL)
+			printf("typedef %sType ENUM (\n", n->name);
+		else
+			return;
+		
+		print_enum_typedef(type);
+		printf(")\n\n");
+
+	} else if (type->basetype == SMI_BASETYPE_BITS) {
+		if (do_typedef == 'e' && type->name != NULL) {
+			SLIST_FOREACH(t, &tdefs, link) {
+				if (strcmp(t->name, type->name) == 0)
+					return;
+			}
+			save_typdef(type->name);
+			printf("typedef %s BITS (\n", type->name);
+		} else if (do_typedef == 'E' && type->name == NULL)
+			printf("typedef %sType BITS (\n", n->name);
+		else
+			return;
+
+		print_enum_typedef(type);
+		printf(")\n\n");
+	}
+}
+
+static void
+print_typdefs(SmiNode *n)
+{
+	SmiNode *p;
+	
+	p = n;
+	n = smiGetFirstChildNode(n);
+	while (n != NULL) {
+		switch (n->nodekind) {
+		  case SMI_NODEKIND_SCALAR:
+		  case SMI_NODEKIND_COLUMN:
+			print_stype(n);
+			break;
+		  case SMI_NODEKIND_COMPLIANCE:
+	  	  case SMI_NODEKIND_GROUP:
+			save_node(n);
+			return;
+		  default:
+			break;
+		}
+		n = smiGetNextChildNode(n);
+	}
+
+	save_node(p);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -373,7 +512,7 @@
 
 	smiInit(NULL);
 
-	while ((opt = getopt(argc, argv, "c:h")) != -1)
+	while ((opt = getopt(argc, argv, "c:Eeh")) != -1)
 		switch (opt) {
 
 		  case 'c':
@@ -388,6 +527,14 @@
 			cut = (u_int)u;
 			break;
 
+		  case 'E':
+			do_typedef = 'E';
+			break;
+
+		  case 'e':
+			do_typedef = 'e';
+			break;
+
 		  case 'h':
 			fprintf(stderr, usgtxt);
 			exit(0);
@@ -414,9 +561,12 @@
 	for (opt = 0; opt < argc; opt++) {
 		n = smiGetFirstNode(mods[opt], SMI_NODEKIND_ANY);
 		for (;;) {
-			level = open_node(n, level, &last);
-			print_it(n, level);
-			last = n;
+			if (do_typedef == 0) {
+				level = open_node(n, level, &last);
+				print_it(n, level);
+				last = n;
+			} else
+				print_typdefs(n);
 
 			if (last_node == NULL ||
 			    (n = smiGetNextNode(last_node, SMI_NODEKIND_ANY))
@@ -424,6 +574,10 @@
 				break;
 		}
 	}
-	level = close_node(last->oidlen - 1, level - 1);
+	if (last != NULL && do_typedef == 0)
+		level = close_node(last->oidlen - 1, level - 1);
+	else if (do_typedef != 0)
+		tdefs_cleanup();
+
 	return (0);
 }
Index: gensnmpdef.1
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/gensnmpdef/gensnmpdef.1,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L contrib/bsnmp/gensnmpdef/gensnmpdef.1 -L contrib/bsnmp/gensnmpdef/gensnmpdef.1 -u -r1.1.1.2 -r1.2
--- contrib/bsnmp/gensnmpdef/gensnmpdef.1
+++ contrib/bsnmp/gensnmpdef/gensnmpdef.1
@@ -1,5 +1,5 @@
 .\"
-.\" Copyright (C) 2004-2005
+.\" Copyright (C) 2004-2006
 .\"	Hartmut Brandt.
 .\"	All rights reserved.
 .\"
@@ -26,9 +26,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $Begemot: bsnmp/gensnmpdef/gensnmpdef.1,v 1.5 2005/10/04 08:46:46 brandt_h Exp $
+.\" $Begemot: gensnmpdef.1 383 2006-05-30 07:40:49Z brandt_h $
 .\"
-.Dd June 14, 2005
+.Dd May 28, 2006
 .Dt GENSNMPDEF 1
 .Os
 .Sh NAME
@@ -36,7 +36,7 @@
 .Nd "generate a MIB description file from MIBs"
 .Sh SYNOPSIS
 .Nm
-.Op Fl h
+.Op Fl hEe
 .Op Fl c Ar cut
 .Ar name Op Ar ...
 .Sh DESCRIPTION
@@ -48,13 +48,28 @@
 for feeding it into
 .Xr gensnmptree 1 .
 .Pp
-The
-.Fl c
-option specifies the number of initial sub-oids that should be omitted
-from the tree.
+The following options are available:
+.Bl -tag -width indent
+.It Fl c Ar cut
+Specify the number of initial sub-oids that should be omitted
+from the tree in the output.
 .Xr gensnmptree 1
 automatically adds 1.3.6 in front of all OIDs so the default value
 of 3 is just correct in most cases.
+.It Fl E
+Generate typedefs for named enumerations.
+These are enumerations defined via the TEXTUAL-CONVENTION macro.
+The normal tree output is suppressed.
+.It Fl e
+Generate typedefs for unnamed enumerations.
+These are enumerations defined in the SYNTAX clause of an OBJECT-TYPE macro.
+The name of the enumeration is formed by appending the string
+.Ql Type
+to the name of the object.
+The normal tree output is suppressed.
+.It Fl h
+Print a short help text and exit.
+.El
 .Pp
 .Nm
 does no attempt on sorting the OID tree so in case of complex and
Index: gensnmptree.c
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/gensnmptree/gensnmptree.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L contrib/bsnmp/gensnmptree/gensnmptree.c -L contrib/bsnmp/gensnmptree/gensnmptree.c -u -r1.2 -r1.3
--- contrib/bsnmp/gensnmptree/gensnmptree.c
+++ contrib/bsnmp/gensnmptree/gensnmptree.c
@@ -3,7 +3,7 @@
  *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
  *	All rights reserved.
  *
- * Copyright (c) 2004
+ * Copyright (c) 2004-2006
  *	Hartmut Brandt.
  *	All rights reserved.
  *
@@ -30,21 +30,35 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Begemot: bsnmp/gensnmptree/gensnmptree.c,v 1.44 2006/02/14 09:04:17 brandt_h Exp $
+ * $Begemot: gensnmptree.c 383 2006-05-30 07:40:49Z brandt_h $
  *
  * Generate OID table from table description.
  *
  * Syntax is:
  * ---------
- * file := tree | tree file
+ * file := top | top file
+ *
+ * top := tree | typedef | include
  *
  * tree := head elements ')'
  *
  * entry := head ':' index STRING elements ')'
  *
- * leaf := head TYPE STRING ACCESS ')'
+ * leaf := head type STRING ACCESS ')'
+ *
+ * column := head type ACCESS ')'
+ *
+ * type := BASETYPE | BASETYPE '|' subtype | enum | bits
+ *
+ * subtype := STRING
  *
- * column := head TYPE ACCESS ')'
+ * enum := ENUM '(' value ')'
+ *
+ * bits := BITS '(' value ')'
+ *
+ * value := optminus INT STRING | optminus INT STRING value
+ *
+ * optminus := '-' | EMPTY
  *
  * head := '(' INT STRING
  *
@@ -52,8 +66,13 @@
  *
  * element := tree | leaf | column
  *
- * index := TYPE | index TYPE
+ * index := type | index type
+ *
+ * typedef := 'typedef' STRING type
  *
+ * include := 'include' filespec
+ *
+ * filespec := '"' STRING '"' | '<' STRING '>'
  */
 #include <sys/types.h>
 #include <sys/param.h>
@@ -82,20 +101,27 @@
 
 u_int tree_size;
 static const char *file_prefix = "";
-static FILE *fp;
 
 /* if true generate local include paths */
 static int localincs = 0;
 
+/* if true print tokens */
+static int debug;
+
 static const char usgtxt[] = "\
-Generate SNMP tables. Copyright (c) 2001-2002 Fraunhofer Institute for\n\
-Open Communication Systems (FhG Fokus). All rights reserved.\n\
-usage: gensnmptree [-hel] [-p prefix] [name]...\n\
+Generate SNMP tables.\n\
+usage: gensnmptree [-dEehlt] [-I directory] [-i infile] [-p prefix]\n\
+	    [name]...\n\
 options:\n\
+  -d		debug mode\n\
+  -E		extract the named enums and bits only\n\
+  -e		extract the named oids or enums\n\
   -h		print this info\n\
-  -e		extrace the named oids\n\
+  -I directory	add directory to include path\n\
+  -i ifile	read from the named file instead of stdin\n\
   -l		generate local include directives\n\
   -p prefix	prepend prefix to file and variable names\n\
+  -t		generated a .def file\n\
 ";
 
 /*
@@ -153,6 +179,29 @@
 
 static LIST_HEAD(, func) funcs = LIST_HEAD_INITIALIZER(funcs);
 
+struct enums {
+	const char	*name;
+	long		value;
+	TAILQ_ENTRY(enums) link;
+};
+
+struct type {
+	const char	*name;
+	const char	*from_fname;
+	u_int		from_lno;
+	u_int		syntax;
+	int		is_enum;
+	int		is_bits;
+	TAILQ_HEAD(, enums) enums;
+	LIST_ENTRY(type) link;
+};
+
+static LIST_HEAD(, type) types = LIST_HEAD_INITIALIZER(types);
+
+static void report(const char *, ...) __dead2 __printflike(1, 2);
+static void report_node(const struct node *, const char *, ...)
+    __dead2 __printflike(2, 3);
+
 /************************************************************
  *
  * Allocate memory and panic just in the case...
@@ -168,6 +217,164 @@
 	return (ptr);
 }
 
+static char *
+savestr(const char *s)
+{
+
+	if (s == NULL)
+		return (NULL);
+	return (strcpy(xalloc(strlen(s) + 1), s));
+}
+
+/************************************************************
+ *
+ * Input stack
+ */
+struct input {
+	FILE		*fp;
+	u_int		lno;
+	char		*fname;
+	char		*path;
+	LIST_ENTRY(input) link;
+};
+static LIST_HEAD(, input) inputs = LIST_HEAD_INITIALIZER(inputs);
+static struct input *input = NULL;
+
+#define MAX_PATHS	100
+static u_int npaths = 2;
+static u_int stdpaths = 2;
+static const char *paths[MAX_PATHS + 1] = {
+	"/usr/share/snmp/defs",
+	"/usr/local/share/snmp/defs",
+	NULL
+};
+
+static int pbchar = -1;
+
+static void
+path_new(const char *path)
+{
+	if (npaths >= MAX_PATHS)
+		report("too many -I directives");
+	memmove(&paths[npaths - stdpaths + 1], &paths[npaths - stdpaths],
+	    sizeof(path[0]) * stdpaths);
+	paths[npaths - stdpaths] = savestr(path);
+	npaths++;
+}
+
+static void
+input_new(FILE *fp, const char *path, const char *fname)
+{
+	struct input *ip;
+
+	ip = xalloc(sizeof(*ip));
+	ip->fp = fp;
+	ip->lno = 1;
+	ip->fname = savestr(fname);
+	ip->path = savestr(path);
+	LIST_INSERT_HEAD(&inputs, ip, link);
+
+	input = ip;
+}
+
+static void
+input_close(void)
+{
+
+	if (input == NULL)
+		return;
+	fclose(input->fp);
+	free(input->fname);
+	free(input->path);
+	LIST_REMOVE(input, link);
+	free(input);
+
+	input = LIST_FIRST(&inputs);
+}
+
+static FILE *
+tryopen(const char *path, const char *fname)
+{
+	char *fn;
+	FILE *fp;
+
+	if (path == NULL)
+		fn = savestr(fname);
+	else {
+		fn = xalloc(strlen(path) + strlen(fname) + 2);
+		sprintf(fn, "%s/%s", path, fname);
+	}
+	fp = fopen(fn, "r");
+	free(fn);
+	return (fp);
+}
+
+static void
+input_fopen(const char *fname, int loc)
+{
+	FILE *fp;
+	char *path;
+	u_int p;
+
+	if (fname[0] == '/') {
+		if ((fp = tryopen(NULL, fname)) != NULL) {
+			input_new(fp, NULL, fname);
+			return;
+		}
+
+	} else {
+		if (loc) {
+			if (input == NULL)
+				path = NULL;
+			else
+				path = input->path;
+
+			if ((fp = tryopen(path, fname)) != NULL) {
+				input_new(fp, NULL, fname);
+				return;
+			}
+		}
+
+		for (p = 0; paths[p] != NULL; p++)
+			if ((fp = tryopen(paths[p], fname)) != NULL) {
+				input_new(fp, paths[p], fname);
+				return;
+			}
+	}
+	report("cannot open '%s'", fname);
+}
+
+static int
+tgetc(void)
+{
+	int c;
+
+	if (pbchar != -1) {
+		c = pbchar;
+		pbchar = -1;
+		return (c);
+	}
+
+	for (;;) {
+		if (input == NULL)
+			return (EOF);
+
+		if ((c = getc(input->fp)) != EOF)
+			return (c);
+
+		input_close();
+	}
+}
+
+static void
+tungetc(int c)
+{
+
+	if (pbchar != -1)
+		abort();
+	pbchar = c;
+}
+
 /************************************************************
  *
  * Parsing input
@@ -178,6 +385,12 @@
 	TOK_STR,	/* string */
 	TOK_ACCESS,	/* access operator */
 	TOK_TYPE,	/* type operator */
+	TOK_ENUM,	/* enum token (kind of a type) */
+	TOK_TYPEDEF,	/* typedef directive */
+	TOK_DEFTYPE,	/* defined type */
+	TOK_INCLUDE,	/* include directive */
+	TOK_FILENAME,	/* filename ("foo.bar" or <foo.bar>) */
+	TOK_BITS,	/* bits token (kind of a type) */
 };
 
 static const struct {
@@ -198,6 +411,10 @@
 	{ "COUNTER", TOK_TYPE, SNMP_SYNTAX_COUNTER },
 	{ "GAUGE", TOK_TYPE, SNMP_SYNTAX_GAUGE },
 	{ "COUNTER64", TOK_TYPE, SNMP_SYNTAX_COUNTER64 },
+	{ "ENUM", TOK_ENUM, SNMP_SYNTAX_INTEGER },
+	{ "BITS", TOK_BITS, SNMP_SYNTAX_OCTETSTRING },
+	{ "typedef", TOK_TYPEDEF, 0 },
+	{ "include", TOK_INCLUDE, 0 },
 	{ NULL, 0, 0 }
 };
 
@@ -205,12 +422,8 @@
 #define	MAXSTR	1000
 char	str[MAXSTR];
 u_long	val;		/* integer values */
-u_int 	lno = 1;	/* current line number */
 int	all_cond;	/* all conditions are true */
-
-static void report(const char *, ...) __dead2 __printflike(1, 2);
-static void report_node(const struct node *, const char *, ...)
-    __dead2 __printflike(2, 3);
+int	saved_token = -1;
 
 /*
  * Report an error and exit.
@@ -222,11 +435,11 @@
 	int c;
 
 	va_start(ap, fmt);
-	fprintf(stderr, "line %u: ", lno);
+	fprintf(stderr, "line %u: ", input->lno);
 	vfprintf(stderr, fmt, ap);
 	fprintf(stderr, "\n");
 	fprintf(stderr, "context: \"");
-	while ((c = getchar()) != EOF && c != '\n')
+	while ((c = tgetc()) != EOF && c != '\n')
 		fprintf(stderr, "%c", c);
 	fprintf(stderr, "\n");
 	va_end(ap);
@@ -251,24 +464,31 @@
 static char *
 savetok(void)
 {
-	return (strcpy(xalloc(strlen(str)+1), str));
+	return (savestr(str));
 }
 
 /*
  * Get the next token from input.
  */
 static int
-gettoken(void)
+gettoken_internal(void)
 {
 	int c;
+	struct type *t;
+
+	if (saved_token != -1) {
+		c = saved_token;
+		saved_token = -1;
+		return (c);
+	}
 
   again:
 	/*
 	 * Skip any whitespace before the next token
 	 */
-	while ((c = getchar()) != EOF) {
+	while ((c = tgetc()) != EOF) {
 		if (c == '\n')
-			lno++;
+			input->lno++;
 		if (!isspace(c))
 			break;
 	}
@@ -281,9 +501,9 @@
 	 * Skip comments
 	 */
 	if (c == '#') {
-		while ((c = getchar()) != EOF) {
+		while ((c = tgetc()) != EOF) {
 			if (c == '\n') {
-				lno++;
+				input->lno++;
 				goto again;
 			}
 		}
@@ -293,15 +513,51 @@
 	/*
 	 * Single character tokens
 	 */
-	if (c == ')' || c == '(' || c == ':')
+	if (strchr("():|-", c) != NULL)
 		return (c);
 
+	if (c == '"' || c == '<') {
+		int end = c;
+		size_t n = 0;
+
+		val = 1;
+		if (c == '<') {
+			val = 0;
+			end = '>';
+		}
+
+		while ((c = tgetc()) != EOF) {
+			if (c == end)
+				break;
+			if (n == sizeof(str) - 1) {
+				str[n++] = '\0';
+				report("filename too long '%s...'", str);
+			}
+			str[n++] = c;
+		}
+		str[n++] = '\0';
+		return (TOK_FILENAME);
+	}
+
 	/*
 	 * Sort out numbers
 	 */
 	if (isdigit(c)) {
-		ungetc(c, stdin);
-		scanf("%lu", &val);
+		size_t n = 0;
+		str[n++] = c;
+		while ((c = tgetc()) != EOF) {
+			if (!isdigit(c)) {
+				tungetc(c);
+				break;
+			}
+			if (n == sizeof(str) - 1) {
+				str[n++] = '\0';
+				report("number too long '%s...'", str);
+			}
+			str[n++] = c;
+		}
+		str[n++] = '\0';
+		sscanf(str, "%lu", &val);
 		return (TOK_NUM);
 	}
 
@@ -311,9 +567,9 @@
 	if (isalpha(c) || c == '_') {
 		size_t n = 0;
 		str[n++] = c;
-		while ((c = getchar()) != EOF) {
-			if (!isalnum(c) && c != '_') {
-				ungetc(c, stdin);
+		while ((c = tgetc()) != EOF) {
+			if (!isalnum(c) && c != '_' && c != '-') {
+				tungetc(c);
 				break;
 			}
 			if (n == sizeof(str) - 1) {
@@ -333,12 +589,181 @@
 				return (keywords[c].tok);
 			}
 
+		LIST_FOREACH(t, &types, link) {
+			if (strcmp(t->name, str) == 0) {
+				val = t->syntax;
+				return (TOK_DEFTYPE);
+			}
+		}
 		return (TOK_STR);
 	}
 	if (isprint(c))
-		errx(1, "%u: unexpected character '%c'", lno, c);
+		errx(1, "%u: unexpected character '%c'", input->lno, c);
 	else
-		errx(1, "%u: unexpected character 0x%02x", lno, (u_int)c);
+		errx(1, "%u: unexpected character 0x%02x", input->lno,
+		    (u_int)c);
+}
+static int
+gettoken(void)
+{
+	int tok = gettoken_internal();
+
+	if (debug) {
+		switch (tok) {
+
+		  case TOK_EOF:
+			fprintf(stderr, "EOF ");
+			break;
+
+		  case TOK_NUM:
+			fprintf(stderr, "NUM(%lu) ", val);
+			break;
+
+		  case TOK_STR:
+			fprintf(stderr, "STR(%s) ", str);
+			break;
+
+		  case TOK_ACCESS:
+			fprintf(stderr, "ACCESS(%lu) ", val);
+			break;
+
+		  case TOK_TYPE:
+			fprintf(stderr, "TYPE(%lu) ", val);
+			break;
+
+		  case TOK_ENUM:
+			fprintf(stderr, "ENUM ");
+			break;
+
+		  case TOK_BITS:
+			fprintf(stderr, "BITS ");
+			break;
+
+		  case TOK_TYPEDEF:
+			fprintf(stderr, "TYPEDEF ");
+			break;
+
+		  case TOK_DEFTYPE:
+			fprintf(stderr, "DEFTYPE(%s,%lu) ", str, val);
+			break;
+
+		  case TOK_INCLUDE:
+			fprintf(stderr, "INCLUDE ");
+			break;
+
+		  case TOK_FILENAME:
+			fprintf(stderr, "FILENAME ");
+			break;
+
+		  default:
+			if (tok < TOK_EOF) {
+				if (isprint(tok))
+					fprintf(stderr, "'%c' ", tok);
+				else if (tok == '\n')
+					fprintf(stderr, "\n");
+				else
+					fprintf(stderr, "%02x ", tok);
+			} else
+				abort();
+			break;
+		}
+	}
+	return (tok);
+}
+
+/**
+ * Pushback a token
+ */
+static void
+pushback(enum tok tok)
+{
+
+	if (saved_token != -1)
+		abort();
+	saved_token = tok;
+}
+
+/*
+ * Create a new type
+ */
+static struct type *
+make_type(const char *s)
+{
+	struct type *t;
+
+	t = xalloc(sizeof(*t));
+	t->name = savestr(s);
+	t->is_enum = 0;
+	t->syntax = SNMP_SYNTAX_NULL;
+	t->from_fname = savestr(input->fname);
+	t->from_lno = input->lno;
+	TAILQ_INIT(&t->enums);
+	LIST_INSERT_HEAD(&types, t, link);
+
+	return (t);
+}
+
+/*
+ * Parse a type. We've seen the ENUM or type keyword already. Leave next
+ * token.
+ */
+static u_int
+parse_type(enum tok *tok, struct type *t, const char *vname)
+{
+	u_int syntax;
+	struct enums *e;
+
+	syntax = val;
+
+	if (*tok == TOK_ENUM || *tok == TOK_BITS) {
+		if (t == NULL && vname != NULL) {
+			t = make_type(vname);
+			t->is_enum = (*tok == TOK_ENUM);
+			t->is_bits = (*tok == TOK_BITS);
+			t->syntax = syntax;
+		}
+		if (gettoken() != '(')
+			report("'(' expected after ENUM");
+
+		if ((*tok = gettoken()) == TOK_EOF)
+			report("unexpected EOF in ENUM");
+		do {
+			e = NULL;
+			if (t != NULL) {
+				e = xalloc(sizeof(*e));
+			}
+			if (*tok == '-') {
+				if ((*tok = gettoken()) == TOK_EOF)
+					report("unexpected EOF in ENUM");
+				e->value = -(long)val;
+			} else
+				e->value = val;
+			
+			if (*tok != TOK_NUM)
+				report("need value for ENUM/BITS");
+			if (gettoken() != TOK_STR)
+				report("need string in ENUM/BITS");
+			if (e != NULL) {
+				e->name = savetok();
+				TAILQ_INSERT_TAIL(&t->enums, e, link);
+			}
+			if ((*tok = gettoken()) == TOK_EOF)
+				report("unexpected EOF in ENUM/BITS");
+		} while (*tok != ')');
+		*tok = gettoken();
+
+	} else if (*tok == TOK_DEFTYPE) {
+		*tok = gettoken();
+
+	} else {
+		if ((*tok = gettoken()) == '|') {
+			if (gettoken() != TOK_STR)
+				report("subtype expected after '|'");
+			*tok = gettoken();
+		}
+	}
+
+	return (syntax);
 }
 
 /*
@@ -352,7 +777,7 @@
 	u_int index_count;
 
 	node = xalloc(sizeof(struct node));
-	node->lno = lno;
+	node->lno = input->lno;
 	node->flags = 0;
 
 	if (tok != '(')
@@ -366,11 +791,12 @@
 		report("node name expected after '(' ID");
 	node->name = savetok();
 
-	if ((tok = gettoken()) == TOK_TYPE) {
+	if ((tok = gettoken()) == TOK_TYPE || tok == TOK_DEFTYPE ||
+	    tok == TOK_ENUM || tok == TOK_BITS) {
 		/* LEAF or COLUM */
-		u_int syntax = val;
+		u_int syntax = parse_type(&tok, NULL, node->name);
 
-		if ((tok = gettoken()) == TOK_STR) {
+		if (tok == TOK_STR) {
 			/* LEAF */
 			node->type = NODE_LEAF;
 			node->u.leaf.func = savetok();
@@ -396,16 +822,18 @@
 
 		index_count = 0;
 		node->u.entry.index = 0;
-		while ((tok = gettoken()) == TOK_TYPE) {
+		tok = gettoken();
+		while (tok == TOK_TYPE || tok == TOK_DEFTYPE ||
+		    tok == TOK_ENUM || tok == TOK_BITS) {
+			u_int syntax = parse_type(&tok, NULL, node->name);
 			if (index_count++ == SNMP_INDEXES_MAX)
 				report("too many table indexes");
 			node->u.entry.index |=
-			    val << (SNMP_INDEX_SHIFT * index_count);
+			    syntax << (SNMP_INDEX_SHIFT * index_count);
 		}
 		node->u.entry.index |= index_count;
 		if (index_count == 0)
 			report("need at least one index");
-
 		if (tok != TOK_STR)
 			report("function name expected");
 
@@ -434,10 +862,49 @@
 }
 
 /*
+ * Parse a top level element. Return the tree if it was a tree, NULL
+ * otherwise.
+ */
+static struct node *
+parse_top(enum tok tok)
+{
+	struct type *t;
+
+	if (tok == '(')
+		return (parse(tok));
+
+	if (tok == TOK_TYPEDEF) {
+		if (gettoken() != TOK_STR)
+			report("type name expected after typedef");
+
+		t = make_type(str);
+
+		tok = gettoken();
+		t->is_enum = (tok == TOK_ENUM);
+		t->is_bits = (tok == TOK_BITS);
+		t->syntax = parse_type(&tok, t, NULL);
+		pushback(tok);
+
+		return (NULL);
+	}
+
+	if (tok == TOK_INCLUDE) {
+		if (gettoken() != TOK_FILENAME)
+			report("filename expected in include directive");
+
+		input_fopen(str, val);
+		return (NULL);
+	}
+
+	report("'(' or 'typedef' expected");
+}
+
+/*
  * Generate the C-code table part for one node.
  */
 static void
-gen_node(struct node *np, struct asn_oid *oid, u_int idx, const char *func)
+gen_node(FILE *fp, struct node *np, struct asn_oid *oid, u_int idx,
+    const char *func)
 {
 	u_int n;
 	struct node *sub;
@@ -449,13 +916,14 @@
 
 	if (np->type == NODE_TREE) {
 		TAILQ_FOREACH(sub, &np->u.tree.subs, link)
-			gen_node(sub, oid, 0, NULL);
+			gen_node(fp, sub, oid, 0, NULL);
 		oid->len--;
 		return;
 	}
 	if (np->type == NODE_ENTRY) {
 		TAILQ_FOREACH(sub, &np->u.entry.subs, link)
-			gen_node(sub, oid, np->u.entry.index, np->u.entry.func);
+			gen_node(fp, sub, oid, np->u.entry.index,
+			    np->u.entry.func);
 		oid->len--;
 		return;
 	}
@@ -540,7 +1008,7 @@
  * Generate the header file with the function declarations.
  */
 static void
-gen_header(struct node *np, u_int oidlen, const char *func)
+gen_header(FILE *fp, struct node *np, u_int oidlen, const char *func)
 {
 	char f[MAXSTR + 4];
 	struct node *sub;
@@ -549,12 +1017,12 @@
 	oidlen++;
 	if (np->type == NODE_TREE) {
 		TAILQ_FOREACH(sub, &np->u.tree.subs, link)
-			gen_header(sub, oidlen, NULL);
+			gen_header(fp, sub, oidlen, NULL);
 		return;
 	}
 	if (np->type == NODE_ENTRY) {
 		TAILQ_FOREACH(sub, &np->u.entry.subs, link)
-			gen_header(sub, oidlen, np->u.entry.func);
+			gen_header(fp, sub, oidlen, np->u.entry.func);
 		return;
 	}
 
@@ -575,7 +1043,7 @@
 
 	if (ptr == NULL) {
 		ptr = xalloc(sizeof(*ptr));
-		ptr->name = strcpy(xalloc(strlen(f)+1), f);
+		ptr->name = savestr(f);
 		LIST_INSERT_HEAD(&funcs, ptr, link);
 
 		fprintf(fp, "int	%s(struct snmp_context *, "
@@ -590,7 +1058,7 @@
  * Generate the OID table.
  */
 static void
-gen_table(struct node *node)
+gen_table(FILE *fp, struct node *node)
 {
 	struct asn_oid oid;
 
@@ -615,7 +1083,7 @@
 
 	oid.len = PREFIX_LEN;
 	memcpy(oid.subs, prefix, sizeof(prefix));
-	gen_node(node, &oid, 0, NULL);
+	gen_node(fp, node, &oid, 0, NULL);
 
 	fprintf(fp, "};\n\n");
 }
@@ -681,12 +1149,11 @@
 		printf("%s%s)\n", (np->flags & FL_GET) ? " GET" : "",
 		    (np->flags & FL_SET) ? " SET" : "");
 		break;
-
 	}
 }
 
 static int
-extract(const struct node *np, struct asn_oid *oid, const char *obj,
+extract(FILE *fp, const struct node *np, struct asn_oid *oid, const char *obj,
     const struct asn_oid *idx, const char *iname)
 {
 	struct node *sub;
@@ -715,11 +1182,11 @@
 
 	if (np->type == NODE_TREE) {
 		TAILQ_FOREACH(sub, &np->u.tree.subs, link)
-			if (!extract(sub, oid, obj, idx, iname))
+			if (!extract(fp, sub, oid, obj, idx, iname))
 				return (0);
 	} else if (np->type == NODE_ENTRY) {
 		TAILQ_FOREACH(sub, &np->u.entry.subs, link)
-			if (!extract(sub, oid, obj, idx, iname))
+			if (!extract(fp, sub, oid, obj, idx, iname))
 				return (0);
 	}
 	oid->len--;
@@ -727,7 +1194,7 @@
 }
 
 static int
-gen_extract(const struct node *root, char *object)
+gen_extract(FILE *fp, const struct node *root, char *object)
 {
 	struct asn_oid oid;
 	struct asn_oid idx;
@@ -773,7 +1240,7 @@
 
 	oid.len = PREFIX_LEN;
 	memcpy(oid.subs, prefix, sizeof(prefix));
-	ret = extract(root, &oid, object, &idx, iname);
+	ret = extract(fp, root, &oid, object, &idx, iname);
 	if (iname != NULL)
 		free(iname);
 
@@ -879,18 +1346,93 @@
 }
 
 static void
-merge(struct node *root, struct node *t)
+merge(struct node **root, struct node *t)
 {
 
+	if (*root == NULL) {
+		*root = t;
+		return;
+	}
+	if (t == NULL)
+		return;
+
 	/* both must be trees */
-	if (root->type != NODE_TREE)
+	if ((*root)->type != NODE_TREE)
 		errx(1, "root is not a tree");
 	if (t->type != NODE_TREE)
 		errx(1, "can merge only with tree");
-	if (root->id != t->id)
+	if ((*root)->id != t->id)
 		errx(1, "trees to merge must have same id");
 
-	merge_subs(&root->u.tree.subs, &t->u.tree.subs);
+	merge_subs(&(*root)->u.tree.subs, &t->u.tree.subs);
+}
+
+static void
+unminus(FILE *fp, const char *s)
+{
+
+	while (*s != '\0') {
+		if (*s == '-')
+			fprintf(fp, "_");
+		else
+			fprintf(fp, "%c", *s);
+		s++;
+	}
+}
+
+static void
+gen_enum(FILE *fp, const struct type *t)
+{
+	const struct enums *e;
+	long min = LONG_MAX;
+
+	fprintf(fp, "\n");
+	fprintf(fp, "#ifndef %s_defined__\n", t->name);
+	fprintf(fp, "#define %s_defined__\n", t->name);
+	fprintf(fp, "/*\n");
+	fprintf(fp, " * From %s:%u\n", t->from_fname, t->from_lno);
+	fprintf(fp, " */\n");
+	fprintf(fp, "enum %s {\n", t->name);
+	TAILQ_FOREACH(e, &t->enums, link) {
+		fprintf(fp, "\t%s_", t->name);
+		unminus(fp, e->name);
+		fprintf(fp, " = %ld,\n", e->value);
+		if (e->value < min)
+			min = e->value;
+	}
+	fprintf(fp, "};\n");
+	fprintf(fp, "#define	STROFF_%s %ld\n", t->name, min);
+	fprintf(fp, "#define	STRING_%s \\\n", t->name);
+	TAILQ_FOREACH(e, &t->enums, link) {
+		fprintf(fp, "\t[%ld] \"%s_", e->value - min, t->name);
+		unminus(fp, e->name);
+		fprintf(fp, "\",\\\n");
+	}
+	fprintf(fp, "\n");
+	fprintf(fp, "#endif /* %s_defined__ */\n", t->name);
+}
+
+static void
+gen_enums(FILE *fp)
+{
+	const struct type *t;
+
+	LIST_FOREACH(t, &types, link)
+		if (t->is_enum || t->is_bits)
+			gen_enum(fp, t);
+}
+
+static int
+extract_enum(FILE *fp, const char *name)
+{
+	const struct type *t;
+
+	LIST_FOREACH(t, &types, link)
+		if ((t->is_enum || t->is_bits) && strcmp(t->name, name) == 0) {
+			gen_enum(fp, t);
+			return (0);
+		}
+	return (-1);
 }
 
 int
@@ -898,22 +1440,41 @@
 {
 	int do_extract = 0;
 	int do_tree = 0;
+	int do_enums = 0;
 	int opt;
 	struct node *root;
 	char fname[MAXPATHLEN + 1];
 	int tok;
+	FILE *fp;
+	char *infile = NULL;
 
-	while ((opt = getopt(argc, argv, "help:t")) != EOF)
+	while ((opt = getopt(argc, argv, "dEehI:i:lp:t")) != EOF)
 		switch (opt) {
 
+		  case 'd':
+			debug = 1;
+			break;
+
 		  case 'h':
 			fprintf(stderr, "%s", usgtxt);
 			exit(0);
 
+		  case 'E':
+			do_enums = 1;
+			break;
+
 		  case 'e':
 			do_extract = 1;
 			break;
 
+		  case 'I':
+			path_new(optarg);
+			break;
+
+		  case 'i':
+			infile = optarg;
+			break;
+
 		  case 'l':
 			localincs = 1;
 			break;
@@ -930,27 +1491,41 @@
 			break;
 		}
 
-	if (do_extract && do_tree)
-		errx(1, "conflicting options -e and -t");
-	if (!do_extract && argc != optind)
+	if (do_extract + do_tree + do_enums > 1)
+		errx(1, "conflicting options -e/-t/-E");
+	if (!do_extract && !do_enums && argc != optind)
 		errx(1, "no arguments allowed");
-	if (do_extract && argc == optind)
+	if ((do_extract || do_enums) && argc == optind)
 		errx(1, "no objects specified");
 
-	root = parse(gettoken());
+	if (infile == NULL) {
+		input_new(stdin, NULL, "<stdin>");
+	} else {
+		if ((fp = fopen(infile, "r")) == NULL)
+			err(1, "%s", infile);
+		input_new(fp, NULL, infile);
+	}
+
+	root = parse_top(gettoken());
 	while ((tok = gettoken()) != TOK_EOF)
-		merge(root, parse(tok));
+		merge(&root, parse_top(tok));
 
 	check_tree(root);
 
 	if (do_extract) {
-		fp = stdout;
 		while (optind < argc) {
-			if (gen_extract(root, argv[optind]))
+			if (gen_extract(stdout, root, argv[optind]))
 				errx(1, "object not found: %s", argv[optind]);
 			optind++;
 		}
-
+		return (0);
+	}
+	if (do_enums) {
+		while (optind < argc) {
+			if (extract_enum(stdout, argv[optind]))
+				errx(1, "enum not found: %s", argv[optind]);
+			optind++;
+		}
 		return (0);
 	}
 	if (do_tree) {
@@ -960,7 +1535,11 @@
 	sprintf(fname, "%stree.h", file_prefix);
 	if ((fp = fopen(fname, "w")) == NULL)
 		err(1, "%s: ", fname);
-	gen_header(root, PREFIX_LEN, NULL);
+	gen_header(fp, root, PREFIX_LEN, NULL);
+
+	fprintf(fp, "\n#ifdef SNMPTREE_TYPES\n");
+	gen_enums(fp);
+	fprintf(fp, "\n#endif /* SNMPTREE_TYPES */\n\n");
 
 	fprintf(fp, "#define %sCTREE_SIZE %u\n", file_prefix, tree_size);
 	fprintf(fp, "extern const struct snmp_node %sctree[];\n", file_prefix);
@@ -970,7 +1549,7 @@
 	sprintf(fname, "%stree.c", file_prefix);
 	if ((fp = fopen(fname, "w")) == NULL)
 		err(1, "%s: ", fname);
-	gen_table(root);
+	gen_table(fp, root);
 	fclose(fp);
 
 	return (0);
Index: gensnmptree.1
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/gensnmptree/gensnmptree.1,v
retrieving revision 1.2
retrieving revision 1.3
diff -L contrib/bsnmp/gensnmptree/gensnmptree.1 -L contrib/bsnmp/gensnmptree/gensnmptree.1 -u -r1.2 -r1.3
--- contrib/bsnmp/gensnmptree/gensnmptree.1
+++ contrib/bsnmp/gensnmptree/gensnmptree.1
@@ -2,6 +2,9 @@
 .\" Copyright (c) 2001-2005
 .\"	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 .\"	All rights reserved.
+.\" Copyright (c) 2006
+.\"	Hartmut Brandt
+.\"	All rights reserved.
 .\"
 .\" Author: Harti Brandt <harti at freebsd.org>
 .\" 
@@ -26,9 +29,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $Begemot: bsnmp/gensnmptree/gensnmptree.1,v 1.7 2006/02/27 09:52:08 brandt_h Exp $
+.\" $Begemot: gensnmptree.1 383 2006-05-30 07:40:49Z brandt_h $
 .\"
-.Dd February 27, 2006
+.Dd May 26, 2006
 .Dt GENSNMPTREE 1
 .Os
 .Sh NAME
@@ -36,7 +39,9 @@
 .Nd "generate C and header files from a MIB description file"
 .Sh SYNOPSIS
 .Nm
-.Op Fl helt
+.Op Fl dEehlt
+.Op Fl I Ar directory
+.Op Fl i Ar infile
 .Op Fl p Ar prefix
 .Op Ar name Ar ...
 .Sh DESCRIPTION
@@ -49,9 +54,12 @@
 daemon or for module writers.
 The second form may be used by SNMP client program writers.
 .Pp
-If the
-.Fl e
-option is not used
+If none of the options
+.Fl e ,
+.Fl E
+or
+.FL t
+are used
 .Nm
 reads a MIB description from its standard input and creates two files: a
 C-file
@@ -61,12 +69,20 @@
 during PDU processing
 and a header file
 .Ar prefix Ns tree.h
-containing appropriate declarations of the callback functions used in this table
-and the table itself.
+containing appropriate declarations of the callback functions used in this
+table, the table itself and definitions for all enums.
 .Pp
-If the
-.Fl e
-option is specified
+The following options are available:
+.Bl -tag -width ".Fl E"
+.It Fl d
+Switch on debugging.
+.It Fl E
+Extract enumerations and bit constructs.
+In this mode the tool emits
+a header file that contains for each type given on the command line a
+C-enum definition and a preprocessor define that may be used to map
+values to strings.
+.It Fl e
 .Nm
 expects MIB variable names (only the last component) on its command line.
 It reads a MIB specification from standard input and for each MIB variable
@@ -83,13 +99,13 @@
 .It Va OID_ Ns Ar name
 is the last component of the OID.
 .El
-.Pp
-The options are as follows:
-.Bl -tag -width ".Fl d Ar argument"
 .It Fl h
 Print a short help page.
-.It Fl e
-Enter extract mode.
+.It Fl I Ar directory
+Add the named directory to the include path just before the standard include
+directories.
+.It Fl i Ar infile
+Read from the named file instead of standard input.
 .It Fl l
 Generate local preprocessor includes.
 This is used for bootstrapping
@@ -103,26 +119,44 @@
 .Sh MIBS
 The syntax of the MIB description file can formally be specified as follows:
 .Bd -unfilled -offset indent
-file := tree | tree file
+ file := top | top file
+
+ top := tree | typedef | include
+
+ tree := head elements ')'
+
+ entry := head ':' index STRING elements ')'
+
+ leaf := head type STRING ACCESS ')'
+
+ column := head type ACCESS ')'
+
+ type := BASETYPE | BASETYPE '|' subtype | enum | bits
+
+ subtype := STRING
 
-tree := head elements ')'
+ enum := ENUM '(' value ')'
 
-entry := head ':' index STRING elements ')'
+ bits := BITS '(' value ')'
 
-leaf := head TYPE STRING ACCESS ')'
+ value := INT STRING | INT STRING value
 
-column := head TYPE ACCESS ')'
+ head := '(' INT STRING
 
-head := '(' INT STRING
+ elements := EMPTY | elements element
 
-elements := EMPTY | elements element
+ element := tree | leaf | column
 
-element := tree | leaf
+ index := type | index type
 
-index := TYPE | index TYPE
+ typedef := 'typedef' STRING type
+
+ include := 'include' filespec
+
+ filespec := '"' STRING '"' | '<' STRING '>'
 .Ed
 .Pp
-.Ar TYPE
+.Ar BASETYPE
 specifies a SNMP data type and may be one of
 .Bl -bullet -offset indent -compact
 .It
@@ -163,10 +197,25 @@
 is a decimal integer and
 .Ar STRING
 is any string starting with a letter or underscore and consisting of
-letters, digits and underscores, that is not one of the keywords.
+letters, digits, underscores and minuses, that is not one of the keywords.
+.Pp
+The
+.Ar typedef
+directive associates a type with a single name.
+.Pp
+The
+.Ar include
+directive is replaced by the contents of the named file.
 .Sh EXAMPLES
 The following MIB description describes the system group:
 .Bd -literal -offset indent
+include "tc.def"
+
+typedef AdminStatus ENUM (
+	1 up
+	2 down
+)
+
 (1 internet
   (2 mgmt
     (1 mibII
Index: asn1.c
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/lib/asn1.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L contrib/bsnmp/lib/asn1.c -L contrib/bsnmp/lib/asn1.c -u -r1.2 -r1.3
--- contrib/bsnmp/lib/asn1.c
+++ contrib/bsnmp/lib/asn1.c
@@ -45,16 +45,6 @@
 #include "support.h"
 #include "asn1.h"
 
-#if !defined(INT32_MIN)
-#define	INT32_MIN	(-0x7fffffff-1)
-#endif
-#if !defined(INT32_MAX)
-#define	INT32_MAX	(0x7fffffff)
-#endif
-#if !defined(UINT32_MAX)
-#define	UINT32_MAX	(0xffffffff)
-#endif
-
 static void asn_error_func(const struct asn_buf *, const char *, ...);
 
 void (*asn_error)(const struct asn_buf *, const char *, ...) = asn_error_func;
Index: snmpclient.c
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/lib/snmpclient.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L contrib/bsnmp/lib/snmpclient.c -L contrib/bsnmp/lib/snmpclient.c -u -r1.2 -r1.3
--- contrib/bsnmp/lib/snmpclient.c
+++ contrib/bsnmp/lib/snmpclient.c
@@ -64,14 +64,6 @@
 #include "snmpclient.h"
 #include "snmppriv.h"
 
-#if !defined(INT32_MAX)
-#define	INT32_MAX	(0x7fffffff)
-#endif
-#if !defined(UINT32_MAX)
-#define	UINT32_MAX	(0xffffffff)
-#endif
-
-
 /* global context */
 struct snmp_client snmp_client;
 
Index: mibII.c
===================================================================
RCS file: /home/cvs/src/contrib/bsnmp/snmp_mibII/mibII.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L contrib/bsnmp/snmp_mibII/mibII.c -L contrib/bsnmp/snmp_mibII/mibII.c -u -r1.2 -r1.3
--- contrib/bsnmp/snmp_mibII/mibII.c
+++ contrib/bsnmp/snmp_mibII/mibII.c
@@ -26,12 +26,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Begemot: bsnmp/snmp_mibII/mibII.c,v 1.24 2006/02/14 09:04:18 brandt_h Exp $
+ * $Begemot: mibII.c 516 2006-10-27 15:54:02Z brandt_h $
  *
  * Implementation of the standard interfaces and ip MIB.
  */
 #include "mibII.h"
 #include "mibII_oid.h"
+#include <net/if.h>
 #include <net/if_types.h>
 
 
@@ -376,16 +377,16 @@
 	u_int ticks;
 
 	if ((ticks = mibif_force_hc_update_interval) == 0) {
-		if (mibif_maxspeed <= 10000000) {
+		if (mibif_maxspeed <= IF_Mbps(10)) {
 			/* at 10Mbps overflow needs 3436 seconds */
 			ticks = 3000 * 100;	/* 50 minutes */
-		} else if (mibif_maxspeed <= 100000000) {
+		} else if (mibif_maxspeed <= IF_Mbps(100)) {
 			/* at 100Mbps overflow needs 343 seconds */
 			ticks = 300 * 100;	/* 5 minutes */
-		} else if (mibif_maxspeed < 650000000) {
+		} else if (mibif_maxspeed < IF_Mbps(622)) {
 			/* at 622Mbps overflow needs 53 seconds */
 			ticks = 40 * 100;	/* 40 seconds */
-		} else if (mibif_maxspeed <= 1000000000) {
+		} else if (mibif_maxspeed <= IF_Mbps(1000)) {
 			/* at 1Gbps overflow needs  34 seconds */
 			ticks = 20 * 100;	/* 20 seconds */
 		} else {


More information about the Midnightbsd-cvs mailing list