GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/netstat/inet.c Lines: 0 748 0.0 %
Date: 2016-12-06 Branches: 0 1437 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: inet.c,v 1.147 2016/07/20 19:57:54 bluhm Exp $	*/
2
/*	$NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $	*/
3
4
/*
5
 * Copyright (c) 1983, 1988, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
#include <sys/queue.h>
34
#include <sys/socket.h>
35
#include <sys/socketvar.h>
36
#include <sys/domain.h>
37
#include <sys/protosw.h>
38
#include <sys/sysctl.h>
39
#define _KERNEL
40
#include <sys/file.h>
41
#undef _KERNEL
42
43
#include <net/route.h>
44
#include <netinet/in.h>
45
#include <netinet/ip.h>
46
#include <netinet/in_pcb.h>
47
#include <netinet/ip_icmp.h>
48
#include <netinet/icmp_var.h>
49
#include <netinet/igmp_var.h>
50
#include <netinet/ip_var.h>
51
#include <netinet/pim_var.h>
52
#include <netinet/tcp.h>
53
#include <netinet/tcp_seq.h>
54
#define TCPSTATES
55
#include <netinet/tcp_fsm.h>
56
#include <netinet/tcp_timer.h>
57
#include <netinet/tcp_var.h>
58
#include <netinet/udp.h>
59
#include <netinet/udp_var.h>
60
#include <netinet/ip_ipsp.h>
61
#include <netinet/ip_ah.h>
62
#include <netinet/ip_esp.h>
63
#include <netinet/ip_ipip.h>
64
#include <netinet/ip_ipcomp.h>
65
#include <netinet/ip_ether.h>
66
#include <netinet/ip_carp.h>
67
#include <netinet/ip_divert.h>
68
#include <net/if.h>
69
#include <net/pfvar.h>
70
#include <net/if_pfsync.h>
71
#include <net/if_pflow.h>
72
73
#include <rpc/rpc.h>
74
#include <rpc/pmap_prot.h>
75
#include <rpc/pmap_clnt.h>
76
77
#include <arpa/inet.h>
78
#include <err.h>
79
#include <limits.h>
80
#include <netdb.h>
81
#include <stdio.h>
82
#include <string.h>
83
#include <unistd.h>
84
#include <stdlib.h>
85
#include <errno.h>
86
#include "netstat.h"
87
88
struct	inpcb inpcb;
89
struct	tcpcb tcpcb;
90
struct	socket sockb;
91
92
char	*inetname(struct in_addr *);
93
void	inetprint(struct in_addr *, in_port_t, const char *, int);
94
char	*inet6name(struct in6_addr *);
95
void	sosplice_dump(u_long);
96
void	sockbuf_dump(struct sockbuf *, const char *);
97
void	protosw_dump(u_long, u_long);
98
void	domain_dump(u_long, u_long, short);
99
void	inpcb_dump(u_long, short, int);
100
void	tcpcb_dump(u_long);
101
102
int type_map[] = { -1, 2, 3, 1, 4, 5 };
103
104
int
105
kf_comp(const void *a, const void *b)
106
{
107
	const struct kinfo_file *ka = a, *kb = b;
108
109
	if (ka->so_family != kb->so_family) {
110
		/* AF_INET < AF_INET6 < AF_LOCAL */
111
		if (ka->so_family == AF_INET)
112
			return (-1);
113
		if (ka->so_family == AF_LOCAL)
114
			return (1);
115
		if (kb->so_family == AF_LOCAL)
116
			return (-1);
117
		return (1);
118
	}
119
	if (ka->so_family == AF_LOCAL) {
120
		if (type_map[ka->so_type] < type_map[kb->so_type])
121
			return (-1);
122
		if (type_map[ka->so_type] > type_map[kb->so_type])
123
			return (1);
124
	} else if (ka->so_family == AF_INET || ka->so_family == AF_INET6) {
125
		if (ka->so_protocol < kb->so_protocol)
126
			return (-1);
127
		if (ka->so_protocol > kb->so_protocol)
128
			return (1);
129
		if (ka->so_type == SOCK_DGRAM || ka->so_type == SOCK_STREAM) {
130
			/* order sockets by remote port desc */
131
			if (ka->inp_fport > kb->inp_fport)
132
				return (-1);
133
			if (ka->inp_fport < kb->inp_fport)
134
				return (1);
135
		} else if (ka->so_type == SOCK_RAW) {
136
			if (ka->inp_proto > kb->inp_proto)
137
				return (-1);
138
			if (ka->inp_proto < kb->inp_proto)
139
				return (1);
140
		}
141
	}
142
	return (0);
143
}
144
145
void
146
protopr(kvm_t *kvmd, u_long pcbaddr, u_int tableid, int proto)
147
{
148
	struct kinfo_file *kf;
149
	int i, fcnt;
150
151
	kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET,
152
	    sizeof(*kf), &fcnt);
153
	if (kf == NULL) {
154
		printf("Out of memory (file table).\n");
155
		return;
156
	}
157
158
	/* sort sockets by AF and type */
159
	qsort(kf, fcnt, sizeof(*kf), kf_comp);
160
161
	for (i = 0; i < fcnt; i++) {
162
		if (Pflag) {
163
			switch (kf[i].so_family) {
164
			case AF_INET:
165
			case AF_INET6:
166
				/*
167
				 * XXX at the moment fstat returns the pointer
168
				 * to the so_pcb or for tcp sockets the tcpcb
169
				 * pointer (inp_ppcb) so check both.
170
				 */
171
				if (pcbaddr == kf[i].so_pcb) {
172
					inpcb_dump(pcbaddr, kf[i].so_protocol,
173
					    kf[i].so_family);
174
					return;
175
				} else if (pcbaddr == kf[i].inp_ppcb &&
176
				    kf[i].so_protocol == IPPROTO_TCP) {
177
					tcpcb_dump(pcbaddr);
178
					return;
179
				}
180
				break;
181
			case AF_UNIX:
182
				if (pcbaddr == kf[i].so_pcb) {
183
					unpcb_dump(pcbaddr);
184
					return;
185
				}
186
				break;
187
			}
188
			continue;
189
		}
190
		if (kf[i].so_family == AF_LOCAL && (kf[i].so_pcb != 0 ||
191
		    kf[i].unp_path[0] != '\0'))
192
			if ((af == AF_LOCAL || af == AF_UNSPEC) && !proto)
193
				unixdomainpr(&kf[i]);
194
		if (kf[i].so_family == AF_INET && kf[i].so_pcb != 0 &&
195
		    kf[i].inp_rtableid == tableid)
196
			if (af == AF_INET || af == AF_UNSPEC)
197
				netdomainpr(&kf[i], proto);
198
		if (kf[i].so_family == AF_INET6 && kf[i].so_pcb != 0 &&
199
		    kf[i].inp_rtableid == tableid)
200
			if (af == AF_INET6 || af == AF_UNSPEC)
201
				netdomainpr(&kf[i], proto);
202
	}
203
}
204
205
/*
206
 * Print a summary of connections related to an Internet
207
 * protocol.  For TCP, also give state of connection.
208
 * Listening processes (aflag) are suppressed unless the
209
 * -a (all) flag is specified.
210
 */
