add statistics for all failures and/or abnormal events; still need

to add per-node statistics
This commit is contained in:
Sam Leffler 2003-10-17 23:15:30 +00:00
parent 627200f847
commit 1be50176db
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121180
7 changed files with 174 additions and 39 deletions

View File

@ -113,16 +113,23 @@ ieee80211_wep_crypt(struct ifnet *ifp, struct mbuf *m0, int txflag)
n0 = NULL;
if ((ctx = ic->ic_wep_ctx) == NULL) {
ctx = malloc(arc4_ctxlen(), M_DEVBUF, M_NOWAIT);
if (ctx == NULL)
if (ctx == NULL) {
ic->ic_stats.is_crypto_nomem++;
goto fail;
}
ic->ic_wep_ctx = ctx;
}
m = m0;
left = m->m_pkthdr.len;
MGET(n, M_DONTWAIT, m->m_type);
n0 = n;
if (n == NULL)
if (n == NULL) {
if (txflag)
ic->ic_stats.is_tx_nombuf++;
else
ic->ic_stats.is_rx_nombuf++;
goto fail;
}
M_MOVE_PKTHDR(n, m);
len = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
if (txflag) {
@ -188,8 +195,13 @@ ieee80211_wep_crypt(struct ifnet *ifp, struct mbuf *m0, int txflag)
len = n->m_len - noff;
if (len == 0) {
MGET(n->m_next, M_DONTWAIT, n->m_type);
if (n->m_next == NULL)
if (n->m_next == NULL) {
if (txflag)
ic->ic_stats.is_tx_nombuf++;
else
ic->ic_stats.is_rx_nombuf++;
goto fail;
}
n = n->m_next;
n->m_len = MLEN;
if (left >= MINCLSIZE) {
@ -223,8 +235,10 @@ ieee80211_wep_crypt(struct ifnet *ifp, struct mbuf *m0, int txflag)
else {
n->m_len = noff;
MGET(n->m_next, M_DONTWAIT, n->m_type);
if (n->m_next == NULL)
if (n->m_next == NULL) {
ic->ic_stats.is_tx_nombuf++;
goto fail;
}
n = n->m_next;
n->m_len = sizeof(crcbuf);
noff = 0;
@ -252,6 +266,7 @@ ieee80211_wep_crypt(struct ifnet *ifp, struct mbuf *m0, int txflag)
n0->m_len, -1, -1);
}
#endif
ic->ic_stats.is_rx_decryptcrc++;
goto fail;
}
}

View File

