Home | History | Annotate | Line # | Download | only in altqstat
altqstat.c revision 1.1
      1 /*	$KAME: altqstat.c,v 1.4 2000/12/03 05:44:19 kawa Exp $	*/
      2 /*
      3  * Copyright (C) 1999-2000
      4  *	Sony Computer Science Laboratories, Inc.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
     16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
     19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25  * SUCH DAMAGE.
     26  */
     27 
     28 #include <sys/param.h>
     29 #include <sys/time.h>
     30 #include <sys/fcntl.h>
     31 
     32 #include <stdio.h>
     33 #include <stdlib.h>
     34 #include <unistd.h>
     35 #include <string.h>
     36 #include <signal.h>
     37 #include <errno.h>
     38 #include <err.h>
     39 #ifndef NO_CURSES
     40 #include <curses.h>
     41 #endif
     42 
     43 #include "quip_client.h"
     44 #include "altqstat.h"
     45 
     46 #define DEV_PATH	"/dev/altq"
     47 
     48 int qdiscfd = -1;
     49 int show_config = 0;
     50 int interval = 5;
     51 int no_server = 0;
     52 char *interface = NULL;
     53 char *qdisc_name = NULL;
     54 
     55 stat_loop_t *stat_loop;
     56 
     57 static void sig_handler(int sig);
     58 static void usage(void);
     59 
     60 static void
     61 sig_handler(int sig)
     62 {
     63 	fprintf(stderr, "Exiting on signal %d\n", sig);
     64 
     65 	close(qdiscfd);  /* close altq device */
     66 	quip_closeserver();  /* clocse socket to altqd */
     67 #ifndef NO_CURSES
     68 	if (qdisc_name != NULL && strcmp(qdisc_name, "wfq") == 0)
     69 		endwin();	/* wfqstat uses curses */
     70 #endif
     71 	exit(0);
     72 }
     73 
     74 static void
     75 usage(void)
     76 {
     77 	fprintf(stderr, "usage: altqstat [-enrs] [-c count] [-w wait] [-i interface|-I input_interface]\n");
     78 	exit(1);
     79 }
     80 
     81 int
     82 main (int argc, char **argv)
     83 {
     84 	int ch, raw_mode = 0;
     85 	int qtype;
     86 	int count = 0;
     87 	char device[64], qname[64], input[32];
     88 
     89 	while ((ch = getopt(argc, argv, "I:c:ei:nrsw:")) != -1) {
     90 		switch (ch) {
     91 		case 'I':
     92 			sprintf(input, "_%s", optarg);
     93 			interface = input;
     94 			break;
     95 		case 'c':
     96 			count = atoi(optarg);
     97 			break;
     98 		case 'e':
     99 			quip_echo = 1;
    100 			break;
    101 		case 'i':
    102 			interface = optarg;
    103 			break;
    104 		case 'n':
    105 			no_server = 1;
    106 			break;
    107 		case 'r':
    108 			raw_mode = 1;
    109 			quip_echo = 1;
    110 			break;
    111 		case 's':
    112 			show_config = 1;
    113 			break;
    114 		case 'w':
    115 			interval = atoi(optarg);
    116 			break;
    117 		default:
    118 			usage();
    119 			break;
    120 		}
    121 	}
    122 
    123 	signal(SIGINT, sig_handler);
    124 	signal(SIGTERM, sig_handler);
    125 	signal(SIGPIPE, sig_handler);
    126 
    127 	if (no_server == 0) {
    128 		if (quip_openserver() < 0 && interface == NULL)
    129 			errx(1, "you have to specify interface!");
    130 	}
    131 
    132 	if (raw_mode == 1) {
    133 		quip_rawmode();
    134 		quip_closeserver();
    135 		exit(0);
    136 	}
    137 
    138 	if (show_config) {
    139 		if (no_server)
    140 			errx(1, "no server (-n) can't be set for show config (-s)!");
    141 		quip_printconfig();
    142 		quip_closeserver();
    143 		exit(0);
    144 	}
    145 
    146 	interface = quip_selectinterface(interface);
    147 	if (interface == NULL)
    148 		errx(1, "no interface found!");
    149 
    150 	qtype = ifname2qdisc(interface, qname);
    151 	if (qtype == 0)
    152 		errx(1, "altq is not attached on %s!", interface);
    153 
    154 	qdisc_name = qname;
    155 
    156 	stat_loop = qdisc2stat_loop(qdisc_name);
    157 	if (stat_loop == NULL)
    158 		errx(1, "qdisc %s is not supported!", qdisc_name);
    159 
    160 	printf("%s: %s on interface %s\n",
    161 	       argv[0], qdisc_name, interface);
    162 
    163 	sprintf(device, "%s/%s", DEV_PATH, qdisc_name);
    164 	if ((qdiscfd = open(device, O_RDONLY)) < 0)
    165 		err(1, "can't open %s", device);
    166 
    167 	(*stat_loop)(qdiscfd, interface, count, interval);
    168 	/* never returns */
    169 
    170 	exit(0);
    171 }
    172 
    173 /* calculate interval in sec */
    174 double
    175 calc_interval(struct timeval *cur_time, struct timeval *last_time)
    176 {
    177 	double sec;
    178 
    179 	sec = (double)(cur_time->tv_sec - last_time->tv_sec) +
    180 	    (double)(cur_time->tv_usec - last_time->tv_usec) / 1000000;
    181 	return (sec);
    182 }
    183 
    184 
    185 /* calculate rate in bps */
    186 double
    187 calc_rate(u_int64_t new_bytes, u_int64_t last_bytes, double interval)
    188 {
    189 	double rate;
    190 
    191 	rate = (double)(new_bytes - last_bytes) * 8 / interval;
    192 	return (rate);
    193 }
    194 
    195 /* calculate packets in second */
    196 double
    197 calc_pps(u_int64_t new_pkts, u_int64_t last_pkts, double interval)
    198 {
    199 	double pps;
    200 
    201 	pps = (double)(new_pkts - last_pkts) / interval;
    202 	return (pps);
    203 }
    204 
    205 #define	R2S_BUFS	8
    206 
    207 char *
    208 rate2str(double rate)
    209 {
    210 	char *buf;
    211 	static char r2sbuf[R2S_BUFS][16];  /* ring bufer for up to R2S_BUFS */
    212 	static int idx = 0;
    213 
    214 	buf = r2sbuf[idx++];
    215 	if (idx == R2S_BUFS)
    216 		idx = 0;
    217 
    218 	if (rate == 0.0)
    219 		sprintf(buf, "0");
    220 	else if (rate >= 1000000.0)
    221 		sprintf(buf, "%.2fM", rate / 1000000.0);
    222 	else
    223 		sprintf(buf, "%.2fK", rate / 1000.0);
    224 	return (buf);
    225 }
    226