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