@ -113,6 +113,7 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
if_printf(ifp, "receive packet with wrong version: %x\n",
wh->i_fc[0]);
ieee80211_unref_node(&ni);
ic->ic_stats.is_rx_badversion++;
goto err;
}
@ -124,19 +125,21 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
* them to go through bpf tapping at the 802.11 layer.
*/
if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
/* XXX statistic */
IEEE80211_DPRINTF2(("%s: frame too short, len %u\n",
__func__, m->m_pkthdr.len));
/* XXX statistic */
ic->ic_stats.is_rx_tooshort++;
goto out; /* XXX */
}
if (ic->ic_state != IEEE80211_S_SCAN) {
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
/* not interested in */
IEEE80211_DPRINTF2(("%s: discard frame from "
"bss %s\n", __func__,
ether_sprintf(wh->i_addr2)));
/* not interested in */
ic->ic_stats.is_rx_wrongbss++;
goto out;
}
break;
@ -153,6 +156,7 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
IEEE80211_DPRINTF2(("%s: discard frame from "
"bss %s\n", __func__,
ether_sprintf(bssid)));
ic->ic_stats.is_rx_wrongbss++;
goto out;
}
break;
@ -171,6 +175,7 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
rxseq == ni->ni_rxseq) {
/* duplicate, silently discarded */
ic->ic_stats.is_rx_dup++; /* XXX per-station stat */
goto out;
}
ni->ni_inact = 0;
@ -180,8 +185,10 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
case IEEE80211_FC0_TYPE_DATA:
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
if (dir != IEEE80211_FC1_DIR_FROMDS)
if (dir != IEEE80211_FC1_DIR_FROMDS) {
ic->ic_stats.is_rx_wrongdir++;
goto out;
}
if ((ifp->if_flags & IFF_SIMPLEX) &&
IEEE80211_IS_MULTICAST(wh->i_addr1) &&
IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
@ -191,17 +198,22 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
* It should be silently discarded for
* SIMPLEX interface.
*/
ic->ic_stats.is_rx_mcastecho++;
goto out;
}
break;
case IEEE80211_M_IBSS:
case IEEE80211_M_AHDEMO:
if (dir != IEEE80211_FC1_DIR_NODS)
if (dir != IEEE80211_FC1_DIR_NODS) {
ic->ic_stats.is_rx_wrongdir++;
goto out;
}
break;
case IEEE80211_M_HOSTAP:
if (dir != IEEE80211_FC1_DIR_TODS)
if (dir != IEEE80211_FC1_DIR_TODS) {
ic->ic_stats.is_rx_wrongdir++;
goto out;
}
/* check if source STA is associated */
if (ni == ic->ic_bss) {
IEEE80211_DPRINTF(("%s: data from unknown src "
@ -215,6 +227,7 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
IEEE80211_REASON_NOT_AUTHED);
ieee80211_free_node(ic, ni);
}
ic->ic_stats.is_rx_notassoc++;
goto err;
}
if (ni->ni_associd == 0) {
@ -225,6 +238,7 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
IEEE80211_FC0_SUBTYPE_DISASSOC,
IEEE80211_REASON_NOT_ASSOCED);
ieee80211_unref_node(&ni);
ic->ic_stats.is_rx_notassoc++;
goto err;
}
break;
@ -234,18 +248,24 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
if (ic->ic_flags & IEEE80211_F_WEPON) {
m = ieee80211_wep_crypt(ifp, m, 0);
if (m == NULL)
if (m == NULL) {
ic->ic_stats.is_rx_wepfail++;
goto err;
}
wh = mtod(m, struct ieee80211_frame *);
} else
} else {
ic->ic_stats.is_rx_nowep++;
goto out;
}
}
/* copy to listener after decrypt */
if (ic->ic_rawbpf)
bpf_mtap(ic->ic_rawbpf, m);
m = ieee80211_decap(ifp, m);
if (m == NULL)
if (m == NULL) {
ic->ic_stats.is_rx_decap++;
goto err;
}
ifp->if_ipackets++;
/* perform as a bridge within the AP */
@ -286,21 +306,29 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
return;
case IEEE80211_FC0_TYPE_MGT:
if (dir != IEEE80211_FC1_DIR_NODS)
if (dir != IEEE80211_FC1_DIR_NODS) {
ic->ic_stats.is_rx_wrongdir++;
goto err;
if (ic->ic_opmode == IEEE80211_M_AHDEMO)
}
if (ic->ic_opmode == IEEE80211_M_AHDEMO) {
ic->ic_stats.is_rx_ahdemo_mgt++;
goto out;
}
subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
/* drop frames without interest */
if (ic->ic_state == IEEE80211_S_SCAN) {
if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
ic->ic_stats.is_rx_mgtdiscard++;
goto out;
}
} else {
if (ic->ic_opmode != IEEE80211_M_IBSS &&
subtype == IEEE80211_FC0_SUBTYPE_BEACON)
subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
ic->ic_stats.is_rx_mgtdiscard++;
goto out;
}
}
if (ifp->if_flags & IFF_DEBUG) {
@ -336,6 +364,7 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
return;
case IEEE80211_FC0_TYPE_CTL:
ic->ic_stats.is_rx_ctl++;
goto out;
default:
IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, type));
@ -475,6 +504,7 @@ ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
IEEE80211_DPRINTF(("%s: extended rate set too large;"
" only using %u of %u rates\n",
__func__, nxrates, xrates[1]));
ic->ic_stats.is_rx_rstoobig++;
}
memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
rs->rs_nrates += nxrates;
@ -482,13 +512,13 @@ ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
return ieee80211_fix_rate(ic, ni, flags);
}
/* XXX statistics */
/* Verify the existence and length of __elem or get out. */
#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
if ((__elem) == NULL) { \
IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n", \
__func__, ieee80211_mgt_subtype_name[subtype >> \
IEEE80211_FC0_SUBTYPE_SHIFT])); \
ic->ic_stats.is_rx_elem_missing++; \
return; \
} \
if ((__elem)[1] > (__maxlen)) { \
@ -497,6 +527,7 @@ ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
ieee80211_mgt_subtype_name[subtype >> \
IEEE80211_FC0_SUBTYPE_SHIFT], \
ether_sprintf(wh->i_addr2))); \
ic->ic_stats.is_rx_elem_toobig++; \
return; \
} \
} while (0)
@ -508,6 +539,7 @@ ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
ieee80211_mgt_subtype_name[subtype >> \
IEEE80211_FC0_SUBTYPE_SHIFT], \
ether_sprintf(wh->i_addr2))); \
ic->ic_stats.is_rx_elem_toosmall++; \
return; \
} \
} while (0)
@ -598,6 +630,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
IEEE80211_DPRINTF(("%s: invalid ERP "
"element; length %u, expecting "
"1\n", __func__, frm[1]));
ic->ic_stats.is_rx_elem_toobig++;
break;
}
erp = frm[2];
@ -605,6 +638,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
default:
IEEE80211_DPRINTF2(("%s: element id %u/len %u "
"ignored\n", __func__, *frm, frm[1]));
ic->ic_stats.is_rx_elem_unknown++;
break;
}
frm += frm[1] + 2;
@ -620,6 +654,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
"%u\n", __func__,
ISPROBE(subtype) ? "probe response" : "beacon",
chan));
ic->ic_stats.is_rx_badchan++;
return;
}
if (chan != bchan) {
@ -634,7 +669,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
"for channel %u\n", __func__,
ISPROBE(subtype) ? "probe response" : "beacon",
bchan, chan));
/* XXX statistic */
ic->ic_stats.is_rx_chanmismatch++;
return;
}
@ -669,8 +704,10 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
#endif
if (ni == NULL) {
ni = ieee80211_alloc_node(ic, wh->i_addr2);
if (ni == NULL)
if (ni == NULL) {
ic->ic_stats.is_rx_nodealloc++;
return;
}
ni->ni_esslen = ssid[1];
memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
memcpy(ni->ni_essid, ssid + 2, ssid[1]);
@ -741,13 +778,16 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
printf(" from %s\n", ether_sprintf(wh->i_addr2));
}
#endif
ic->ic_stats.is_rx_ssidmismatch++;
return;
}
if (ni == ic->ic_bss) {
ni = ieee80211_dup_bss(ic, wh->i_addr2);
if (ni == NULL)
if (ni == NULL) {
ic->ic_stats.is_rx_nodealloc++;
return;
}
IEEE80211_DPRINTF(("%s: new req from %s\n",
__func__, ether_sprintf(wh->i_addr2)));
allocbs = 1;
@ -792,12 +832,24 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
/* TODO: shared key auth */
IEEE80211_DPRINTF(("%s: unsupported auth %d from %s\n",
__func__, algo, ether_sprintf(wh->i_addr2)));
ic->ic_stats.is_rx_auth_unsupported++;
return;
}
if (ic->ic_state != IEEE80211_S_RUN) {
IEEE80211_DPRINTF(("%s: discard auth from %s; "
"state %u\n", __func__,
ether_sprintf(wh->i_addr2), ic->ic_state));
ic->ic_stats.is_rx_bad_auth++;
break;
}
if (seq != (ic->ic_opmode == IEEE80211_M_STA ? 2 : 1)) {
IEEE80211_DPRINTF(("%s: discard auth from %s; seq %u\n",
__func__, ether_sprintf(wh->i_addr2), seq));
ic->ic_stats.is_rx_bad_auth++;
break;
}
switch (ic->ic_opmode) {
case IEEE80211_M_IBSS:
if (ic->ic_state != IEEE80211_S_RUN || seq != 1)
return;
ieee80211_new_state(ic, IEEE80211_S_AUTH,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
@ -807,12 +859,12 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
break;
case IEEE80211_M_HOSTAP:
if (ic->ic_state != IEEE80211_S_RUN || seq != 1)
return;
if (ni == ic->ic_bss) {
ni = ieee80211_alloc_node(ic, wh->i_addr2);
if (ni == NULL)
if (ni == NULL) {
ic->ic_stats.is_rx_nodealloc++;
return;
}
IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
ni->ni_rssi = rssi;
ni->ni_rstamp = rstamp;
@ -829,8 +881,6 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
break;
case IEEE80211_M_STA:
if (ic->ic_state != IEEE80211_S_AUTH || seq != 2)
return;
if (status != 0) {
if_printf(&ic->ic_if,
"authentication failed (reason %d) for %s\n",
@ -838,6 +888,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
ether_sprintf(wh->i_addr3));
if (ni != ic->ic_bss)
ni->ni_fails++;
ic->ic_stats.is_rx_auth_fail++;
return;
}
ieee80211_new_state(ic, IEEE80211_S_ASSOC,
@ -877,6 +928,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
IEEE80211_DPRINTF(("%s: ignore other bss from %s\n",
__func__, ether_sprintf(wh->i_addr2)));
ic->ic_stats.is_rx_assoc_bss++;
return;
}
capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
@ -909,6 +961,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
printf(" from %s\n", ether_sprintf(wh->i_addr2));
}
#endif
ic->ic_stats.is_rx_ssidmismatch++;
return;
}
if (ni == ic->ic_bss) {
@ -921,6 +974,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
IEEE80211_REASON_ASSOC_NOT_AUTHED);
ieee80211_free_node(ic, ni);
}
ic->ic_stats.is_rx_assoc_notauth++;
return;
}
/* XXX per-node cipher suite */
@ -935,6 +989,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
ni->ni_associd = 0;
IEEE80211_SEND_MGMT(ic, ni, resp,
IEEE80211_STATUS_CAPINFO);
ic->ic_stats.is_rx_assoc_capmismatch++;
return;
}
ieee80211_setup_rates(ic, ni, rates, xrates,
@ -946,6 +1001,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
ni->ni_associd = 0;
IEEE80211_SEND_MGMT(ic, ni, resp,
IEEE80211_STATUS_BASIC_RATE);
ic->ic_stats.is_rx_assoc_norate++;
return;
}
ni->ni_rssi = rssi;
@ -1003,6 +1059,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
status, ether_sprintf(wh->i_addr3));
if (ni != ic->ic_bss)
ni->ni_fails++;
ic->ic_stats.is_rx_auth_fail++;
return;
}
ni->ni_associd = le16toh(*(u_int16_t *)frm);
@ -1039,6 +1096,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
*/
IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
reason = le16toh(*(u_int16_t *)frm);
ic->ic_stats.is_rx_deauth++;
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
ieee80211_new_state(ic, IEEE80211_S_AUTH,
@ -1068,6 +1126,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
*/
IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
reason = le16toh(*(u_int16_t *)frm);
ic->ic_stats.is_rx_disassoc++;
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
ieee80211_new_state(ic, IEEE80211_S_ASSOC,
@ -1091,6 +1150,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
default:
IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not "
"handled\n", __func__, subtype));
ic->ic_stats.is_rx_badsubtype++;
break;
}
#undef ISPROBE

