1193242Ssam/*-
2193242Ssam * Copyright (c) 2006 Sam Leffler, Errno Consulting
3193242Ssam * All rights reserved.
4193242Ssam *
5193242Ssam * Redistribution and use in source and binary forms, with or without
6193242Ssam * modification, are permitted provided that the following conditions
7193242Ssam * are met:
8193242Ssam * 1. Redistributions of source code must retain the above copyright
9193242Ssam *    notice, this list of conditions and the following disclaimer,
10193242Ssam *    without modification.
11193242Ssam * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12193242Ssam *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13193242Ssam *    redistribution must be conditioned upon including a substantially
14193242Ssam *    similar Disclaimer requirement for further binary redistribution.
15193242Ssam *
16193242Ssam * NO WARRANTY
17193242Ssam * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18193242Ssam * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19193242Ssam * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20193242Ssam * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21193242Ssam * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22193242Ssam * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23193242Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24193242Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25193242Ssam * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26193242Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27193242Ssam * THE POSSIBILITY OF SUCH DAMAGES.
28193242Ssam *
29193242Ssam * $FreeBSD$
30193242Ssam */
31193242Ssam
32193242Ssam/*
33193242Ssam * Simple Marvell-specific tool to inspect and monitor network traffic
34193242Ssam * statistics.
35193242Ssam *
36193242Ssam *	mwlstats [-i interface] [-l] [-o fmtstring] [interval]
37193242Ssam *
38193242Ssam * (default interface is mv0).  If interval is specified a rolling output
39193242Ssam * a la netstat -i is displayed every interval seconds.  The format of
40193242Ssam * the rolling display can be controlled a la ps.  The -l option will
41193242Ssam * print a list of all possible statistics for use with the -o option.
42193242Ssam */
43193242Ssam
44193242Ssam#include <stdlib.h>
45193242Ssam#include <stdio.h>
46193242Ssam#include <signal.h>
47193242Ssam#include <unistd.h>
48193242Ssam#include <err.h>
49193242Ssam
50193242Ssam#include "mwlstats.h"
51193242Ssam
52193242Ssam#define	S_DEFAULT \
53193242Ssam	"input,output,txtry,txretry,txmretry,txdoneput,rxfcs,rxcrypt,rxicv,rssi,rate"
54193242Ssam
55193242Ssamstatic int signalled;
56193242Ssam
57193242Ssamstatic void
58193242Ssamcatchalarm(int signo __unused)
59193242Ssam{
60193242Ssam	signalled = 1;
61193242Ssam}
62193242Ssam
63193242Ssamint
64193242Ssammain(int argc, char *argv[])
65193242Ssam{
66193242Ssam	struct mwlstatfoo *wf;
67193242Ssam	int c;
68193242Ssam
69193242Ssam	wf = mwlstats_new("mwl0", S_DEFAULT);
70193242Ssam	while ((c = getopt(argc, argv, "i:lo:")) != -1) {
71193242Ssam		switch (c) {
72193242Ssam		case 'i':
73193242Ssam			wf->setifname(wf, optarg);
74193242Ssam			break;
75193242Ssam		case 'l':
76193242Ssam			wf->print_fields(wf, stdout);
77193242Ssam			return 0;
78193242Ssam		case 'o':
79193242Ssam			wf->setfmt(wf, optarg);
80193242Ssam			break;
81193242Ssam		default:
82193242Ssam			errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [interval]\n", argv[0]);
83193242Ssam			/*NOTREACHED*/
84193242Ssam		}
85193242Ssam	}
86193242Ssam	argc -= optind;
87193242Ssam	argv += optind;
88193242Ssam
89193242Ssam	if (argc > 0) {
90193242Ssam		u_long interval = strtoul(argv[0], NULL, 0);
91193242Ssam		int line, omask;
92193242Ssam
93193242Ssam		if (interval < 1)
94193242Ssam			interval = 1;
95193242Ssam		signal(SIGALRM, catchalarm);
96193242Ssam		signalled = 0;
97193242Ssam		alarm(interval);
98193242Ssam	banner:
99193242Ssam		wf->print_header(wf, stdout);
100193242Ssam		line = 0;
101193242Ssam	loop:
102193242Ssam		if (line != 0) {
103193242Ssam			wf->collect_cur(wf);
104193242Ssam			wf->print_current(wf, stdout);
105193242Ssam			wf->update_tot(wf);
106193242Ssam		} else {
107193242Ssam			wf->collect_tot(wf);
108193242Ssam			wf->print_total(wf, stdout);
109193242Ssam		}
110193242Ssam		fflush(stdout);
111193242Ssam		omask = sigblock(sigmask(SIGALRM));
112193242Ssam		if (!signalled)
113193242Ssam			sigpause(0);
114193242Ssam		sigsetmask(omask);
115193242Ssam		signalled = 0;
116193242Ssam		alarm(interval);
117193242Ssam		line++;
118193242Ssam		if (line == 21)		/* XXX tty line count */
119193242Ssam			goto banner;
120193242Ssam		else
121193242Ssam			goto loop;
122193242Ssam		/*NOTREACHED*/
123193242Ssam	} else {
124193242Ssam		wf->collect_tot(wf);
125193242Ssam		wf->print_verbose(wf, stdout);
126193242Ssam	}
127193242Ssam	return 0;
128193242Ssam}
129