1 /* $OpenBSD: inet.c,v 1.54 2001/11/19 19:02:15 mpech 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.54 2001/11/19 19:02:15 mpech 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 __P((u_long, char *, int)); 96 97 char *inetname __P((struct in_addr *)); 98 void inetprint __P((struct in_addr *, int, char *, int)); 99 #ifdef INET6 100 char *inet6name __P((struct in6_addr *)); 101 void inet6print __P((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 strcpy(namebuf, name0); 207 strcat(namebuf, "6"); 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 dup. data (%qd byte%s duped)\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 #undef p 319 #undef p1 320 #undef p2 321 #undef p2a 322 #undef p3 323 } 324 325 /* 326 * Dump UDP statistics structure. 327 */ 328 void 329 udp_stats(off, name) 330 u_long off; 331 char *name; 332 { 333 struct udpstat udpstat; 334 u_long delivered; 335 336 if (off == 0) 337 return; 338 kread(off, (char *)&udpstat, sizeof (udpstat)); 339 printf("%s:\n", name); 340 #define p(f, m) if (udpstat.f || sflag <= 1) \ 341 printf(m, udpstat.f, plural(udpstat.f)) 342 #define p1(f, m) if (udpstat.f || sflag <= 1) \ 343 printf(m, udpstat.f) 344 p(udps_ipackets, "\t%lu datagram%s received\n"); 345 p1(udps_hdrops, "\t%lu with incomplete header\n"); 346 p1(udps_badlen, "\t%lu with bad data length field\n"); 347 p1(udps_badsum, "\t%lu with bad checksum\n"); 348 p1(udps_nosum, "\t%lu with no checksum\n"); 349 p(udps_inhwcsum, "\t%lu input packet%s hardware-checksummed\n"); 350 p(udps_outhwcsum, "\t%lu output packet%s hardware-checksummed\n"); 351 p1(udps_noport, "\t%lu dropped due to no socket\n"); 352 p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n"); 353 p1(udps_nosec, "\t%lu dropped due to missing IPSec protection\n"); 354 p1(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); 355 delivered = udpstat.udps_ipackets - 356 udpstat.udps_hdrops - 357 udpstat.udps_badlen - 358 udpstat.udps_badsum - 359 udpstat.udps_noport - 360 udpstat.udps_noportbcast - 361 udpstat.udps_fullsock; 362 if (delivered || sflag <= 1) 363 printf("\t%lu delivered\n", delivered); 364 p(udps_opackets, "\t%lu datagram%s output\n"); 365 p1(udps_pcbhashmiss, "\t%lu missed PCB cache\n"); 366 #undef p 367 #undef p1 368 } 369 370 /* 371 * Dump IP statistics structure. 372 */ 373 void 374 ip_stats(off, name) 375 u_long off; 376 char *name; 377 { 378 struct ipstat ipstat; 379 380 if (off == 0) 381 return; 382 kread(off, (char *)&ipstat, sizeof (ipstat)); 383 printf("%s:\n", name); 384 385 #define p(f, m) if (ipstat.f || sflag <= 1) \ 386 printf(m, ipstat.f, plural(ipstat.f)) 387 #define p1(f, m) if (ipstat.f || sflag <= 1) \ 388 printf(m, ipstat.f) 389 390 p(ips_total, "\t%lu total packet%s received\n"); 391 p(ips_badsum, "\t%lu bad header checksum%s\n"); 392 p1(ips_toosmall, "\t%lu with size smaller than minimum\n"); 393 p1(ips_tooshort, "\t%lu with data size < data length\n"); 394 p1(ips_badhlen, "\t%lu with header length < data size\n"); 395 p1(ips_badlen, "\t%lu with data length < header length\n"); 396 p1(ips_badoptions, "\t%lu with bad options\n"); 397 p1(ips_badvers, "\t%lu with incorrect version number\n"); 398 p(ips_fragments, "\t%lu fragment%s received\n"); 399 p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n"); 400 p(ips_badfrags, "\t%lu malformed fragment%s dropped\n"); 401 p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 402 p(ips_reassembled, "\t%lu packet%s reassembled ok\n"); 403 p(ips_delivered, "\t%lu packet%s for this host\n"); 404 p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n"); 405 p(ips_forward, "\t%lu packet%s forwarded\n"); 406 p(ips_cantforward, "\t%lu packet%s not forwardable\n"); 407 p(ips_redirectsent, "\t%lu redirect%s sent\n"); 408 p(ips_localout, "\t%lu packet%s sent from this host\n"); 409 p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 410 p(ips_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n"); 411 p(ips_noroute, "\t%lu output packet%s discarded due to no route\n"); 412 p(ips_fragmented, "\t%lu output datagram%s fragmented\n"); 413 p(ips_ofragments, "\t%lu fragment%s created\n"); 414 p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 415 p1(ips_rcvmemdrop, "\t%lu fragment floods\n"); 416 p(ips_toolong, "\t%lu packet%s with ip length > max ip packet size\n"); 417 p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n"); 418 p(ips_badaddr, "\t%lu datagram%s with bad address in header\n"); 419 p(ips_inhwcsum, "\t%lu input datagram%s checksum-processed by hardware\n"); 420 p(ips_outhwcsum, "\t%lu output datagram%s checksum-processed by hardware\n"); 421 #undef p 422 #undef p1 423 } 424 425 static char *icmpnames[] = { 426 "echo reply", 427 "#1", 428 "#2", 429 "destination unreachable", 430 "source quench", 431 "routing redirect", 432 "#6", 433 "#7", 434 "echo", 435 "router advertisement", 436 "router solicitation", 437 "time exceeded", 438 "parameter problem", 439 "time stamp", 440 "time stamp reply", 441 "information request", 442 "information request reply", 443 "address mask request", 444 "address mask reply", 445 }; 446 447 /* 448 * Dump ICMP statistics. 449 */ 450 void 451 icmp_stats(off, name) 452 u_long off; 453 char *name; 454 { 455 struct icmpstat icmpstat; 456 int i, first; 457 458 if (off == 0) 459 return; 460 kread(off, (char *)&icmpstat, sizeof (icmpstat)); 461 printf("%s:\n", name); 462 463 #define p(f, m) if (icmpstat.f || sflag <= 1) \ 464 printf(m, icmpstat.f, plural(icmpstat.f)) 465 466 p(icps_error, "\t%lu call%s to icmp_error\n"); 467 p(icps_oldicmp, 468 "\t%lu error%s not generated 'cuz old message was icmp\n"); 469 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 470 if (icmpstat.icps_outhist[i] != 0) { 471 if (first) { 472 printf("\tOutput packet histogram:\n"); 473 first = 0; 474 } 475 printf("\t\t%s: %lu\n", icmpnames[i], 476 icmpstat.icps_outhist[i]); 477 } 478 p(icps_badcode, "\t%lu message%s with bad code fields\n"); 479 p(icps_tooshort, "\t%lu message%s < minimum length\n"); 480 p(icps_checksum, "\t%lu bad checksum%s\n"); 481 p(icps_badlen, "\t%lu message%s with bad length\n"); 482 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 483 if (icmpstat.icps_inhist[i] != 0) { 484 if (first) { 485 printf("\tInput packet histogram:\n"); 486 first = 0; 487 } 488 printf("\t\t%s: %lu\n", icmpnames[i], 489 icmpstat.icps_inhist[i]); 490 } 491 p(icps_reflect, "\t%lu message response%s generated\n"); 492 #undef p 493 } 494 495 /* 496 * Dump IGMP statistics structure. 497 */ 498 void 499 igmp_stats(off, name) 500 u_long off; 501 char *name; 502 { 503 struct igmpstat igmpstat; 504 505 if (off == 0) 506 return; 507 kread(off, (char *)&igmpstat, sizeof (igmpstat)); 508 printf("%s:\n", name); 509 510 #define p(f, m) if (igmpstat.f || sflag <= 1) \ 511 printf(m, igmpstat.f, plural(igmpstat.f)) 512 #define py(f, m) if (igmpstat.f || sflag <= 1) \ 513 printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 514 p(igps_rcv_total, "\t%lu message%s received\n"); 515 p(igps_rcv_tooshort, "\t%lu message%s received with too few bytes\n"); 516 p(igps_rcv_badsum, "\t%lu message%s received with bad checksum\n"); 517 py(igps_rcv_queries, "\t%lu membership quer%s received\n"); 518 py(igps_rcv_badqueries, "\t%lu membership quer%s received with invalid field(s)\n"); 519 p(igps_rcv_reports, "\t%lu membership report%s received\n"); 520 p(igps_rcv_badreports, "\t%lu membership report%s received with invalid field(s)\n"); 521 p(igps_rcv_ourreports, "\t%lu membership report%s received for groups to which we belong\n"); 522 p(igps_snd_reports, "\t%lu membership report%s sent\n"); 523 #undef p 524 #undef py 525 } 526 527 struct rpcnams { 528 struct rpcnams *next; 529 in_port_t port; 530 int proto; 531 char *rpcname; 532 }; 533 534 char * 535 getrpcportnam(port, proto) 536 in_port_t port; 537 int proto; 538 { 539 struct sockaddr_in server_addr; 540 struct hostent *hp; 541 static struct pmaplist *head; 542 int socket = RPC_ANYSOCK; 543 struct timeval minutetimeout; 544 CLIENT *client; 545 struct rpcent *rpc; 546 static int first; 547 static struct rpcnams *rpcn; 548 struct rpcnams *n; 549 char num[20]; 550 551 if (first == 0) { 552 first = 1; 553 memset((char *)&server_addr, 0, sizeof server_addr); 554 server_addr.sin_family = AF_INET; 555 if ((hp = gethostbyname("localhost")) != NULL) 556 memmove((caddr_t)&server_addr.sin_addr, hp->h_addr, 557 hp->h_length); 558 else 559 (void) inet_aton("0.0.0.0", &server_addr.sin_addr); 560 561 minutetimeout.tv_sec = 60; 562 minutetimeout.tv_usec = 0; 563 server_addr.sin_port = htons(PMAPPORT); 564 if ((client = clnttcp_create(&server_addr, PMAPPROG, 565 PMAPVERS, &socket, 50, 500)) == NULL) 566 return (NULL); 567 if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL, 568 xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { 569 clnt_destroy(client); 570 return (NULL); 571 } 572 for (; head != NULL; head = head->pml_next) { 573 n = (struct rpcnams *)malloc(sizeof(struct rpcnams)); 574 if (n == NULL) 575 continue; 576 n->next = rpcn; 577 rpcn = n; 578 n->port = head->pml_map.pm_port; 579 n->proto = head->pml_map.pm_prot; 580 581 rpc = getrpcbynumber(head->pml_map.pm_prog); 582 if (rpc) 583 n->rpcname = strdup(rpc->r_name); 584 else { 585 snprintf(num, sizeof num, "%ld", 586 head->pml_map.pm_prog); 587 n->rpcname = strdup(num); 588 } 589 } 590 clnt_destroy(client); 591 } 592 593 for (n = rpcn; n; n = n->next) 594 if (n->port == port && n->proto == proto) 595 return (n->rpcname); 596 return (NULL); 597 } 598 599 /* 600 * Pretty print an Internet address (net address + port). 601 * If the nflag was specified, use numbers instead of names. 602 */ 603 void 604 inetprint(in, port, proto, local) 605 struct in_addr *in; 606 in_port_t port; 607 char *proto; 608 int local; 609 { 610 struct servent *sp = 0; 611 char line[80], *cp, *nam; 612 int width; 613 614 snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16, 615 inetname(in)); 616 cp = strchr(line, '\0'); 617 if (!nflag && port) 618 sp = getservbyport((int)port, proto); 619 if (sp || port == 0) 620 snprintf(cp, line + sizeof line - cp, "%.8s", 621 sp ? sp->s_name : "*"); 622 else if (local && !nflag && (nam = getrpcportnam(ntohs(port), 623 (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP)))) 624 snprintf(cp, line + sizeof line - cp, "%d[%.8s]", 625 ntohs(port), nam); 626 else 627 snprintf(cp, line + sizeof line - cp, "%d", ntohs(port)); 628 width = Aflag ? 18 : 22; 629 printf(" %-*.*s", width, width, line); 630 } 631 632 /* 633 * Construct an Internet address representation. 634 * If the nflag has been supplied, give 635 * numeric value, otherwise try for symbolic name. 636 */ 637 char * 638 inetname(inp) 639 struct in_addr *inp; 640 { 641 char *cp; 642 static char line[50]; 643 struct hostent *hp; 644 struct netent *np; 645 static char domain[MAXHOSTNAMELEN + 1]; 646 static int first = 1; 647 648 if (first && !nflag) { 649 first = 0; 650 if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 651 (cp = strchr(domain, '.'))) 652 (void) strcpy(domain, cp + 1); 653 else 654 domain[0] = 0; 655 } 656 cp = 0; 657 if (!nflag && inp->s_addr != INADDR_ANY) { 658 int net = inet_netof(*inp); 659 int lna = inet_lnaof(*inp); 660 661 if (lna == INADDR_ANY) { 662 np = getnetbyaddr(net, AF_INET); 663 if (np) 664 cp = np->n_name; 665 } 666 if (cp == 0) { 667 hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 668 if (hp) { 669 if ((cp = strchr(hp->h_name, '.')) && 670 !strcmp(cp + 1, domain)) 671 *cp = 0; 672 cp = hp->h_name; 673 } 674 } 675 } 676 if (inp->s_addr == INADDR_ANY) 677 snprintf(line, sizeof line, "*"); 678 else if (cp) 679 snprintf(line, sizeof line, "%s", cp); 680 else { 681 inp->s_addr = ntohl(inp->s_addr); 682 #define C(x) ((x) & 0xff) 683 snprintf(line, sizeof line, "%u.%u.%u.%u", 684 C(inp->s_addr >> 24), C(inp->s_addr >> 16), 685 C(inp->s_addr >> 8), C(inp->s_addr)); 686 } 687 return (line); 688 } 689 690 /* 691 * Dump AH statistics structure. 692 */ 693 void 694 ah_stats(off, name) 695 u_long off; 696 char *name; 697 { 698 struct ahstat ahstat; 699 700 if (off == 0) 701 return; 702 kread(off, (char *)&ahstat, sizeof (ahstat)); 703 printf("%s:\n", name); 704 705 #define p(f, m) if (ahstat.f || sflag <= 1) \ 706 printf(m, ahstat.f, plural(ahstat.f)) 707 #define p1(f, m) if (ahstat.f || sflag <= 1) \ 708 printf(m, ahstat.f) 709 710 p1(ahs_input, "\t%u input AH packets\n"); 711 p1(ahs_output, "\t%u output AH packets\n"); 712 p(ahs_nopf, "\t%u packet%s from unsupported protocol families\n"); 713 p(ahs_hdrops, "\t%u packet%s shorter than header shows\n"); 714 p(ahs_pdrops, "\t%u packet%s dropped due to policy\n"); 715 p(ahs_notdb, "\t%u packet%s for which no TDB was found\n"); 716 p(ahs_badkcr, "\t%u input packet%s that failed to be processed\n"); 717 p(ahs_badauth, "\t%u packet%s that failed verification received\n"); 718 p(ahs_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 719 p(ahs_qfull, "\t%u packet%s were dropped due to full output queue\n"); 720 p(ahs_wrap, "\t%u packet%s where counter wrapping was detected\n"); 721 p(ahs_replay, "\t%u possibly replayed packet%s received\n"); 722 p(ahs_badauthl, "\t%u packet%s with bad authenticator length received\n"); 723 p(ahs_invalid, "\t%u packet%s attempted to use an invalid tdb\n"); 724 p(ahs_toobig, "\t%u packet%s got larger than max IP packet size\n"); 725 p(ahs_crypto, "\t%u packet%s that failed crypto processing\n"); 726 p(ahs_ibytes, "\t%qu input byte%s\n"); 727 p(ahs_obytes, "\t%qu output byte%s\n"); 728 729 #undef p 730 #undef p1 731 } 732 733 /* 734 * Dump etherip statistics structure. 735 */ 736 void 737 etherip_stats(off, name) 738 u_long off; 739 char *name; 740 { 741 struct etheripstat etheripstat; 742 743 744 if (off == 0) 745 return; 746 kread(off, (char *)ðeripstat, sizeof (etheripstat)); 747 printf("%s:\n", name); 748 749 #define p(f, m) if (etheripstat.f || sflag <= 1) \ 750 printf(m, etheripstat.f, plural(etheripstat.f)) 751 752 753 p(etherip_hdrops, "\t%u packet%s shorter than header shows\n"); 754 p(etherip_qfull, "\t%u packet%s were dropped due to full output queue\n"); 755 p(etherip_noifdrops, "\t%u packet%s were dropped because of no interface/bridge information\n"); 756 p(etherip_pdrops, "\t%u packet%s dropped due to policy\n"); 757 p(etherip_adrops, "\t%u packet%s dropped for other reasons\n"); 758 p(etherip_ipackets, "\t%u input ethernet-in-IP packet%s\n"); 759 p(etherip_opackets, "\t%u output ethernet-in-IP packet%s\n"); 760 p(etherip_ibytes, "\t%qu input byte%s\n"); 761 p(etherip_obytes, "\t%qu output byte%s\n"); 762 #undef p 763 } 764 765 /* 766 * Dump ESP statistics structure. 767 */ 768 void 769 esp_stats(off, name) 770 u_long off; 771 char *name; 772 { 773 struct espstat espstat; 774 775 776 if (off == 0) 777 return; 778 kread(off, (char *)&espstat, sizeof (espstat)); 779 printf("%s:\n", name); 780 781 #define p(f, m) if (espstat.f || sflag <= 1) \ 782 printf(m, espstat.f, plural(espstat.f)) 783 784 p(esps_input, "\t%u input ESP packet%s\n"); 785 p(esps_output, "\t%u output ESP packet%s\n"); 786 p(esps_nopf, "\t%u packet%s from unsupported protocol families\n"); 787 p(esps_hdrops, "\t%u packet%s shorter than header shows\n"); 788 p(esps_pdrops, "\t%u packet%s dropped due to policy\n"); 789 p(esps_notdb, "\t%u packet%s for which no TDB was found\n"); 790 p(esps_badkcr, "\t%u input packet%s that failed to be processed\n"); 791 p(esps_badenc, "\t%u packet%s with bad encryption received\n"); 792 p(esps_badauth, "\t%u packet%s that failed verification received\n"); 793 p(esps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 794 p(esps_qfull, "\t%u packet%s were dropped due to full output queue\n"); 795 p(esps_wrap, "\t%u packet%s where counter wrapping was detected\n"); 796 p(esps_replay, "\t%u possibly replayed packet%s received\n"); 797 p(esps_badilen, "\t%u packet%s with bad payload size or padding received\n"); 798 p(esps_invalid, "\t%u packet%s attempted to use an invalid tdb\n"); 799 p(esps_toobig, "\t%u packet%s got larger than max IP packet size\n"); 800 p(esps_crypto, "\t%u packet%s that failed crypto processing\n"); 801 p(esps_ibytes, "\t%qu input byte%s\n"); 802 p(esps_obytes, "\t%qu output byte%s\n"); 803 804 #undef p 805 } 806 807 /* 808 * Dump ESP statistics structure. 809 */ 810 void 811 ipip_stats(off, name) 812 u_long off; 813 char *name; 814 { 815 struct ipipstat ipipstat; 816 817 if (off == 0) 818 return; 819 kread(off, (char *)&ipipstat, sizeof (ipipstat)); 820 printf("%s:\n", name); 821 822 #define p(f, m) if (ipipstat.f || sflag <= 1) \ 823 printf(m, ipipstat.f, plural(ipipstat.f)) 824 825 p(ipips_ipackets, "\t%u total input packet%s\n"); 826 p(ipips_opackets, "\t%u total output packet%s\n"); 827 p(ipips_hdrops, "\t%u packet%s shorter than header shows\n"); 828 p(ipips_pdrops, "\t%u packet%s dropped due to policy\n"); 829 p(ipips_spoof, "\t%u packet%s with possibly spoofed local addresses\n"); 830 p(ipips_qfull, "\t%u packet%s were dropped due to full output queue\n"); 831 p(ipips_ibytes, "\t%qu input byte%s\n"); 832 p(ipips_obytes, "\t%qu output byte%s\n"); 833 p(ipips_family, "\t%u protocol family mismatches\n"); 834 p(ipips_unspec, "\t%u attempts to use tunnel with unspecified endpoint(s)\n"); 835 #undef p 836 } 837 838 /* 839 * Dump IPCOMP statistics structure. 840 */ 841 void 842 ipcomp_stats(off, name) 843 u_long off; 844 char *name; 845 { 846 struct ipcompstat ipcompstat; 847 848 849 if (off == 0) 850 return; 851 kread(off, (char *)&ipcompstat, sizeof (ipcompstat)); 852 printf("%s:\n", name); 853 854 #define p(f, m) if (ipcompstat.f || sflag <= 1) \ 855 printf(m, ipcompstat.f, plural(ipcompstat.f)) 856 857 p(ipcomps_input, "\t%u input IPCOMP packet%s\n"); 858 p(ipcomps_output, "\t%u output IPCOMP packet%s\n"); 859 p(ipcomps_nopf, "\t%u packet%s from unsupported protocol families\n"); 860 p(ipcomps_hdrops, "\t%u packet%s shorter than header shows\n"); 861 p(ipcomps_pdrops, "\t%u packet%s dropped due to policy\n"); 862 p(ipcomps_notdb, "\t%u packet%s for which no TDB was found\n"); 863 p(ipcomps_badkcr, "\t%u input packet%s that failed to be processed\n"); 864 p(ipcomps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n"); 865 p(ipcomps_qfull, "\t%u packet%s were dropped due to full output queue\n"); 866 p(ipcomps_wrap, "\t%u packet%s where counter wrapping was detected\n"); 867 p(ipcomps_invalid, "\t%u packet%s attempted to use an invalid tdb\n"); 868 p(ipcomps_toobig, "\t%u packet%s got larger than max IP packet size\n"); 869 p(ipcomps_crypto, "\t%u packet%s that failed (de)compression processing\n"); 870 p(ipcomps_ibytes, "\t%qu input byte%s\n"); 871 p(ipcomps_obytes, "\t%qu output byte%s\n"); 872 873 #undef p 874 } 875