View File

@ -720,6 +720,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
int error = 0;
u_int kid, len;
struct ieee80211req *ireq;
struct ifreq *ifr;
u_int8_t tmpkey[IEEE80211_KEYBUF_SIZE];
char tmpssid[IEEE80211_NWID_LEN];
struct ieee80211_channel *chan;
@ -981,6 +982,10 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
error = ieee80211_cfgset(ifp, cmd, data);
break;
case SIOCG80211STATS:
ifr = (struct ifreq *)data;
copyout(&ic->ic_stats, ifr->ifr_data, sizeof (ic->ic_stats));
break;
default:
error = ether_ioctl(ifp, cmd, data);
break;

View File

@ -38,6 +38,50 @@
* IEEE 802.11 ioctls.
*/
struct ieee80211_stats {
u_int32_t is_rx_badversion; /* rx frame with bad version */
u_int32_t is_rx_tooshort; /* rx frame too short */
u_int32_t is_rx_wrongbss; /* rx from wrong bssid */
u_int32_t is_rx_dup; /* rx discard 'cuz dup */
u_int32_t is_rx_wrongdir; /* rx w/ wrong direction */
u_int32_t is_rx_mcastecho; /* rx discard 'cuz mcast echo */
u_int32_t is_rx_notassoc; /* rx discard 'cuz sta !assoc */
u_int32_t is_rx_nowep; /* rx w/ wep but wep !config */
u_int32_t is_rx_wepfail; /* rx wep processing failed */
u_int32_t is_rx_decap; /* rx decapsulation failed */
u_int32_t is_rx_mgtdiscard; /* rx discard mgt frames */
u_int32_t is_rx_ctl; /* rx discard ctrl frames */
u_int32_t is_rx_rstoobig; /* rx rate set truncated */
u_int32_t is_rx_elem_missing; /* rx required element missing*/
u_int32_t is_rx_elem_toobig; /* rx element too big */
u_int32_t is_rx_elem_toosmall; /* rx element too small */
u_int32_t is_rx_elem_unknown; /* rx element unknown */
u_int32_t is_rx_badchan; /* rx frame w/ invalid chan */
u_int32_t is_rx_chanmismatch; /* rx frame chan mismatch */
u_int32_t is_rx_nodealloc; /* rx frame dropped */
u_int32_t is_rx_ssidmismatch; /* rx frame ssid mismatch */
u_int32_t is_rx_auth_unsupported; /* rx w/ unsupported auth alg */
u_int32_t is_rx_auth_fail; /* rx sta auth failure */
u_int32_t is_rx_assoc_bss; /* rx assoc from wrong bssid */
u_int32_t is_rx_assoc_notauth; /* rx assoc w/o auth */
u_int32_t is_rx_assoc_capmismatch;/* rx assoc w/ cap mismatch */
u_int32_t is_rx_assoc_norate; /* rx assoc w/ no rate match */
u_int32_t is_rx_deauth; /* rx deauthentication */
u_int32_t is_rx_disassoc; /* rx disassociation */
u_int32_t is_rx_badsubtype; /* rx frame w/ unknown subtype*/
u_int32_t is_rx_nombuf; /* rx failed for lack of mbuf */
u_int32_t is_rx_decryptcrc; /* rx decrypt failed on crc */
u_int32_t is_rx_ahdemo_mgt; /* rx discard ahdemo mgt frame*/
u_int32_t is_rx_bad_auth; /* rx bad auth request */
u_int32_t is_tx_nombuf; /* tx failed for lack of mbuf */
u_int32_t is_tx_nonode; /* tx failed for no node */
u_int32_t is_tx_unknownmgt; /* tx of unknown mgt frame */
u_int32_t is_scan_active; /* active scans started */
u_int32_t is_scan_passive; /* passive scans started */
u_int32_t is_node_timeout; /* nodes timed out inactivity */
u_int32_t is_crypto_nomem; /* no memory for crypto ctx */
};
#ifdef __FreeBSD__
/*
* FreeBSD-style ioctls.
@ -79,6 +123,8 @@ struct ieee80211req {
#ifndef IEEE80211_CHAN_ANY
#define IEEE80211_CHAN_ANY 0xffff /* token for ``any channel'' */
#endif
#define SIOCG80211STATS _IOWR('i', 236, struct ifreq)
#endif /* __FreeBSD__ */
#endif /* _NET80211_IEEE80211_IOCTL_H_ */

