PERFORCE change 38422 for review

Sam Leffler sam at FreeBSD.org
Mon Sep 22 09:02:00 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=38422

Change 38422 by sam at sam_ebb on 2003/09/22 09:01:36

	o allocate node table entries with a specific malloc type
	o add various statistics (still need per-node stats)
	o add SIOCG80211STATS ioctl to retrieve statistics
	o correct spelling of IEEE80211_IOCT_RTSTHRESHOLD

Affected files ...

.. //depot/projects/netperf/sys/net80211/ieee80211_crypto.c#2 edit
.. //depot/projects/netperf/sys/net80211/ieee80211_input.c#7 edit
.. //depot/projects/netperf/sys/net80211/ieee80211_ioctl.c#3 edit
.. //depot/projects/netperf/sys/net80211/ieee80211_ioctl.h#2 edit
.. //depot/projects/netperf/sys/net80211/ieee80211_node.c#8 edit
.. //depot/projects/netperf/sys/net80211/ieee80211_output.c#6 edit
.. //depot/projects/netperf/sys/net80211/ieee80211_var.h#5 edit

Differences ...

==== //depot/projects/netperf/sys/net80211/ieee80211_crypto.c#2 (text+ko) ====

@@ -113,16 +113,23 @@
 	n0 = NULL;
 	if ((ctx = ic->ic_wep_ctx) == NULL) {
 		ctx = malloc(arc4_ctxlen(), M_DEVBUF, M_NOWAIT);
-		if (ctx == NULL)
+		if (ctx == NULL) {
+			/* XXX statistic */
 			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 @@
 			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 @@
 		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 @@
 					    n0->m_len, -1, -1);
 			}
 #endif
+			ic->ic_stats.is_rx_decryptcrc++;
 			goto fail;
 		}
 	}

==== //depot/projects/netperf/sys/net80211/ieee80211_input.c#7 (text+ko) ====

@@ -113,6 +113,7 @@
 			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;
 	}
 
@@ -125,6 +126,7 @@
 	 */
 	if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
 		/* XXX statistic */
+		ic->ic_stats.is_rx_tooshort++;
 		goto out;		/* XXX */
 	}
 	if (ic->ic_state != IEEE80211_S_SCAN) {
@@ -135,6 +137,7 @@
 					"bss %s\n", __func__,
 					ether_sprintf(wh->i_addr2)));
 				/* not interested in */
+				ic->ic_stats.is_rx_wrongbss++;
 				goto out;
 			}
 			break;
@@ -150,6 +153,7 @@
 				/* not interested in */
 				IEEE80211_DPRINTF2(("%s: other bss %s\n",
 					__func__, ether_sprintf(wh->i_addr3)));
+				ic->ic_stats.is_rx_wrongbss++;
 				goto out;
 			}
 			break;
@@ -168,6 +172,7 @@
 		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;
@@ -177,8 +182,10 @@
 	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)) {
@@ -188,17 +195,22 @@
 				 * 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 "
@@ -212,6 +224,7 @@
 					    IEEE80211_REASON_NOT_AUTHED);
 					ieee80211_free_node(ic, ni);
 				}
+				ic->ic_stats.is_rx_notassoc++;
 				goto err;
 			}
 			if (ni->ni_associd == 0) {
@@ -222,6 +235,7 @@
 				    IEEE80211_FC0_SUBTYPE_DISASSOC,
 				    IEEE80211_REASON_NOT_ASSOCED);
 				ieee80211_unref_node(&ni);
+				ic->ic_stats.is_rx_notassoc++;
 				goto err;
 			}
 			break;
@@ -231,18 +245,24 @@
 		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 */
@@ -283,21 +303,29 @@
 		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) {
+			/* XXX statistic */
 			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) {
@@ -333,6 +361,7 @@
 		return;
 
 	case IEEE80211_FC0_TYPE_CTL:
+		ic->ic_stats.is_rx_ctl++;
 		goto out;
 	default:
 		IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, type));
@@ -472,6 +501,7 @@
 			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;
@@ -479,13 +509,13 @@
 	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)) {					\
@@ -494,6 +524,7 @@
 			ieee80211_mgt_subtype_name[subtype >>		\
 				IEEE80211_FC0_SUBTYPE_SHIFT],		\
 			ether_sprintf(wh->i_addr2)));			\
