So apparently I use IPv6 more often than the end-users. This diff allows us to actually skip the {ud,tc}p6 prefix if we actually present an IPv6 address as described in the manpage and done by net-snmp.
While here I also made it possible possible to do a retry if IPv6-address:port fails by pasting the port back to the hostname. This allows us to do snmp walk ::1, similar to what net-snmp does. Not that with this we actually comform better to what snmpcmd(1) describes in their manpage, which apparently doesn't support ::1:161, but only [::1]:161. OK? martijn@ Index: snmpc.c =================================================================== RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v retrieving revision 1.17 diff -u -p -r1.17 snmpc.c --- snmpc.c 26 Oct 2019 19:34:15 -0000 1.17 +++ snmpc.c 9 Jan 2020 16:30:54 -0000 @@ -918,7 +918,6 @@ snmpc_parseagent(char *agent, char *defa hints.ai_socktype = SOCK_STREAM; } else if (strcasecmp(specifier, "unix") == 0) { hints.ai_family = AF_UNIX; - hints.ai_socktype = SOCK_STREAM; hints.ai_addr = (struct sockaddr *)&saddr; hints.ai_addrlen = sizeof(saddr); saddr.sun_len = sizeof(saddr); @@ -928,45 +927,51 @@ snmpc_parseagent(char *agent, char *defa errx(1, "Hostname path too long"); ai = &hints; } else { - port = hostname; + *--hostname = ':'; hostname = specifier; - specifier = NULL; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; - } - if (port == NULL) { - if (hints.ai_family == AF_INET) { - if ((port = strchr(hostname, ':')) != NULL) - *port++ = '\0'; - } else if (hints.ai_family == AF_INET6) { - if (hostname[0] == '[') { - hostname++; - if ((port = strchr(hostname, ']')) == NULL) - errx(1, "invalid agent"); - *port++ = '\0'; - if (port[0] == ':') - *port++ = '\0'; - else - port = NULL; - } else { - if ((port = strrchr(hostname, ':')) == NULL) - errx(1, "invalid agent"); - *port++ = '\0'; - } - } } } else { hostname = specifier; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; + } + + if (hints.ai_family == AF_INET) { + if ((port = strchr(hostname, ':')) != NULL) + *port++ = '\0'; + } else if (hints.ai_family == AF_INET6 || hints.ai_family == 0) { + if (hostname[0] == '[') { + hints.ai_family = AF_INET6; + hostname++; + if ((port = strchr(hostname, ']')) == NULL) + errx(1, "invalid agent"); + *port++ = '\0'; + if (port[0] == ':') + *port++ = '\0'; + else if (port[0] == '\0') + port = NULL; + else + errx(1, "invalid agent"); + } else { + if ((port = strrchr(hostname, ':')) == NULL) + errx(1, "invalid agent"); + *port++ = '\0'; + } } if (hints.ai_family != AF_UNIX) { + if (hints.ai_socktype == 0) + hints.ai_socktype = SOCK_DGRAM; if (port == NULL) port = defaultport; error = getaddrinfo(hostname, port, &hints, &ai0); - if (error) - errx(1, "%s", gai_strerror(error)); + if (error) { + if (error != EAI_NODATA && port != defaultport) + errx(1, "%s", gai_strerror(error)); + *--port = ':'; + error = getaddrinfo(hostname, defaultport, &hints, + &ai0); + if (error) + errx(1, "%s", gai_strerror(error)); + } s = -1; for (ai = ai0; ai != NULL; ai = ai->ai_next) { if ((s = socket(ai->ai_family, ai->ai_socktype, @@ -975,8 +980,7 @@ snmpc_parseagent(char *agent, char *defa break; } } else - s = socket(hints.ai_family, hints.ai_socktype, - hints.ai_protocol); + s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) err(1, "socket");