From owner-svn-src-all@freebsd.org Wed May 1 09:05:50 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0245A1585511; Wed, 1 May 2019 09:05:50 +0000 (UTC) (envelope-from ae@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 944FA6CE27; Wed, 1 May 2019 09:05:49 +0000 (UTC) (envelope-from ae@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 677671F257; Wed, 1 May 2019 09:05:49 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x4195npX072168; Wed, 1 May 2019 09:05:49 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4195nbh072167; Wed, 1 May 2019 09:05:49 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201905010905.x4195nbh072167@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Wed, 1 May 2019 09:05:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r346988 - stable/12/contrib/bsnmp/lib X-SVN-Group: stable-12 X-SVN-Commit-Author: ae X-SVN-Commit-Paths: stable/12/contrib/bsnmp/lib X-SVN-Commit-Revision: 346988 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 944FA6CE27 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.98)[-0.975,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 May 2019 09:05:50 -0000 Author: ae Date: Wed May 1 09:05:48 2019 New Revision: 346988 URL: https://svnweb.freebsd.org/changeset/base/346988 Log: MFC r345843: Follow the declared behaviour that specifies server string format in bsnmpclient(3). snmp_parse_server() function accepts string where some fields can be omitted: [trans::][community@][server][:port] "trans" field can be "udp", "udp6", "dgram" and "stream". "community" can be empty string, if it is omitted, the default value will be used. For read_community it is "public", for write_comminity it is "private". "server" field can be hostname, IPv4 address or IPv6 address. IPv6 address should be specified in brackets "[]". If port is omitted, the default value "snmp" will be used for "udp" and "udp6" transports. So, now for bsnmpget(1) and bsnmwalk(1) it is not required to specify all fields in argument of '-s' option. E.g. # bsnmpget -s 127.1 sysName.0 # bsnmpget -s "udp::127.1" sysName.0 # bsnmpget -s "udp::public@127.1" sysName.0 # bsnmpget -s "udp::public@127.1:161" sysName.0 # bsnmpget -s "udp::[::1]" sysName.0 # bsnmpget -s "udp6::[::1]" sysName.0 # bsnmpget -s "[fe80::1%lo0]" sysName.0 PR: 236664 Reported by: olivier Modified: stable/12/contrib/bsnmp/lib/snmpclient.c Directory Properties: stable/12/ (props changed) Modified: stable/12/contrib/bsnmp/lib/snmpclient.c ============================================================================== --- stable/12/contrib/bsnmp/lib/snmpclient.c Wed May 1 09:04:14 2019 (r346987) +++ stable/12/contrib/bsnmp/lib/snmpclient.c Wed May 1 09:05:48 2019 (r346988) @@ -1874,38 +1874,47 @@ snmp_client_set_port(struct snmp_client *cl, const cha return (0); } +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 - * (starting with '_' or a letter and including also '_') terminated by - * a double colon. The string may not be empty. The transport identifier - * is optional. + * terminated by a double colon. The string may not be empty. The transport + * identifier is optional. * * \param sc client struct to set errors * \param strp possible start of transport; updated to point to * the next character to parse * - * \return end of transport; equals *strp if there is none; NULL if there - * was an error + * \return transport identifier */ -static inline const char * +static inline int get_transp(struct snmp_client *sc, const char **strp) { - const char *p = *strp; + const char *p; + size_t i; - if (isascii(*p) && (isalpha(*p) || *p == '_')) { - p++; - while (isascii(*p) && (isalnum(*p) || *p == '_')) - p++; - if (p[0] == ':' && p[1] == ':') { - *strp = p + 2; - return (p); + for (i = 0; i < nitems(trans_list); i++) { + if (trans_list[i] == NULL || *trans_list[i] == '\0') + continue; + p = strstr(*strp, trans_list[i]); + if (p == *strp) { + *strp += strlen(trans_list[i]); + return ((int)i); } } + + p = *strp; if (p[0] == ':' && p[1] == ':') { seterr(sc, "empty transport specifier"); - return (NULL); + return (-1); } - return (*strp); + /* by default assume UDP */ + return (SNMP_TRANS_UDP); } /** @@ -2143,24 +2152,13 @@ save_str(struct snmp_client *sc, const char *const s[2 int snmp_parse_server(struct snmp_client *sc, const char *str) { -#if DEBUG_PARSE const char *const orig = str; -#endif - - const char *const trans_list[] = { - [SNMP_TRANS_UDP] = "udp", - [SNMP_TRANS_LOC_DGRAM] = "dgram", - [SNMP_TRANS_LOC_STREAM] = "stream", - [SNMP_TRANS_UDP6] = "udp6", - }; - /* parse input */ - const char *const transp[2] = { - str, - get_transp(sc, &str), - }; - if (transp[1] == NULL) + int i, trans = get_transp(sc, &str); + if (trans < 0) return (-1); + /* choose automatically */ + i = orig == str ? -1: trans; const char *const comm[2] = { str, @@ -2206,7 +2204,7 @@ snmp_parse_server(struct snmp_client *sc, const char * } #if DEBUG_PARSE - printf("transp: %zu %zu\n", transp[0] - orig, transp[1] - orig); + printf("transp: %u\n", trans); printf("comm: %zu %zu\n", comm[0] - orig, comm[1] - orig); printf("ipv6: %zu %zu\n", ipv6[0] - orig, ipv6[1] - orig); printf("ipv4: %zu %zu\n", ipv4[0] - orig, ipv4[1] - orig); @@ -2215,69 +2213,73 @@ snmp_parse_server(struct snmp_client *sc, const char * #endif /* analyse and allocate */ - int i = -1; - if (transp[0] != transp[1]) { - for (i = 0; i < (int)nitems(trans_list); i++) { - if (trans_list[i] != NULL && - strlen(trans_list[i]) == (size_t)(transp[1] - - transp[0]) && !strncmp(trans_list[i], transp[0], - transp[1] - transp[0])) - break; - } - - if (i == (int)nitems(trans_list)) { - seterr(sc, "unknown transport specifier '%.*s'", - transp[1] - transp[0], transp[0]); - return (-1); - } - } - char *chost; if (ipv6[0] != ipv6[1]) { if ((chost = save_str(sc, ipv6)) == NULL) return (-1); - if (i == -1) - i = SNMP_TRANS_UDP6; + if (i == -1 || trans == SNMP_TRANS_UDP) + trans = SNMP_TRANS_UDP6; } else if (ipv4[0] != ipv4[1]) { if ((chost = save_str(sc, ipv4)) == NULL) return (-1); if (i == -1) - i = SNMP_TRANS_UDP; + trans = SNMP_TRANS_UDP; } else { if ((chost = save_str(sc, host)) == NULL) return (-1); if (i == -1) { - /* Default transport is UDP unless the host contains - * a slash in which case we default to DGRAM. */ - i = SNMP_TRANS_UDP; + /* + * Default transport is UDP unless the host contains + * a slash in which case we default to DGRAM. + */ for (const char *p = host[0]; p < host[1]; p++) if (*p == '/') { - i = SNMP_TRANS_LOC_DGRAM; + trans = SNMP_TRANS_LOC_DGRAM; break; } } } - char *cport = save_str(sc, port); + char *cport; + + if (port[0] == port[1] && ( + trans == SNMP_TRANS_UDP || trans == SNMP_TRANS_UDP6)) { + /* If port was not specified, use "snmp" name by default */ + cport = strdup("snmp"); + } else + cport = save_str(sc, port); + if (cport == NULL) { free(chost); return (-1); } /* commit */ - sc->trans = i; + sc->trans = trans; + /* + * If community string was specified and it is empty, overwrite it. + * If it was not specified, use default. + */ + if (comm[0] != comm[1] || strrchr(comm[0], '@') != NULL) { + strncpy(sc->read_community, comm[0], comm[1] - comm[0]); + sc->read_community[comm[1] - comm[0]] = '\0'; + strncpy(sc->write_community, comm[0], comm[1] - comm[0]); + sc->write_community[comm[1] - comm[0]] = '\0'; + } - strncpy(sc->read_community, comm[0], comm[1] - comm[0]); - sc->read_community[comm[1] - comm[0]] = '\0'; - strncpy(sc->write_community, comm[0], comm[1] - comm[0]); - sc->write_community[comm[1] - comm[0]] = '\0'; - free(sc->chost); sc->chost = chost; free(sc->cport); sc->cport = cport; +#if DEBUG_PARSE + printf("Committed values:\n"); + printf("trans: %u\n", sc->trans); + printf("comm: '%s'/'%s'\n", sc->read_community, sc->write_community); + printf("host: '%s'\n", sc->chost); + printf("port: '%s'\n", sc->cport); +#endif return (0); }