Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Mar 2020 17:50:32 +0000 (UTC)
From:      Hartmut Brandt <harti@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r359490 - in vendor/bsnmp/dist: . config gensnmpdef gensnmptree lib snmp_mibII snmp_ntp snmp_target snmp_usm snmp_vacm snmpd tests
Message-ID:  <202003311750.02VHoWCk065614@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: harti
Date: Tue Mar 31 17:50:32 2020
New Revision: 359490
URL: https://svnweb.freebsd.org/changeset/base/359490

Log:
  Import version 1.14 of bsnmp. This mainly consists of bug fixes
  in the ASN.1 functions and comes with a test suite for these
  functions.

Added:
  vendor/bsnmp/dist/snmpd/trans_inet.c   (contents, props changed)
  vendor/bsnmp/dist/snmpd/trans_inet.h   (contents, props changed)
  vendor/bsnmp/dist/tests/
  vendor/bsnmp/dist/tests/asn1.cc   (contents, props changed)
  vendor/bsnmp/dist/tests/catch.hpp   (contents, props changed)
  vendor/bsnmp/dist/tests/constbuf.h   (contents, props changed)
  vendor/bsnmp/dist/tests/main.cc   (contents, props changed)
  vendor/bsnmp/dist/tests/snmp_parse_server.cc   (contents, props changed)
Deleted:
  vendor/bsnmp/dist/Makefile.in
  vendor/bsnmp/dist/README.1st
  vendor/bsnmp/dist/config/
  vendor/bsnmp/dist/configure.ac
  vendor/bsnmp/dist/gensnmpdef/Makefile.in
  vendor/bsnmp/dist/gensnmptree/Makefile.in
  vendor/bsnmp/dist/lib/Makefile.in
  vendor/bsnmp/dist/lib/snmptc.h.in
  vendor/bsnmp/dist/libbsnmp.pc.in
  vendor/bsnmp/dist/snmp_mibII/Makefile.in
  vendor/bsnmp/dist/snmp_ntp/Makefile.in
  vendor/bsnmp/dist/snmp_target/Makefile.in
  vendor/bsnmp/dist/snmp_usm/Makefile.in
  vendor/bsnmp/dist/snmp_vacm/Makefile.in
  vendor/bsnmp/dist/snmpd/Makefile.in
Modified:
  vendor/bsnmp/dist/gensnmptree/gensnmptree.1
  vendor/bsnmp/dist/gensnmptree/gensnmptree.c
  vendor/bsnmp/dist/lib/asn1.c
  vendor/bsnmp/dist/lib/bsnmpclient.3
  vendor/bsnmp/dist/lib/snmp.h
  vendor/bsnmp/dist/lib/snmpclient.c
  vendor/bsnmp/dist/lib/snmpclient.h
  vendor/bsnmp/dist/lib/snmpcrypto.c
  vendor/bsnmp/dist/lib/tc.def
  vendor/bsnmp/dist/snmp_mibII/mibII.c
  vendor/bsnmp/dist/snmp_mibII/mibII.h
  vendor/bsnmp/dist/snmp_mibII/mibII_interfaces.c
  vendor/bsnmp/dist/snmp_mibII/snmp_mibII.h
  vendor/bsnmp/dist/snmp_ntp/snmp_ntp.c
  vendor/bsnmp/dist/snmp_target/target_snmp.c
  vendor/bsnmp/dist/snmp_usm/usm_snmp.c
  vendor/bsnmp/dist/snmp_vacm/vacm_snmp.c
  vendor/bsnmp/dist/snmpd/BEGEMOT-SNMPD.txt
  vendor/bsnmp/dist/snmpd/main.c
  vendor/bsnmp/dist/snmpd/snmpd.config
  vendor/bsnmp/dist/snmpd/snmpd.h
  vendor/bsnmp/dist/snmpd/snmpmod.h
  vendor/bsnmp/dist/snmpd/trans_lsock.c
  vendor/bsnmp/dist/snmpd/trans_udp.c
  vendor/bsnmp/dist/snmpd/trap.c
  vendor/bsnmp/dist/snmpd/tree.def

Modified: vendor/bsnmp/dist/gensnmptree/gensnmptree.1
==============================================================================
--- vendor/bsnmp/dist/gensnmptree/gensnmptree.1	Tue Mar 31 16:47:15 2020	(r359489)
+++ vendor/bsnmp/dist/gensnmptree/gensnmptree.1	Tue Mar 31 17:50:32 2020	(r359490)
@@ -2,7 +2,7 @@
 .\" Copyright (c) 2001-2005
 .\"	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 .\"	All rights reserved.
-.\" Copyright (c) 2006
+.\" Copyright (c) 2006,2018
 .\"	Hartmut Brandt
 .\"	All rights reserved.
 .\"
@@ -31,7 +31,7 @@
 .\"
 .\" $Begemot: gensnmptree.1 383 2006-05-30 07:40:49Z brandt_h $
 .\"
