1 /* $OpenBSD: inet.c,v 1.182 2024/04/17 20:48:51 bluhm Exp $ */ 2 /* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/queue.h> 34 #include <sys/socket.h> 35 #include <sys/socketvar.h> 36 #include <sys/domain.h> 37 #include <sys/protosw.h> 38 #include <sys/sysctl.h> 39 #define _KERNEL 40 #include <sys/file.h> 41 #undef _KERNEL 42 43 #include <net/route.h> 44 #include <netinet/in.h> 45 #include <netinet/ip.h> 46 #include <netinet/in_pcb.h> 47 #include <netinet/ip_icmp.h> 48 #include <netinet/icmp_var.h> 49 #include <netinet/igmp_var.h> 50 #include <netinet/ip_var.h> 51 #include <netinet/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 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 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 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 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 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 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 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 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 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 * 813 getrpcportnam(in_port_t port, int proto) 814 { 815 struct sockaddr_in server_addr; 816 struct hostent *hp; 817 static struct pmaplist *head; 818 int socket = RPC_ANYSOCK; 819 struct timeval minutetimeout; 820 CLIENT *client; 821 struct rpcent *rpc; 822 static int first; 823 static struct rpcnams *rpcn; 824 struct rpcnams *n; 825 char num[20]; 826 827 if (first == 0) { 828 first = 1; 829 memset(&server_addr, 0, sizeof server_addr); 830 server_addr.sin_family = AF_INET; 831 if ((hp = gethostbyname("localhost")) != NULL) 832 memmove((caddr_t)&server_addr.sin_addr, hp->h_addr, 833 hp->h_length); 834 else 835 (void) inet_aton("0.0.0.0", &server_addr.sin_addr); 836 837 minutetimeout.tv_sec = 60; 838 minutetimeout.tv_usec = 0; 839 server_addr.sin_port = htons(PMAPPORT); 840 if ((client = clnttcp_create(&server_addr, PMAPPROG, 841 PMAPVERS, &socket, 50, 500)) == NULL) 842 return (NULL); 843 if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL, 844 xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { 845 clnt_destroy(client); 846 return (NULL); 847 } 848 for (; head != NULL; head = head->pml_next) { 849 n = malloc(sizeof(struct rpcnams)); 850 if (n == NULL) 851 continue; 852 n->next = rpcn; 853 rpcn = n; 854 n->port = head->pml_map.pm_port; 855 n->proto = head->pml_map.pm_prot; 856 857 rpc = getrpcbynumber(head->pml_map.pm_prog); 858 if (rpc) 859 n->rpcname = strdup(rpc->r_name); 860 else { 861 snprintf(num, sizeof num, "%ld", 862 head->pml_map.pm_prog); 863 n->rpcname = strdup(num); 864 } 865 } 866 clnt_destroy(client); 867 } 868 869 for (n = rpcn; n; n = n->next) 870 if (n->port == port && n->proto == proto) 871 return (n->rpcname); 872 return (NULL); 873 } 874 875 /* 876 * Pretty print an Internet address (net address + port). 877 * If the nflag was specified, use numbers instead of names. 878 */ 879 void 880 inetprint(struct in_addr *in, in_port_t port, const char *proto, int local) 881 { 882 struct servent *sp = 0; 883 char line[80], *cp, *nam; 884 int width; 885 886 snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16, 887 inetname(in)); 888 cp = strchr(line, '\0'); 889 if (!nflag && port) 890 sp = getservbyport((int)port, proto); 891 if (sp || port == 0) 892 snprintf(cp, line + sizeof line - cp, "%.8s", 893 sp ? sp->s_name : "*"); 894 else if (local && !nflag && (nam = getrpcportnam(ntohs(port), 895 (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP)))) 896 snprintf(cp, line + sizeof line - cp, "%d[%.8s]", 897 ntohs(port), nam); 898 else 899 snprintf(cp, line + sizeof line - cp, "%d", ntohs(port)); 900 width = Aflag ? 18 : 22; 901 printf(" %-*.*s", width, width, line); 902 } 903 904 /* 905 * Construct an Internet address representation. 906 * If the nflag has been supplied, give 907 * numeric value, otherwise try for symbolic name. 908 */ 909 char * 910 inetname(struct in_addr *inp) 911 { 912 char *cp; 913 static char line[50]; 914 struct hostent *hp; 915 static char domain[HOST_NAME_MAX+1]; 916 static int first = 1; 917 918 if (first && !nflag) { 919 first = 0; 920 if (gethostname(domain, sizeof(domain)) == 0 && 921 (cp = strchr(domain, '.'))) 922 (void) strlcpy(domain, cp + 1, sizeof domain); 923 else 924 domain[0] = '\0'; 925 } 926 cp = NULL; 927 if (!nflag && inp->s_addr != INADDR_ANY) { 928 hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 929 if (hp) { 930 if ((cp = strchr(hp->h_name, '.')) && 931 !strcmp(cp + 1, domain)) 932 *cp = '\0'; 933 cp = hp->h_name; 934 } 935 } 936 if (inp->s_addr == INADDR_ANY) 937 snprintf(line, sizeof line, "*"); 938 else if (cp) 939 snprintf(line, sizeof line, "%s", cp); 940 else { 941 inp->s_addr = ntohl(inp->s_addr); 942 #define C(x) ((x) & 0xff) 943 snprintf(line, sizeof line, "%u.%u.%u.%u", 944 C(inp->s_addr >> 24), C(inp->s_addr >> 16), 945 C(inp->s_addr >> 8), C(inp->s_addr)); 946 } 947 return (line); 948 } 949 950 /* 951 * Dump AH statistics structure. 952 */ 953 void 954 ah_stats(char *name) 955 { 956 struct ahstat ahstat; 957 int mib[] = { CTL_NET, PF_INET, IPPROTO_AH, AHCTL_STATS }; 958 size_t len = sizeof(ahstat); 959 960 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 961 &ahstat, &len, NULL, 0) == -1) { 962 if (errno != ENOPROTOOPT) 963 warn("%s", name); 964 return; 965 } 966 967 printf("%s:\n", name); 968 #define p(f, m) if (ahstat.f || sflag <= 1) \ 969 printf(m, ahstat.f, plural(ahstat.f)) 970 #define p1(f, m) if (ahstat.f || sflag <= 1) \ 971 printf(m, ahstat.f) 972 973 p1(ahs_input, "\t%llu input AH packets\n"); 974 p1(ahs_output, "\t%llu output AH packets\n"); 975 p(ahs_nopf, "\t%llu packet%s from unsupported protocol families\n"); 976 p(ahs_hdrops, "\t%llu packet%s shorter than header shows\n"); 977 p(ahs_pdrops, "\t%llu packet%s dropped due to policy\n"); 978 p(ahs_notdb, "\t%llu packet%s for which no TDB was found\n"); 979 p(ahs_badkcr, "\t%llu input packet%s that failed to be processed\n"); 980 p(ahs_badauth, "\t%llu packet%s that failed verification received\n"); 981 p(ahs_noxform, "\t%llu packet%s for which no XFORM was set in TDB received\n"); 982 p(ahs_qfull, "\t%llu packet%s were dropped due to full output queue\n"); 983 p(ahs_wrap, "\t%llu packet%s where counter wrapping was detected\n"); 984 p(ahs_replay, "\t%llu possibly replayed packet%s received\n"); 985 p(ahs_badauthl, "\t%llu packet%s with bad authenticator length received\n"); 986 p(ahs_invalid, "\t%llu packet%s attempted to use an invalid TDB\n"); 987 p(ahs_toobig, "\t%llu packet%s got larger than max IP packet size\n"); 988 p(ahs_crypto, "\t%llu packet%s that failed crypto processing\n"); 989 p(ahs_outfail, "\t%llu output packet%s could not be sent\n"); 990 p(ahs_ibytes, "\t%llu input byte%s\n"); 991 p(ahs_obytes, "\t%llu output byte%s\n"); 992 993 #undef p 994 #undef p1 995 } 996 997 /* 998 * Dump etherip statistics structure. 999 */ 1000 void 1001 etherip_stats(char *name) 1002 { 1003 struct etheripstat etheripstat; 1004 int mib[] = { CTL_NET, PF_INET, IPPROTO_ETHERIP, ETHERIPCTL_STATS }; 1005 size_t len = sizeof(etheripstat); 1006 1007 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1008 ðeripstat, &len, NULL, 0) == -1) { 1009 if (errno != ENOPROTOOPT) 1010 warn("%s", name); 1011 return; 1012 } 1013 1014 printf("%s:\n", name); 1015 #define p(f, m) if (etheripstat.f || sflag <= 1) \ 1016 printf(m, etheripstat.f, plural(etheripstat.f)) 1017 1018 p(etherips_hdrops, "\t%llu packet%s shorter than header shows\n"); 1019 p(etherips_qfull, "\t%llu packet%s were dropped due to full output queue\n"); 1020 p(etherips_noifdrops, "\t%llu packet%s were dropped because of no interface/bridge information\n"); 1021 p(etherips_pdrops, "\t%llu packet%s dropped due to policy\n"); 1022 p(etherips_adrops, "\t%llu packet%s dropped for other reasons\n"); 1023 p(etherips_ipackets, "\t%llu input ethernet-in-IP packet%s\n"); 1024 p(etherips_opackets, "\t%llu output ethernet-in-IP packet%s\n"); 1025 p(etherips_ibytes, "\t%llu input byte%s\n"); 1026 p(etherips_obytes, "\t%llu output byte%s\n"); 1027 #undef p 1028 } 1029 1030 /* 1031 * Dump IPsec statistics structure. 1032 */ 1033 void 1034 ipsec_stats(char *name) 1035 { 1036 struct ipsecstat ipsecstat; 1037 int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_IPSEC_STATS }; 1038 size_t len = sizeof(ipsecstat); 1039 1040 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1041 &ipsecstat, &len, NULL, 0) == -1) { 1042 if (errno != ENOPROTOOPT) 1043 warn("%s", name); 1044 return; 1045 } 1046 1047 printf("%s:\n", name); 1048 #define p(f, m) if (ipsecstat.f || sflag <= 1) \ 1049 printf(m, ipsecstat.f, plural(ipsecstat.f)) 1050 p(ipsec_ipackets, "\t%llu input IPsec packet%s\n"); 1051 p(ipsec_opackets, "\t%llu output IPsec packet%s\n"); 1052 p(ipsec_ibytes, "\t%llu input byte%s\n"); 1053 p(ipsec_obytes, "\t%llu output byte%s\n"); 1054 p(ipsec_idecompbytes, "\t%llu input byte%s, decompressed\n"); 1055 p(ipsec_ouncompbytes, "\t%llu output byte%s, uncompressed\n"); 1056 p(ipsec_idrops, "\t%llu packet%s dropped on input\n"); 1057 p(ipsec_odrops, "\t%llu packet%s dropped on output\n"); 1058 p(ipsec_crypto, "\t%llu packet%s that failed crypto processing\n"); 1059 p(ipsec_noxform, "\t%llu packet%s for which no XFORM was set in TDB received\n"); 1060 p(ipsec_notdb, "\t%llu packet%s for which no TDB was found\n"); 1061 p(ipsec_exctdb, "\t%llu TDB%s with hardlimit excess\n"); 1062 #undef p 1063 } 1064 1065 /* 1066 * Dump ESP statistics structure. 1067 */ 1068 void 1069 esp_stats(char *name) 1070 { 1071 struct espstat espstat; 1072 int mib[] = { CTL_NET, PF_INET, IPPROTO_ESP, ESPCTL_STATS }; 1073 size_t len = sizeof(espstat); 1074 1075 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1076 &espstat, &len, NULL, 0) == -1) { 1077 if (errno != ENOPROTOOPT) 1078 warn("%s", name); 1079 return; 1080 } 1081 1082 printf("%s:\n", name); 1083 #define p(f, m) if (espstat.f || sflag <= 1) \ 1084 printf(m, espstat.f, plural(espstat.f)) 1085 1086 p(esps_input, "\t%llu input ESP packet%s\n"); 1087 p(esps_output, "\t%llu output ESP packet%s\n"); 1088 p(esps_nopf, "\t%llu packet%s from unsupported protocol families\n"); 1089 p(esps_hdrops, "\t%llu packet%s shorter than header shows\n"); 1090 p(esps_pdrops, "\t%llu packet%s dropped due to policy\n"); 1091 p(esps_notdb, "\t%llu packet%s for which no TDB was found\n"); 1092 p(esps_badkcr, "\t%llu input packet%s that failed to be processed\n"); 1093 p(esps_badenc, "\t%llu packet%s with bad encryption received\n"); 1094 p(esps_badauth, "\t%llu packet%s that failed verification received\n"); 1095 p(esps_noxform, "\t%llu packet%s for which no XFORM was set in TDB received\n"); 1096 p(esps_qfull, "\t%llu packet%s were dropped due to full output queue\n"); 1097 p(esps_wrap, "\t%llu packet%s where counter wrapping was detected\n"); 1098 p(esps_replay, "\t%llu possibly replayed packet%s received\n"); 1099 p(esps_badilen, "\t%llu packet%s with bad payload size or padding received\n"); 1100 p(esps_invalid, "\t%llu packet%s attempted to use an invalid TDB\n"); 1101 p(esps_toobig, "\t%llu packet%s got larger than max IP packet size\n"); 1102 p(esps_crypto, "\t%llu packet%s that failed crypto processing\n"); 1103 p(esps_outfail, "\t%llu output packet%s could not be sent\n"); 1104 p(esps_udpencin, "\t%llu input UDP encapsulated ESP packet%s\n"); 1105 p(esps_udpencout, "\t%llu output UDP encapsulated ESP packet%s\n"); 1106 p(esps_udpinval, "\t%llu UDP packet%s for non-encapsulating TDB received\n"); 1107 p(esps_udpneeded, "\t%llu raw ESP packet%s for encapsulating TDB received\n"); 1108 p(esps_ibytes, "\t%llu input byte%s\n"); 1109 p(esps_obytes, "\t%llu output byte%s\n"); 1110 1111 #undef p 1112 } 1113 1114 /* 1115 * Dump IP-in-IP statistics structure. 1116 */ 1117 void 1118 ipip_stats(char *name) 1119 { 1120 struct ipipstat ipipstat; 1121 int mib[] = { CTL_NET, PF_INET, IPPROTO_IPIP, IPIPCTL_STATS }; 1122 size_t len = sizeof(ipipstat); 1123 1124 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1125 &ipipstat, &len, NULL, 0) == -1) { 1126 if (errno != ENOPROTOOPT) 1127 warn("%s", name); 1128 return; 1129 } 1130 1131 printf("%s:\n", name); 1132 #define p(f, m) if (ipipstat.f || sflag <= 1) \ 1133 printf(m, ipipstat.f, plural(ipipstat.f)) 1134 1135 p(ipips_ipackets, "\t%llu total input packet%s\n"); 1136 p(ipips_opackets, "\t%llu total output packet%s\n"); 1137 p(ipips_hdrops, "\t%llu packet%s shorter than header shows\n"); 1138 p(ipips_pdrops, "\t%llu packet%s dropped due to policy\n"); 1139 p(ipips_spoof, "\t%llu packet%s with possibly spoofed local addresses\n"); 1140 p(ipips_qfull, "\t%llu packet%s were dropped due to full output queue\n"); 1141 p(ipips_ibytes, "\t%llu input byte%s\n"); 1142 p(ipips_obytes, "\t%llu output byte%s\n"); 1143 p(ipips_family, "\t%llu protocol family mismatche%s\n"); 1144 p(ipips_unspec, "\t%llu attempt%s to use tunnel with unspecified endpoint(s)\n"); 1145 #undef p 1146 } 1147 1148 /* 1149 * Dump CARP statistics structure. 1150 */ 1151 void 1152 carp_stats(char *name) 1153 { 1154 struct carpstats carpstat; 1155 int mib[] = { CTL_NET, PF_INET, IPPROTO_CARP, CARPCTL_STATS }; 1156 size_t len = sizeof(carpstat); 1157 1158 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1159 &carpstat, &len, NULL, 0) == -1) { 1160 if (errno != ENOPROTOOPT) 1161 warn("%s", name); 1162 return; 1163 } 1164 1165 printf("%s:\n", name); 1166 #define p(f, m) if (carpstat.f || sflag <= 1) \ 1167 printf(m, carpstat.f, plural(carpstat.f)) 1168 #define p2(f, m) if (carpstat.f || sflag <= 1) \ 1169 printf(m, carpstat.f) 1170 1171 p(carps_ipackets, "\t%llu packet%s received (IPv4)\n"); 1172 p(carps_ipackets6, "\t%llu packet%s received (IPv6)\n"); 1173 p(carps_badif, "\t\t%llu packet%s discarded for bad interface\n"); 1174 p(carps_badttl, "\t\t%llu packet%s discarded for wrong TTL\n"); 1175 p(carps_hdrops, "\t\t%llu packet%s shorter than header\n"); 1176 p(carps_badsum, "\t\t%llu discarded for bad checksum%s\n"); 1177 p(carps_badver, "\t\t%llu discarded packet%s with a bad version\n"); 1178 p2(carps_badlen, "\t\t%llu discarded because packet too short\n"); 1179 p2(carps_badauth, "\t\t%llu discarded for bad authentication\n"); 1180 p2(carps_badvhid, "\t\t%llu discarded for unknown vhid\n"); 1181 p2(carps_badaddrs, "\t\t%llu discarded because of a bad address list\n"); 1182 p(carps_opackets, "\t%llu packet%s sent (IPv4)\n"); 1183 p(carps_opackets6, "\t%llu packet%s sent (IPv6)\n"); 1184 p2(carps_onomem, "\t\t%llu send failed due to mbuf memory error\n"); 1185 p(carps_preempt, "\t%llu transition%s to master\n"); 1186 #undef p 1187 #undef p2 1188 } 1189 1190 /* 1191 * Dump pfsync statistics structure. 1192 */ 1193 void 1194 pfsync_stats(char *name) 1195 { 1196 struct pfsyncstats pfsyncstat; 1197 int mib[] = { CTL_NET, PF_INET, IPPROTO_PFSYNC, PFSYNCCTL_STATS }; 1198 size_t len = sizeof(pfsyncstat); 1199 1200 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1201 &pfsyncstat, &len, NULL, 0) == -1) { 1202 if (errno != ENOPROTOOPT) 1203 warn("%s", name); 1204 return; 1205 } 1206 1207 printf("%s:\n", name); 1208 #define p(f, m) if (pfsyncstat.f || sflag <= 1) \ 1209 printf(m, pfsyncstat.f, plural(pfsyncstat.f)) 1210 #define p2(f, m) if (pfsyncstat.f || sflag <= 1) \ 1211 printf(m, pfsyncstat.f) 1212 1213 p(pfsyncs_ipackets, "\t%llu packet%s received (IPv4)\n"); 1214 p(pfsyncs_ipackets6, "\t%llu packet%s received (IPv6)\n"); 1215 p(pfsyncs_badif, "\t\t%llu packet%s discarded for bad interface\n"); 1216 p(pfsyncs_badttl, "\t\t%llu packet%s discarded for bad ttl\n"); 1217 p(pfsyncs_hdrops, "\t\t%llu packet%s shorter than header\n"); 1218 p(pfsyncs_badver, "\t\t%llu packet%s discarded for bad version\n"); 1219 p(pfsyncs_badauth, "\t\t%llu packet%s discarded for bad HMAC\n"); 1220 p(pfsyncs_badact,"\t\t%llu packet%s discarded for bad action\n"); 1221 p(pfsyncs_badlen, "\t\t%llu packet%s discarded for short packet\n"); 1222 p(pfsyncs_badval, "\t\t%llu state%s discarded for bad values\n"); 1223 p(pfsyncs_stale, "\t\t%llu stale state%s\n"); 1224 p(pfsyncs_badstate, "\t\t%llu failed state lookup/insert%s\n"); 1225 p(pfsyncs_opackets, "\t%llu packet%s sent (IPv4)\n"); 1226 p(pfsyncs_opackets6, "\t%llu packet%s sent (IPv6)\n"); 1227 p2(pfsyncs_onomem, "\t\t%llu send failed due to mbuf memory error\n"); 1228 p2(pfsyncs_oerrors, "\t\t%llu send error\n"); 1229 #undef p 1230 #undef p2 1231 } 1232 1233 /* 1234 * Dump pflow statistics structure. 1235 */ 1236 void 1237 pflow_stats(char *name) 1238 { 1239 struct pflowstats flowstats; 1240 int mib[] = { CTL_NET, PF_PFLOW, NET_PFLOW_STATS }; 1241 size_t len = sizeof(struct pflowstats); 1242 1243 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &flowstats, &len, 1244 NULL, 0) == -1) { 1245 if (errno != ENOPROTOOPT) 1246 warn("%s", name); 1247 return; 1248 } 1249 1250 printf("%s:\n", name); 1251 #define p(f, m) if (flowstats.f || sflag <= 1) \ 1252 printf(m, flowstats.f, plural(flowstats.f)) 1253 #define p2(f, m) if (flowstats.f || sflag <= 1) \ 1254 printf(m, flowstats.f) 1255 1256 p(pflow_flows, "\t%llu flow%s sent\n"); 1257 p(pflow_packets, "\t%llu packet%s sent\n"); 1258 p2(pflow_onomem, "\t\t%llu send failed due to mbuf memory error\n"); 1259 p2(pflow_oerrors, "\t\t%llu send error\n"); 1260 #undef p 1261 #undef p2 1262 } 1263 1264 /* 1265 * Dump IPCOMP statistics structure. 1266 */ 1267 void 1268 ipcomp_stats(char *name) 1269 { 1270 struct ipcompstat ipcompstat; 1271 int mib[] = { CTL_NET, PF_INET, IPPROTO_IPCOMP, IPCOMPCTL_STATS }; 1272 size_t len = sizeof(ipcompstat); 1273 1274 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1275 &ipcompstat, &len, NULL, 0) == -1) { 1276 if (errno != ENOPROTOOPT) 1277 warn("%s", name); 1278 return; 1279 } 1280 1281 printf("%s:\n", name); 1282 #define p(f, m) if (ipcompstat.f || sflag <= 1) \ 1283 printf(m, ipcompstat.f, plural(ipcompstat.f)) 1284 1285 p(ipcomps_input, "\t%llu input IPCOMP packet%s\n"); 1286 p(ipcomps_output, "\t%llu output IPCOMP packet%s\n"); 1287 p(ipcomps_nopf, "\t%llu packet%s from unsupported protocol families\n"); 1288 p(ipcomps_hdrops, "\t%llu packet%s shorter than header shows\n"); 1289 p(ipcomps_pdrops, "\t%llu packet%s dropped due to policy\n"); 1290 p(ipcomps_notdb, "\t%llu packet%s for which no TDB was found\n"); 1291 p(ipcomps_badkcr, "\t%llu input packet%s that failed to be processed\n"); 1292 p(ipcomps_noxform, "\t%llu packet%s for which no XFORM was set in TDB received\n"); 1293 p(ipcomps_qfull, "\t%llu packet%s were dropped due to full output queue\n"); 1294 p(ipcomps_wrap, "\t%llu packet%s where counter wrapping was detected\n"); 1295 p(ipcomps_invalid, "\t%llu packet%s attempted to use an invalid TDB\n"); 1296 p(ipcomps_toobig, "\t%llu packet%s got larger than max IP packet size\n"); 1297 p(ipcomps_crypto, "\t%llu packet%s that failed (de)compression processing\n"); 1298 p(ipcomps_outfail, "\t%llu output packet%s could not be sent\n"); 1299 p(ipcomps_minlen, "\t%llu packet%s less than minimum compression length\n"); 1300 p(ipcomps_ibytes, "\t%llu input byte%s\n"); 1301 p(ipcomps_obytes, "\t%llu output byte%s\n"); 1302 1303 #undef p 1304 } 1305 1306 /* 1307 * Dump the contents of a socket structure 1308 */ 1309 void 1310 socket_dump(u_long off) 1311 { 1312 struct socket so; 1313 1314 if (off == 0) 1315 return; 1316 kread(off, &so, sizeof(so)); 1317 1318 #define p(fmt, v, sep) printf(#v " " fmt sep, so.v); 1319 #define pp(fmt, v, sep) printf(#v " " fmt sep, so.v); 1320 printf("socket %#lx\n ", off); 1321 p("%#.4x", so_type, "\n "); 1322 p("%#.4x", so_options, "\n "); 1323 p("%d", so_linger, "\n "); 1324 p("%#.4x", so_state, "\n "); 1325 pp("%p", so_pcb, ", "); 1326 pp("%p", so_proto, ", "); 1327 pp("%p", so_head, "\n "); 1328 p("%d", so_q0len, ", "); 1329 p("%d", so_qlen, ", "); 1330 p("%d", so_qlimit, "\n "); 1331 p("%d", so_timeo, "\n "); 1332 p("%u", so_error, "\n "); 1333 p("%p", so_sigio.sir_sigio, "\n "); 1334 p("%lu", so_oobmark, "\n "); 1335 if (so.so_sp) 1336 sosplice_dump((u_long)so.so_sp); 1337 sockbuf_dump(&so.so_rcv, "so_rcv"); 1338 sockbuf_dump(&so.so_snd, "so_snd"); 1339 p("%u", so_euid, ", "); 1340 p("%u", so_ruid, ", "); 1341 p("%u", so_egid, ", "); 1342 p("%u", so_rgid, "\n "); 1343 p("%d", so_cpid, "\n"); 1344 #undef p 1345 #undef pp 1346 1347 protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb); 1348 } 1349 1350 /* 1351 * Dump the contents of a struct sosplice 1352 */ 1353 void 1354 sosplice_dump(u_long off) 1355 { 1356 struct sosplice ssp; 1357 1358 if (off == 0) 1359 return; 1360 kread(off, &ssp, sizeof(ssp)); 1361 1362 #define p(fmt, v, sep) printf(#v " " fmt sep, ssp.v); 1363 #define pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v); 1364 #define pp(fmt, v, sep) printf(#v " " fmt sep, ssp.v); 1365 pp("%p", ssp_socket, ", "); 1366 pp("%p", ssp_soback, "\n "); 1367 p("%lld", ssp_len, ", "); 1368 p("%lld", ssp_max, ", "); 1369 pll("%lld", ssp_idletv.tv_sec, ", "); 1370 p("%ld", ssp_idletv.tv_usec, "\n "); 1371 #undef p 1372 #undef pll 1373 #undef pp 1374 } 1375 1376 /* 1377 * Dump the contents of a socket buffer 1378 */ 1379 void 1380 sockbuf_dump(struct sockbuf *sb, const char *name) 1381 { 1382 #define p(fmt, v, sep) printf(#v " " fmt sep, sb->v); 1383 printf("%s ", name); 1384 p("%lu", sb_cc, ", "); 1385 p("%lu", sb_datacc, ", "); 1386 p("%lu", sb_hiwat, ", "); 1387 p("%lu", sb_wat, "\n "); 1388 printf("%s ", name); 1389 p("%lu", sb_mbcnt, ", "); 1390 p("%lu", sb_mbmax, ", "); 1391 p("%ld", sb_lowat, "\n "); 1392 printf("%s ", name); 1393 p("%#.4x", sb_flags, ", "); 1394 p("%llu", sb_timeo_nsecs, "\n "); 1395 #undef p 1396 } 1397 1398 /* 1399 * Dump the contents of a protosw structure 1400 */ 1401 void 1402 protosw_dump(u_long off, u_long pcb) 1403 { 1404 struct protosw proto; 1405 1406 if (off == 0) 1407 return; 1408 kread(off, &proto, sizeof(proto)); 1409 1410 #define p(fmt, v, sep) printf(#v " " fmt sep, proto.v); 1411 #define pp(fmt, v, sep) printf(#v " " fmt sep, proto.v); 1412 printf("protosw %#lx\n ", off); 1413 p("%#.4x", pr_type, "\n "); 1414 pp("%p", pr_domain, "\n "); 1415 p("%d", pr_protocol, "\n "); 1416 p("%#.4x", pr_flags, "\n"); 1417 #undef p 1418 #undef pp 1419 1420 domain_dump((u_long)proto.pr_domain, pcb, proto.pr_protocol); 1421 } 1422 1423 /* 1424 * Dump the contents of a domain structure 1425 */ 1426 void 1427 domain_dump(u_long off, u_long pcb, short protocol) 1428 { 1429 struct domain dom; 1430 char name[256]; 1431 1432 if (off == 0) 1433 return; 1434 kread(off, &dom, sizeof(dom)); 1435 kread((u_long)dom.dom_name, name, sizeof(name)); 1436 1437 #define p(fmt, v, sep) printf(#v " " fmt sep, dom.v); 1438 printf("domain %#lx\n ", off); 1439 p("%d", dom_family, "\n "); 1440 printf("dom_name %.*s\n", (int)sizeof(name), name); 1441 #undef p 1442 } 1443 1444 /* 1445 * Dump the contents of a internet PCB 1446 */ 1447 void 1448 inpcb_dump(u_long off, short protocol, int af) 1449 { 1450 struct inpcb inp; 1451 char faddr[256], laddr[256], raddr[256]; 1452 1453 if (off == 0) 1454 return; 1455 kread(off, &inp, sizeof(inp)); 1456 1457 if (vflag) 1458 socket_dump((u_long)inp.inp_socket); 1459 1460 switch (af) { 1461 case AF_INET: 1462 inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr)); 1463 inet_ntop(af, &inp.inp_laddr, laddr, sizeof(laddr)); 1464 inet_ntop(af, &inp.inp_route.ro_dstsin.sin_addr, raddr, 1465 sizeof(raddr)); 1466 break; 1467 case AF_INET6: 1468 inet_ntop(af, &inp.inp_faddr6, faddr, sizeof(faddr)); 1469 inet_ntop(af, &inp.inp_laddr6, laddr, sizeof(laddr)); 1470 inet_ntop(af, &inp.inp_route.ro_dstsin6.sin6_addr, raddr, 1471 sizeof(raddr)); 1472 break; 1473 default: 1474 faddr[0] = laddr[0] = '\0'; 1475 } 1476 1477 #define p(fmt, v, sep) printf(#v " " fmt sep, inp.v); 1478 #define pp(fmt, v, sep) printf(#v " " fmt sep, inp.v); 1479 printf("inpcb %#lx\n ", off); 1480 pp("%p", inp_table, "\n "); 1481 printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr); 1482 HTONS(inp.inp_fport); 1483 HTONS(inp.inp_lport); 1484 p("%u", inp_fport, ", "); 1485 p("%u", inp_lport, "\n "); 1486 pp("%p", inp_socket, ", "); 1487 pp("%p", inp_ppcb, "\n "); 1488 pp("%p", inp_route.ro_rt, ", "); 1489 printf("ro_dst %s\n ", raddr); 1490 p("%#.8x", inp_flags, "\n "); 1491 p("%d", inp_hops, "\n "); 1492 p("%u", inp_seclevel.sl_auth, ", "); 1493 p("%u", inp_seclevel.sl_esp_trans, ", "); 1494 p("%u", inp_seclevel.sl_esp_network, ", "); 1495 p("%u", inp_seclevel.sl_ipcomp, "\n "); 1496 p("%u", inp_ip_minttl, "\n "); 1497 p("%d", inp_cksum6, "\n "); 1498 pp("%p", inp_icmp6filt, "\n "); 1499 pp("%p", inp_pf_sk, "\n "); 1500 p("%u", inp_rtableid, "\n "); 1501 p("%d", inp_pipex, "\n"); 1502 #undef p 1503 #undef pp 1504 1505 switch (protocol) { 1506 case IPPROTO_TCP: 1507 tcpcb_dump((u_long)inp.inp_ppcb); 1508 break; 1509 } 1510 } 1511 1512 /* 1513 * Dump the contents of a TCP PCB 1514 */ 1515 void 1516 tcpcb_dump(u_long off) 1517 { 1518 struct tcpcb tcpcb; 1519 1520 if (off == 0) 1521 return; 1522 kread(off, (char *)&tcpcb, sizeof (tcpcb)); 1523 1524 #define p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v); 1525 #define pp(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v); 1526 printf("tcpcb %#lx\n ", off); 1527 pp("%p", t_inpcb, "\n "); 1528 p("%d", t_state, ""); 1529 if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES) 1530 printf(" (%s)", tcpstates[tcpcb.t_state]); 1531 printf("\n "); 1532 p("%d", t_rxtshift, ", "); 1533 p("%d", t_rxtcur, ", "); 1534 p("%d", t_dupacks, "\n "); 1535 p("%u", t_maxseg, ", "); 1536 p("%u", t_maxopd, ", "); 1537 p("%u", t_peermss, "\n "); 1538 p("0x%x", t_flags, ", "); 1539 p("%u", t_force, "\n "); 1540 p("%u", iss, "\n "); 1541 p("%u", snd_una, ", "); 1542 p("%u", snd_nxt, ", "); 1543 p("%u", snd_up, "\n "); 1544 p("%u", snd_wl1, ", "); 1545 p("%u", snd_wl2, ", "); 1546 p("%lu", snd_wnd, "\n "); 1547 p("%d", sack_enable, ", "); 1548 p("%d", snd_numholes, ", "); 1549 p("%u", snd_last, "\n "); 1550 p("%u", irs, "\n "); 1551 p("%u", rcv_nxt, ", "); 1552 p("%u", rcv_up, ", "); 1553 p("%lu", rcv_wnd, "\n "); 1554 p("%u", rcv_lastsack, "\n "); 1555 p("%d", rcv_numsacks, "\n "); 1556 p("%u", rcv_adv, ", "); 1557 p("%u", snd_max, "\n "); 1558 p("%lu", snd_cwnd, ", "); 1559 p("%lu", snd_ssthresh, ", "); 1560 p("%lu", max_sndwnd, "\n "); 1561 p("%llu", t_rcvtime, ", "); 1562 p("%llu", t_rtttime, ", "); 1563 p("%u", t_rtseq, "\n "); 1564 p("%u", t_srtt, ", "); 1565 p("%u", t_rttvar, ", "); 1566 p("%u", t_rttmin, "\n "); 1567 p("%u", t_oobflags, ", "); 1568 p("%u", t_iobc, "\n "); 1569 p("%u", t_softerror, "\n "); 1570 p("%u", snd_scale, ", "); 1571 p("%u", rcv_scale, ", "); 1572 p("%u", request_r_scale, ", "); 1573 p("%u", requested_s_scale, "\n "); 1574 p("%u", ts_recent, ", "); 1575 p("%llu", ts_recent_age, "\n "); 1576 p("%u", last_ack_sent, "\n "); 1577 HTONS(tcpcb.t_pmtud_ip_len); 1578 HTONS(tcpcb.t_pmtud_nextmtu); 1579 p("%u", t_pmtud_mss_acked, ", "); 1580 p("%u", t_pmtud_mtu_sent, "\n "); 1581 p("%u", t_pmtud_nextmtu, ", "); 1582 p("%u", t_pmtud_ip_len, ", "); 1583 p("%u", t_pmtud_ip_hl, "\n "); 1584 p("%u", t_pmtud_th_seq, "\n "); 1585 p("%u", pf, "\n"); 1586 #undef p 1587 #undef pp 1588 } 1589