wiki:Old/Athstats/athstats-oml
/*-
 * 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 18 years ago Last modified on Jul 31, 2006, 1:27:39 AM
Note: See TracWiki for help on using the wiki.