The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=8a1576dc26b90706948061e5ed33f07a03a5899c

commit 8a1576dc26b90706948061e5ed33f07a03a5899c
Author:     Ishan Agrawal <[email protected]>
AuthorDate: 2026-07-04 03:40:31 +0000
Commit:     Kristof Provost <[email protected]>
CommitDate: 2026-07-05 14:03:20 +0000

    truss: track Netlink socket protocols
    
    Record the Netlink protocol associated with AF_NETLINK sockets when
    they are created and pass it to libsysdecode during message decoding.
    
    Use the protocol to distinguish between Generic Netlink and Route
    Netlink sockets, ensuring that Generic Netlink decoding is only
    performed for NETLINK_GENERIC sockets.
    
    Signed-off-by:  Ishan Agrawal <[email protected]>
    Reviewed by:    kp
    Sponsored-by :  Google LLC (GSoC 2026)
---
 lib/libsysdecode/netlink.c   |  2 +-
 lib/libsysdecode/sysdecode.h |  3 ++-
 usr.bin/truss/setup.c        |  1 +
 usr.bin/truss/syscalls.c     | 32 ++++++++++++++++++++------------
 usr.bin/truss/truss.h        |  1 +
 5 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/lib/libsysdecode/netlink.c b/lib/libsysdecode/netlink.c
index 2143a0d391a5..723272d3b8da 100644
--- a/lib/libsysdecode/netlink.c
+++ b/lib/libsysdecode/netlink.c
@@ -21,7 +21,7 @@
  * to fallback to a standard hex/string dump.
  */
 bool
-sysdecode_netlink(FILE *fp, const void *buf, size_t len)
+sysdecode_netlink(FILE *fp, const void *buf, size_t len, int protocol)
 {
        const struct nlmsghdr *nl = buf;
        size_t remaining = len;
diff --git a/lib/libsysdecode/sysdecode.h b/lib/libsysdecode/sysdecode.h
index 3675a582a9b8..bd38bb5bdc42 100644
--- a/lib/libsysdecode/sysdecode.h
+++ b/lib/libsysdecode/sysdecode.h
@@ -136,7 +136,8 @@ bool        sysdecode_wait4_options(FILE *_fp, int 
_options, int *_rem);
 bool   sysdecode_wait6_options(FILE *_fp, int _options, int *_rem);
 const char *sysdecode_whence(int _whence);
 bool   sysdecode_shmflags(FILE *_fp, int _flags, int *_rem);
-bool   sysdecode_netlink(FILE *_fp, const void *_buf, size_t _len);
+bool   sysdecode_netlink(FILE *_fp, const void *_buf, size_t _len,
+    int _protocol);
 
 #if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
 
diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c
index ecc4a1792144..d35b392aba1e 100644
--- a/usr.bin/truss/setup.c
+++ b/usr.bin/truss/setup.c
@@ -587,6 +587,7 @@ exit_syscall(struct trussinfo *info, struct ptrace_lwpinfo 
*pl)
 
                f->fd = (int)psr.sr_retval[0];
                f->domain = (int)t->cs.args[0];
+               f->protocol = (int)t->cs.args[2];
 
                LIST_INSERT_HEAD(&p->fdlist, f, entries);
        }
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index dbc621124071..a92c903dc691 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -1573,17 +1573,17 @@ user_ptr32_to_psaddr(int32_t user_pointer)
  * Check whether a file descriptor belongs to an AF_NETLINK socket
  * for the current traced process.
  */
-static bool
-is_netlink(struct trussinfo *trussinfo, int num_fd)
+static int
+get_netlink_protocol(struct trussinfo *trussinfo, int num_fd)
 {
        struct procinfo *p = trussinfo->curthread->proc;
        struct fd_domain *f;
 
        LIST_FOREACH(f, &p->fdlist, entries) {
                if (f->fd == num_fd && f->domain == AF_NETLINK)
-                       return (true);
+                       return (f->protocol);
        }
-       return (false);
+       return (-1);
 }
 
 #define NETLINK_MAX_DECODE 4096
@@ -1593,7 +1593,8 @@ is_netlink(struct trussinfo *trussinfo, int num_fd)
  * and attempt to decode and print it.
  */
 static bool
-print_netlink(FILE *fp, struct trussinfo *trussinfo, void *msg, size_t len)
+print_netlink(FILE *fp, struct trussinfo *trussinfo, void *msg, size_t len,
+    int protocol)
 {
        char *buf;
        pid_t pid = trussinfo->curthread->proc->pid;
@@ -1615,7 +1616,7 @@ print_netlink(FILE *fp, struct trussinfo *trussinfo, void 
*msg, size_t len)
                return (false);
        }
 
-       if (sysdecode_netlink(fp, buf, read_len)) {
+       if (sysdecode_netlink(fp, buf, read_len, protocol)) {
                success = true;
        }
        free(buf);
@@ -1690,12 +1691,18 @@ print_arg(struct syscall_arg *sc, syscallarg_t *args, 
syscallarg_t *retval,
        }
        case BinString: {
                if ((strcmp(decode->name, "sendto") == 0 ||
-                   strcmp(decode->name, "recvfrom") == 0) &&
-                   is_netlink(trussinfo, (int)args[0]))
-                       if (print_netlink(fp, trussinfo,
+                   strcmp(decode->name, "recvfrom") == 0)) {
+
+                       int protocol =
+                           get_netlink_protocol(trussinfo, (int)args[0]);
+
+                       if ((protocol != -1) &&
+                           print_netlink(fp, trussinfo,
                            (void *)args[sc->offset],
-                           (size_t)args[sc->offset + 1]))
+                           (size_t)args[sc->offset + 1],
+                           protocol))
                                break;
+               }
                /*
                 * Binary block of data that might have printable characters.
                 * XXX If type|OUT, assume that the length is the syscall's
@@ -2770,11 +2777,12 @@ print_arg(struct syscall_arg *sc, syscallarg_t *args, 
syscallarg_t *retval,
                print_sockaddr(fp, trussinfo, (uintptr_t)msghdr.msg_name, 
msghdr.msg_namelen);
                fprintf(fp, ",%d,", msghdr.msg_namelen);
                /* Attempt Netlink decode; fallback to standard iovec if it 
fails. */
-               if ((!is_netlink(trussinfo, (int)args[0])) ||
+               int protocol = get_netlink_protocol(trussinfo, (int)args[0]);
+               if ((protocol == -1) ||
                    (get_struct(pid, (uintptr_t)msghdr.msg_iov,
                    &iov, sizeof(iov)) == -1) ||
                    (!print_netlink(fp, trussinfo, (void *)iov.iov_base,
-                   (size_t)iov.iov_len))) {
+                   (size_t)iov.iov_len, protocol))) {
                        print_iovec(fp, trussinfo, (uintptr_t)msghdr.msg_iov,
                            msghdr.msg_iovlen);
                }
diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h
index 737ebc184806..077460fe4090 100644
--- a/usr.bin/truss/truss.h
+++ b/usr.bin/truss/truss.h
@@ -100,6 +100,7 @@ struct fd_domain
 
        int fd;
        int domain;
+       int protocol;
 };
 
 struct procinfo {

Reply via email to