aboutsummaryrefslogtreecommitdiffstats
path: root/package/iwinfo
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2013-04-27 09:45:06 +0000
committerJo-Philipp Wich <jow@openwrt.org>2013-04-27 09:45:06 +0000
commitacd03cf8d8c3a047108b7983944b0c8d0228f812 (patch)
tree2825e0cb2ae9d5cb7d1659d82aca130412df80ad /package/iwinfo
parent344bc0ebcac126e43235d1bb4f719ff1794fe794 (diff)
downloadupstream-acd03cf8d8c3a047108b7983944b0c8d0228f812.tar.gz
upstream-acd03cf8d8c3a047108b7983944b0c8d0228f812.tar.bz2
upstream-acd03cf8d8c3a047108b7983944b0c8d0228f812.zip
AA: iwinfo: merge r34982, r35005, r35007, r35471, r36292, r36339, r36417, r36449, r36450
git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@36465 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/iwinfo')
-rw-r--r--package/iwinfo/Makefile8
-rw-r--r--package/iwinfo/src/hardware.txt55
-rw-r--r--package/iwinfo/src/include/iwinfo.h22
-rw-r--r--package/iwinfo/src/iwinfo_cli.c29
-rw-r--r--package/iwinfo/src/iwinfo_lib.c76
-rw-r--r--package/iwinfo/src/iwinfo_nl80211.c328
-rw-r--r--package/iwinfo/src/iwinfo_utils.c49
7 files changed, 393 insertions, 174 deletions
diff --git a/package/iwinfo/Makefile b/package/iwinfo/Makefile
index bbef2bdc85..3758692450 100644
--- a/package/iwinfo/Makefile
+++ b/package/iwinfo/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
+# Copyright (C) 2010-2013 Jo-Philipp Wich <xm@subsignal.org>
#
# This is free software, licensed under the GPL 2 license.
#
@@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libiwinfo
-PKG_RELEASE:=36
+PKG_RELEASE:=43
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
PKG_CONFIG_DEPENDS := \
@@ -39,7 +39,7 @@ define Package/libiwinfo-lua
SECTION:=lang
CATEGORY:=Languages
TITLE:=libiwinfo Lua binding
- DEPENDS:=+libiwinfo +liblua +lua
+ DEPENDS:=+libiwinfo +liblua
MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
endef
@@ -101,6 +101,8 @@ endef
define Package/libiwinfo/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_BIN) $(PKG_BUILD_DIR)/libiwinfo.so $(1)/usr/lib/libiwinfo.so
+ $(INSTALL_DIR) $(1)/usr/share/libiwinfo
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/hardware.txt $(1)/usr/share/libiwinfo/hardware.txt
endef
define Package/libiwinfo-lua/install
diff --git a/package/iwinfo/src/hardware.txt b/package/iwinfo/src/hardware.txt
new file mode 100644
index 0000000000..6b20518c36
--- /dev/null
+++ b/package/iwinfo/src/hardware.txt
@@ -0,0 +1,55 @@
+# libiwinfo hardware database
+# vendor id | device id | subsystem vendor id | subsystem device id |
+# txpower offset | frequency offset | "vendor name" | "device name"
+0xffff 0xffff 0xffff 0xb102 0 0 "Ubiquiti" "PowerStation2 (18V)"
+0xffff 0xffff 0xffff 0xb202 0 0 "Ubiquiti" "PowerStation2 (16D)"
+0xffff 0xffff 0xffff 0xb302 0 0 "Ubiquiti" "PowerStation2 (EXT)"
+0xffff 0xffff 0xffff 0xb105 0 0 "Ubiquiti" "PowerStation5 (22V)"
+0xffff 0xffff 0xffff 0xb305 0 0 "Ubiquiti" "PowerStation5 (EXT)"
+0xffff 0xffff 0xffff 0xc302 0 0 "Ubiquiti" "PicoStation2"
+0xffff 0xffff 0xffff 0xc3a2 10 0 "Ubiquiti" "PicoStation2 HP"
+0xffff 0xffff 0xffff 0xa105 0 0 "Ubiquiti" "WispStation5"
+0xffff 0xffff 0xffff 0xa002 10 0 "Ubiquiti" "LiteStation2"
+0xffff 0xffff 0xffff 0xa005 5 0 "Ubiquiti" "LiteStation5"
+0xffff 0xffff 0xffff 0xc002 10 0 "Ubiquiti" "NanoStation2"
+0xffff 0xffff 0xffff 0xc005 5 0 "Ubiquiti" "NanoStation5"
+0xffff 0xffff 0xffff 0xc102 10 0 "Ubiquiti" "NanoStation Loco2"
+0xffff 0xffff 0xffff 0xc105 5 0 "Ubiquiti" "NanoStation Loco5"
+0xffff 0xffff 0xffff 0xc202 10 0 "Ubiquiti" "Bullet2"
+0xffff 0xffff 0xffff 0xc205 5 0 "Ubiquiti" "Bullet5"
+0x168c 0x001b 0x0777 0x3002 10 0 "Ubiquiti" "XR2"
+0x168c 0x001b 0x7777 0x3002 10 0 "Ubiquiti" "XR2"
+0x168c 0x001b 0x0777 0x3b02 10 0 "Ubiquiti" "XR2.3"
+0x168c 0x001b 0x0777 0x3c02 10 0 "Ubiquiti" "XR2.6"
+0x168c 0x001b 0x0777 0x3b03 10 0 "Ubiquiti" "XR3-2.8"
+0x168c 0x001b 0x0777 0x3c03 10 0 "Ubiquiti" "XR3-3.6"
+0x168c 0x001b 0x0777 0x3003 10 0 "Ubiquiti" "XR3"
+0x168c 0x001b 0x0777 0x3004 10 0 "Ubiquiti" "XR4"
+0x168c 0x001b 0x0777 0x3005 10 0 "Ubiquiti" "XR5"
+0x168c 0x001b 0x7777 0x3005 10 0 "Ubiquiti" "XR5"
+0x168c 0x001b 0x0777 0x3007 10 0 "Ubiquiti" "XR7"
+0x168c 0x001b 0x0777 0x3009 10 -1520 "Ubiquiti" "XR9"
+0x168c 0x001b 0x168c 0x2063 0 0 "Atheros" "AR5413"
+0x168c 0x0013 0x168c 0x1042 1 0 "Ubiquiti" "SRC"
+0x168c 0x0013 0x0777 0x2041 10 0 "Ubiquiti" "SR2"
+0x168c 0x0013 0x0777 0x2004 6 0 "Ubiquiti" "SR4"
+0x168c 0x0013 0x7777 0x2004 6 0 "Ubiquiti" "SR4"
+0x168c 0x0013 0x0777 0x1004 6 0 "Ubiquiti" "SR4C"
+0x168c 0x0013 0x7777 0x1004 6 0 "Ubiquiti" "SR4C"
+0x168c 0x0013 0x168c 0x2042 7 0 "Ubiquiti" "SR5"
+0x168c 0x0013 0x7777 0x2009 12 -1500 "Ubiquiti" "SR9"
+0x168c 0x0027 0x168c 0x2082 7 0 "Ubiquiti" "SR71A"
+0x168c 0x0027 0x0777 0x4082 7 0 "Ubiquiti" "SR71"
+0x168c 0x0029 0x0777 0x4005 7 0 "Ubiquiti" "SR71-15"
+0x168c 0x002a 0x0777 0xe302 12 0 "Ubiquiti" "PicoStation M2" /* ToDo: confirm offset */
+0x168c 0x002a 0x0777 0xe012 12 0 "Ubiquiti" "NanoStation M2" /* ToDo: confirm offset */
+0x168c 0x002a 0x0777 0xe005 5 0 "Ubiquiti" "NanoStation M5" /* ToDo: confirm offset */
+0x168c 0x002a 0x0777 0xe202 12 0 "Ubiquiti" "Bullet M2"
+0x168c 0x002a 0x0777 0xe805 5 0 "Ubiquiti" "Bullet M5"
+0x168c 0x0029 0x168c 0xa094 0 0 "Atheros" "AR9220"
+0x168c 0x0029 0x168c 0xa095 0 0 "Atheros" "AR9223"
+0x168c 0x002a 0x168c 0xa093 0 0 "Atheros" "AR9280"
+0x168c 0x002b 0x168c 0xa091 0 0 "Atheros" "AR9285"
+0x1814 0x3050 0x1814 0x0005 0 0 "RaLink" "Rt3050"
+0x1814 0x3052 0x1814 0x0008 0 0 "RaLink" "Rt3052"
+0x1814 0x3352 0x1814 0x000c 0 0 "RaLink" "Rt3352"
diff --git a/package/iwinfo/src/include/iwinfo.h b/package/iwinfo/src/include/iwinfo.h
index 868c10b359..0d92d8db1e 100644
--- a/package/iwinfo/src/include/iwinfo.h
+++ b/package/iwinfo/src/include/iwinfo.h
@@ -50,11 +50,16 @@ extern const char *IWINFO_AUTH_NAMES[];
enum iwinfo_opmode {
- IWINFO_OPMODE_UNKNOWN = 0,
- IWINFO_OPMODE_MASTER = 1,
- IWINFO_OPMODE_ADHOC = 2,
- IWINFO_OPMODE_CLIENT = 3,
- IWINFO_OPMODE_MONITOR = 4,
+ IWINFO_OPMODE_UNKNOWN = 0,
+ IWINFO_OPMODE_MASTER = 1,
+ IWINFO_OPMODE_ADHOC = 2,
+ IWINFO_OPMODE_CLIENT = 3,
+ IWINFO_OPMODE_MONITOR = 4,
+ IWINFO_OPMODE_AP_VLAN = 5,
+ IWINFO_OPMODE_WDS = 6,
+ IWINFO_OPMODE_MESHPOINT = 7,
+ IWINFO_OPMODE_P2P_CLIENT = 8,
+ IWINFO_OPMODE_P2P_GO = 9,
};
extern const char *IWINFO_OPMODE_NAMES[];
@@ -127,8 +132,8 @@ struct iwinfo_hardware_id {
};
struct iwinfo_hardware_entry {
- const char *vendor_name;
- const char *device_name;
+ char vendor_name[64];
+ char device_name[64];
uint16_t vendor_id;
uint16_t device_id;
uint16_t subsystem_vendor_id;
@@ -138,7 +143,8 @@ struct iwinfo_hardware_entry {
};
extern const struct iwinfo_iso3166_label IWINFO_ISO3166_NAMES[];
-extern const struct iwinfo_hardware_entry IWINFO_HARDWARE_ENTRIES[];
+
+#define IWINFO_HARDWARE_FILE "/usr/share/libiwinfo/hardware.txt"
struct iwinfo_ops {
diff --git a/package/iwinfo/src/iwinfo_cli.c b/package/iwinfo/src/iwinfo_cli.c
index 7ec5aef95c..8da216a6ef 100644
--- a/package/iwinfo/src/iwinfo_cli.c
+++ b/package/iwinfo/src/iwinfo_cli.c
@@ -17,6 +17,7 @@
*/
#include <stdio.h>
+#include <glob.h>
#include "iwinfo.h"
@@ -735,9 +736,11 @@ static void print_countrylist(const struct iwinfo_ops *iw, const char *ifname)
int main(int argc, char **argv)
{
int i;
+ char *p;
const struct iwinfo_ops *iw;
+ glob_t globbuf;
- if (argc < 3)
+ if (argc > 1 && argc < 3)
{
fprintf(stderr,
"Usage:\n"
@@ -752,6 +755,30 @@ int main(int argc, char **argv)
return 1;
}
+ if (argc == 1)
+ {
+ glob("/sys/class/net/*", 0, NULL, &globbuf);
+
+ for (i = 0; i < globbuf.gl_pathc; i++)
+ {
+ p = strrchr(globbuf.gl_pathv[i], '/');
+
+ if (!p)
+ continue;
+
+ iw = iwinfo_backend(++p);
+
+ if (!iw)
+ continue;
+
+ print_info(iw, p);
+ printf("\n");
+ }
+
+ globfree(&globbuf);
+ return 0;
+ }
+
iw = iwinfo_backend(argv[1]);
if (!iw)
diff --git a/package/iwinfo/src/iwinfo_lib.c b/package/iwinfo/src/iwinfo_lib.c
index dd65e45aa9..df1f450cc5 100644
--- a/package/iwinfo/src/iwinfo_lib.c
+++ b/package/iwinfo/src/iwinfo_lib.c
@@ -1,7 +1,7 @@
/*
* iwinfo - Wireless Information Library - Lua Bindings
*
- * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
+ * Copyright (C) 2009-2013 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
@@ -50,6 +50,11 @@ const char *IWINFO_OPMODE_NAMES[] = {
"Ad-Hoc",
"Client",
"Monitor",
+ "Master (VLAN)",
+ "WDS",
+ "Mesh Point",
+ "P2P Client",
+ "P2P Go",
};
@@ -308,75 +313,6 @@ const struct iwinfo_iso3166_label IWINFO_ISO3166_NAMES[] = {
{ 0, "" }
};
-/*
- * hardware database
- */
-
-const char VENDOR_UBNT[] = "Ubiquiti";
-const char VENDOR_ATH[] = "Atheros";
-const char VENDOR_RALINK[] = "RaLink";
-
-const struct iwinfo_hardware_entry IWINFO_HARDWARE_ENTRIES[] = {
-/* { vendor, model, vendorid, deviceid, subsys vendorid, subsys deviceid, poweroff, freqoff } */
-#if defined(USE_MADWIFI) || defined(USE_NL80211)
- { VENDOR_UBNT, "PowerStation2 (18V)", 0xffff, 0xffff, 0xffff, 0xb102, 0, 0 },
- { VENDOR_UBNT, "PowerStation2 (16D)", 0xffff, 0xffff, 0xffff, 0xb202, 0, 0 },
- { VENDOR_UBNT, "PowerStation2 (EXT)", 0xffff, 0xffff, 0xffff, 0xb302, 0, 0 },
- { VENDOR_UBNT, "PowerStation5 (22V)", 0xffff, 0xffff, 0xffff, 0xb105, 0, 0 },
- { VENDOR_UBNT, "PowerStation5 (EXT)", 0xffff, 0xffff, 0xffff, 0xb305, 0, 0 },
- { VENDOR_UBNT, "PicoStation2", 0xffff, 0xffff, 0xffff, 0xc302, 0, 0 },
- { VENDOR_UBNT, "PicoStation2 HP", 0xffff, 0xffff, 0xffff, 0xc3a2, 10, 0 },
- { VENDOR_UBNT, "WispStation5", 0xffff, 0xffff, 0xffff, 0xa105, 0, 0 },
- { VENDOR_UBNT, "LiteStation2", 0xffff, 0xffff, 0xffff, 0xa002, 10, 0 },
- { VENDOR_UBNT, "LiteStation5", 0xffff, 0xffff, 0xffff, 0xa005, 5, 0 },
- { VENDOR_UBNT, "NanoStation2", 0xffff, 0xffff, 0xffff, 0xc002, 10, 0 },
- { VENDOR_UBNT, "NanoStation5", 0xffff, 0xffff, 0xffff, 0xc005, 5, 0 },
- { VENDOR_UBNT, "NanoStation Loco2", 0xffff, 0xffff, 0xffff, 0xc102, 10, 0 },
- { VENDOR_UBNT, "NanoStation Loco5", 0xffff, 0xffff, 0xffff, 0xc105, 5, 0 },
- { VENDOR_UBNT, "Bullet2", 0xffff, 0xffff, 0xffff, 0xc202, 10, 0 },
- { VENDOR_UBNT, "Bullet5", 0xffff, 0xffff, 0xffff, 0xc205, 5, 0 },
- { VENDOR_UBNT, "XR2", 0x168c, 0x001b, 0x0777, 0x3002, 10, 0 },
- { VENDOR_UBNT, "XR2", 0x168c, 0x001b, 0x7777, 0x3002, 10, 0 },
- { VENDOR_UBNT, "XR2.3", 0x168c, 0x001b, 0x0777, 0x3b02, 10, 0 },
- { VENDOR_UBNT, "XR2.6", 0x168c, 0x001b, 0x0777, 0x3c02, 10, 0 },
- { VENDOR_UBNT, "XR3-2.8", 0x168c, 0x001b, 0x0777, 0x3b03, 10, 0 },
- { VENDOR_UBNT, "XR3-3.6", 0x168c, 0x001b, 0x0777, 0x3c03, 10, 0 },
- { VENDOR_UBNT, "XR3", 0x168c, 0x001b, 0x0777, 0x3003, 10, 0 },
- { VENDOR_UBNT, "XR4", 0x168c, 0x001b, 0x0777, 0x3004, 10, 0 },
- { VENDOR_UBNT, "XR5", 0x168c, 0x001b, 0x0777, 0x3005, 10, 0 },
- { VENDOR_UBNT, "XR5", 0x168c, 0x001b, 0x7777, 0x3005, 10, 0 },
- { VENDOR_UBNT, "XR7", 0x168c, 0x001b, 0x0777, 0x3007, 10, 0 },
- { VENDOR_UBNT, "XR9", 0x168c, 0x001b, 0x0777, 0x3009, 10, -1520 },
- { VENDOR_ATH, "AR5413", 0x168c, 0x001b, 0x168c, 0x2063, 0, 0 },
- { VENDOR_UBNT, "SRC", 0x168c, 0x0013, 0x168c, 0x1042, 1, 0 },
- { VENDOR_UBNT, "SR2", 0x168c, 0x0013, 0x0777, 0x2041, 10, 0 },
- { VENDOR_UBNT, "SR4", 0x168c, 0x0013, 0x0777, 0x2004, 6, 0 },
- { VENDOR_UBNT, "SR4", 0x168c, 0x0013, 0x7777, 0x2004, 6, 0 },
- { VENDOR_UBNT, "SR4C", 0x168c, 0x0013, 0x0777, 0x1004, 6, 0 },
- { VENDOR_UBNT, "SR4C", 0x168c, 0x0013, 0x7777, 0x1004, 6, 0 },
- { VENDOR_UBNT, "SR5", 0x168c, 0x0013, 0x168c, 0x2042, 7, 0 },
- { VENDOR_UBNT, "SR9", 0x168c, 0x0013, 0x7777, 0x2009, 12, -1500 },
- { VENDOR_UBNT, "SR71A", 0x168c, 0x0027, 0x168c, 0x2082, 10, 0 },
- { VENDOR_UBNT, "SR71", 0x168c, 0x0027, 0x0777, 0x4082, 10, 0 },
-#endif
-#ifdef USE_NL80211
- { VENDOR_UBNT, "PicoStation M2", 0x168c, 0x002a, 0x0777, 0xe302, 12, 0 }, /* ToDo: confirm offset */
- { VENDOR_UBNT, "NanoStation M2", 0x168c, 0x002a, 0x0777, 0xe012, 12, 0 }, /* ToDo: confirm offset */
- { VENDOR_UBNT, "NanoStation M5", 0x168c, 0x002a, 0x0777, 0xe005, 5, 0 }, /* ToDo: confirm offset */
- { VENDOR_UBNT, "Bullet M2", 0x168c, 0x002a, 0x0777, 0xe202, 12, 0 },
- { VENDOR_UBNT, "Bullet M5", 0x168c, 0x002a, 0x0777, 0xe805, 5, 0 },
-
- { VENDOR_ATH, "AR9220", 0x168c, 0x0029, 0x168c, 0xa094, 0, 0 },
- { VENDOR_ATH, "AR9223", 0x168c, 0x0029, 0x168c, 0xa095, 0, 0 },
- { VENDOR_ATH, "AR9280", 0x168c, 0x002a, 0x168c, 0xa093, 0, 0 },
- { VENDOR_ATH, "AR9285", 0x168c, 0x002b, 0x168c, 0xa091, 0, 0 },
- { VENDOR_RALINK, "Rt3050", 0x1814, 0x3050, 0x1814, 0x0005, 0, 0 },
- { VENDOR_RALINK, "Rt3052", 0x1814, 0x3052, 0x1814, 0x0008, 0, 0 },
- { VENDOR_RALINK, "Rt3352", 0x1814, 0x3352, 0x1814, 0x000c, 0, 0 },
-#endif
- { NULL }
-};
-
const char * iwinfo_type(const char *ifname)
{
diff --git a/package/iwinfo/src/iwinfo_nl80211.c b/package/iwinfo/src/iwinfo_nl80211.c
index 763ed61c97..dd619e2d6f 100644
--- a/package/iwinfo/src/iwinfo_nl80211.c
+++ b/package/iwinfo/src/iwinfo_nl80211.c
@@ -1,7 +1,7 @@
/*
* iwinfo - Wireless Information Library - NL80211 Backend
*
- * Copyright (C) 2010 Jo-Philipp Wich <xm@subsignal.org>
+ * Copyright (C) 2010-2013 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
@@ -346,23 +346,30 @@ static int nl80211_freq2channel(int freq)
{
if (freq == 2484)
return 14;
-
- if (freq < 2484)
+ else if (freq < 2484)
return (freq - 2407) / 5;
-
- return (freq / 5) - 1000;
+ else if (freq >= 4910 && freq <= 4980)
+ return (freq - 4000) / 5;
+ else
+ return (freq - 5000) / 5;
}
static int nl80211_channel2freq(int channel, const char *band)
{
- if (channel == 14)
- return 2484;
-
- if ((channel < 14) && (!band || band[0] != 'a'))
- return (channel * 5) + 2407;
-
- if (channel > 0)
- return (1000 + channel) * 5;
+ if (!band || band[0] != 'a')
+ {
+ if (channel == 14)
+ return 2484;
+ else if (channel < 14)
+ return (channel * 5) + 2407;
+ }
+ else
+ {
+ if (channel >= 182 && channel <= 196)
+ return (channel * 5) + 4000;
+ else
+ return (channel * 5) + 5000;
+ }
return 0;
}
@@ -448,12 +455,17 @@ static char * nl80211_ifname2phy(const char *ifname)
static char * nl80211_hostapd_info(const char *ifname)
{
+ int mode;
char *phy;
char path[32] = { 0 };
static char buf[4096] = { 0 };
FILE *conf;
- if ((phy = nl80211_ifname2phy(ifname)) != NULL)
+ if (nl80211_get_mode(ifname, &mode))
+ return NULL;
+
+ if ((mode == IWINFO_OPMODE_MASTER || mode == IWINFO_OPMODE_AP_VLAN) &&
+ (phy = nl80211_ifname2phy(ifname)) != NULL)
{
snprintf(path, sizeof(path), "/var/run/hostapd-%s.conf", phy);
@@ -716,50 +728,180 @@ void nl80211_close(void)
}
}
+
+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)
{
- return wext_get_mode(ifname, 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];
+};
+
+static int nl80211_get_ssid_bssid_cb(struct nl_msg *msg, void *arg)
+{
+ int ielen;
+ unsigned char *ie;
+ struct nl80211_ssid_bssid *sb = arg;
+ struct nlattr **tb = nl80211_parse(msg);
+ struct nlattr *bss[NL80211_BSS_MAX + 1];
+
+ static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
+ [NL80211_BSS_INFORMATION_ELEMENTS] = { },
+ [NL80211_BSS_STATUS] = { .type = NLA_U32 },
+ };
+
+ if (!tb[NL80211_ATTR_BSS] ||
+ nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
+ bss_policy) ||
+ !bss[NL80211_BSS_BSSID] ||
+ !bss[NL80211_BSS_STATUS] ||
+ !bss[NL80211_BSS_INFORMATION_ELEMENTS])
+ {
+ return NL_SKIP;
+ }
+
+ switch (nla_get_u32(bss[NL80211_BSS_STATUS]))
+ {
+ case NL80211_BSS_STATUS_ASSOCIATED:
+ case NL80211_BSS_STATUS_AUTHENTICATED:
+ case NL80211_BSS_STATUS_IBSS_JOINED:
+
+ if (sb->ssid)
+ {
+ ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
+ ielen = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
+
+ while (ielen >= 2 && ielen >= ie[1])
+ {
+ if (ie[0] == 0)
+ {
+ memcpy(sb->ssid, ie + 2, min(ie[1], IWINFO_ESSID_MAX_SIZE));
+ return NL_SKIP;
+ }
+
+ ielen -= ie[1] + 2;
+ ie += ie[1] + 2;
+ }
+ }
+ else
+ {
+ sb->bssid[0] = 1;
+ memcpy(sb->bssid + 1, nla_data(bss[NL80211_BSS_BSSID]), 6);
+ return NL_SKIP;
+ }
+
+ default:
+ return NL_SKIP;
+ }
}
int nl80211_get_ssid(const char *ifname, char *buf)
{
- char *ssid;
+ char *res;
+ struct nl80211_msg_conveyor *req;
+ struct nl80211_ssid_bssid sb;
+
+ /* try to find ssid from scan dump results */
+ res = nl80211_phy2ifname(ifname);
+ req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_SCAN, NLM_F_DUMP);
+
+ sb.ssid = buf;
+ *buf = 0;
- if (!wext_get_ssid(ifname, buf))
+ if (req)
{
- return 0;
+ nl80211_send(req, nl80211_get_ssid_bssid_cb, &sb);
+ nl80211_free(req);
}
- else if ((ssid = nl80211_hostapd_info(ifname)) &&
- (ssid = nl80211_getval(ifname, ssid, "ssid")))
+
+ /* failed, try to find from hostapd info */
+ if ((*buf == 0) &&
+ (res = nl80211_hostapd_info(ifname)) &&
+ (res = nl80211_getval(ifname, res, "ssid")))
{
- memcpy(buf, ssid, strlen(ssid));
- return 0;
+ memcpy(buf, res, strlen(res));
}
- return -1;
+ return (*buf == 0) ? -1 : 0;
}
int nl80211_get_bssid(const char *ifname, char *buf)
{
- char *bssid;
- unsigned char mac[6];
+ char *res;
+ struct nl80211_msg_conveyor *req;
+ struct nl80211_ssid_bssid sb;
+
+ /* try to find bssid from scan dump results */
+ res = nl80211_phy2ifname(ifname);
+ req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_SCAN, NLM_F_DUMP);
- if (!wext_get_bssid(ifname, buf))
+ sb.ssid = NULL;
+ sb.bssid[0] = 0;
+
+ if (req)
{
- return 0;
+ nl80211_send(req, nl80211_get_ssid_bssid_cb, &sb);
+ nl80211_free(req);
}
- else if ((bssid = nl80211_hostapd_info(ifname)) &&
- (bssid = nl80211_getval(ifname, bssid, "bssid")))
+
+ /* failed, try to find mac from hostapd info */
+ if ((sb.bssid[0] == 0) &&
+ (res = nl80211_hostapd_info(ifname)) &&
+ (res = nl80211_getval(ifname, res, "bssid")))
{
- mac[0] = strtol(&bssid[0], NULL, 16);
- mac[1] = strtol(&bssid[3], NULL, 16);
- mac[2] = strtol(&bssid[6], NULL, 16);
- mac[3] = strtol(&bssid[9], NULL, 16);
- mac[4] = strtol(&bssid[12], NULL, 16);
- mac[5] = strtol(&bssid[15], NULL, 16);
+ sb.bssid[0] = 1;
+ sb.bssid[1] = strtol(&res[0], NULL, 16);
+ sb.bssid[2] = strtol(&res[3], NULL, 16);
+ sb.bssid[3] = strtol(&res[6], NULL, 16);
+ sb.bssid[4] = strtol(&res[9], NULL, 16);
+ sb.bssid[5] = strtol(&res[12], NULL, 16);
+ sb.bssid[6] = strtol(&res[15], NULL, 16);
+ }
+ if (sb.bssid[0])
+ {
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ sb.bssid[1], sb.bssid[2], sb.bssid[3],
+ sb.bssid[4], sb.bssid[5], sb.bssid[6]);
return 0;
}
@@ -768,7 +910,7 @@ int nl80211_get_bssid(const char *ifname, char *buf)
}
-static int nl80211_get_frequency_cb(struct nl_msg *msg, void *arg)
+static int nl80211_get_frequency_scan_cb(struct nl_msg *msg, void *arg)
{
int *freq = arg;
struct nlattr **attr = nl80211_parse(msg);
@@ -789,28 +931,56 @@ static int nl80211_get_frequency_cb(struct nl_msg *msg, void *arg)
return NL_SKIP;
}
+static int nl80211_get_frequency_info_cb(struct nl_msg *msg, void *arg)
+{
+ int *freq = arg;
+ struct nlattr **tb = nl80211_parse(msg);
+
+ if (tb[NL80211_ATTR_WIPHY_FREQ])
+ *freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
+
+ return NL_SKIP;
+}
+
int nl80211_get_frequency(const char *ifname, int *buf)
{
+ int chn;
char *res, *channel;
struct nl80211_msg_conveyor *req;
+ /* try to find frequency from interface info */
+ res = nl80211_phy2ifname(ifname);
+ req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_INTERFACE, 0);
*buf = 0;
- if ((res = nl80211_hostapd_info(ifname)) &&
+ if (req)
+ {
+ nl80211_send(req, nl80211_get_frequency_info_cb, buf);
+ nl80211_free(req);
+ }
+
+ /* failed, try to find frequency from hostapd info */
+ if ((*buf == 0) &&
+ (res = nl80211_hostapd_info(ifname)) &&
(channel = nl80211_getval(NULL, res, "channel")))
{
- *buf = nl80211_channel2freq(atoi(channel),
- nl80211_getval(NULL, res, "hw_mode"));
+ chn = atoi(channel);
+ *buf = nl80211_channel2freq(chn, nl80211_getval(NULL, res, "hw_mode"));
}
else
{
- res = nl80211_phy2ifname(ifname);
- req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_SCAN, NLM_F_DUMP);
-
- if (req)
+ /* failed, try to find frequency from scan results */
+ if (*buf == 0)
{
- nl80211_send(req, nl80211_get_frequency_cb, buf);
- nl80211_free(req);
+ res = nl80211_phy2ifname(ifname);
+ req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_SCAN,
+ NLM_F_DUMP);
+
+ if (req)
+ {
+ nl80211_send(req, nl80211_get_frequency_scan_cb, buf);
+ nl80211_free(req);
+ }
}
}
@@ -831,6 +1001,18 @@ int nl80211_get_channel(const char *ifname, int *buf)
int nl80211_get_txpower(const char *ifname, int *buf)
{
+#if 0
+ char *res;
+ char path[PATH_MAX];
+
+ res = nl80211_ifname2phy(ifname);
+ snprintf(path, sizeof(path), "/sys/kernel/debug/ieee80211/%s/power",
+ res ? res : ifname);
+
+ if ((*buf = nl80211_readint(path)) > -1)
+ return 0;
+#endif
+
return wext_get_txpower(ifname, buf);
}
@@ -931,9 +1113,6 @@ int nl80211_get_bitrate(const char *ifname, int *buf)
{
struct nl80211_rssi_rate rr;
- if (!wext_get_bitrate(ifname, buf))
- return 0;
-
nl80211_fill_signal(ifname, &rr);
if (rr.rate)
@@ -949,9 +1128,6 @@ int nl80211_get_signal(const char *ifname, int *buf)
{
struct nl80211_rssi_rate rr;
- if (!wext_get_signal(ifname, buf))
- return 0;
-
nl80211_fill_signal(ifname, &rr);
if (rr.rssi)
@@ -1018,43 +1194,39 @@ int nl80211_get_quality(const char *ifname, int *buf)
{
int signal;
- if (wext_get_quality(ifname, buf))
+ if (!nl80211_get_signal(ifname, &signal))
{
- *buf = 0;
-
- if (!nl80211_get_signal(ifname, &signal))
+ /* A positive signal level is usually just a quality
+ * value, pass through as-is */
+ if (signal >= 0)
{
- /* A positive signal level is usually just a quality
- * value, pass through as-is */
- if (signal >= 0)
- {
- *buf = signal;
- }
+ *buf = signal;
+ }
- /* The cfg80211 wext compat layer assumes a signal range
- * of -110 dBm to -40 dBm, the quality value is derived
- * by adding 110 to the signal level */
- else
- {
- if (signal < -110)
- signal = -110;
- else if (signal > -40)
- signal = -40;
+ /* The cfg80211 wext compat layer assumes a signal range
+ * of -110 dBm to -40 dBm, the quality value is derived
+ * by adding 110 to the signal level */
+ else
+ {
+ if (signal < -110)
+ signal = -110;
+ else if (signal > -40)
+ signal = -40;
- *buf = (signal + 110);
- }
+ *buf = (signal + 110);
}
+
+ return 0;
}
- return 0;
+ return -1;
}
int nl80211_get_quality_max(const char *ifname, int *buf)
{
- if (wext_get_quality_max(ifname, buf))
- /* The cfg80211 wext compat layer assumes a maximum
- * quality of 70 */
- *buf = 70;
+ /* The cfg80211 wext compat layer assumes a maximum
+ * quality of 70 */
+ *buf = 70;
return 0;
}
diff --git a/package/iwinfo/src/iwinfo_utils.c b/package/iwinfo/src/iwinfo_utils.c
index 164e51f847..b6760c3486 100644
--- a/package/iwinfo/src/iwinfo_utils.c
+++ b/package/iwinfo/src/iwinfo_utils.c
@@ -28,7 +28,7 @@ static int ioctl_socket = -1;
static int iwinfo_ioctl_socket(void)
{
/* Prepare socket */
- if( ioctl_socket == -1 )
+ if (ioctl_socket == -1)
{
ioctl_socket = socket(AF_INET, SOCK_DGRAM, 0);
fcntl(ioctl_socket, F_SETFD, fcntl(ioctl_socket, F_GETFD) | FD_CLOEXEC);
@@ -82,7 +82,7 @@ int iwinfo_ifup(const char *ifname)
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- if( iwinfo_ioctl(SIOCGIFFLAGS, &ifr) )
+ if (iwinfo_ioctl(SIOCGIFFLAGS, &ifr))
return 0;
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
@@ -96,7 +96,7 @@ int iwinfo_ifdown(const char *ifname)
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- if( iwinfo_ioctl(SIOCGIFFLAGS, &ifr) )
+ if (iwinfo_ioctl(SIOCGIFFLAGS, &ifr))
return 0;
ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
@@ -110,7 +110,7 @@ int iwinfo_ifmac(const char *ifname)
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- if( iwinfo_ioctl(SIOCGIFHWADDR, &ifr) )
+ if (iwinfo_ioctl(SIOCGIFHWADDR, &ifr))
return 0;
ifr.ifr_hwaddr.sa_data[1]++;
@@ -121,33 +121,54 @@ int iwinfo_ifmac(const char *ifname)
void iwinfo_close(void)
{
- if( ioctl_socket > -1 )
+ if (ioctl_socket > -1)
close(ioctl_socket);
+
+ ioctl_socket = -1;
}
struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id)
{
- const struct iwinfo_hardware_entry *e;
+ FILE *db;
+ char buf[256] = { 0 };
+ static struct iwinfo_hardware_entry e;
+
+ if (!(db = fopen(IWINFO_HARDWARE_FILE, "r")))
+ return NULL;
- for (e = IWINFO_HARDWARE_ENTRIES; e->vendor_name; e++)
+ while (fgets(buf, sizeof(buf) - 1, db) != NULL)
{
- if ((e->vendor_id != 0xffff) && (e->vendor_id != id->vendor_id))
+ memset(&e, 0, sizeof(e));
+
+ if (sscanf(buf, "%hx %hx %hx %hx %hd %hd \"%63[^\"]\" \"%63[^\"]\"",
+ &e.vendor_id, &e.device_id,
+ &e.subsystem_vendor_id, &e.subsystem_device_id,
+ &e.txpower_offset, &e.frequency_offset,
+ e.vendor_name, e.device_name) < 8)
+ continue;
+
+ if ((e.vendor_id != 0xffff) && (e.vendor_id != id->vendor_id))
continue;
- if ((e->device_id != 0xffff) && (e->device_id != id->device_id))
+ if ((e.device_id != 0xffff) && (e.device_id != id->device_id))
continue;
- if ((e->subsystem_vendor_id != 0xffff) &&
- (e->subsystem_vendor_id != id->subsystem_vendor_id))
+ if ((e.subsystem_vendor_id != 0xffff) &&
+ (e.subsystem_vendor_id != id->subsystem_vendor_id))
continue;
- if ((e->subsystem_device_id != 0xffff) &&
- (e->subsystem_device_id != id->subsystem_device_id))
+ if ((e.subsystem_device_id != 0xffff) &&
+ (e.subsystem_device_id != id->subsystem_device_id))
continue;
- return (struct iwinfo_hardware_entry *)e;
+ break;
}
+ fclose(db);
+
+ if (e.device_name[0])
+ return &e;
+
return NULL;
}