aboutsummaryrefslogtreecommitdiffstats
path: root/pcap-linux.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2010-11-13 17:42:47 -0800
committerGuy Harris <guy@alum.mit.edu>2010-11-13 17:42:47 -0800
commitade794238b623a81e2585d1c2073a3bececa10ae (patch)
treec2b6496fb80a1d7e96d27671e449169aade7c7b0 /pcap-linux.c
parent38ef87dd396d9f2a13f640828815e3067a360c0d (diff)
Add support for libnl 2.x, adapted from a newer version of the iw command.
Diffstat (limited to 'pcap-linux.c')
-rw-r--r--pcap-linux.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/pcap-linux.c b/pcap-linux.c
index f8b3f10..deabbc4 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -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) {
/*