The unix(4) man page incorrectly states: "A UNIX-domain socket supports two socket-level options for use with setsockopt(2) and getsockopt(2): [...]"
In reality, the protocol level when using these socket options must be 0, which is a magic number not really documented anywhere except the test suite. I think we should: (a) introduce SOL_LOCAL to sys/un.h as an alias for 0, as in FreeBSD (b) document it (c) update all in-tree users of Unix-domain socket options to use SOL_LOCAL instead of hardcoding 0
Index: lib/libc/net/getpeereid.c =================================================================== RCS file: /cvsroot/src/lib/libc/net/getpeereid.c,v retrieving revision 1.3 diff -u -r1.3 getpeereid.c --- lib/libc/net/getpeereid.c 16 Feb 2018 19:21:49 -0000 1.3 +++ lib/libc/net/getpeereid.c 5 Aug 2021 13:19:15 -0000 @@ -57,7 +57,7 @@ } len = sizeof(cred); - if (getsockopt(s, 0, LOCAL_PEEREID, &cred, &len) == -1) + if (getsockopt(s, SOL_LOCAL, LOCAL_PEEREID, &cred, &len) == -1) return -1; if (euid != NULL) Index: lib/libc/rpc/svc_vc.c =================================================================== RCS file: /cvsroot/src/lib/libc/rpc/svc_vc.c,v retrieving revision 1.34 diff -u -r1.34 svc_vc.c --- lib/libc/rpc/svc_vc.c 10 Nov 2015 20:56:20 -0000 1.34 +++ lib/libc/rpc/svc_vc.c 5 Aug 2021 13:19:15 -0000 @@ -178,8 +178,8 @@ * We want to be able to check credentials on local sockets. */ if (sslocal.ss_family == AF_LOCAL) - if (setsockopt(fd, 0, LOCAL_CREDS, &one, (socklen_t)sizeof one) - == -1) + if (setsockopt(fd, SOL_LOCAL, LOCAL_CREDS, &one, + (socklen_t)sizeof one) == -1) goto cleanup_svc_vc_create; xprt->xp_ltaddr.maxlen = xprt->xp_ltaddr.len = sslocal.ss_len; Index: lib/libperfuse/perfuse.c =================================================================== RCS file: /cvsroot/src/lib/libperfuse/perfuse.c,v retrieving revision 1.42 diff -u -r1.42 perfuse.c --- lib/libperfuse/perfuse.c 17 Apr 2019 12:30:51 -0000 1.42 +++ lib/libperfuse/perfuse.c 5 Aug 2021 13:19:15 -0000 @@ -255,7 +255,7 @@ */ opt = 1; optlen = sizeof(opt); - if (setsockopt(sv[1], 0, LOCAL_CREDS, &opt, optlen) != 0) + if (setsockopt(sv[1], SOL_LOCAL, LOCAL_CREDS, &opt, optlen) != 0) DWARN("%s: setsockopt LOCAL_CREDS failed", __func__); (void)sprintf(fdstr, "%d", sv[1]); Index: regress/sys/kern/unfdpass/unfdpass.c =================================================================== RCS file: /cvsroot/src/regress/sys/kern/unfdpass/unfdpass.c,v retrieving revision 1.11 diff -u -r1.11 unfdpass.c --- regress/sys/kern/unfdpass/unfdpass.c 10 Jan 2017 22:37:44 -0000 1.11 +++ regress/sys/kern/unfdpass/unfdpass.c 5 Aug 2021 13:19:15 -0000 @@ -168,7 +168,7 @@ sun.sun_len = SUN_LEN(&sun); i = 1; - if (setsockopt(listensock, 0, LOCAL_CREDS, &i, sizeof(i)) == -1) + if (setsockopt(listensock, SOL_LOCAL, LOCAL_CREDS, &i, sizeof(i)) == -1) err(1, "setsockopt"); if (bind(listensock, (struct sockaddr *)&sun, sizeof(sun)) == -1) Index: share/man/man4/unix.4 =================================================================== RCS file: /cvsroot/src/share/man/man4/unix.4,v retrieving revision 1.26 diff -u -r1.26 unix.4 --- share/man/man4/unix.4 3 Jul 2017 21:30:58 -0000 1.26 +++ share/man/man4/unix.4 5 Aug 2021 13:19:16 -0000 @@ -173,8 +173,8 @@ when the destination socket is closed. .Pp A UNIX-domain socket supports two -.Tn socket-level -options for use with +.Dv SOL_LOCAL +level options for use with .Xr setsockopt 2 and .Xr getsockopt 2 : Index: sys/kern/uipc_usrreq.c =================================================================== RCS file: /cvsroot/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.200 diff -u -r1.200 uipc_usrreq.c --- sys/kern/uipc_usrreq.c 6 Nov 2020 14:50:13 -0000 1.200 +++ sys/kern/uipc_usrreq.c 5 Aug 2021 13:19:20 -0000 @@ -608,7 +608,7 @@ KASSERT(solocked(so)); - if (sopt->sopt_level != 0) { + if (sopt->sopt_level != SOL_LOCAL) { error = ENOPROTOOPT; } else switch (op) { Index: sys/sys/un.h =================================================================== RCS file: /cvsroot/src/sys/sys/un.h,v retrieving revision 1.59 diff -u -r1.59 un.h --- sys/sys/un.h 6 Nov 2020 14:50:13 -0000 1.59 +++ sys/sys/un.h 5 Aug 2021 13:19:20 -0000 @@ -56,6 +56,7 @@ * Socket options for UNIX IPC domain. */ #if defined(_NETBSD_SOURCE) +#define SOL_LOCAL 0 /* options level for get/setsockopt */ #define LOCAL_OCREDS 0x0001 /* pass credentials to receiver */ #define LOCAL_CONNWAIT 0x0002 /* connects block until accepted */ #define LOCAL_PEEREID 0x0003 /* get peer identification */ Index: tests/net/net/t_unix.c =================================================================== RCS file: /cvsroot/src/tests/net/net/t_unix.c,v retrieving revision 1.24 diff -u -r1.24 t_unix.c --- tests/net/net/t_unix.c 28 Aug 2020 14:18:29 -0000 1.24 +++ tests/net/net/t_unix.c 5 Aug 2021 13:19:20 -0000 @@ -147,7 +147,7 @@ # define LOCAL_PEEREID SO_PEERCRED # define LEVEL SOL_SOCKET #else -# define LEVEL 0 +# define LEVEL SOL_LOCAL #endif #ifdef LOCAL_PEEREID Index: usr.sbin/perfused/msg.c =================================================================== RCS file: /cvsroot/src/usr.sbin/perfused/msg.c,v retrieving revision 1.25 diff -u -r1.25 msg.c --- usr.sbin/perfused/msg.c 17 Apr 2019 12:30:51 -0000 1.25 +++ usr.sbin/perfused/msg.c 5 Aug 2021 13:19:21 -0000 @@ -92,7 +92,7 @@ * Request peer credentials */ opt = 1; - if (setsockopt(s, 0, LOCAL_CREDS, &opt, sizeof(opt)) != 0) + if (setsockopt(s, SOL_LOCAL, LOCAL_CREDS, &opt, sizeof(opt)) != 0) DWARN("%s: setsockopt LOCAL_CREDS failed", __func__); if (bind(s, sa, (socklen_t )sun.sun_len) == -1) Index: usr.sbin/perfused/perfused.c =================================================================== RCS file: /cvsroot/src/usr.sbin/perfused/perfused.c,v retrieving revision 1.25 diff -u -r1.25 perfused.c --- usr.sbin/perfused/perfused.c 12 Dec 2014 09:58:39 -0000 1.25 +++ usr.sbin/perfused/perfused.c 5 Aug 2021 13:19:21 -0000 @@ -125,7 +125,7 @@ * We do not need peer creds beyond this point */ opt = 0; - if (setsockopt(fd, 0, LOCAL_CREDS, &opt, sizeof(opt)) != 0) + if (setsockopt(fd, SOL_LOCAL, LOCAL_CREDS, &opt, sizeof(opt)) != 0) DWARN("%s: setsockopt LOCAL_CREDS failed", __func__); #ifdef PERFUSE_DEBUG Index: usr.sbin/sdpd/server.c =================================================================== RCS file: /cvsroot/src/usr.sbin/sdpd/server.c,v retrieving revision 1.11 diff -u -r1.11 server.c --- usr.sbin/sdpd/server.c 1 Mar 2012 22:38:31 -0000 1.11 +++ usr.sbin/sdpd/server.c 5 Aug 2021 13:19:21 -0000 @@ -165,7 +165,7 @@ } opt = 1; - if (setsockopt(fd, 0, LOCAL_CREDS, &opt, sizeof(opt)) == -1) + if (setsockopt(fd, SOL_LOCAL, LOCAL_CREDS, &opt, sizeof(opt)) == -1) log_crit("Warning: No credential checks on control socket"); memset(&un, 0, sizeof(un));