+		ic->ic_stats.is_rx_elem_toobig++;			\
 		return;							\
 	}								\
 } while (0)
@@ -505,6 +536,7 @@
 			ieee80211_mgt_subtype_name[subtype >>		\
 				IEEE80211_FC0_SUBTYPE_SHIFT],		\
 			ether_sprintf(wh->i_addr2)));			\
+		ic->ic_stats.is_rx_elem_toosmall++;			\
 		return;							\
 	}								\
 } while (0)
@@ -595,6 +627,7 @@
 					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];
@@ -602,6 +635,7 @@
 			default:
 				IEEE80211_DPRINTF(("%s: element id %u/len %u "
 					"ignored\n", __func__, *frm, frm[1]));
+				ic->ic_stats.is_rx_elem_unknown++;
 				break;
 			}
 			frm += frm[1] + 2;
@@ -617,6 +651,7 @@
 				"%u\n", __func__,
 				ISPROBE(subtype) ? "probe response" : "beacon",
 				chan));
+			ic->ic_stats.is_rx_badchan++;
 			return;
 		}
 		if (chan != bchan) {
@@ -631,7 +666,7 @@
 				"for channel %u\n", __func__,
 				ISPROBE(subtype) ? "probe response" : "beacon",
 				bchan, chan));
-			/* XXX statistic */
+			ic->ic_stats.is_rx_chanmismatch++;
 			return;
 		}
 
@@ -666,8 +701,10 @@
 #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]);
@@ -738,13 +775,16 @@
 				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;
@@ -789,12 +829,15 @@
 			/* 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;
 		}
 		switch (ic->ic_opmode) {
 		case IEEE80211_M_IBSS:
-			if (ic->ic_state != IEEE80211_S_RUN || seq != 1)
+			if (ic->ic_state != IEEE80211_S_RUN || seq != 1) {
+				/* XXX statistic */
 				return;
+			}
 			ieee80211_new_state(ic, IEEE80211_S_AUTH,
 			    wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
 			break;
@@ -808,8 +851,10 @@
 				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;
@@ -826,8 +871,10 @@
 			break;
 
 		case IEEE80211_M_STA:
-			if (ic->ic_state != IEEE80211_S_AUTH || seq != 2)
+			if (ic->ic_state != IEEE80211_S_AUTH || seq != 2) {
+				/* XXX statistic */
 				return;
+			}
 			if (status != 0) {
 				if_printf(&ic->ic_if,
 				    "authentication failed (reason %d) for %s\n",
@@ -835,6 +882,7 @@
 				    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,
@@ -874,6 +922,7 @@
 		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;
@@ -906,6 +955,7 @@
 				printf(" from %s\n", ether_sprintf(wh->i_addr2));
 			}
 #endif
+			ic->ic_stats.is_rx_ssidmismatch++;
 			return;
 		}
 		if (ni == ic->ic_bss) {
@@ -918,6 +968,7 @@
 				    IEEE80211_REASON_ASSOC_NOT_AUTHED);
 				ieee80211_free_node(ic, ni);
 			}
+			ic->ic_stats.is_rx_assoc_notauth++;
 			return;
 		}
 		/* XXX per-node cipher suite */
@@ -932,6 +983,7 @@
 			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,
@@ -943,6 +995,7 @@
 			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;
@@ -1000,6 +1053,7 @@
 			    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);
@@ -1036,6 +1090,7 @@
 		 */
 		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,
@@ -1065,6 +1120,7 @@
 		 */
 		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,
@@ -1088,6 +1144,7 @@
 	default:
 		IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not "
 			"handled\n", __func__, subtype));
+		ic->ic_stats.is_rx_badsubtype++;
 		break;
 	}
 #undef ISPROBE

==== //depot/projects/netperf/sys/net80211/ieee80211_ioctl.c#3 (text+ko) ====

@@ -720,6 +720,7 @@
 	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;
@@ -823,7 +824,7 @@
 		case IEEE80211_IOC_POWERSAVESLEEP:
 			ireq->i_val = ic->ic_lintval;
 			break;
-		case IEEE80211_IOCT_RTSTHRESHOLD:
+		case IEEE80211_IOC_RTSTHRESHOLD:
 			ireq->i_val = ic->ic_rtsthreshold;
 			break;
 		default:
@@ -958,7 +959,7 @@
 			ic->ic_lintval = ireq->i_val;
 			error = ENETRESET;
 			break;