-.Dd May 26, 2006
+.Dd April 2, 2019
 .Dt GENSNMPTREE 1
 .Os
 .Sh NAME
@@ -39,7 +39,7 @@
 .Nd "generate C and header files from a MIB description file"
 .Sh SYNOPSIS
 .Nm
-.Op Fl dEehlt
+.Op Fl dEeFfhlt
 .Op Fl I Ar directory
 .Op Fl i Ar infile
 .Op Fl p Ar prefix
@@ -99,6 +99,12 @@ is the length of the OID.
 .It Va OID_ Ns Ar name
 is the last component of the OID.
 .El
+.It Fl F
+emit definitions for C-functions includeable in a C-file that do some basic
+stuff on enums like value checking and conversion between value and strings.
+.It Fl f
+emit definitions for inline C-functions that do some basic
+stuff on enums like value checking and conversion between value and strings.
 .It Fl h
 Print a short help page.
 .It Fl I Ar directory

Modified: vendor/bsnmp/dist/gensnmptree/gensnmptree.c
==============================================================================
--- vendor/bsnmp/dist/gensnmptree/gensnmptree.c	Tue Mar 31 16:47:15 2020	(r359489)
+++ vendor/bsnmp/dist/gensnmptree/gensnmptree.c	Tue Mar 31 17:50:32 2020	(r359490)
@@ -123,9 +123,40 @@ options:\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\
+  -t		generate a .def file\n\
 ";
 
+/**
+ * Program operation.
+ */
+enum op {
+	/** generate the tree */
+	OP_GEN,
+
+	/** extract OIDs */
+	OP_EXTRACT,
+
+	/** print the parsed tree */
+	OP_TREE,
+
+	/** extract enums */
+	OP_ENUMS,
+};
+
+/**
+ * Which functions to create.
+ */
+enum gen_funcs {
+	/** none */
+	GEN_FUNCS_NONE,
+
+	/** functions for header files */
+	GEN_FUNCS_H,
+
+	/** functions for C files */
+	GEN_FUNCS_C,
+};
+
 /*
  * A node in the OID tree
  */
@@ -161,15 +192,18 @@ struct node {
 	    uint32_t	index;	/* index for table entry */
 	    char	*func;	/* function for tables */
 	    struct node_list subs;
+	    char	*subtypes[SNMP_INDEXES_MAX];
 	  }		entry;
 
 	  struct leaf {
 	    enum snmp_syntax syntax;	/* syntax for this leaf */
 	    char	*func;		/* function name */
+	    char	*subtype;	/* subtype */
 	  }		leaf;
 
 	  struct column {
 	    enum snmp_syntax syntax;	/* syntax for this column */
+	    char	*subtype;	/* subtype */
 	  }		column;
 	}		u;
 };
