As a precedent, nc has a conversational, specific style of error
reporting when a socketopt fails. With the IPv4/6-specific options, we
refactored the code to the point that the error messages are less
specific and maybe misleading (e.g. setting ToS on an IPv6 socket).

This patch makes the per-address-family options instead have specific
error reporting, and IMO simplifies things a bit as well.

I'll admit it I have an ulterior motive here too. Structuring code like
this also makes it easier to add #ifdefs for non-existent sockopts for
the portable version packaged with LibreSSL.

diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c
index c9c5ebe..f5dfe18 100644
--- a/src/usr.bin/nc/netcat.c
+++ b/src/usr.bin/nc/netcat.c
@@ -1412,18 +1412,13 @@ set_common_sockopts(int s, int af)
                        err(1, NULL);
        }
        if (Tflag != -1) {
-               int proto, option;
-
-               if (af == AF_INET6) {
-                       proto = IPPROTO_IPV6;
-                       option = IPV6_TCLASS;
-               } else {
-                       proto = IPPROTO_IP;
-                       option = IP_TOS;
-               }
-
-               if (setsockopt(s, proto, option, &Tflag, sizeof(Tflag)) == -1)
+               if (af == AF_INET && setsockopt(s, IPPROTO_IP,
+                   IP_TOS, &Tflag, sizeof(Tflag)) == -1)
                        err(1, "set IP ToS");
+
+               else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
+                   IPV6_TCLASS, &Tflag, sizeof(Tflag)) == -1)
+                       err(1, "set IPv6 traffic class");
        }
        if (Iflag) {
                if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
@@ -1435,28 +1430,25 @@ set_common_sockopts(int s, int af)
                    &Oflag, sizeof(Oflag)) == -1)
                        err(1, "set TCP send buffer size");
        }
-       if (ttl != -1 || minttl != -1) {
-               int proto, in_ttl_opt, out_ttl_opt;
-               switch (af) {
-               case AF_INET:
-                       proto = IPPROTO_IP;
-                       in_ttl_opt = IP_MINTTL;
-                       out_ttl_opt = IP_TTL;
-                       break;
-               case AF_INET6:
-                       proto = IPPROTO_IPV6;
-                       in_ttl_opt = IPV6_MINHOPCOUNT;
-                       out_ttl_opt = IPV6_UNICAST_HOPS;
-                       break;
-               default:
-                       errx(1, "unknown address family: %d", af);
-               }
-               if (minttl != -1 && setsockopt(s, proto, in_ttl_opt,
-                   &minttl, sizeof(minttl)))
-                       err(1, "setsockopt minttl");
-               if (ttl != -1 && setsockopt(s, proto, out_ttl_opt,
-                   &ttl, sizeof(ttl)))
-                       err(1, "setsockopt ttl");
+
+       if (ttl != -1) {
+               if (af == AF_INET && setsockopt(s, IPPROTO_IP,
+                   IP_TTL, &ttl, sizeof(ttl)))
+                       err(1, "set IP TTL");
+
+               else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
+                   IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)))
+                       err(1, "set IPv6 unicast hops");
+       }
+
+       if (minttl != -1) {
+               if (af == AF_INET && setsockopt(s, IPPROTO_IP,
+                   IP_MINTTL, &minttl, sizeof(minttl)))
+                       err(1, "set IP min TTL");
+
+               else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
+                   IPV6_MINHOPCOUNT, &minttl, sizeof(minttl)))
+                       err(1, "set IPv6 min hop count");
        }
 }
 

Reply via email to