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