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