]> git.ipfire.org Git - telemetry.git/commitdiff
daemon: Add a handler to fetch a nl80211 socket
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 30 Mar 2026 14:26:36 +0000 (14:26 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 30 Mar 2026 14:35:54 +0000 (14:35 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/daemon/daemon.c
src/daemon/daemon.h

index 2d116a5b63845e1740212ba7e5512ef24703b1af..929199789ed94697424d777c9b2e66530ff684d7 100644 (file)
 #include <systemd/sd-event.h>
 
 #ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_GENL
+#  include <netlink/genl/ctrl.h>
+#  include <netlink/genl/genl.h>
+# endif
 # ifdef HAVE_LIBNL3_ROUTE
 #  include <netlink/route/route.h>
 #  include <netlink/socket.h>
@@ -82,11 +86,17 @@ struct td_daemon {
 
        // Netlink Sockets
 #ifdef HAVE_LIBNL3
-# ifdef HAVE_LIBNL3_ROUTE
        struct {
+               // 802.11
+# ifdef HAVE_LIBNL3_GENL
+               struct nl_sock* nl80211;
+# endif /* HAVE_LIBNL3_GENL */
+
+               // Route
+# ifdef HAVE_LIBNL3_ROUTE
                struct nl_sock* route;
-       } nl_sockets;
 # endif /* HAVE_LIBNL3_ROUTE */
+       } nl_sockets;
 #endif /* HAVE_LIBNL3 */
 };
 
@@ -279,6 +289,10 @@ static int td_daemon_setup_udev(td_daemon* self) {
 static void td_daemon_free(td_daemon* self) {
        // Free Netlink Sockets
 #ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_GENL
+       if (self->nl_sockets.nl80211)
+               nl_socket_free(self->nl_sockets.nl80211);
+# endif /* HAVE_LIBNL3_GENL */
 # ifdef HAVE_LIBNL3_ROUTE
        if (self->nl_sockets.route)
                nl_socket_free(self->nl_sockets.route);
@@ -438,38 +452,75 @@ int td_daemon_flush_source(
 }
 
 #ifdef HAVE_LIBNL3
-# ifdef HAVE_LIBNL3_ROUTE
-struct nl_sock* td_daemon_get_nl_route_socket(td_daemon* self) {
+static struct nl_sock* td_daemon_get_nl_socket(td_daemon* self, int protocol) {
+       struct nl_sock* sock = NULL;
+       int r;
+
+       // Allocate a new socket
+       sock = nl_socket_alloc();
+       if (!sock) {
+               ERROR(self->ctx, "Failed to allocate a new Netlink socket: %m\n");
+               goto ERROR;
+       }
+
+       // Connect the protocol
+       r = nl_connect(sock, protocol);
+       if (r < 0) {
+               ERROR(self->ctx, "Failed to select netlink protocol %d: %s\n",
+                               protocol, nl_geterror(r));
+               errno = ENOTSUP;
+               goto ERROR;
+       }
+
+       // Return the socket
+       return sock;
+
+ERROR:
+       if (sock)
+               nl_socket_free(sock);
+
+       return NULL;
+}
+
+# ifdef HAVE_LIBNL3_GENL
+struct nl_sock* td_daemon_get_nl_80211_socket(td_daemon* self) {
+       struct nl_sock* sock = NULL;
        int r;
 
        // Create socket if not already done
-       if (!self->nl_sockets.route) {
-               // Allocate a new socket
-               self->nl_sockets.route = nl_socket_alloc();
-               if (!self->nl_sockets.route) {
-                       ERROR(self->ctx, "Failed to allocate a new Netlink socket: %m\n");
-                       goto ERROR;
-               }
+       if (!self->nl_sockets.nl80211) {
+               sock = td_daemon_get_nl_socket(self, NETLINK_GENERIC);
 
-               // Select routing
-               r = nl_connect(self->nl_sockets.route, NETLINK_ROUTE);
+               // Resolve 802.11
+               r = genl_ctrl_resolve(sock, "nl80211");
                if (r < 0) {
-                       ERROR(self->ctx, "Failed to select routing: %s\n", nl_geterror(r));
+                       ERROR(self->ctx, "Failed to resolve nl80211: %s\n", nl_geterror(r));
                        errno = ENOTSUP;
                        goto ERROR;
                }
+
+               // Store the socket
+               self->nl_sockets.nl80211 = sock;
        }
 
-       return self->nl_sockets.route;
+       return self->nl_sockets.nl80211;
 
 ERROR:
-       if (self->nl_sockets.route) {
-               nl_socket_free(self->nl_sockets.route);
-               self->nl_sockets.route = NULL;
-       }
+       if (sock)
+               nl_socket_free(sock);
 
        return NULL;
 }
+# endif /* HAVE_LIBNL3_GENL */
+
+# ifdef HAVE_LIBNL3_ROUTE
+struct nl_sock* td_daemon_get_nl_route_socket(td_daemon* self) {
+       // Create socket if not already done
+       if (!self->nl_sockets.route)
+               self->nl_sockets.route = td_daemon_get_nl_socket(self, NETLINK_ROUTE);
+
+       return self->nl_sockets.route;
+}
 # endif /* HAVE_LIBNL3_ROUTE */
 #endif /* HAVE_LIBNL3 */
 
index 574af63cd5461f0ec1751bf7285a50f797abdbde..64ab376a8b315ce9ef47264237c65753e6871946 100644 (file)
@@ -59,6 +59,10 @@ int td_daemon_flush_source(
        td_daemon* self, td_source* source, const char* object);
 
 #ifdef HAVE_LIBNL3
+# ifdef HAVE_LIBNL3_GENL
+struct nl_sock* td_daemon_get_nl_80211_socket(td_daemon* self);
+# endif /* HAVE_LIBNL3_GENL */
+
 # ifdef HAVE_LIBNL3_ROUTE
 struct nl_sock* td_daemon_get_nl_route_socket(td_daemon* self);
 # endif /* HAVE_LIBNL3_ROUTE */