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