211
void
212
netdomainpr(struct kinfo_file *kf, int proto)
213
{
214
	static int af = 0, type = 0;
215
	struct in_addr laddr, faddr;
216
	struct in6_addr laddr6, faddr6;
217
	const char *name, *name6;
218
	int addrlen = 22;
219
	int isany = 0;
220
	int istcp = 0;
221
	int isip6 = 0;
222
223
	/* XXX should fix kinfo_file instead but not now */
224
	if (kf->so_pcb == -1)
225
		kf->so_pcb = 0;
226
227
	switch (proto) {
228
	case IPPROTO_TCP:
229
	case IPPROTO_UDP:
230
	case IPPROTO_DIVERT:
231
		if (kf->so_protocol != proto)
232
			return;
233
		break;
234
	case IPPROTO_IPV4:
235
		if (kf->so_type != SOCK_RAW || kf->so_family != AF_INET)
236
			return;
237
		break;
238
	case IPPROTO_IPV6:
239
		if (kf->so_type != SOCK_RAW || kf->so_family != AF_INET6)
240
			return;
241
		break;
242
	}
243
244
	/* make in_addr6 access a bit easier */
245
#define s6_addr32 __u6_addr.__u6_addr32
246
	laddr.s_addr = kf->inp_laddru[0];
247
	laddr6.s6_addr32[0] = kf->inp_laddru[0];
248
	laddr6.s6_addr32[1] = kf->inp_laddru[1];
249
	laddr6.s6_addr32[2] = kf->inp_laddru[2];
250
	laddr6.s6_addr32[3] = kf->inp_laddru[3];
251
252
	faddr.s_addr = kf->inp_faddru[0];
253
	faddr6.s6_addr32[0] = kf->inp_faddru[0];
254
	faddr6.s6_addr32[1] = kf->inp_faddru[1];
255
	faddr6.s6_addr32[2] = kf->inp_faddru[2];
256
	faddr6.s6_addr32[3] = kf->inp_faddru[3];
257
#undef s6_addr32
258
259
	switch (kf->so_family) {
260
	case AF_INET:
261
		isany = faddr.s_addr == INADDR_ANY;
262
		break;
263
	case AF_INET6:
264
		isany = IN6_IS_ADDR_UNSPECIFIED(&faddr6);
265
		isip6 = 1;
266
		break;
267
	}
268
269
	switch (kf->so_protocol) {
270
	case IPPROTO_TCP:
271
		name = "tcp";
272
		name6 = "tcp6";
273
		istcp = 1;
274
		break;
275
	case IPPROTO_UDP:
276
		name = "udp";
277
		name6 = "udp6";
278
		break;
279
	case IPPROTO_DIVERT:
280
		name = "divert";
281
		name6 = "divert6";
282
		break;
283
	default:
284
		name = "ip";
285
		name6 = "ip6";
286
		break;
287
	}
288
289
	/* filter listening sockets out unless -a is set */
290
	if (!aflag && istcp && kf->t_state <= TCPS_LISTEN)
291
		return;
292
	else if (!aflag && isany)
293
		return;
294
295
	if (af != kf->so_family || type != kf->so_type) {
296
		af = kf->so_family;
297
		type = kf->so_type;
298
		printf("Active Internet connections");
299
		if (aflag)
300
			printf(" (including servers)");
301
		putchar('\n');
302
		if (Aflag) {
303
			addrlen = 18;
304
			printf("%-*.*s ", PLEN, PLEN, "PCB");
305
		}
306
		printf("%-7.7s %-6.6s %-6.6s ",
307
		    "Proto", "Recv-Q", "Send-Q");
308
		if (Bflag && istcp)
309
			printf("%-6.6s %-6.6s %-6.6s ",
310
			    "Recv-W", "Send-W", "Cgst-W");
311
		printf(" %-*.*s %-*.*s %s\n",
312
		    addrlen, addrlen, "Local Address",
313
		    addrlen, addrlen, "Foreign Address", "(state)");
314
	}
315
316
	if (Aflag)
317
		printf("%#*llx%s ", FAKE_PTR(kf->so_pcb));
318
319
	printf("%-7.7s %6llu %6llu ",
320
	    isip6 ? name6: name, kf->so_rcv_cc, kf->so_snd_cc);
321
	if (Bflag && istcp)
322
		printf("%6llu %6llu %6llu ", kf->t_rcv_wnd, kf->t_snd_wnd,
323
		    (kf->t_state == TCPS_ESTABLISHED) ?
324
		    kf->t_snd_cwnd : 0);
325
326
	if (isip6) {
327
		inet6print(&laddr6, kf->inp_lport, name);
328
		inet6print(&faddr6, kf->inp_fport, name);
329
	} else {
330
		inetprint(&laddr, kf->inp_lport, name, 1);
331
		inetprint(&faddr, kf->inp_fport, name, 0);
332
	}
333
	if (istcp) {
334
		if (kf->t_state < 0 || kf->t_state >= TCP_NSTATES)
335
			printf(" %d", kf->t_state);
336
		else
337
			printf(" %s", tcpstates[kf->t_state]);
338
	} else if (kf->so_type == SOCK_RAW) {
339
		printf(" %u", kf->inp_proto);
340
	}
341
	putchar('\n');
342
}
343
344
/*
345
 * Dump TCP statistics structure.
346
 */
347
void
348
tcp_stats(char *name)
349
{
350
	struct tcpstat tcpstat;
351
	int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS };
352
	size_t len = sizeof(tcpstat);
353
354
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
355
	    &tcpstat, &len, NULL, 0) == -1) {
356
		if (errno != ENOPROTOOPT)
357
			warn("%s", name);
358
		return;
359
	}
360
361
	printf("%s:\n", name);
362
#define	p(f, m) if (tcpstat.f || sflag <= 1) \
363
	printf(m, tcpstat.f, plural(tcpstat.f))
364
#define	p1(f, m) if (tcpstat.f || sflag <= 1) \
365
	printf(m, tcpstat.f)
366
#define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
367
	printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
368
#define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
369
	printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
370
#define	p2b(f1, f2, m) if (tcpstat.f1 || sflag <= 1) \
371
	printf(m, tcpstat.f1, tcpstat.f2)
372
#define	p2bys(f1, f2, m) if (tcpstat.f1 || sflag <= 1) \
373
	printf(m, tcpstat.f1, pluralys(tcpstat.f1), tcpstat.f2)
374
#define	pes(f, m) if (tcpstat.f || sflag <= 1) \
375
	printf(m, tcpstat.f, plurales(tcpstat.f))
376
#define	pys(f, m) if (tcpstat.f || sflag <= 1) \
377
	printf(m, tcpstat.f, pluralys(tcpstat.f))
378
379
	p(tcps_sndtotal, "\t%u packet%s sent\n");
380
	p2(tcps_sndpack,tcps_sndbyte,
381
	    "\t\t%u data packet%s (%qd byte%s)\n");
382
	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
383
	    "\t\t%u data packet%s (%qd byte%s) retransmitted\n");
384
	p(tcps_sndrexmitfast, "\t\t%qd fast retransmitted packet%s\n");
385
	p2a(tcps_sndacks, tcps_delack,
386
	    "\t\t%u ack-only packet%s (%u delayed)\n");
387
	p(tcps_sndurg, "\t\t%u URG only packet%s\n");
388
	p(tcps_sndprobe, "\t\t%u window probe packet%s\n");
389
	p(tcps_sndwinup, "\t\t%u window update packet%s\n");
390
	p(tcps_sndctrl, "\t\t%u control packet%s\n");
391
	p(tcps_outswcsum, "\t\t%u packet%s software-checksummed\n");
392
	p(tcps_rcvtotal, "\t%u packet%s received\n");
393
	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%u ack%s (for %qd byte%s)\n");
394
	p(tcps_rcvdupack, "\t\t%u duplicate ack%s\n");
395
	p(tcps_rcvacktoomuch, "\t\t%u ack%s for unsent data\n");
396
	p(tcps_rcvacktooold, "\t\t%u ack%s for old data\n");
397
	p2(tcps_rcvpack, tcps_rcvbyte,
398
	    "\t\t%u packet%s (%qu byte%s) received in-sequence\n");
399
	p2(tcps_rcvduppack, tcps_rcvdupbyte,
400
	    "\t\t%u completely duplicate packet%s (%qd byte%s)\n");
401
	p(tcps_pawsdrop, "\t\t%u old duplicate packet%s\n");
402
	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
403
	    "\t\t%u packet%s with some duplicate data (%qd byte%s duplicated)\n");
404
	p2(tcps_rcvoopack, tcps_rcvoobyte,
405
	    "\t\t%u out-of-order packet%s (%qd byte%s)\n");
406
	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
407
	    "\t\t%u packet%s (%qd byte%s) of data after window\n");
408
	p(tcps_rcvwinprobe, "\t\t%u window probe%s\n");
409
	p(tcps_rcvwinupd, "\t\t%u window update packet%s\n");
410
	p(tcps_rcvafterclose, "\t\t%u packet%s received after close\n");
411
	p(tcps_rcvbadsum, "\t\t%u discarded for bad checksum%s\n");
412
	p(tcps_rcvbadoff, "\t\t%u discarded for bad header offset field%s\n");
413
	p1(tcps_rcvshort, "\t\t%u discarded because packet too short\n");
414
	p1(tcps_rcvnosec, "\t\t%u discarded for missing IPsec protection\n");
415
	p1(tcps_rcvmemdrop, "\t\t%u discarded due to memory shortage\n");
416
	p(tcps_inswcsum, "\t\t%u packet%s software-checksummed\n");
417
	p(tcps_rcvbadsig, "\t\t%u bad/missing md5 checksum%s\n");
