/*-
* 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 <sys/types.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/wireless.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include <unistd.h>
#include <sys/time.h> // 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;
}
Last modified
19 years ago
Last modified on Jul 31, 2006, 1:27:39 AM
Note:
See TracWiki
for help on using the wiki.
