|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)inet.c 4.14 (Berkeley) 83/09/21"; ! 3: #endif ! 4: ! 5: #include <sys/types.h> ! 6: #include <sys/socket.h> ! 7: #include <sys/socketvar.h> ! 8: #include <sys/mbuf.h> ! 9: #include <sys/protosw.h> ! 10: ! 11: #include <net/route.h> ! 12: #include <netinet/in.h> ! 13: #include <netinet/in_systm.h> ! 14: #include <netinet/in_pcb.h> ! 15: #include <netinet/ip.h> ! 16: #include <netinet/ip_icmp.h> ! 17: #include <netinet/icmp_var.h> ! 18: #include <netinet/ip_var.h> ! 19: #include <netinet/tcp.h> ! 20: #include <netinet/tcpip.h> ! 21: #include <netinet/tcp_seq.h> ! 22: #define TCPSTATES ! 23: #include <netinet/tcp_fsm.h> ! 24: #include <netinet/tcp_timer.h> ! 25: #include <netinet/tcp_var.h> ! 26: #include <netinet/tcp_debug.h> ! 27: #include <netinet/udp.h> ! 28: #include <netinet/udp_var.h> ! 29: #include <net/if.h> ! 30: ! 31: #include <netdb.h> ! 32: #include <nlist.h> ! 33: #include "nstat.h" ! 34: ! 35: struct inpcb inpcb; ! 36: struct tcpcb tcpcb; ! 37: struct socket sock; ! 38: struct protosw proto; ! 39: ! 40: extern long flaggiven; ! 41: extern int kmem; /* file descriptor of kmem file */ ! 42: extern char *system; ! 43: ! 44: static int first = 1; ! 45: char *inetname(); ! 46: ! 47: static int getvm; ! 48: struct nlist inetnl[] = { ! 49: # define N_TCB 0 ! 50: { "_tcb" }, ! 51: ! 52: # define N_TCPSTAT 1 ! 53: { "_tcpstat" }, ! 54: # define N_TCPSTUDY 2 ! 55: { "_tcpstudy" }, ! 56: ! 57: # define N_UDB 3 ! 58: { "_udb" }, ! 59: # define N_UDPSTAT 4 ! 60: { "_udpstat" }, ! 61: ! 62: # define N_IPSTAT 5 ! 63: { "_ipstat" }, ! 64: # define N_IPINTR 6 ! 65: { "_ipintrq" }, ! 66: # define N_IPSTUDY 7 ! 67: { "_ipstudy" }, ! 68: ! 69: # define N_ICMPSTAT 8 ! 70: { "_icmpstat" }, ! 71: ! 72: # define N_RAWCB 9 ! 73: { "_rawcb" }, ! 74: ! 75: { "" }, ! 76: }; ! 77: ! 78: struct protoy { ! 79: u_char pr_index; /* index into nlist of cb head */ ! 80: u_char pr_sindex; /* index into nlist of stat block */ ! 81: char *pr_name; /* well-known name */ ! 82: } protoy[] = { ! 83: { N_TCB, N_TCPSTAT, "tcp" }, ! 84: { N_UDB, N_UDPSTAT, "udp" }, ! 85: { -1, N_IPSTAT, "ip" }, ! 86: { -1, N_ICMPSTAT, "icmp" }, ! 87: { -1, -1, 0 } ! 88: }; ! 89: ! 90: /* ! 91: * Print a summary of connections related to an Internet ! 92: * protocol. For TCP, also give state of connection. ! 93: * Listening processes (aflag) are suppressed unless the ! 94: * -a (all) flag is specified. ! 95: */ ! 96: protopr(name) ! 97: char *name; ! 98: { ! 99: off_t off = 0; ! 100: struct inpcb cb; ! 101: register struct inpcb *prev, *next; ! 102: int istcp; ! 103: ! 104: struct protoy *p; ! 105: ! 106: if (!getvm) { ! 107: nlist(system, inetnl); ! 108: getvm++; ! 109: } ! 110: for (p= &protoy[0]; p->pr_name; p++) { ! 111: if (strcmp(p->pr_name, name) == 0) { ! 112: off = inetnl[p->pr_index].n_value; ! 113: break; ! 114: } ! 115: } ! 116: if (off == 0) { ! 117: printf("%s control block: symbol not in namelist\n", name); ! 118: return; ! 119: } ! 120: istcp = strcmp(name, "tcp") == 0; ! 121: klseek(kmem, off, 0); ! 122: read(kmem, &cb, sizeof (struct inpcb)); ! 123: inpcb = cb; ! 124: prev = (struct inpcb *)off; ! 125: if (first) { ! 126: printf("Active connections"); ! 127: printf(" (including servers)"); ! 128: putchar('\n'); ! 129: if (Aflag) ! 130: printf("%-8.8s ", "PCB"); ! 131: printf("%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s %s\n", ! 132: "Proto", "Recv-Q", "Send-Q", ! 133: "Local Address", "Foreign Address", "(state)", ! 134: /* "(retry)");*/ ! 135: ""); ! 136: first = 0; ! 137: } ! 138: while (inpcb.inp_next != (struct inpcb *)off) { ! 139: char *cp; ! 140: ! 141: next = inpcb.inp_next; ! 142: klseek(kmem, (off_t)next, 0); ! 143: read(kmem, &inpcb, sizeof (inpcb)); ! 144: if (inpcb.inp_prev != prev) { ! 145: printf("???\n"); ! 146: break; ! 147: } ! 148: klseek(kmem, (off_t)inpcb.inp_socket, 0); ! 149: read(kmem, &sock, sizeof (sock)); ! 150: if (istcp) { ! 151: klseek(kmem, (off_t)inpcb.inp_ppcb, 0); ! 152: read(kmem, &tcpcb, sizeof (tcpcb)); ! 153: } ! 154: if (Aflag) ! 155: printf("%8x ", inpcb.inp_ppcb); ! 156: printf("%-5.5s %6d %6d ", name, sock.so_rcv.sb_cc, ! 157: sock.so_snd.sb_cc); ! 158: inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name); ! 159: inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name); ! 160: if (istcp) { ! 161: if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES) ! 162: printf(" %d", tcpcb.t_state); ! 163: else ! 164: printf(" %s", tcpstates[tcpcb.t_state]); ! 165: /* printf(" (%d)", tcpcb.t_rxtshift); */ ! 166: } ! 167: putchar('\n'); ! 168: if (Aflag) { ! 169: printf("\tinpcb:%x,", next); ! 170: if (inpcb.inp_route.ro_dst.sa_family==AF_INET) { ! 171: struct sockaddr_in *sin; ! 172: sin = (struct sockaddr_in *)&inpcb.inp_route.ro_dst; ! 173: printf(" ro_dst:"); ! 174: inetprint(&sin->sin_addr, sin->sin_port, name); ! 175: if (inpcb.inp_route.ro_rt) ! 176: printrt(inpcb.inp_route.ro_rt); ! 177: } ! 178: putchar('\n'); ! 179: putchar('\n'); ! 180: } ! 181: prev = next; ! 182: } ! 183: } ! 184: ! 185: /* ! 186: * Dump TCP statistics structure. ! 187: */ ! 188: tcp_stats() ! 189: { ! 190: off_t off; ! 191: struct tcpstat tcpstat; ! 192: struct tcpstudy tcpstudy; ! 193: ! 194: struct protoy *p; ! 195: char *name = "tcp"; ! 196: ! 197: if (!getvm) { ! 198: nlist(system, inetnl); ! 199: getvm++; ! 200: } ! 201: for (p= &protoy[0]; p->pr_name; p++) { ! 202: if (strcmp(p->pr_name, name) == 0) { ! 203: off = inetnl[p->pr_sindex].n_value; ! 204: break; ! 205: } ! 206: } ! 207: if (off == 0) { ! 208: printf("%sstat: symbol not in namelist\n", name); ! 209: return; ! 210: } ! 211: klseek(kmem, off, 0); ! 212: read(kmem, (char *)&tcpstat, sizeof (tcpstat)); ! 213: ! 214: printf("%s:\n\t%d bad header checksum%s\n", name, ! 215: tcpstat.tcps_badsum, plural(tcpstat.tcps_badsum)); ! 216: printf("\t%d bad header offset field%s\n", ! 217: tcpstat.tcps_badoff, plural(tcpstat.tcps_badoff)); ! 218: printf("\t%d recv incomplete header%s\n", ! 219: tcpstat.tcps_hdrops, plural(tcpstat.tcps_hdrops)); ! 220: printf("\t%d disconnect due to xmit timedout\n", tcpstat.tcps_xdrops); ! 221: printf("\t%d bad segment%s\n", ! 222: tcpstat.tcps_badsegs, plural(tcpstat.tcps_badsegs)); ! 223: printf("\t%d retries due to unacknowledged packet%s\n", ! 224: tcpstat.tcps_unack, plural(tcpstat.tcps_unack)); ! 225: /* ! 226: /* if (!inetnl[N_TCPSTUDY].n_value) { ! 227: /* printf("%sstat: symbol tcpstudy not in namelist\n",name); ! 228: /* return; ! 229: /* } ! 230: /* klseek(kmem,(long)inetnl[N_TCPSTUDY].n_value, 0); ! 231: /* read(kmem, (char *)&tcpstudy, sizeof(tcpstudy)); ! 232: /* ! 233: /* printf("\t# of Incoming Packets Dropped Due To: \n"); ! 234: /* printf("\t\taddr not in pcb: %d\n",tcpstudy.tcps_notinpcb); ! 235: /* printf("\t\tcontrol block doesnot have tcp control block: %d\n", ! 236: /* tcpstudy.tcps_notcpcb); ! 237: /* printf("\t\tstate is not in sync: %d\n", tcpstudy.tcps_badstate); ! 238: /* printf("\t\tcannot connect: %d\n", tcpstudy.tcps_noconnect); ! 239: /* printf("\t\tack out of seq: %d\n", tcpstudy.tcps_ackoutofseq); ! 240: /* printf("\t\tdata out of window: %d\n", tcpstudy.tcps_outwinedge); ! 241: /**/ ! 242: } ! 243: ! 244: /* ! 245: * Dump UDP statistics structure. ! 246: */ ! 247: udp_stats() ! 248: { ! 249: off_t off; ! 250: struct udpstat udpstat; ! 251: ! 252: struct protoy *p; ! 253: char *name = "udp"; ! 254: ! 255: if (!getvm) { ! 256: nlist(system, inetnl); ! 257: getvm++; ! 258: } ! 259: for (p= &protoy[0]; p->pr_name; p++) { ! 260: if (strcmp(p->pr_name, name) == 0) { ! 261: off = inetnl[p->pr_sindex].n_value; ! 262: break; ! 263: } ! 264: } ! 265: if (off == 0) { ! 266: printf("%sstat: symbol not in namelist\n", name); ! 267: return; ! 268: } ! 269: klseek(kmem, off, 0); ! 270: read(kmem, (char *)&udpstat, sizeof (udpstat)); ! 271: printf("%s:\n\t%d bad header checksum%s\n", name, ! 272: udpstat.udps_badsum, plural(udpstat.udps_badsum)); ! 273: printf("\t%d incomplete header%s\n", ! 274: udpstat.udps_hdrops, plural(udpstat.udps_hdrops)); ! 275: printf("\t%d bad data length field%s\n", ! 276: udpstat.udps_badlen, plural(udpstat.udps_badlen)); ! 277: } ! 278: ! 279: /* ! 280: * Dump IP statistics structure. ! 281: */ ! 282: ip_stats() ! 283: { ! 284: off_t off; ! 285: off_t off2; ! 286: struct ipstat ipstat; ! 287: struct ipstudy ipstudy; ! 288: struct ifqueue ipint; ! 289: ! 290: struct protoy *p; ! 291: char *name = "ip"; ! 292: ! 293: if (!getvm) { ! 294: nlist(system, inetnl); ! 295: getvm++; ! 296: } ! 297: for (p= &protoy[0]; p->pr_name; p++) { ! 298: if (strcmp(p->pr_name, name) == 0) { ! 299: off = inetnl[p->pr_sindex].n_value; ! 300: break; ! 301: } ! 302: } ! 303: if (off == 0) { ! 304: printf("%sstat: symbol not in namelist\n", name); ! 305: return; ! 306: } ! 307: ! 308: klseek(kmem, off, 0); ! 309: read(kmem, (char *)&ipstat, sizeof (ipstat)); ! 310: ! 311: printf("%s:\n\t%d bad header checksum%s\n", name, ! 312: ipstat.ips_badsum, plural(ipstat.ips_badsum)); ! 313: printf("\t%d with size smaller than minimum\n", ipstat.ips_tooshort); ! 314: printf("\t%d with data size < data length\n", ipstat.ips_toosmall); ! 315: printf("\t%d with header length < data size\n", ipstat.ips_badhlen); ! 316: printf("\t%d with data length < header length\n", ipstat.ips_badlen); ! 317: ! 318: /* off2 = inetnl[N_IPINTR].n_value; ! 319: /* if (off2 == 0) { ! 320: /* printf("ipintrq symbol not in namelist\n"); ! 321: /* return; ! 322: /* } ! 323: /* klseek(kmem, off2, 0); ! 324: /* read(kmem, (char *)&ipint, sizeof (ipint)); ! 325: /* ! 326: /* printf("\tipinput q:%d dropped due to full queue\n", ipint.ifq_drops); ! 327: /* printf("\tipinput q:%d len \n", ipint.ifq_len); ! 328: /* printf("\tipinput q:%d maxlen \n", ipint.ifq_maxlen); ! 329: /**/ ! 330: ! 331: /* off2 = inetnl[N_IPSTUDY].n_value; ! 332: /* if (off2==0) { ! 333: /* printf("ipstudy symbol not in namelist\n"); ! 334: /* return; ! 335: /* } ! 336: /* klseek(kmem, off2, 0); ! 337: /* read(kmem, (char *)&ipstudy, sizeof(ipstudy)); ! 338: /* printf("\tPackets Dropped Due To:\n"); ! 339: /* printf("\t\tno ifnet (use full addr) for strictroute: %d\n", ! 340: /* ipstudy.ips_ssnoifaddr); ! 341: /* printf("\t\tno interface (use net#) for strictroute: %d\n", ! 342: /* ipstudy.ips_ssnoifnet); ! 343: /* printf("\t\tbad option length: %d\n", ipstudy.ips_oplen); ! 344: /* printf("\t\tcant tell host from net: %d\n", ! 345: /* ipstudy.ips_cantdiffnethost); ! 346: /* printf("\t\ttime exceeded: %d\n", ipstudy.ips_timxceed); ! 347: /* printf("\t\tmessage length too big: %d\n", ipstudy.ips_msgsize); ! 348: /* printf("\t\tbad port: %d\n",ipstudy.ips_badport); ! 349: /* printf("\t\thost or net unreached: %d\n", ipstudy.ips_unreach); ! 350: /**/ ! 351: } ! 352: ! 353: static char *icmpnames[] = { ! 354: "echo reply", ! 355: "#1", ! 356: "#2", ! 357: "destination unreachable", ! 358: "source quench", ! 359: "routing redirect", ! 360: "#6", ! 361: "#7", ! 362: "echo", ! 363: "#9", ! 364: "#10", ! 365: "time exceeded", ! 366: "parameter problem", ! 367: "time stamp", ! 368: "time stamp reply", ! 369: "information request", ! 370: "information request reply" ! 371: }; ! 372: ! 373: /* ! 374: * Dump ICMP statistics. ! 375: */ ! 376: icmp_stats() ! 377: { ! 378: off_t off; ! 379: struct icmpstat icmpstat; ! 380: register int i, first; ! 381: ! 382: struct protoy *p; ! 383: char *name = "icmp"; ! 384: ! 385: if (!getvm) { ! 386: nlist(system, inetnl); ! 387: ++getvm; ! 388: } ! 389: for (p= &protoy[0]; p->pr_name; p++) { ! 390: if (strcmp(p->pr_name, name) == 0) { ! 391: off = inetnl[p->pr_sindex].n_value; ! 392: break; ! 393: } ! 394: } ! 395: if (off == 0) { ! 396: printf("%sstat: symbol not in namelist\n", name); ! 397: return; ! 398: } ! 399: klseek(kmem, off, 0); ! 400: read(kmem, (char *)&icmpstat, sizeof (icmpstat)); ! 401: printf("%s:\n\t%d call%s to icmp_error\n", name, ! 402: icmpstat.icps_error, plural(icmpstat.icps_error)); ! 403: printf("\t%d error%s not generated 'cuz old message too short\n", ! 404: icmpstat.icps_oldshort, plural(icmpstat.icps_oldshort)); ! 405: printf("\t%d error%s not generated 'cuz old message was icmp\n", ! 406: icmpstat.icps_oldicmp, plural(icmpstat.icps_oldicmp)); ! 407: for (first = 1, i = 0; i < ICMP_IREQREPLY + 1; i++) ! 408: if (icmpstat.icps_outhist[i] != 0) { ! 409: if (first) { ! 410: printf("\tOutput histogram:\n"); ! 411: first = 0; ! 412: } ! 413: printf("\t\t%s: %d\n", icmpnames[i], ! 414: icmpstat.icps_outhist[i]); ! 415: } ! 416: printf("\t%d message%s with bad code fields\n", ! 417: icmpstat.icps_badcode, plural(icmpstat.icps_badcode)); ! 418: printf("\t%d message%s < minimum length\n", ! 419: icmpstat.icps_tooshort, plural(icmpstat.icps_tooshort)); ! 420: printf("\t%d bad checksum%s\n", ! 421: icmpstat.icps_checksum, plural(icmpstat.icps_checksum)); ! 422: printf("\t%d message%s with bad length\n", ! 423: icmpstat.icps_badlen, plural(icmpstat.icps_badlen)); ! 424: printf("\t%d message response%s generated\n", ! 425: icmpstat.icps_reflect, plural(icmpstat.icps_reflect)); ! 426: for (first = 1, i = 0; i < ICMP_IREQREPLY + 1; i++) ! 427: if (icmpstat.icps_inhist[i] != 0) { ! 428: if (first) { ! 429: printf("\tInput histogram:\n"); ! 430: first = 0; ! 431: } ! 432: printf("\t\t%s: %d\n", icmpnames[i], ! 433: icmpstat.icps_inhist[i]); ! 434: } ! 435: } ! 436: ! 437: /* ! 438: * Pretty print an Internet address (net address + port). ! 439: * If the nflag was specified, use numbers instead of names. ! 440: */ ! 441: inetprint(in, port, proto) ! 442: register struct in_addr *in; ! 443: int port; ! 444: char *proto; ! 445: { ! 446: struct servent *sp = 0; ! 447: char line[80], *cp, *index(); ! 448: ! 449: sprintf(line, "%.10s.", inetname(*in)); ! 450: cp = index(line, '\0'); ! 451: if (!nflag && port) ! 452: sp = getservbyport(port, proto); ! 453: if (sp || port == 0) ! 454: sprintf(cp, "%.8s", sp ? sp->s_name : "*"); ! 455: else ! 456: sprintf(cp, "%d", ntohs((u_short)port)); ! 457: printf(" %-18.18s", line); ! 458: } ! 459: ! 460: /* ! 461: * Construct an Internet address representation. ! 462: * If the nflag has been supplied, give ! 463: * numeric value, otherwise try for symbolic name. ! 464: */ ! 465: char * ! 466: inetname(in) ! 467: struct in_addr in; ! 468: { ! 469: char *cp = 0; ! 470: static char line[50]; ! 471: ! 472: if (!nflag) { ! 473: if (inet_lnaof(in) == INADDR_ANY) { ! 474: struct netent *np; ! 475: ! 476: np = getnetbyaddr(inet_netof(in), AF_INET); ! 477: if (np) ! 478: cp = np->n_name; ! 479: } else { ! 480: struct hostent *hp; ! 481: ! 482: hp = gethostbyaddr(&in, sizeof (struct in_addr), ! 483: AF_INET); ! 484: if (hp) ! 485: cp = hp->h_name; ! 486: } ! 487: } ! 488: if (in.s_addr == INADDR_ANY) ! 489: strcpy(line, "*"); ! 490: else if (cp) ! 491: strcpy(line, cp); ! 492: else { ! 493: u_char *ucp = (u_char *)∈ ! 494: sprintf(line, "%u.%u.%u.%u", ucp[0], ucp[1], ucp[2], ucp[3]); ! 495: } ! 496: return (line); ! 497: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.