1 /* $OpenBSD: inet.c,v 1.176 2023/05/23 09:16:16 jan 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_inhwlro, "\t\t%u input LRO generated packet%s from hardware\n"); 443 p(tcps_inpktlro, "\t\t%u input LRO coalesced packet%s by hardware\n"); 444 p(tcps_inbadlro, "\t\t%u input bad LRO packet%s\n"); 445 p(tcps_connattempt, "\t%u connection request%s\n"); 446 p(tcps_accepts, "\t%u connection accept%s\n"); 447 p(tcps_connects, "\t%u connection%s established (including accepts)\n"); 448 p2(tcps_closed, tcps_drops, 449 "\t%u connection%s closed (including %u drop%s)\n"); 450 p(tcps_conndrained, "\t%llu connection%s drained\n"); 451 p(tcps_conndrops, "\t%u embryonic connection%s dropped\n"); 452 p2(tcps_rttupdated, tcps_segstimed, 453 "\t%u segment%s updated rtt (of %u attempt%s)\n"); 454 p(tcps_rexmttimeo, "\t%u retransmit timeout%s\n"); 455 p(tcps_timeoutdrop, "\t\t%u connection%s dropped by rexmit timeout\n"); 456 p(tcps_persisttimeo, "\t%u persist timeout%s\n"); 457 p(tcps_keeptimeo, "\t%u keepalive timeout%s\n"); 458 p(tcps_keepprobe, "\t\t%u keepalive probe%s sent\n"); 459 p(tcps_keepdrops, "\t\t%u connection%s dropped by keepalive\n"); 460 p(tcps_predack, "\t%u correct ACK header prediction%s\n"); 461 p(tcps_preddat, "\t%u correct data packet header prediction%s\n"); 462 pes(tcps_pcbhashmiss, "\t%u PCB cache miss%s\n"); 463 p1(tcps_noport, "\t%u dropped due to no socket\n"); 464 465 p(tcps_ecn_accepts, "\t%u ECN connection%s accepted\n"); 466 p(tcps_ecn_rcvece, "\t\t%u ECE packet%s received\n"); 467 p(tcps_ecn_rcvcwr, "\t\t%u CWR packet%s received\n"); 468 p(tcps_ecn_rcvce, "\t\t%u CE packet%s received\n"); 469 p(tcps_ecn_sndect, "\t\t%u ECT packet%s sent\n"); 470 p(tcps_ecn_sndece, "\t\t%u ECE packet%s sent\n"); 471 p(tcps_ecn_sndcwr, "\t\t%u CWR packet%s sent\n"); 472 p1(tcps_cwr_frecovery, "\t\t\tcwr by fastrecovery: %u\n"); 473 p1(tcps_cwr_timeout, "\t\t\tcwr by timeout: %u\n"); 474 p1(tcps_cwr_ecn, "\t\t\tcwr by ecn: %u\n"); 475 476 p(tcps_badsyn, "\t%u bad connection attempt%s\n"); 477 p(tcps_dropsyn, "\t%u SYN packet%s dropped due to queue or memory full\n"); 478 pys(tcps_sc_added, "\t%llu SYN cache entr%s added\n"); 479 p(tcps_sc_collisions, "\t\t%llu hash collision%s\n"); 480 p1(tcps_sc_completed, "\t\t%llu completed\n"); 481 p1(tcps_sc_aborted, "\t\t%llu aborted (no space to build PCB)\n"); 482 p1(tcps_sc_timed_out, "\t\t%llu timed out\n"); 483 p1(tcps_sc_overflowed, "\t\t%llu dropped due to overflow\n"); 484 p1(tcps_sc_bucketoverflow, "\t\t%llu dropped due to bucket overflow\n"); 485 p1(tcps_sc_reset, "\t\t%llu dropped due to RST\n"); 486 p1(tcps_sc_unreach, "\t\t%llu dropped due to ICMP unreachable\n"); 487 p(tcps_sc_retransmitted, "\t%llu SYN,ACK%s retransmitted\n"); 488 p(tcps_sc_dupesyn, "\t%llu duplicate SYN%s received for entries " 489 "already in the cache\n"); 490 p(tcps_sc_dropped, "\t%llu SYN%s dropped (no route or no space)\n"); 491 p(tcps_sc_seedrandom, "\t%llu SYN cache seed%s with new random\n"); 492 p1(tcps_sc_hash_size, "\t%llu hash bucket array size in current " 493 "SYN cache\n"); 494 p2bys(tcps_sc_entry_count, tcps_sc_entry_limit, 495 "\t%llu entr%s in current SYN cache, limit is %llu\n"); 496 p2b(tcps_sc_bucket_maxlen, tcps_sc_bucket_limit, 497 "\t%llu longest bucket length in current SYN cache, limit is %llu\n"); 498 p(tcps_sc_uses_left, "\t%llu use%s of current SYN cache left\n"); 499 500 p(tcps_sack_recovery_episode, "\t%llu SACK recovery episode%s\n"); 501 p(tcps_sack_rexmits, 502 "\t\t%llu segment rexmit%s in SACK recovery episodes\n"); 503 p(tcps_sack_rexmit_bytes, 504 "\t\t%llu byte rexmit%s in SACK recovery episodes\n"); 505 p(tcps_sack_rcv_opts, "\t%llu SACK option%s received\n"); 506 p(tcps_sack_snd_opts, "\t%llu SACK option%s sent\n"); 507 p(tcps_sack_drop_opts, "\t%llu SACK option%s dropped\n"); 508 509 #undef p 510 #undef p1 511 #undef p2 512 #undef p2a 513 #undef p2b 514 #undef p2bys 515 #undef pes 516 #undef pys 517 } 518 519 /* 520 * Dump UDP statistics structure. 521 */ 522 void 523 udp_stats(char *name) 524 { 525 struct udpstat udpstat; 526 u_long delivered; 527 int mib[] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS }; 528 size_t len = sizeof(udpstat); 529 530 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 531 &udpstat, &len, NULL, 0) == -1) { 532 if (errno != ENOPROTOOPT) 533 warn("%s", name); 534 return; 535 } 536 537 printf("%s:\n", name); 538 #define p(f, m) if (udpstat.f || sflag <= 1) \ 539 printf(m, udpstat.f, plural(udpstat.f)) 540 #define p1(f, m) if (udpstat.f || sflag <= 1) \ 541 printf(m, udpstat.f) 542 543 p(udps_ipackets, "\t%lu datagram%s received\n"); 544 p1(udps_hdrops, "\t%lu with incomplete header\n"); 545 p1(udps_badlen, "\t%lu with bad data length field\n"); 546 p1(udps_badsum, "\t%lu with bad checksum\n"); 547 p1(udps_nosum, "\t%lu with no checksum\n"); 548 p(udps_inswcsum, "\t%lu input packet%s software-checksummed\n"); 549 p(udps_outswcsum, "\t%lu output packet%s software-checksummed\n"); 550 p1(udps_noport, "\t%lu dropped due to no socket\n"); 551 p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n"); 552 p1(udps_nosec, "\t%lu dropped due to missing IPsec protection\n"); 553 p1(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); 554 delivered = udpstat.udps_ipackets - udpstat.udps_hdrops - 555 udpstat.udps_badlen - udpstat.udps_badsum - 556 udpstat.udps_noport - udpstat.udps_noportbcast - 557 udpstat.udps_fullsock; 558 if (delivered || sflag <= 1) 559 printf("\t%lu delivered\n", delivered); 560 p(udps_opackets, "\t%lu datagram%s output\n"); 561 p1(udps_pcbhashmiss, "\t%lu missed PCB cache\n"); 562 #undef p 563 #undef p1 564 } 565 566 /* 567 * Dump IP statistics structure. 568 */ 569 void 570 ip_stats(char *name) 571 { 572 struct ipstat ipstat; 573 int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS }; 574 size_t len = sizeof(ipstat); 575 576 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 577 &ipstat, &len, NULL, 0) == -1) { 578 if (errno != ENOPROTOOPT) 579 warn("%s", name); 580 return; 581 } 582 583 printf("%s:\n", name); 584 #define p(f, m) if (ipstat.f || sflag <= 1) \ 585 printf(m, ipstat.f, plural(ipstat.f)) 586 #define p1(f, m) if (ipstat.f || sflag <= 1) \ 587 printf(m, ipstat.f) 588 589 p(ips_total, "\t%lu total packet%s received\n"); 590 p(ips_badsum, "\t%lu bad header checksum%s\n"); 591 p1(ips_toosmall, "\t%lu with size smaller than minimum\n"); 592 p1(ips_tooshort, "\t%lu with data size < data length\n"); 593 p1(ips_badhlen, "\t%lu with header length < data size\n"); 594 p1(ips_badlen, "\t%lu with data length < header length\n"); 595 p1(ips_badoptions, "\t%lu with bad options\n"); 596 p1(ips_badvers, "\t%lu with incorrect version number\n"); 597 p(ips_fragments, "\t%lu fragment%s received\n"); 598 p(ips_fragdropped, "\t%lu fragment%s dropped (duplicates or out of space)\n"); 599 p(ips_badfrags, "\t%lu malformed fragment%s dropped\n"); 600 p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 601 p(ips_reassembled, "\t%lu packet%s reassembled ok\n"); 602 p(ips_delivered, "\t%lu packet%s for this host\n"); 603 p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n"); 604 p(ips_forward, "\t%lu packet%s forwarded\n"); 605 p(ips_cantforward, "\t%lu packet%s not forwardable\n"); 606 p(ips_redirectsent, "\t%lu redirect%s sent\n"); 607 p(ips_localout, "\t%lu packet%s sent from this host\n"); 608 p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 609 p(ips_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n"); 610 p(ips_noroute, "\t%lu output packet%s discarded due to no route\n"); 611 p(ips_fragmented, "\t%lu output datagram%s fragmented\n"); 612 p(ips_ofragments, "\t%lu fragment%s created\n"); 613 p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 614 p1(ips_rcvmemdrop, "\t%lu fragment floods\n"); 615 p(ips_toolong, "\t%lu packet%s with ip length > max ip packet size\n"); 616 p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n"); 617 p(ips_badaddr, "\t%lu datagram%s with bad address in header\n"); 618 p(ips_inswcsum, "\t%lu input datagram%s software-checksummed\n"); 619 p(ips_outswcsum, "\t%lu output datagram%s software-checksummed\n"); 620 p(ips_notmember, "\t%lu multicast packet%s which we don't join\n"); 621 p(ips_wrongif, "\t%lu packet%s received on wrong interface\n"); 622 p(ips_idropped, "\t%lu input packet%s dropped due to no bufs, etc.\n"); 623 #undef p 624 #undef p1 625 } 626 627 /* 628 * Dump DIVERT statistics structure. 629 */ 630 void 631 div_stats(char *name) 632 { 633 struct divstat divstat; 634 int mib[] = { CTL_NET, PF_INET, IPPROTO_DIVERT, DIVERTCTL_STATS }; 635 size_t len = sizeof(divstat); 636 637 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 638 &divstat, &len, NULL, 0) == -1) { 639 if (errno != ENOPROTOOPT) 640 warn("%s", name); 641 return; 642 } 643 644 printf("%s:\n", name); 645 #define p(f, m) if (divstat.f || sflag <= 1) \ 646 printf(m, divstat.f, plural(divstat.f)) 647 #define p1(f, m) if (divstat.f || sflag <= 1) \ 648 printf(m, divstat.f) 649 p(divs_ipackets, "\t%lu total packet%s received\n"); 650 p1(divs_noport, "\t%lu dropped due to no socket\n"); 651 p1(divs_fullsock, "\t%lu dropped due to full socket buffers\n"); 652 p(divs_opackets, "\t%lu packet%s output\n"); 653 p1(divs_errors, "\t%lu errors\n"); 654 #undef p 655 #undef p1 656 } 657 658 static char *icmpnames[ICMP_MAXTYPE + 1] = { 659 "echo reply", 660 "#1", 661 "#2", 662 "destination unreachable", 663 "source quench", 664 "routing redirect", 665 "#6", 666 "#7", 667 "echo", 668 "router advertisement", 669 "router solicitation", 670 "time exceeded", 671 "parameter problem", 672 "time stamp", 673 "time stamp reply", 674 "information request", 675 "information request reply", 676 "address mask request", 677 "address mask reply", 678 "#19", 679 "#20", 680 "#21", 681 "#22", 682 "#23", 683 "#24", 684 "#25", 685 "#26", 686 "#27", 687 "#28", 688 "#29", 689 "traceroute", 690 "data conversion error", 691 "mobile host redirect", 692 "IPv6 where-are-you", 693 "IPv6 i-am-here", 694 "mobile registration request", 695 "mobile registration reply", 696 "#37", 697 "#38", 698 "SKIP", 699 "Photuris", 700 }; 701 702 /* 703 * Dump ICMP statistics. 704 */ 705 void 706 icmp_stats(char *name) 707 { 708 struct icmpstat icmpstat; 709 int i, first; 710 int mib[] = { CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS }; 711 size_t len = sizeof(icmpstat); 712 713 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 714 &icmpstat, &len, NULL, 0) == -1) { 715 if (errno != ENOPROTOOPT) 716 warn("%s", name); 717 return; 718 } 719 720 printf("%s:\n", name); 721 #define p(f, m) if (icmpstat.f || sflag <= 1) \ 722 printf(m, icmpstat.f, plural(icmpstat.f)) 723 724 p(icps_error, "\t%lu call%s to icmp_error\n"); 725 p(icps_oldicmp, 726 "\t%lu error%s not generated because old message was icmp\n"); 727 p(icps_toofreq, 728 "\t%lu error%s not generated because of rate limitation\n"); 729 730 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 731 if (icmpstat.icps_outhist[i] != 0) { 732 if (first) { 733 printf("\tOutput packet histogram:\n"); 734 first = 0; 735 } 736 if (icmpnames[i]) 737 printf("\t\t%s:", icmpnames[i]); 738 else 739 printf("\t\t#%d:", i); 740 printf(" %lu\n", icmpstat.icps_outhist[i]); 741 } 742 p(icps_badcode, "\t%lu message%s with bad code fields\n"); 743 p(icps_tooshort, "\t%lu message%s < minimum length\n"); 744 p(icps_checksum, "\t%lu bad checksum%s\n"); 745 p(icps_badlen, "\t%lu message%s with bad length\n"); 746 p(icps_bmcastecho, "\t%lu echo request%s to broadcast/multicast " 747 "rejected\n"); 748 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 749 if (icmpstat.icps_inhist[i] != 0) { 750 if (first) { 751 printf("\tInput packet histogram:\n"); 752 first = 0; 753 } 754 if (icmpnames[i]) 755 printf("\t\t%s:", icmpnames[i]); 756 else 757 printf("\t\t#%d:", i); 758 printf(" %lu\n", icmpstat.icps_inhist[i]); 759 } 760 p(icps_reflect, "\t%lu message response%s generated\n"); 761 #undef p 762 } 763 764 /* 765 * Dump IGMP statistics structure. 766 */ 767 void 768 igmp_stats(char *name) 769 { 770 struct igmpstat igmpstat; 771 int mib[] = { CTL_NET, PF_INET, IPPROTO_IGMP, IGMPCTL_STATS }; 772 size_t len = sizeof(igmpstat); 773 774 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 775 &igmpstat, &len, NULL, 0) == -1) { 776 if (errno != ENOPROTOOPT) 777 warn("%s", name); 778 return; 779 } 780 781 printf("%s:\n", name); 782 #define p(f, m) if (igmpstat.f || sflag <= 1) \ 783 printf(m, igmpstat.f, plural(igmpstat.f)) 784 #define py(f, m) if (igmpstat.f || sflag <= 1) \ 785 printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 786 787 p(igps_rcv_total, "\t%lu message%s received\n"); 788 p(igps_rcv_tooshort, "\t%lu message%s received with too few bytes\n"); 789 p(igps_rcv_badsum, "\t%lu message%s received with bad checksum\n"); 790 py(igps_rcv_queries, "\t%lu membership quer%s received\n"); 791 py(igps_rcv_badqueries, "\t%lu membership quer%s received with invalid field(s)\n"); 792 p(igps_rcv_reports, "\t%lu membership report%s received\n"); 793 p(igps_rcv_badreports, "\t%lu membership report%s received with invalid field(s)\n"); 794 p(igps_rcv_ourreports, "\t%lu membership report%s received for groups to which we belong\n"); 795 p(igps_snd_reports, "\t%lu membership report%s sent\n"); 796 #undef p 797 #undef py 798 } 799 800 struct rpcnams { 801 struct rpcnams *next; 802 in_port_t port; 803 int proto; 804 char *rpcname; 805 }; 806 807 static char * 808 getrpcportnam(in_port_t port, int proto) 809 { 810 struct sockaddr_in server_addr; 811 struct hostent *hp; 812 static struct pmaplist *head; 813 int socket = RPC_ANYSOCK; 814 struct timeval minutetimeout; 815 CLIENT *client; 816 struct rpcent *rpc; 817 static int first; 818 static struct rpcnams *rpcn; 819 struct rpcnams *n; 820 char num[20]; 821 822 if (first == 0) { 823 first = 1; 824 memset(&server_addr, 0, sizeof server_addr); 825 server_addr.sin_family = AF_INET; 826 if ((hp = gethostbyname("localhost")) != NULL) 827 memmove((caddr_t)&server_addr.sin_addr, hp->h_addr, 828 hp->h_length); 829 else 830 (void) inet_aton("0.0.0.0", &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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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, &((struct sockaddr_in *) 1460 (&inp.inp_route.ro_dst))->sin_addr, raddr, 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_route6.ro_dst.sin6_addr, 1466 raddr, 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[0], ", "); 1488 p("%u", inp_seclevel[1], ", "); 1489 p("%u", inp_seclevel[2], ", "); 1490 p("%u", inp_seclevel[3], "\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 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("%u", t_rcvtime, ", "); 1557 p("%u", 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("%u", 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