]> The Tcpdump Group git mirrors - libpcap/blobdiff - pcap-linux.c
Add support for libnl 2.x, adapted from a newer version of the iw command.
[libpcap] / pcap-linux.c
index f8b3f106c572178808fd5ccf3e2e49304462118d..deabbc4a986a2232d9515207e259c7f6d70ce47d 100644 (file)
@@ -527,8 +527,37 @@ get_mac80211_phydev(pcap_t *handle, const char *device, char *phydev_path,
        return 1;
 }
 
+#ifndef HAVE_LIBNL_2_x
+/* libnl 2.x compatibility code */
+
+#define nl_sock nl_handle
+
+static inline struct nl_handle *
+nl_socket_alloc(void)
+{
+       return nl_handle_alloc();
+}
+
+static inline void
+nl_socket_free(struct nl_handle *h)
+{
+       nl_handle_destroy(h);
+}
+
+static inline int
+__genl_ctrl_alloc_cache(struct nl_handle *h, struct nl_cache **cache)
+{
+       struct nl_cache *tmp = genl_ctrl_alloc_cache(h);
+       if (!tmp)
+               return -ENOMEM;
+       *cache = tmp;
+       return 0;
+}
+#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache
+#endif /* !HAVE_LIBNL_2_x */
+
 struct nl80211_state {
-       struct nl_handle *nl_handle;
+       struct nl_sock *nl_sock;
        struct nl_cache *nl_cache;
        struct genl_family *nl80211;
 };
@@ -536,23 +565,26 @@ struct nl80211_state {
 static int
 nl80211_init(pcap_t *handle, struct nl80211_state *state, const char *device)
 {
-       state->nl_handle = nl_handle_alloc();
-       if (!state->nl_handle) {
+       int err;
+
+       state->nl_sock = nl_socket_alloc();
+       if (!state->nl_sock) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: failed to allocate netlink handle", device);
                return PCAP_ERROR;
        }
 
-       if (genl_connect(state->nl_handle)) {
+       if (genl_connect(state->nl_sock)) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: failed to connect to generic netlink", device);
                goto out_handle_destroy;
        }
 
-       state->nl_cache = genl_ctrl_alloc_cache(state->nl_handle);
-       if (!state->nl_cache) {
+       err = genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache);
+       if (err < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
-                   "%s: failed to allocate generic netlink cache", device);
+                   "%s: failed to allocate generic netlink cache: %s",
+                   device, strerror(-err));
                goto out_handle_destroy;
        }
 
@@ -568,7 +600,7 @@ nl80211_init(pcap_t *handle, struct nl80211_state *state, const char *device)
 out_cache_free:
        nl_cache_free(state->nl_cache);
 out_handle_destroy:
-       nl_handle_destroy(state->nl_handle);
+       nl_socket_free(state->nl_sock);
        return PCAP_ERROR;
 }
 
@@ -577,7 +609,7 @@ nl80211_cleanup(struct nl80211_state *state)
 {
        genl_family_put(state->nl80211);
        nl_cache_free(state->nl_cache);
-       nl_handle_destroy(state->nl_handle);
+       nl_socket_free(state->nl_sock);
 }
 
 static int
@@ -605,7 +637,7 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
        NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice);
        NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);
 
-       err = nl_send_auto_complete(state->nl_handle, msg);
+       err = nl_send_auto_complete(state->nl_sock, msg);
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
@@ -626,7 +658,7 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
                        return PCAP_ERROR;
                }
        }
-       err = nl_wait_for_ack(state->nl_handle);
+       err = nl_wait_for_ack(state->nl_sock);
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
@@ -685,7 +717,7 @@ del_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
                    0, NL80211_CMD_DEL_INTERFACE, 0);
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
 
-       err = nl_send_auto_complete(state->nl_handle, msg);
+       err = nl_send_auto_complete(state->nl_sock, msg);
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
@@ -706,7 +738,7 @@ del_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
                        return PCAP_ERROR;
                }
        }
-       err = nl_wait_for_ack(state->nl_handle);
+       err = nl_wait_for_ack(state->nl_sock);
        if (err < 0) {
                if (err == -ENFILE) {
                        /*