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