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