More statistics fixups:
o change rssi to be signed in ieee80211_nodestats o add noise floor in ieee80211_nodestats (use an implicit hole to preserve layout); return it as zero until we can update the api's so the driver can provide noise floor data o add a bandaid so IEEE80211_IOC_STA_STATS works for sta mode; when all nodes are in the station table this will no longer be needed o fix braino in IEEE80211_IOC_STA_INFO implementation; was supposed to take a mac address and return info for that sta or all stations if ff:ff:ff:ff:ff was supplied--but somehow this didn't get implemented; implement the intended semantics and leave a compat shim at the old ioctl number for the previous api Reviewed by: mlaier MFC after: 3 weeks
This commit is contained in:
parent
06efa2f0eb
commit
d1c85dae69
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=161146
@ -960,8 +960,12 @@ ieee80211_ioctl_getstastats(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
if (error != 0)
|
||||
return error;
|
||||
ni = ieee80211_find_node(&ic->ic_sta, macaddr);
|
||||
if (ni == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
if (ni == NULL) {
|
||||
/* XXX special-case sta-mode until bss is node in ic_sta */
|
||||
if (ic->ic_opmode != IEEE80211_M_STA)
|
||||
return ENOENT;
|
||||
ni = ieee80211_ref_node(ic->ic_bss);
|
||||
}
|
||||
if (ireq->i_len > sizeof(struct ieee80211req_sta_stats))
|
||||
ireq->i_len = sizeof(struct ieee80211req_sta_stats);
|
||||
/* NB: copy out only the statistics */
|
||||
@ -1251,6 +1255,7 @@ get_sta_info(void *arg, struct ieee80211_node *ni)
|
||||
si->isi_state = ni->ni_flags;
|
||||
si->isi_authmode = ni->ni_authmode;
|
||||
si->isi_rssi = ic->ic_node_getrssi(ni);
|
||||
si->isi_noise = 0; /* XXX */
|
||||
si->isi_capinfo = ni->ni_capinfo;
|
||||
si->isi_erp = ni->ni_erp;
|
||||
IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr);
|
||||
@ -1293,39 +1298,85 @@ get_sta_info(void *arg, struct ieee80211_node *ni)
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
getstainfo_common(struct ieee80211com *ic, struct ieee80211req *ireq,
|
||||
struct ieee80211_node *ni, int off)
|
||||
{
|
||||
struct stainforeq req;
|
||||
size_t space;
|
||||
void *p;
|
||||
int error;
|
||||
|
||||
if (ireq->i_len < sizeof(struct stainforeq))
|
||||
return EFAULT;
|
||||
|
||||
error = 0;
|
||||
req.space = 0;
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req);
|
||||
if (ni == NULL)
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req);
|
||||
else
|
||||
get_sta_space(&req, ni);
|
||||
if (req.space > ireq->i_len)
|
||||
req.space = ireq->i_len;
|
||||
if (req.space > 0) {
|
||||
size_t space;
|
||||
void *p;
|
||||
|
||||
space = req.space;
|
||||
/* XXX M_WAITOK after driver lock released */
|
||||
MALLOC(p, void *, space, M_TEMP, M_NOWAIT);
|
||||
if (p == NULL)
|
||||
return ENOMEM;
|
||||
if (p == NULL) {
|
||||
error = ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
req.si = p;
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req);
|
||||
if (ni == NULL)
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req);
|
||||
else
|
||||
get_sta_info(&req, ni);
|
||||
ireq->i_len = space - req.space;
|
||||
error = copyout(p, ireq->i_data, ireq->i_len);
|
||||
error = copyout(p, (u_int8_t *) ireq->i_data+off, ireq->i_len);
|
||||
FREE(p, M_TEMP);
|
||||
} else
|
||||
ireq->i_len = 0;
|
||||
|
||||
bad:
|
||||
if (ni != NULL)
|
||||
ieee80211_free_node(ni);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
{
|
||||
u_int8_t macaddr[IEEE80211_ADDR_LEN];
|
||||
const int off = __offsetof(struct ieee80211req_sta_req, info);
|
||||
struct ieee80211_node *ni;
|
||||
int error;
|
||||
|
||||
if (ireq->i_len < sizeof(struct ieee80211req_sta_req))
|
||||
return EFAULT;
|
||||
error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
|
||||
if (error != 0)
|
||||
return error;
|
||||
if (IEEE80211_ADDR_EQ(macaddr, ic->ic_ifp->if_broadcastaddr)) {
|
||||
ni = NULL;
|
||||
} else {
|
||||
ni = ieee80211_find_node(&ic->ic_sta, macaddr);
|
||||
if (ni == NULL) {
|
||||
/* XXX special-case sta-mode until bss is in ic_sta */
|
||||
if (ic->ic_opmode != IEEE80211_M_STA)
|
||||
return EINVAL; /* XXX */
|
||||
ni = ieee80211_ref_node(ic->ic_bss);
|
||||
}
|
||||
}
|
||||
return getstainfo_common(ic, ireq, ni, off);
|
||||
}
|
||||
|
||||
#ifdef COMPAT_FREEBSD6
|
||||
#define IEEE80211_IOC_STA_INFO_OLD 45
|
||||
|
||||
static int
|
||||
old_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
{
|
||||
if (ireq->i_len < sizeof(struct ieee80211req_sta_info))
|
||||
return EFAULT;
|
||||
return getstainfo_common(ic, ireq, NULL, 0);
|
||||
}
|
||||
#endif /* COMPAT_FREEBSD6 */
|
||||
|
||||
static int
|
||||
ieee80211_ioctl_getstatxpow(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
{
|
||||
@ -1611,6 +1662,11 @@ ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
|
||||
case IEEE80211_IOC_STA_TXPOW:
|
||||
error = ieee80211_ioctl_getstatxpow(ic, ireq);
|
||||
break;
|
||||
#ifdef COMPAT_FREEBSD6
|
||||
case IEEE80211_IOC_STA_INFO_OLD:
|
||||
error = old_getstainfo(ic, ireq);
|
||||
break;
|
||||
#endif
|
||||
case IEEE80211_IOC_STA_INFO:
|
||||
error = ieee80211_ioctl_getstainfo(ic, ireq);
|
||||
break;
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <net80211/ieee80211_crypto.h>
|
||||
|
||||
/*
|
||||
* Per/node (station) statistics available when operating as an AP.
|
||||
* Per/node (station) statistics.
|
||||
*/
|
||||
struct ieee80211_nodestats {
|
||||
u_int32_t ns_rx_data; /* rx data frames */
|
||||
@ -311,7 +311,7 @@ struct ieee80211req_sta_info {
|
||||
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;
|
||||
int8_t isi_rssi; /* receive signal strength */
|
||||
u_int8_t isi_capinfo; /* capabilities */
|
||||
u_int8_t isi_erp; /* ERP element */
|
||||
u_int8_t isi_macaddr[IEEE80211_ADDR_LEN];
|
||||
@ -319,6 +319,7 @@ struct ieee80211req_sta_info {
|
||||
/* negotiated rates */
|
||||
u_int8_t isi_rates[IEEE80211_RATE_MAXSIZE];
|
||||
u_int8_t isi_txrate; /* index to isi_rates[] */
|
||||
int8_t isi_noise; /* noise floor */
|
||||
u_int16_t isi_ie_len; /* IE length */
|
||||
u_int16_t isi_associd; /* assoc response */
|
||||
u_int16_t isi_txpower; /* current tx power */
|
||||
@ -433,7 +434,7 @@ struct ieee80211req {
|
||||
#define IEEE80211_IOC_CHANINFO 42 /* channel info list */
|
||||
#define IEEE80211_IOC_TXPOWMAX 43 /* max tx power for channel */
|
||||
#define IEEE80211_IOC_STA_TXPOW 44 /* per-station tx power limit */
|
||||
#define IEEE80211_IOC_STA_INFO 45 /* station/neighbor info */
|
||||
/* 45 was IEEE80211_IOC_STA_INFO */
|
||||
#define IEEE80211_IOC_WME_CWMIN 46 /* WME: ECWmin */
|
||||
#define IEEE80211_IOC_WME_CWMAX 47 /* WME: ECWmax */
|
||||
#define IEEE80211_IOC_WME_AIFS 48 /* WME: AIFSN */
|
||||
@ -450,6 +451,7 @@ struct ieee80211req {
|
||||
#define IEEE80211_IOC_BURST 75 /* packet bursting */
|
||||
#define IEEE80211_IOC_SCAN_RESULTS 76 /* get scan results */
|
||||
#define IEEE80211_IOC_BMISSTHRESHOLD 77 /* beacon miss threshold */
|
||||
#define IEEE80211_IOC_STA_INFO 78 /* station/neighbor info */
|
||||
|
||||
/*
|
||||
* Scan result data returned for IEEE80211_IOC_SCAN_RESULTS.
|
||||
|
Loading…
Reference in New Issue
Block a user