From dabf916db20da0013033efb763b632aecaea20a5 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Tue, 12 Oct 2010 04:56:36 +0000 Subject: [PATCH] libiwinfo: support txpwrlist(), freqlist() and countrylist() for radioX pseudodevices in nl80211 backend, implement __gc methamethod --- contrib/package/iwinfo/src/iwinfo_lualib.c | 16 +++ contrib/package/iwinfo/src/iwinfo_madwifi.c | 6 ++ contrib/package/iwinfo/src/iwinfo_madwifi.h | 1 + contrib/package/iwinfo/src/iwinfo_nl80211.c | 99 ++++++++++++++++--- contrib/package/iwinfo/src/iwinfo_nl80211.h | 1 + contrib/package/iwinfo/src/iwinfo_wext.c | 8 ++ contrib/package/iwinfo/src/iwinfo_wext.h | 2 + contrib/package/iwinfo/src/iwinfo_wext_scan.c | 6 ++ contrib/package/iwinfo/src/iwinfo_wl.c | 6 ++ contrib/package/iwinfo/src/iwinfo_wl.h | 1 + 10 files changed, 130 insertions(+), 16 deletions(-) diff --git a/contrib/package/iwinfo/src/iwinfo_lualib.c b/contrib/package/iwinfo/src/iwinfo_lualib.c index 1377ffeb2..312a3dae7 100644 --- a/contrib/package/iwinfo/src/iwinfo_lualib.c +++ b/contrib/package/iwinfo/src/iwinfo_lualib.c @@ -308,6 +308,21 @@ static int iwinfo_L_type(lua_State *L) return 1; } +/* Shutdown backends */ +static int iwinfo_L__gc(lua_State *L) +{ +#ifdef USE_WL + wl_close(); +#endif +#ifdef USE_MADWIFI + madwifi_close(); +#endif +#ifdef USE_NL80211 + nl80211_close(); +#endif + wext_close(); +} + /* * Build a short textual description of the crypto info */ @@ -930,6 +945,7 @@ static const luaL_reg R_wext[] = { /* Common */ static const luaL_reg R_common[] = { { "type", iwinfo_L_type }, + { "__gc", iwinfo_L__gc }, { NULL, NULL } }; diff --git a/contrib/package/iwinfo/src/iwinfo_madwifi.c b/contrib/package/iwinfo/src/iwinfo_madwifi.c index daecf5df3..9c3bb2688 100644 --- a/contrib/package/iwinfo/src/iwinfo_madwifi.c +++ b/contrib/package/iwinfo/src/iwinfo_madwifi.c @@ -292,6 +292,12 @@ int madwifi_probe(const char *ifname) return ( !!madwifi_isvap(ifname, NULL) || madwifi_iswifi(ifname) ); } +void madwifi_close(void) +{ + if( ioctl_socket > -1 ) + close(ioctl_socket); +} + int madwifi_get_mode(const char *ifname, char *buf) { return wext_get_mode(ifname, buf); diff --git a/contrib/package/iwinfo/src/iwinfo_madwifi.h b/contrib/package/iwinfo/src/iwinfo_madwifi.h index 1f2291838..7e0129c9e 100644 --- a/contrib/package/iwinfo/src/iwinfo_madwifi.h +++ b/contrib/package/iwinfo/src/iwinfo_madwifi.h @@ -44,5 +44,6 @@ int madwifi_get_scanlist(const char *ifname, char *buf, int *len); int madwifi_get_freqlist(const char *ifname, char *buf, int *len); int madwifi_get_countrylist(const char *ifname, char *buf, int *len); int madwifi_get_mbssid_support(const char *ifname, int *buf); +void madwifi_close(void); #endif diff --git a/contrib/package/iwinfo/src/iwinfo_nl80211.c b/contrib/package/iwinfo/src/iwinfo_nl80211.c index 7d2a96a6c..a693d53db 100644 --- a/contrib/package/iwinfo/src/iwinfo_nl80211.c +++ b/contrib/package/iwinfo/src/iwinfo_nl80211.c @@ -77,17 +77,7 @@ static int nl80211_init(void) err: - if( nls && nls->nl_sock ) - nl_socket_free(nls->nl_sock); - - if( nls && nls->nl_cache ) - nl_cache_free(nls->nl_cache); - - if( nls ) - free(nls); - - nls = NULL; - + nl80211_close(); return err; } @@ -148,19 +138,21 @@ static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, in { static struct nl80211_msg_conveyor cv; - int ifidx; + int ifidx = -1, phyidx = -1; struct nl_msg *req = NULL; struct nl_cb *cb = NULL; if( nl80211_init() < 0 ) goto err; - if( !strncmp(ifname, "mon.", 4) ) + if( !strncmp(ifname, "radio", 5) ) + phyidx = atoi(&ifname[5]); + else if( !strncmp(ifname, "mon.", 4) ) ifidx = if_nametoindex(&ifname[4]); else ifidx = if_nametoindex(ifname); - if( ifidx < 0 ) + if( (ifidx < 0) && (phyidx < 0) ) return NULL; req = nlmsg_alloc(); @@ -174,7 +166,11 @@ static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, in genlmsg_put(req, 0, 0, genl_family_get_id(nls->nl80211), 0, flags, cmd, 0); - NLA_PUT_U32(req, NL80211_ATTR_IFINDEX, ifidx); + if( ifidx > -1 ) + NLA_PUT_U32(req, NL80211_ATTR_IFINDEX, ifidx); + + if( phyidx > -1 ) + NLA_PUT_U32(req, NL80211_ATTR_WIPHY, phyidx); nlmsg_get(req); @@ -395,6 +391,21 @@ int nl80211_probe(const char *ifname) return !!nl80211_ifname2phy(ifname); } +void nl80211_close(void) +{ + if( nls ) + { + if( nls->nl_sock ) + nl_socket_free(nls->nl_sock); + + if( nls->nl_cache ) + nl_cache_free(nls->nl_cache); + + free(nls); + nls = NULL; + } +} + int nl80211_get_mode(const char *ifname, char *buf) { return wext_get_mode(ifname, buf); @@ -1171,7 +1182,63 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len) int nl80211_get_freqlist(const char *ifname, char *buf, int *len) { - return wext_get_freqlist(ifname, buf, len); + char *phy; + int count = 0, bands_remain, freqs_remain; + struct nl80211_msg_conveyor *req, *res; + struct nlattr *bands[NL80211_BAND_ATTR_MAX + 1]; + struct nlattr *freqs[NL80211_FREQUENCY_ATTR_MAX + 1]; + struct nlattr *band, *freq; + struct iwinfo_freqlist_entry *e = (struct iwinfo_freqlist_entry *)buf; + + static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { + [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 }, + [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 }, + }; + + if( !wext_get_freqlist(ifname, buf, len) ) + return 0; + + req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0); + if( req ) + { + res = nl80211_send(req); + if( res ) + { + nla_for_each_nested(band, + res->attr[NL80211_ATTR_WIPHY_BANDS], bands_remain) + { + nla_parse(bands, NL80211_BAND_ATTR_MAX, nla_data(band), + nla_len(band), NULL); + + nla_for_each_nested(freq, + bands[NL80211_BAND_ATTR_FREQS], freqs_remain) + { + nla_parse(freqs, NL80211_FREQUENCY_ATTR_MAX, + nla_data(freq), nla_len(freq), freq_policy); + + e->mhz = nla_get_u32(freqs[NL80211_FREQUENCY_ATTR_FREQ]); + e->channel = nl80211_freq2channel(e->mhz); + + e++; + count++; + } + } + nl80211_free(res); + } + nl80211_free(req); + } + + if( count > 0 ) + { + *len = count * sizeof(struct iwinfo_freqlist_entry); + return 0; + } + + return -1; } int nl80211_get_country(const char *ifname, char *buf) diff --git a/contrib/package/iwinfo/src/iwinfo_nl80211.h b/contrib/package/iwinfo/src/iwinfo_nl80211.h index 0cf74195d..97a290484 100644 --- a/contrib/package/iwinfo/src/iwinfo_nl80211.h +++ b/contrib/package/iwinfo/src/iwinfo_nl80211.h @@ -79,5 +79,6 @@ 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_mbssid_support(const char *ifname, int *buf); +void nl80211_close(void); #endif diff --git a/contrib/package/iwinfo/src/iwinfo_wext.c b/contrib/package/iwinfo/src/iwinfo_wext.c index 7bd1574c1..e9e79e375 100644 --- a/contrib/package/iwinfo/src/iwinfo_wext.c +++ b/contrib/package/iwinfo/src/iwinfo_wext.c @@ -113,6 +113,14 @@ int wext_probe(const char *ifname) return 0; } +void wext_close(void) +{ + wext_scan_close(); + + if( ioctl_socket > -1 ) + close(ioctl_socket); +} + int wext_get_mode(const char *ifname, char *buf) { struct iwreq wrq; diff --git a/contrib/package/iwinfo/src/iwinfo_wext.h b/contrib/package/iwinfo/src/iwinfo_wext.h index 917ea121f..d58fa1c2f 100644 --- a/contrib/package/iwinfo/src/iwinfo_wext.h +++ b/contrib/package/iwinfo/src/iwinfo_wext.h @@ -48,5 +48,7 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len); int wext_get_freqlist(const char *ifname, char *buf, int *len); int wext_get_countrylist(const char *ifname, char *buf, int *len); int wext_get_mbssid_support(const char *ifname, int *buf); +void wext_scan_close(void); +void wext_close(void); #endif diff --git a/contrib/package/iwinfo/src/iwinfo_wext_scan.c b/contrib/package/iwinfo/src/iwinfo_wext_scan.c index f81261837..d5b486b7e 100644 --- a/contrib/package/iwinfo/src/iwinfo_wext_scan.c +++ b/contrib/package/iwinfo/src/iwinfo_wext_scan.c @@ -653,3 +653,9 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len) return -1; } + +void wext_scan_close(void) +{ + if( ioctl_socket > -1 ) + close(ioctl_socket); +} diff --git a/contrib/package/iwinfo/src/iwinfo_wl.c b/contrib/package/iwinfo/src/iwinfo_wl.c index 81df81faf..cb778fe3d 100644 --- a/contrib/package/iwinfo/src/iwinfo_wl.c +++ b/contrib/package/iwinfo/src/iwinfo_wl.c @@ -75,6 +75,12 @@ int wl_probe(const char *ifname) return 0; } +void wl_close(void) +{ + if( ioctl_socket > -1 ) + close(ioctl_socket); +} + int wl_get_mode(const char *ifname, char *buf) { int ret = -1; diff --git a/contrib/package/iwinfo/src/iwinfo_wl.h b/contrib/package/iwinfo/src/iwinfo_wl.h index 0a991a35f..b734cb6fb 100644 --- a/contrib/package/iwinfo/src/iwinfo_wl.h +++ b/contrib/package/iwinfo/src/iwinfo_wl.h @@ -45,5 +45,6 @@ int wl_get_scanlist(const char *ifname, char *buf, int *len); int wl_get_freqlist(const char *ifname, char *buf, int *len); int wl_get_countrylist(const char *ifname, char *buf, int *len); int wl_get_mbssid_support(const char *ifname, int *buf); +void wl_close(void); #endif -- 2.25.1