View File

@ -148,8 +148,11 @@ ieee80211_begin_scan(struct ifnet *ifp)
* In all but hostap mode scanning starts off in
* an active mode before switching to passive.
*/
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
ic->ic_flags |= IEEE80211_F_ASCAN;
ic->ic_stats.is_scan_active++;
} else
ic->ic_stats.is_scan_passive++;
if (ifp->if_flags & IFF_DEBUG)
if_printf(ifp, "begin %s scan\n",
(ic->ic_flags & IEEE80211_F_ASCAN) ?
@ -581,6 +584,7 @@ ieee80211_timeout_nodes(struct ieee80211com *ic)
IEEE80211_FC0_SUBTYPE_DEAUTH,
IEEE80211_REASON_AUTH_EXPIRE);
ieee80211_free_node(ic, ni);
ic->ic_stats.is_node_timeout++;
goto restart;
}
}

View File

@ -155,7 +155,7 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node **pni)
if (m->m_len < sizeof(struct ether_header)) {
m = m_pullup(m, sizeof(struct ether_header));
if (m == NULL) {
/* XXX statistic */
ic->ic_stats.is_tx_nombuf++;
goto bad;
}
}
@ -183,6 +183,7 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node **pni)
IEEE80211_DPRINTF(("%s: no node for dst %s, "
"discard frame\n", __func__,
ether_sprintf(eh.ether_dhost)));
ic->ic_stats.is_tx_nonode++;
goto bad;
}
ni = ic->ic_bss;
@ -200,8 +201,10 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node **pni)
llc->llc_snap.org_code[2] = 0;
llc->llc_snap.ether_type = eh.ether_type;
M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
if (m == NULL)
if (m == NULL) {
ic->ic_stats.is_tx_nombuf++;
goto bad;
}
wh = mtod(m, struct ieee80211_frame *);
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
*(u_int16_t *)wh->i_dur = 0;
@ -312,7 +315,7 @@ int
ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
int type, int arg)
{
#define senderr(_x) do { ret = _x; goto bad; } while (0)
#define senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0)
struct ifnet *ifp = &ic->ic_if;
struct mbuf *m;
u_int8_t *frm;
@ -343,7 +346,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
+ 2 + IEEE80211_RATE_SIZE
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE));
if (m == NULL)
senderr(ENOMEM);
senderr(ENOMEM, is_tx_nombuf);
m->m_data += sizeof(struct ieee80211_frame);
frm = mtod(m, u_int8_t *);
frm = ieee80211_add_ssid(frm, ic->ic_des_essid, ic->ic_des_esslen);
@ -375,7 +378,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
+ 6
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE));
if (m == NULL)
senderr(ENOMEM);
senderr(ENOMEM, is_tx_nombuf);
m->m_data += sizeof(struct ieee80211_frame);
frm = mtod(m, u_int8_t *);
@ -435,7 +438,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
case IEEE80211_FC0_SUBTYPE_AUTH:
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
senderr(ENOMEM);
senderr(ENOMEM, is_tx_nombuf);
MH_ALIGN(m, 2 * 3);
m->m_pkthdr.len = m->m_len = 6;
frm = mtod(m, u_int8_t *);
@ -453,7 +456,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
ether_sprintf(ni->ni_macaddr), arg);
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
senderr(ENOMEM);
senderr(ENOMEM, is_tx_nombuf);
MH_ALIGN(m, 2);
m->m_pkthdr.len = m->m_len = 2;
*mtod(m, u_int16_t *) = htole16(arg); /* reason */
@ -478,7 +481,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
+ 2 + IEEE80211_RATE_SIZE
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE));
if (m == NULL)
senderr(ENOMEM);
senderr(ENOMEM, is_tx_nombuf);
m->m_data += sizeof(struct ieee80211_frame);
frm = mtod(m, u_int8_t *);
@ -534,7 +537,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
+ 2 + IEEE80211_RATE_SIZE
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE));
if (m == NULL)
senderr(ENOMEM);
senderr(ENOMEM, is_tx_nombuf);
m->m_data += sizeof(struct ieee80211_frame);
frm = mtod(m, u_int8_t *);
@ -565,7 +568,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
ether_sprintf(ni->ni_macaddr), arg);
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
senderr(ENOMEM);
senderr(ENOMEM, is_tx_nombuf);
MH_ALIGN(m, 2);
m->m_pkthdr.len = m->m_len = 2;
*mtod(m, u_int16_t *) = htole16(arg); /* reason */
@ -574,7 +577,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
default:
IEEE80211_DPRINTF(("%s: invalid mgmt frame type %u\n",
__func__, type));
senderr(EINVAL);
senderr(EINVAL, is_tx_unknownmgt);
/* NOTREACHED */
}

View File

@ -40,6 +40,7 @@
#include <net80211/ieee80211.h>
#include <net80211/ieee80211_crypto.h>
#include <net80211/ieee80211_ioctl.h> /* for ieee80211_stats */
#include <net80211/ieee80211_node.h>
#include <net80211/ieee80211_proto.h>
@ -193,6 +194,7 @@ struct ieee80211com {
int ic_wep_txkey; /* default tx key index */
void *ic_wep_ctx; /* wep crypt context */
u_int32_t ic_iv; /* initial vector for wep */
struct ieee80211_stats ic_stats; /* statistics */
};
#define ic_if ic_ac.ac_if
#define ic_softc ic_if.if_softc