xref: /minix3/usr.bin/netstat/main.c (revision 66dfcc8533c70ea68511edc95c03189c8eb0a7a2)
1*66dfcc85SDavid van Moolenbroek /*	$NetBSD: main.c,v 1.95 2014/11/12 03:34:59 christos Exp $	*/
2*66dfcc85SDavid van Moolenbroek 
3*66dfcc85SDavid van Moolenbroek /*
4*66dfcc85SDavid van Moolenbroek  * Copyright (c) 1983, 1988, 1993
5*66dfcc85SDavid van Moolenbroek  *	Regents of the University of California.  All rights reserved.
6*66dfcc85SDavid van Moolenbroek  *
7*66dfcc85SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
8*66dfcc85SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
9*66dfcc85SDavid van Moolenbroek  * are met:
10*66dfcc85SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
11*66dfcc85SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
12*66dfcc85SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
13*66dfcc85SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
14*66dfcc85SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
15*66dfcc85SDavid van Moolenbroek  * 3. Neither the name of the University nor the names of its contributors
16*66dfcc85SDavid van Moolenbroek  *    may be used to endorse or promote products derived from this software
17*66dfcc85SDavid van Moolenbroek  *    without specific prior written permission.
18*66dfcc85SDavid van Moolenbroek  *
19*66dfcc85SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*66dfcc85SDavid van Moolenbroek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*66dfcc85SDavid van Moolenbroek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*66dfcc85SDavid van Moolenbroek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*66dfcc85SDavid van Moolenbroek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*66dfcc85SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*66dfcc85SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*66dfcc85SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*66dfcc85SDavid van Moolenbroek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*66dfcc85SDavid van Moolenbroek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*66dfcc85SDavid van Moolenbroek  * SUCH DAMAGE.
30*66dfcc85SDavid van Moolenbroek  */
31*66dfcc85SDavid van Moolenbroek 
32*66dfcc85SDavid van Moolenbroek #include <sys/cdefs.h>
33*66dfcc85SDavid van Moolenbroek #ifndef lint
34*66dfcc85SDavid van Moolenbroek __COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1993\
35*66dfcc85SDavid van Moolenbroek  Regents of the University of California.  All rights reserved.");
36*66dfcc85SDavid van Moolenbroek #endif /* not lint */
37*66dfcc85SDavid van Moolenbroek 
38*66dfcc85SDavid van Moolenbroek #ifndef lint
39*66dfcc85SDavid van Moolenbroek #if 0
40*66dfcc85SDavid van Moolenbroek static char sccsid[] = "from: @(#)main.c	8.4 (Berkeley) 3/1/94";
41*66dfcc85SDavid van Moolenbroek #else
42*66dfcc85SDavid van Moolenbroek __RCSID("$NetBSD: main.c,v 1.95 2014/11/12 03:34:59 christos Exp $");
43*66dfcc85SDavid van Moolenbroek #endif
44*66dfcc85SDavid van Moolenbroek #endif /* not lint */
45*66dfcc85SDavid van Moolenbroek 
46*66dfcc85SDavid van Moolenbroek #include <sys/param.h>
47*66dfcc85SDavid van Moolenbroek #include <sys/file.h>
48*66dfcc85SDavid van Moolenbroek #include <sys/protosw.h>
49*66dfcc85SDavid van Moolenbroek #include <sys/socket.h>
50*66dfcc85SDavid van Moolenbroek 
51*66dfcc85SDavid van Moolenbroek #include <net/if.h>
52*66dfcc85SDavid van Moolenbroek #include <netinet/in.h>
53*66dfcc85SDavid van Moolenbroek 
54*66dfcc85SDavid van Moolenbroek #include <ctype.h>
55*66dfcc85SDavid van Moolenbroek #include <err.h>
56*66dfcc85SDavid van Moolenbroek #include <errno.h>
57*66dfcc85SDavid van Moolenbroek #include <kvm.h>
58*66dfcc85SDavid van Moolenbroek #include <limits.h>
59*66dfcc85SDavid van Moolenbroek #include <netdb.h>
60*66dfcc85SDavid van Moolenbroek #include <nlist.h>
61*66dfcc85SDavid van Moolenbroek #include <paths.h>
62*66dfcc85SDavid van Moolenbroek #include <stdio.h>
63*66dfcc85SDavid van Moolenbroek #include <stdlib.h>
64*66dfcc85SDavid van Moolenbroek #include <string.h>
65*66dfcc85SDavid van Moolenbroek #include <unistd.h>
66*66dfcc85SDavid van Moolenbroek #include "netstat.h"
67*66dfcc85SDavid van Moolenbroek #include "rtutil.h"
68*66dfcc85SDavid van Moolenbroek #include "prog_ops.h"
69*66dfcc85SDavid van Moolenbroek 
70*66dfcc85SDavid van Moolenbroek struct nlist nl[] = {
71*66dfcc85SDavid van Moolenbroek #define	N_MBSTAT	0
72*66dfcc85SDavid van Moolenbroek 	{ "_mbstat", 0, 0, 0, 0 },
73*66dfcc85SDavid van Moolenbroek #define	N_IPSTAT	1
74*66dfcc85SDavid van Moolenbroek 	{ "_ipstat", 0, 0, 0, 0 },	/* not available via kvm */
75*66dfcc85SDavid van Moolenbroek #define	N_TCBTABLE	2
76*66dfcc85SDavid van Moolenbroek 	{ "_tcbtable", 0, 0, 0, 0 },
77*66dfcc85SDavid van Moolenbroek #define	N_TCPSTAT	3
78*66dfcc85SDavid van Moolenbroek 	{ "_tcpstat", 0, 0, 0, 0 },	/* not available via kvm */
79*66dfcc85SDavid van Moolenbroek #define	N_UDBTABLE	4
80*66dfcc85SDavid van Moolenbroek 	{ "_udbtable", 0, 0, 0, 0 },
81*66dfcc85SDavid van Moolenbroek #define	N_UDPSTAT	5
82*66dfcc85SDavid van Moolenbroek 	{ "_udpstat", 0, 0, 0, 0 },	/* not available via kvm */
83*66dfcc85SDavid van Moolenbroek #define	N_IFNET_LIST		6
84*66dfcc85SDavid van Moolenbroek 	{ "_ifnet_list", 0, 0, 0, 0 },
85*66dfcc85SDavid van Moolenbroek #define	N_ICMPSTAT	7
86*66dfcc85SDavid van Moolenbroek 	{ "_icmpstat", 0, 0, 0, 0 },	/* not available via kvm */
87*66dfcc85SDavid van Moolenbroek #define	N_RTSTAT	8
88*66dfcc85SDavid van Moolenbroek 	{ "_rtstat", 0, 0, 0, 0 },
89*66dfcc85SDavid van Moolenbroek #define	N_UNIXSW	9
90*66dfcc85SDavid van Moolenbroek 	{ "_unixsw", 0, 0, 0, 0 },
91*66dfcc85SDavid van Moolenbroek #define N_RTREE		10
92*66dfcc85SDavid van Moolenbroek 	{ "_rt_tables", 0, 0, 0, 0 },
93*66dfcc85SDavid van Moolenbroek #define	N_NFILE		11
94*66dfcc85SDavid van Moolenbroek 	{ "_nfile", 0, 0, 0, 0 },
95*66dfcc85SDavid van Moolenbroek #define N_IGMPSTAT	12
96*66dfcc85SDavid van Moolenbroek 	{ "_igmpstat", 0, 0, 0, 0 },	/* not available via kvm */
97*66dfcc85SDavid van Moolenbroek #define N_MRTPROTO	13
98*66dfcc85SDavid van Moolenbroek 	{ "_ip_mrtproto", 0, 0, 0, 0 },
99*66dfcc85SDavid van Moolenbroek #define N_MRTSTAT	14
100*66dfcc85SDavid van Moolenbroek 	{ "_mrtstat", 0, 0, 0, 0 },
101*66dfcc85SDavid van Moolenbroek #define N_MFCHASHTBL	15
102*66dfcc85SDavid van Moolenbroek 	{ "_mfchashtbl", 0, 0, 0, 0 },
103*66dfcc85SDavid van Moolenbroek #define	N_MFCHASH	16
104*66dfcc85SDavid van Moolenbroek 	{ "_mfchash", 0, 0, 0, 0 },
105*66dfcc85SDavid van Moolenbroek #define N_VIFTABLE	17
106*66dfcc85SDavid van Moolenbroek 	{ "_viftable", 0, 0, 0, 0 },
107*66dfcc85SDavid van Moolenbroek #define N_MSIZE		18
108*66dfcc85SDavid van Moolenbroek 	{ "_msize", 0, 0, 0, 0 },
109*66dfcc85SDavid van Moolenbroek #define N_MCLBYTES	19
110*66dfcc85SDavid van Moolenbroek 	{ "_mclbytes", 0, 0, 0, 0 },
111*66dfcc85SDavid van Moolenbroek #define N_DDPSTAT	20
112*66dfcc85SDavid van Moolenbroek 	{ "_ddpstat", 0, 0, 0, 0 },	/* not available via kvm */
113*66dfcc85SDavid van Moolenbroek #define N_DDPCB		21
114*66dfcc85SDavid van Moolenbroek 	{ "_ddpcb", 0, 0, 0, 0 },
115*66dfcc85SDavid van Moolenbroek #define N_MBPOOL	22
116*66dfcc85SDavid van Moolenbroek 	{ "_mbpool", 0, 0, 0, 0 },
117*66dfcc85SDavid van Moolenbroek #define N_MCLPOOL	23
118*66dfcc85SDavid van Moolenbroek 	{ "_mclpool", 0, 0, 0, 0 },
119*66dfcc85SDavid van Moolenbroek #define N_IP6STAT	24
120*66dfcc85SDavid van Moolenbroek 	{ "_ip6stat", 0, 0, 0, 0 },	/* not available via kvm */
121*66dfcc85SDavid van Moolenbroek #define N_TCP6STAT	25
122*66dfcc85SDavid van Moolenbroek 	{ "_tcp6stat", 0, 0, 0, 0 },	/* not available via kvm */
123*66dfcc85SDavid van Moolenbroek #define N_UDP6STAT	26
124*66dfcc85SDavid van Moolenbroek 	{ "_udp6stat", 0, 0, 0, 0 },	/* not available via kvm */
125*66dfcc85SDavid van Moolenbroek #define N_ICMP6STAT	27
126*66dfcc85SDavid van Moolenbroek 	{ "_icmp6stat", 0, 0, 0, 0 },	/* not available via kvm */
127*66dfcc85SDavid van Moolenbroek #define N_IPSECSTAT	28
128*66dfcc85SDavid van Moolenbroek 	{ "_ipsecstat", 0, 0, 0, 0 },	/* not available via kvm */
129*66dfcc85SDavid van Moolenbroek #define N_IPSEC6STAT	29
130*66dfcc85SDavid van Moolenbroek 	{ "_ipsec6stat", 0, 0, 0, 0 },	/* not available via kvm */
131*66dfcc85SDavid van Moolenbroek #define N_PIM6STAT	30
132*66dfcc85SDavid van Moolenbroek 	{ "_pim6stat", 0, 0, 0, 0 },	/* not available via kvm */
133*66dfcc85SDavid van Moolenbroek #define N_MRT6PROTO	31
134*66dfcc85SDavid van Moolenbroek 	{ "_ip6_mrtproto", 0, 0, 0, 0 },
135*66dfcc85SDavid van Moolenbroek #define N_MRT6STAT	32
136*66dfcc85SDavid van Moolenbroek 	{ "_mrt6stat", 0, 0, 0, 0 },
137*66dfcc85SDavid van Moolenbroek #define N_MF6CTABLE	33
138*66dfcc85SDavid van Moolenbroek 	{ "_mf6ctable", 0, 0, 0, 0 },
139*66dfcc85SDavid van Moolenbroek #define N_MIF6TABLE	34
140*66dfcc85SDavid van Moolenbroek 	{ "_mif6table", 0, 0, 0, 0 },
141*66dfcc85SDavid van Moolenbroek #define N_PFKEYSTAT	35
142*66dfcc85SDavid van Moolenbroek 	{ "_pfkeystat", 0, 0, 0, 0 },	/* not available via kvm */
143*66dfcc85SDavid van Moolenbroek #define N_ARPSTAT	36
144*66dfcc85SDavid van Moolenbroek 	{ "_arpstat", 0, 0, 0, 0 },	/* not available via kvm */
145*66dfcc85SDavid van Moolenbroek #define N_RIP6STAT	37
146*66dfcc85SDavid van Moolenbroek 	{ "_rip6stat", 0, 0, 0, 0 },	/* not available via kvm */
147*66dfcc85SDavid van Moolenbroek #define	N_ARPINTRQ	38
148*66dfcc85SDavid van Moolenbroek 	{ "_arpintrq", 0, 0, 0, 0 },
149*66dfcc85SDavid van Moolenbroek #define	N_IPINTRQ	39
150*66dfcc85SDavid van Moolenbroek 	{ "_ipintrq", 0, 0, 0, 0 },
151*66dfcc85SDavid van Moolenbroek #define	N_IP6INTRQ	40
152*66dfcc85SDavid van Moolenbroek 	{ "_ip6intrq", 0, 0, 0, 0 },
153*66dfcc85SDavid van Moolenbroek #define	N_ATINTRQ1	41
154*66dfcc85SDavid van Moolenbroek 	{ "_atintrq1", 0, 0, 0, 0 },
155*66dfcc85SDavid van Moolenbroek #define	N_ATINTRQ2	42
156*66dfcc85SDavid van Moolenbroek 	{ "_atintrq2", 0, 0, 0, 0 },
157*66dfcc85SDavid van Moolenbroek #define	N_NSINTRQ	43
158*66dfcc85SDavid van Moolenbroek 	{ "_nsintrq", 0, 0, 0, 0 },
159*66dfcc85SDavid van Moolenbroek #define	N_LLCINTRQ	44
160*66dfcc85SDavid van Moolenbroek 	{ "_llcintrq", 0, 0, 0, 0 },
161*66dfcc85SDavid van Moolenbroek #define	N_HDINTRQ	45
162*66dfcc85SDavid van Moolenbroek 	{ "_hdintrq", 0, 0, 0, 0 },
163*66dfcc85SDavid van Moolenbroek #define	N_NATMINTRQ	46
164*66dfcc85SDavid van Moolenbroek 	{ "_natmintrq", 0, 0, 0, 0 },
165*66dfcc85SDavid van Moolenbroek #define	N_PPPOEDISCINQ	47
166*66dfcc85SDavid van Moolenbroek 	{ "_ppoediscinq", 0, 0, 0, 0 },
167*66dfcc85SDavid van Moolenbroek #define	N_PPPOEINQ	48
168*66dfcc85SDavid van Moolenbroek 	{ "_ppoeinq", 0, 0, 0, 0 },
169*66dfcc85SDavid van Moolenbroek #define	N_PKINTRQ	49
170*66dfcc85SDavid van Moolenbroek 	{ "_pkintrq", 0, 0, 0, 0 },
171*66dfcc85SDavid van Moolenbroek #define	N_HARDCLOCK_TICKS 50
172*66dfcc85SDavid van Moolenbroek 	{ "_hardclock_ticks", 0, 0, 0, 0 },
173*66dfcc85SDavid van Moolenbroek #define N_PIMSTAT	51
174*66dfcc85SDavid van Moolenbroek 	{ "_pimstat", 0, 0, 0, 0 },
175*66dfcc85SDavid van Moolenbroek #define N_CARPSTAT	52
176*66dfcc85SDavid van Moolenbroek 	{ "_carpstats", 0, 0, 0, 0 },	/* not available via kvm */
177*66dfcc85SDavid van Moolenbroek #define N_PFSYNCSTAT	53
178*66dfcc85SDavid van Moolenbroek 	{ "_pfsyncstats", 0, 0, 0, 0},  /* not available via kvm */
179*66dfcc85SDavid van Moolenbroek 	{ "", 0, 0, 0, 0 },
180*66dfcc85SDavid van Moolenbroek };
181*66dfcc85SDavid van Moolenbroek 
182*66dfcc85SDavid van Moolenbroek struct protox {
183*66dfcc85SDavid van Moolenbroek 	u_char	pr_index;		/* index into nlist of cb head */
184*66dfcc85SDavid van Moolenbroek 	u_char	pr_sindex;		/* index into nlist of stat block */
185*66dfcc85SDavid van Moolenbroek 	u_char	pr_wanted;		/* 1 if wanted, 0 otherwise */
186*66dfcc85SDavid van Moolenbroek 	void	(*pr_cblocks)		/* control blocks printing routine */
187*66dfcc85SDavid van Moolenbroek 			__P((u_long, const char *));
188*66dfcc85SDavid van Moolenbroek 	void	(*pr_stats)		/* statistics printing routine */
189*66dfcc85SDavid van Moolenbroek 			__P((u_long, const char *));
190*66dfcc85SDavid van Moolenbroek 	void	(*pr_istats)
191*66dfcc85SDavid van Moolenbroek 			__P((const char *));	/* per/if statistics printing routine */
192*66dfcc85SDavid van Moolenbroek 	void	(*pr_dump)		/* PCB state dump routine */
193*66dfcc85SDavid van Moolenbroek 			__P((u_long, const char *, u_long));
194*66dfcc85SDavid van Moolenbroek 	const char *pr_name;		/* well-known name */
195*66dfcc85SDavid van Moolenbroek } protox[] = {
196*66dfcc85SDavid van Moolenbroek 	{ N_TCBTABLE,	N_TCPSTAT,	1,	protopr,
197*66dfcc85SDavid van Moolenbroek 	  tcp_stats,	NULL,		tcp_dump,	"tcp" },
198*66dfcc85SDavid van Moolenbroek 	{ N_UDBTABLE,	N_UDPSTAT,	1,	protopr,
199*66dfcc85SDavid van Moolenbroek 	  udp_stats,	NULL,		0,	"udp" },
200*66dfcc85SDavid van Moolenbroek 	{ -1,		N_IPSTAT,	1,	0,
201*66dfcc85SDavid van Moolenbroek 	  ip_stats,	NULL,		0,	"ip" },
202*66dfcc85SDavid van Moolenbroek 	{ -1,		N_ICMPSTAT,	1,	0,
203*66dfcc85SDavid van Moolenbroek 	  icmp_stats,	NULL,		0,	"icmp" },
204*66dfcc85SDavid van Moolenbroek 	{ -1,		N_IGMPSTAT,	1,	0,
205*66dfcc85SDavid van Moolenbroek 	  igmp_stats,	NULL,		0,	"igmp" },
206*66dfcc85SDavid van Moolenbroek 	{ -1,		N_CARPSTAT,	1,	0,
207*66dfcc85SDavid van Moolenbroek 	  carp_stats,	NULL,		0,	"carp" },
208*66dfcc85SDavid van Moolenbroek #ifdef IPSEC
209*66dfcc85SDavid van Moolenbroek 	{ -1,		N_IPSECSTAT,	1,	0,
210*66dfcc85SDavid van Moolenbroek 	  fast_ipsec_stats, NULL,	0,	"ipsec" },
211*66dfcc85SDavid van Moolenbroek #endif
212*66dfcc85SDavid van Moolenbroek 	{ -1,		N_PIMSTAT,	1,	0,
213*66dfcc85SDavid van Moolenbroek 	  pim_stats,	NULL,		0,	"pim" },
214*66dfcc85SDavid van Moolenbroek 	{ -1,		N_PFSYNCSTAT,  1,  0,
215*66dfcc85SDavid van Moolenbroek 	  pfsync_stats,  NULL,		0,  "pfsync" },
216*66dfcc85SDavid van Moolenbroek 	{ -1,		-1,		0,	0,
217*66dfcc85SDavid van Moolenbroek 	  0,		NULL,		0,	0 }
218*66dfcc85SDavid van Moolenbroek };
219*66dfcc85SDavid van Moolenbroek 
220*66dfcc85SDavid van Moolenbroek #ifdef INET6
221*66dfcc85SDavid van Moolenbroek struct protox ip6protox[] = {
222*66dfcc85SDavid van Moolenbroek 	{ -1,		N_IP6STAT,	1,	0,
223*66dfcc85SDavid van Moolenbroek 	  ip6_stats,	ip6_ifstats,	0,	"ip6" },
224*66dfcc85SDavid van Moolenbroek 	{ -1,		N_ICMP6STAT,	1,	0,
225*66dfcc85SDavid van Moolenbroek 	  icmp6_stats,	icmp6_ifstats,	0,	"icmp6" },
226*66dfcc85SDavid van Moolenbroek #ifdef TCP6
227*66dfcc85SDavid van Moolenbroek 	{ N_TCBTABLE,	N_TCP6STAT,	1,	ip6protopr,
228*66dfcc85SDavid van Moolenbroek 	  tcp6_stats,	NULL,		tcp6_dump,	"tcp6" },
229*66dfcc85SDavid van Moolenbroek #else
230*66dfcc85SDavid van Moolenbroek 	{ N_TCBTABLE,	N_TCP6STAT,	1,	ip6protopr,
231*66dfcc85SDavid van Moolenbroek 	  tcp_stats,	NULL,		tcp6_dump,	"tcp6" },
232*66dfcc85SDavid van Moolenbroek #endif
233*66dfcc85SDavid van Moolenbroek 	{ N_UDBTABLE,	N_UDP6STAT,	1,	ip6protopr,
234*66dfcc85SDavid van Moolenbroek 	  udp6_stats,	NULL,		0,	"udp6" },
235*66dfcc85SDavid van Moolenbroek #ifdef IPSEC
236*66dfcc85SDavid van Moolenbroek 	{ -1,		N_IPSEC6STAT,	1,	0,
237*66dfcc85SDavid van Moolenbroek 	  fast_ipsec_stats, NULL,	0,	"ipsec6" },
238*66dfcc85SDavid van Moolenbroek #endif
239*66dfcc85SDavid van Moolenbroek 	{ -1,		N_PIM6STAT,	1,	0,
240*66dfcc85SDavid van Moolenbroek 	  pim6_stats,	NULL,		0,	"pim6" },
241*66dfcc85SDavid van Moolenbroek 	{ -1,		N_RIP6STAT,	1,	0,
242*66dfcc85SDavid van Moolenbroek 	  rip6_stats,	NULL,		0,	"rip6" },
243*66dfcc85SDavid van Moolenbroek 	{ -1,		-1,		0,	0,
244*66dfcc85SDavid van Moolenbroek 	  0,		NULL,		0,	0 }
245*66dfcc85SDavid van Moolenbroek };
246*66dfcc85SDavid van Moolenbroek #endif
247*66dfcc85SDavid van Moolenbroek 
248*66dfcc85SDavid van Moolenbroek struct protox arpprotox[] = {
249*66dfcc85SDavid van Moolenbroek 	{ -1,		N_ARPSTAT,	1,	0,
250*66dfcc85SDavid van Moolenbroek 	  arp_stats,	NULL,		0,	"arp" },
251*66dfcc85SDavid van Moolenbroek 	{ -1,		-1,		0,	0,
252*66dfcc85SDavid van Moolenbroek 	  0,		NULL,		0,	0 }
253*66dfcc85SDavid van Moolenbroek };
254*66dfcc85SDavid van Moolenbroek 
255*66dfcc85SDavid van Moolenbroek #ifdef IPSEC
256*66dfcc85SDavid van Moolenbroek struct protox pfkeyprotox[] = {
257*66dfcc85SDavid van Moolenbroek 	{ -1,		N_PFKEYSTAT,	1,	0,
258*66dfcc85SDavid van Moolenbroek 	  pfkey_stats,	NULL,		0,	"pfkey" },
259*66dfcc85SDavid van Moolenbroek 	{ -1,		-1,		0,	0,
260*66dfcc85SDavid van Moolenbroek 	  0,		NULL,		0,	0 }
261*66dfcc85SDavid van Moolenbroek };
262*66dfcc85SDavid van Moolenbroek #endif
263*66dfcc85SDavid van Moolenbroek 
264*66dfcc85SDavid van Moolenbroek #ifndef SMALL
265*66dfcc85SDavid van Moolenbroek struct protox atalkprotox[] = {
266*66dfcc85SDavid van Moolenbroek 	{ N_DDPCB,	N_DDPSTAT,	1,	atalkprotopr,
267*66dfcc85SDavid van Moolenbroek 	  ddp_stats,	NULL,		0,	"ddp" },
268*66dfcc85SDavid van Moolenbroek 	{ -1,		-1,		0,	0,
269*66dfcc85SDavid van Moolenbroek 	  0,		NULL,		0,	NULL }
270*66dfcc85SDavid van Moolenbroek };
271*66dfcc85SDavid van Moolenbroek #endif
272*66dfcc85SDavid van Moolenbroek 
273*66dfcc85SDavid van Moolenbroek struct protox *protoprotox[] = { protox,
274*66dfcc85SDavid van Moolenbroek #ifdef INET6
275*66dfcc85SDavid van Moolenbroek 				 ip6protox,
276*66dfcc85SDavid van Moolenbroek #endif
277*66dfcc85SDavid van Moolenbroek 				 arpprotox,
278*66dfcc85SDavid van Moolenbroek #ifdef IPSEC
279*66dfcc85SDavid van Moolenbroek 				 pfkeyprotox,
280*66dfcc85SDavid van Moolenbroek #endif
281*66dfcc85SDavid van Moolenbroek #ifndef SMALL
282*66dfcc85SDavid van Moolenbroek 				 atalkprotox,
283*66dfcc85SDavid van Moolenbroek #endif
284*66dfcc85SDavid van Moolenbroek 				 NULL };
285*66dfcc85SDavid van Moolenbroek 
286*66dfcc85SDavid van Moolenbroek const struct softintrq {
287*66dfcc85SDavid van Moolenbroek 	const char *siq_name;
288*66dfcc85SDavid van Moolenbroek 	int siq_index;
289*66dfcc85SDavid van Moolenbroek } softintrq[] = {
290*66dfcc85SDavid van Moolenbroek 	{ "arpintrq", N_ARPINTRQ },
291*66dfcc85SDavid van Moolenbroek 	{ "ipintrq", N_IPINTRQ },
292*66dfcc85SDavid van Moolenbroek 	{ "ip6intrq", N_IP6INTRQ },
293*66dfcc85SDavid van Moolenbroek 	{ "atintrq1", N_ATINTRQ1 },
294*66dfcc85SDavid van Moolenbroek 	{ "atintrq2", N_ATINTRQ2 },
295*66dfcc85SDavid van Moolenbroek 	{ "llcintrq", N_LLCINTRQ },
296*66dfcc85SDavid van Moolenbroek 	{ "hdintrq", N_HDINTRQ },
297*66dfcc85SDavid van Moolenbroek 	{ "natmintrq", N_NATMINTRQ },
298*66dfcc85SDavid van Moolenbroek 	{ "ppoediscinq", N_PPPOEDISCINQ },
299*66dfcc85SDavid van Moolenbroek 	{ "ppoeinq", N_PPPOEINQ },
300*66dfcc85SDavid van Moolenbroek 	{ "pkintrq", N_PKINTRQ },
301*66dfcc85SDavid van Moolenbroek 	{ NULL, -1 },
302*66dfcc85SDavid van Moolenbroek };
303*66dfcc85SDavid van Moolenbroek 
304*66dfcc85SDavid van Moolenbroek int main __P((int, char *[]));
305*66dfcc85SDavid van Moolenbroek static void printproto __P((struct protox *, const char *));
306*66dfcc85SDavid van Moolenbroek static void print_softintrq __P((void));
307*66dfcc85SDavid van Moolenbroek __dead static void usage(void);
308*66dfcc85SDavid van Moolenbroek static struct protox *name2protox __P((const char *));
309*66dfcc85SDavid van Moolenbroek static struct protox *knownname __P((const char *));
310*66dfcc85SDavid van Moolenbroek static void prepare(const char *, const char *, struct protox *tp);
311*66dfcc85SDavid van Moolenbroek static kvm_t *prepare_kvmd(const char *, const char *, char *);
312*66dfcc85SDavid van Moolenbroek 
313*66dfcc85SDavid van Moolenbroek static kvm_t *kvmd = NULL;
314*66dfcc85SDavid van Moolenbroek gid_t egid;
315*66dfcc85SDavid van Moolenbroek int interval;	/* repeat interval for i/f stats */
316*66dfcc85SDavid van Moolenbroek static const char *nlistf = NULL, *memf = NULL;
317*66dfcc85SDavid van Moolenbroek 
318*66dfcc85SDavid van Moolenbroek kvm_t *
get_kvmd(void)319*66dfcc85SDavid van Moolenbroek get_kvmd(void)
320*66dfcc85SDavid van Moolenbroek {
321*66dfcc85SDavid van Moolenbroek 	char buf[_POSIX2_LINE_MAX];
322*66dfcc85SDavid van Moolenbroek 
323*66dfcc85SDavid van Moolenbroek 	if (kvmd != NULL)
324*66dfcc85SDavid van Moolenbroek 		return kvmd;
325*66dfcc85SDavid van Moolenbroek 	if ((kvmd = prepare_kvmd(nlistf, memf, buf)) == NULL)
326*66dfcc85SDavid van Moolenbroek 		errx(1, "kvm error: %s", buf);
327*66dfcc85SDavid van Moolenbroek 	return kvmd;
328*66dfcc85SDavid van Moolenbroek }
329*66dfcc85SDavid van Moolenbroek 
330*66dfcc85SDavid van Moolenbroek static kvm_t *
prepare_kvmd(const char * nf,const char * mf,char * errbuf)331*66dfcc85SDavid van Moolenbroek prepare_kvmd(const char *nf, const char *mf, char *errbuf)
332*66dfcc85SDavid van Moolenbroek {
333*66dfcc85SDavid van Moolenbroek 	kvm_t *k;
334*66dfcc85SDavid van Moolenbroek 
335*66dfcc85SDavid van Moolenbroek 	(void)setegid(egid);
336*66dfcc85SDavid van Moolenbroek 	k = kvm_openfiles(nf, mf, NULL, O_RDONLY, errbuf);
337*66dfcc85SDavid van Moolenbroek 	(void)setgid(getgid());
338*66dfcc85SDavid van Moolenbroek 	return k;
339*66dfcc85SDavid van Moolenbroek }
340*66dfcc85SDavid van Moolenbroek 
341*66dfcc85SDavid van Moolenbroek void
prepare(const char * nf,const char * mf,struct protox * tp)342*66dfcc85SDavid van Moolenbroek prepare(const char *nf, const char *mf, struct protox *tp)
343*66dfcc85SDavid van Moolenbroek {
344*66dfcc85SDavid van Moolenbroek 	char buf[_POSIX2_LINE_MAX];
345*66dfcc85SDavid van Moolenbroek 	/*
346*66dfcc85SDavid van Moolenbroek 	 * Try to figure out if we can use sysctl or not.
347*66dfcc85SDavid van Moolenbroek 	 */
348*66dfcc85SDavid van Moolenbroek 	if (nf != NULL || mf != NULL) {
349*66dfcc85SDavid van Moolenbroek 		/* Of course, we can't use sysctl with dumps. */
350*66dfcc85SDavid van Moolenbroek 		if (force_sysctl)
351*66dfcc85SDavid van Moolenbroek 			errx(EXIT_FAILURE, "can't use sysctl with dumps");
352*66dfcc85SDavid van Moolenbroek 
353*66dfcc85SDavid van Moolenbroek 		/*
354*66dfcc85SDavid van Moolenbroek 		 * If we have -M or -N, we're not dealing with live memory
355*66dfcc85SDavid van Moolenbroek 		 * or want to use kvm interface explicitly.  It is sometimes
356*66dfcc85SDavid van Moolenbroek 		 * useful to dig inside of kernel without extending
357*66dfcc85SDavid van Moolenbroek 		 * sysctl interface (i.e., without rebuilding kernel).
358*66dfcc85SDavid van Moolenbroek 		 */
359*66dfcc85SDavid van Moolenbroek 		use_sysctl = 0;
360*66dfcc85SDavid van Moolenbroek 	} else if (qflag ||
361*66dfcc85SDavid van Moolenbroek 		   iflag ||
362*66dfcc85SDavid van Moolenbroek #ifndef SMALL
363*66dfcc85SDavid van Moolenbroek 		   gflag ||
364*66dfcc85SDavid van Moolenbroek #endif
365*66dfcc85SDavid van Moolenbroek 		   (pflag && tp->pr_sindex == N_PIMSTAT) ||
366*66dfcc85SDavid van Moolenbroek 		   Pflag) {
367*66dfcc85SDavid van Moolenbroek 		/* These flags are not yet supported via sysctl(3). */
368*66dfcc85SDavid van Moolenbroek 		use_sysctl = 0;
369*66dfcc85SDavid van Moolenbroek 	} else {
370*66dfcc85SDavid van Moolenbroek 		/* We can use sysctl(3). */
371*66dfcc85SDavid van Moolenbroek 		use_sysctl = 1;
372*66dfcc85SDavid van Moolenbroek 	}
373*66dfcc85SDavid van Moolenbroek 
374*66dfcc85SDavid van Moolenbroek 	if (force_sysctl && !use_sysctl) {
375*66dfcc85SDavid van Moolenbroek 		/* Let the user know what's about to happen. */
376*66dfcc85SDavid van Moolenbroek 		warnx("forcing sysctl usage even though it might not be "\
377*66dfcc85SDavid van Moolenbroek 		    "supported");
378*66dfcc85SDavid van Moolenbroek 		use_sysctl = 1;
379*66dfcc85SDavid van Moolenbroek 	}
380*66dfcc85SDavid van Moolenbroek 
381*66dfcc85SDavid van Moolenbroek #ifdef __minix
382*66dfcc85SDavid van Moolenbroek 	use_sysctl = 1;
383*66dfcc85SDavid van Moolenbroek #endif /* __minix */
384*66dfcc85SDavid van Moolenbroek 
385*66dfcc85SDavid van Moolenbroek 	kvmd = prepare_kvmd(nf, mf, buf);
386*66dfcc85SDavid van Moolenbroek 
387*66dfcc85SDavid van Moolenbroek 	if (!use_sysctl) {
388*66dfcc85SDavid van Moolenbroek 
389*66dfcc85SDavid van Moolenbroek 		if (kvmd == NULL)
390*66dfcc85SDavid van Moolenbroek 			errx(1, "kvm error: %s", buf);
391*66dfcc85SDavid van Moolenbroek 		if (kvm_nlist(kvmd, nl) < 0 || nl[0].n_type == 0) {
392*66dfcc85SDavid van Moolenbroek 			if (nf)
393*66dfcc85SDavid van Moolenbroek 				errx(1, "%s: no namelist", nf);
394*66dfcc85SDavid van Moolenbroek 			else
395*66dfcc85SDavid van Moolenbroek 				errx(1, "no namelist");
396*66dfcc85SDavid van Moolenbroek 		}
397*66dfcc85SDavid van Moolenbroek 	} else
398*66dfcc85SDavid van Moolenbroek 		(void)setgid(getgid());
399*66dfcc85SDavid van Moolenbroek }
400*66dfcc85SDavid van Moolenbroek 
401*66dfcc85SDavid van Moolenbroek int
main(int argc,char * argv[])402*66dfcc85SDavid van Moolenbroek main(int argc, char *argv[])
403*66dfcc85SDavid van Moolenbroek {
404*66dfcc85SDavid van Moolenbroek 	struct protoent *p;
405*66dfcc85SDavid van Moolenbroek 	struct protox *tp;	/* for printing cblocks & stats */
406*66dfcc85SDavid van Moolenbroek 	int ch;
407*66dfcc85SDavid van Moolenbroek 	char *cp;
408*66dfcc85SDavid van Moolenbroek 	char *afname, *afnames;
409*66dfcc85SDavid van Moolenbroek 	u_long pcbaddr;
410*66dfcc85SDavid van Moolenbroek 
411*66dfcc85SDavid van Moolenbroek 	if (prog_init) {
412*66dfcc85SDavid van Moolenbroek 		if (prog_init() == -1)
413*66dfcc85SDavid van Moolenbroek 			err(1, "init failed");
414*66dfcc85SDavid van Moolenbroek 		force_sysctl = 1; /* cheap trick */
415*66dfcc85SDavid van Moolenbroek 	}
416*66dfcc85SDavid van Moolenbroek 
417*66dfcc85SDavid van Moolenbroek 	egid = getegid();
418*66dfcc85SDavid van Moolenbroek 	(void)setegid(getgid());
419*66dfcc85SDavid van Moolenbroek 	tp = NULL;
420*66dfcc85SDavid van Moolenbroek 	af = AF_UNSPEC;
421*66dfcc85SDavid van Moolenbroek 	afnames = NULL;
422*66dfcc85SDavid van Moolenbroek 	pcbaddr = 0;
423*66dfcc85SDavid van Moolenbroek 
424*66dfcc85SDavid van Moolenbroek 	while ((ch = getopt(argc, argv,
425*66dfcc85SDavid van Moolenbroek 	    "AabBdf:ghI:LliM:mN:nP:p:qrsStTuVvw:X")) != -1)
426*66dfcc85SDavid van Moolenbroek 		switch (ch) {
427*66dfcc85SDavid van Moolenbroek 		case 'A':
428*66dfcc85SDavid van Moolenbroek 			Aflag = RT_AFLAG;
429*66dfcc85SDavid van Moolenbroek 			break;
430*66dfcc85SDavid van Moolenbroek 		case 'a':
431*66dfcc85SDavid van Moolenbroek 			aflag = 1;
432*66dfcc85SDavid van Moolenbroek 			break;
433*66dfcc85SDavid van Moolenbroek 		case 'b':
434*66dfcc85SDavid van Moolenbroek 			bflag = 1;
435*66dfcc85SDavid van Moolenbroek 			break;
436*66dfcc85SDavid van Moolenbroek 		case 'B':
437*66dfcc85SDavid van Moolenbroek 			Bflag = 1;
438*66dfcc85SDavid van Moolenbroek 			break;
439*66dfcc85SDavid van Moolenbroek 		case 'd':
440*66dfcc85SDavid van Moolenbroek 			dflag = 1;
441*66dfcc85SDavid van Moolenbroek 			break;
442*66dfcc85SDavid van Moolenbroek 		case 'f':
443*66dfcc85SDavid van Moolenbroek 			afnames = optarg;
444*66dfcc85SDavid van Moolenbroek 			break;
445*66dfcc85SDavid van Moolenbroek #ifndef SMALL
446*66dfcc85SDavid van Moolenbroek 		case 'g':
447*66dfcc85SDavid van Moolenbroek 			gflag = 1;
448*66dfcc85SDavid van Moolenbroek 			break;
449*66dfcc85SDavid van Moolenbroek #endif
450*66dfcc85SDavid van Moolenbroek 		case 'h':
451*66dfcc85SDavid van Moolenbroek 			hflag = 1;
452*66dfcc85SDavid van Moolenbroek 			break;
453*66dfcc85SDavid van Moolenbroek 		case 'I':
454*66dfcc85SDavid van Moolenbroek 			iflag = 1;
455*66dfcc85SDavid van Moolenbroek 			interface = optarg;
456*66dfcc85SDavid van Moolenbroek 			break;
457*66dfcc85SDavid van Moolenbroek 		case 'i':
458*66dfcc85SDavid van Moolenbroek 			iflag = 1;
459*66dfcc85SDavid van Moolenbroek 			break;
460*66dfcc85SDavid van Moolenbroek 		case 'L':
461*66dfcc85SDavid van Moolenbroek 			Lflag = RT_LFLAG;
462*66dfcc85SDavid van Moolenbroek 			break;
463*66dfcc85SDavid van Moolenbroek 		case 'l':
464*66dfcc85SDavid van Moolenbroek 			lflag = 1;
465*66dfcc85SDavid van Moolenbroek 			break;
466*66dfcc85SDavid van Moolenbroek 		case 'M':
467*66dfcc85SDavid van Moolenbroek 			memf = optarg;
468*66dfcc85SDavid van Moolenbroek 			break;
469*66dfcc85SDavid van Moolenbroek 		case 'm':
470*66dfcc85SDavid van Moolenbroek 			mflag = 1;
471*66dfcc85SDavid van Moolenbroek 			break;
472*66dfcc85SDavid van Moolenbroek 		case 'N':
473*66dfcc85SDavid van Moolenbroek 			nlistf = optarg;
474*66dfcc85SDavid van Moolenbroek 			break;
475*66dfcc85SDavid van Moolenbroek 		case 'n':
476*66dfcc85SDavid van Moolenbroek 			numeric_addr = numeric_port = nflag = RT_NFLAG;
477*66dfcc85SDavid van Moolenbroek 			break;
478*66dfcc85SDavid van Moolenbroek 		case 'P':
479*66dfcc85SDavid van Moolenbroek 			errno = 0;
480*66dfcc85SDavid van Moolenbroek 			pcbaddr = strtoul(optarg, &cp, 16);
481*66dfcc85SDavid van Moolenbroek 			if (*cp != '\0' || errno == ERANGE)
482*66dfcc85SDavid van Moolenbroek 				errx(1, "invalid PCB address %s",
483*66dfcc85SDavid van Moolenbroek 				    optarg);
484*66dfcc85SDavid van Moolenbroek 			Pflag = 1;
485*66dfcc85SDavid van Moolenbroek 			break;
486*66dfcc85SDavid van Moolenbroek 		case 'p':
487*66dfcc85SDavid van Moolenbroek 			if ((tp = name2protox(optarg)) == NULL)
488*66dfcc85SDavid van Moolenbroek 				errx(1, "%s: unknown or uninstrumented protocol",
489*66dfcc85SDavid van Moolenbroek 				    optarg);
490*66dfcc85SDavid van Moolenbroek 			pflag = 1;
491*66dfcc85SDavid van Moolenbroek 			break;
492*66dfcc85SDavid van Moolenbroek 		case 'q':
493*66dfcc85SDavid van Moolenbroek 			qflag = 1;
494*66dfcc85SDavid van Moolenbroek 			break;
495*66dfcc85SDavid van Moolenbroek 		case 'r':
496*66dfcc85SDavid van Moolenbroek 			rflag = 1;
497*66dfcc85SDavid van Moolenbroek 			break;
498*66dfcc85SDavid van Moolenbroek 		case 's':
499*66dfcc85SDavid van Moolenbroek 			++sflag;
500*66dfcc85SDavid van Moolenbroek 			break;
501*66dfcc85SDavid van Moolenbroek 		case 'S':
502*66dfcc85SDavid van Moolenbroek 			numeric_addr = 1;
503*66dfcc85SDavid van Moolenbroek 			break;
504*66dfcc85SDavid van Moolenbroek 		case 't':
505*66dfcc85SDavid van Moolenbroek 			tflag = 1;
506*66dfcc85SDavid van Moolenbroek 			break;
507*66dfcc85SDavid van Moolenbroek 		case 'T':
508*66dfcc85SDavid van Moolenbroek 			tagflag = RT_TFLAG;
509*66dfcc85SDavid van Moolenbroek 			break;
510*66dfcc85SDavid van Moolenbroek 		case 'u':
511*66dfcc85SDavid van Moolenbroek 			af = AF_LOCAL;
512*66dfcc85SDavid van Moolenbroek 			break;
513*66dfcc85SDavid van Moolenbroek 		case 'V':
514*66dfcc85SDavid van Moolenbroek 			Vflag++;
515*66dfcc85SDavid van Moolenbroek 			break;
516*66dfcc85SDavid van Moolenbroek 		case 'v':
517*66dfcc85SDavid van Moolenbroek 			vflag = RT_VFLAG;
518*66dfcc85SDavid van Moolenbroek 			break;
519*66dfcc85SDavid van Moolenbroek 		case 'w':
520*66dfcc85SDavid van Moolenbroek 			interval = atoi(optarg);
521*66dfcc85SDavid van Moolenbroek 			iflag = 1;
522*66dfcc85SDavid van Moolenbroek 			break;
523*66dfcc85SDavid van Moolenbroek 		case 'X':
524*66dfcc85SDavid van Moolenbroek 			force_sysctl = 1;
525*66dfcc85SDavid van Moolenbroek 			break;
526*66dfcc85SDavid van Moolenbroek 		case '?':
527*66dfcc85SDavid van Moolenbroek 		default:
528*66dfcc85SDavid van Moolenbroek 			usage();
529*66dfcc85SDavid van Moolenbroek 		}
530*66dfcc85SDavid van Moolenbroek 	argv += optind;
531*66dfcc85SDavid van Moolenbroek 	argc -= optind;
532*66dfcc85SDavid van Moolenbroek 
533*66dfcc85SDavid van Moolenbroek #define	BACKWARD_COMPATIBILITY
534*66dfcc85SDavid van Moolenbroek #ifdef	BACKWARD_COMPATIBILITY
535*66dfcc85SDavid van Moolenbroek 	if (*argv) {
536*66dfcc85SDavid van Moolenbroek 		if (isdigit((unsigned char)**argv)) {
537*66dfcc85SDavid van Moolenbroek 			interval = atoi(*argv);
538*66dfcc85SDavid van Moolenbroek 			if (interval <= 0)
539*66dfcc85SDavid van Moolenbroek 				usage();
540*66dfcc85SDavid van Moolenbroek 			++argv;
541*66dfcc85SDavid van Moolenbroek 			iflag = 1;
542*66dfcc85SDavid van Moolenbroek 		}
543*66dfcc85SDavid van Moolenbroek 		if (*argv) {
544*66dfcc85SDavid van Moolenbroek 			nlistf = *argv;
545*66dfcc85SDavid van Moolenbroek 			if (*++argv)
546*66dfcc85SDavid van Moolenbroek 				memf = *argv;
547*66dfcc85SDavid van Moolenbroek 		}
548*66dfcc85SDavid van Moolenbroek 	}
549*66dfcc85SDavid van Moolenbroek #endif
550*66dfcc85SDavid van Moolenbroek 
551*66dfcc85SDavid van Moolenbroek 	prepare(nlistf, memf, tp);
552*66dfcc85SDavid van Moolenbroek 
553*66dfcc85SDavid van Moolenbroek #ifndef SMALL
554*66dfcc85SDavid van Moolenbroek 	if (Bflag) {
555*66dfcc85SDavid van Moolenbroek 		if (sflag)
556*66dfcc85SDavid van Moolenbroek 			bpf_stats();
557*66dfcc85SDavid van Moolenbroek 		else
558*66dfcc85SDavid van Moolenbroek 			bpf_dump(interface);
559*66dfcc85SDavid van Moolenbroek 		exit(0);
560*66dfcc85SDavid van Moolenbroek 	}
561*66dfcc85SDavid van Moolenbroek #endif
562*66dfcc85SDavid van Moolenbroek 
563*66dfcc85SDavid van Moolenbroek 	if (mflag) {
564*66dfcc85SDavid van Moolenbroek 		mbpr(nl[N_MBSTAT].n_value,  nl[N_MSIZE].n_value,
565*66dfcc85SDavid van Moolenbroek 		    nl[N_MCLBYTES].n_value, nl[N_MBPOOL].n_value,
566*66dfcc85SDavid van Moolenbroek 		    nl[N_MCLPOOL].n_value);
567*66dfcc85SDavid van Moolenbroek 		exit(0);
568*66dfcc85SDavid van Moolenbroek 	}
569*66dfcc85SDavid van Moolenbroek 	if (Pflag) {
570*66dfcc85SDavid van Moolenbroek 		if (tp == NULL) {
571*66dfcc85SDavid van Moolenbroek 			/* Default to TCP. */
572*66dfcc85SDavid van Moolenbroek 			tp = name2protox("tcp");
573*66dfcc85SDavid van Moolenbroek 		}
574*66dfcc85SDavid van Moolenbroek 		if (tp->pr_dump)
575*66dfcc85SDavid van Moolenbroek 			(*tp->pr_dump)(nl[tp->pr_index].n_value, tp->pr_name,
576*66dfcc85SDavid van Moolenbroek 			    pcbaddr);
577*66dfcc85SDavid van Moolenbroek 		else
578*66dfcc85SDavid van Moolenbroek 			printf("%s: no PCB dump routine\n", tp->pr_name);
579*66dfcc85SDavid van Moolenbroek 		exit(0);
580*66dfcc85SDavid van Moolenbroek 	}
581*66dfcc85SDavid van Moolenbroek 	if (pflag) {
582*66dfcc85SDavid van Moolenbroek 		if (iflag && tp->pr_istats)
583*66dfcc85SDavid van Moolenbroek 			intpr(interval, nl[N_IFNET_LIST].n_value, tp->pr_istats);
584*66dfcc85SDavid van Moolenbroek 		else if (tp->pr_stats)
585*66dfcc85SDavid van Moolenbroek 			(*tp->pr_stats)(nl[tp->pr_sindex].n_value,
586*66dfcc85SDavid van Moolenbroek 				tp->pr_name);
587*66dfcc85SDavid van Moolenbroek 		else
588*66dfcc85SDavid van Moolenbroek 			printf("%s: no stats routine\n", tp->pr_name);
589*66dfcc85SDavid van Moolenbroek 		exit(0);
590*66dfcc85SDavid van Moolenbroek 	}
591*66dfcc85SDavid van Moolenbroek 	if (qflag) {
592*66dfcc85SDavid van Moolenbroek 		print_softintrq();
593*66dfcc85SDavid van Moolenbroek 		exit(0);
594*66dfcc85SDavid van Moolenbroek 	}
595*66dfcc85SDavid van Moolenbroek 	/*
596*66dfcc85SDavid van Moolenbroek 	 * Keep file descriptors open to avoid overhead
597*66dfcc85SDavid van Moolenbroek 	 * of open/close on each call to get* routines.
598*66dfcc85SDavid van Moolenbroek 	 */
599*66dfcc85SDavid van Moolenbroek 	sethostent(1);
600*66dfcc85SDavid van Moolenbroek 	setnetent(1);
601*66dfcc85SDavid van Moolenbroek 	/*
602*66dfcc85SDavid van Moolenbroek 	 * If -f was used afnames != NULL, loop over the address families.
603*66dfcc85SDavid van Moolenbroek 	 * Otherwise do this at least once (with af == AF_UNSPEC).
604*66dfcc85SDavid van Moolenbroek 	 */
605*66dfcc85SDavid van Moolenbroek 	afname = NULL;
606*66dfcc85SDavid van Moolenbroek 	do {
607*66dfcc85SDavid van Moolenbroek 		if (afnames != NULL) {
608*66dfcc85SDavid van Moolenbroek 			afname = strsep(&afnames, ",");
609*66dfcc85SDavid van Moolenbroek 			if (afname == NULL)
610*66dfcc85SDavid van Moolenbroek 				break;		/* Exit early */
611*66dfcc85SDavid van Moolenbroek 			if (strcmp(afname, "inet") == 0)
612*66dfcc85SDavid van Moolenbroek 				af = AF_INET;
613*66dfcc85SDavid van Moolenbroek 			else if (strcmp(afname, "inet6") == 0)
614*66dfcc85SDavid van Moolenbroek 				af = AF_INET6;
615*66dfcc85SDavid van Moolenbroek 			else if (strcmp(afname, "arp") == 0)
616*66dfcc85SDavid van Moolenbroek 				af = AF_ARP;
617*66dfcc85SDavid van Moolenbroek 			else if (strcmp(afname, "pfkey") == 0)
618*66dfcc85SDavid van Moolenbroek 				af = PF_KEY;
619*66dfcc85SDavid van Moolenbroek 			else if (strcmp(afname, "unix") == 0
620*66dfcc85SDavid van Moolenbroek 			    || strcmp(afname, "local") == 0)
621*66dfcc85SDavid van Moolenbroek 				af = AF_LOCAL;
622*66dfcc85SDavid van Moolenbroek 			else if (strcmp(afname, "atalk") == 0)
623*66dfcc85SDavid van Moolenbroek 				af = AF_APPLETALK;
624*66dfcc85SDavid van Moolenbroek 			else if (strcmp(afname, "mpls") == 0)
625*66dfcc85SDavid van Moolenbroek 				af = AF_MPLS;
626*66dfcc85SDavid van Moolenbroek 			else {
627*66dfcc85SDavid van Moolenbroek 				warnx("%s: unknown address family",
628*66dfcc85SDavid van Moolenbroek 				    afname);
629*66dfcc85SDavid van Moolenbroek 				continue;
630*66dfcc85SDavid van Moolenbroek 			}
631*66dfcc85SDavid van Moolenbroek 		}
632*66dfcc85SDavid van Moolenbroek 
633*66dfcc85SDavid van Moolenbroek 		if (iflag) {
634*66dfcc85SDavid van Moolenbroek 			if (af != AF_UNSPEC)
635*66dfcc85SDavid van Moolenbroek 				goto protostat;
636*66dfcc85SDavid van Moolenbroek 
637*66dfcc85SDavid van Moolenbroek 			intpr(interval, nl[N_IFNET_LIST].n_value, NULL);
638*66dfcc85SDavid van Moolenbroek 			break;
639*66dfcc85SDavid van Moolenbroek 		}
640*66dfcc85SDavid van Moolenbroek 		if (rflag) {
641*66dfcc85SDavid van Moolenbroek 			if (sflag)
642*66dfcc85SDavid van Moolenbroek 				rt_stats(use_sysctl ? 0 : nl[N_RTSTAT].n_value);
643*66dfcc85SDavid van Moolenbroek 			else {
644*66dfcc85SDavid van Moolenbroek 				if (use_sysctl)
645*66dfcc85SDavid van Moolenbroek 					p_rttables(af,
646*66dfcc85SDavid van Moolenbroek 					    nflag|tagflag|vflag|Lflag, 0, ~0);
647*66dfcc85SDavid van Moolenbroek 				else
648*66dfcc85SDavid van Moolenbroek 					routepr(nl[N_RTREE].n_value);
649*66dfcc85SDavid van Moolenbroek 			}
650*66dfcc85SDavid van Moolenbroek 			break;
651*66dfcc85SDavid van Moolenbroek 		}
652*66dfcc85SDavid van Moolenbroek #ifndef SMALL
653*66dfcc85SDavid van Moolenbroek 		if (gflag) {
654*66dfcc85SDavid van Moolenbroek 			if (sflag) {
655*66dfcc85SDavid van Moolenbroek 				if (af == AF_INET || af == AF_UNSPEC)
656*66dfcc85SDavid van Moolenbroek 					mrt_stats(nl[N_MRTPROTO].n_value,
657*66dfcc85SDavid van Moolenbroek 						  nl[N_MRTSTAT].n_value);
658*66dfcc85SDavid van Moolenbroek #ifdef INET6
659*66dfcc85SDavid van Moolenbroek 				if (af == AF_INET6 || af == AF_UNSPEC)
660*66dfcc85SDavid van Moolenbroek 					mrt6_stats(nl[N_MRT6PROTO].n_value,
661*66dfcc85SDavid van Moolenbroek 						   nl[N_MRT6STAT].n_value);
662*66dfcc85SDavid van Moolenbroek #endif
663*66dfcc85SDavid van Moolenbroek 			}
664*66dfcc85SDavid van Moolenbroek 			else {
665*66dfcc85SDavid van Moolenbroek 				if (af == AF_INET || af == AF_UNSPEC)
666*66dfcc85SDavid van Moolenbroek 					mroutepr(nl[N_MRTPROTO].n_value,
667*66dfcc85SDavid van Moolenbroek 						 nl[N_MFCHASHTBL].n_value,
668*66dfcc85SDavid van Moolenbroek 						 nl[N_MFCHASH].n_value,
669*66dfcc85SDavid van Moolenbroek 						 nl[N_VIFTABLE].n_value);
670*66dfcc85SDavid van Moolenbroek #ifdef INET6
671*66dfcc85SDavid van Moolenbroek 				if (af == AF_INET6 || af == AF_UNSPEC)
672*66dfcc85SDavid van Moolenbroek 					mroute6pr(nl[N_MRT6PROTO].n_value,
673*66dfcc85SDavid van Moolenbroek 						  nl[N_MF6CTABLE].n_value,
674*66dfcc85SDavid van Moolenbroek 						  nl[N_MIF6TABLE].n_value);
675*66dfcc85SDavid van Moolenbroek #endif
676*66dfcc85SDavid van Moolenbroek 			}
677*66dfcc85SDavid van Moolenbroek 			break;
678*66dfcc85SDavid van Moolenbroek 		}
679*66dfcc85SDavid van Moolenbroek #endif
680*66dfcc85SDavid van Moolenbroek 	  protostat:
681*66dfcc85SDavid van Moolenbroek 		if (af == AF_INET || af == AF_UNSPEC) {
682*66dfcc85SDavid van Moolenbroek 			setprotoent(1);
683*66dfcc85SDavid van Moolenbroek 			setservent(1);
684*66dfcc85SDavid van Moolenbroek 			/* ugh, this is O(MN) ... why do we do this? */
685*66dfcc85SDavid van Moolenbroek 			while ((p = getprotoent()) != NULL) {
686*66dfcc85SDavid van Moolenbroek 				for (tp = protox; tp->pr_name; tp++)
687*66dfcc85SDavid van Moolenbroek 					if (strcmp(tp->pr_name, p->p_name) == 0)
688*66dfcc85SDavid van Moolenbroek 						break;
689*66dfcc85SDavid van Moolenbroek 				if (tp->pr_name == 0 || tp->pr_wanted == 0)
690*66dfcc85SDavid van Moolenbroek 					continue;
691*66dfcc85SDavid van Moolenbroek 				printproto(tp, p->p_name);
692*66dfcc85SDavid van Moolenbroek 				tp->pr_wanted = 0;
693*66dfcc85SDavid van Moolenbroek 			}
694*66dfcc85SDavid van Moolenbroek 			endprotoent();
695*66dfcc85SDavid van Moolenbroek 			for (tp = protox; tp->pr_name; tp++)
696*66dfcc85SDavid van Moolenbroek 				if (tp->pr_wanted)
697*66dfcc85SDavid van Moolenbroek 					printproto(tp, tp->pr_name);
698*66dfcc85SDavid van Moolenbroek 		}
699*66dfcc85SDavid van Moolenbroek #ifdef INET6
700*66dfcc85SDavid van Moolenbroek 		if (af == AF_INET6 || af == AF_UNSPEC)
701*66dfcc85SDavid van Moolenbroek 			for (tp = ip6protox; tp->pr_name; tp++)
702*66dfcc85SDavid van Moolenbroek 				printproto(tp, tp->pr_name);
703*66dfcc85SDavid van Moolenbroek #endif
704*66dfcc85SDavid van Moolenbroek 		if (af == AF_ARP || af == AF_UNSPEC)
705*66dfcc85SDavid van Moolenbroek 			for (tp = arpprotox; tp->pr_name; tp++)
706*66dfcc85SDavid van Moolenbroek 				printproto(tp, tp->pr_name);
707*66dfcc85SDavid van Moolenbroek #ifdef IPSEC
708*66dfcc85SDavid van Moolenbroek 		if (af == PF_KEY || af == AF_UNSPEC)
709*66dfcc85SDavid van Moolenbroek 			for (tp = pfkeyprotox; tp->pr_name; tp++)
710*66dfcc85SDavid van Moolenbroek 				printproto(tp, tp->pr_name);
711*66dfcc85SDavid van Moolenbroek #endif
712*66dfcc85SDavid van Moolenbroek #ifndef SMALL
713*66dfcc85SDavid van Moolenbroek 		if (af == AF_APPLETALK || af == AF_UNSPEC)
714*66dfcc85SDavid van Moolenbroek 			for (tp = atalkprotox; tp->pr_name; tp++)
715*66dfcc85SDavid van Moolenbroek 				printproto(tp, tp->pr_name);
716*66dfcc85SDavid van Moolenbroek 		if ((af == AF_LOCAL || af == AF_UNSPEC) && !sflag)
717*66dfcc85SDavid van Moolenbroek 			unixpr(nl[N_UNIXSW].n_value);
718*66dfcc85SDavid van Moolenbroek #endif
719*66dfcc85SDavid van Moolenbroek 	} while (afnames != NULL && afname != NULL);
720*66dfcc85SDavid van Moolenbroek 	exit(0);
721*66dfcc85SDavid van Moolenbroek }
722*66dfcc85SDavid van Moolenbroek 
723*66dfcc85SDavid van Moolenbroek /*
724*66dfcc85SDavid van Moolenbroek  * Print out protocol statistics or control blocks (per sflag).
725*66dfcc85SDavid van Moolenbroek  * If the interface was not specifically requested, and the symbol
726*66dfcc85SDavid van Moolenbroek  * is not in the namelist, ignore this one.
727*66dfcc85SDavid van Moolenbroek  */
728*66dfcc85SDavid van Moolenbroek static void
printproto(struct protox * tp,const char * name)729*66dfcc85SDavid van Moolenbroek printproto(struct protox *tp, const char *name)
730*66dfcc85SDavid van Moolenbroek {
731*66dfcc85SDavid van Moolenbroek 	void (*pr) __P((u_long, const char *));
732*66dfcc85SDavid van Moolenbroek 	u_long off;
733*66dfcc85SDavid van Moolenbroek 
734*66dfcc85SDavid van Moolenbroek 	if (sflag) {
735*66dfcc85SDavid van Moolenbroek 		if (iflag) {
736*66dfcc85SDavid van Moolenbroek 			if (tp->pr_istats)
737*66dfcc85SDavid van Moolenbroek 				intpr(interval, nl[N_IFNET_LIST].n_value,
738*66dfcc85SDavid van Moolenbroek 				      tp->pr_istats);
739*66dfcc85SDavid van Moolenbroek 			return;
740*66dfcc85SDavid van Moolenbroek 		}
741*66dfcc85SDavid van Moolenbroek 		else {
742*66dfcc85SDavid van Moolenbroek 			pr = tp->pr_stats;
743*66dfcc85SDavid van Moolenbroek 			off = nl[tp->pr_sindex].n_value;
744*66dfcc85SDavid van Moolenbroek 		}
745*66dfcc85SDavid van Moolenbroek 	} else {
746*66dfcc85SDavid van Moolenbroek 		pr = tp->pr_cblocks;
747*66dfcc85SDavid van Moolenbroek 		off = nl[tp->pr_index].n_value;
748*66dfcc85SDavid van Moolenbroek 	}
749*66dfcc85SDavid van Moolenbroek 	if (pr != NULL && ((off || af != AF_UNSPEC) || use_sysctl)) {
750*66dfcc85SDavid van Moolenbroek 		(*pr)(off, name);
751*66dfcc85SDavid van Moolenbroek 	}
752*66dfcc85SDavid van Moolenbroek }
753*66dfcc85SDavid van Moolenbroek 
754*66dfcc85SDavid van Moolenbroek /*
755*66dfcc85SDavid van Moolenbroek  * Print softintrq status.
756*66dfcc85SDavid van Moolenbroek  */
757*66dfcc85SDavid van Moolenbroek void
print_softintrq(void)758*66dfcc85SDavid van Moolenbroek print_softintrq(void)
759*66dfcc85SDavid van Moolenbroek {
760*66dfcc85SDavid van Moolenbroek 	struct ifqueue intrq, *ifq = &intrq;
761*66dfcc85SDavid van Moolenbroek 	const struct softintrq *siq;
762*66dfcc85SDavid van Moolenbroek 	u_long off;
763*66dfcc85SDavid van Moolenbroek 
764*66dfcc85SDavid van Moolenbroek 	for (siq = softintrq; siq->siq_name != NULL; siq++) {
765*66dfcc85SDavid van Moolenbroek 		off = nl[siq->siq_index].n_value;
766*66dfcc85SDavid van Moolenbroek 		if (off == 0)
767*66dfcc85SDavid van Moolenbroek 			continue;
768*66dfcc85SDavid van Moolenbroek 
769*66dfcc85SDavid van Moolenbroek 		kread(off, (char *)ifq, sizeof(*ifq));
770*66dfcc85SDavid van Moolenbroek 		printf("%s:\n", siq->siq_name);
771*66dfcc85SDavid van Moolenbroek 		printf("\tqueue length: %d\n", ifq->ifq_len);
772*66dfcc85SDavid van Moolenbroek 		printf("\tmaximum queue length: %d\n", ifq->ifq_maxlen);
773*66dfcc85SDavid van Moolenbroek 		printf("\tpackets dropped: %d\n", ifq->ifq_drops);
774*66dfcc85SDavid van Moolenbroek 	}
775*66dfcc85SDavid van Moolenbroek }
776*66dfcc85SDavid van Moolenbroek 
777*66dfcc85SDavid van Moolenbroek /*
778*66dfcc85SDavid van Moolenbroek  * Read kernel memory, return 0 on success.
779*66dfcc85SDavid van Moolenbroek  */
780*66dfcc85SDavid van Moolenbroek int
kread(u_long addr,char * buf,int size)781*66dfcc85SDavid van Moolenbroek kread(u_long addr, char *buf, int size)
782*66dfcc85SDavid van Moolenbroek {
783*66dfcc85SDavid van Moolenbroek 
784*66dfcc85SDavid van Moolenbroek 	if (kvm_read(kvmd, addr, buf, size) != size) {
785*66dfcc85SDavid van Moolenbroek 		warnx("%s", kvm_geterr(kvmd));
786*66dfcc85SDavid van Moolenbroek 		return (-1);
787*66dfcc85SDavid van Moolenbroek 	}
788*66dfcc85SDavid van Moolenbroek 	return (0);
789*66dfcc85SDavid van Moolenbroek }
790*66dfcc85SDavid van Moolenbroek 
791*66dfcc85SDavid van Moolenbroek const char *
plural(int n)792*66dfcc85SDavid van Moolenbroek plural(int n)
793*66dfcc85SDavid van Moolenbroek {
794*66dfcc85SDavid van Moolenbroek 
795*66dfcc85SDavid van Moolenbroek 	return (n != 1 ? "s" : "");
796*66dfcc85SDavid van Moolenbroek }
797*66dfcc85SDavid van Moolenbroek 
798*66dfcc85SDavid van Moolenbroek const char *
plurales(int n)799*66dfcc85SDavid van Moolenbroek plurales(int n)
800*66dfcc85SDavid van Moolenbroek {
801*66dfcc85SDavid van Moolenbroek 
802*66dfcc85SDavid van Moolenbroek 	return (n != 1 ? "es" : "");
803*66dfcc85SDavid van Moolenbroek }
804*66dfcc85SDavid van Moolenbroek 
805*66dfcc85SDavid van Moolenbroek int
get_hardticks(void)806*66dfcc85SDavid van Moolenbroek get_hardticks(void)
807*66dfcc85SDavid van Moolenbroek {
808*66dfcc85SDavid van Moolenbroek 	int hardticks;
809*66dfcc85SDavid van Moolenbroek 
810*66dfcc85SDavid van Moolenbroek 	kread(nl[N_HARDCLOCK_TICKS].n_value, (char *)&hardticks,
811*66dfcc85SDavid van Moolenbroek 	    sizeof(hardticks));
812*66dfcc85SDavid van Moolenbroek 	return (hardticks);
813*66dfcc85SDavid van Moolenbroek }
814*66dfcc85SDavid van Moolenbroek 
815*66dfcc85SDavid van Moolenbroek /*
816*66dfcc85SDavid van Moolenbroek  * Find the protox for the given "well-known" name.
817*66dfcc85SDavid van Moolenbroek  */
818*66dfcc85SDavid van Moolenbroek static struct protox *
knownname(const char * name)819*66dfcc85SDavid van Moolenbroek knownname(const char *name)
820*66dfcc85SDavid van Moolenbroek {
821*66dfcc85SDavid van Moolenbroek 	struct protox **tpp, *tp;
822*66dfcc85SDavid van Moolenbroek 
823*66dfcc85SDavid van Moolenbroek 	for (tpp = protoprotox; *tpp; tpp++)
824*66dfcc85SDavid van Moolenbroek 		for (tp = *tpp; tp->pr_name; tp++)
825*66dfcc85SDavid van Moolenbroek 			if (strcmp(tp->pr_name, name) == 0)
826*66dfcc85SDavid van Moolenbroek 				return (tp);
827*66dfcc85SDavid van Moolenbroek 	return (NULL);
828*66dfcc85SDavid van Moolenbroek }
829*66dfcc85SDavid van Moolenbroek 
830*66dfcc85SDavid van Moolenbroek /*
831*66dfcc85SDavid van Moolenbroek  * Find the protox corresponding to name.
832*66dfcc85SDavid van Moolenbroek  */
833*66dfcc85SDavid van Moolenbroek static struct protox *
name2protox(const char * name)834*66dfcc85SDavid van Moolenbroek name2protox(const char *name)
835*66dfcc85SDavid van Moolenbroek {
836*66dfcc85SDavid van Moolenbroek 	struct protox *tp;
837*66dfcc85SDavid van Moolenbroek 	char **alias;			/* alias from p->aliases */
838*66dfcc85SDavid van Moolenbroek 	struct protoent *p;
839*66dfcc85SDavid van Moolenbroek 
840*66dfcc85SDavid van Moolenbroek 	/*
841*66dfcc85SDavid van Moolenbroek 	 * Try to find the name in the list of "well-known" names. If that
842*66dfcc85SDavid van Moolenbroek 	 * fails, check if name is an alias for an Internet protocol.
843*66dfcc85SDavid van Moolenbroek 	 */
844*66dfcc85SDavid van Moolenbroek 	if ((tp = knownname(name)) != NULL)
845*66dfcc85SDavid van Moolenbroek 		return (tp);
846*66dfcc85SDavid van Moolenbroek 
847*66dfcc85SDavid van Moolenbroek 	setprotoent(1);			/* make protocol lookup cheaper */
848*66dfcc85SDavid van Moolenbroek 	while ((p = getprotoent()) != NULL) {
849*66dfcc85SDavid van Moolenbroek 		/* assert: name not same as p->name */
850*66dfcc85SDavid van Moolenbroek 		for (alias = p->p_aliases; *alias; alias++)
851*66dfcc85SDavid van Moolenbroek 			if (strcmp(name, *alias) == 0) {
852*66dfcc85SDavid van Moolenbroek 				endprotoent();
853*66dfcc85SDavid van Moolenbroek 				return (knownname(p->p_name));
854*66dfcc85SDavid van Moolenbroek 			}
855*66dfcc85SDavid van Moolenbroek 	}
856*66dfcc85SDavid van Moolenbroek 	endprotoent();
857*66dfcc85SDavid van Moolenbroek 	return (NULL);
858*66dfcc85SDavid van Moolenbroek }
859*66dfcc85SDavid van Moolenbroek 
860*66dfcc85SDavid van Moolenbroek static void
usage(void)861*66dfcc85SDavid van Moolenbroek usage(void)
862*66dfcc85SDavid van Moolenbroek {
863*66dfcc85SDavid van Moolenbroek 	const char *progname = getprogname();
864*66dfcc85SDavid van Moolenbroek 
865*66dfcc85SDavid van Moolenbroek 	(void)fprintf(stderr,
866*66dfcc85SDavid van Moolenbroek "usage: %s [-Aan] [-f address_family[,family ...]] [-M core] [-N system]\n", progname);
867*66dfcc85SDavid van Moolenbroek 	(void)fprintf(stderr,
868*66dfcc85SDavid van Moolenbroek "       %s [-bdgiLmnqrsSv] [-f address_family[,family ...]] [-M core] [-N system]\n",
869*66dfcc85SDavid van Moolenbroek 	progname);
870*66dfcc85SDavid van Moolenbroek 	(void)fprintf(stderr,
871*66dfcc85SDavid van Moolenbroek "       %s [-dn] [-I interface] [-M core] [-N system] [-w wait]\n", progname);
872*66dfcc85SDavid van Moolenbroek 	(void)fprintf(stderr,
873*66dfcc85SDavid van Moolenbroek "       %s [-p protocol] [-M core] [-N system]\n", progname);
874*66dfcc85SDavid van Moolenbroek 	(void)fprintf(stderr,
875*66dfcc85SDavid van Moolenbroek "       %s [-p protocol] [-M core] [-N system] -P pcbaddr\n", progname);
876*66dfcc85SDavid van Moolenbroek 	(void)fprintf(stderr,
877*66dfcc85SDavid van Moolenbroek "       %s [-p protocol] [-i] [-I Interface] \n", progname);
878*66dfcc85SDavid van Moolenbroek 	(void)fprintf(stderr,
879*66dfcc85SDavid van Moolenbroek "       %s [-s] [-f address_family[,family ...]] [-i] [-I Interface]\n", progname);
880*66dfcc85SDavid van Moolenbroek 	(void)fprintf(stderr,
881*66dfcc85SDavid van Moolenbroek "       %s [-s] [-B] [-I interface]\n", progname);
882*66dfcc85SDavid van Moolenbroek 	exit(1);
883*66dfcc85SDavid van Moolenbroek }
884