{{{ /*- * Copyright (c) 2002-2004 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. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * 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: src/tools/tools/ath/athstats.c,v 1.4 2003/12/07 21:40:52 sam Exp $ */ /* * Simple Atheros-specific tool to inspect and monitor network traffic * statistics. * athstats [--interface interface] [--interval interval] * (default interface is ath0 and default interval is 1 second). * If interval is specified a rolling output is displayed every interval msec. */ /* Modified by Kishore Ramachandran - kishore@winlab.rutgers.edu. Oct 14 2005 */ #include #include #include #include #include #include #include #include #include #include #include #include // For setitimer #include "ah_desc.h" #include "ieee80211_radiotap.h" #include "if_athioctl.h" #include "include/oml_orbit_winlab_athstats.h" // For OML static int signalled; static void catchalarm(int signo) { signalled = 1; } int main(int argc, char *argv[]) { struct ifreq ifr; struct itimerval it_val; struct ath_stats cur, total; u_long interval, off, icur, ocur, itot, otot; int s, line, omask; sigset_t oset1, oset2, *oset1_p, *oset2_p; if (argc < 5) { fprintf(stderr, "Usage: ./athfstats --interface name_of_interface --interval how often to query the driver in ms.\n"); fprintf(stderr, "E.g. : ./athfstats --interface ath0 --interval 100\n"); exit(-1); } if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) err(1, "socket"); if (strcmp(argv[1], "--interface") == 0) { if (!(strcmp(argv[2], "ath0")) || !(strcmp(argv[2], "ath1"))) strncpy(ifr.ifr_name, argv[2], sizeof (ifr.ifr_name)); else { fprintf(stderr, "Expecting madwifi to name interfaces as ath0 or ath1. Using ath0 as default.\n"); strncpy(ifr.ifr_name, "ath0", sizeof (ifr.ifr_name)); } } else { fprintf(stderr, "Usage: ./athstats-oml --interface name_of_interface --interval interval_in_ms\n"); exit(-1); } if (strcmp(argv[3], "--interval") == 0) { if ((interval = strtoul(argv[4], NULL, 0)) < 1) { fprintf(stderr, "Expecting interval value greater than or equal to 1. Using 100ms as default.\n"); interval = 100; } } else { fprintf(stderr, "Usage: ./athstats-oml --interface name_of_interface --interval interval_in_ms\n"); exit(-1); } signal(SIGALRM, catchalarm); signalled = 0; it_val.it_value.tv_sec = interval/1000; it_val.it_value.tv_usec = (interval*1000) % 1000000; it_val.it_interval = it_val.it_value; if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) { perror("error calling setitimer()"); exit(-1); } initialize_oml(&argc, (const char **)argv, NULL); line = 0; // loop: while (1) { if (line != 0) { ifr.ifr_data = (caddr_t) &cur; if (ioctl(s, SIOCGATHSTATS, &ifr) < 0) err(1, ifr.ifr_name); oml_queryport(cur.ast_tx_packets - total.ast_tx_packets, cur.ast_tx_xretries - total.ast_tx_xretries, cur.ast_tx_fifoerr - total.ast_tx_fifoerr, cur.ast_tx_filtered - total.ast_tx_filtered, cur.ast_tx_shortretry - total.ast_tx_shortretry, cur.ast_tx_longretry - total.ast_tx_longretry, cur.ast_rx_packets - total.ast_rx_packets, cur.ast_rx_crcerr - total.ast_rx_crcerr, cur.ast_rx_fifoerr - total.ast_rx_fifoerr, cur.ast_rx_phyerr - total.ast_rx_phyerr ); total = cur; itot = icur; otot = ocur; } else { ifr.ifr_data = (caddr_t) &total; if (ioctl(s, SIOCGATHSTATS, &ifr) < 0) err(1, ifr.ifr_name); oml_queryport(total.ast_tx_packets, total.ast_tx_xretries, total.ast_tx_fifoerr, total.ast_tx_filtered, total.ast_tx_shortretry, total.ast_tx_longretry, total.ast_rx_packets, total.ast_rx_crcerr, total.ast_rx_fifoerr, total.ast_rx_phyerr ); } oset1_p = &oset1; oset2_p = &oset2; sigemptyset(oset1_p); sigemptyset(oset2_p); sigaddset(oset1_p, SIGALRM); sigprocmask(SIG_BLOCK, oset1_p, oset2_p); if (!signalled) sigsuspend(oset2_p); sigprocmask(SIG_SETMASK, oset2_p, NULL); signalled = 0; it_val.it_value.tv_sec = interval/1000; it_val.it_value.tv_usec = (interval*1000) % 1000000; it_val.it_interval = it_val.it_value; if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) { perror("error calling setitimer()"); exit(-1); } line++; } // goto loop; /*NOTREACHED*/ return 0; } }}}