418
	p(tcps_rcvgoodsig, "\t\t%qd good md5 checksum%s\n");
419
	p(tcps_connattempt, "\t%u connection request%s\n");
420
	p(tcps_accepts, "\t%u connection accept%s\n");
421
	p(tcps_connects, "\t%u connection%s established (including accepts)\n");
422
	p2(tcps_closed, tcps_drops,
423
	    "\t%u connection%s closed (including %u drop%s)\n");
424
	p(tcps_conndrained, "\t%qd connection%s drained\n");
425
	p(tcps_conndrops, "\t%u embryonic connection%s dropped\n");
426
	p2(tcps_rttupdated, tcps_segstimed,
427
	    "\t%u segment%s updated rtt (of %u attempt%s)\n");
428
	p(tcps_rexmttimeo, "\t%u retransmit timeout%s\n");
429
	p(tcps_timeoutdrop, "\t\t%u connection%s dropped by rexmit timeout\n");
430
	p(tcps_persisttimeo, "\t%u persist timeout%s\n");
431
	p(tcps_keeptimeo, "\t%u keepalive timeout%s\n");
432
	p(tcps_keepprobe, "\t\t%u keepalive probe%s sent\n");
433
	p(tcps_keepdrops, "\t\t%u connection%s dropped by keepalive\n");
434
	p(tcps_predack, "\t%u correct ACK header prediction%s\n");
435
	p(tcps_preddat, "\t%u correct data packet header prediction%s\n");
436
	pes(tcps_pcbhashmiss, "\t%u PCB cache miss%s\n");
437
	p1(tcps_noport, "\t%u dropped due to no socket\n");
438
439
	p(tcps_ecn_accepts, "\t%u ECN connection%s accepted\n");
440
	p(tcps_ecn_rcvece, "\t\t%u ECE packet%s received\n");
441
	p(tcps_ecn_rcvcwr, "\t\t%u CWR packet%s received\n");
442
	p(tcps_ecn_rcvce, "\t\t%u CE packet%s received\n");
443
	p(tcps_ecn_sndect, "\t\t%u ECT packet%s sent\n");
444
	p(tcps_ecn_sndece, "\t\t%u ECE packet%s sent\n");
445
	p(tcps_ecn_sndcwr, "\t\t%u CWR packet%s sent\n");
446
	p1(tcps_cwr_frecovery, "\t\t\tcwr by fastrecovery: %u\n");
447
	p1(tcps_cwr_timeout, "\t\t\tcwr by timeout: %u\n");
448
	p1(tcps_cwr_ecn, "\t\t\tcwr by ecn: %u\n");
449
450
	p(tcps_badsyn, "\t%u bad connection attempt%s\n");
451
	p(tcps_dropsyn, "\t%u SYN packet%s dropped due to queue or memory full\n");
452
	pys(tcps_sc_added, "\t%qd SYN cache entr%s added\n");
453
	p(tcps_sc_collisions, "\t\t%qd hash collision%s\n");
454
	p1(tcps_sc_completed, "\t\t%qd completed\n");
455
	p1(tcps_sc_aborted, "\t\t%qd aborted (no space to build PCB)\n");
456
	p1(tcps_sc_timed_out, "\t\t%qd timed out\n");
457
	p1(tcps_sc_overflowed, "\t\t%qd dropped due to overflow\n");
458
	p1(tcps_sc_bucketoverflow, "\t\t%qd dropped due to bucket overflow\n");
459
	p1(tcps_sc_reset, "\t\t%qd dropped due to RST\n");
460
	p1(tcps_sc_unreach, "\t\t%qd dropped due to ICMP unreachable\n");
461
	p(tcps_sc_retransmitted, "\t%qd SYN,ACK%s retransmitted\n");
462
	p(tcps_sc_dupesyn, "\t%qd duplicate SYN%s received for entries "
463
	    "already in the cache\n");
464
	p(tcps_sc_dropped, "\t%qd SYN%s dropped (no route or no space)\n");
465
	p(tcps_sc_seedrandom, "\t%qd SYN cache seed%s with new random\n");
466
	p1(tcps_sc_hash_size, "\t%qd hash bucket array size in current "
467
	    "SYN cache\n");
468
	p2bys(tcps_sc_entry_count, tcps_sc_entry_limit,
469
	    "\t%qd entr%s in current SYN cache, limit is %qd\n");
470
	p2b(tcps_sc_bucket_maxlen, tcps_sc_bucket_limit,
471
	    "\t%qd longest bucket length in current SYN cache, limit is %qd\n");
472
	p(tcps_sc_uses_left, "\t%qd use%s of current SYN cache left\n");
473
474
	p(tcps_sack_recovery_episode, "\t%qd SACK recovery episode%s\n");
475
	p(tcps_sack_rexmits,
476
		"\t\t%qd segment rexmit%s in SACK recovery episodes\n");
477
	p(tcps_sack_rexmit_bytes,
478
		"\t\t%qd byte rexmit%s in SACK recovery episodes\n");
479
	p(tcps_sack_rcv_opts,
480
		"\t%qd SACK option%s received\n");
481
	p(tcps_sack_snd_opts, "\t%qd SACK option%s sent\n");
482
483
#undef p
484
#undef p1
485
#undef p2
486
#undef p2a
487
#undef p2b
488
#undef p2bys
489
#undef pes
490
#undef pys
491
}
492
493
/*
494
 * Dump UDP statistics structure.
495
 */
496
void
497
udp_stats(char *name)
498
{
499
	struct udpstat udpstat;
500
	u_long delivered;
501
	int mib[] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS };
502
	size_t len = sizeof(udpstat);
503
504
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
505
	    &udpstat, &len, NULL, 0) == -1) {
506
		if (errno != ENOPROTOOPT)
507
			warn("%s", name);
508
		return;
509
	}
510
511
	printf("%s:\n", name);
512
#define	p(f, m) if (udpstat.f || sflag <= 1) \
513
	printf(m, udpstat.f, plural(udpstat.f))
514
#define	p1(f, m) if (udpstat.f || sflag <= 1) \
515
	printf(m, udpstat.f)
516
517
	p(udps_ipackets, "\t%lu datagram%s received\n");
518
	p1(udps_hdrops, "\t%lu with incomplete header\n");
519
	p1(udps_badlen, "\t%lu with bad data length field\n");
520
	p1(udps_badsum, "\t%lu with bad checksum\n");
521
	p1(udps_nosum, "\t%lu with no checksum\n");
522
	p(udps_inswcsum, "\t%lu input packet%s software-checksummed\n");
523
	p(udps_outswcsum, "\t%lu output packet%s software-checksummed\n");
524
	p1(udps_noport, "\t%lu dropped due to no socket\n");
525
	p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
526
	p1(udps_nosec, "\t%lu dropped due to missing IPsec protection\n");
527
	p1(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
528
	delivered = udpstat.udps_ipackets - udpstat.udps_hdrops -
529
	    udpstat.udps_badlen - udpstat.udps_badsum -
530
	    udpstat.udps_noport - udpstat.udps_noportbcast -
531
	    udpstat.udps_fullsock;
532
	if (delivered || sflag <= 1)
533
		printf("\t%lu delivered\n", delivered);
534
	p(udps_opackets, "\t%lu datagram%s output\n");
535
	p1(udps_pcbhashmiss, "\t%lu missed PCB cache\n");
536
#undef p
537
#undef p1
538
}
539
540
/*
541
 * Dump IP statistics structure.
542
 */
543
void
544
ip_stats(char *name)
545
{
546
	struct ipstat ipstat;
547
	int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS };
548
	size_t len = sizeof(ipstat);
549
550
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
551
	    &ipstat, &len, NULL, 0) == -1) {
552
		if (errno != ENOPROTOOPT)
553
			warn("%s", name);
554
		return;
555
	}
556
557
	printf("%s:\n", name);
558
#define	p(f, m) if (ipstat.f || sflag <= 1) \
559
	printf(m, ipstat.f, plural(ipstat.f))
560
#define	p1(f, m) if (ipstat.f || sflag <= 1) \
561
	printf(m, ipstat.f)
562
563
	p(ips_total, "\t%lu total packet%s received\n");
564
	p(ips_badsum, "\t%lu bad header checksum%s\n");
565
	p1(ips_toosmall, "\t%lu with size smaller than minimum\n");
566
	p1(ips_tooshort, "\t%lu with data size < data length\n");
567
	p1(ips_badhlen, "\t%lu with header length < data size\n");
