PERFORCE change 65931 for review
Sam Leffler
sam at FreeBSD.org
Sat Nov 27 11:35:53 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=65931
Change 65931 by sam at sam_ebb on 2004/11/27 19:35:45
crude per-station stats reporting
Affected files ...
.. //depot/projects/wifi/tools/tools/ath/80211stats.c#4 edit
Differences ...
==== //depot/projects/wifi/tools/tools/ath/80211stats.c#4 (text+ko) ====
@@ -47,9 +47,12 @@
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_var.h>
+#include <net/ethernet.h>
#include <stdio.h>
#include <signal.h>
+#include <unistd.h>
+#include <err.h>
#include "../../../sys/net80211/ieee80211_ioctl.h"
@@ -144,30 +147,142 @@
#undef N
}
+struct ifreq ifr;
+int s;
+
+static void
+print_sta_stats(FILE *fd, const u_int8_t macaddr[IEEE80211_ADDR_LEN])
+{
+#define STAT(x,fmt) \
+ if (ns->ns_##x) { fprintf(fd, "%s" #x " " fmt, sep, ns->ns_##x); sep = " "; }
+ struct ieee80211req ireq;
+ struct ieee80211req_sta_stats stats;
+ const struct ieee80211_nodestats *ns = &stats.is_stats;
+ const char *sep;
+
+ (void) memset(&ireq, 0, sizeof(ireq));
+ (void) strncpy(ireq.i_name, ifr.ifr_name, sizeof(ireq.i_name));
+ ireq.i_type = IEEE80211_IOC_STA_STATS;
+ ireq.i_data = &stats;
+ ireq.i_len = sizeof(stats);
+ memcpy(stats.is_u.macaddr, macaddr, IEEE80211_ADDR_LEN);
+ if (ioctl(s, SIOCG80211, &ireq) < 0)
+ err(1, "unable to get station stats for %s",
+ ether_ntoa((const struct ether_addr*) macaddr));
+
+ fprintf(fd, "%s:\n", ether_ntoa((const struct ether_addr*) macaddr));
+
+ sep = "\t";
+ STAT(rx_data, "%u");
+ STAT(rx_mgmt, "%u");
+ STAT(rx_ctrl, "%u");
+ STAT(rx_beacons, "%u");
+ STAT(rx_proberesp, "%u");
+ STAT(rx_ucast, "%u");
+ STAT(rx_mcast, "%u");
+ STAT(rx_bytes, "%llu");
+ STAT(rx_dup, "%u");
+ STAT(rx_noprivacy, "%u");
+ STAT(rx_wepfail, "%u");
+ STAT(rx_demicfail, "%u");
+ STAT(rx_decap, "%u");
+ STAT(rx_defrag, "%u");
+ STAT(rx_disassoc, "%u");
+ STAT(rx_deauth, "%u");
+ STAT(rx_decryptcrc, "%u");
+ STAT(rx_unauth, "%u");
+ STAT(rx_unencrypted, "%u");
+ fprintf(fd, "\n");
+
+ sep = "\t";
+ STAT(tx_data, "%u");
+ STAT(tx_mgmt, "%u");
+ STAT(tx_probereq, "%u");
+ STAT(tx_ucast, "%u");
+ STAT(tx_mcast, "%u");
+ STAT(tx_bytes, "%llu");
+ STAT(tx_novlantag, "%u");
+ STAT(tx_vlanmismatch, "%u");
+ fprintf(fd, "\n");
+
+ sep = "\t";
+ STAT(tx_assoc, "%u");
+ STAT(tx_assoc_fail, "%u");
+ STAT(tx_auth, "%u");
+ STAT(tx_auth_fail, "%u");
+ STAT(tx_deauth, "%u");
+ STAT(tx_deauth_code, "%llu");
+ STAT(tx_disassoc, "%u");
+ STAT(tx_disassoc_code, "%u");
+ fprintf(fd, "\n");
+
+#undef STAT
+}
+
int
main(int argc, char *argv[])
{
- int s;
- struct ifreq ifr;
- struct ieee80211_stats stats;
+ int c, len;
+ struct ieee80211req_sta_info *si;
+ uint8_t buf[24*1024], *cp;
+ struct ieee80211req ireq;
+ int allnodes = 0;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
err(1, "socket");
- if (argc > 1 && strcmp(argv[1], "-i") == 0) {
- if (argc < 2) {
- fprintf(stderr, "%s: missing interface name for -i\n",
- argv[0]);
- exit(-1);
+ strncpy(ifr.ifr_name, "ath0", sizeof (ifr.ifr_name));
+ while ((c = getopt(argc, argv, "ai:")) != -1)
+ switch (c) {
+ case 'a':
+ allnodes++;
+ break;
+ case 'i':
+ strncpy(ifr.ifr_name, optarg, sizeof (ifr.ifr_name));
+ break;
+ default:
+ errx(1, "usage: %s [-a] [-i device] [mac...]\n");
+ /*NOTREACHED*/
}
- strncpy(ifr.ifr_name, argv[2], sizeof (ifr.ifr_name));
- argc -= 2, argv += 2;
- } else
- strncpy(ifr.ifr_name, "ath0", sizeof (ifr.ifr_name));
+
+ if (argc == optind && !allnodes) {
+ struct ieee80211_stats stats;
- ifr.ifr_data = (caddr_t) &stats;
- if (ioctl(s, SIOCG80211STATS, &ifr) < 0)
- err(1, ifr.ifr_name);
- printstats(stdout, &stats);
- return 0;
+ /* no args, just show global stats */
+ ifr.ifr_data = (caddr_t) &stats;
+ if (ioctl(s, SIOCG80211STATS, &ifr) < 0)
+ err(1, ifr.ifr_name);
+ printstats(stdout, &stats);
+ return 0;
+ }
+ if (allnodes) {
+ /*
+ * Retrieve station/neighbor table and print stats for each.
+ */
+ (void) memset(&ireq, 0, sizeof(ireq));
+ (void) strncpy(ireq.i_name, ifr.ifr_name, sizeof(ireq.i_name));
+ ireq.i_type = IEEE80211_IOC_STA_INFO;
+ ireq.i_data = buf;
+ ireq.i_len = sizeof(buf);
+ if (ioctl(s, SIOCG80211, &ireq) < 0)
+ err(1, "unable to get station information");
+ len = ireq.i_len;
+ if (len >= sizeof(struct ieee80211req_sta_info)) {
+ cp = buf;
+ do {
+ si = (struct ieee80211req_sta_info *) cp;
+ print_sta_stats(stdout, si->isi_macaddr);
+ cp += si->isi_len, len -= si->isi_len;
+ } while (len >= sizeof(struct ieee80211req_sta_info));
+ }
+ } else {
+ /*
+ * Print stats for specified stations.
+ */
+ for (c = optind; c < argc; c++) {
+ const struct ether_addr *ea = ether_aton(argv[c]);
+ if (ea != NULL)
+ print_sta_stats(stdout, ea->octet);
+ }
+ }
}
More information about the p4-projects
mailing list