@@ -213,7 +247,7 @@ xalloc(size_t size)
 {
 	void *ptr;
 
-	if ((ptr = malloc(size)) == NULL)
+	if ((ptr = calloc(1, size)) == NULL)
 		err(1, "allocing %zu bytes", size);
 
 	return (ptr);
@@ -709,12 +743,14 @@ make_type(const char *s)
  * token.
  */
 static u_int
-parse_type(enum tok *tok, struct type *t, const char *vname)
+parse_type(enum tok *tok, struct type *t, const char *vname, char **subtype)
 {
 	u_int syntax;
 	struct enums *e;
 
 	syntax = val;
+	if (subtype != NULL)
+		*subtype = NULL;
 
 	if (*tok == TOK_ENUM || *tok == TOK_BITS) {
 		if (t == NULL && vname != NULL) {
@@ -758,6 +794,8 @@ parse_type(enum tok *tok, struct type *t, const char *
 		if ((*tok = gettoken()) == '|') {
 			if (gettoken() != TOK_STR)
 				report("subtype expected after '|'");
+			if (subtype != NULL)
+				*subtype = savetok();
 			*tok = gettoken();
 		}
 	}
@@ -793,18 +831,21 @@ parse(enum tok tok)
 	if ((tok = gettoken()) == TOK_TYPE || tok == TOK_DEFTYPE ||
 	    tok == TOK_ENUM || tok == TOK_BITS) {
 		/* LEAF or COLUM */
-		u_int syntax = parse_type(&tok, NULL, node->name);
+		char *subtype;
+		u_int syntax = parse_type(&tok, NULL, node->name, &subtype);
 
 		if (tok == TOK_STR) {
 			/* LEAF */
 			node->type = NODE_LEAF;
 			node->u.leaf.func = savetok();
 			node->u.leaf.syntax = syntax;
+			node->u.leaf.subtype = subtype;
 			tok = gettoken();
 		} else {
 			/* COLUMN */
 			node->type = NODE_COLUMN;
 			node->u.column.syntax = syntax;
+			node->u.column.subtype = subtype;
 		}
 
 		while (tok != ')') {
@@ -824,9 +865,12 @@ parse(enum tok tok)
 		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)
+			char *subtype;
+			u_int syntax = parse_type(&tok, NULL, node->name,
+			    &subtype);
+			if (index_count == SNMP_INDEXES_MAX)
 				report("too many table indexes");
+			node->u.entry.subtypes[index_count++] = subtype;
 			node->u.entry.index |=
 			    syntax << (SNMP_INDEX_SHIFT * index_count);
 		}
@@ -881,7 +925,8 @@ parse_top(enum tok tok)
 		tok = gettoken();
 		t->is_enum = (tok == TOK_ENUM);
 		t->is_bits = (tok == TOK_BITS);
-		t->syntax = parse_type(&tok, t, NULL);
+
+		t->syntax = parse_type(&tok, t, NULL, NULL);
 		pushback(tok);
 
 		return (NULL);
@@ -902,7 +947,7 @@ parse_top(enum tok tok)
  * Generate the C-code table part for one node.
  */
 static void
-gen_node(FILE *fp, struct node *np, struct asn_oid *oid, u_int idx,
+gen_node(FILE *fp, const struct node *np, struct asn_oid *oid, u_int idx,
     const char *func)
 {
 	u_int n;
@@ -1007,7 +1052,7 @@ gen_node(FILE *fp, struct node *np, struct asn_oid *oi
  * Generate the header file with the function declarations.
  */
 static void
-gen_header(FILE *fp, struct node *np, u_int oidlen, const char *func)
+gen_header(FILE *fp, const struct node *np, u_int oidlen, const char *func)
 {
 	char f[MAXSTR + 4];
 	struct node *sub;
@@ -1057,7 +1102,7 @@ gen_header(FILE *fp, struct node *np, u_int oidlen, co
  * Generate the OID table.
  */
 static void
-gen_table(FILE *fp, struct node *node)
+gen_table(FILE *fp, const struct node *node)
 {
 	struct asn_oid oid;
 
@@ -1116,6 +1161,8 @@ gen_tree(const struct node *np, int level)
 
 	  case NODE_LEAF:
 		print_syntax(np->u.leaf.syntax);
+		if (np->u.leaf.subtype != NULL)
+			printf(" | %s", np->u.leaf.subtype);
 		printf(" %s%s%s)\n", np->u.leaf.func,
 		    (np->flags & FL_GET) ? " GET" : "",
 		    (np->flags & FL_SET) ? " SET" : "");
@@ -1135,8 +1182,11 @@ gen_tree(const struct node *np, int level)
 	  case NODE_ENTRY:
 		printf(" :");
 
-		for (i = 0; i < SNMP_INDEX_COUNT(np->u.entry.index); i++)
+		for (i = 0; i < SNMP_INDEX_COUNT(np->u.entry.index); i++) {
 			print_syntax(SNMP_INDEX(np->u.entry.index, i));
+			if (np->u.entry.subtypes[i] != NULL)
+				printf(" | %s", np->u.entry.subtypes[i]);
+		}
 		printf(" %s\n", np->u.entry.func);
 		TAILQ_FOREACH(sp, &np->u.entry.subs, link)
 			gen_tree(sp, level + 1);
@@ -1145,6 +1195,8 @@ gen_tree(const struct node *np, int level)
 
 	  case NODE_COLUMN:
 		print_syntax(np->u.column.syntax);
+		if (np->u.column.subtype != NULL)
+			printf(" | %s", np->u.column.subtype);
 		printf("%s%s)\n", (np->flags & FL_GET) ? " GET" : "",
 		    (np->flags & FL_SET) ? " SET" : "");
 		break;
@@ -1380,45 +1432,6 @@ unminus(FILE *fp, const char *s)
 }
 
 /**
- * Generate a definition for the enum packed into a guard against multiple
- * definitions.
- *
- * \param fp	file to write definition to
- * \param t	type
- */
-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);
-}
-
-/**
  * Generate helper functions for an enum.
  *
  * We always generate a switch statement for the isok function. The compiler
@@ -1483,6 +1496,54 @@ gen_enum_funcs(FILE *fp, const struct type *t, int cco
 }
 
 /**
+ * Generate a definition for the enum packed into a guard against multiple
+ * definitions.
+ *
+ * \param fp	file to write definition to
+ * \param t	type
+ * \param dof	generate functions too
+ */
+static void
+gen_enum(FILE *fp, const struct type *t, int dof)
+{
+	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");
+	if (dof) {
+		fprintf(fp, "#ifdef SNMPENUM_FUNCS\n");
+		fprintf(fp, "\n");
+		gen_enum_funcs(fp, t, 0);
+		fprintf(fp, "\n");
+		fprintf(fp, "#endif\n");
+		fprintf(fp, "\n");
+	}
+	fprintf(fp, "#endif /* %s_defined__ */\n", t->name);
+}
+
+/**
  * Generate helper functions for an enum. This generates code for a c file.
  *
  * \param fp		file to write to
@@ -1519,13 +1580,13 @@ gen_all_enum_funcs(FILE *fp, int ccode)
 }
 
 static void
-gen_enums(FILE *fp)
+gen_enums(FILE *fp, int dof)
 {
 	const struct type *t;
 
 	LIST_FOREACH(t, &types, link)
 		if (t->is_enum || t->is_bits)
-			gen_enum(fp, t);
+			gen_enum(fp, t, dof);
 }
 
 /**
@@ -1545,9 +1606,7 @@ extract_enum(FILE *fp, const char *name, int gen_funcs
 
 	LIST_FOREACH(t, &types, link)
 		if ((t->is_enum || t->is_bits) && strcmp(t->name, name) == 0) {
-			gen_enum(fp, t);
-			if (gen_funcs)
-				gen_enum_funcs(fp, t, 0);
+			gen_enum(fp, t, gen_funcs);
 			return (0);
 		}
 	return (-1);
@@ -1566,11 +1625,8 @@ extract_all_enums(FILE *fp, int gen_funcs)
 	const struct type *t;
 
 	LIST_FOREACH(t, &types, link)
-		if (t->is_enum || t->is_bits) {
-			gen_enum(fp, t);
-			if (gen_funcs)
-				gen_enum_funcs(fp, t, 0);
-		}
+		if (t->is_enum || t->is_bits)
+			gen_enum(fp, t, gen_funcs);
 }
 
 /**
@@ -1578,13 +1634,12 @@ extract_all_enums(FILE *fp, int gen_funcs)
  *
  * \param argc		number of arguments
  * \param argv		arguments (enum names)
- * \param gen_funcs_h	generate functions into the header file
- * \param gen_funcs_c	generate a .c file with functions
+ * \param gen_funcs	which functions to generate
  */
 static void
-make_enums(int argc, char *argv[], int gen_funcs_h, int gen_funcs_c)
+make_enums(int argc, char *argv[], enum gen_funcs gen_funcs)
 {
-	if (gen_funcs_c) {
+	if (gen_funcs == GEN_FUNCS_C) {
 		if (argc == 0)
 			gen_all_enum_funcs(stdout, 1);
 		else {
@@ -1594,30 +1649,58 @@ make_enums(int argc, char *argv[], int gen_funcs_h, in
 		}
 	} else {
 		if (argc == 0)
-			extract_all_enums(stdout, gen_funcs_h);
+			extract_all_enums(stdout, gen_funcs == GEN_FUNCS_H);
 		else {
 			for (int i = 0; i < argc; i++)
-				if (extract_enum(stdout, argv[i], gen_funcs_h))
+				if (extract_enum(stdout, argv[i],
+				    gen_funcs == GEN_FUNCS_H))
 					errx(1, "enum not found: %s", argv[i]);
 		}
 	}
 }
 
+/**
+ * Produce the operation tables for the daemon or a module.
+ *
+ * \param root		tree root
+ * \param gen_funcs	generate enum funcs
+ */
+static void
+make_table(const struct node *root, int gen_funcs)
+{
+	FILE *fp;
+
+	char fname[MAXPATHLEN + 1];
+	sprintf(fname, "%stree.h", file_prefix);
+	if ((fp = fopen(fname, "w")) == NULL)
+		err(1, "%s: ", fname);
+	gen_header(fp, root, PREFIX_LEN, NULL);
+
+	fprintf(fp, "\n#ifdef SNMPTREE_TYPES\n");
+	gen_enums(fp, gen_funcs);
+	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);
+
+	fclose(fp);
+
+	sprintf(fname, "%stree.c", file_prefix);
+	if ((fp = fopen(fname, "w")) == NULL)
+		err(1, "%s: ", fname);
+	gen_table(fp, root);
+	fclose(fp);
+}
+
 int
 main(int argc, char *argv[])
 {
-	int do_extract = 0;
-	int do_tree = 0;
-	int do_enums = 0;
-	int gen_funcs_h = 0;
-	int gen_funcs_c = 0;
-	int opt;
-	struct node *root;
-	char fname[MAXPATHLEN + 1];
-	int tok;
-	FILE *fp;
+	enum op op = OP_GEN;
+	enum gen_funcs gen_funcs = GEN_FUNCS_NONE;
+
 	char *infile = NULL;
 
+	int opt;
 	while ((opt = getopt(argc, argv, "dEeFfhI:i:lp:t")) != EOF)
 		switch (opt) {
 
@@ -1626,19 +1709,29 @@ main(int argc, char *argv[])
 			break;
 
 		  case 'E':
-			do_enums = 1;
+			if (op != OP_GEN && op != OP_ENUMS)
+				errx(1, "-E conflicts with earlier options");
+			op = OP_ENUMS;
 			break;
 
 		  case 'e':
-			do_extract = 1;
+			if (op != OP_GEN && op != OP_EXTRACT)
+				errx(1, "-e conflicts with earlier options");
+			op = OP_EXTRACT;
 			break;
 
 		  case 'F':
-			gen_funcs_c = 1;
+			if (gen_funcs != GEN_FUNCS_NONE &&
+			    gen_funcs != GEN_FUNCS_C)
+				errx(1, "-F conflicts with -f");
+			gen_funcs = GEN_FUNCS_C;
 			break;
 
 		  case 'f':
-			gen_funcs_h = 1;
+			if (gen_funcs != GEN_FUNCS_NONE &&
+			    gen_funcs != GEN_FUNCS_H)
+				errx(1, "-f conflicts with -F");
+			gen_funcs = GEN_FUNCS_H;
 			break;
 
 		  case 'h':
@@ -1665,73 +1758,61 @@ main(int argc, char *argv[])
 			break;
 
 		  case 't':
-			do_tree = 1;
+			if (op != OP_GEN && op != OP_TREE)
+				errx(1, "-t conflicts with earlier options");
+			op = OP_TREE;
 			break;
 		}
 
-	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)
-		errx(1, "no objects specified");
+	argc -= optind;
+	argv += optind;
 
-	if ((gen_funcs_h || gen_funcs_c) && !do_enums)
-		errx(1, "-f and -F require -E");
-	if (gen_funcs_h && gen_funcs_c)
-		errx(1, "-f and -F are mutually exclusive");
-
+	/* open input */
 	if (infile == NULL) {
 		input_new(stdin, NULL, "<stdin>");
 	} else {
+		FILE *fp;
 		if ((fp = fopen(infile, "r")) == NULL)
 			err(1, "%s", infile);
 		input_new(fp, NULL, infile);
 	}
 
-	root = parse_top(gettoken());
+	/* parse and check input */
+	struct node *root = parse_top(gettoken());
+
+	int tok;
 	while ((tok = gettoken()) != TOK_EOF)
 		merge(&root, parse_top(tok));
 
 	if (root)
 		check_tree(root);
 
-	if (do_extract) {
-		while (optind < argc) {
-			if (gen_extract(stdout, root, argv[optind]))
-				errx(1, "object not found: %s", argv[optind]);
-			optind++;
-		}
+	/* do what the user has requested */
+	switch (op) {
+
+	  case OP_EXTRACT:
+		if (argc == 0)
+			errx(1, "-e requires arguments");
+
+		for (int i = 0; i < argc; i++)
+			if (gen_extract(stdout, root, argv[i]))
+				errx(1, "object not found: %s", argv[i]);
 		return (0);
-	}
-	if (do_enums) {
-		make_enums(argc - optind, argv + optind,
-		    gen_funcs_h, gen_funcs_c);
+
+	  case OP_ENUMS:
+		make_enums(argc, argv, gen_funcs);
 		return (0);
-	}
-	if (do_tree) {
+
+	  case OP_TREE:
+		if (argc != 0)
+			errx(1, "-t allows no arguments");
 		gen_tree(root, 0);
 		return (0);
-	}
-	sprintf(fname, "%stree.h", file_prefix);
-	if ((fp = fopen(fname, "w")) == NULL)
-		err(1, "%s: ", fname);
-	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);
-
-	fclose(fp);
-
-	sprintf(fname, "%stree.c", file_prefix);
-	if ((fp = fopen(fname, "w")) == NULL)
-		err(1, "%s: ", fname);
-	gen_table(fp, root);
-	fclose(fp);
-
-	return (0);
+	  case OP_GEN:
+		if (argc != 0)
+			errx(1, "tree generation allows no arguments");
+		make_table(root, gen_funcs == GEN_FUNCS_H);
+		return (0);
+	}
 }

Modified: vendor/bsnmp/dist/lib/asn1.c
==============================================================================
--- vendor/bsnmp/dist/lib/asn1.c	Tue Mar 31 16:47:15 2020	(r359489)
+++ vendor/bsnmp/dist/lib/asn1.c	Tue Mar 31 17:50:32 2020	(r359490)
@@ -65,8 +65,8 @@ asn_get_header(struct asn_buf *b, u_char *type, asn_le
 		return (ASN_ERR_EOBUF);
 	}
 	*type = *b->asn_cptr;
-	if ((*type & ASN_TYPE_MASK) > 0x30) {
-		asn_error(b, "types > 0x30 not supported (%u)",
+	if ((*type & ASN_TYPE_MASK) > 0x1e) {
+		asn_error(b, "tags > 0x1e not supported (%#x)",
 		    *type & ASN_TYPE_MASK);
 		return (ASN_ERR_FAILED);
 	}
@@ -100,6 +100,19 @@ asn_get_header(struct asn_buf *b, u_char *type, asn_le
 		*len = *b->asn_cptr++;
 		b->asn_len--;
 	}
+
+#ifdef	BOGUS_CVE_2019_5610_FIX
+	/*
+	 * This is the fix from CVE-2019-5610.
+	 *
+	 * This is the wrong place. Each of the asn functions should check
+	 * that it has enough info for its own work.
+	 */
+	if (*len > b->asn_len) {
+		asn_error(b, "lenen %u exceeding asn_len %u", *len, b->asn_len);
+		return (ASN_ERR_EOBUF);
+	}
+#endif
 	return (ASN_ERR_OK);
 }
 
@@ -142,7 +155,7 @@ asn_put_len(u_char *ptr, asn_len_t len)
 
 /*
  * Write a header (tag and length fields).
- * Tags are restricted to one byte tags (value <= 0x30) and the
+ * Tags are restricted to one byte tags (value <= 0x1e) and the
  * lenght field to 16-bit. All errors stop the encoding.
  */
 enum asn_err
@@ -151,8 +164,8 @@ asn_put_header(struct asn_buf *b, u_char type, asn_len
 	u_int lenlen;
 
 	/* tag field */
-	if ((type & ASN_TYPE_MASK) > 0x30) {
-		asn_error(NULL, "types > 0x30 not supported (%u)",
+	if ((type & ASN_TYPE_MASK) > 0x1e) {
+		asn_error(NULL, "types > 0x1e not supported (%#x)",
 		    type & ASN_TYPE_MASK);
 		return (ASN_ERR_FAILED);
 	}
@@ -246,9 +259,10 @@ asn_get_real_integer(struct asn_buf *b, asn_len_t len,
 		return (ASN_ERR_BADLEN);
 	}
 	err = ASN_ERR_OK;
-	if (len > 8)
+	if (len > 8) {
+		asn_error(b, "integer too long");
 		err = ASN_ERR_RANGE;
-	else if (len > 1 &&
+	} else if (len > 1 &&
 	    ((*b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) ||
 	    (*b->asn_cptr == 0xff && (b->asn_cptr[1] & 0x80) == 0x80))) {
 		asn_error(b, "non-minimal integer");
@@ -326,27 +340,35 @@ asn_put_real_integer(struct asn_buf *b, u_char type, i
 static enum asn_err
 asn_get_real_unsigned(struct asn_buf *b, asn_len_t len, uint64_t *vp)
 {
-	enum asn_err err;
-
+	*vp = 0;
 	if (b->asn_len < len) {
 		asn_error(b, "truncated integer");
 		return (ASN_ERR_EOBUF);
 	}
 	if (len == 0) {
+		/* X.690: 8.3.1 */
 		asn_error(b, "zero-length integer");
-		*vp = 0;
 		return (ASN_ERR_BADLEN);
 	}
-	err = ASN_ERR_OK;
-	*vp = 0;
-	if ((*b->asn_cptr & 0x80) || (len == 9 && *b->asn_cptr != 0)) {
+	if (len > 1 && *b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) {
+		/* X.690: 8.3.2 */
+		asn_error(b, "non-minimal unsigned");
+		b->asn_cptr += len;
+		b->asn_len -= len;
+		return (ASN_ERR_BADLEN);
+		
+	}
+
+	enum asn_err err = ASN_ERR_OK;
+
+	if ((*b->asn_cptr & 0x80) || len > 9 ||
+	    (len == 9 && *b->asn_cptr != 0)) {
 		/* negative integer or too larger */
 		*vp = 0xffffffffffffffffULL;
-		err = ASN_ERR_RANGE;
-	} else if (len > 1 &&
-	    *b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) {
-		asn_error(b, "non-minimal unsigned");
-		err = ASN_ERR_BADLEN;
+		asn_error(b, "unsigned too large or negative");
+		b->asn_cptr += len;
+		b->asn_len -= len;
+		return (ASN_ERR_RANGE);
 	}
 
 	while (len--) {
@@ -400,11 +422,14 @@ asn_get_integer_raw(struct asn_buf *b, asn_len_t len, 
 	enum asn_err ret;
 
 	if ((ret = asn_get_real_integer(b, len, &val)) == ASN_ERR_OK) {
-		if (len > 4)
+		if (len > 4) {
+			asn_error(b, "integer too long");
 			ret = ASN_ERR_BADLEN;
-		else if (val > INT32_MAX || val < INT32_MIN)
+		} else if (val > INT32_MAX || val < INT32_MIN) {
 			/* may not happen */
+			asn_error(b, "integer out of range");
 			ret = ASN_ERR_RANGE;
+		}
 		*vp = (int32_t)val;
 	}
 	return (ret);
@@ -584,7 +609,7 @@ asn_get_objid_raw(struct asn_buf *b, asn_len_t len, st
 				return (ASN_ERR_EOBUF);
 			}
 			if (subid > (ASN_MAXID >> 7)) {
-				asn_error(b, "OBID subid too larger");
+				asn_error(b, "OID subid too larger");
 				err = ASN_ERR_RANGE;
 			}
 			subid = (subid << 7) | (*b->asn_cptr & 0x7f);
@@ -640,7 +665,7 @@ asn_put_objid(struct asn_buf *b, const struct asn_oid 
 		oidlen = 2;
 	} else if (oid->len == 1) {
 		/* illegal */
-		asn_error(b, "short oid");
+		asn_error(NULL, "short oid");
 		if (oid->subs[0] > 2)
 			asn_error(NULL, "oid[0] too large (%u)", oid->subs[0]);
 		err = ASN_ERR_RANGE;
@@ -652,7 +677,8 @@ asn_put_objid(struct asn_buf *b, const struct asn_oid 
 			err = ASN_ERR_RANGE;
 		}
 		if (oid->subs[0] > 2 ||
-		    (oid->subs[0] < 2 && oid->subs[1] >= 40)) {
+		    (oid->subs[0] < 2 && oid->subs[1] >= 40) ||
+		    (oid->subs[0] == 2 && oid->subs[1] > ASN_MAXID - 2 * 40)) {
 			asn_error(NULL, "oid out of range (%u,%u)",
 			    oid->subs[0], oid->subs[1]);
 			err = ASN_ERR_RANGE;
@@ -809,10 +835,7 @@ asn_get_uint32_raw(struct asn_buf *b, asn_len_t len, u
 	enum asn_err err;
 
 	if ((err = asn_get_real_unsigned(b, len, &v)) == ASN_ERR_OK) {
-		if (len > 5) {
-			asn_error(b, "uint32 too long %u", len);
-			err = ASN_ERR_BADLEN;
-		} else if (v > UINT32_MAX) {
+		if (v > UINT32_MAX) {
 			asn_error(b, "uint32 too large %llu", v);
 			err = ASN_ERR_RANGE;
 		}

Modified: vendor/bsnmp/dist/lib/bsnmpclient.3
==============================================================================
--- vendor/bsnmp/dist/lib/bsnmpclient.3	Tue Mar 31 16:47:15 2020	(r359489)
+++ vendor/bsnmp/dist/lib/bsnmpclient.3	Tue Mar 31 17:50:32 2020	(r359490)
@@ -31,7 +31,7 @@
 .\"
 .\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.12 2005/10/04 08:46:50 brandt_h Exp $
 .\"
-.Dd December 31, 2016
+.Dd March 31, 2020
 .Dt BSNMPCLIENT 3
 .Os
 .Sh NAME
@@ -177,7 +177,9 @@ If it is
 a local stream socket is used.
 For
 .Dv SNMP_TRANS_UDP
-a UDP socket is created.
+a UDPv4 socket and for
+.Dv SNMP_TRANS_UDP6
+a UDPv6 socket is created.
 It uses the
 .Va chost
 field as the path to the server's socket for local sockets.
@@ -675,7 +677,12 @@ The syntax of a server specification is
 .Pp
 where
 .Va trans
-is the transport name (one of udp, stream or dgram),
+is the transport name (one of
+.Qq udp ,
+.Qq udp6 ,
+.Qq stream
+or
+.Qq dgram ) ,
 .Va community
 is the string to be used for both the read and the write community,
 .Va server
@@ -685,13 +692,51 @@ of a local socket, and
 is the port in case of UDP transport.
 The function returns 0 in the case of success and return -1 and sets
 the error string in case of an error.
+.Pp
+The function
+.Fn snmp_parse_serverr
+fills the transport, the port number and the community strings with
+reasonable default values when they are not specified.
+The default transport
+is
+.Dv SNMP_TRANS_UDP .
+If the host name contains a slash the default is modified to
+.Dv SNMP_TRANS_LOC_DGRAM .
+If the host name looks like a numeric IPv6 address the default is
+.Dv SNMP_TRANS_UDP6 .
+For numeric IPv6 addresses the transport name udp is automatically
+translated as
+.Dv SNMP_TRANS_UDP6 .
+The default port number (for
+.Dv udp
+or
+.Dv udp6 )
+is
+.Qq snmp .
+The default read community is
+.Qq public
+and the default write community
+.Qq private .
+.Pp
+.Fn snmp_parse_server
+recognizes path names, host names and numerical IPv4 and IPv6 addresses.
+A string consisting of digits and periods is assumed to be an IPv4 address
+and must be parseable by
+.Fn inet_aton 3 .
+An IPv6 address is any string enclosed in square brackets.
+It must be parseable with
+.Fn gethostinfo 3 .
+.Pp
+The port number for
+.Fn snmp_parse_server
+can be specified numerically or symbolically.
+It is ignored for local sockets.
 .Sh DIAGNOSTICS
-If an error occurs in any of the function an error indication as described
+If an error occurs in any of the functions an error indication as described
 above is returned.
-Additionally the function sets a printable error string
-in the
+Additionally the function sets a printable error string in the
 .Va error
-filed of
+field of
 .Va snmp_client .
 .Sh SEE ALSO
 .Xr gensnmptree 1 ,

Modified: vendor/bsnmp/dist/lib/snmp.h
==============================================================================
--- vendor/bsnmp/dist/lib/snmp.h	Tue Mar 31 16:47:15 2020	(r359489)
+++ vendor/bsnmp/dist/lib/snmp.h	Tue Mar 31 17:50:32 2020	(r359490)
@@ -42,6 +42,9 @@
 
 #include <sys/types.h>
 
+#define	BSNMP_MAJOR	1
+#define	BSNMP_MINOR	13
+
 #define SNMP_COMMUNITY_MAXLEN		128
 #define SNMP_MAX_BINDINGS		100
 #define	SNMP_CONTEXT_NAME_SIZ		(32 + 1)

Modified: vendor/bsnmp/dist/lib/snmpclient.c
==============================================================================
--- vendor/bsnmp/dist/lib/snmpclient.c	Tue Mar 31 16:47:15 2020	(r359489)
+++ vendor/bsnmp/dist/lib/snmpclient.c	Tue Mar 31 17:50:32 2020	(r359490)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005
+ * Copyright (c) 2004-2005,2018-2019
  *	Hartmut Brandt.
  *	All rights reserved.
  * Copyright (c) 2001-2003
@@ -34,11 +34,13 @@
  *
  * Support functions for SNMP clients.
  */
-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/time.h>
 #include <sys/queue.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <net/if.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
@@ -58,12 +60,16 @@
 #include <err.h>
 #endif
 
+#include <arpa/inet.h>
+
 #include "support.h"
 #include "asn1.h"
 #include "snmp.h"
 #include "snmpclient.h"
 #include "snmppriv.h"
 
+#define	DEBUG_PARSE	0
+
 /* global context */
 struct snmp_client snmp_client;
 
@@ -474,7 +480,7 @@ table_check_response(struct tabwork *work, const struc
 		if (snmp_client.version == SNMP_V1 &&
 		    resp->error_status == SNMP_ERR_NOSUCHNAME &&
 		    resp->error_index ==
-		    (work->descr->last_change.len == 0) ? 1 : 2)
+		    ((work->descr->last_change.len == 0) ? 1 : 2))
 			/* EOT */
 			return (0);
 		/* Error */
@@ -924,7 +930,8 @@ open_client_udp(const char *host, const char *port)
 	/* open connection */
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_flags = AI_CANONNAME;
-	hints.ai_family = AF_INET;
+	hints.ai_family = snmp_client.trans == SNMP_TRANS_UDP ? AF_INET :
+	    AF_INET6;
 	hints.ai_socktype = SOCK_DGRAM;
 	hints.ai_protocol = 0;
 	error = getaddrinfo(snmp_client.chost, snmp_client.cport, &hints, &res0);
@@ -1068,6 +1075,7 @@ snmp_open(const char *host, const char *port, const ch
 	switch (snmp_client.trans) {
 
 	  case SNMP_TRANS_UDP:
+	  case SNMP_TRANS_UDP6:
 		if (open_client_udp(host, port) != 0)
 			return (-1);
 		break;
@@ -1866,99 +1874,425 @@ snmp_client_set_port(struct snmp_client *cl, const cha
 	return (0);
 }
 
-/*
- * parse a server specification
+static const char *const trans_list[] = {
+	[SNMP_TRANS_UDP]	= "udp::",
+	[SNMP_TRANS_LOC_DGRAM]	= "dgram::",
+	[SNMP_TRANS_LOC_STREAM]	= "stream::",
+	[SNMP_TRANS_UDP6]	= "udp6::",
+};
+
+/**
+ * Try to get a transport identifier which is a leading alphanumeric string
+ * terminated by a double colon. The string may not be empty. The transport
+ * identifier is optional. Unknown transport identifiers are reject.
+ * Be careful: a double colon can also occur in a numeric IPv6 address.
  *
- * [trans::][community@][server][:port]
+ * \param sc	client struct to set errors
+ * \param strp	possible start of transport; updated to point to
+ *		the next character to parse
+ *
+ * \return	transport identifier
  */
-int
-snmp_parse_server(struct snmp_client *sc, const char *str)
+static inline int
+get_transp(struct snmp_client *sc, const char **strp)
 {
-	const char *p, *s = str;
+	const char *p;
+	size_t i;
 
-	/* look for a double colon */
-	for (p = s; *p != '\0'; p++) {
-		if (*p == '\\' && p[1] != '\0') {
-			p++;
-			continue;
+	for (i = 0; i < nitems(trans_list); i++) {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202003311750.02VHoWCk065614>