568
	p1(ips_badlen, "\t%lu with data length < header length\n");
569
	p1(ips_badoptions, "\t%lu with bad options\n");
570
	p1(ips_badvers, "\t%lu with incorrect version number\n");
571
	p(ips_fragments, "\t%lu fragment%s received\n");
572
	p(ips_fragdropped, "\t%lu fragment%s dropped (duplicates or out of space)\n");
573
	p(ips_badfrags, "\t%lu malformed fragment%s dropped\n");
574
	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
575
	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
576
	p(ips_delivered, "\t%lu packet%s for this host\n");
577
	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
578
	p(ips_forward, "\t%lu packet%s forwarded\n");
579
	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
580
	p(ips_redirectsent, "\t%lu redirect%s sent\n");
581
	p(ips_localout, "\t%lu packet%s sent from this host\n");
582
	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
583
	p(ips_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n");
584
	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
585
	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
586
	p(ips_ofragments, "\t%lu fragment%s created\n");
587
	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
588
	p1(ips_rcvmemdrop, "\t%lu fragment floods\n");
589
	p(ips_toolong, "\t%lu packet%s with ip length > max ip packet size\n");
590
	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
591
	p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
592
	p(ips_inswcsum, "\t%lu input datagram%s software-checksummed\n");
593
	p(ips_outswcsum, "\t%lu output datagram%s software-checksummed\n");
594
	p(ips_notmember, "\t%lu multicast packet%s which we don't join\n");
595
#undef p
596
#undef p1
597
}
598
599
/*
600
 * Dump DIVERT statistics structure.
601
 */
602
void
603
div_stats(char *name)
604
{
605
	struct divstat divstat;
606
	int mib[] = { CTL_NET, PF_INET, IPPROTO_DIVERT, DIVERTCTL_STATS };
607
	size_t len = sizeof(divstat);
608
609
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
610
	    &divstat, &len, NULL, 0) == -1) {
611
		if (errno != ENOPROTOOPT)
612
			warn("%s", name);
613
		return;
614
	}
615
616
	printf("%s:\n", name);
617
#define	p(f, m) if (divstat.f || sflag <= 1) \
618
	printf(m, divstat.f, plural(divstat.f))
619
#define	p1(f, m) if (divstat.f || sflag <= 1) \
620
	printf(m, divstat.f)
621
	p(divs_ipackets, "\t%lu total packet%s received\n");
622
	p1(divs_noport, "\t%lu dropped due to no socket\n");
623
	p1(divs_fullsock, "\t%lu dropped due to full socket buffers\n");
624
	p(divs_opackets, "\t%lu packet%s output\n");
625
	p1(divs_errors, "\t%lu errors\n");
626
#undef p
627
#undef p1
628
}
629
630
static	char *icmpnames[ICMP_MAXTYPE + 1] = {
631
	"echo reply",
632
	"#1",
633
	"#2",
634
	"destination unreachable",
635
	"source quench",
636
	"routing redirect",
637
	"#6",
638
	"#7",
639
	"echo",
640
	"router advertisement",
641
	"router solicitation",
642
	"time exceeded",
643
	"parameter problem",
644
	"time stamp",
645
	"time stamp reply",
646
	"information request",
647
	"information request reply",
648
	"address mask request",
649
	"address mask reply",
650
	"#19",
651
	"#20",
652
	"#21",
653
	"#22",
654
	"#23",
655
	"#24",
656
	"#25",
657
	"#26",
658
	"#27",
659
	"#28",
660
	"#29",
661
	"traceroute",
662
	"data conversion error",
663
	"mobile host redirect",
664
	"IPv6 where-are-you",
665
	"IPv6 i-am-here",
666
	"mobile registration request",
667
	"mobile registration reply",
668
	"#37",
669
	"#38",
670
	"SKIP",
671
	"Photuris",
672
};
673
674
/*
675
 * Dump ICMP statistics.
676
 */
677
void
678
icmp_stats(char *name)
679
{
680
	struct icmpstat icmpstat;
681
	int i, first;
682
	int mib[] = { CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS };
683
	size_t len = sizeof(icmpstat);
684
685
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
686
	    &icmpstat, &len, NULL, 0) == -1) {
687
		if (errno != ENOPROTOOPT)
688
			warn("%s", name);
689
		return;
690
	}
691
692
	printf("%s:\n", name);
693
#define	p(f, m) if (icmpstat.f || sflag <= 1) \
694
	printf(m, icmpstat.f, plural(icmpstat.f))
695
696
	p(icps_error, "\t%lu call%s to icmp_error\n");
697
	p(icps_oldicmp,
698
	    "\t%lu error%s not generated because old message was icmp\n");
699
	p(icps_toofreq,
700
	    "\t%lu error%s not generated because of rate limitation\n");
701
702
	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
703
		if (icmpstat.icps_outhist[i] != 0) {
704
			if (first) {
705
				printf("\tOutput packet histogram:\n");
706
				first = 0;
707
			}
708
			if (icmpnames[i])
709
				printf("\t\t%s:", icmpnames[i]);
710
			else
711
				printf("\t\t#%d:", i);
712
			printf(" %lu\n", icmpstat.icps_outhist[i]);
713
		}
714
	p(icps_badcode, "\t%lu message%s with bad code fields\n");
715
	p(icps_tooshort, "\t%lu message%s < minimum length\n");
716
	p(icps_checksum, "\t%lu bad checksum%s\n");
717
	p(icps_badlen, "\t%lu message%s with bad length\n");
718
	p(icps_bmcastecho, "\t%lu echo request%s to broadcast/multicast "
719
	    "rejected\n");
720
	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
721
		if (icmpstat.icps_inhist[i] != 0) {
722
			if (first) {
723
				printf("\tInput packet histogram:\n");
724
				first = 0;
725
			}
726
			if (icmpnames[i])
727
				printf("\t\t%s:", icmpnames[i]);
728
			else
729
				printf("\t\t#%d:", i);
730
			printf(" %lu\n", icmpstat.icps_inhist[i]);
731
		}
732
	p(icps_reflect, "\t%lu message response%s generated\n");
733
#undef p
734
}
735
736
/*
737
 * Dump IGMP statistics structure.
738
 */
739
void
740
igmp_stats(char *name)
741
{
742
	struct igmpstat igmpstat;
743
	int mib[] = { CTL_NET, PF_INET, IPPROTO_IGMP, IGMPCTL_STATS };
744
	size_t len = sizeof(igmpstat);
745
746
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
747
	    &igmpstat, &len, NULL, 0) == -1) {
748
		if (errno != ENOPROTOOPT)
749
			warn("%s", name);
750
		return;
751
	}
752
753
	printf("%s:\n", name);
754
#define	p(f, m) if (igmpstat.f || sflag <= 1) \
755
	printf(m, igmpstat.f, plural(igmpstat.f))
756
#define	py(f, m) if (igmpstat.f || sflag <= 1) \
757
	printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
758
759
	p(igps_rcv_total, "\t%lu message%s received\n");
760
	p(igps_rcv_tooshort, "\t%lu message%s received with too few bytes\n");
761
	p(igps_rcv_badsum, "\t%lu message%s received with bad checksum\n");
762
	py(igps_rcv_queries, "\t%lu membership quer%s received\n");
763
	py(igps_rcv_badqueries, "\t%lu membership quer%s received with invalid field(s)\n");
764
	p(igps_rcv_reports, "\t%lu membership report%s received\n");
765
	p(igps_rcv_badreports, "\t%lu membership report%s received with invalid field(s)\n");
766
	p(igps_rcv_ourreports, "\t%lu membership report%s received for groups to which we belong\n");
767
	p(igps_snd_reports, "\t%lu membership report%s sent\n");
768
#undef p
769
#undef py
770
}
771
772
/*
773
 * Dump PIM statistics structure.
774
 */
775
void
776
pim_stats(char *name)
777
{
778
	struct pimstat pimstat;
779
	int mib[] = { CTL_NET, PF_INET, IPPROTO_PIM, PIMCTL_STATS };
780
	size_t len = sizeof(pimstat);
781
782
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
783
	    &pimstat, &len, NULL, 0) == -1) {
784
		if (errno != ENOPROTOOPT)
785
			warn("%s", name);
786
		return;
787
	}
788
789
	printf("%s:\n", name);
790
#define	p(f, m) if (pimstat.f || sflag <= 1) \
791
	printf(m, pimstat.f, plural(pimstat.f))
