Date: Tue, 9 Nov 2004 20:28:19 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 64713 for review Message-ID: <200411092028.iA9KSJOv042589@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=64713 Change 64713 by sam@sam_ebb on 2004/11/09 20:27:19 o incomplete get station info support o pad scan results structure o add ibss stats Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#11 edit .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#5 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#11 (text+ko) ==== @@ -948,12 +948,41 @@ return error; } +static void +get_scan_result(struct ieee80211req_scan_result *sr, + const struct ieee80211_node *ni) +{ + struct ieee80211com *ic = ni->ni_ic; + + memset(sr, 0, sizeof(*sr)); + sr->isr_ssid_len = ni->ni_esslen; + if (ni->ni_wpa_ie != NULL) + sr->isr_ie_len += 2+ni->ni_wpa_ie[1]; + if (ni->ni_wme_ie != NULL) + sr->isr_ie_len += 2+ni->ni_wme_ie[1]; + sr->isr_len = sizeof(*sr) + sr->isr_ssid_len + sr->isr_ie_len; + sr->isr_len = roundup(sr->isr_len, sizeof(u_int32_t)); + if (ni->ni_chan != IEEE80211_CHAN_ANYC) { + sr->isr_freq = ni->ni_chan->ic_freq; + sr->isr_flags = ni->ni_chan->ic_flags; + } + sr->isr_rssi = ic->ic_node_getrssi(ni); + sr->isr_intval = ni->ni_intval; + sr->isr_capinfo = ni->ni_capinfo; + sr->isr_erp = ni->ni_erp; + IEEE80211_ADDR_COPY(sr->isr_bssid, ni->ni_bssid); + sr->isr_nrates = ni->ni_rates.rs_nrates; + if (sr->isr_nrates > 15) + sr->isr_nrates = 15; + memcpy(sr->isr_rates, ni->ni_rates.rs_rates, sr->isr_nrates); +} + static int ieee80211_ioctl_getscanresults(struct ieee80211com *ic, struct ieee80211req *ireq) { union { struct ieee80211req_scan_result res; - char data[512]; + char data[512]; /* XXX shrink? */ } u; struct ieee80211req_scan_result *sr = &u.res; struct ieee80211_node_table *nt; @@ -967,30 +996,14 @@ /* XXX locking */ nt = &ic->ic_scan; TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - sr->isr_ssid_len = ni->ni_esslen; - sr->isr_ie_len = 0; - if (ni->ni_wpa_ie != NULL) - sr->isr_ie_len += 2+ni->ni_wpa_ie[1]; - if (ni->ni_wme_ie != NULL) - sr->isr_ie_len += 2+ni->ni_wme_ie[1]; - sr->isr_len = sizeof(*sr) + sr->isr_ssid_len + sr->isr_ie_len; + /* NB: skip pre-scan node state */ + if (ni->ni_chan == IEEE80211_CHAN_ANYC) + continue; + get_scan_result(sr, ni); if (sr->isr_len > sizeof(u)) continue; /* XXX */ if (space < sr->isr_len) break; - sr->isr_freq = ni->ni_chan->ic_freq; - sr->isr_flags = ni->ni_chan->ic_flags; - sr->isr_noise = 0; - sr->isr_rssi = ic->ic_node_getrssi(ni); - sr->isr_intval = ni->ni_intval; - sr->isr_capinfo = ni->ni_capinfo; - sr->isr_erp = ni->ni_erp; - IEEE80211_ADDR_COPY(sr->isr_bssid, ni->ni_bssid); - sr->isr_nrates = ni->ni_rates.rs_nrates; - if (sr->isr_nrates > 15) - sr->isr_nrates = 15; - memcpy(sr->isr_rates, ni->ni_rates.rs_rates, sr->isr_nrates); - sr->isr_scangen = 0; /* XXX to be added */ cp = (u_int8_t *)(sr+1); memcpy(cp, ni->ni_essid, ni->ni_esslen); cp += ni->ni_esslen; @@ -1012,7 +1025,92 @@ return error; } +static void +get_sta_info(struct ieee80211req_sta_info *si, const struct ieee80211_node *ni) +{ + struct ieee80211com *ic = ni->ni_ic; + + si->isi_ie_len = 0; + if (ni->ni_wpa_ie != NULL) + si->isi_ie_len += 2+ni->ni_wpa_ie[1]; + if (ni->ni_wme_ie != NULL) + si->isi_ie_len += 2+ni->ni_wme_ie[1]; + si->isi_len = sizeof(*si) + si->isi_ie_len, sizeof(u_int32_t); + si->isi_len = roundup(si->isi_len, sizeof(u_int32_t)); + si->isi_freq = ni->ni_chan->ic_freq; + si->isi_flags = ni->ni_chan->ic_flags; + si->isi_state = ni->ni_flags; + si->isi_authmode = ni->ni_authmode; + si->isi_rssi = ic->ic_node_getrssi(ni); + si->isi_capinfo = ni->ni_capinfo; + si->isi_erp = ni->ni_erp; + IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr); + si->isi_nrates = ni->ni_rates.rs_nrates; + if (si->isi_nrates > 15) + si->isi_nrates = 15; + memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates); + si->isi_txrate = ni->ni_txrate; + si->isi_associd = ni->ni_associd; + si->isi_txpower = ni->ni_txpower; + si->isi_vlan = ni->ni_vlan; + si->isi_txseq = ni->ni_txseq; + si->isi_rxseq = ni->ni_rxseq; + memcpy(si->isi_rxseqs, ni->ni_rxseqs, sizeof(ni->ni_rxseqs)); + if (ic->ic_opmode == IEEE80211_M_IBSS || ni->ni_associd != 0) + si->isi_inact = ic->ic_inact_run; + else if (ieee80211_node_is_authorized(ni)) + si->isi_inact = ic->ic_inact_auth; + else + si->isi_inact = ic->ic_inact_init; + si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT; +} + static int +ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq) +{ + union { + struct ieee80211req_sta_info info; + char data[512]; /* XXX shrink? */ + } u; + struct ieee80211req_sta_info *si = &u.info; + struct ieee80211_node_table *nt; + struct ieee80211_node *ni; + int error, space; + u_int8_t *p, *cp; + + nt = ic->ic_sta; + if (nt == NULL) + return EINVAL; + p = ireq->i_data; + space = ireq->i_len; + error = 0; + /* XXX locking */ + TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { + get_sta_info(si, ni); + if (si->isi_len > sizeof(u)) + continue; /* XXX */ + if (space < si->isi_len) + break; + cp = (u_int8_t *)(si+1); + if (ni->ni_wpa_ie != NULL) { + memcpy(cp, ni->ni_wpa_ie, 2+ni->ni_wpa_ie[1]); + cp += 2+ni->ni_wpa_ie[1]; + } + if (ni->ni_wme_ie != NULL) { + memcpy(cp, ni->ni_wme_ie, 2+ni->ni_wme_ie[1]); + cp += 2+ni->ni_wme_ie[1]; + } + error = copyout(si, p, si->isi_len); + if (error) + break; + p += si->isi_len; + space -= si->isi_len; + } + ireq->i_len -= space; + return error; +} + +static int ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211req *ireq) { const struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn; @@ -1201,6 +1299,9 @@ case IEEE80211_IOC_INACT_INIT: ireq->i_val = ic->ic_inact_init * IEEE80211_INACT_WAIT; break; + case IEEE80211_IOC_STA_INFO: + error = ieee80211_ioctl_getstainfo(ic, ireq); + break; default: error = EINVAL; break; ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#5 (text+ko) ==== @@ -164,6 +164,8 @@ u_int32_t is_crypto_attachfail; /* cipher attach failed */ u_int32_t is_crypto_swfallback; /* cipher fallback to s/w */ u_int32_t is_crypto_keyfail; /* driver key alloc failed */ + u_int32_t is_ibss_capmismatch; /* merge failed-cap mismatch */ + u_int32_t is_ibss_norate; /* merge failed-rate mismatch */ }; /* @@ -264,6 +266,48 @@ struct ieee80211_nodestats is_stats; }; +/* + * Station information block; the mac address is used + * to retrieve other data like stats, unicast key, etc. + */ +struct ieee80211req_sta_info { + u_int16_t isi_len; /* length (mult of 4) */ + u_int16_t isi_freq; /* MHz */ + u_int16_t isi_flags; /* channel flags */ + u_int16_t isi_state; /* state flags */ + u_int8_t isi_authmode; /* authentication algorithm */ + u_int8_t isi_rssi; + u_int8_t isi_capinfo; /* capabilities */ + u_int8_t isi_erp; /* ERP element */ + u_int8_t isi_macaddr[IEEE80211_ADDR_LEN]; + u_int8_t isi_nrates; + u_int8_t isi_rates[15]; /* negotiated rates */ + u_int8_t isi_txrate; /* index to isi_rates[] */ + u_int8_t isi_ie_len; /* IE length */ + u_int16_t isi_associd; /* assoc response */ + u_int16_t isi_txpower; /* current tx power */ + u_int16_t isi_vlan; /* vlan tag */ + u_int16_t isi_txseq; /* seq to be transmitted */ + u_int16_t isi_rxseq; /* seq previous received */ + u_int16_t isi_rxseqs[16]; /* seq previous for qos frames*/ + u_int16_t isi_inact; /* inactivity timer */ + /* XXX frag state? */ + /* variable length IE data */ +}; + +/* + * Retrieve per-station information; to retrieve all + * specify a mac address of ff:ff:ff:ff:ff:ff. + */ +struct ieee80211req_sta_req { + union { + /* NB: explicitly force 64-bit alignment */ + u_int8_t macaddr[IEEE80211_ADDR_LEN]; + u_int64_t pad; + } is_u; + struct ieee80211req_sta_info info[1]; /* variable length */ +}; + #ifdef __FreeBSD__ /* * FreeBSD-style ioctls. @@ -336,26 +380,30 @@ #define IEEE80211_IOC_INACT 42 /* station inactivity timeout */ #define IEEE80211_IOC_INACT_AUTH 43 /* station auth inact timeout */ #define IEEE80211_IOC_INACT_INIT 44 /* station init inact timeout */ +#define IEEE80211_IOC_STA_INFO 45 /* station/neighbor info */ #ifndef IEEE80211_CHAN_ANY #define IEEE80211_CHAN_ANY 0xffff /* token for ``any channel'' */ #endif +/* + * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS. + */ struct ieee80211req_scan_result { - u_int16_t isr_len; /* length (mult of 4) */ - u_int16_t isr_freq; /* MHz */ - u_int16_t isr_flags; /* channel flags */ + u_int16_t isr_len; /* length (mult of 4) */ + u_int16_t isr_freq; /* MHz */ + u_int16_t isr_flags; /* channel flags */ u_int8_t isr_noise; u_int8_t isr_rssi; - u_int8_t isr_intval; /* beacon interval */ - u_int8_t isr_capinfo; /* capabilities */ - u_int8_t isr_erp; /* ERP element */ + u_int8_t isr_intval; /* beacon interval */ + u_int8_t isr_capinfo; /* capabilities */ + u_int8_t isr_erp; /* ERP element */ u_int8_t isr_bssid[IEEE80211_ADDR_LEN]; u_int8_t isr_nrates; - u_int8_t isr_rates[15]; /* XXX */ - u_int8_t isr_ssid_len; /* SSID length */ - u_int8_t isr_ie_len; /* IE length */ - u_int8_t isr_scangen; /* scan generation # */ + u_int8_t isr_rates[15]; /* XXX */ + u_int8_t isr_ssid_len; /* SSID length */ + u_int8_t isr_ie_len; /* IE length */ + u_int8_t isr_pad[5]; /* variable length SSID followed by IE data */ };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411092028.iA9KSJOv042589>