+++ /dev/null
-/*
- * iwinfo - Wireless Information Library - NL80211 Headers
- *
- * Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
- *
- * The iwinfo library is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * The iwinfo library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with the iwinfo library. If not, see http://www.gnu.org/licenses/.
- */
-
-#ifndef __IWINFO_NL80211_H_
-#define __IWINFO_NL80211_H_
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <dirent.h>
-#include <signal.h>
-#include <sys/un.h>
-#include <netlink/netlink.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-
-#include "iwinfo.h"
-#include "iwinfo/utils.h"
-#include "iwinfo/api/nl80211.h"
-
-struct nl80211_state {
- struct nl_sock *nl_sock;
- struct nl_cache *nl_cache;
- struct genl_family *nl80211;
- struct genl_family *nlctrl;
-};
-
-struct nl80211_msg_conveyor {
- struct nl_msg *msg;
- struct nl_cb *cb;
-};
-
-struct nl80211_event_conveyor {
- int wait;
- int recv;
-};
-
-struct nl80211_group_conveyor {
- const char *name;
- int id;
-};
-
-struct nl80211_rssi_rate {
- int16_t rate;
- int8_t rssi;
-};
-
-struct nl80211_array_buf {
- void *buf;
- int count;
-};
-
-int nl80211_probe(const char *ifname);
-int nl80211_get_mode(const char *ifname, int *buf);
-int nl80211_get_ssid(const char *ifname, char *buf);
-int nl80211_get_bssid(const char *ifname, char *buf);
-int nl80211_get_country(const char *ifname, char *buf);
-int nl80211_get_channel(const char *ifname, int *buf);
-int nl80211_get_frequency(const char *ifname, int *buf);
-int nl80211_get_frequency_offset(const char *ifname, int *buf);
-int nl80211_get_txpower(const char *ifname, int *buf);
-int nl80211_get_txpower_offset(const char *ifname, int *buf);
-int nl80211_get_bitrate(const char *ifname, int *buf);
-int nl80211_get_signal(const char *ifname, int *buf);
-int nl80211_get_noise(const char *ifname, int *buf);
-int nl80211_get_quality(const char *ifname, int *buf);
-int nl80211_get_quality_max(const char *ifname, int *buf);
-int nl80211_get_encryption(const char *ifname, char *buf);
-int nl80211_get_phyname(const char *ifname, char *buf);
-int nl80211_get_assoclist(const char *ifname, char *buf, int *len);
-int nl80211_get_txpwrlist(const char *ifname, char *buf, int *len);
-int nl80211_get_scanlist(const char *ifname, char *buf, int *len);
-int nl80211_get_freqlist(const char *ifname, char *buf, int *len);
-int nl80211_get_countrylist(const char *ifname, char *buf, int *len);
-int nl80211_get_hwmodelist(const char *ifname, int *buf);
-int nl80211_get_mbssid_support(const char *ifname, int *buf);
-int nl80211_get_hardware_id(const char *ifname, char *buf);
-int nl80211_get_hardware_name(const char *ifname, char *buf);
-void nl80211_close(void);
-
-static const struct iwinfo_ops nl80211_ops = {
- .name = "nl80211",
- .probe = nl80211_probe,
- .channel = nl80211_get_channel,
- .frequency = nl80211_get_frequency,
- .frequency_offset = nl80211_get_frequency_offset,
- .txpower = nl80211_get_txpower,
- .txpower_offset = nl80211_get_txpower_offset,
- .bitrate = nl80211_get_bitrate,
- .signal = nl80211_get_signal,
- .noise = nl80211_get_noise,
- .quality = nl80211_get_quality,
- .quality_max = nl80211_get_quality_max,
- .mbssid_support = nl80211_get_mbssid_support,
- .hwmodelist = nl80211_get_hwmodelist,
- .mode = nl80211_get_mode,
- .ssid = nl80211_get_ssid,
- .bssid = nl80211_get_bssid,
- .country = nl80211_get_country,
- .hardware_id = nl80211_get_hardware_id,
- .hardware_name = nl80211_get_hardware_name,
- .encryption = nl80211_get_encryption,
- .phyname = nl80211_get_phyname,
- .assoclist = nl80211_get_assoclist,
- .txpwrlist = nl80211_get_txpwrlist,
- .scanlist = nl80211_get_scanlist,
- .freqlist = nl80211_get_freqlist,
- .countrylist = nl80211_get_countrylist,
- .close = nl80211_close
-};
-
-#endif
#ifdef USE_NL80211
/* NL80211 */
-LUA_WRAP_INT(nl80211,channel)
-LUA_WRAP_INT(nl80211,frequency)
-LUA_WRAP_INT(nl80211,frequency_offset)
-LUA_WRAP_INT(nl80211,txpower)
-LUA_WRAP_INT(nl80211,txpower_offset)
-LUA_WRAP_INT(nl80211,bitrate)
-LUA_WRAP_INT(nl80211,signal)
-LUA_WRAP_INT(nl80211,noise)
-LUA_WRAP_INT(nl80211,quality)
-LUA_WRAP_INT(nl80211,quality_max)
-LUA_WRAP_STRING(nl80211,ssid)
-LUA_WRAP_STRING(nl80211,bssid)
-LUA_WRAP_STRING(nl80211,country)
-LUA_WRAP_STRING(nl80211,hardware_name)
-LUA_WRAP_STRING(nl80211,phyname)
-LUA_WRAP_STRUCT(nl80211,mode)
-LUA_WRAP_STRUCT(nl80211,assoclist)
-LUA_WRAP_STRUCT(nl80211,txpwrlist)
-LUA_WRAP_STRUCT(nl80211,scanlist)
-LUA_WRAP_STRUCT(nl80211,freqlist)
-LUA_WRAP_STRUCT(nl80211,countrylist)
-LUA_WRAP_STRUCT(nl80211,hwmodelist)
-LUA_WRAP_STRUCT(nl80211,encryption)
-LUA_WRAP_STRUCT(nl80211,mbssid_support)
-LUA_WRAP_STRUCT(nl80211,hardware_id)
+LUA_WRAP_INT_OP(nl80211,channel)
+LUA_WRAP_INT_OP(nl80211,frequency)
+LUA_WRAP_INT_OP(nl80211,frequency_offset)
+LUA_WRAP_INT_OP(nl80211,txpower)
+LUA_WRAP_INT_OP(nl80211,txpower_offset)
+LUA_WRAP_INT_OP(nl80211,bitrate)
+LUA_WRAP_INT_OP(nl80211,signal)
+LUA_WRAP_INT_OP(nl80211,noise)
+LUA_WRAP_INT_OP(nl80211,quality)
+LUA_WRAP_INT_OP(nl80211,quality_max)
+LUA_WRAP_STRING_OP(nl80211,ssid)
+LUA_WRAP_STRING_OP(nl80211,bssid)
+LUA_WRAP_STRING_OP(nl80211,country)
+LUA_WRAP_STRING_OP(nl80211,hardware_name)
+LUA_WRAP_STRING_OP(nl80211,phyname)
+LUA_WRAP_STRUCT_OP(nl80211,mode)
+LUA_WRAP_STRUCT_OP(nl80211,assoclist)
+LUA_WRAP_STRUCT_OP(nl80211,txpwrlist)
+LUA_WRAP_STRUCT_OP(nl80211,scanlist)
+LUA_WRAP_STRUCT_OP(nl80211,freqlist)
+LUA_WRAP_STRUCT_OP(nl80211,countrylist)
+LUA_WRAP_STRUCT_OP(nl80211,hwmodelist)
+LUA_WRAP_STRUCT_OP(nl80211,encryption)
+LUA_WRAP_STRUCT_OP(nl80211,mbssid_support)
+LUA_WRAP_STRUCT_OP(nl80211,hardware_id)
#endif
/* Wext */
* Parts of this code are derived from the Linux iw utility.
*/
-#include "iwinfo/nl80211.h"
+#include "iwinfo_nl80211.h"
#define min(x, y) ((x) < (y)) ? (x) : (y)
static struct nl80211_state *nls = NULL;
+static void nl80211_close(void)
+{
+ if (nls)
+ {
+ if (nls->nlctrl)
+ genl_family_put(nls->nlctrl);
+
+ if (nls->nl80211)
+ genl_family_put(nls->nl80211);
+
+ if (nls->nl_sock)
+ nl_socket_free(nls->nl_sock);
+
+ if (nls->nl_cache)
+ nl_cache_free(nls->nl_cache);
+
+ free(nls);
+ nls = NULL;
+ }
+}
+
static int nl80211_init(void)
{
int err, fd;
return err;
}
+static int nl80211_readint(const char *path)
+{
+ int fd;
+ int rv = -1;
+ char buffer[16];
+
+ if ((fd = open(path, O_RDONLY)) > -1)
+ {
+ if (read(fd, buffer, sizeof(buffer)) > 0)
+ rv = atoi(buffer);
+
+ close(fd);
+ }
+
+ return rv;
+}
+
static int nl80211_msg_error(struct sockaddr_nl *nla,
struct nlmsgerr *err, void *arg)
return phy[0] ? phy : NULL;
}
+static char * nl80211_phy2ifname(const char *ifname)
+{
+ int fd, ifidx = -1, cifidx = -1, phyidx = -1;
+ char buffer[64];
+ static char nif[IFNAMSIZ] = { 0 };
+
+ DIR *d;
+ struct dirent *e;
+
+ if (!ifname)
+ return NULL;
+ else if (!strncmp(ifname, "phy", 3))
+ phyidx = atoi(&ifname[3]);
+ else if (!strncmp(ifname, "radio", 5))
+ phyidx = atoi(&ifname[5]);
+
+ memset(nif, 0, sizeof(nif));
+
+ if (phyidx > -1)
+ {
+ if ((d = opendir("/sys/class/net")) != NULL)
+ {
+ while ((e = readdir(d)) != NULL)
+ {
+ snprintf(buffer, sizeof(buffer),
+ "/sys/class/net/%s/phy80211/index", e->d_name);
+
+ if (nl80211_readint(buffer) == phyidx)
+ {
+ snprintf(buffer, sizeof(buffer),
+ "/sys/class/net/%s/ifindex", e->d_name);
+
+ if ((cifidx = nl80211_readint(buffer)) >= 0 &&
+ ((ifidx < 0) || (cifidx < ifidx)))
+ {
+ ifidx = cifidx;
+ strncpy(nif, e->d_name, sizeof(nif));
+ }
+ }
+ }
+
+ closedir(d);
+ }
+ }
+
+ return nif[0] ? nif : NULL;
+}
+
+static int nl80211_get_mode_cb(struct nl_msg *msg, void *arg)
+{
+ int *mode = arg;
+ struct nlattr **tb = nl80211_parse(msg);
+ const int ifmodes[NL80211_IFTYPE_MAX + 1] = {
+ IWINFO_OPMODE_UNKNOWN, /* unspecified */
+ IWINFO_OPMODE_ADHOC, /* IBSS */
+ IWINFO_OPMODE_CLIENT, /* managed */
+ IWINFO_OPMODE_MASTER, /* AP */
+ IWINFO_OPMODE_AP_VLAN, /* AP/VLAN */
+ IWINFO_OPMODE_WDS, /* WDS */
+ IWINFO_OPMODE_MONITOR, /* monitor */
+ IWINFO_OPMODE_MESHPOINT, /* mesh point */
+ IWINFO_OPMODE_P2P_CLIENT, /* P2P-client */
+ IWINFO_OPMODE_P2P_GO, /* P2P-GO */
+ };
+
+ if (tb[NL80211_ATTR_IFTYPE])
+ *mode = ifmodes[nla_get_u32(tb[NL80211_ATTR_IFTYPE])];
+
+ return NL_SKIP;
+}
+
+
+static int nl80211_get_mode(const char *ifname, int *buf)
+{
+ char *res;
+ struct nl80211_msg_conveyor *req;
+
+ res = nl80211_phy2ifname(ifname);
+ req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_INTERFACE, 0);
+ *buf = IWINFO_OPMODE_UNKNOWN;
+
+ if (req)
+ {
+ nl80211_send(req, nl80211_get_mode_cb, buf);
+ nl80211_free(req);
+ }
+
+ return (*buf == IWINFO_OPMODE_UNKNOWN) ? -1 : 0;
+}
+
static char * nl80211_hostapd_info(const char *ifname)
{
int mode;
return rv;
}
-static inline int nl80211_readint(const char *path)
-{
- int fd;
- int rv = -1;
- char buffer[16];
-
- if ((fd = open(path, O_RDONLY)) > -1)
- {
- if (read(fd, buffer, sizeof(buffer)) > 0)
- rv = atoi(buffer);
-
- close(fd);
- }
-
- return rv;
-}
-
-static char * nl80211_phy2ifname(const char *ifname)
-{
- int fd, ifidx = -1, cifidx = -1, phyidx = -1;
- char buffer[64];
- static char nif[IFNAMSIZ] = { 0 };
-
- DIR *d;
- struct dirent *e;
-
- if (!ifname)
- return NULL;
- else if (!strncmp(ifname, "phy", 3))
- phyidx = atoi(&ifname[3]);
- else if (!strncmp(ifname, "radio", 5))
- phyidx = atoi(&ifname[5]);
-
- memset(nif, 0, sizeof(nif));
-
- if (phyidx > -1)
- {
- if ((d = opendir("/sys/class/net")) != NULL)
- {
- while ((e = readdir(d)) != NULL)
- {
- snprintf(buffer, sizeof(buffer),
- "/sys/class/net/%s/phy80211/index", e->d_name);
-
- if (nl80211_readint(buffer) == phyidx)
- {
- snprintf(buffer, sizeof(buffer),
- "/sys/class/net/%s/ifindex", e->d_name);
-
- if ((cifidx = nl80211_readint(buffer)) >= 0 &&
- ((ifidx < 0) || (cifidx < ifidx)))
- {
- ifidx = cifidx;
- strncpy(nif, e->d_name, sizeof(nif));
- }
- }
- }
-
- closedir(d);
- }
- }
-
- return nif[0] ? nif : NULL;
-}
-
static char * nl80211_ifadd(const char *ifname)
{
int phyidx;
}
-int nl80211_probe(const char *ifname)
+static int nl80211_probe(const char *ifname)
{
return !!nl80211_ifname2phy(ifname);
}
-void nl80211_close(void)
-{
- if (nls)
- {
- if (nls->nlctrl)
- genl_family_put(nls->nlctrl);
-
- if (nls->nl80211)
- genl_family_put(nls->nl80211);
-
- if (nls->nl_sock)
- nl_socket_free(nls->nl_sock);
-
- if (nls->nl_cache)
- nl_cache_free(nls->nl_cache);
-
- free(nls);
- nls = NULL;
- }
-}
-
-
-static int nl80211_get_mode_cb(struct nl_msg *msg, void *arg)
-{
- int *mode = arg;
- struct nlattr **tb = nl80211_parse(msg);
- const int ifmodes[NL80211_IFTYPE_MAX + 1] = {
- IWINFO_OPMODE_UNKNOWN, /* unspecified */
- IWINFO_OPMODE_ADHOC, /* IBSS */
- IWINFO_OPMODE_CLIENT, /* managed */
- IWINFO_OPMODE_MASTER, /* AP */
- IWINFO_OPMODE_AP_VLAN, /* AP/VLAN */
- IWINFO_OPMODE_WDS, /* WDS */
- IWINFO_OPMODE_MONITOR, /* monitor */
- IWINFO_OPMODE_MESHPOINT, /* mesh point */
- IWINFO_OPMODE_P2P_CLIENT, /* P2P-client */
- IWINFO_OPMODE_P2P_GO, /* P2P-GO */
- };
-
- if (tb[NL80211_ATTR_IFTYPE])
- *mode = ifmodes[nla_get_u32(tb[NL80211_ATTR_IFTYPE])];
-
- return NL_SKIP;
-}
-
-int nl80211_get_mode(const char *ifname, int *buf)
-{
- char *res;
- struct nl80211_msg_conveyor *req;
-
- res = nl80211_phy2ifname(ifname);
- req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_INTERFACE, 0);
- *buf = IWINFO_OPMODE_UNKNOWN;
-
- if (req)
- {
- nl80211_send(req, nl80211_get_mode_cb, buf);
- nl80211_free(req);
- }
-
- return (*buf == IWINFO_OPMODE_UNKNOWN) ? -1 : 0;
-}
-
-
struct nl80211_ssid_bssid {
unsigned char *ssid;
unsigned char bssid[7];
}
}
-int nl80211_get_ssid(const char *ifname, char *buf)
+static int nl80211_get_ssid(const char *ifname, char *buf)
{
char *res;
struct nl80211_msg_conveyor *req;
return (*buf == 0) ? -1 : 0;
}
-int nl80211_get_bssid(const char *ifname, char *buf)
+static int nl80211_get_bssid(const char *ifname, char *buf)
{
char *res;
struct nl80211_msg_conveyor *req;
return NL_SKIP;
}
-int nl80211_get_frequency(const char *ifname, int *buf)
+static int nl80211_get_frequency(const char *ifname, int *buf)
{
int chn;
char *res, *channel;
return (*buf == 0) ? -1 : 0;
}
-int nl80211_get_channel(const char *ifname, int *buf)
+static int nl80211_get_channel(const char *ifname, int *buf)
{
if (!nl80211_get_frequency(ifname, buf))
{
}
-int nl80211_get_txpower(const char *ifname, int *buf)
+static int nl80211_get_txpower(const char *ifname, int *buf)
{
#if 0
char *res;
}
}
-int nl80211_get_bitrate(const char *ifname, int *buf)
+static int nl80211_get_bitrate(const char *ifname, int *buf)
{
struct nl80211_rssi_rate rr;
return -1;
}
-int nl80211_get_signal(const char *ifname, int *buf)
+static int nl80211_get_signal(const char *ifname, int *buf)
{
struct nl80211_rssi_rate rr;
}
-int nl80211_get_noise(const char *ifname, int *buf)
+static int nl80211_get_noise(const char *ifname, int *buf)
{
int8_t noise;
struct nl80211_msg_conveyor *req;
return -1;
}
-int nl80211_get_quality(const char *ifname, int *buf)
+static int nl80211_get_quality(const char *ifname, int *buf)
{
int signal;
return -1;
}
-int nl80211_get_quality_max(const char *ifname, int *buf)
+static int nl80211_get_quality_max(const char *ifname, int *buf)
{
/* The cfg80211 wext compat layer assumes a maximum
* quality of 70 */
return 0;
}
-int nl80211_get_encryption(const char *ifname, char *buf)
+static int nl80211_get_encryption(const char *ifname, char *buf)
{
int i;
char k[9];
return -1;
}
-int nl80211_get_phyname(const char *ifname, char *buf)
+static int nl80211_get_phyname(const char *ifname, char *buf)
{
const char *name;
return NL_SKIP;
}
-int nl80211_get_assoclist(const char *ifname, char *buf, int *len)
+static int nl80211_get_assoclist(const char *ifname, char *buf, int *len)
{
DIR *d;
int i, noise = 0;
return NL_SKIP;
}
-int nl80211_get_txpwrlist(const char *ifname, char *buf, int *len)
+static int nl80211_get_txpwrlist(const char *ifname, char *buf, int *len)
{
int ch_cur;
int dbm_max = -1, dbm_cur, dbm_cnt;
return *len ? 0 : -1;
}
-int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
+static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
{
int freq, rssi, qmax, count;
char *res;
return NL_SKIP;
}
-int nl80211_get_freqlist(const char *ifname, char *buf, int *len)
+static int nl80211_get_freqlist(const char *ifname, char *buf, int *len)
{
struct nl80211_msg_conveyor *req;
struct nl80211_array_buf arr = { .buf = buf, .count = 0 };
return NL_SKIP;
}
-int nl80211_get_country(const char *ifname, char *buf)
+static int nl80211_get_country(const char *ifname, char *buf)
{
int rv = -1;
struct nl80211_msg_conveyor *req;
return rv;
}
-int nl80211_get_countrylist(const char *ifname, char *buf, int *len)
+static int nl80211_get_countrylist(const char *ifname, char *buf, int *len)
{
int i, count;
struct iwinfo_country_entry *e = (struct iwinfo_country_entry *)buf;
return NL_SKIP;
}
-int nl80211_get_hwmodelist(const char *ifname, int *buf)
+static int nl80211_get_hwmodelist(const char *ifname, int *buf)
{
struct nl80211_msg_conveyor *req;
return NL_SKIP;
}
-int nl80211_get_mbssid_support(const char *ifname, int *buf)
+static int nl80211_get_mbssid_support(const char *ifname, int *buf)
{
struct nl80211_msg_conveyor *req;
return 0;
}
-int nl80211_get_hardware_id(const char *ifname, char *buf)
+static int nl80211_get_hardware_id(const char *ifname, char *buf)
{
int rv;
char *res;
return iwinfo_hardware(&id);
}
-int nl80211_get_hardware_name(const char *ifname, char *buf)
+static int nl80211_get_hardware_name(const char *ifname, char *buf)
{
const struct iwinfo_hardware_entry *hw;
return 0;
}
-int nl80211_get_txpower_offset(const char *ifname, int *buf)
+static int nl80211_get_txpower_offset(const char *ifname, int *buf)
{
const struct iwinfo_hardware_entry *hw;
return 0;
}
-int nl80211_get_frequency_offset(const char *ifname, int *buf)
+static int nl80211_get_frequency_offset(const char *ifname, int *buf)
{
const struct iwinfo_hardware_entry *hw;
*buf = hw->frequency_offset;
return 0;
}
+
+const struct iwinfo_ops nl80211_ops = {
+ .name = "nl80211",
+ .probe = nl80211_probe,
+ .channel = nl80211_get_channel,
+ .frequency = nl80211_get_frequency,
+ .frequency_offset = nl80211_get_frequency_offset,
+ .txpower = nl80211_get_txpower,
+ .txpower_offset = nl80211_get_txpower_offset,
+ .bitrate = nl80211_get_bitrate,
+ .signal = nl80211_get_signal,
+ .noise = nl80211_get_noise,
+ .quality = nl80211_get_quality,
+ .quality_max = nl80211_get_quality_max,
+ .mbssid_support = nl80211_get_mbssid_support,
+ .hwmodelist = nl80211_get_hwmodelist,
+ .mode = nl80211_get_mode,
+ .ssid = nl80211_get_ssid,
+ .bssid = nl80211_get_bssid,
+ .country = nl80211_get_country,
+ .hardware_id = nl80211_get_hardware_id,
+ .hardware_name = nl80211_get_hardware_name,
+ .encryption = nl80211_get_encryption,
+ .phyname = nl80211_get_phyname,
+ .assoclist = nl80211_get_assoclist,
+ .txpwrlist = nl80211_get_txpwrlist,
+ .scanlist = nl80211_get_scanlist,
+ .freqlist = nl80211_get_freqlist,
+ .countrylist = nl80211_get_countrylist,
+ .close = nl80211_close
+};