792
#define	py(f, m) if (pimstat.f || sflag <= 1) \
793
	printf(m, pimstat.f, pimstat.f != 1 ? "ies" : "y")
794
795
	p(pims_rcv_total_msgs, "\t%llu message%s received\n");
796
	p(pims_rcv_total_bytes, "\t%llu byte%s received\n");
797
	p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
798
	p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n");
799
	p(pims_rcv_badversion, "\t%llu message%s received with bad version\n");
800
	p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n");
801
	p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n");
802
	p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n");
803
	p(pims_rcv_badregisters, "\t%llu bad register%s received\n");
804
	p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n");
805
	p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n");
806
#undef p
807
#undef py
808
}
809
810
struct rpcnams {
811
	struct rpcnams *next;
812
	in_port_t port;
813
	int	  proto;
814
	char	*rpcname;
815
};
816
817
static char *
818
getrpcportnam(in_port_t port, int proto)
819
{
820
	struct sockaddr_in server_addr;
821
	struct hostent *hp;
822
	static struct pmaplist *head;
823
	int socket = RPC_ANYSOCK;
824
	struct timeval minutetimeout;
825
	CLIENT *client;
826
	struct rpcent *rpc;
827
	static int first;
828
	static struct rpcnams *rpcn;
829
	struct rpcnams *n;
830
	char num[20];
831
832
	if (first == 0) {
833
		first = 1;
834
		memset(&server_addr, 0, sizeof server_addr);
835
		server_addr.sin_family = AF_INET;
836
		if ((hp = gethostbyname("localhost")) != NULL)
837
			memmove((caddr_t)&server_addr.sin_addr, hp->h_addr,
838
			    hp->h_length);
839
		else
840
			(void) inet_aton("0.0.0.0", &server_addr.sin_addr);
841
842
		minutetimeout.tv_sec = 60;
843
		minutetimeout.tv_usec = 0;
844
		server_addr.sin_port = htons(PMAPPORT);
845
		if ((client = clnttcp_create(&server_addr, PMAPPROG,
846
		    PMAPVERS, &socket, 50, 500)) == NULL)
847
			return (NULL);
848
		if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
849
		    xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
850
			clnt_destroy(client);
851
			return (NULL);
852
		}
853
		for (; head != NULL; head = head->pml_next) {
854
			n = malloc(sizeof(struct rpcnams));
855
			if (n == NULL)
856
				continue;
857
			n->next = rpcn;
858
			rpcn = n;
859
			n->port = head->pml_map.pm_port;
860
			n->proto = head->pml_map.pm_prot;
861
862
			rpc = getrpcbynumber(head->pml_map.pm_prog);
863
			if (rpc)
864
				n->rpcname = strdup(rpc->r_name);
865
			else {
866
				snprintf(num, sizeof num, "%ld",
867
				    head->pml_map.pm_prog);
868
				n->rpcname = strdup(num);
869
			}
870
		}
871
		clnt_destroy(client);
872
	}
873
874
	for (n = rpcn; n; n = n->next)
875
		if (n->port == port && n->proto == proto)
876
			return (n->rpcname);
877
	return (NULL);
878
}
879
880
/*
881
 * Pretty print an Internet address (net address + port).
882
 * If the nflag was specified, use numbers instead of names.
883
 */
884
void
885
inetprint(struct in_addr *in, in_port_t port, const char *proto, int local)
886
{
887
	struct servent *sp = 0;
888
	char line[80], *cp, *nam;
889
	int width;
890
891
	snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16,
892
	    inetname(in));
893
	cp = strchr(line, '\0');
894
	if (!nflag && port)
895
		sp = getservbyport((int)port, proto);
896
	if (sp || port == 0)
897
		snprintf(cp, line + sizeof line - cp, "%.8s",
898
		    sp ? sp->s_name : "*");
899
	else if (local && !nflag && (nam = getrpcportnam(ntohs(port),
900
	    (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP))))
901
		snprintf(cp, line + sizeof line - cp, "%d[%.8s]",
902
		    ntohs(port), nam);
903
	else
904
		snprintf(cp, line + sizeof line - cp, "%d", ntohs(port));
905
	width = Aflag ? 18 : 22;
906
	printf(" %-*.*s", width, width, line);
907
}
908
909
/*
910
 * Construct an Internet address representation.
911
 * If the nflag has been supplied, give
912
 * numeric value, otherwise try for symbolic name.
913
 */
914
char *
915
inetname(struct in_addr *inp)
916
{
917
	char *cp;
918
	static char line[50];
919
	struct hostent *hp;
920
	static char domain[HOST_NAME_MAX+1];
921
	static int first = 1;
922
923
	if (first && !nflag) {
924
		first = 0;
925
		if (gethostname(domain, sizeof(domain)) == 0 &&
926
		    (cp = strchr(domain, '.')))
927
			(void) strlcpy(domain, cp + 1, sizeof domain);
928
		else
929
			domain[0] = '\0';
930
	}
931
	cp = NULL;
932
	if (!nflag && inp->s_addr != INADDR_ANY) {
933
		hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
934
		if (hp) {
935
			if ((cp = strchr(hp->h_name, '.')) &&
936
			    !strcmp(cp + 1, domain))
937
				*cp = '\0';
938
			cp = hp->h_name;
939
		}
940
	}
941
	if (inp->s_addr == INADDR_ANY)
942
		snprintf(line, sizeof line, "*");
943
	else if (cp)
944
		snprintf(line, sizeof line, "%s", cp);
945
	else {
946
		inp->s_addr = ntohl(inp->s_addr);
947
#define C(x)	((x) & 0xff)
948
		snprintf(line, sizeof line, "%u.%u.%u.%u",
949
		    C(inp->s_addr >> 24), C(inp->s_addr >> 16),
950
		    C(inp->s_addr >> 8), C(inp->s_addr));
951
	}
952
	return (line);
953
}
954
955
/*
956
 * Dump AH statistics structure.
957
 */
958
void
959
ah_stats(char *name)
960
{
961
	struct ahstat ahstat;
962
	int mib[] = { CTL_NET, PF_INET, IPPROTO_AH, AHCTL_STATS };
963
	size_t len = sizeof(ahstat);
964
965
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
966
	    &ahstat, &len, NULL, 0) == -1) {
967
		if (errno != ENOPROTOOPT)
968
			warn("%s", name);
969
		return;
970
	}
971
972
	printf("%s:\n", name);
973
#define p(f, m) if (ahstat.f || sflag <= 1) \
974
	printf(m, ahstat.f, plural(ahstat.f))
975
#define p1(f, m) if (ahstat.f || sflag <= 1) \
976
	printf(m, ahstat.f)
977
978
	p1(ahs_input, "\t%u input AH packets\n");
979
	p1(ahs_output, "\t%u output AH packets\n");
980
	p(ahs_nopf, "\t%u packet%s from unsupported protocol families\n");
981
	p(ahs_hdrops, "\t%u packet%s shorter than header shows\n");
982
	p(ahs_pdrops, "\t%u packet%s dropped due to policy\n");
983
	p(ahs_notdb, "\t%u packet%s for which no TDB was found\n");
984
	p(ahs_badkcr, "\t%u input packet%s that failed to be processed\n");
985
	p(ahs_badauth, "\t%u packet%s that failed verification received\n");
986
	p(ahs_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
987
	p(ahs_qfull, "\t%u packet%s were dropped due to full output queue\n");
988
	p(ahs_wrap, "\t%u packet%s where counter wrapping was detected\n");
989
	p(ahs_replay, "\t%u possibly replayed packet%s received\n");
990
	p(ahs_badauthl, "\t%u packet%s with bad authenticator length received\n");
991
	p(ahs_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
992
	p(ahs_toobig, "\t%u packet%s got larger than max IP packet size\n");
993
	p(ahs_crypto, "\t%u packet%s that failed crypto processing\n");
994
	p(ahs_ibytes, "\t%qu input byte%s\n");
995
	p(ahs_obytes, "\t%qu output byte%s\n");
996
997
#undef p
998
#undef p1
999
}
1000
1001
/*
1002
 * Dump etherip statistics structure.
1003
 */
1004
void
1005
etherip_stats(char *name)
1006
{
1007
	struct etheripstat etheripstat;
1008
	int mib[] = { CTL_NET, PF_INET, IPPROTO_ETHERIP, ETHERIPCTL_STATS };
1009
	size_t len = sizeof(etheripstat);
1010
1011
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1012
	    &etheripstat, &len, NULL, 0) == -1) {
1013
		if (errno != ENOPROTOOPT)
1014
			warn("%s", name);
1015
		return;
1016
	}
