Date: Sat, 27 Nov 2004 19:35:52 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 65931 for review Message-ID: <200411271935.iARJZqeG031605@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=65931 Change 65931 by sam@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); + } + } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411271935.iARJZqeG031605>