/*- * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ /* * Simple Atheros-specific tool to inspect and monitor network traffic * statistics. * * athstats [-i interface] [-bz] [-l] [-o fmtstring] [interval] * * (default interface is ath0). If interval is specified a rolling output * a la netstat -i is displayed every interval seconds. The format of * the rolling display can be controlled a la ps. The -l option will * print a list of all possible statistics for use with the -o option. */ #include #include #include #include #include #include #include "athstats.h" static struct { const char *tag; const char *fmt; } tags[] = { { "default", "input,output,altrate,short,long,xretry,crcerr,crypt,phyerr,rssi,rate" }, { "ani", "avgbrssi,avgrssi,avgtxrssi,NI,SI,step,owsd,cwst,NI+,NI-,SI+,SI-,OFDM,CCK,LISTEN" }, { "tdma", "input,output,bexmit,tdmau,tdmadj,crcerr,phyerr,phytor,rssi,noise,rate" }, }; static const char * getfmt(const char *tag) { #define N(a) (sizeof(a)/sizeof(a[0])) int i; for (i = 0; i < N(tags); i++) if (strcasecmp(tags[i].tag, tag) == 0) return tags[i].fmt; return tag; #undef N } static int signalled; static void catchalarm(int signo __unused) { signalled = 1; } int main(int argc, char *argv[]) { struct athstatfoo *wf; const char *ifname; int c, banner = 1; ifname = getenv("ATH"); if (ifname == NULL) ifname = "ath0"; wf = athstats_new(ifname, getfmt("default")); while ((c = getopt(argc, argv, "bi:lo:z")) != -1) { switch (c) { case 'b': banner = 0; break; case 'i': wf->setifname(wf, optarg); break; case 'l': wf->print_fields(wf, stdout); return 0; case 'o': wf->setfmt(wf, getfmt(optarg)); break; case 'z': wf->zerostats(wf); break; default: errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [-z] [interval]\n", argv[0]); /*NOTREACHED*/ } } argc -= optind; argv += optind; if (argc > 0) { u_long interval = strtoul(argv[0], NULL, 0); int line, omask; if (interval < 1) interval = 1; signal(SIGALRM, catchalarm); signalled = 0; alarm(interval); banner: if (banner) wf->print_header(wf, stdout); line = 0; loop: if (line != 0) { wf->collect_cur(wf); wf->print_current(wf, stdout); wf->update_tot(wf); } else { wf->collect_tot(wf); wf->print_total(wf, stdout); } fflush(stdout); omask = sigblock(sigmask(SIGALRM)); if (!signalled) sigpause(0); sigsetmask(omask); signalled = 0; alarm(interval); line++; if (line == 21) /* XXX tty line count */ goto banner; else goto loop; /*NOTREACHED*/ } else { wf->collect_tot(wf); wf->print_verbose(wf, stdout); } return 0; }