1 /* $OpenBSD: inet.c,v 1.62 2002/06/09 04:07:10 jsyn 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. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #ifndef lint 38 #if 0 39 static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94"; 40 #else 41 static char *rcsid = "$OpenBSD: inet.c,v 1.62 2002/06/09 04:07:10 jsyn Exp $"; 42 #endif 43 #endif /* not lint */ 44 45 #include <sys/param.h> 46 #include <sys/queue.h> 47 #include <sys/socket.h> 48 #include <sys/socketvar.h> 49 #include <sys/mbuf.h> 50 #include <sys/protosw.h> 51 52 #include <net/route.h> 53 #include <netinet/in.h> 54 #include <netinet/in_systm.h> 55 #include <netinet/ip.h> 56 #include <netinet/in_pcb.h> 57 #include <netinet/ip_icmp.h> 58 #include <netinet/icmp_var.h> 59 #include <netinet/igmp_var.h> 60 #include <netinet/ip_var.h> 61 #include <netinet/tcp.h> 62 #include <netinet/tcpip.h> 63 #include <netinet/tcp_seq.h> 64 #define TCPSTATES 65 #include <netinet/tcp_fsm.h> 66 #include <netinet/tcp_timer.h> 67 #include <netinet/tcp_var.h> 68 #include <netinet/tcp_debug.h> 69 #include <netinet/udp.h> 70 #include <netinet/udp_var.h> 71 #include <netinet/ip_ipsp.h> 72 #include <netinet/ip_ah.h> 73 #include <netinet/ip_esp.h> 74 #include <netinet/ip_ipip.h> 75 #include <netinet/ip_ipcomp.h> 76 #include <netinet/ip_ether.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 *, int, 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(off, name) 112 u_long off; 113 char *name; 114 { 115 protopr0(off, name, AF_INET); 116 } 117 118 #ifdef INET6 119 void 120 ip6protopr(off, name) 121 u_long off; 122 char *name; 123 { 124 protopr0(off, name, AF_INET6); 125 } 126 #endif 127 128 static void 129 protopr0(off, name, af) 130 u_long off; 131 char *name; 132 int af; 133 { 134 struct inpcbtable table; 135 struct inpcb *head, *next, *prev; 136 struct inpcb inpcb; 137 int istcp; 138 int first = 1; 139 char *name0; 140 char namebuf[20]; 141 142 name0 = name; 143 if (off == 0) 144 return; 145 istcp = strcmp(name, "tcp") == 0; 146 kread(off, (char *)&table, sizeof table); 147 prev = head = 148 (struct inpcb *)&((struct inpcbtable *)off)->inpt_queue.cqh_first; 149 next = table.inpt_queue.cqh_first; 150 151 while (next != head) { 152 kread((u_long)next, (char *)&inpcb, sizeof inpcb); 153 if (inpcb.inp_queue.cqe_prev != prev) { 154 printf("???\n"); 155 break; 156 } 157 prev = next; 158 next = inpcb.inp_queue.cqe_next; 159 160 switch (af) { 161 case AF_INET: 162 if ((inpcb.inp_flags & INP_IPV6) != 0) 163 continue; 164 break; 165 case AF_INET6: 166 if ((inpcb.inp_flags & INP_IPV6) == 0) 167 continue; 168 break; 169 default: 170 break; 171 } 172 173 if (!aflag && 174 inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) 175 continue; 176 kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb)); 177 if (istcp) { 178 kread((u_long)inpcb.inp_ppcb, 179 (char *)&tcpcb, sizeof (tcpcb)); 180 } 181 if (first) { 182 printf("Active Internet connections"); 183 if (aflag) 184 printf(" (including servers)"); 185 putchar('\n'); 186 if (Aflag) 187 printf("%-*.*s %-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n", 188 PLEN, PLEN, "PCB", "Proto", "Recv-Q", 189 "Send-Q", "Local Address", 190 "Foreign Address", "(state)"); 191 else 192 printf("%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 193 "Proto", "Recv-Q", "Send-Q", 194 "Local Address", "Foreign Address", 195 "(state)"); 196 first = 0; 197 } 198 if (Aflag) { 199 if (istcp) 200 printf("%*p ", PLEN, inpcb.inp_ppcb); 201 else 202 printf("%*p ", PLEN, prev); 203 } 204 #ifdef INET6 205 if (inpcb.inp_flags & INP_IPV6) { 206 strlcpy(namebuf, name0, sizeof namebuf); 207 strlcat(namebuf, "6", sizeof namebuf); 208 name = namebuf; 209 } else 210 name = name0; 211 #endif 212 printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc, 213 sockb.so_snd.sb_cc); 214 #ifdef INET6 215 if (inpcb.inp_flags & INP_IPV6) { 216 inet6print(&inpcb.inp_laddr6, (int)inpcb.inp_lport, 217 name, 1); 218 inet6print(&inpcb.inp_faddr6, (int)inpcb.inp_fport, 219 name, 0); 220 } else 221 #endif 222 { 223 inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport, 224 name, 1); 225 inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport, 226 name, 0); 227 } 228 if (istcp) { 229 if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES) 230 printf(" %d", tcpcb.t_state); 231 else 232 printf(" %s", tcpstates[tcpcb.t_state]); 233 } 234 putchar('\n'); 235 } 236 } 237 238 /* 239 * Dump TCP statistics structure. 240 */ 241 void 242 tcp_stats(off, name) 243 u_long off; 244 char *name; 245 { 246 struct tcpstat tcpstat; 247 248 if (off == 0) 249 return; 250 printf ("%s:\n", name); 251 kread(off, (char *)&tcpstat, sizeof (tcpstat)); 252 253 #define p(f, m) if (tcpstat.f || sflag <= 1) \ 254 printf(m, tcpstat.f, plural(tcpstat.f)) 255 #define p1(f, m) if (tcpstat.f || sflag <= 1) \ 256 printf(m, tcpstat.f) 257 #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 258 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) 259 #define p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 260 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2) 261 #define p3(f, m) if (tcpstat.f || sflag <= 1) \ 262 printf(m, tcpstat.f, plurales(tcpstat.f)) 263 264 p(tcps_sndtotal, "\t%u packet%s sent\n"); 265 p2(tcps_sndpack,tcps_sndbyte, 266 "\t\t%u data packet%s (%qd byte%s)\n"); 267 p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, 268 "\t\t%u data packet%s (%qd byte%s) retransmitted\n"); 269 p(tcps_sndrexmitfast, "\t\t%qd fast retransmitted packet%s\n"); 270 p2a(tcps_sndacks, tcps_delack, 271 "\t\t%u ack-only packet%s (%u delayed)\n"); 272 p(tcps_sndurg, "\t\t%u URG only packet%s\n"); 273 p(tcps_sndprobe, "\t\t%u window probe packet%s\n"); 274 p(tcps_sndwinup, "\t\t%u window update packet%s\n"); 275 p(tcps_sndctrl, "\t\t%u control packet%s\n"); 276 p(tcps_outhwcsum, "\t\t%u packet%s hardware-checksummed\n"); 277 p(tcps_rcvtotal, "\t%u packet%s received\n"); 278 p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%u ack%s (for %qd byte%s)\n"); 279 p(tcps_rcvdupack, "\t\t%u duplicate ack%s\n"); 280 p(tcps_rcvacktoomuch, "\t\t%u ack%s for unsent data\n"); 281 p2(tcps_rcvpack, tcps_rcvbyte, 282 "\t\t%u packet%s (%qu byte%s) received in-sequence\n"); 283 p2(tcps_rcvduppack, tcps_rcvdupbyte, 284 "\t\t%u completely duplicate packet%s (%qd byte%s)\n"); 285 p(tcps_pawsdrop, "\t\t%u old duplicate packet%s\n"); 286 p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, 287 "\t\t%u packet%s with some duplicate data (%qd byte%s duplicated)\n"); 288 p2(tcps_rcvoopack, tcps_rcvoobyte, 289 "\t\t%u out-of-order packet%s (%qd byte%s)\n"); 290 p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, 291 "\t\t%u packet%s (%qd byte%s) of data after window\n"); 292 p(tcps_rcvwinprobe, "\t\t%u window probe%s\n"); 293 p(tcps_rcvwinupd, "\t\t%u window update packet%s\n"); 294 p(tcps_rcvafterclose, "\t\t%u packet%s received after close\n"); 295 p(tcps_rcvbadsum, "\t\t%u discarded for bad checksum%s\n"); 296 p(tcps_rcvbadoff, "\t\t%u discarded for bad header offset field%s\n"); 297 p1(tcps_rcvshort, "\t\t%u discarded because packet too short\n"); 298 p1(tcps_rcvnosec, "\t\t%u discarded for missing IPsec protection\n"); 299 p(tcps_inhwcsum, "\t\t%u packet%s hardware-checksummed\n"); 300 p(tcps_connattempt, "\t%u connection request%s\n"); 301 p(tcps_accepts, "\t%u connection accept%s\n"); 302 p(tcps_connects, "\t%u connection%s established (including accepts)\n"); 303 p2(tcps_closed, tcps_drops, 304 "\t%u connection%s closed (including %u drop%s)\n"); 305 p(tcps_conndrops, "\t%u embryonic connection%s dropped\n"); 306 p2(tcps_rttupdated, tcps_segstimed, 307 "\t%u segment%s updated rtt (of %u attempt%s)\n"); 308 p(tcps_rexmttimeo, "\t%u retransmit timeout%s\n"); 309 p(tcps_timeoutdrop, "\t\t%u connection%s dropped by rexmit timeout\n"); 310 p(tcps_persisttimeo, "\t%u persist timeout%s\n"); 311 p(tcps_keeptimeo, "\t%u keepalive timeout%s\n"); 312 p(tcps_keepprobe, "\t\t%u keepalive probe%s sent\n"); 313 p(tcps_keepdrops, "\t\t%u connection%s dropped by keepalive\n"); 314 p(tcps_predack, "\t%u correct ACK header prediction%s\n"); 315 p(tcps_preddat, "\t%u correct data packet header prediction%s\n"); 316 p3(tcps_pcbhashmiss, "\t%u PCB cache miss%s\n"); 317 p(tcps_badsyn, "\t%u SYN packet%s received with same src/dst address/port\n"); 318 319 p(tcps_ecn_accepts, "\t%u ECN connection%s accepted\n"); 320 p(tcps_ecn_rcvece, "\t\t%u ECE packet%s received\n"); 321 p(tcps_ecn_rcvcwr, "\t\t%u CWR packet%s received\n"); 322 p(tcps_ecn_rcvce, "\t\t%u CE packet%s received\n"); 323 p(tcps_ecn_sndect, "\t\t%u ECT packet%s sent\n"); 324 p(tcps_ecn_sndece, "\t\t%u ECE packet%s sent\n"); 325 p(tcps_ecn_sndcwr, "\t\t%u CWR packet%s sent\n"); 326 p1(tcps_cwr_frecovery, "\t\t\tcwr by fastrecovery: %u\n"); 327 p1(tcps_cwr_timeout, "\t\t\tcwr by timeout: %u\n"); 328 p1(tcps_cwr_ecn, "\t\t\tcwr by ecn: %u\n"); 329 330 #undef p 331 #undef p1 332 #undef p2 333 #undef p2a 334 #undef p3 335 } 336 337 /* 338 * Dump UDP statistics structure. 339 */ 340 void 341 udp_stats(off, name) 342 u_long off; 343 char *name; 344 { 345 struct udpstat udpstat; 346 u_long delivered; 347 348 if (off == 0) 349 return; 350 kread(off, (char *)&udpstat, sizeof (udpstat)); 351 printf("%s:\n", name); 352 #define p(f, m) if (udpstat.f || sflag <= 1) \ 353 printf(m, udpstat.f, plural(udpstat.f)) 354 #define p1(f, m) if (udpstat.f || sflag <= 1) \ 355 printf(m, udpstat.f) 356 357 p(udps_ipackets, "\t%lu datagram%s received\n"); 358 p1(udps_hdrops, "\t%lu with incomplete header\n"); 359 p1(udps_badlen, "\t%lu with bad data length field\n"); 360 p1(udps_badsum, "\t%lu with bad checksum\n"); 361 p1(udps_nosum, "\t%lu with no checksum\n"); 362 p(udps_inhwcsum, "\t%lu input packet%s hardware-checksummed\n"); 363 p(udps_outhwcsum, "\t%lu output packet%s hardware-checksummed\n"); 364 p1(udps_noport, "\t%lu dropped due to no socket\n"); 365 p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n"); 366 p1(udps_nosec, "\t%lu dropped due to missing IPsec protection\n"); 367 p1(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); 368 delivered = udpstat.udps_ipackets - udpstat.udps_hdrops - 369 udpstat.udps_badlen - udpstat.udps_badsum - 370 udpstat.udps_noport - udpstat.udps_noportbcast - 371 udpstat.udps_fullsock; 372 if (delivered || sflag <= 1) 373 printf("\t%lu delivered\n", delivered); 374 p(udps_opackets, "\t%lu datagram%s output\n"); 375 p1(udps_pcbhashmiss, "\t%lu missed PCB cache\n"); 376 #undef p 377 #undef p1 378 } 379 380 /* 381 * Dump IP statistics structure. 382 */ 383 void 384 ip_stats(off, name) 385 u_long off; 386 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[] = { 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 }; 456 457 /* 458 * Dump ICMP statistics. 459 */ 460 void 461 icmp_stats(off, name) 462 u_long off; 463 char *name; 464 { 465 struct icmpstat icmpstat; 466 int i, first; 467 468 if (off == 0) 469 return; 470 kread(off, (char *)&icmpstat, sizeof (icmpstat)); 471 printf("%s:\n", name); 472 473 #define p(f, m) if (icmpstat.f || sflag <= 1) \ 474 printf(m, icmpstat.f, plural(icmpstat.f)) 475 476 p(icps_error, "\t%lu call%s to icmp_error\n"); 477 p(icps_oldicmp, 478 "\t%lu error%s not generated because old message was icmp\n"); 479 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 480 if (icmpstat.icps_outhist[i] != 0) { 481 if (first) { 482 printf("\tOutput packet histogram:\n"); 483 first = 0; 484 } 485 printf("\t\t%s: %lu\n", icmpnames[i], 486 icmpstat.icps_outhist[i]); 487 } 488 p(icps_badcode, "\t%lu message%s with bad code fields\n"); 489 p(icps_tooshort, "\t%lu message%s < minimum length\n"); 490 p(icps_checksum, "\t%lu bad checksum%s\n"); 491 p(icps_badlen, "\t%lu message%s with bad length\n"); 492 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 493 if (icmpstat.icps_inhist[i] != 0) { 494 if (first) { 495 printf("\tInput packet histogram:\n"); 496 first = 0; 497 } 498 printf("\t\t%s: %lu\n", icmpnames[i], 499 icmpstat.icps_inhist[i]); 500 } 501 p(icps_reflect, "\t%lu message response%s generated\n"); 502 #undef p 503 } 504 505 /* 506 * Dump IGMP statistics structure. 507 */ 508 void 509 igmp_stats(off, name) 510 u_long off; 511 char *name; 512 { 513 struct igmpstat igmpstat; 514 515 if (off == 0) 516 return; 517 kread(off, (char *)&igmpstat, sizeof (igmpstat)); 518 printf("%s:\n", name); 519 520 #define p(f, m) if (igmpstat.f || sflag <= 1) \ 521 printf(m, igmpstat.f, plural(igmpstat.f)) 522 #define py(f, m) if (igmpstat.f || sflag <= 1) \ 523 printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 524 525 p(igps_rcv_total, "\t%lu message%s received\n"); 526 p(igps_rcv_tooshort, "\t%lu message%s received with too few bytes\n"); 527 p(igps_rcv_badsum, "\t%lu message%s received with bad checksum\n"); 528 py(igps_rcv_queries, "\t%lu membership quer%s received\n"); 529 py(igps_rcv_badqueries, "\t%lu membership quer%s received with invalid field(s)\n"); 530 p(igps_rcv_reports, "\t%lu membership report%s received\n"); 531 p(igps_rcv_badreports, "\t%lu membership report%s received with invalid field(s)\n"); 532 p(igps_rcv_ourreports, "\t%lu membership report%s received for groups to which we belong\n"); 533 p(igps_snd_reports, "\t%lu membership report%s sent\n"); 534 #undef p 535 #undef py 536 } 537 538 struct rpcnams { 539 struct rpcnams *next; 540 in_port_t port; 541 int proto; 542 char *rpcname; 543 }; 544 545 char * 546 getrpcportnam(port, proto) 547 in_port_t port; 548 int proto; 549 { 550 struct sockaddr_in server_addr; 551 struct hostent *hp; 552 static struct pmaplist *head; 553 int socket = RPC_ANYSOCK; 554 struct timeval minutetimeout; 555 CLIENT *client; 556 struct rpcent *rpc; 557 static int first; 558 static struct rpcnams *rpcn; 559 struct rpcnams *n; 560 char num[20]; 561 562 if (first == 0) { 563 first = 1; 564 memset((char *)&server_addr, 0, sizeof server_addr); 565 server_addr.sin_family = AF_INET; 566 if ((hp = gethostbyname("localhost")) != NULL) 567 memmove((caddr_t)&server_addr.sin_addr, hp->h_addr, 568 hp->h_length); 569 else 570 (void) inet_aton("0.0.0.0", &server_addr.sin_addr); 571 572 minutetimeout.tv_sec = 60; 573 minutetimeout.tv_usec = 0; 574 server_addr.sin_port = htons(PMAPPORT); 575 if ((client = clnttcp_create(&server_addr, PMAPPROG, 576 PMAPVERS, &socket, 50, 500)) == NULL) 577 return (NULL); 578 if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL, 579 xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { 580 clnt_destroy(client); 581 return (NULL); 582 } 583 for (; head != NULL; head = head->pml_next) { 584 n = (struct rpcnams *)malloc(sizeof(struct rpcnams)); 585 if (n == NULL) 586 continue; 587 n->next = rpcn; 588 rpcn = n; 589 n->port = head->pml_map.pm_port; 590 n->proto = head->pml_map.pm_prot; 591 592 rpc = getrpcbynumber(head->pml_map.pm_prog); 593 if (rpc) 594 n->rpcname = strdup(rpc->r_name); 595 else { 596 snprintf(num, sizeof num, "%ld", 597 head->pml_map.pm_prog); 598 n->rpcname = strdup(num); 599 } 600 } 601 clnt_destroy(client); 602 } 603 604 for (n = rpcn; n; n = n->next) 605 if (n->port == port && n->proto == proto) 606 return (n->rpcname); 607 return (NULL); 608 } 609 610 /* 611 * Pretty print an Internet address (net address + port). 612 * If the nflag was specified, use numbers instead of names. 613 */ 614 void 615 inetprint(in, port, proto, local) 616 struct in_addr *in; 617 in_port_t port; 618 char *proto; 619 int local; 620 { 621 struct servent *sp = 0; 622 char line[80], *cp, *nam; 623 int width; 624 625 snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16, 626 inetname(in)); 627 cp = strchr(line, '\0'); 628 if (!nflag && port) 629 sp = getservbyport((int)port, proto); 630 if (sp || port == 0) 631 snprintf(cp, line + sizeof line - cp, "%.8s", 632 sp ? sp->s_name : "*"); 633 else if (local && !nflag && (nam = getrpcportnam(ntohs(port), 634 (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP)))) 635 snprintf(cp, line + sizeof line - cp, "%d[%.8s]", 636 ntohs(port), nam); 637 else 638 snprintf(cp, line + sizeof line - cp, "%d", ntohs(port)); 639 width = Aflag ? 18 : 22; 640 printf(" %-*.*s", width, width, line); 641 } 642 643 /* 644 * Construct an Internet address representation. 645 * If the nflag has been supplied, give 646 * numeric value, otherwise try for symbolic name. 647 */ 648 char * 649 inetname(inp) 650 struct in_addr *inp; 651 { 652 char *cp; 653 static char line[50]; 654 struct hostent *hp; 655 struct netent *np; 656 static char domain[MAXHOSTNAMELEN]; 657 static int first = 1; 658 659 if (first && !nflag) { 660 first = 0; 661 if (gethostname(domain, sizeof(domain)) == 0 && 662 (cp = strchr(domain, '.'))) 663 (void) strlcpy(domain, cp + 1, sizeof domain); 664 else 665 domain[0] = '\0'; 666 } 667 cp = 0; 668 if (!nflag && inp->s_addr != INADDR_ANY) { 669 int net = inet_netof(*inp); 670 int lna = inet_lnaof(*inp); 671 672 if (lna == INADDR_ANY) { 673 np = getnetbyaddr(net, AF_INET); 674 if (np) 675 cp = np->n_name; 676 } 677 if (cp == 0) { 678 hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 679 if (hp) { 680 if ((cp = strchr(hp->h_name, '.')) && 681 !strcmp(cp + 1, domain)) 682 *cp = 0; 683 cp = hp->h_name; 684 } 685 } 686 } 687 if (inp->s_addr == INADDR_ANY) 688 snprintf(line, sizeof line, "*"); 689 else if (cp) 690 snprintf(line, sizeof line, "%s", cp); 691 else { 692 inp->s_addr = ntohl(inp->s_addr); 693 #define C(x) ((x) & 0xff) 694 snprintf(line, sizeof line, "%u.%u.%u.%u", 695 C(inp->s_addr >> 24), C(inp->s_addr >> 16), 696 C(inp->s_addr >> 8), C(inp->s_addr)); 697 } 698 return (line); 699 } 700 701 /* 702 * Dump AH statistics structure. 703 */ 704 void 705 ah_stats(off, name) 706 u_long off; 707 char *name; 708 { 709 struct ahstat ahstat; 710 711 if (off == 0) 712 return; 713 kread(off, (char *)&ahstat, sizeof (ahstat)); 714 printf("%s:\n", name); 715 716 #define p(f, m) if (ahstat.f || sflag <= 1) \ 717 printf(m, ahstat.f, plural(ahstat.f)) 718 #define p1(f, m) if (ahstat.f || sflag <= 1) \ 719 printf(m, ahstat.f) 720 721 p1(ahs_input, "\t%u input AH packets\n"); 722 p1(ahs_output, "\t%u output AH packets\n"); 723 p(ahs_nopf, "\t%u packet%s from unsupported protocol families\n"); 724 p(ahs_hdrops, "\t%u packet%s shorter than header shows\n"); 725 p(ahs_pdrops, "\t%u packet%s dropped due to policy\n"); 726 p(ahs_notdb, "\t%u packet%s for which no TDB was found\n"); 727 p(ahs_badkcr, "\t%u input packet%s that failed to be processed\n"); 728 p(ahs_badauth, "\t%u packet%s that failed verification received\n"); 729 p(ahs_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 730 p(ahs_qfull, "\t%u packet%s were dropped due to full output queue\n"); 731 p(ahs_wrap, "\t%u packet%s where counter wrapping was detected\n"); 732 p(ahs_replay, "\t%u possibly replayed packet%s received\n"); 733 p(ahs_badauthl, "\t%u packet%s with bad authenticator length received\n"); 734 p(ahs_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 735 p(ahs_toobig, "\t%u packet%s got larger than max IP packet size\n"); 736 p(ahs_crypto, "\t%u packet%s that failed crypto processing\n"); 737 p(ahs_ibytes, "\t%qu input byte%s\n"); 738 p(ahs_obytes, "\t%qu output byte%s\n"); 739 740 #undef p 741 #undef p1 742 } 743 744 /* 745 * Dump etherip statistics structure. 746 */ 747 void 748 etherip_stats(off, name) 749 u_long off; 750 char *name; 751 { 752 struct etheripstat etheripstat; 753 754 if (off == 0) 755 return; 756 kread(off, (char *)ðeripstat, sizeof (etheripstat)); 757 printf("%s:\n", name); 758 759 #define p(f, m) if (etheripstat.f || sflag <= 1) \ 760 printf(m, etheripstat.f, plural(etheripstat.f)) 761 762 763 p(etherip_hdrops, "\t%u packet%s shorter than header shows\n"); 764 p(etherip_qfull, "\t%u packet%s were dropped due to full output queue\n"); 765 p(etherip_noifdrops, "\t%u packet%s were dropped because of no interface/bridge information\n"); 766 p(etherip_pdrops, "\t%u packet%s dropped due to policy\n"); 767 p(etherip_adrops, "\t%u packet%s dropped for other reasons\n"); 768 p(etherip_ipackets, "\t%u input ethernet-in-IP packet%s\n"); 769 p(etherip_opackets, "\t%u output ethernet-in-IP packet%s\n"); 770 p(etherip_ibytes, "\t%qu input byte%s\n"); 771 p(etherip_obytes, "\t%qu output byte%s\n"); 772 #undef p 773 } 774 775 /* 776 * Dump ESP statistics structure. 777 */ 778 void 779 esp_stats(off, name) 780 u_long off; 781 char *name; 782 { 783 struct espstat espstat; 784 785 if (off == 0) 786 return; 787 kread(off, (char *)&espstat, sizeof (espstat)); 788 printf("%s:\n", name); 789 790 #define p(f, m) if (espstat.f || sflag <= 1) \ 791 printf(m, espstat.f, plural(espstat.f)) 792 793 p(esps_input, "\t%u input ESP packet%s\n"); 794 p(esps_output, "\t%u output ESP packet%s\n"); 795 p(esps_nopf, "\t%u packet%s from unsupported protocol families\n"); 796 p(esps_hdrops, "\t%u packet%s shorter than header shows\n"); 797 p(esps_pdrops, "\t%u packet%s dropped due to policy\n"); 798 p(esps_notdb, "\t%u packet%s for which no TDB was found\n"); 799 p(esps_badkcr, "\t%u input packet%s that failed to be processed\n"); 800 p(esps_badenc, "\t%u packet%s with bad encryption received\n"); 801 p(esps_badauth, "\t%u packet%s that failed verification received\n"); 802 p(esps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 803 p(esps_qfull, "\t%u packet%s were dropped due to full output queue\n"); 804 p(esps_wrap, "\t%u packet%s where counter wrapping was detected\n"); 805 p(esps_replay, "\t%u possibly replayed packet%s received\n"); 806 p(esps_badilen, "\t%u packet%s with bad payload size or padding received\n"); 807 p(esps_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 808 p(esps_toobig, "\t%u packet%s got larger than max IP packet size\n"); 809 p(esps_crypto, "\t%u packet%s that failed crypto processing\n"); 810 p(esps_ibytes, "\t%qu input byte%s\n"); 811 p(esps_obytes, "\t%qu output byte%s\n"); 812 813 #undef p 814 } 815 816 /* 817 * Dump ESP statistics structure. 818 */ 819 void 820 ipip_stats(off, name) 821 u_long off; 822 char *name; 823 { 824 struct ipipstat ipipstat; 825 826 if (off == 0) 827 return; 828 kread(off, (char *)&ipipstat, sizeof (ipipstat)); 829 printf("%s:\n", name); 830 831 #define p(f, m) if (ipipstat.f || sflag <= 1) \ 832 printf(m, ipipstat.f, plural(ipipstat.f)) 833 834 p(ipips_ipackets, "\t%u total input packet%s\n"); 835 p(ipips_opackets, "\t%u total output packet%s\n"); 836 p(ipips_hdrops, "\t%u packet%s shorter than header shows\n"); 837 p(ipips_pdrops, "\t%u packet%s dropped due to policy\n"); 838 p(ipips_spoof, "\t%u packet%s with possibly spoofed local addresses\n"); 839 p(ipips_qfull, "\t%u packet%s were dropped due to full output queue\n"); 840 p(ipips_ibytes, "\t%qu input byte%s\n"); 841 p(ipips_obytes, "\t%qu output byte%s\n"); 842 p(ipips_family, "\t%u protocol family mismatches\n"); 843 p(ipips_unspec, "\t%u attempts to use tunnel with unspecified endpoint(s)\n"); 844 #undef p 845 } 846 847 /* 848 * Dump IPCOMP statistics structure. 849 */ 850 void 851 ipcomp_stats(off, name) 852 u_long off; 853 char *name; 854 { 855 struct ipcompstat ipcompstat; 856 857 if (off == 0) 858 return; 859 kread(off, (char *)&ipcompstat, sizeof (ipcompstat)); 860 printf("%s:\n", name); 861 862 #define p(f, m) if (ipcompstat.f || sflag <= 1) \ 863 printf(m, ipcompstat.f, plural(ipcompstat.f)) 864 865 p(ipcomps_input, "\t%u input IPCOMP packet%s\n"); 866 p(ipcomps_output, "\t%u output IPCOMP packet%s\n"); 867 p(ipcomps_nopf, "\t%u packet%s from unsupported protocol families\n"); 868 p(ipcomps_hdrops, "\t%u packet%s shorter than header shows\n"); 869 p(ipcomps_pdrops, "\t%u packet%s dropped due to policy\n"); 870 p(ipcomps_notdb, "\t%u packet%s for which no TDB was found\n"); 871 p(ipcomps_badkcr, "\t%u input packet%s that failed to be processed\n"); 872 p(ipcomps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 873 p(ipcomps_qfull, "\t%u packet%s were dropped due to full output queue\n"); 874 p(ipcomps_wrap, "\t%u packet%s where counter wrapping was detected\n"); 875 p(ipcomps_invalid, "\t%u packet%s attempted to use an invalid TDB\n"); 876 p(ipcomps_toobig, "\t%u packet%s got larger than max IP packet size\n"); 877 p(ipcomps_crypto, "\t%u packet%s that failed (de)compression processing\n"); 878 p(ipcomps_ibytes, "\t%qu input byte%s\n"); 879 p(ipcomps_obytes, "\t%qu output byte%s\n"); 880 881 #undef p 882 } 883