1 /* $OpenBSD: inet.c,v 1.80 2004/01/15 10:17:33 markus 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 #ifndef lint 34 #if 0 35 static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94"; 36 #else 37 static const char *rcsid = "$OpenBSD: inet.c,v 1.80 2004/01/15 10:17:33 markus Exp $"; 38 #endif 39 #endif /* not lint */ 40 41 #include <sys/param.h> 42 #include <sys/queue.h> 43 #include <sys/socket.h> 44 #include <sys/socketvar.h> 45 #include <sys/mbuf.h> 46 #include <sys/protosw.h> 47 48 #include <net/route.h> 49 #include <netinet/in.h> 50 #include <netinet/in_systm.h> 51 #include <netinet/ip.h> 52 #include <netinet/in_pcb.h> 53 #include <netinet/ip_icmp.h> 54 #include <netinet/icmp_var.h> 55 #include <netinet/igmp_var.h> 56 #include <netinet/ip_var.h> 57 #include <netinet/tcp.h> 58 #include <netinet/tcpip.h> 59 #include <netinet/tcp_seq.h> 60 #define TCPSTATES 61 #include <netinet/tcp_fsm.h> 62 #include <netinet/tcp_timer.h> 63 #include <netinet/tcp_var.h> 64 #include <netinet/tcp_debug.h> 65 #include <netinet/udp.h> 66 #include <netinet/udp_var.h> 67 #include <netinet/ip_ipsp.h> 68 #include <netinet/ip_ah.h> 69 #include <netinet/ip_esp.h> 70 #include <netinet/ip_ipip.h> 71 #include <netinet/ip_ipcomp.h> 72 #include <netinet/ip_ether.h> 73 #include <netinet/ip_carp.h> 74 #include <net/if.h> 75 #include <net/pfvar.h> 76 #include <net/if_pfsync.h> 77 78 #include <arpa/inet.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 "netstat.h" 86 87 #include <rpc/rpc.h> 88 #include <rpc/pmap_prot.h> 89 #include <rpc/pmap_clnt.h> 90 91 struct inpcb inpcb; 92 struct tcpcb tcpcb; 93 struct socket sockb; 94 95 static void protopr0(u_long, char *, int); 96 97 char *inetname(struct in_addr *); 98 void inetprint(struct in_addr *, in_port_t, char *, int); 99 #ifdef INET6 100 char *inet6name(struct in6_addr *); 101 void inet6print(struct in6_addr *, int, char *, int); 102 #endif 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) 112 { 113 protopr0(off, name, AF_INET); 114 } 115 116 #ifdef INET6 117 void 118 ip6protopr(u_long off, char *name) 119 { 120 protopr0(off, name, AF_INET6); 121 } 122 #endif 123 124 static void 125 protopr0(u_long off, char *name, int af) 126 { 127 struct inpcbtable table; 128 struct inpcb *head, *next, *prev; 129 struct inpcb inpcb; 130 int istcp, israw; 131 int first = 1; 132 char *name0; 133 char namebuf[20]; 134 135 name0 = name; 136 if (off == 0) 137 return; 138 istcp = strcmp(name, "tcp") == 0; 139 israw = strncmp(name, "ip", 2) == 0; 140 kread(off, (char *)&table, sizeof table); 141 prev = head = 142 (struct inpcb *)&((struct inpcbtable *)off)->inpt_queue.cqh_first; 143 next = table.inpt_queue.cqh_first; 144 145 while (next != head) { 146 kread((u_long)next, (char *)&inpcb, sizeof inpcb); 147 if (inpcb.inp_queue.cqe_prev != prev) { 148 printf("???\n"); 149 break; 150 } 151 prev = next; 152 next = inpcb.inp_queue.cqe_next; 153 154 switch (af) { 155 case AF_INET: 156 if ((inpcb.inp_flags & INP_IPV6) != 0) 157 continue; 158 break; 159 case AF_INET6: 160 if ((inpcb.inp_flags & INP_IPV6) == 0) 161 continue; 162 break; 163 default: 164 break; 165 } 166 167 if (!aflag && 168 inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) 169 continue; 170 kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb)); 171 if (istcp) { 172 kread((u_long)inpcb.inp_ppcb, 173 (char *)&tcpcb, sizeof (tcpcb)); 174 } 175 if (first) { 176 printf("Active Internet connections"); 177 if (aflag) 178 printf(" (including servers)"); 179 putchar('\n'); 180 if (Aflag) 181 printf("%-*.*s %-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n", 182 PLEN, PLEN, "PCB", "Proto", "Recv-Q", 183 "Send-Q", "Local Address", 184 "Foreign Address", "(state)"); 185 else 186 printf("%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 187 "Proto", "Recv-Q", "Send-Q", 188 "Local Address", "Foreign Address", 189 "(state)"); 190 first = 0; 191 } 192 if (Aflag) { 193 if (istcp) 194 printf("%*p ", PLEN, inpcb.inp_ppcb); 195 else 196 printf("%*p ", PLEN, prev); 197 } 198 #ifdef INET6 199 if (inpcb.inp_flags & INP_IPV6 && !israw) { 200 strlcpy(namebuf, name0, sizeof namebuf); 201 strlcat(namebuf, "6", sizeof namebuf); 202 name = namebuf; 203 } else 204 name = name0; 205 #endif 206 printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc, 207 sockb.so_snd.sb_cc); 208 #ifdef INET6 209 if (inpcb.inp_flags & INP_IPV6) { 210 inet6print(&inpcb.inp_laddr6, (int)inpcb.inp_lport, 211 name, 1); 212 inet6print(&inpcb.inp_faddr6, (int)inpcb.inp_fport, 213 name, 0); 214 } else 215 #endif 216 { 217 inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport, 218 name, 1); 219 inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport, 220 name, 0); 221 } 222 if (istcp) { 223 if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES) 224 printf(" %d", tcpcb.t_state); 225 else 226 printf(" %s", tcpstates[tcpcb.t_state]); 227 } else if (israw) { 228 struct protoent *pe = NULL; 229 u_int8_t proto; 230 #ifdef INET6 231 if (inpcb.inp_flags & INP_IPV6) 232 proto = inpcb.inp_ipv6.ip6_nxt; 233 else 234 #endif 235 proto = inpcb.inp_ip.ip_p; 236 if (!nflag) 237 pe = getprotobynumber(proto); 238 if (pe) 239 printf(" %s", pe->p_name); 240 else 241 printf(" %u", proto); 242 } 243 putchar('\n'); 244 } 245 } 246 247 /* 248 * Dump TCP statistics structure. 249 */ 250 void 251 tcp_stats(u_long off, char *name) 252 { 253 struct tcpstat tcpstat; 254 255 if (off == 0) 256 return; 257 printf("%s:\n", name); 258 kread(off, (char *)&tcpstat, sizeof (tcpstat)); 259 260 #define p(f, m) if (tcpstat.f || sflag <= 1) \ 261 printf(m, tcpstat.f, plural(tcpstat.f)) 262 #define p1(f, m) if (tcpstat.f || sflag <= 1) \ 263 printf(m, tcpstat.f) 264 #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 265 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) 266 #define p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 267 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2) 268 #define p3(f, m) if (tcpstat.f || sflag <= 1) \ 269 printf(m, tcpstat.f, plurales(tcpstat.f)) 270 271 p(tcps_sndtotal, "\t%u packet%s sent\n"); 272 p2(tcps_sndpack,tcps_sndbyte, 273 "\t\t%u data packet%s (%qd byte%s)\n"); 274 p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, 275 "\t\t%u data packet%s (%qd byte%s) retransmitted\n"); 276 p(tcps_sndrexmitfast, "\t\t%qd fast retransmitted packet%s\n"); 277 p2a(tcps_sndacks, tcps_delack, 278 "\t\t%u ack-only packet%s (%u delayed)\n"); 279 p(tcps_sndurg, "\t\t%u URG only packet%s\n"); 280 p(tcps_sndprobe, "\t\t%u window probe packet%s\n"); 281 p(tcps_sndwinup, "\t\t%u window update packet%s\n"); 282 p(tcps_sndctrl, "\t\t%u control packet%s\n"); 283 p(tcps_outhwcsum, "\t\t%u packet%s hardware-checksummed\n"); 284 p(tcps_rcvtotal, "\t%u packet%s received\n"); 285 p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%u ack%s (for %qd byte%s)\n"); 286 p(tcps_rcvdupack, "\t\t%u duplicate ack%s\n"); 287 p(tcps_rcvacktoomuch, "\t\t%u ack%s for unsent data\n"); 288 p2(tcps_rcvpack, tcps_rcvbyte, 289 "\t\t%u packet%s (%qu byte%s) received in-sequence\n"); 290 p2(tcps_rcvduppack, tcps_rcvdupbyte, 291 "\t\t%u completely duplicate packet%s (%qd byte%s)\n"); 292 p(tcps_pawsdrop, "\t\t%u old duplicate packet%s\n"); 293 p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, 294 "\t\t%u packet%s with some duplicate data (%qd byte%s duplicated)\n"); 295 p2(tcps_rcvoopack, tcps_rcvoobyte, 296 "\t\t%u out-of-order packet%s (%qd byte%s)\n"); 297 p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, 298 "\t\t%u packet%s (%qd byte%s) of data after window\n"); 299 p(tcps_rcvwinprobe, "\t\t%u window probe%s\n"); 300 p(tcps_rcvwinupd, "\t\t%u window update packet%s\n"); 301 p(tcps_rcvafterclose, "\t\t%u packet%s received after close\n"); 302 p(tcps_rcvbadsum, "\t\t%u discarded for bad checksum%s\n"); 303 p(tcps_rcvbadoff, "\t\t%u discarded for bad header offset field%s\n"); 304 p1(tcps_rcvshort, "\t\t%u discarded because packet too short\n"); 305 p1(tcps_rcvnosec, "\t\t%u discarded for missing IPsec protection\n"); 306 p(tcps_inhwcsum, "\t\t%u packet%s hardware-checksummed\n"); 307 p(tcps_rcvbadsig, "\t\t%u bad/missing md5 checksum%s\n"); 308 p(tcps_rcvgoodsig, "\t\t%qd good md5 checksum%s\n"); 309 p(tcps_connattempt, "\t%u connection request%s\n"); 310 p(tcps_accepts, "\t%u connection accept%s\n"); 311 p(tcps_connects, "\t%u connection%s established (including accepts)\n"); 312 p2(tcps_closed, tcps_drops, 313 "\t%u connection%s closed (including %u drop%s)\n"); 314 p(tcps_conndrops, "\t%u embryonic connection%s dropped\n"); 315 p2(tcps_rttupdated, tcps_segstimed, 316 "\t%u segment%s updated rtt (of %u attempt%s)\n"); 317 p(tcps_rexmttimeo, "\t%u retransmit timeout%s\n"); 318 p(tcps_timeoutdrop, "\t\t%u connection%s dropped by rexmit timeout\n"); 319 p(tcps_persisttimeo, "\t%u persist timeout%s\n"); 320 p(tcps_keeptimeo, "\t%u keepalive timeout%s\n"); 321 p(tcps_keepprobe, "\t\t%u keepalive probe%s sent\n"); 322 p(tcps_keepdrops, "\t\t%u connection%s dropped by keepalive\n"); 323 p(tcps_predack, "\t%u correct ACK header prediction%s\n"); 324 p(tcps_preddat, "\t%u correct data packet header prediction%s\n"); 325 p3(tcps_pcbhashmiss, "\t%u PCB cache miss%s\n"); 326 327 p(tcps_ecn_accepts, "\t%u ECN connection%s accepted\n"); 328 p(tcps_ecn_rcvece, "\t\t%u ECE packet%s received\n"); 329 p(tcps_ecn_rcvcwr, "\t\t%u CWR packet%s received\n"); 330 p(tcps_ecn_rcvce, "\t\t%u CE packet%s received\n"); 331 p(tcps_ecn_sndect, "\t\t%u ECT packet%s sent\n"); 332 p(tcps_ecn_sndece, "\t\t%u ECE packet%s sent\n"); 333 p(tcps_ecn_sndcwr, "\t\t%u CWR packet%s sent\n"); 334 p1(tcps_cwr_frecovery, "\t\t\tcwr by fastrecovery: %u\n"); 335 p1(tcps_cwr_timeout, "\t\t\tcwr by timeout: %u\n"); 336 p1(tcps_cwr_ecn, "\t\t\tcwr by ecn: %u\n"); 337 338 p(tcps_badsyn, "\t%u bad connection attempt%s\n"); 339 p1(tcps_sc_added, "\t%qd SYN cache entries added\n"); 340 p(tcps_sc_collisions, "\t\t%qd hash collision%s\n"); 341 p1(tcps_sc_completed, "\t\t%qd completed\n"); 342 p1(tcps_sc_aborted, "\t\t%qd aborted (no space to build PCB)\n"); 343 p1(tcps_sc_timed_out, "\t\t%qd timed out\n"); 344 p1(tcps_sc_overflowed, "\t\t%qd dropped due to overflow\n"); 345 p1(tcps_sc_bucketoverflow, "\t\t%qd dropped due to bucket overflow\n"); 346 p1(tcps_sc_reset, "\t\t%qd dropped due to RST\n"); 347 p1(tcps_sc_unreach, "\t\t%qd dropped due to ICMP unreachable\n"); 348 p(tcps_sc_retransmitted, "\t%qd SYN,ACK%s retransmitted\n"); 349 p(tcps_sc_dupesyn, "\t%qd duplicate SYN%s received for entries " 350 "already in the cache\n"); 351 p(tcps_sc_dropped, "\t%qd SYN%s dropped (no route or no space)\n"); 352 353 #undef p 354 #undef p1 355 #undef p2 356 #undef p2a 357 #undef p3 358 } 359 360 /* 361 * Dump UDP statistics structure. 362 */ 363 void 364 udp_stats(u_long off, char *name) 365 { 366 struct udpstat udpstat; 367 u_long delivered; 368 369 if (off == 0) 370 return; 371 kread(off, (char *)&udpstat, sizeof (udpstat)); 372 printf("%s:\n", name); 373 #define p(f, m) if (udpstat.f || sflag <= 1) \ 374 printf(m, udpstat.f, plural(udpstat.f)) 375 #define p1(f, m) if (udpstat.f || sflag <= 1) \ 376 printf(m, udpstat.f) 377 378 p(udps_ipackets, "\t%lu datagram%s received\n"); 379 p1(udps_hdrops, "\t%lu with incomplete header\n"); 380 p1(udps_badlen, "\t%lu with bad data length field\n"); 381 p1(udps_badsum, "\t%lu with bad checksum\n"); 382 p1(udps_nosum, "\t%lu with no checksum\n"); 383 p(udps_inhwcsum, "\t%lu input packet%s hardware-checksummed\n"); 384 p(udps_outhwcsum, "\t%lu output packet%s hardware-checksummed\n"); 385 p1(udps_noport, "\t%lu dropped due to no socket\n"); 386 p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n"); 387 p1(udps_nosec, "\t%lu dropped due to missing IPsec protection\n"); 388 p1(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); 389 delivered = udpstat.udps_ipackets - udpstat.udps_hdrops - 390 udpstat.udps_badlen - udpstat.udps_badsum - 391 udpstat.udps_noport - udpstat.udps_noportbcast - 392 udpstat.udps_fullsock; 393 if (delivered || sflag <= 1) 394 printf("\t%lu delivered\n", delivered); 395 p(udps_opackets, "\t%lu datagram%s output\n"); 396 p1(udps_pcbhashmiss, "\t%lu missed PCB cache\n"); 397 #undef p 398 #undef p1 399 } 400 401 /* 402 * Dump IP statistics structure. 403 */ 404 void 405 ip_stats(u_long off, char *name) 406 { 407 struct ipstat ipstat; 408 409 if (off == 0) 410 return; 411 kread(off, (char *)&ipstat, sizeof (ipstat)); 412 printf("%s:\n", name); 413 414 #define p(f, m) if (ipstat.f || sflag <= 1) \ 415 printf(m, ipstat.f, plural(ipstat.f)) 416 #define p1(f, m) if (ipstat.f || sflag <= 1) \ 417 printf(m, ipstat.f) 418 419 p(ips_total, "\t%lu total packet%s received\n"); 420 p(ips_badsum, "\t%lu bad header checksum%s\n"); 421 p1(ips_toosmall, "\t%lu with size smaller than minimum\n"); 422 p1(ips_tooshort, "\t%lu with data size < data length\n"); 423 p1(ips_badhlen, "\t%lu with header length < data size\n"); 424 p1(ips_badlen, "\t%lu with data length < header length\n"); 425 p1(ips_badoptions, "\t%lu with bad options\n"); 426 p1(ips_badvers, "\t%lu with incorrect version number\n"); 427 p(ips_fragments, "\t%lu fragment%s received\n"); 428 p(ips_fragdropped, "\t%lu fragment%s dropped (duplicates or out of space)\n"); 429 p(ips_badfrags, "\t%lu malformed fragment%s dropped\n"); 430 p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 431 p(ips_reassembled, "\t%lu packet%s reassembled ok\n"); 432 p(ips_delivered, "\t%lu packet%s for this host\n"); 433 p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n"); 434 p(ips_forward, "\t%lu packet%s forwarded\n"); 435 p(ips_cantforward, "\t%lu packet%s not forwardable\n"); 436 p(ips_redirectsent, "\t%lu redirect%s sent\n"); 437 p(ips_localout, "\t%lu packet%s sent from this host\n"); 438 p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 439 p(ips_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n"); 440 p(ips_noroute, "\t%lu output packet%s discarded due to no route\n"); 441 p(ips_fragmented, "\t%lu output datagram%s fragmented\n"); 442 p(ips_ofragments, "\t%lu fragment%s created\n"); 443 p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 444 p1(ips_rcvmemdrop, "\t%lu fragment floods\n"); 445 p(ips_toolong, "\t%lu packet%s with ip length > max ip packet size\n"); 446 p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n"); 447 p(ips_badaddr, "\t%lu datagram%s with bad address in header\n"); 448 p(ips_inhwcsum, "\t%lu input datagram%s checksum-processed by hardware\n"); 449 p(ips_outhwcsum, "\t%lu output datagram%s checksum-processed by hardware\n"); 450 #undef p 451 #undef p1 452 } 453 454 static char *icmpnames[ICMP_MAXTYPE + 1] = { 455 "echo reply", 456 "#1", 457 "#2", 458 "destination unreachable", 459 "source quench", 460 "routing redirect", 461 "#6", 462 "#7", 463 "echo", 464 "router advertisement", 465 "router solicitation", 466 "time exceeded", 467 "parameter problem", 468 "time stamp", 469 "time stamp reply", 470 "information request", 471 "information request reply", 472 "address mask request", 473 "address mask reply", 474 "#19", 475 "#20", 476 "#21", 477 "#22", 478 "#23", 479 "#24", 480 "#25", 481 "#26", 482 "#27", 483 "#28", 484 "#29", 485 "traceroute", 486 "data conversion error", 487 "mobile host redirect", 488 "IPv6 where-are-you", 489 "IPv6 i-am-here", 490 "mobile registration request", 491 "mobile registration reply", 492 "#37", 493 "#38", 494 "SKIP", 495 "Photuris", 496 }; 497 498 /* 499 * Dump ICMP statistics. 500 */ 501 void 502 icmp_stats(u_long off, char *name) 503 { 504 struct icmpstat icmpstat; 505 int i, first; 506 507 if (off == 0) 508 return; 509 kread(off, (char *)&icmpstat, sizeof (icmpstat)); 510 printf("%s:\n", name); 511 512 #define p(f, m) if (icmpstat.f || sflag <= 1) \ 513 printf(m, icmpstat.f, plural(icmpstat.f)) 514 515 p(icps_error, "\t%lu call%s to icmp_error\n"); 516 p(icps_oldicmp, 517 "\t%lu error%s not generated because old message was icmp\n"); 518 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 519 if (icmpstat.icps_outhist[i] != 0) { 520 if (first) { 521 printf("\tOutput packet histogram:\n"); 522 first = 0; 523 } 524 if (icmpnames[i]) 525 printf("\t\t%s:", icmpnames[i]); 526 else 527 printf("\t\t#%d:", i); 528 printf(" %lu\n", icmpstat.icps_outhist[i]); 529 } 530 p(icps_badcode, "\t%lu message%s with bad code fields\n"); 531 p(icps_tooshort, "\t%lu message%s < minimum length\n"); 532 p(icps_checksum, "\t%lu bad checksum%s\n"); 533 p(icps_badlen, "\t%lu message%s with bad length\n"); 534 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 535 if (icmpstat.icps_inhist[i] != 0) { 536 if (first) { 537 printf("\tInput packet histogram:\n"); 538 first = 0; 539 } 540 if (icmpnames[i]) 541 printf("\t\t%s:", icmpnames[i]); 542 else 543 printf("\t\t#%d:", i); 544 printf(" %lu\n", icmpstat.icps_inhist[i]); 545 } 546 p(icps_reflect, "\t%lu message response%s generated\n"); 547 #undef p 548 } 549 550 /* 551 * Dump IGMP statistics structure. 552 */ 553 void 554 igmp_stats(u_long off, char *name) 555 { 556 struct igmpstat igmpstat; 557 558 if (off == 0) 559 return; 560 kread(off, (char *)&igmpstat, sizeof (igmpstat)); 561 printf("%s:\n", name); 562 563 #define p(f, m) if (igmpstat.f || sflag <= 1) \ 564 printf(m, igmpstat.f, plural(igmpstat.f)) 565 #define py(f, m) if (igmpstat.f || sflag <= 1) \ 566 printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 567 568 p(igps_rcv_total, "\t%lu message%s received\n"); 569 p(igps_rcv_tooshort, "\t%lu message%s received with too few bytes\n"); 570 p(igps_rcv_badsum, "\t%lu message%s received with bad checksum\n"); 571 py(igps_rcv_queries, "\t%lu membership quer%s received\n"); 572 py(igps_rcv_badqueries, "\t%lu membership quer%s received with invalid field(s)\n"); 573 p(igps_rcv_reports, "\t%lu membership report%s received\n"); 574 p(igps_rcv_badreports, "\t%lu membership report%s received with invalid field(s)\n"); 575 p(igps_rcv_ourreports, "\t%lu membership report%s received for groups to which we belong\n"); 576 p(igps_snd_reports, "\t%lu membership report%s sent\n"); 577 #undef p 578 #undef py 579 } 580 581 struct rpcnams { 582 struct rpcnams *next; 583 in_port_t port; 584 int proto; 585 char *rpcname; 586 }; 587 588 static char * 589 getrpcportnam(in_port_t port, int proto) 590 { 591 struct sockaddr_in server_addr; 592 struct hostent *hp; 593 static struct pmaplist *head; 594 int socket = RPC_ANYSOCK; 595 struct timeval minutetimeout; 596 CLIENT *client; 597 struct rpcent *rpc; 598 static int first; 599 static struct rpcnams *rpcn; 600 struct rpcnams *n; 601 char num[20]; 602 603 if (first == 0) { 604 first = 1; 605 memset((char *)&server_addr, 0, sizeof server_addr); 606 server_addr.sin_family = AF_INET; 607 if ((hp = gethostbyname("localhost")) != NULL) 608 memmove((caddr_t)&server_addr.sin_addr, hp->h_addr, 609 hp->h_length); 610 else 611 (void) inet_aton("0.0.0.0", &server_addr.sin_addr); 612 613 minutetimeout.tv_sec = 60; 614 minutetimeout.tv_usec = 0; 615 server_addr.sin_port = htons(PMAPPORT); 616 if ((client = clnttcp_create(&server_addr, PMAPPROG, 617 PMAPVERS, &socket, 50, 500)) == NULL) 618 return (NULL); 619 if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL, 620 xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { 621 clnt_destroy(client); 622 return (NULL); 623 } 624 for (; head != NULL; head = head->pml_next) { 625 n = (struct rpcnams *)malloc(sizeof(struct rpcnams)); 626 if (n == NULL) 627 continue; 628 n->next = rpcn; 629 rpcn = n; 630 n->port = head->pml_map.pm_port; 631 n->proto = head->pml_map.pm_prot; 632 633 rpc = getrpcbynumber(head->pml_map.pm_prog); 634 if (rpc) 635 n->rpcname = strdup(rpc->r_name); 636 else { 637 snprintf(num, sizeof num, "%ld", 638 head->pml_map.pm_prog); 639 n->rpcname = strdup(num); 640 } 641 } 642 clnt_destroy(client); 643 } 644 645 for (n = rpcn; n; n = n->next) 646 if (n->port == port && n->proto == proto) 647 return (n->rpcname); 648 return (NULL); 649 } 650 651 /* 652 * Pretty print an Internet address (net address + port). 653 * If the nflag was specified, use numbers instead of names. 654 */ 655 void 656 inetprint(struct in_addr *in, in_port_t port, char *proto, int local) 657 { 658 struct servent *sp = 0; 659 char line[80], *cp, *nam; 660 int width; 661 662 snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16, 663 inetname(in)); 664 cp = strchr(line, '\0'); 665 if (!nflag && port) 666 sp = getservbyport((int)port, proto); 667 if (sp || port == 0) 668 snprintf(cp, line + sizeof line - cp, "%.8s", 669 sp ? sp->s_name : "*"); 670 else if (local && !nflag && (nam = getrpcportnam(ntohs(port), 671 (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP)))) 672 snprintf(cp, line + sizeof line - cp, "%d[%.8s]", 673 ntohs(port), nam); 674 else 675 snprintf(cp, line + sizeof line - cp, "%d", ntohs(port)); 676 width = Aflag ? 18 : 22; 677 printf(" %-*.*s", width, width, line); 678 } 679 680 /* 681 * Construct an Internet address representation. 682 * If the nflag has been supplied, give 683 * numeric value, otherwise try for symbolic name. 684 */ 685 char * 686 inetname(struct in_addr *inp) 687 { 688 char *cp; 689 static char line[50]; 690 struct hostent *hp; 691 struct netent *np; 692 static char domain[MAXHOSTNAMELEN]; 693 static int first = 1; 694 695 if (first && !nflag) { 696 first = 0; 697 if (gethostname(domain, sizeof(domain)) == 0 && 698 (cp = strchr(domain, '.'))) 699 (void) strlcpy(domain, cp + 1, sizeof domain); 700 else 701 domain[0] = '\0'; 702 } 703 cp = 0; 704 if (!nflag && inp->s_addr != INADDR_ANY) { 705 int net = inet_netof(*inp); 706 int lna = inet_lnaof(*inp); 707 708 if (lna == INADDR_ANY) { 709 np = getnetbyaddr(net, AF_INET); 710 if (np) 711 cp = np->n_name; 712 } 713 if (cp == 0) { 714 hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 715 if (hp) { 716 if ((cp = strchr(hp->h_name, '.')) && 717 !strcmp(cp + 1, domain)) 718 *cp = 0; 719 cp = hp->h_name; 720 } 721 } 722 } 723 if (inp->s_addr == INADDR_ANY) 724 snprintf(line, sizeof line, "*"); 725 else if (cp) 726 snprintf(line, sizeof line, "%s", cp); 727 else { 728 inp->s_addr = ntohl(inp->s_addr); 729 #define C(x) ((x) & 0xff) 730 snprintf(line, sizeof line, "%u.%u.%u.%u", 731 C(inp->s_addr >> 24), C(inp->s_addr >> 16), 732 C(inp->s_addr >> 8), C(inp->s_addr)); 733 } 734 return (line); 735 } 736 737 /* 738 * Dump AH statistics structure. 739 */ 740 void 741 ah_stats(u_long off, char *name) 742 { 743 struct ahstat ahstat; 744 745 if (off == 0) 746 return; 747 kread(off, (char *)&ahstat, sizeof (ahstat)); 748 printf("%s:\n", name); 749 750 #define p(f, m) if (ahstat.f || sflag <= 1) \ 751 printf(m, ahstat.f, plural(ahstat.f)) 752 #define p1(f, m) if (ahstat.f || sflag <= 1) \ 753 printf(m, ahstat.f) 754 755 p1(ahs_input, "\t%u input AH packets\n"); 756 p1(ahs_output, "\t%u output AH packets\n"); 757 p(ahs_nopf, "\t%u packet%s from unsupported protocol families\n"); 758 p(ahs_hdrops, "\t%u packet%s shorter than header shows\n"); 759 p(ahs_pdrops, "\t%u packet%s dropped due to policy\n"); 760 p(ahs_notdb, "\t%u packet%s for which no TDB was found\n"); 761 p(ahs_badkcr, "\t%u input packet%s that failed to be processed\n"); 762 p(ahs_badauth, "\t%u packet%s that failed verification received\n"); 763 p(ahs_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 764 p(ahs_qfull, "\t%u packet%s were dropped due to full output queue\n"); 765 p(ahs_wrap, "\t%u packet%s where counter wrapping was detected\n"); 766 p(ahs_replay, "\t%u possibly replayed packet%s received\n"); 767 p(ahs_badauthl, "\t%u packet%s with bad authenticator length received\n"); 768 p(ahs_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 769 p(ahs_toobig, "\t%u packet%s got larger than max IP packet size\n"); 770 p(ahs_crypto, "\t%u packet%s that failed crypto processing\n"); 771 p(ahs_ibytes, "\t%qu input byte%s\n"); 772 p(ahs_obytes, "\t%qu output byte%s\n"); 773 774 #undef p 775 #undef p1 776 } 777 778 /* 779 * Dump etherip statistics structure. 780 */ 781 void 782 etherip_stats(u_long off, char *name) 783 { 784 struct etheripstat etheripstat; 785 786 if (off == 0) 787 return; 788 kread(off, (char *)ðeripstat, sizeof (etheripstat)); 789 printf("%s:\n", name); 790 791 #define p(f, m) if (etheripstat.f || sflag <= 1) \ 792 printf(m, etheripstat.f, plural(etheripstat.f)) 793 794 p(etherip_hdrops, "\t%u packet%s shorter than header shows\n"); 795 p(etherip_qfull, "\t%u packet%s were dropped due to full output queue\n"); 796 p(etherip_noifdrops, "\t%u packet%s were dropped because of no interface/bridge information\n"); 797 p(etherip_pdrops, "\t%u packet%s dropped due to policy\n"); 798 p(etherip_adrops, "\t%u packet%s dropped for other reasons\n"); 799 p(etherip_ipackets, "\t%u input ethernet-in-IP packet%s\n"); 800 p(etherip_opackets, "\t%u output ethernet-in-IP packet%s\n"); 801 p(etherip_ibytes, "\t%qu input byte%s\n"); 802 p(etherip_obytes, "\t%qu output byte%s\n"); 803 #undef p 804 } 805 806 /* 807 * Dump ESP statistics structure. 808 */ 809 void 810 esp_stats(u_long off, char *name) 811 { 812 struct espstat espstat; 813 814 if (off == 0) 815 return; 816 kread(off, (char *)&espstat, sizeof (espstat)); 817 printf("%s:\n", name); 818 819 #define p(f, m) if (espstat.f || sflag <= 1) \ 820 printf(m, espstat.f, plural(espstat.f)) 821 822 p(esps_input, "\t%u input ESP packet%s\n"); 823 p(esps_output, "\t%u output ESP packet%s\n"); 824 p(esps_nopf, "\t%u packet%s from unsupported protocol families\n"); 825 p(esps_hdrops, "\t%u packet%s shorter than header shows\n"); 826 p(esps_pdrops, "\t%u packet%s dropped due to policy\n"); 827 p(esps_notdb, "\t%u packet%s for which no TDB was found\n"); 828 p(esps_badkcr, "\t%u input packet%s that failed to be processed\n"); 829 p(esps_badenc, "\t%u packet%s with bad encryption received\n"); 830 p(esps_badauth, "\t%u packet%s that failed verification received\n"); 831 p(esps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 832 p(esps_qfull, "\t%u packet%s were dropped due to full output queue\n"); 833 p(esps_wrap, "\t%u packet%s where counter wrapping was detected\n"); 834 p(esps_replay, "\t%u possibly replayed packet%s received\n"); 835 p(esps_badilen, "\t%u packet%s with bad payload size or padding received\n"); 836 p(esps_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 837 p(esps_toobig, "\t%u packet%s got larger than max IP packet size\n"); 838 p(esps_crypto, "\t%u packet%s that failed crypto processing\n"); 839 p(esps_udpencin, "\t%u input UDP encapsulated ESP packet%s\n"); 840 p(esps_udpencout, "\t%u output UDP encapsulated ESP packet%s\n"); 841 p(esps_udpinval, "\t%u UDP packet%s for non-encapsulating TDB received\n"); 842 p(esps_ibytes, "\t%qu input byte%s\n"); 843 p(esps_obytes, "\t%qu output byte%s\n"); 844 845 #undef p 846 } 847 848 /* 849 * Dump IP-in-IP statistics structure. 850 */ 851 void 852 ipip_stats(u_long off, char *name) 853 { 854 struct ipipstat ipipstat; 855 856 if (off == 0) 857 return; 858 kread(off, (char *)&ipipstat, sizeof (ipipstat)); 859 printf("%s:\n", name); 860 861 #define p(f, m) if (ipipstat.f || sflag <= 1) \ 862 printf(m, ipipstat.f, plural(ipipstat.f)) 863 864 p(ipips_ipackets, "\t%u total input packet%s\n"); 865 p(ipips_opackets, "\t%u total output packet%s\n"); 866 p(ipips_hdrops, "\t%u packet%s shorter than header shows\n"); 867 p(ipips_pdrops, "\t%u packet%s dropped due to policy\n"); 868 p(ipips_spoof, "\t%u packet%s with possibly spoofed local addresses\n"); 869 p(ipips_qfull, "\t%u packet%s were dropped due to full output queue\n"); 870 p(ipips_ibytes, "\t%qu input byte%s\n"); 871 p(ipips_obytes, "\t%qu output byte%s\n"); 872 p(ipips_family, "\t%u protocol family mismatche%s\n"); 873 p(ipips_unspec, "\t%u attempt%s to use tunnel with unspecified endpoint(s)\n"); 874 #undef p 875 } 876 877 /* 878 * Dump CARP statistics structure. 879 */ 880 void 881 carp_stats(u_long off, char *name) 882 { 883 struct carpstats carpstat; 884 885 if (off == 0) 886 return; 887 kread(off, (char *)&carpstat, sizeof(carpstat)); 888 printf("%s:\n", name); 889 890 #define p(f, m) if (carpstat.f || sflag <= 1) \ 891 printf(m, carpstat.f, plural(carpstat.f)) 892 #define p2(f, m) if (carpstat.f || sflag <= 1) \ 893 printf(m, carpstat.f) 894 895 p(carps_ipackets, "\t%lu packet%s received (IPv4)\n"); 896 p(carps_ipackets6, "\t%lu packet%s received (IPv6)\n"); 897 p(carps_badif, "\t\t%lu packet%s discarded for bad interface\n"); 898 p(carps_hdrops, "\t\t%lu packet%s shorter than header\n"); 899 p(carps_badsum, "\t\t%lu discarded for bad checksum%s\n"); 900 p(carps_badver, "\t\t%lu discarded packet%s with a bad version\n"); 901 p2(carps_badlen, "\t\t%lu discarded because packet too short\n"); 902 p2(carps_badauth, "\t\t%lu discarded for bad authentication\n"); 903 p2(carps_badvhid, "\t\t%lu discarded for bad vhid\n"); 904 p2(carps_badaddrs, "\t\t%lu discarded because of a bad address list\n"); 905 p(carps_opackets, "\t%lu packet%s sent (IPv4)\n"); 906 p(carps_opackets6, "\t%lu packet%s sent (IPv6)\n"); 907 #if notyet 908 p(carps_ostates, "\t\t%s state update%s sent\n"); 909 #endif 910 #undef p 911 #undef p2 912 } 913 914 /* 915 * Dump pfsync statistics structure. 916 */ 917 void 918 pfsync_stats(u_long off, char *name) 919 { 920 struct pfsyncstats pfsyncstat; 921 922 if (off == 0) 923 return; 924 kread(off, (char *)&pfsyncstat, sizeof(pfsyncstat)); 925 printf("%s:\n", name); 926 927 #define p(f, m) if (pfsyncstat.f || sflag <= 1) \ 928 printf(m, pfsyncstat.f, plural(pfsyncstat.f)) 929 #define p2(f, m) if (pfsyncstat.f || sflag <= 1) \ 930 printf(m, pfsyncstat.f) 931 932 p(pfsyncs_ipackets, "\t%lu packet%s received (IPv4)\n"); 933 p(pfsyncs_ipackets6, "\t%lu packet%s received (IPv6)\n"); 934 p(pfsyncs_badif, "\t\t%lu packet%s discarded for bad interface\n"); 935 p(pfsyncs_badttl, "\t\t%lu packet%s discarded for bad ttl\n"); 936 p(pfsyncs_hdrops, "\t\t%lu packet%s shorter than header\n"); 937 p(pfsyncs_badver, "\t\t%lu discarded packet%s with a bad version\n"); 938 p(pfsyncs_badact, "\t\t%lu discarded packet%s with a bad action\n"); 939 p2(pfsyncs_badlen, "\t\t%lu discarded because packet too short\n"); 940 p2(pfsyncs_badauth, "\t\t%lu discarded for bad authentication\n"); 941 p(pfsyncs_badstate, "\t%lu failed state lookup/insert%s\n"); 942 p(pfsyncs_opackets, "\t%lu packet%s sent (IPv4)\n"); 943 p(pfsyncs_opackets6, "\t%lu packet%s sent (IPv6)\n"); 944 p2(pfsyncs_onomem, "\t\t%lu send failed due to mbuf memory error\n"); 945 p2(pfsyncs_oerrors, "\t\t%lu send error\n"); 946 #undef p 947 #undef p2 948 } 949 950 /* 951 * Dump IPCOMP statistics structure. 952 */ 953 void 954 ipcomp_stats(u_long off, char *name) 955 { 956 struct ipcompstat ipcompstat; 957 958 if (off == 0) 959 return; 960 kread(off, (char *)&ipcompstat, sizeof (ipcompstat)); 961 printf("%s:\n", name); 962 963 #define p(f, m) if (ipcompstat.f || sflag <= 1) \ 964 printf(m, ipcompstat.f, plural(ipcompstat.f)) 965 966 p(ipcomps_input, "\t%u input IPCOMP packet%s\n"); 967 p(ipcomps_output, "\t%u output IPCOMP packet%s\n"); 968 p(ipcomps_nopf, "\t%u packet%s from unsupported protocol families\n"); 969 p(ipcomps_hdrops, "\t%u packet%s shorter than header shows\n"); 970 p(ipcomps_pdrops, "\t%u packet%s dropped due to policy\n"); 971 p(ipcomps_notdb, "\t%u packet%s for which no TDB was found\n"); 972 p(ipcomps_badkcr, "\t%u input packet%s that failed to be processed\n"); 973 p(ipcomps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 974 p(ipcomps_qfull, "\t%u packet%s were dropped due to full output queue\n"); 975 p(ipcomps_wrap, "\t%u packet%s where counter wrapping was detected\n"); 976 p(ipcomps_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 977 p(ipcomps_toobig, "\t%u packet%s got larger than max IP packet size\n"); 978 p(ipcomps_crypto, "\t%u packet%s that failed (de)compression processing\n"); 979 p(ipcomps_minlen, "\t%u packet%s less than minimum compression length\n"); 980 p(ipcomps_ibytes, "\t%qu input byte%s\n"); 981 p(ipcomps_obytes, "\t%qu output byte%s\n"); 982 983 #undef p 984 } 985