1017
1018
	printf("%s:\n", name);
1019
#define p(f, m) if (etheripstat.f || sflag <= 1) \
1020
	printf(m, etheripstat.f, plural(etheripstat.f))
1021
1022
	p(etherip_hdrops, "\t%u packet%s shorter than header shows\n");
1023
	p(etherip_qfull, "\t%u packet%s were dropped due to full output queue\n");
1024
	p(etherip_noifdrops, "\t%u packet%s were dropped because of no interface/bridge information\n");
1025
	p(etherip_pdrops, "\t%u packet%s dropped due to policy\n");
1026
	p(etherip_adrops, "\t%u packet%s dropped for other reasons\n");
1027
	p(etherip_ipackets, "\t%u input ethernet-in-IP packet%s\n");
1028
	p(etherip_opackets, "\t%u output ethernet-in-IP packet%s\n");
1029
	p(etherip_ibytes, "\t%qu input byte%s\n");
1030
	p(etherip_obytes, "\t%qu output byte%s\n");
1031
#undef p
1032
}
1033
1034
/*
1035
 * Dump ESP statistics structure.
1036
 */
1037
void
1038
esp_stats(char *name)
1039
{
1040
	struct espstat espstat;
1041
	int mib[] = { CTL_NET, PF_INET, IPPROTO_ESP, ESPCTL_STATS };
1042
	size_t len = sizeof(espstat);
1043
1044
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1045
	    &espstat, &len, NULL, 0) == -1) {
1046
		if (errno != ENOPROTOOPT)
1047
			warn("%s", name);
1048
		return;
1049
	}
1050
1051
	printf("%s:\n", name);
1052
#define p(f, m) if (espstat.f || sflag <= 1) \
1053
	printf(m, espstat.f, plural(espstat.f))
1054
1055
	p(esps_input, "\t%u input ESP packet%s\n");
1056
	p(esps_output, "\t%u output ESP packet%s\n");
1057
	p(esps_nopf, "\t%u packet%s from unsupported protocol families\n");
1058
	p(esps_hdrops, "\t%u packet%s shorter than header shows\n");
1059
	p(esps_pdrops, "\t%u packet%s dropped due to policy\n");
1060
	p(esps_notdb, "\t%u packet%s for which no TDB was found\n");
1061
	p(esps_badkcr, "\t%u input packet%s that failed to be processed\n");
1062
	p(esps_badenc, "\t%u packet%s with bad encryption received\n");
1063
	p(esps_badauth, "\t%u packet%s that failed verification received\n");
1064
	p(esps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
1065
	p(esps_qfull, "\t%u packet%s were dropped due to full output queue\n");
1066
	p(esps_wrap, "\t%u packet%s where counter wrapping was detected\n");
1067
	p(esps_replay, "\t%u possibly replayed packet%s received\n");
1068
	p(esps_badilen, "\t%u packet%s with bad payload size or padding received\n");
1069
	p(esps_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
1070
	p(esps_toobig, "\t%u packet%s got larger than max IP packet size\n");
1071
	p(esps_crypto, "\t%u packet%s that failed crypto processing\n");
1072
	p(esps_udpencin, "\t%u input UDP encapsulated ESP packet%s\n");
1073
	p(esps_udpencout, "\t%u output UDP encapsulated ESP packet%s\n");
1074
	p(esps_udpinval, "\t%u UDP packet%s for non-encapsulating TDB received\n");
1075
	p(esps_ibytes, "\t%qu input byte%s\n");
1076
	p(esps_obytes, "\t%qu output byte%s\n");
1077
1078
#undef p
1079
}
1080
1081
/*
1082
 * Dump IP-in-IP statistics structure.
1083
 */
1084
void
1085
ipip_stats(char *name)
1086
{
1087
	struct ipipstat ipipstat;
1088
	int mib[] = { CTL_NET, PF_INET, IPPROTO_IPIP, IPIPCTL_STATS };
1089
	size_t len = sizeof(ipipstat);
1090
1091
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1092
	    &ipipstat, &len, NULL, 0) == -1) {
1093
		if (errno != ENOPROTOOPT)
1094
			warn("%s", name);
1095
		return;
1096
	}
1097
1098
	printf("%s:\n", name);
1099
#define p(f, m) if (ipipstat.f || sflag <= 1) \
1100
	printf(m, ipipstat.f, plural(ipipstat.f))
1101
1102
	p(ipips_ipackets, "\t%u total input packet%s\n");
1103
	p(ipips_opackets, "\t%u total output packet%s\n");
1104
	p(ipips_hdrops, "\t%u packet%s shorter than header shows\n");
1105
	p(ipips_pdrops, "\t%u packet%s dropped due to policy\n");
1106
	p(ipips_spoof, "\t%u packet%s with possibly spoofed local addresses\n");
1107
	p(ipips_qfull, "\t%u packet%s were dropped due to full output queue\n");
1108
	p(ipips_ibytes, "\t%qu input byte%s\n");
1109
	p(ipips_obytes, "\t%qu output byte%s\n");
1110
	p(ipips_family, "\t%u protocol family mismatche%s\n");
1111
	p(ipips_unspec, "\t%u attempt%s to use tunnel with unspecified endpoint(s)\n");
1112
#undef p
1113
}
1114
1115
/*
1116
 * Dump CARP statistics structure.
1117
 */
1118
void
1119
carp_stats(char *name)
1120
{
1121
	struct carpstats carpstat;
1122
	int mib[] = { CTL_NET, PF_INET, IPPROTO_CARP, CARPCTL_STATS };
1123
	size_t len = sizeof(carpstat);
1124
1125
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1126
	    &carpstat, &len, NULL, 0) == -1) {
1127
		if (errno != ENOPROTOOPT)
1128
			warn("%s", name);
1129
		return;
1130
	}
1131
1132
	printf("%s:\n", name);
1133
#define p(f, m) if (carpstat.f || sflag <= 1) \
1134
	printf(m, carpstat.f, plural(carpstat.f))
1135
#define p2(f, m) if (carpstat.f || sflag <= 1) \
1136
	printf(m, carpstat.f)
1137
1138
	p(carps_ipackets, "\t%llu packet%s received (IPv4)\n");
1139
	p(carps_ipackets6, "\t%llu packet%s received (IPv6)\n");
1140
	p(carps_badif, "\t\t%llu packet%s discarded for bad interface\n");
1141
	p(carps_badttl, "\t\t%llu packet%s discarded for wrong TTL\n");
1142
	p(carps_hdrops, "\t\t%llu packet%s shorter than header\n");
1143
	p(carps_badsum, "\t\t%llu discarded for bad checksum%s\n");
1144
	p(carps_badver,	"\t\t%llu discarded packet%s with a bad version\n");
1145
	p2(carps_badlen, "\t\t%llu discarded because packet too short\n");
1146
	p2(carps_badauth, "\t\t%llu discarded for bad authentication\n");
1147
	p2(carps_badvhid, "\t\t%llu discarded for unknown vhid\n");
1148
	p2(carps_badaddrs, "\t\t%llu discarded because of a bad address list\n");
1149
	p(carps_opackets, "\t%llu packet%s sent (IPv4)\n");
1150
	p(carps_opackets6, "\t%llu packet%s sent (IPv6)\n");
1151
	p2(carps_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1152
	p(carps_preempt, "\t%llu transition%s to master\n");
1153
#undef p
1154
#undef p2
1155
}
1156
1157
/*
1158
 * Dump pfsync statistics structure.
1159
 */
1160
void
1161
pfsync_stats(char *name)
1162
{
1163
	struct pfsyncstats pfsyncstat;
1164
	int mib[] = { CTL_NET, PF_INET, IPPROTO_PFSYNC, PFSYNCCTL_STATS };
1165
	size_t len = sizeof(pfsyncstat);
1166
1167
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1168
	    &pfsyncstat, &len, NULL, 0) == -1) {
1169
		if (errno != ENOPROTOOPT)
1170
			warn("%s", name);
1171
		return;
1172
	}
1173
1174
	printf("%s:\n", name);
1175
#define p(f, m) if (pfsyncstat.f || sflag <= 1) \
1176
	printf(m, pfsyncstat.f, plural(pfsyncstat.f))
1177
#define p2(f, m) if (pfsyncstat.f || sflag <= 1) \
1178
	printf(m, pfsyncstat.f)
