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