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