1 /* $OpenBSD: inet.c,v 1.151 2016/09/02 09:39:32 vgross 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/pim_var.h> 53 #include <netinet/tcp.h> 54 #include <netinet/tcp_seq.h> 55 #define TCPSTATES 56 #include <netinet/tcp_fsm.h> 57 #include <netinet/tcp_timer.h> 58 #include <netinet/tcp_var.h> 59 #include <netinet/udp.h> 60 #include <netinet/udp_var.h> 61 #include <netinet/ip_ipsp.h> 62 #include <netinet/ip_ah.h> 63 #include <netinet/ip_esp.h> 64 #include <netinet/ip_ipip.h> 65 #include <netinet/ip_ipcomp.h> 66 #include <netinet/ip_ether.h> 67 #include <netinet/ip_carp.h> 68 #include <netinet/ip_divert.h> 69 #include <net/if.h> 70 #include <net/pfvar.h> 71 #include <net/if_pfsync.h> 72 #include <net/if_pflow.h> 73 74 #include <rpc/rpc.h> 75 #include <rpc/pmap_prot.h> 76 #include <rpc/pmap_clnt.h> 77 78 #include <arpa/inet.h> 79 #include <err.h> 80 #include <limits.h> 81 #include <netdb.h> 82 #include <stdio.h> 83 #include <string.h> 84 #include <unistd.h> 85 #include <stdlib.h> 86 #include <errno.h> 87 #include "netstat.h" 88 89 struct inpcb inpcb; 90 struct tcpcb tcpcb; 91 struct socket sockb; 92 93 char *inetname(struct in_addr *); 94 void inetprint(struct in_addr *, in_port_t, const char *, int); 95 char *inet6name(struct in6_addr *); 96 void sosplice_dump(u_long); 97 void sockbuf_dump(struct sockbuf *, const char *); 98 void protosw_dump(u_long, u_long); 99 void domain_dump(u_long, u_long, short); 100 void inpcb_dump(u_long, short, int); 101 void tcpcb_dump(u_long); 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 /* 774 * Dump PIM statistics structure. 775 */ 776 void 777 pim_stats(char *name) 778 { 779 struct pimstat pimstat; 780 int mib[] = { CTL_NET, PF_INET, IPPROTO_PIM, PIMCTL_STATS }; 781 size_t len = sizeof(pimstat); 782 783 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 784 &pimstat, &len, NULL, 0) == -1) { 785 if (errno != ENOPROTOOPT) 786 warn("%s", name); 787 return; 788 } 789 790 printf("%s:\n", name); 791 #define p(f, m) if (pimstat.f || sflag <= 1) \ 792 printf(m, pimstat.f, plural(pimstat.f)) 793 #define py(f, m) if (pimstat.f || sflag <= 1) \ 794 printf(m, pimstat.f, pimstat.f != 1 ? "ies" : "y") 795 796 p(pims_rcv_total_msgs, "\t%llu message%s received\n"); 797 p(pims_rcv_total_bytes, "\t%llu byte%s received\n"); 798 p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n"); 799 p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n"); 800 p(pims_rcv_badversion, "\t%llu message%s received with bad version\n"); 801 p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n"); 802 p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n"); 803 p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n"); 804 p(pims_rcv_badregisters, "\t%llu bad register%s received\n"); 805 p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n"); 806 p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n"); 807 #undef p 808 #undef py 809 } 810 811 struct rpcnams { 812 struct rpcnams *next; 813 in_port_t port; 814 int proto; 815 char *rpcname; 816 }; 817 818 static char * 819 getrpcportnam(in_port_t port, int proto) 820 { 821 struct sockaddr_in server_addr; 822 struct hostent *hp; 823 static struct pmaplist *head; 824 int socket = RPC_ANYSOCK; 825 struct timeval minutetimeout; 826 CLIENT *client; 827 struct rpcent *rpc; 828 static int first; 829 static struct rpcnams *rpcn; 830 struct rpcnams *n; 831 char num[20]; 832 833 if (first == 0) { 834 first = 1; 835 memset(&server_addr, 0, sizeof server_addr); 836 server_addr.sin_family = AF_INET; 837 if ((hp = gethostbyname("localhost")) != NULL) 838 memmove((caddr_t)&server_addr.sin_addr, hp->h_addr, 839 hp->h_length); 840 else 841 (void) inet_aton("0.0.0.0", &server_addr.sin_addr); 842 843 minutetimeout.tv_sec = 60; 844 minutetimeout.tv_usec = 0; 845 server_addr.sin_port = htons(PMAPPORT); 846 if ((client = clnttcp_create(&server_addr, PMAPPROG, 847 PMAPVERS, &socket, 50, 500)) == NULL) 848 return (NULL); 849 if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL, 850 xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { 851 clnt_destroy(client); 852 return (NULL); 853 } 854 for (; head != NULL; head = head->pml_next) { 855 n = malloc(sizeof(struct rpcnams)); 856 if (n == NULL) 857 continue; 858 n->next = rpcn; 859 rpcn = n; 860 n->port = head->pml_map.pm_port; 861 n->proto = head->pml_map.pm_prot; 862 863 rpc = getrpcbynumber(head->pml_map.pm_prog); 864 if (rpc) 865 n->rpcname = strdup(rpc->r_name); 866 else { 867 snprintf(num, sizeof num, "%ld", 868 head->pml_map.pm_prog); 869 n->rpcname = strdup(num); 870 } 871 } 872 clnt_destroy(client); 873 } 874 875 for (n = rpcn; n; n = n->next) 876 if (n->port == port && n->proto == proto) 877 return (n->rpcname); 878 return (NULL); 879 } 880 881 /* 882 * Pretty print an Internet address (net address + port). 883 * If the nflag was specified, use numbers instead of names. 884 */ 885 void 886 inetprint(struct in_addr *in, in_port_t port, const char *proto, int local) 887 { 888 struct servent *sp = 0; 889 char line[80], *cp, *nam; 890 int width; 891 892 snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16, 893 inetname(in)); 894 cp = strchr(line, '\0'); 895 if (!nflag && port) 896 sp = getservbyport((int)port, proto); 897 if (sp || port == 0) 898 snprintf(cp, line + sizeof line - cp, "%.8s", 899 sp ? sp->s_name : "*"); 900 else if (local && !nflag && (nam = getrpcportnam(ntohs(port), 901 (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP)))) 902 snprintf(cp, line + sizeof line - cp, "%d[%.8s]", 903 ntohs(port), nam); 904 else 905 snprintf(cp, line + sizeof line - cp, "%d", ntohs(port)); 906 width = Aflag ? 18 : 22; 907 printf(" %-*.*s", width, width, line); 908 } 909 910 /* 911 * Construct an Internet address representation. 912 * If the nflag has been supplied, give 913 * numeric value, otherwise try for symbolic name. 914 */ 915 char * 916 inetname(struct in_addr *inp) 917 { 918 char *cp; 919 static char line[50]; 920 struct hostent *hp; 921 static char domain[HOST_NAME_MAX+1]; 922 static int first = 1; 923 924 if (first && !nflag) { 925 first = 0; 926 if (gethostname(domain, sizeof(domain)) == 0 && 927 (cp = strchr(domain, '.'))) 928 (void) strlcpy(domain, cp + 1, sizeof domain); 929 else 930 domain[0] = '\0'; 931 } 932 cp = NULL; 933 if (!nflag && inp->s_addr != INADDR_ANY) { 934 hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 935 if (hp) { 936 if ((cp = strchr(hp->h_name, '.')) && 937 !strcmp(cp + 1, domain)) 938 *cp = '\0'; 939 cp = hp->h_name; 940 } 941 } 942 if (inp->s_addr == INADDR_ANY) 943 snprintf(line, sizeof line, "*"); 944 else if (cp) 945 snprintf(line, sizeof line, "%s", cp); 946 else { 947 inp->s_addr = ntohl(inp->s_addr); 948 #define C(x) ((x) & 0xff) 949 snprintf(line, sizeof line, "%u.%u.%u.%u", 950 C(inp->s_addr >> 24), C(inp->s_addr >> 16), 951 C(inp->s_addr >> 8), C(inp->s_addr)); 952 } 953 return (line); 954 } 955 956 /* 957 * Dump AH statistics structure. 958 */ 959 void 960 ah_stats(char *name) 961 { 962 struct ahstat ahstat; 963 int mib[] = { CTL_NET, PF_INET, IPPROTO_AH, AHCTL_STATS }; 964 size_t len = sizeof(ahstat); 965 966 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 967 &ahstat, &len, NULL, 0) == -1) { 968 if (errno != ENOPROTOOPT) 969 warn("%s", name); 970 return; 971 } 972 973 printf("%s:\n", name); 974 #define p(f, m) if (ahstat.f || sflag <= 1) \ 975 printf(m, ahstat.f, plural(ahstat.f)) 976 #define p1(f, m) if (ahstat.f || sflag <= 1) \ 977 printf(m, ahstat.f) 978 979 p1(ahs_input, "\t%u input AH packets\n"); 980 p1(ahs_output, "\t%u output AH packets\n"); 981 p(ahs_nopf, "\t%u packet%s from unsupported protocol families\n"); 982 p(ahs_hdrops, "\t%u packet%s shorter than header shows\n"); 983 p(ahs_pdrops, "\t%u packet%s dropped due to policy\n"); 984 p(ahs_notdb, "\t%u packet%s for which no TDB was found\n"); 985 p(ahs_badkcr, "\t%u input packet%s that failed to be processed\n"); 986 p(ahs_badauth, "\t%u packet%s that failed verification received\n"); 987 p(ahs_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 988 p(ahs_qfull, "\t%u packet%s were dropped due to full output queue\n"); 989 p(ahs_wrap, "\t%u packet%s where counter wrapping was detected\n"); 990 p(ahs_replay, "\t%u possibly replayed packet%s received\n"); 991 p(ahs_badauthl, "\t%u packet%s with bad authenticator length received\n"); 992 p(ahs_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 993 p(ahs_toobig, "\t%u packet%s got larger than max IP packet size\n"); 994 p(ahs_crypto, "\t%u packet%s that failed crypto processing\n"); 995 p(ahs_ibytes, "\t%llu input byte%s\n"); 996 p(ahs_obytes, "\t%llu output byte%s\n"); 997 998 #undef p 999 #undef p1 1000 } 1001 1002 /* 1003 * Dump etherip statistics structure. 1004 */ 1005 void 1006 etherip_stats(char *name) 1007 { 1008 struct etheripstat etheripstat; 1009 int mib[] = { CTL_NET, PF_INET, IPPROTO_ETHERIP, ETHERIPCTL_STATS }; 1010 size_t len = sizeof(etheripstat); 1011 1012 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1013 ðeripstat, &len, NULL, 0) == -1) { 1014 if (errno != ENOPROTOOPT) 1015 warn("%s", name); 1016 return; 1017 } 1018 1019 printf("%s:\n", name); 1020 #define p(f, m) if (etheripstat.f || sflag <= 1) \ 1021 printf(m, etheripstat.f, plural(etheripstat.f)) 1022 1023 p(etherip_hdrops, "\t%u packet%s shorter than header shows\n"); 1024 p(etherip_qfull, "\t%u packet%s were dropped due to full output queue\n"); 1025 p(etherip_noifdrops, "\t%u packet%s were dropped because of no interface/bridge information\n"); 1026 p(etherip_pdrops, "\t%u packet%s dropped due to policy\n"); 1027 p(etherip_adrops, "\t%u packet%s dropped for other reasons\n"); 1028 p(etherip_ipackets, "\t%u input ethernet-in-IP packet%s\n"); 1029 p(etherip_opackets, "\t%u output ethernet-in-IP packet%s\n"); 1030 p(etherip_ibytes, "\t%llu input byte%s\n"); 1031 p(etherip_obytes, "\t%llu output byte%s\n"); 1032 #undef p 1033 } 1034 1035 /* 1036 * Dump ESP statistics structure. 1037 */ 1038 void 1039 esp_stats(char *name) 1040 { 1041 struct espstat espstat; 1042 int mib[] = { CTL_NET, PF_INET, IPPROTO_ESP, ESPCTL_STATS }; 1043 size_t len = sizeof(espstat); 1044 1045 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1046 &espstat, &len, NULL, 0) == -1) { 1047 if (errno != ENOPROTOOPT) 1048 warn("%s", name); 1049 return; 1050 } 1051 1052 printf("%s:\n", name); 1053 #define p(f, m) if (espstat.f || sflag <= 1) \ 1054 printf(m, espstat.f, plural(espstat.f)) 1055 1056 p(esps_input, "\t%u input ESP packet%s\n"); 1057 p(esps_output, "\t%u output ESP packet%s\n"); 1058 p(esps_nopf, "\t%u packet%s from unsupported protocol families\n"); 1059 p(esps_hdrops, "\t%u packet%s shorter than header shows\n"); 1060 p(esps_pdrops, "\t%u packet%s dropped due to policy\n"); 1061 p(esps_notdb, "\t%u packet%s for which no TDB was found\n"); 1062 p(esps_badkcr, "\t%u input packet%s that failed to be processed\n"); 1063 p(esps_badenc, "\t%u packet%s with bad encryption received\n"); 1064 p(esps_badauth, "\t%u packet%s that failed verification received\n"); 1065 p(esps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 1066 p(esps_qfull, "\t%u packet%s were dropped due to full output queue\n"); 1067 p(esps_wrap, "\t%u packet%s where counter wrapping was detected\n"); 1068 p(esps_replay, "\t%u possibly replayed packet%s received\n"); 1069 p(esps_badilen, "\t%u packet%s with bad payload size or padding received\n"); 1070 p(esps_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 1071 p(esps_toobig, "\t%u packet%s got larger than max IP packet size\n"); 1072 p(esps_crypto, "\t%u packet%s that failed crypto processing\n"); 1073 p(esps_udpencin, "\t%u input UDP encapsulated ESP packet%s\n"); 1074 p(esps_udpencout, "\t%u output UDP encapsulated ESP packet%s\n"); 1075 p(esps_udpinval, "\t%u UDP packet%s for non-encapsulating TDB received\n"); 1076 p(esps_udpneeded, "\t%u raw ESP packet%s for encapsulating TDB received\n"); 1077 p(esps_ibytes, "\t%llu input byte%s\n"); 1078 p(esps_obytes, "\t%llu output byte%s\n"); 1079 1080 #undef p 1081 } 1082 1083 /* 1084 * Dump IP-in-IP statistics structure. 1085 */ 1086 void 1087 ipip_stats(char *name) 1088 { 1089 struct ipipstat ipipstat; 1090 int mib[] = { CTL_NET, PF_INET, IPPROTO_IPIP, IPIPCTL_STATS }; 1091 size_t len = sizeof(ipipstat); 1092 1093 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1094 &ipipstat, &len, NULL, 0) == -1) { 1095 if (errno != ENOPROTOOPT) 1096 warn("%s", name); 1097 return; 1098 } 1099 1100 printf("%s:\n", name); 1101 #define p(f, m) if (ipipstat.f || sflag <= 1) \ 1102 printf(m, ipipstat.f, plural(ipipstat.f)) 1103 1104 p(ipips_ipackets, "\t%u total input packet%s\n"); 1105 p(ipips_opackets, "\t%u total output packet%s\n"); 1106 p(ipips_hdrops, "\t%u packet%s shorter than header shows\n"); 1107 p(ipips_pdrops, "\t%u packet%s dropped due to policy\n"); 1108 p(ipips_spoof, "\t%u packet%s with possibly spoofed local addresses\n"); 1109 p(ipips_qfull, "\t%u packet%s were dropped due to full output queue\n"); 1110 p(ipips_ibytes, "\t%llu input byte%s\n"); 1111 p(ipips_obytes, "\t%llu output byte%s\n"); 1112 p(ipips_family, "\t%u protocol family mismatche%s\n"); 1113 p(ipips_unspec, "\t%u attempt%s to use tunnel with unspecified endpoint(s)\n"); 1114 #undef p 1115 } 1116 1117 /* 1118 * Dump CARP statistics structure. 1119 */ 1120 void 1121 carp_stats(char *name) 1122 { 1123 struct carpstats carpstat; 1124 int mib[] = { CTL_NET, PF_INET, IPPROTO_CARP, CARPCTL_STATS }; 1125 size_t len = sizeof(carpstat); 1126 1127 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1128 &carpstat, &len, NULL, 0) == -1) { 1129 if (errno != ENOPROTOOPT) 1130 warn("%s", name); 1131 return; 1132 } 1133 1134 printf("%s:\n", name); 1135 #define p(f, m) if (carpstat.f || sflag <= 1) \ 1136 printf(m, carpstat.f, plural(carpstat.f)) 1137 #define p2(f, m) if (carpstat.f || sflag <= 1) \ 1138 printf(m, carpstat.f) 1139 1140 p(carps_ipackets, "\t%llu packet%s received (IPv4)\n"); 1141 p(carps_ipackets6, "\t%llu packet%s received (IPv6)\n"); 1142 p(carps_badif, "\t\t%llu packet%s discarded for bad interface\n"); 1143 p(carps_badttl, "\t\t%llu packet%s discarded for wrong TTL\n"); 1144 p(carps_hdrops, "\t\t%llu packet%s shorter than header\n"); 1145 p(carps_badsum, "\t\t%llu discarded for bad checksum%s\n"); 1146 p(carps_badver, "\t\t%llu discarded packet%s with a bad version\n"); 1147 p2(carps_badlen, "\t\t%llu discarded because packet too short\n"); 1148 p2(carps_badauth, "\t\t%llu discarded for bad authentication\n"); 1149 p2(carps_badvhid, "\t\t%llu discarded for unknown vhid\n"); 1150 p2(carps_badaddrs, "\t\t%llu discarded because of a bad address list\n"); 1151 p(carps_opackets, "\t%llu packet%s sent (IPv4)\n"); 1152 p(carps_opackets6, "\t%llu packet%s sent (IPv6)\n"); 1153 p2(carps_onomem, "\t\t%llu send failed due to mbuf memory error\n"); 1154 p(carps_preempt, "\t%llu transition%s to master\n"); 1155 #undef p 1156 #undef p2 1157 } 1158 1159 /* 1160 * Dump pfsync statistics structure. 1161 */ 1162 void 1163 pfsync_stats(char *name) 1164 { 1165 struct pfsyncstats pfsyncstat; 1166 int mib[] = { CTL_NET, PF_INET, IPPROTO_PFSYNC, PFSYNCCTL_STATS }; 1167 size_t len = sizeof(pfsyncstat); 1168 1169 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1170 &pfsyncstat, &len, NULL, 0) == -1) { 1171 if (errno != ENOPROTOOPT) 1172 warn("%s", name); 1173 return; 1174 } 1175 1176 printf("%s:\n", name); 1177 #define p(f, m) if (pfsyncstat.f || sflag <= 1) \ 1178 printf(m, pfsyncstat.f, plural(pfsyncstat.f)) 1179 #define p2(f, m) if (pfsyncstat.f || sflag <= 1) \ 1180 printf(m, pfsyncstat.f) 1181 1182 p(pfsyncs_ipackets, "\t%llu packet%s received (IPv4)\n"); 1183 p(pfsyncs_ipackets6, "\t%llu packet%s received (IPv6)\n"); 1184 p(pfsyncs_badif, "\t\t%llu packet%s discarded for bad interface\n"); 1185 p(pfsyncs_badttl, "\t\t%llu packet%s discarded for bad ttl\n"); 1186 p(pfsyncs_hdrops, "\t\t%llu packet%s shorter than header\n"); 1187 p(pfsyncs_badver, "\t\t%llu packet%s discarded for bad version\n"); 1188 p(pfsyncs_badauth, "\t\t%llu packet%s discarded for bad HMAC\n"); 1189 p(pfsyncs_badact,"\t\t%llu packet%s discarded for bad action\n"); 1190 p(pfsyncs_badlen, "\t\t%llu packet%s discarded for short packet\n"); 1191 p(pfsyncs_badval, "\t\t%llu state%s discarded for bad values\n"); 1192 p(pfsyncs_stale, "\t\t%llu stale state%s\n"); 1193 p(pfsyncs_badstate, "\t\t%llu failed state lookup/insert%s\n"); 1194 p(pfsyncs_opackets, "\t%llu packet%s sent (IPv4)\n"); 1195 p(pfsyncs_opackets6, "\t%llu packet%s sent (IPv6)\n"); 1196 p2(pfsyncs_onomem, "\t\t%llu send failed due to mbuf memory error\n"); 1197 p2(pfsyncs_oerrors, "\t\t%llu send error\n"); 1198 #undef p 1199 #undef p2 1200 } 1201 1202 /* 1203 * Dump pflow statistics structure. 1204 */ 1205 void 1206 pflow_stats(char *name) 1207 { 1208 struct pflowstats flowstats; 1209 int mib[] = { CTL_NET, PF_PFLOW, NET_PFLOW_STATS }; 1210 size_t len = sizeof(struct pflowstats); 1211 1212 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &flowstats, &len, 1213 NULL, 0) == -1) { 1214 if (errno != ENOPROTOOPT) 1215 warn("%s", name); 1216 return; 1217 } 1218 1219 printf("%s:\n", name); 1220 #define p(f, m) if (flowstats.f || sflag <= 1) \ 1221 printf(m, flowstats.f, plural(flowstats.f)) 1222 #define p2(f, m) if (flowstats.f || sflag <= 1) \ 1223 printf(m, flowstats.f) 1224 1225 p(pflow_flows, "\t%llu flow%s sent\n"); 1226 p(pflow_packets, "\t%llu packet%s sent\n"); 1227 p2(pflow_onomem, "\t\t%llu send failed due to mbuf memory error\n"); 1228 p2(pflow_oerrors, "\t\t%llu send error\n"); 1229 #undef p 1230 #undef p2 1231 } 1232 1233 /* 1234 * Dump IPCOMP statistics structure. 1235 */ 1236 void 1237 ipcomp_stats(char *name) 1238 { 1239 struct ipcompstat ipcompstat; 1240 int mib[] = { CTL_NET, PF_INET, IPPROTO_IPCOMP, IPCOMPCTL_STATS }; 1241 size_t len = sizeof(ipcompstat); 1242 1243 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), 1244 &ipcompstat, &len, NULL, 0) == -1) { 1245 if (errno != ENOPROTOOPT) 1246 warn("%s", name); 1247 return; 1248 } 1249 1250 printf("%s:\n", name); 1251 #define p(f, m) if (ipcompstat.f || sflag <= 1) \ 1252 printf(m, ipcompstat.f, plural(ipcompstat.f)) 1253 1254 p(ipcomps_input, "\t%u input IPCOMP packet%s\n"); 1255 p(ipcomps_output, "\t%u output IPCOMP packet%s\n"); 1256 p(ipcomps_nopf, "\t%u packet%s from unsupported protocol families\n"); 1257 p(ipcomps_hdrops, "\t%u packet%s shorter than header shows\n"); 1258 p(ipcomps_pdrops, "\t%u packet%s dropped due to policy\n"); 1259 p(ipcomps_notdb, "\t%u packet%s for which no TDB was found\n"); 1260 p(ipcomps_badkcr, "\t%u input packet%s that failed to be processed\n"); 1261 p(ipcomps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 1262 p(ipcomps_qfull, "\t%u packet%s were dropped due to full output queue\n"); 1263 p(ipcomps_wrap, "\t%u packet%s where counter wrapping was detected\n"); 1264 p(ipcomps_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 1265 p(ipcomps_toobig, "\t%u packet%s got larger than max IP packet size\n"); 1266 p(ipcomps_crypto, "\t%u packet%s that failed (de)compression processing\n"); 1267 p(ipcomps_minlen, "\t%u packet%s less than minimum compression length\n"); 1268 p(ipcomps_ibytes, "\t%llu input byte%s\n"); 1269 p(ipcomps_obytes, "\t%llu output byte%s\n"); 1270 1271 #undef p 1272 } 1273 1274 /* 1275 * Dump the contents of a socket structure 1276 */ 1277 void 1278 socket_dump(u_long off) 1279 { 1280 struct socket so; 1281 1282 if (off == 0) 1283 return; 1284 kread(off, &so, sizeof(so)); 1285 1286 #define p(fmt, v, sep) printf(#v " " fmt sep, so.v); 1287 #define pp(fmt, v, sep) printf(#v " " fmt sep, so.v); 1288 printf("socket %#lx\n ", off); 1289 p("%#.4x", so_type, "\n "); 1290 p("%#.4x", so_options, "\n "); 1291 p("%d", so_linger, "\n "); 1292 p("%#.4x", so_state, "\n "); 1293 pp("%p", so_pcb, ", "); 1294 pp("%p", so_proto, ", "); 1295 pp("%p", so_head, "\n "); 1296 p("%d", so_q0len, ", "); 1297 p("%d", so_qlen, ", "); 1298 p("%d", so_qlimit, "\n "); 1299 p("%d", so_timeo, "\n "); 1300 p("%u", so_error, "\n "); 1301 p("%d", so_pgid, ", "); 1302 p("%u", so_siguid, ", "); 1303 p("%u", so_sigeuid, "\n "); 1304 p("%lu", so_oobmark, "\n "); 1305 if (so.so_sp) 1306 sosplice_dump((u_long)so.so_sp); 1307 sockbuf_dump(&so.so_rcv, "so_rcv"); 1308 sockbuf_dump(&so.so_snd, "so_snd"); 1309 p("%u", so_euid, ", "); 1310 p("%u", so_ruid, ", "); 1311 p("%u", so_egid, ", "); 1312 p("%u", so_rgid, "\n "); 1313 p("%d", so_cpid, "\n"); 1314 #undef p 1315 #undef pp 1316 1317 protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb); 1318 } 1319 1320 /* 1321 * Dump the contents of a struct sosplice 1322 */ 1323 void 1324 sosplice_dump(u_long off) 1325 { 1326 struct sosplice ssp; 1327 1328 if (off == 0) 1329 return; 1330 kread(off, &ssp, sizeof(ssp)); 1331 1332 #define p(fmt, v, sep) printf(#v " " fmt sep, ssp.v); 1333 #define pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v); 1334 #define pp(fmt, v, sep) printf(#v " " fmt sep, ssp.v); 1335 pp("%p", ssp_socket, ", "); 1336 pp("%p", ssp_soback, "\n "); 1337 p("%lld", ssp_len, ", "); 1338 p("%lld", ssp_max, ", "); 1339 pll("%lld", ssp_idletv.tv_sec, ", "); 1340 p("%ld", ssp_idletv.tv_usec, "\n "); 1341 #undef p 1342 #undef pll 1343 #undef pp 1344 } 1345 1346 /* 1347 * Dump the contents of a socket buffer 1348 */ 1349 void 1350 sockbuf_dump(struct sockbuf *sb, const char *name) 1351 { 1352 #define p(fmt, v, sep) printf(#v " " fmt sep, sb->v); 1353 printf("%s ", name); 1354 p("%lu", sb_cc, ", "); 1355 p("%lu", sb_datacc, ", "); 1356 p("%lu", sb_hiwat, ", "); 1357 p("%lu", sb_wat, "\n "); 1358 printf("%s ", name); 1359 p("%lu", sb_mbcnt, ", "); 1360 p("%lu", sb_mbmax, ", "); 1361 p("%ld", sb_lowat, "\n "); 1362 printf("%s ", name); 1363 p("%#.8x", sb_flagsintr, ", "); 1364 p("%#.4x", sb_flags, ", "); 1365 p("%u", sb_timeo, "\n "); 1366 #undef p 1367 } 1368 1369 /* 1370 * Dump the contents of a protosw structure 1371 */ 1372 void 1373 protosw_dump(u_long off, u_long pcb) 1374 { 1375 struct protosw proto; 1376 1377 if (off == 0) 1378 return; 1379 kread(off, &proto, sizeof(proto)); 1380 1381 #define p(fmt, v, sep) printf(#v " " fmt sep, proto.v); 1382 #define pp(fmt, v, sep) printf(#v " " fmt sep, proto.v); 1383 printf("protosw %#lx\n ", off); 1384 p("%#.4x", pr_type, "\n "); 1385 pp("%p", pr_domain, "\n "); 1386 p("%d", pr_protocol, "\n "); 1387 p("%#.4x", pr_flags, "\n"); 1388 #undef p 1389 #undef pp 1390 1391 domain_dump((u_long)proto.pr_domain, pcb, proto.pr_protocol); 1392 } 1393 1394 /* 1395 * Dump the contents of a domain structure 1396 */ 1397 void 1398 domain_dump(u_long off, u_long pcb, short protocol) 1399 { 1400 struct domain dom; 1401 char name[256]; 1402 1403 if (off == 0) 1404 return; 1405 kread(off, &dom, sizeof(dom)); 1406 kread((u_long)dom.dom_name, name, sizeof(name)); 1407 1408 #define p(fmt, v, sep) printf(#v " " fmt sep, dom.v); 1409 printf("domain %#lx\n ", off); 1410 p("%d", dom_family, "\n "); 1411 printf("dom_name %.*s\n", (int)sizeof(name), name); 1412 #undef p 1413 } 1414 1415 /* 1416 * Dump the contents of a internet PCB 1417 */ 1418 void 1419 inpcb_dump(u_long off, short protocol, int af) 1420 { 1421 struct inpcb inp; 1422 char faddr[256], laddr[256]; 1423 1424 if (off == 0) 1425 return; 1426 kread(off, &inp, sizeof(inp)); 1427 1428 if (vflag) 1429 socket_dump((u_long)inp.inp_socket); 1430 1431 switch (af) { 1432 case AF_INET: 1433 inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr)); 1434 inet_ntop(af, &inp.inp_laddr, laddr, sizeof(laddr)); 1435 break; 1436 case AF_INET6: 1437 inet_ntop(af, &inp.inp_faddr6, faddr, sizeof(faddr)); 1438 inet_ntop(af, &inp.inp_laddr6, laddr, sizeof(laddr)); 1439 break; 1440 default: 1441 faddr[0] = laddr[0] = '\0'; 1442 } 1443 1444 #define p(fmt, v, sep) printf(#v " " fmt sep, inp.v); 1445 #define pp(fmt, v, sep) printf(#v " " fmt sep, inp.v); 1446 printf("inpcb %#lx\n ", off); 1447 pp("%p", inp_table, "\n "); 1448 printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr); 1449 HTONS(inp.inp_fport); 1450 HTONS(inp.inp_lport); 1451 p("%u", inp_fport, ", "); 1452 p("%u", inp_lport, "\n "); 1453 pp("%p", inp_socket, ", "); 1454 pp("%p", inp_ppcb, "\n "); 1455 p("%#.8x", inp_flags, "\n "); 1456 p("%d", inp_hops, "\n "); 1457 p("%u", inp_seclevel[0], ", "); 1458 p("%u", inp_seclevel[1], ", "); 1459 p("%u", inp_seclevel[2], ", "); 1460 p("%u", inp_seclevel[3], "\n "); 1461 p("%u", inp_ip_minttl, "\n "); 1462 p("%d", inp_cksum6, "\n "); 1463 pp("%p", inp_icmp6filt, "\n "); 1464 pp("%p", inp_pf_sk, "\n "); 1465 p("%u", inp_rtableid, "\n "); 1466 p("%d", inp_pipex, "\n"); 1467 #undef p 1468 #undef pp 1469 1470 switch (protocol) { 1471 case IPPROTO_TCP: 1472 tcpcb_dump((u_long)inp.inp_ppcb); 1473 break; 1474 } 1475 } 1476 1477 /* 1478 * Dump the contents of a TCP PCB 1479 */ 1480 void 1481 tcpcb_dump(u_long off) 1482 { 1483 struct tcpcb tcpcb; 1484 1485 if (off == 0) 1486 return; 1487 kread(off, (char *)&tcpcb, sizeof (tcpcb)); 1488 1489 #define p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v); 1490 #define pp(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v); 1491 printf("tcpcb %#lx\n ", off); 1492 pp("%p", t_inpcb, "\n "); 1493 p("%d", t_state, ""); 1494 if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES) 1495 printf(" (%s)", tcpstates[tcpcb.t_state]); 1496 printf("\n "); 1497 p("%d", t_rxtshift, ", "); 1498 p("%d", t_rxtcur, ", "); 1499 p("%d", t_dupacks, "\n "); 1500 p("%u", t_maxseg, ", "); 1501 p("%u", t_maxopd, ", "); 1502 p("%u", t_peermss, "\n "); 1503 p("0x%x", t_flags, ", "); 1504 p("%u", t_force, "\n "); 1505 p("%u", iss, "\n "); 1506 p("%u", snd_una, ", "); 1507 p("%u", snd_nxt, ", "); 1508 p("%u", snd_up, "\n "); 1509 p("%u", snd_wl1, ", "); 1510 p("%u", snd_wl2, ", "); 1511 p("%lu", snd_wnd, "\n "); 1512 p("%d", sack_enable, ", "); 1513 p("%d", snd_numholes, ", "); 1514 p("%u", snd_fack, ", "); 1515 p("%lu",snd_awnd, "\n "); 1516 p("%u", retran_data, ", "); 1517 p("%u", snd_last, "\n "); 1518 p("%u", irs, "\n "); 1519 p("%u", rcv_nxt, ", "); 1520 p("%u", rcv_up, ", "); 1521 p("%lu", rcv_wnd, "\n "); 1522 p("%u", rcv_lastsack, "\n "); 1523 p("%d", rcv_numsacks, "\n "); 1524 p("%u", rcv_adv, ", "); 1525 p("%u", snd_max, "\n "); 1526 p("%lu", snd_cwnd, ", "); 1527 p("%lu", snd_ssthresh, ", "); 1528 p("%lu", max_sndwnd, "\n "); 1529 p("%u", t_rcvtime, ", "); 1530 p("%u", t_rtttime, ", "); 1531 p("%u", t_rtseq, "\n "); 1532 p("%u", t_srtt, ", "); 1533 p("%u", t_rttvar, ", "); 1534 p("%u", t_rttmin, "\n "); 1535 p("%u", t_oobflags, ", "); 1536 p("%u", t_iobc, "\n "); 1537 p("%u", t_softerror, "\n "); 1538 p("%u", snd_scale, ", "); 1539 p("%u", rcv_scale, ", "); 1540 p("%u", request_r_scale, ", "); 1541 p("%u", requested_s_scale, "\n "); 1542 p("%u", ts_recent, ", "); 1543 p("%u", ts_recent_age, "\n "); 1544 p("%u", last_ack_sent, "\n "); 1545 HTONS(tcpcb.t_pmtud_ip_len); 1546 HTONS(tcpcb.t_pmtud_nextmtu); 1547 p("%u", t_pmtud_mss_acked, ", "); 1548 p("%u", t_pmtud_mtu_sent, "\n "); 1549 p("%u", t_pmtud_nextmtu, ", "); 1550 p("%u", t_pmtud_ip_len, ", "); 1551 p("%u", t_pmtud_ip_hl, "\n "); 1552 p("%u", t_pmtud_th_seq, "\n "); 1553 p("%u", pf, "\n"); 1554 #undef p 1555 #undef pp 1556 } 1557