From owner-p4-projects@FreeBSD.ORG Sat Nov 27 19:35:53 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 2306E16A4D0; Sat, 27 Nov 2004 19:35:53 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BFF0516A4CF for ; Sat, 27 Nov 2004 19:35:52 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8BD6043D31 for ; Sat, 27 Nov 2004 19:35:52 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id iARJZqsf031608 for ; Sat, 27 Nov 2004 19:35:52 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id iARJZqeG031605 for perforce@freebsd.org; Sat, 27 Nov 2004 19:35:52 GMT (envelope-from sam@freebsd.org) Date: Sat, 27 Nov 2004 19:35:52 GMT Message-Id: <200411271935.iARJZqeG031605@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 65931 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Nov 2004 19:35:53 -0000 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 #include #include +#include #include #include +#include +#include #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); + } + } }