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");
 

Reply via email to