1179
1180
	p(pfsyncs_ipackets, "\t%llu packet%s received (IPv4)\n");
1181
	p(pfsyncs_ipackets6, "\t%llu packet%s received (IPv6)\n");
1182
	p(pfsyncs_badif, "\t\t%llu packet%s discarded for bad interface\n");
1183
	p(pfsyncs_badttl, "\t\t%llu packet%s discarded for bad ttl\n");
1184
	p(pfsyncs_hdrops, "\t\t%llu packet%s shorter than header\n");
1185
	p(pfsyncs_badver, "\t\t%llu packet%s discarded for bad version\n");
1186
	p(pfsyncs_badauth, "\t\t%llu packet%s discarded for bad HMAC\n");
1187
	p(pfsyncs_badact,"\t\t%llu packet%s discarded for bad action\n");
1188
	p(pfsyncs_badlen, "\t\t%llu packet%s discarded for short packet\n");
1189
	p(pfsyncs_badval, "\t\t%llu state%s discarded for bad values\n");
1190
	p(pfsyncs_stale, "\t\t%llu stale state%s\n");
1191
	p(pfsyncs_badstate, "\t\t%llu failed state lookup/insert%s\n");
1192
	p(pfsyncs_opackets, "\t%llu packet%s sent (IPv4)\n");
1193
	p(pfsyncs_opackets6, "\t%llu packet%s sent (IPv6)\n");
1194
	p2(pfsyncs_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1195
	p2(pfsyncs_oerrors, "\t\t%llu send error\n");
1196
#undef p
1197
#undef p2
1198
}
1199
1200
/*
1201
 * Dump pflow statistics structure.
1202
 */
1203
void
1204
pflow_stats(char *name)
1205
{
1206
	struct pflowstats flowstats;
1207
	int mib[] = { CTL_NET, PF_PFLOW, NET_PFLOW_STATS };
1208
	size_t len = sizeof(struct pflowstats);
1209
1210
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &flowstats, &len,
1211
	    NULL, 0) == -1) {
1212
		if (errno != ENOPROTOOPT)
1213
			warn("%s", name);
1214
		return;
1215
	}
1216
1217
	printf("%s:\n", name);
1218
#define p(f, m) if (flowstats.f || sflag <= 1) \
1219
	printf(m, flowstats.f, plural(flowstats.f))
1220
#define p2(f, m) if (flowstats.f || sflag <= 1) \
1221
	printf(m, flowstats.f)
1222
1223
	p(pflow_flows, "\t%llu flow%s sent\n");
1224
	p(pflow_packets, "\t%llu packet%s sent\n");
1225
	p2(pflow_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1226
	p2(pflow_oerrors, "\t\t%llu send error\n");
1227
#undef p
1228
#undef p2
1229
}
1230
1231
/*
1232
 * Dump IPCOMP statistics structure.
1233
 */
1234
void
1235
ipcomp_stats(char *name)
1236
{
1237
	struct ipcompstat ipcompstat;
1238
	int mib[] = { CTL_NET, PF_INET, IPPROTO_IPCOMP, IPCOMPCTL_STATS };
1239
	size_t len = sizeof(ipcompstat);
1240
1241
	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1242
	    &ipcompstat, &len, NULL, 0) == -1) {
1243
		if (errno != ENOPROTOOPT)
1244
			warn("%s", name);
1245
		return;
1246
	}
1247
1248
	printf("%s:\n", name);
1249
#define p(f, m) if (ipcompstat.f || sflag <= 1) \
1250
	printf(m, ipcompstat.f, plural(ipcompstat.f))
1251
1252
	p(ipcomps_input, "\t%u input IPCOMP packet%s\n");
1253
	p(ipcomps_output, "\t%u output IPCOMP packet%s\n");
1254
	p(ipcomps_nopf, "\t%u packet%s from unsupported protocol families\n");
1255
	p(ipcomps_hdrops, "\t%u packet%s shorter than header shows\n");
1256
	p(ipcomps_pdrops, "\t%u packet%s dropped due to policy\n");
1257
	p(ipcomps_notdb, "\t%u packet%s for which no TDB was found\n");
1258
	p(ipcomps_badkcr, "\t%u input packet%s that failed to be processed\n");
1259
	p(ipcomps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
1260
	p(ipcomps_qfull, "\t%u packet%s were dropped due to full output queue\n");
1261
	p(ipcomps_wrap, "\t%u packet%s where counter wrapping was detected\n");
1262
	p(ipcomps_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
1263
	p(ipcomps_toobig, "\t%u packet%s got larger than max IP packet size\n");
1264
	p(ipcomps_crypto, "\t%u packet%s that failed (de)compression processing\n");
1265
	p(ipcomps_minlen, "\t%u packet%s less than minimum compression length\n");
1266
	p(ipcomps_ibytes, "\t%qu input byte%s\n");
1267
	p(ipcomps_obytes, "\t%qu output byte%s\n");
1268
1269
#undef p
1270
}
1271
1272
/*
1273
 * Dump the contents of a socket structure
1274
 */
1275
void
1276
socket_dump(u_long off)
1277
{
1278
	struct socket so;
1279
1280
	if (off == 0)
1281
		return;
1282
	kread(off, &so, sizeof(so));
1283
1284
#define	p(fmt, v, sep) printf(#v " " fmt sep, so.v);
1285
#define	pp(fmt, v, sep) printf(#v " " fmt sep, so.v);
1286
	printf("socket %#lx\n ", off);
1287
	p("%#.4x", so_type, "\n ");
1288
	p("%#.4x", so_options, "\n ");
1289
	p("%d", so_linger, "\n ");
1290
	p("%#.4x", so_state, "\n ");
1291
	pp("%p", so_pcb, ", ");
1292
	pp("%p", so_proto, ", ");
1293
	pp("%p", so_head, "\n ");
1294
	p("%d", so_q0len, ", ");
1295
	p("%d", so_qlen, ", ");
1296
	p("%d", so_qlimit, "\n ");
1297
	p("%d", so_timeo, "\n ");
1298
	p("%u", so_error, "\n ");
1299
	p("%d", so_pgid, ", ");
1300
	p("%u", so_siguid, ", ");
1301
	p("%u", so_sigeuid, "\n ");
1302
	p("%lu", so_oobmark, "\n ");
1303
	if (so.so_sp)
1304
		sosplice_dump((u_long)so.so_sp);
1305
	sockbuf_dump(&so.so_rcv, "so_rcv");
1306
	sockbuf_dump(&so.so_snd, "so_snd");
1307
	p("%u", so_euid, ", ");
1308
	p("%u", so_ruid, ", ");
1309
	p("%u", so_egid, ", ");
1310
	p("%u", so_rgid, "\n ");
1311
	p("%d", so_cpid, "\n");
1312
#undef	p
1313
#undef	pp
1314
1315
	protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb);
1316
}
1317
1318
/*
1319
 * Dump the contents of a struct sosplice
1320
 */
1321
void
1322
sosplice_dump(u_long off)
1323
{
1324
	struct sosplice ssp;
1325
1326
	if (off == 0)
1327
		return;
1328
	kread(off, &ssp, sizeof(ssp));
1329
1330
#define	p(fmt, v, sep) printf(#v " " fmt sep, ssp.v);
1331
#define	pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v);
1332
#define	pp(fmt, v, sep) printf(#v " " fmt sep, ssp.v);
1333
	pp("%p", ssp_socket, ", ");
1334
	pp("%p", ssp_soback, "\n ");
1335
	p("%lld", ssp_len, ", ");
1336
	p("%lld", ssp_max, ", ");
1337
	pll("%lld", ssp_idletv.tv_sec, ", ");
1338
	p("%ld", ssp_idletv.tv_usec, "\n ");
1339
#undef	p
1340
#undef	pll
1341
#undef	pp
1342
}
1343
1344
/*
1345
 * Dump the contents of a socket buffer
1346
 */
1347
void
1348
sockbuf_dump(struct sockbuf *sb, const char *name)
1349
{
1350
#define	p(fmt, v, sep) printf(#v " " fmt sep, sb->v);
1351
	printf("%s ", name);
1352
	p("%lu", sb_cc, ", ");
1353
	p("%lu", sb_datacc, ", ");
1354
	p("%lu", sb_hiwat, ", ");
1355
	p("%lu", sb_wat, "\n ");
1356
	printf("%s ", name);
1357
	p("%lu", sb_mbcnt, ", ");
1358
	p("%lu", sb_mbmax, ", ");
1359
	p("%ld", sb_lowat, "\n ");
1360
	printf("%s ", name);
1361
	p("%#.8x", sb_flagsintr, ", ");
1362
	p("%#.4x", sb_flags, ", ");
1363
	p("%u", sb_timeo, "\n ");
1364
#undef	p
1365
}
1366
1367
/*
1368
 * Dump the contents of a protosw structure
1369
 */
