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