From 486770051bda52c6c763f82a68fa0ccfdbd1d908 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sat, 3 Dec 2011 00:22:25 +0000 Subject: [PATCH] libiwinfo: reimplement iwinfo.lua in C and package it as "iwinfo" --- contrib/package/iwinfo/Makefile | 24 +- contrib/package/iwinfo/src/Makefile | 33 +- contrib/package/iwinfo/src/iwinfo.lua | 217 -------- contrib/package/iwinfo/src/iwinfo_cli.c | 683 ++++++++++++++++++++++++ 4 files changed, 724 insertions(+), 233 deletions(-) delete mode 100755 contrib/package/iwinfo/src/iwinfo.lua create mode 100644 contrib/package/iwinfo/src/iwinfo_cli.c diff --git a/contrib/package/iwinfo/Makefile b/contrib/package/iwinfo/Makefile index a8990294d..a89bd1447 100644 --- a/contrib/package/iwinfo/Makefile +++ b/contrib/package/iwinfo/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libiwinfo -PKG_RELEASE:=17 +PKG_RELEASE:=18 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) @@ -26,6 +26,7 @@ define Package/libiwinfo/description madwifi, nl80211 and wext driver interfaces. endef + define Package/libiwinfo-lua SUBMENU:=Lua SECTION:=lang @@ -39,6 +40,19 @@ define Package/libiwinfo-lua/description backends. endef + +define Package/iwinfo + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Generalized Wireless Information utility + DEPENDS:=+libiwinfo +endef + +define Package/iwinfo/description + Command line frontend for the wireless information library. +endef + + define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ @@ -81,11 +95,15 @@ define Package/libiwinfo/install endef define Package/libiwinfo-lua/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo.lua $(1)/usr/bin/iwinfo $(INSTALL_DIR) $(1)/usr/lib/lua $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo.so $(1)/usr/lib/lua/iwinfo.so endef +define Package/iwinfo/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo $(1)/usr/bin/iwinfo +endef + $(eval $(call BuildPackage,libiwinfo)) $(eval $(call BuildPackage,libiwinfo-lua)) +$(eval $(call BuildPackage,iwinfo)) diff --git a/contrib/package/iwinfo/src/Makefile b/contrib/package/iwinfo/src/Makefile index f8e624412..572bef9f9 100644 --- a/contrib/package/iwinfo/src/Makefile +++ b/contrib/package/iwinfo/src/Makefile @@ -1,37 +1,44 @@ IWINFO_BACKENDS = $(BACKENDS) IWINFO_CFLAGS = $(CFLAGS) -std=gnu99 -fstrict-aliasing -Iinclude -IWINFO_LDFLAGS = $(LDFLAGS) -shared -IWINFO_SO = libiwinfo.so -IWINFO_OBJ = iwinfo_utils.o iwinfo_wext.o iwinfo_wext_scan.o iwinfo_lib.o +IWINFO_LIB = libiwinfo.so +IWINFO_LIB_LDFLAGS = $(LDFLAGS) -shared +IWINFO_LIB_OBJ = iwinfo_utils.o iwinfo_wext.o iwinfo_wext_scan.o iwinfo_lib.o +IWINFO_LUA = iwinfo.so IWINFO_LUA_LDFLAGS = $(LDFLAGS) -shared -L. -liwinfo -llua -IWINFO_LUA_SO = iwinfo.so IWINFO_LUA_OBJ = iwinfo_lua.o +IWINFO_CLI = iwinfo +IWINFO_CLI_LDFLAGS = $(LDFLAGS) -L. -liwinfo +IWINFO_CLI_OBJ = iwinfo_cli.o + + ifneq ($(filter wl,$(IWINFO_BACKENDS)),) IWINFO_CFLAGS += -DUSE_WL - IWINFO_OBJ += iwinfo_wl.o + IWINFO_LIB_OBJ += iwinfo_wl.o endif ifneq ($(filter madwifi,$(IWINFO_BACKENDS)),) IWINFO_CFLAGS += -DUSE_MADWIFI - IWINFO_OBJ += iwinfo_madwifi.o + IWINFO_LIB_OBJ += iwinfo_madwifi.o endif ifneq ($(filter nl80211,$(IWINFO_BACKENDS)),) - IWINFO_CFLAGS += -DUSE_NL80211 - IWINFO_LDFLAGS += -lnl-tiny - IWINFO_OBJ += iwinfo_nl80211.o + IWINFO_CFLAGS += -DUSE_NL80211 + IWINFO_CLI_LDFLAGS += -lnl-tiny + IWINFO_LIB_LDFLAGS += -lnl-tiny + IWINFO_LIB_OBJ += iwinfo_nl80211.o endif %.o: %.c $(CC) $(IWINFO_CFLAGS) $(FPIC) -c -o $@ $< -compile: clean $(IWINFO_OBJ) $(IWINFO_LUA_OBJ) - $(LD) $(IWINFO_LDFLAGS) -o $(IWINFO_SO) $(IWINFO_OBJ) - $(LD) $(IWINFO_LUA_LDFLAGS) -o $(IWINFO_LUA_SO) $(IWINFO_LUA_OBJ) +compile: clean $(IWINFO_LIB_OBJ) $(IWINFO_LUA_OBJ) $(IWINFO_CLI_OBJ) + $(CC) $(IWINFO_LIB_LDFLAGS) -o $(IWINFO_LIB) $(IWINFO_LIB_OBJ) + $(CC) $(IWINFO_LUA_LDFLAGS) -o $(IWINFO_LUA) $(IWINFO_LUA_OBJ) + $(CC) $(IWINFO_CLI_LDFLAGS) -o $(IWINFO_CLI) $(IWINFO_CLI_OBJ) clean: - rm -f *.o $(IWINFO_SO) $(IWINFO_LUA_SO) + rm -f *.o $(IWINFO_LIB) $(IWINFO_LUA) $(IWINFO_CLI) diff --git a/contrib/package/iwinfo/src/iwinfo.lua b/contrib/package/iwinfo/src/iwinfo.lua deleted file mode 100755 index 811022052..000000000 --- a/contrib/package/iwinfo/src/iwinfo.lua +++ /dev/null @@ -1,217 +0,0 @@ -#!/usr/bin/lua - -require "iwinfo" - -function printf(fmt, ...) - print(string.format(fmt, ...)) -end - -function s(x) - if x == nil then - return "?" - else - return tostring(x) - end -end - -function n(x) - if x == nil then - return 0 - else - return tonumber(x) - end -end - -function print_info(api, dev) - local iw = iwinfo[api] - local enc = iw.encryption(dev) - - local function hwmode() - local m = iw.hwmodelist(dev) - if m then - local s = "802.11" - if m.a then s = s.."a" end - if m.b then s = s.."b" end - if m.g then s = s.."g" end - if m.n then s = s.."n" end - return s - else - return "?" - end - end - - printf("%-9s ESSID: \"%s\"", - dev, s(iw.ssid(dev))) - - printf(" Access Point: %s", - s(iw.bssid(dev))) - - printf(" Type: %s HW Mode(s): %s", - api, hwmode()) - - printf(" Mode: %s Channel: %d (%.3f GHz)", - s(iw.mode(dev)), n(iw.channel(dev)), n(iw.frequency(dev)) / 1000) - - printf(" Tx-Power: %s dBm Link Quality: %s/%s", - s(iw.txpower(dev)), s(iw.quality(dev)), s(iw.quality_max(dev))) - - printf(" Signal: %s dBm Noise: %s dBm", - s(iw.signal(dev)), s(iw.noise(dev))) - - printf(" Bit Rate: %.1f MBit/s", - n(iw.bitrate(dev)) / 1000) - - printf(" Encryption: %s", - s(enc and enc.description or "None")) - - printf(" Supports VAPs: %s", - iw.mbssid_support(dev) and "yes" or "no") - - print("") -end - -function print_scan(api, dev) - local iw = iwinfo[api] - local sr = iw.scanlist(dev) - local si, se - - if sr and #sr > 0 then - for si, se in ipairs(sr) do - printf("Cell %02d - Address: %s", si, se.bssid) - printf(" ESSID: \"%s\"", - s(se.ssid)) - - printf(" Mode: %s Channel: %d", - s(se.mode), n(se.channel)) - - printf(" Signal: %s dBm Quality: %d/%d", - s(se.signal), n(se.quality), n(se.quality_max)) - - printf(" Encryption: %s", - s(se.encryption.description or "None")) - - print("") - end - else - print("No scan results or scanning not possible") - print("") - end -end - -function print_txpwrlist(api, dev) - local iw = iwinfo[api] - local pl = iw.txpwrlist(dev) - local cp = n(iw.txpower(dev)) - local pe - - if pl and #pl > 0 then - for _, pe in ipairs(pl) do - printf("%s%3d dBm (%4d mW)", - (cp == pe.dbm) and "*" or " ", - n(pe.dbm), n(pe.mw)) - end - else - print("No TX power information available") - end - - print("") -end - -function print_freqlist(api, dev) - local iw = iwinfo[api] - local fl = iw.freqlist(dev) - local cc = n(iw.channel(dev)) - local fe - - if fl and #fl > 0 then - for _, fe in ipairs(fl) do - printf("%s %.3f GHz (Channel %d)%s", - (cc == fe.channel) and "*" or " ", - n(fe.mhz) / 1000, n(fe.channel), - fe.restricted and " [restricted]" or "") - end - else - print("No frequency information available") - end - - print("") -end - -function print_assoclist(api, dev) - local iw = iwinfo[api] - local al = iw.assoclist(dev) - local ns = iw.noise(dev) - local ai, ae - - if al and next(al) then - for ai, ae in pairs(al) do - printf("%s %s dBm / %d dBm (SNR %d)", - ai, s(ae.signal), ns, n(ae.signal) - ns) - end - else - print("No client connected or no information available") - end - - print("") -end - -function print_countrylist(api, dev) - local iw = iwinfo[api] - local cl = iw.countrylist(dev) - local cc = iw.country(dev) - local ce - - if cl and #cl > 0 then - for _, ce in ipairs(cl) do - printf("%s %4s %s", - (cc == ce.alpha2) and "*" or " ", - ce.ccode, ce.name) - end - else - print("No country code information available") - end - - print("") -end - - -if #arg ~= 2 then - print("Usage:") - print(" iwinfo info") - print(" iwinfo scan") - print(" iwinfo txpowerlist") - print(" iwinfo freqlist") - print(" iwinfo assoclist") - print(" iwinfo countrylist") - os.exit(1) -end - -local dev = arg[1] -local api = iwinfo.type(dev) -if not api then - print("No such wireless device: " .. dev) - os.exit(1) -end - - -if arg[2]:match("^i") then - print_info(api, dev) - -elseif arg[2]:match("^s") then - print_scan(api, dev) - -elseif arg[2]:match("^t") then - print_txpwrlist(api, dev) - -elseif arg[2]:match("^f") then - print_freqlist(api, dev) - -elseif arg[2]:match("^a") then - print_assoclist(api, dev) - -elseif arg[2]:match("^c") then - print_countrylist(api, dev) - -else - print("Unknown command: " .. arg[2]) -end diff --git a/contrib/package/iwinfo/src/iwinfo_cli.c b/contrib/package/iwinfo/src/iwinfo_cli.c new file mode 100644 index 000000000..4229b19f5 --- /dev/null +++ b/contrib/package/iwinfo/src/iwinfo_cli.c @@ -0,0 +1,683 @@ +/* + * iwinfo - Wireless Information Library - Command line frontend + * + * Copyright (C) 2011 Jo-Philipp Wich + * + * 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/. + */ + +#include + +#include "iwinfo.h" + + +static char * format_bssid(unsigned char *mac) +{ + static char buf[18]; + + snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + return buf; +} + +static char * format_ssid(char *ssid) +{ + static char buf[IWINFO_ESSID_MAX_SIZE+3]; + + if (ssid && ssid[0]) + snprintf(buf, sizeof(buf), "\"%s\"", ssid); + else + snprintf(buf, sizeof(buf), "unknown"); + + return buf; +} + +static char * format_channel(int ch) +{ + static char buf[8]; + + if (ch <= 0) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "%d", ch); + + return buf; +} + +static char * format_frequency(int freq) +{ + static char buf[10]; + + if (freq <= 0) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "%.3f GHz", ((float)freq / 1000.0)); + + return buf; +} + +static char * format_txpower(int pwr) +{ + static char buf[10]; + + if (pwr < 0) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "%d dBm", pwr); + + return buf; +} + +static char * format_quality(int qual) +{ + static char buf[8]; + + if (qual < 0) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "%d", qual); + + return buf; +} + +static char * format_quality_max(int qmax) +{ + static char buf[8]; + + if (qmax < 0) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "%d", qmax); + + return buf; +} + +static char * format_signal(int sig) +{ + static char buf[10]; + + if (!sig) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "%d dBm", sig); + + return buf; +} + +static char * format_noise(int noise) +{ + static char buf[10]; + + if (!noise) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "%d dBm", noise); + + return buf; +} + +static char * format_rate(int rate) +{ + static char buf[14]; + + if (rate <= 0) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "%.1f MBit/s", ((float)rate / 1000.0)); + + return buf; +} + +static char * format_enc_ciphers(int ciphers) +{ + static char str[128] = { 0 }; + char *pos = str; + + if (ciphers & IWINFO_CIPHER_WEP40) + pos += sprintf(pos, "WEP-40, "); + + if (ciphers & IWINFO_CIPHER_WEP104) + pos += sprintf(pos, "WEP-104, "); + + if (ciphers & IWINFO_CIPHER_TKIP) + pos += sprintf(pos, "TKIP, "); + + if (ciphers & IWINFO_CIPHER_CCMP) + pos += sprintf(pos, "CCMP, "); + + if (ciphers & IWINFO_CIPHER_WRAP) + pos += sprintf(pos, "WRAP, "); + + if (ciphers & IWINFO_CIPHER_AESOCB) + pos += sprintf(pos, "AES-OCB, "); + + if (ciphers & IWINFO_CIPHER_CKIP) + pos += sprintf(pos, "CKIP, "); + + if (!ciphers || (ciphers & IWINFO_CIPHER_NONE)) + pos += sprintf(pos, "NONE, "); + + *(pos - 2) = 0; + + return str; +} + +static char * format_enc_suites(int suites) +{ + static char str[64] = { 0 }; + char *pos = str; + + if (suites & IWINFO_KMGMT_PSK) + pos += sprintf(pos, "PSK/"); + + if (suites & IWINFO_KMGMT_8021x) + pos += sprintf(pos, "802.1X/"); + + if (!suites || (suites & IWINFO_KMGMT_NONE)) + pos += sprintf(pos, "NONE/"); + + *(pos - 1) = 0; + + return str; +} + +static char * format_encryption(struct iwinfo_crypto_entry *c) +{ + static char buf[512]; + + if (!c) + { + snprintf(buf, sizeof(buf), "unknown"); + } + else if (c->enabled) + { + /* WEP */ + if (c->auth_algs && !c->wpa_version) + { + if ((c->auth_algs & IWINFO_AUTH_OPEN) && + (c->auth_algs & IWINFO_AUTH_SHARED)) + { + snprintf(buf, sizeof(buf), "WEP Open/Shared (%s)", + format_enc_ciphers(c->pair_ciphers)); + } + else if (c->auth_algs & IWINFO_AUTH_OPEN) + { + snprintf(buf, sizeof(buf), "WEP Open System (%s)", + format_enc_ciphers(c->pair_ciphers)); + } + else if (c->auth_algs & IWINFO_AUTH_SHARED) + { + snprintf(buf, sizeof(buf), "WEP Shared Auth (%s)", + format_enc_ciphers(c->pair_ciphers)); + } + } + + /* WPA */ + else if (c->wpa_version) + { + switch (c->wpa_version) { + case 3: + snprintf(buf, sizeof(buf), "mixed WPA/WPA2 %s (%s)", + format_enc_suites(c->auth_suites), + format_enc_ciphers(c->pair_ciphers & c->group_ciphers)); + break; + + case 2: + snprintf(buf, sizeof(buf), "WPA2 %s (%s)", + format_enc_suites(c->auth_suites), + format_enc_ciphers(c->pair_ciphers & c->group_ciphers)); + break; + + case 1: + snprintf(buf, sizeof(buf), "WPA %s (%s)", + format_enc_suites(c->auth_suites), + format_enc_ciphers(c->pair_ciphers & c->group_ciphers)); + break; + } + } + else + { + snprintf(buf, sizeof(buf), "none"); + } + } + else + { + snprintf(buf, sizeof(buf), "none"); + } + + return buf; +} + +static char * format_hwmodes(int modes) +{ + static char buf[12]; + + if (modes <= 0) + snprintf(buf, sizeof(buf), "unknown"); + else + snprintf(buf, sizeof(buf), "802.11%s%s%s%s", + (modes & IWINFO_80211_A) ? "a" : "", + (modes & IWINFO_80211_B) ? "b" : "", + (modes & IWINFO_80211_G) ? "g" : "", + (modes & IWINFO_80211_N) ? "n" : ""); + + return buf; +} + + +static const char * print_type(const struct iwinfo_ops *iw, const char *ifname) +{ + const char *type = iwinfo_type(ifname); + return type ? type : "unknown"; +} + +static char * print_ssid(const struct iwinfo_ops *iw, const char *ifname) +{ + char buf[IWINFO_ESSID_MAX_SIZE+1] = { 0 }; + + if (iw->ssid(ifname, buf)) + memset(buf, 0, sizeof(buf)); + + return format_ssid(buf); +} + +static char * print_bssid(const struct iwinfo_ops *iw, const char *ifname) +{ + static char buf[18] = { 0 }; + + if (iw->bssid(ifname, buf)) + snprintf(buf, sizeof(buf), "00:00:00:00:00:00"); + + return buf; +} + +static char * print_mode(const struct iwinfo_ops *iw, const char *ifname) +{ + static char buf[128]; + + if (iw->mode(ifname, buf)) + snprintf(buf, sizeof(buf), "unknown"); + + return buf; +} + +static char * print_channel(const struct iwinfo_ops *iw, const char *ifname) +{ + int ch; + if (iw->channel(ifname, &ch)) + ch = -1; + + return format_channel(ch); +} + +static char * print_frequency(const struct iwinfo_ops *iw, const char *ifname) +{ + int freq; + if (iw->frequency(ifname, &freq)) + freq = -1; + + return format_frequency(freq); +} + +static char * print_txpower(const struct iwinfo_ops *iw, const char *ifname) +{ + int pwr; + if (iw->txpower(ifname, &pwr)) + pwr = -1; + + return format_txpower(pwr); +} + +static char * print_quality(const struct iwinfo_ops *iw, const char *ifname) +{ + int qual; + if (iw->quality(ifname, &qual)) + qual = -1; + + return format_quality(qual); +} + +static char * print_quality_max(const struct iwinfo_ops *iw, const char *ifname) +{ + int qmax; + if (iw->quality_max(ifname, &qmax)) + qmax = -1; + + return format_quality_max(qmax); +} + +static char * print_signal(const struct iwinfo_ops *iw, const char *ifname) +{ + int sig; + if (iw->signal(ifname, &sig)) + sig = 0; + + return format_signal(sig); +} + +static char * print_noise(const struct iwinfo_ops *iw, const char *ifname) +{ + int noise; + if (iw->noise(ifname, &noise)) + noise = 0; + + return format_noise(noise); +} + +static char * print_rate(const struct iwinfo_ops *iw, const char *ifname) +{ + int rate; + if (iw->bitrate(ifname, &rate)) + rate = -1; + + return format_rate(rate); +} + +static char * print_encryption(const struct iwinfo_ops *iw, const char *ifname) +{ + struct iwinfo_crypto_entry c = { 0 }; + if (iw->encryption(ifname, (char *)&c)) + return format_encryption(NULL); + + return format_encryption(&c); +} + +static char * print_hwmodes(const struct iwinfo_ops *iw, const char *ifname) +{ + int modes; + if (iw->hwmodelist(ifname, &modes)) + modes = -1; + + return format_hwmodes(modes); +} + +static char * print_mbssid_supp(const struct iwinfo_ops *iw, const char *ifname) +{ + int supp; + static char buf[4]; + + if (iw->mbssid_support(ifname, &supp)) + snprintf(buf, sizeof(buf), "no"); + else + snprintf(buf, sizeof(buf), "%s", supp ? "yes" : "no"); + + return buf; +} + + +static void print_info(const struct iwinfo_ops *iw, const char *ifname) +{ + printf("%-9s ESSID: %s\n", + ifname, + print_ssid(iw, ifname)); + printf(" Access Point: %s\n", + print_bssid(iw, ifname)); + printf(" Type: %s HW Mode(s): %s\n", + print_type(iw, ifname), + print_hwmodes(iw, ifname)); + printf(" Mode: %s Channel: %s (%s)\n", + print_mode(iw, ifname), + print_channel(iw, ifname), + print_frequency(iw, ifname)); + printf(" Tx-Power: %s Link Quality: %s/%s\n", + print_txpower(iw, ifname), + print_quality(iw, ifname), + print_quality_max(iw, ifname)); + printf(" Signal: %s Noise: %s\n", + print_signal(iw, ifname), + print_noise(iw, ifname)); + printf(" Bit Rate: %s\n", + print_rate(iw, ifname)); + printf(" Encryption: %s\n", + print_encryption(iw, ifname)); + printf(" Supports VAPs: %s\n", + print_mbssid_supp(iw, ifname)); +} + + +static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) +{ + int i, x, len; + char buf[IWINFO_BUFSIZE]; + struct iwinfo_scanlist_entry *e; + + if (iw->scanlist(ifname, buf, &len)) + { + printf("Scanning not possible\n\n"); + return; + } + else if (len <= 0) + { + printf("No scan results\n\n"); + return; + } + + for (i = 0, x = 1; i < len; i += sizeof(struct iwinfo_scanlist_entry), x++) + { + e = (struct iwinfo_scanlist_entry *) &buf[i]; + + printf("Cell %02d - Address: %s\n", + x, + format_bssid(e->mac)); + printf(" ESSID: %s\n", + format_ssid(e->ssid)); + printf(" Mode: %s Channel: %s\n", + e->mode ? (char *)e->mode : "unknown", + format_channel(e->channel)); + printf(" Signal: %s Quality: %s/%s\n", + format_signal(e->signal - 0x100), + format_quality(e->quality), + format_quality_max(e->quality_max)); + printf(" Encryption: %s\n\n", + format_encryption(&e->crypto)); + } +} + + +static void print_txpwrlist(const struct iwinfo_ops *iw, const char *ifname) +{ + int len, pwr, i; + char buf[IWINFO_BUFSIZE]; + struct iwinfo_txpwrlist_entry *e; + + if (iw->txpwrlist(ifname, buf, &len) || len <= 0) + { + printf("No TX power information available\n"); + return; + } + + if (iw->txpower(ifname, &pwr)) + pwr = -1; + + for (i = 0; i < len; i += sizeof(struct iwinfo_txpwrlist_entry)) + { + e = (struct iwinfo_txpwrlist_entry *) &buf[i]; + + printf("%s%3d dBm (%4d mW)\n", + (pwr == e->dbm) ? "*" : " ", + e->dbm, + e->mw); + } +} + + +static void print_freqlist(const struct iwinfo_ops *iw, const char *ifname) +{ + int i, len, ch; + char buf[IWINFO_BUFSIZE]; + struct iwinfo_freqlist_entry *e; + + if (iw->freqlist(ifname, buf, &len) || len <= 0) + { + printf("No frequency information available\n"); + return; + } + + if (iw->channel(ifname, &ch)) + ch = -1; + + for (i = 0; i < len; i += sizeof(struct iwinfo_freqlist_entry)) + { + e = (struct iwinfo_freqlist_entry *) &buf[i]; + + printf("%s %s (Channel %s)%s\n", + (ch == e->channel) ? "*" : " ", + format_frequency(e->mhz), + format_channel(e->channel), + e->restricted ? " [restricted]" : ""); + } +} + + +static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname) +{ + int i, len; + char buf[IWINFO_BUFSIZE]; + struct iwinfo_assoclist_entry *e; + + if (iw->assoclist(ifname, buf, &len)) + { + printf("No information available\n"); + return; + } + else if (len <= 0) + { + printf("No station connected\n"); + return; + } + + for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) + { + e = (struct iwinfo_assoclist_entry *) &buf[i]; + + printf("%s %s / %s (SNR %d)\n", + format_bssid(e->mac), + format_signal(e->signal), + format_noise(e->noise), + (e->signal - e->noise)); + } +} + + +static char * lookup_country(char *buf, int len, int iso3166) +{ + int i; + struct iwinfo_country_entry *c; + + for (i = 0; i < len; i += sizeof(struct iwinfo_country_entry)) + { + c = (struct iwinfo_country_entry *) &buf[i]; + + if (c->iso3166 == iso3166) + return c->ccode; + } + + return NULL; +} + +static void print_countrylist(const struct iwinfo_ops *iw, const char *ifname) +{ + int len; + char buf[IWINFO_BUFSIZE]; + char *ccode; + char curcode[3]; + const struct iwinfo_iso3166_label *l; + + if (iw->countrylist(ifname, buf, &len)) + { + printf("No country code information available\n"); + return; + } + + if (iw->country(ifname, curcode)) + memset(curcode, 0, sizeof(curcode)); + + for (l = IWINFO_ISO3166_NAMES; l->iso3166; l++) + { + if ((ccode = lookup_country(buf, len, l->iso3166)) != NULL) + { + printf("%s %4s %c%c\n", + strncmp(ccode, curcode, 2) ? " " : "*", + ccode, (l->iso3166 / 256), (l->iso3166 % 256)); + } + } +} + + +int main(int argc, char **argv) +{ + int i; + const struct iwinfo_ops *iw; + + if (argc < 3) + { + fprintf(stderr, + "Usage:\n" + " iwinfo info\n" + " iwinfo scan\n" + " iwinfo txpowerlist\n" + " iwinfo freqlist\n" + " iwinfo assoclist\n" + " iwinfo countrylist\n" + ); + + return 1; + } + + iw = iwinfo_backend(argv[1]); + + if (!iw) + { + fprintf(stderr, "No such wireless device: %s\n", argv[1]); + return 1; + } + + for (i = 2; i < argc; i++) + { + switch(argv[i][0]) + { + case 'i': + print_info(iw, argv[1]); + break; + + case 's': + print_scanlist(iw, argv[1]); + break; + + case 't': + print_txpwrlist(iw, argv[1]); + break; + + case 'f': + print_freqlist(iw, argv[1]); + break; + + case 'a': + print_assoclist(iw, argv[1]); + break; + + case 'c': + print_countrylist(iw, argv[1]); + break; + + default: + fprintf(stderr, "Unknown command: %s\n", argv[i]); + return 1; + } + } + + iwinfo_finish(); + + return 0; +} -- 2.25.1