GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/netstat/inet.c Lines: 0 813 0.0 %
Date: 2017-11-13 Branches: 0 858 0.0 %

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