-		case IEEE80211_IOCT_RTSTHRESHOLD:
+		case IEEE80211_IOC_RTSTHRESHOLD:
 			if (!(IEEE80211_RTS_MIN < ireq->i_val &&
 			      ireq->i_val < IEEE80211_RTS_MAX)) {
 				error = EINVAL;
@@ -981,6 +982,10 @@
 			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;

==== //depot/projects/netperf/sys/net80211/ieee80211_ioctl.h#2 (text+ko) ====

@@ -74,11 +74,54 @@
 #define 	IEEE80211_POWERSAVE_PSP_CAM	3
 #define 	IEEE80211_POWERSAVE_ON		IEEE80211_POWERSAVE_CAM
 #define IEEE80211_IOC_POWERSAVESLEEP	11
-#define	IEEE80211_IOCT_RTSTHRESHOLD	12
+#define	IEEE80211_IOC_RTSTHRESHOLD	12
 
 #ifndef IEEE80211_CHAN_ANY
 #define	IEEE80211_CHAN_ANY	0xffff		/* token for ``any channel'' */
 #endif
+
+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_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 */
+};
+
+#define	SIOCG80211STATS		_IOWR('i', 236, struct ifreq)
 #endif /* __FreeBSD__ */
 
 #endif /* _NET80211_IEEE80211_IOCTL_H_ */

==== //depot/projects/netperf/sys/net80211/ieee80211_node.c#8 (text+ko) ====

@@ -78,6 +78,8 @@
 static void _ieee80211_free_node(struct ieee80211com *,
 		struct ieee80211_node *);
 
+MALLOC_DEFINE(M_80211_NODE, "node", "802.11 node state");
+
 void
 ieee80211_node_attach(struct ifnet *ifp)
 {
@@ -145,8 +147,11 @@
 	 * 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) ?
@@ -393,14 +398,14 @@
 static struct ieee80211_node *
 ieee80211_node_alloc(struct ieee80211com *ic)
 {
-	return malloc(sizeof(struct ieee80211_node), M_DEVBUF,
+	return malloc(sizeof(struct ieee80211_node), M_80211_NODE,
 		M_NOWAIT | M_ZERO);
 }
 
 static void
 ieee80211_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
 {
-	free(ni, M_DEVBUF);
+	free(ni, M_80211_NODE);
 }
 
 static void
@@ -559,6 +564,7 @@
 			    IEEE80211_FC0_SUBTYPE_DEAUTH,
 			    IEEE80211_REASON_AUTH_EXPIRE);
 			ieee80211_free_node(ic, ni);
+			ic->ic_stats.is_node_timeout++;
 			ni = nextbs;
 		} else
 			ni = TAILQ_NEXT(ni, ni_list);

==== //depot/projects/netperf/sys/net80211/ieee80211_output.c#6 (text+ko) ====

@@ -155,7 +155,7 @@
 	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;
 		}
 	}
@@ -171,7 +171,7 @@
 			 * multicast/broadcast frame.
 			 */
 			if (!IEEE80211_IS_MULTICAST(eh.ether_dhost)) {
-				/* ic->ic_stats.st_tx_nonode++; XXX statistic */
+				ic->ic_stats.is_tx_nonode++; 
 				goto bad;
 			}
 			ni = ic->ic_bss;
@@ -189,8 +189,10 @@
 	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;
@@ -301,7 +303,7 @@
 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;
@@ -332,7 +334,7 @@
 		       + 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);
@@ -362,7 +364,7 @@
 		       + 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 *);
 
@@ -406,7 +408,7 @@
 	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 *);
@@ -424,7 +426,7 @@
 			    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 */
@@ -449,7 +451,7 @@
 		       + 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 *);
 
@@ -505,7 +507,7 @@
 		       + 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 *);
 
@@ -536,7 +538,7 @@
 			    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 */
@@ -545,7 +547,7 @@
 	default:
 		IEEE80211_DPRINTF(("%s: invalid mgmt frame type %u\n",
 			__func__, type));
-		senderr(EINVAL);
+		senderr(EINVAL, is_tx_unknownmgt);
 		/* NOTREACHED */
 	}
 

==== //depot/projects/netperf/sys/net80211/ieee80211_var.h#5 (text+ko) ====

@@ -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>
 
@@ -192,6 +193,7 @@
 	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


More information about the p4-projects mailing list