|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)inet.c 5.15 (Berkeley) 6/18/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include <sys/param.h> ! 25: #include <sys/socket.h> ! 26: #include <sys/socketvar.h> ! 27: #include <sys/mbuf.h> ! 28: #include <sys/protosw.h> ! 29: ! 30: #include <net/route.h> ! 31: #include <netinet/in.h> ! 32: #include <netinet/in_systm.h> ! 33: #include <netinet/ip.h> ! 34: #include <netinet/in_pcb.h> ! 35: #include <netinet/ip_icmp.h> ! 36: #include <netinet/icmp_var.h> ! 37: #include <netinet/ip_var.h> ! 38: #include <netinet/tcp.h> ! 39: #include <netinet/tcpip.h> ! 40: #include <netinet/tcp_seq.h> ! 41: #define TCPSTATES ! 42: #include <netinet/tcp_fsm.h> ! 43: #include <netinet/tcp_timer.h> ! 44: #include <netinet/tcp_var.h> ! 45: #include <netinet/tcp_debug.h> ! 46: #include <netinet/udp.h> ! 47: #include <netinet/udp_var.h> ! 48: ! 49: #include <netdb.h> ! 50: ! 51: #include <stdio.h> ! 52: #include <string.h> ! 53: ! 54: struct inpcb inpcb; ! 55: struct tcpcb tcpcb; ! 56: struct socket sockb; ! 57: extern int Aflag; ! 58: extern int aflag; ! 59: extern int nflag; ! 60: extern char *plural(); ! 61: ! 62: char *inetname(); ! 63: ! 64: /* ! 65: * Print a summary of connections related to an Internet ! 66: * protocol. For TCP, also give state of connection. ! 67: * Listening processes (aflag) are suppressed unless the ! 68: * -a (all) flag is specified. ! 69: */ ! 70: protopr(off, name) ! 71: off_t off; ! 72: char *name; ! 73: { ! 74: struct inpcb cb; ! 75: register struct inpcb *prev, *next; ! 76: int istcp; ! 77: static int first = 1; ! 78: ! 79: if (off == 0) ! 80: return; ! 81: istcp = strcmp(name, "tcp") == 0; ! 82: kvm_read(off, (char *)&cb, sizeof (struct inpcb)); ! 83: inpcb = cb; ! 84: prev = (struct inpcb *)off; ! 85: if (inpcb.inp_next == (struct inpcb *)off) ! 86: return; ! 87: while (inpcb.inp_next != (struct inpcb *)off) { ! 88: ! 89: next = inpcb.inp_next; ! 90: kvm_read((off_t)next, (char *)&inpcb, sizeof (inpcb)); ! 91: if (inpcb.inp_prev != prev) { ! 92: printf("???\n"); ! 93: break; ! 94: } ! 95: if (!aflag && ! 96: inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) { ! 97: prev = next; ! 98: continue; ! 99: } ! 100: kvm_read((off_t)inpcb.inp_socket, ! 101: (char *)&sockb, sizeof (sockb)); ! 102: if (istcp) { ! 103: kvm_read((off_t)inpcb.inp_ppcb, ! 104: (char *)&tcpcb, sizeof (tcpcb)); ! 105: } ! 106: if (first) { ! 107: printf("Active Internet connections"); ! 108: if (aflag) ! 109: printf(" (including servers)"); ! 110: putchar('\n'); ! 111: if (Aflag) ! 112: printf("%-8.8s ", "PCB"); ! 113: printf(Aflag ? ! 114: "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : ! 115: "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", ! 116: "Proto", "Recv-Q", "Send-Q", ! 117: "Local Address", "Foreign Address", "(state)"); ! 118: first = 0; ! 119: } ! 120: if (Aflag) ! 121: if (istcp) ! 122: printf("%8x ", inpcb.inp_ppcb); ! 123: else ! 124: printf("%8x ", next); ! 125: printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, ! 126: sockb.so_snd.sb_cc); ! 127: inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name); ! 128: inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name); ! 129: if (istcp) { ! 130: if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES) ! 131: printf(" %d", tcpcb.t_state); ! 132: else ! 133: printf(" %s", tcpstates[tcpcb.t_state]); ! 134: } ! 135: putchar('\n'); ! 136: prev = next; ! 137: } ! 138: } ! 139: ! 140: /* ! 141: * Dump TCP statistics structure. ! 142: */ ! 143: tcp_stats(off, name) ! 144: off_t off; ! 145: char *name; ! 146: { ! 147: struct tcpstat tcpstat; ! 148: ! 149: if (off == 0) ! 150: return; ! 151: printf ("%s:\n", name); ! 152: kvm_read(off, (char *)&tcpstat, sizeof (tcpstat)); ! 153: ! 154: #define p(f, m) printf(m, tcpstat.f, plural(tcpstat.f)) ! 155: #define p2(f1, f2, m) printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) ! 156: ! 157: p(tcps_sndtotal, "\t%d packet%s sent\n"); ! 158: p2(tcps_sndpack,tcps_sndbyte, ! 159: "\t\t%d data packet%s (%d byte%s)\n"); ! 160: p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, ! 161: "\t\t%d data packet%s (%d byte%s) retransmitted\n"); ! 162: p2(tcps_sndacks, tcps_delack, ! 163: "\t\t%d ack-only packet%s (%d delayed)\n"); ! 164: p(tcps_sndurg, "\t\t%d URG only packet%s\n"); ! 165: p(tcps_sndprobe, "\t\t%d window probe packet%s\n"); ! 166: p(tcps_sndwinup, "\t\t%d window update packet%s\n"); ! 167: p(tcps_sndctrl, "\t\t%d control packet%s\n"); ! 168: p(tcps_rcvtotal, "\t%d packet%s received\n"); ! 169: p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%d ack%s (for %d byte%s)\n"); ! 170: p(tcps_rcvdupack, "\t\t%d duplicate ack%s\n"); ! 171: p(tcps_rcvacktoomuch, "\t\t%d ack%s for unsent data\n"); ! 172: p2(tcps_rcvpack, tcps_rcvbyte, ! 173: "\t\t%d packet%s (%d byte%s) received in-sequence\n"); ! 174: p2(tcps_rcvduppack, tcps_rcvdupbyte, ! 175: "\t\t%d completely duplicate packet%s (%d byte%s)\n"); ! 176: p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, ! 177: "\t\t%d packet%s with some dup. data (%d byte%s duped)\n"); ! 178: p2(tcps_rcvoopack, tcps_rcvoobyte, ! 179: "\t\t%d out-of-order packet%s (%d byte%s)\n"); ! 180: p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, ! 181: "\t\t%d packet%s (%d byte%s) of data after window\n"); ! 182: p(tcps_rcvwinprobe, "\t\t%d window probe%s\n"); ! 183: p(tcps_rcvwinupd, "\t\t%d window update packet%s\n"); ! 184: p(tcps_rcvafterclose, "\t\t%d packet%s received after close\n"); ! 185: p(tcps_rcvbadsum, "\t\t%d discarded for bad checksum%s\n"); ! 186: p(tcps_rcvbadoff, "\t\t%d discarded for bad header offset field%s\n"); ! 187: p(tcps_rcvshort, "\t\t%d discarded because packet too short\n"); ! 188: p(tcps_connattempt, "\t%d connection request%s\n"); ! 189: p(tcps_accepts, "\t%d connection accept%s\n"); ! 190: p(tcps_connects, "\t%d connection%s established (including accepts)\n"); ! 191: p2(tcps_closed, tcps_drops, ! 192: "\t%d connection%s closed (including %d drop%s)\n"); ! 193: p(tcps_conndrops, "\t%d embryonic connection%s dropped\n"); ! 194: p2(tcps_rttupdated, tcps_segstimed, ! 195: "\t%d segment%s updated rtt (of %d attempt%s)\n"); ! 196: p(tcps_rexmttimeo, "\t%d retransmit timeout%s\n"); ! 197: p(tcps_timeoutdrop, "\t\t%d connection%s dropped by rexmit timeout\n"); ! 198: p(tcps_persisttimeo, "\t%d persist timeout%s\n"); ! 199: p(tcps_keeptimeo, "\t%d keepalive timeout%s\n"); ! 200: p(tcps_keepprobe, "\t\t%d keepalive probe%s sent\n"); ! 201: p(tcps_keepdrops, "\t\t%d connection%s dropped by keepalive\n"); ! 202: #undef p ! 203: #undef p2 ! 204: } ! 205: ! 206: /* ! 207: * Dump UDP statistics structure. ! 208: */ ! 209: udp_stats(off, name) ! 210: off_t off; ! 211: char *name; ! 212: { ! 213: struct udpstat udpstat; ! 214: ! 215: if (off == 0) ! 216: return; ! 217: kvm_read(off, (char *)&udpstat, sizeof (udpstat)); ! 218: printf("%s:\n\t%u incomplete header%s\n", name, ! 219: udpstat.udps_hdrops, plural(udpstat.udps_hdrops)); ! 220: printf("\t%u bad data length field%s\n", ! 221: udpstat.udps_badlen, plural(udpstat.udps_badlen)); ! 222: printf("\t%u bad checksum%s\n", ! 223: udpstat.udps_badsum, plural(udpstat.udps_badsum)); ! 224: } ! 225: ! 226: /* ! 227: * Dump IP statistics structure. ! 228: */ ! 229: ip_stats(off, name) ! 230: off_t off; ! 231: char *name; ! 232: { ! 233: struct ipstat ipstat; ! 234: ! 235: if (off == 0) ! 236: return; ! 237: kvm_read(off, (char *)&ipstat, sizeof (ipstat)); ! 238: printf("%s:\n\t%u total packets received\n", name, ! 239: ipstat.ips_total); ! 240: printf("\t%u bad header checksum%s\n", ! 241: ipstat.ips_badsum, plural(ipstat.ips_badsum)); ! 242: printf("\t%u with size smaller than minimum\n", ipstat.ips_tooshort); ! 243: printf("\t%u with data size < data length\n", ipstat.ips_toosmall); ! 244: printf("\t%u with header length < data size\n", ipstat.ips_badhlen); ! 245: printf("\t%u with data length < header length\n", ipstat.ips_badlen); ! 246: printf("\t%u fragment%s received\n", ! 247: ipstat.ips_fragments, plural(ipstat.ips_fragments)); ! 248: printf("\t%u fragment%s dropped (dup or out of space)\n", ! 249: ipstat.ips_fragdropped, plural(ipstat.ips_fragdropped)); ! 250: printf("\t%u fragment%s dropped after timeout\n", ! 251: ipstat.ips_fragtimeout, plural(ipstat.ips_fragtimeout)); ! 252: printf("\t%u packet%s forwarded\n", ! 253: ipstat.ips_forward, plural(ipstat.ips_forward)); ! 254: printf("\t%u packet%s not forwardable\n", ! 255: ipstat.ips_cantforward, plural(ipstat.ips_cantforward)); ! 256: printf("\t%u redirect%s sent\n", ! 257: ipstat.ips_redirectsent, plural(ipstat.ips_redirectsent)); ! 258: } ! 259: ! 260: static char *icmpnames[] = { ! 261: "echo reply", ! 262: "#1", ! 263: "#2", ! 264: "destination unreachable", ! 265: "source quench", ! 266: "routing redirect", ! 267: "#6", ! 268: "#7", ! 269: "echo", ! 270: "#9", ! 271: "#10", ! 272: "time exceeded", ! 273: "parameter problem", ! 274: "time stamp", ! 275: "time stamp reply", ! 276: "information request", ! 277: "information request reply", ! 278: "address mask request", ! 279: "address mask reply", ! 280: }; ! 281: ! 282: /* ! 283: * Dump ICMP statistics. ! 284: */ ! 285: icmp_stats(off, name) ! 286: off_t off; ! 287: char *name; ! 288: { ! 289: struct icmpstat icmpstat; ! 290: register int i, first; ! 291: ! 292: if (off == 0) ! 293: return; ! 294: kvm_read(off, (char *)&icmpstat, sizeof (icmpstat)); ! 295: printf("%s:\n\t%u call%s to icmp_error\n", name, ! 296: icmpstat.icps_error, plural(icmpstat.icps_error)); ! 297: printf("\t%u error%s not generated 'cuz old message was icmp\n", ! 298: icmpstat.icps_oldicmp, plural(icmpstat.icps_oldicmp)); ! 299: for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) ! 300: if (icmpstat.icps_outhist[i] != 0) { ! 301: if (first) { ! 302: printf("\tOutput histogram:\n"); ! 303: first = 0; ! 304: } ! 305: printf("\t\t%s: %u\n", icmpnames[i], ! 306: icmpstat.icps_outhist[i]); ! 307: } ! 308: printf("\t%u message%s with bad code fields\n", ! 309: icmpstat.icps_badcode, plural(icmpstat.icps_badcode)); ! 310: printf("\t%u message%s < minimum length\n", ! 311: icmpstat.icps_tooshort, plural(icmpstat.icps_tooshort)); ! 312: printf("\t%u bad checksum%s\n", ! 313: icmpstat.icps_checksum, plural(icmpstat.icps_checksum)); ! 314: printf("\t%u message%s with bad length\n", ! 315: icmpstat.icps_badlen, plural(icmpstat.icps_badlen)); ! 316: for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) ! 317: if (icmpstat.icps_inhist[i] != 0) { ! 318: if (first) { ! 319: printf("\tInput histogram:\n"); ! 320: first = 0; ! 321: } ! 322: printf("\t\t%s: %u\n", icmpnames[i], ! 323: icmpstat.icps_inhist[i]); ! 324: } ! 325: printf("\t%u message response%s generated\n", ! 326: icmpstat.icps_reflect, plural(icmpstat.icps_reflect)); ! 327: } ! 328: ! 329: /* ! 330: * Pretty print an Internet address (net address + port). ! 331: * If the nflag was specified, use numbers instead of names. ! 332: */ ! 333: inetprint(in, port, proto) ! 334: register struct in_addr *in; ! 335: u_short port; ! 336: char *proto; ! 337: { ! 338: struct servent *sp = 0; ! 339: char line[80], *cp, *index(); ! 340: int width; ! 341: ! 342: sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inetname(*in)); ! 343: cp = index(line, '\0'); ! 344: if (!nflag && port) ! 345: sp = getservbyport((int)port, proto); ! 346: if (sp || port == 0) ! 347: sprintf(cp, "%.8s", sp ? sp->s_name : "*"); ! 348: else ! 349: sprintf(cp, "%d", ntohs((u_short)port)); ! 350: width = Aflag ? 18 : 22; ! 351: printf(" %-*.*s", width, width, line); ! 352: } ! 353: ! 354: /* ! 355: * Construct an Internet address representation. ! 356: * If the nflag has been supplied, give ! 357: * numeric value, otherwise try for symbolic name. ! 358: */ ! 359: char * ! 360: inetname(in) ! 361: struct in_addr in; ! 362: { ! 363: register char *cp; ! 364: static char line[50]; ! 365: struct hostent *hp; ! 366: struct netent *np; ! 367: static char domain[MAXHOSTNAMELEN + 1]; ! 368: static int first = 1; ! 369: ! 370: if (first && !nflag) { ! 371: first = 0; ! 372: if (gethostname(domain, MAXHOSTNAMELEN) == 0 && ! 373: (cp = index(domain, '.'))) ! 374: (void) strcpy(domain, cp + 1); ! 375: else ! 376: domain[0] = 0; ! 377: } ! 378: cp = 0; ! 379: if (!nflag && in.s_addr != INADDR_ANY) { ! 380: int net = inet_netof(in); ! 381: int lna = inet_lnaof(in); ! 382: ! 383: if (lna == INADDR_ANY) { ! 384: np = getnetbyaddr(net, AF_INET); ! 385: if (np) ! 386: cp = np->n_name; ! 387: } ! 388: if (cp == 0) { ! 389: hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET); ! 390: if (hp) { ! 391: if ((cp = index(hp->h_name, '.')) && ! 392: !strcmp(cp + 1, domain)) ! 393: *cp = 0; ! 394: cp = hp->h_name; ! 395: } ! 396: } ! 397: } ! 398: if (in.s_addr == INADDR_ANY) ! 399: strcpy(line, "*"); ! 400: else if (cp) ! 401: strcpy(line, cp); ! 402: else { ! 403: in.s_addr = ntohl(in.s_addr); ! 404: #define C(x) ((x) & 0xff) ! 405: sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24), ! 406: C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr)); ! 407: } ! 408: return (line); ! 409: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.