#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>
// 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 */
};
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);
}
#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 */