PERFORCE change 64713 for review
Sam Leffler
sam at FreeBSD.org
Tue Nov 9 12:28:20 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=64713
Change 64713 by sam at 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 */
};
More information about the p4-projects
mailing list