1370
void
1371
protosw_dump(u_long off, u_long pcb)
1372
{
1373
	struct protosw proto;
1374
1375
	if (off == 0)
1376
		return;
1377
	kread(off, &proto, sizeof(proto));
1378
1379
#define	p(fmt, v, sep) printf(#v " " fmt sep, proto.v);
1380
#define	pp(fmt, v, sep) printf(#v " " fmt sep, proto.v);
1381
	printf("protosw %#lx\n ", off);
1382
	p("%#.4x", pr_type, "\n ");
1383
	pp("%p", pr_domain, "\n ");
1384
	p("%d", pr_protocol, "\n ");
1385
	p("%#.4x", pr_flags, "\n");
1386
#undef	p
1387
#undef	pp
1388
1389
	domain_dump((u_long)proto.pr_domain, pcb, proto.pr_protocol);
1390
}
1391
1392
/*
1393
 * Dump the contents of a domain structure
1394
 */
1395
void
1396
domain_dump(u_long off, u_long pcb, short protocol)
1397
{
1398
	struct domain dom;
1399
	char name[256];
1400
1401
	if (off == 0)
1402
		return;
1403
	kread(off, &dom, sizeof(dom));
1404
	kread((u_long)dom.dom_name, name, sizeof(name));
1405
1406
#define	p(fmt, v, sep) printf(#v " " fmt sep, dom.v);
1407
	printf("domain %#lx\n ", off);
1408
	p("%d", dom_family, "\n ");
1409
	printf("dom_name %.*s\n", (int)sizeof(name), name);
1410
#undef	p
1411
}
1412
1413
/*
1414
 * Dump the contents of a internet PCB
1415
 */
1416
void
1417
inpcb_dump(u_long off, short protocol, int af)
1418
{
1419
	struct inpcb inp;
1420
	char faddr[256], laddr[256];
1421
1422
	if (off == 0)
1423
		return;
1424
	kread(off, &inp, sizeof(inp));
1425
1426
	if (vflag)
1427
		socket_dump((u_long)inp.inp_socket);
1428
1429
	switch (af) {
1430
	case AF_INET:
1431
		inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr));
1432
		inet_ntop(af, &inp.inp_laddr, laddr, sizeof(laddr));
1433
		break;
1434
	case AF_INET6:
1435
		inet_ntop(af, &inp.inp_faddr6, faddr, sizeof(faddr));
1436
		inet_ntop(af, &inp.inp_laddr6, laddr, sizeof(laddr));
1437
		break;
1438
	default:
1439
		faddr[0] = laddr[0] = '\0';
1440
	}
1441
1442
#define	p(fmt, v, sep) printf(#v " " fmt sep, inp.v);
1443
#define	pp(fmt, v, sep) printf(#v " " fmt sep, inp.v);
1444
	printf("inpcb %#lx\n ", off);
1445
	pp("%p", inp_table, "\n ");
1446
	printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr);
1447
	HTONS(inp.inp_fport);
1448
	HTONS(inp.inp_lport);
1449
	p("%u", inp_fport, ", ");
1450
	p("%u", inp_lport, "\n ");
1451
	pp("%p", inp_socket, ", ");
1452
	pp("%p", inp_ppcb, "\n ");
1453
	p("%#.8x", inp_flags, "\n ");
1454
	p("%d", inp_hops, "\n ");
1455
	p("%u", inp_seclevel[0], ", ");
1456
	p("%u", inp_seclevel[1], ", ");
1457
	p("%u", inp_seclevel[2], ", ");
1458
	p("%u", inp_seclevel[3], "\n ");
1459
	p("%u", inp_ip_minttl, "\n ");
1460
	p("%d", inp_cksum6, "\n ");
1461
	pp("%p", inp_icmp6filt, "\n ");
1462
	pp("%p", inp_pf_sk, "\n ");
1463
	p("%u", inp_rtableid, "\n ");
1464
	p("%d", inp_pipex, "\n");
1465
#undef	p
1466
#undef	pp
1467
1468
	switch (protocol) {
1469
	case IPPROTO_TCP:
1470
		tcpcb_dump((u_long)inp.inp_ppcb);
1471
		break;
1472
	}
1473
}
1474
1475
/*
1476
 * Dump the contents of a TCP PCB
1477
 */
1478
void
1479
tcpcb_dump(u_long off)
1480
{
1481
	struct tcpcb tcpcb;
1482
1483
	if (off == 0)
1484
		return;
1485
	kread(off, (char *)&tcpcb, sizeof (tcpcb));
1486
1487
#define	p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
1488
#define	pp(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
1489
	printf("tcpcb %#lx\n ", off);
1490
	pp("%p", t_inpcb, "\n ");
1491
	p("%d", t_state, "");
1492
	if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES)
1493
		printf(" (%s)", tcpstates[tcpcb.t_state]);
1494
	printf("\n ");
1495
	p("%d", t_rxtshift, ", ");
1496
	p("%d", t_rxtcur, ", ");
1497
	p("%d", t_dupacks, "\n ");
1498
	p("%u", t_maxseg, ", ");
1499
	p("%u", t_maxopd, ", ");
1500
	p("%u", t_peermss, "\n ");
1501
	p("0x%x", t_flags, ", ");
1502
	p("%u", t_force, "\n ");
1503
	p("%u", iss, "\n ");
1504
	p("%u", snd_una, ", ");
1505
	p("%u", snd_nxt, ", ");
1506
	p("%u", snd_up, "\n ");
1507
	p("%u", snd_wl1, ", ");
1508
	p("%u", snd_wl2, ", ");
1509
	p("%lu", snd_wnd, "\n ");
1510
	p("%d", sack_enable, ", ");
1511
	p("%d", snd_numholes, ", ");
1512
	p("%u", snd_fack, ", ");
1513
	p("%lu",snd_awnd, "\n ");
1514
	p("%u", retran_data, ", ");
1515
	p("%u", snd_last, "\n ");
1516
	p("%u", irs, "\n ");
1517
	p("%u", rcv_nxt, ", ");
1518
	p("%u", rcv_up, ", ");
1519
	p("%lu", rcv_wnd, "\n ");
1520
	p("%u", rcv_lastsack, "\n ");
1521
	p("%d", rcv_numsacks, "\n ");
1522
	p("%u", rcv_adv, ", ");
1523
	p("%u", snd_max, "\n ");
1524
	p("%lu", snd_cwnd, ", ");
1525
	p("%lu", snd_ssthresh, ", ");
1526
	p("%lu", max_sndwnd, "\n ");
1527
	p("%u", t_rcvtime, ", ");
1528
	p("%u", t_rtttime, ", ");
1529
	p("%u", t_rtseq, "\n ");
1530
	p("%u", t_srtt, ", ");
1531
	p("%u", t_rttvar, ", ");
1532
	p("%u", t_rttmin, "\n ");
1533
	p("%u", t_oobflags, ", ");
1534
	p("%u", t_iobc, "\n ");
1535
	p("%u", t_softerror, "\n ");
1536
	p("%u", snd_scale, ", ");
1537
	p("%u", rcv_scale, ", ");
1538
	p("%u", request_r_scale, ", ");
1539
	p("%u", requested_s_scale, "\n ");
1540
	p("%u", ts_recent, ", ");
1541
	p("%u", ts_recent_age, "\n ");
1542
	p("%u", last_ack_sent, "\n ");
1543
	HTONS(tcpcb.t_pmtud_ip_len);
1544
	HTONS(tcpcb.t_pmtud_nextmtu);
1545
	p("%u", t_pmtud_mss_acked, ", ");
1546
	p("%u", t_pmtud_mtu_sent, "\n ");
1547
	p("%u", t_pmtud_nextmtu, ", ");
1548
	p("%u", t_pmtud_ip_len, ", ");
1549
	p("%u", t_pmtud_ip_hl, "\n ");
1550
	p("%u", t_pmtud_th_seq, "\n ");
1551
	p("%u", pf, "\n");
1552
#undef	p
1553
#undef	pp
1554
}