From owner-svn-src-vendor@freebsd.org Tue Mar 31 17:51:18 2020 Return-Path: Delivered-To: svn-src-vendor@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 1D094265560; Tue, 31 Mar 2020 17:51:18 +0000 (UTC) (envelope-from harti@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48sH1w6Jlqz3PDM; Tue, 31 Mar 2020 17:51:16 +0000 (UTC) (envelope-from harti@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1E6EBDE51; Tue, 31 Mar 2020 17:50:34 +0000 (UTC) (envelope-from harti@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 02VHoXTN065621; Tue, 31 Mar 2020 17:50:33 GMT (envelope-from harti@FreeBSD.org) Received: (from harti@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 02VHoWCk065614; Tue, 31 Mar 2020 17:50:32 GMT (envelope-from harti@FreeBSD.org) Message-Id: <202003311750.02VHoWCk065614@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: harti set sender to harti@FreeBSD.org using -f From: Hartmut Brandt Date: Tue, 31 Mar 2020 17:50:32 +0000 (UTC) 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 X-SVN-Group: vendor X-SVN-Commit-Author: harti X-SVN-Commit-Paths: in vendor/bsnmp/dist: . config gensnmpdef gensnmptree lib snmp_mibII snmp_ntp snmp_target snmp_usm snmp_vacm snmpd tests X-SVN-Commit-Revision: 359490 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Mar 2020 17:51:18 -0000 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, ""); } 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 +#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 +#include #include #include #include #include +#include +#include #include #include #include @@ -58,12 +60,16 @@ #include #endif +#include + #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 ***