Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148927680
D51072.1789187603.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D51072.1789187603.diff
View Options
diff --git a/contrib/bsnmp/lib/snmpclient.c b/contrib/bsnmp/lib/snmpclient.c
--- a/contrib/bsnmp/lib/snmpclient.c
+++ b/contrib/bsnmp/lib/snmpclient.c
@@ -1926,70 +1926,64 @@
* community strings are legal.
*
* \param sc client struct to set errors
- * \param strp possible start of community; updated to the point to
- * the next character to parse
+ * \param comm possible start of community; updated to start & end
*
- * \return end of community; equals *strp if there is none; NULL if there
- * was an error
+ * \return the next character to parse; NULL if there was an error
*/
static inline const char *
-get_comm(struct snmp_client *sc, const char **strp)
+get_comm(struct snmp_client *sc, const char *comm[2])
{
- const char *p = strrchr(*strp, '@');
+ const char *p = strrchr(comm[0], '@');
if (p == NULL)
/* no community string */
- return (*strp);
+ return (comm[1] = comm[0]);
- if (p - *strp > SNMP_COMMUNITY_MAXLEN) {
+ if (p - comm[0] > SNMP_COMMUNITY_MAXLEN) {
seterr(sc, "community string too long '%.*s'",
- p - *strp, *strp);
+ p - comm[0], comm[0]);
return (NULL);
}
- *strp = p + 1;
- return (p);
+ return ((comm[1] = p) + 1);
}
/**
* Try to get an IPv6 address. This starts with an [ and should end with an ]
* and everything between should be not longer than INET6_ADDRSTRLEN and
- * parseable by inet_pton().
+ * parseable by getaddrinfo().
*
* \param sc client struct to set errors
- * \param strp possible start of IPv6 address (the '['); updated to point to
- * the next character to parse (the one after the closing ']')
+ * \param ipv6 possible start of IPv6 address (the '['); updated to actual
+ * start (one after '[') and actual end (the '[' itself)
*
- * \return end of address (equals *strp + 1 if there is none) or NULL
- * on errors
+ * \return the next character to parse (the one after the closing ']')
+ * or NULL on errors
*/
static inline const char *
-get_ipv6(struct snmp_client *sc, const char **strp)
+get_ipv6(struct snmp_client *sc, const char *ipv6[2])
{
- char str[INET6_ADDRSTRLEN + IF_NAMESIZE];
+ char str[INET6_ADDRSTRLEN];
+ const char *p;
struct addrinfo hints, *res;
int error;
- if (**strp != '[')
- return (*strp + 1);
+ if (ipv6[0][0] != '[')
+ return (ipv6[1] = ipv6[0]);
- const char *p = *strp + 1;
- while (*p != ']' ) {
- if (*p == '\0') {
- seterr(sc, "unterminated IPv6 address '%.*s'",
- p - *strp, *strp);
- return (NULL);
- }
- p++;
+ if ((p = strchr(++(ipv6[0]), ']')) == NULL) {
+ seterr(sc, "unterminated IPv6 address '%s'", ipv6[0]);
+ return (NULL);
}
- if (p - *strp > INET6_ADDRSTRLEN + IF_NAMESIZE) {
- seterr(sc, "IPv6 address too long '%.*s'", p - *strp, *strp);
+ if ((size_t)(p - ipv6[0]) >= sizeof(str)) {
+ seterr(sc, "IPv6 address too long '%.*s'",
+ p - ipv6[0], ipv6[0]);
return (NULL);
}
- strncpy(str, *strp + 1, p - (*strp + 1));
- str[p - (*strp + 1)] = '\0';
+ strncpy(str, ipv6[0], p - ipv6[0]);
+ str[p - ipv6[0]] = '\0';
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME | AI_NUMERICHOST;
@@ -2002,8 +1996,7 @@
return (NULL);
}
freeaddrinfo(res);
- *strp = p + 1;
- return (p);
+ return ((ipv6[1] = p) + 1);
}
/**
@@ -2012,30 +2005,29 @@
* inet_aton().
*
* \param sc client struct to set errors
- * \param strp possible start of IPv4 address; updated to point to the
- * next character to parse
+ * \param ipv4 possible start of IPv4 address; updated to start & end
*
- * \return end of address (equals *strp if there is none) or NULL
- * on errors
+ * \return the next character to parse; or NULL on errors
*/
static inline const char *
-get_ipv4(struct snmp_client *sc, const char **strp)
+get_ipv4(struct snmp_client *sc, const char *ipv4[2])
{
- const char *p = *strp;
+ char str[INET_ADDRSTRLEN];
+ const char *p = ipv4[0];
while (isascii(*p) && (isdigit(*p) || *p == '.'))
p++;
- if (p - *strp > INET_ADDRSTRLEN) {
- seterr(sc, "IPv4 address too long '%.*s'", p - *strp, *strp);
+ if ((size_t)(p - ipv4[0]) >= sizeof(str)) {
+ seterr(sc, "IPv4 address too long '%.*s'",
+ p - ipv4[0], ipv4[0]);
return (NULL);
}
- if (*strp == p)
- return *strp;
+ if (p == ipv4[0])
+ return (ipv4[1] = ipv4[0]);
- char str[INET_ADDRSTRLEN + 1];
- strncpy(str, *strp, p - *strp);
- str[p - *strp] = '\0';
+ strncpy(str, ipv4[0], p - ipv4[0]);
+ str[p - ipv4[0]] = '\0';
struct in_addr addr;
if (inet_aton(str, &addr) != 1) {
@@ -2043,8 +2035,7 @@
return (NULL);
}
- *strp = p;
- return (p);
+ return (ipv4[1] = p);
}
/**
@@ -2052,24 +2043,19 @@
* the last colon (if any). There is no length restriction.
*
* \param sc client struct to set errors
- * \param strp possible start of hostname; updated to point to the next
- * character to parse (the trailing NUL character or the last
- * colon)
+ * \param host possible start of hostname; start & end updated
*
- * \return end of address (equals *strp if there is none)
+ * \return next character to parse (semicolon or NUL)
*/
static inline const char *
-get_host(struct snmp_client *sc __unused, const char **strp)
+get_host(struct snmp_client *sc __unused, const char *host[2])
{
- const char *p = strrchr(*strp, ':');
+ const char *p = strrchr(host[0], ':');
- if (p == NULL) {
- *strp += strlen(*strp);
- return (*strp);
- }
+ if (p == NULL)
+ return (host[1] = host[0] + strlen(host[0]));
- *strp = p;
- return (p);
+ return (host[1] = p);
}
/**
@@ -2077,25 +2063,24 @@
* of string. The port number must not be empty.
*
* \param sc client struct to set errors
- * \param strp possible start of port specification; if this points to a
+ * \param port possible start of port specification; if this points to a
* colon there is a port specification
*
* \return end of port number (equals *strp if there is none); NULL
* if there is no port number
*/
static inline const char *
-get_port(struct snmp_client *sc, const char **strp)
+get_port(struct snmp_client *sc, const char *port[2])
{
- if (**strp != ':')
- return (*strp + 1);
+ if (*port[0] != ':')
+ return (port[1] = port[0]);
- if ((*strp)[1] == '\0') {
+ if (port[0][1] == '\0') {
seterr(sc, "empty port name");
return (NULL);
}
- *strp += strlen(*strp);
- return (*strp);
+ return (port[1] = ++(port[0]) + strlen(port[0]));
}
/**
@@ -2156,6 +2141,7 @@
snmp_parse_server(struct snmp_client *sc, const char *str)
{
const char *const orig = str;
+ const char *comm[2], *ipv6[2], *ipv4[2], *host[2], *port[2];
/* parse input */
int def_trans = 0, trans = get_transp(sc, &str);
@@ -2165,42 +2151,32 @@
if (orig == str)
def_trans = 1;
- const char *const comm[2] = {
- str,
- get_comm(sc, &str),
- };
- if (comm[1] == NULL)
+ comm[0] = str;
+ if ((str = get_comm(sc, comm)) == NULL)
return (-1);
- const char *const ipv6[2] = {
- str + 1,
- get_ipv6(sc, &str),
- };
- if (ipv6[1] == NULL)
+ ipv6[0] = str;
+ if ((str = get_ipv6(sc, ipv6)) == NULL)
return (-1);
- const char *ipv4[2] = {
- str,
- str,
- };
-
- const char *host[2] = {
- str,
- str,
- };
-
if (ipv6[0] == ipv6[1]) {
- ipv4[1] = get_ipv4(sc, &str);
+ ipv4[0] = str;
+ if ((str = get_ipv4(sc, ipv4)) == NULL) {
+ /* This failure isn't fatal: restore str. */
+ str = ipv4[0];
+ ipv4[0] = ipv4[1] = NULL;
+ }
- if (ipv4[0] == ipv4[1])
- host[1] = get_host(sc, &str);
- }
+ if (ipv4[0] == ipv4[1]) {
+ host[0] = str;
+ str = get_host(sc, host);
+ } else
+ host[0] = host[1] = NULL;
+ } else
+ ipv4[0] = ipv4[1] = host[0] = host[1] = NULL;
- const char *port[2] = {
- str + 1,
- get_port(sc, &str),
- };
- if (port[1] == NULL)
+ port[0] = str;
+ if ((str = get_port(sc, port)) == NULL)
return (-1);
if (*str != '\0') {
@@ -2231,7 +2207,7 @@
return (-1);
if (def_trans)
trans = SNMP_TRANS_UDP;
- } else {
+ } else if (host[0] != host[1]) {
if ((chost = save_str(sc, host)) == NULL)
return (-1);
@@ -2246,6 +2222,17 @@
break;
}
}
+ } else switch (trans) {
+ case SNMP_TRANS_UDP:
+ case SNMP_TRANS_UDP6:
+ if ((chost = strdup(DEFAULT_HOST)) == NULL)
+ return (-1);
+ break;
+ case SNMP_TRANS_LOC_DGRAM:
+ case SNMP_TRANS_LOC_STREAM:
+ if ((chost = strdup(SNMP_DEFAULT_LOCAL)) == NULL)
+ return (-1);
+ break;
}
char *cport;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Sep 12, 4:33 AM (16 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29566997
Default Alt Text
D51072.1789187603.diff (8 KB)
Attached To
Mode
D51072: libbsnmp: make snmp_parse_server() more robust when lacking info
Attached
Detach File
Event Timeline
Log In to Comment