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