1 /*-
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * 2012, Adrian Chadd
4 * 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 * without modification.
12 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
13 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
14 * redistribution must be conditioned upon including a substantially
15 * similar Disclaimer requirement for further binary redistribution.
16 *
17 * NO WARRANTY
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
21 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
23 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGES.
29 */
30
31 /*
32 * Simple Atheros-specific tool to inspect and monitor software queue
33 * and aggregate statistics.
34 *
35 * athaggrstats [-i interface] [-bz] [-l] [-o fmtstring] [interval]
36 *
37 * (default interface is ath0). If interval is specified a rolling output
38 * a la netstat -i is displayed every interval seconds. The format of
39 * the rolling display can be controlled a la ps. The -l option will
40 * print a list of all possible statistics for use with the -o option.
41 */
42
43 #include <sys/param.h>
44
45 #include <err.h>
46 #include <signal.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <unistd.h>
51
52 #include "athaggrstats.h"
53
54 static struct {
55 const char *tag;
56 const char *fmt;
57 } tags[] = {
58 { "default",
59 "singlepkt,nonbawpkt,aggrpkt,bawclosedpkt,lhsinglepkt,schednopkt,rtsaggrlimit"
60 },
61 };
62
63 static const char *
getfmt(const char * tag)64 getfmt(const char *tag)
65 {
66 int i;
67 for (i = 0; i < nitems(tags); i++)
68 if (strcasecmp(tags[i].tag, tag) == 0)
69 return tags[i].fmt;
70 return tag;
71 }
72
73 static int signalled;
74
75 static void
catchalarm(int signo __unused)76 catchalarm(int signo __unused)
77 {
78 signalled = 1;
79 }
80
81 int
main(int argc,char * argv[])82 main(int argc, char *argv[])
83 {
84 struct athaggrstatfoo *wf;
85 const char *ifname;
86 int c, banner = 1;
87
88 ifname = getenv("ATH");
89 if (ifname == NULL)
90 ifname = ATH_DEFAULT;
91 wf = athaggrstats_new(ifname, getfmt("default"));
92 while ((c = getopt(argc, argv, "bi:lo:z")) != -1) {
93 switch (c) {
94 case 'b':
95 banner = 0;
96 break;
97 case 'i':
98 wf->setifname(wf, optarg);
99 break;
100 case 'l':
101 wf->print_fields(wf, stdout);
102 return 0;
103 case 'o':
104 wf->setfmt(wf, getfmt(optarg));
105 break;
106 case 'z':
107 wf->zerostats(wf);
108 break;
109 default:
110 errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [-z] [interval]\n", argv[0]);
111 /*NOTREACHED*/
112 }
113 }
114 argc -= optind;
115 argv += optind;
116
117 if (argc > 0) {
118 u_long interval = strtoul(argv[0], NULL, 0);
119 int line, omask;
120
121 if (interval < 1)
122 interval = 1;
123 signal(SIGALRM, catchalarm);
124 signalled = 0;
125 alarm(interval);
126 banner:
127 if (banner)
128 wf->print_header(wf, stdout);
129 line = 0;
130 loop:
131 if (line != 0) {
132 wf->collect_cur(wf);
133 wf->print_current(wf, stdout);
134 wf->update_tot(wf);
135 } else {
136 wf->collect_tot(wf);
137 wf->print_total(wf, stdout);
138 }
139 fflush(stdout);
140 omask = sigblock(sigmask(SIGALRM));
141 if (!signalled)
142 sigpause(0);
143 sigsetmask(omask);
144 signalled = 0;
145 alarm(interval);
146 line++;
147 if (line == 21) /* XXX tty line count */
148 goto banner;
149 else
150 goto loop;
151 /*NOTREACHED*/
152 } else {
153 wf->collect_tot(wf);
154 wf->print_verbose(wf, stdout);
155 }
156 return 0;
157 }
158