1: /* 2: * Copyright (c) 1983 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #if defined(DO_SCCS) && !defined(lint) 8: static char sccsid[] = "@(#)dispnet.c 5.6 (Berkeley) 8/22/87"; 9: #endif 10: 11: #include <stdio.h> 12: #include <sys/param.h> 13: #include <netdb.h> 14: 15: #include <sys/socket.h> 16: #include <sys/socketvar.h> 17: #include <sys/mbuf.h> 18: #include <sys/protosw.h> 19: 20: #define KERNEL /* to get routehash and RTHASHSIZ */ 21: #include <net/route.h> 22: #undef KERNEL 23: #include <net/if.h> 24: #include <net/raw_cb.h> 25: 26: #include <netinet/in.h> 27: #include <netinet/in_var.h> 28: #include <netinet/in_pcb.h> 29: 30: #include <arpa/inet.h> 31: 32: #include <netinet/ip_var.h> 33: #include <netinet/tcp.h> 34: 35: #include <netinet/tcp_fsm.h> 36: #include <netinet/tcp_timer.h> 37: #include <netinet/tcp_var.h> 38: #include <netinet/tcpip.h> 39: #include <netinet/udp.h> 40: #include <netinet/udp_var.h> 41: #include <sys/un.h> 42: #include <sys/unpcb.h> 43: #include "crash.h" 44: #include "net.h" 45: 46: char *subhead; /* pntr to sub-heading */ 47: struct arenas arenash = {0}; /* list head */ 48: long lseek(); 49: char *hoststr(), 50: *sprintf(); 51: char DASHES[] = "---------"; 52: char FWARN[] = "\tWARNING:"; 53: char Fccd[] = "%schar count discrepancy in %s queue; survey gives %d\n"; 54: 55: /* 56: * Header portion of struct mbufx, defined in mbuf.h 57: */ 58: struct mbufxh { /* external part of mbuf */ 59: struct mbuf *mh_mbuf; /* back pointer to mbuf */ 60: short mh_ref; /* reference counter */ 61: }; 62: 63: char *mbtmsgs[] = { 64: "bget(cache) ", 65: "bget(alloc) ", 66: " bfree", 67: "ioget ", 68: "sget ", 69: " sfree", 70: "MBXGET ", 71: " MBXFREE", 72: "MGET ", 73: " MFREE", 74: }; 75: #define NMBTMSGS 10 76: 77: /* 78: * The following defines are taken from mbuf11.c. They should 79: * be in an include file. 80: */ 81: 82: struct mbuf *mbcache[256]; /* mbuf cache for fast allocation */ 83: u_int mbfree; 84: u_int mbend; 85: 86: /* End of stuff taken from mbuf11.c */ 87: 88: struct mbstat mbstat; 89: struct ipstat ipstat; 90: int in_ckodd; /* from in_cksum.c */ 91: 92: struct prname { 93: int pr_id; 94: char *pr_name; 95: }; 96: 97: struct prname inetprotos[] = { 98: { IPPROTO_ICMP, "icmp" }, 99: { IPPROTO_GGP, "ggp", }, 100: { IPPROTO_TCP, "tcp", }, 101: { IPPROTO_EGP, "egp", }, 102: { IPPROTO_PUP, "pup", }, 103: { IPPROTO_UDP, "udp", }, 104: { IPPROTO_IDP, "idp", }, 105: { IPPROTO_RAW, "raw", }, 106: 0 107: }; 108: 109: struct prname impprotos[] = { 110: { IMPLINK_IP, "ip" }, 111: 0 112: }; 113: 114: struct pfname { 115: int pf_id; 116: char *pf_name; 117: struct prname *pf_protos; 118: } pfnames[] = { 119: { PF_UNSPEC, "unspec", 0 }, 120: { PF_UNIX, "unix", 0 }, 121: { PF_INET, "inet", inetprotos }, 122: { PF_IMPLINK, "implink", impprotos }, 123: { PF_PUP, "pup", 0 }, 124: { PF_CHAOS, "chaos", 0 }, 125: { PF_NS, "ns", 0 }, 126: { PF_NBS, "nbs", 0 }, 127: { PF_ECMA, "ecma", 0 }, 128: { PF_DATAKIT, "datakit", 0 }, 129: { PF_CCITT, "ccitt", 0 }, 130: { PF_SNA, "sna", 0 }, 131: { PF_DECnet, "DECnet", 0 }, 132: { PF_DLI, "dli", 0 }, 133: { PF_LAT, "lat", 0 }, 134: { PF_HYLINK, "hylink", 0 }, 135: { PF_APPLETALK, "apple", 0 }, 136: 0 137: }; 138: 139: int internetprint(); 140: 141: struct sockname { 142: int sa_id; 143: char *sa_name; 144: int (*sa_printer)(); 145: } addrnames[] = { 146: { AF_UNSPEC, "unspec", 0 }, 147: { AF_UNIX, "unix", 0 }, 148: { AF_INET, "inet", internetprint }, 149: { AF_IMPLINK, "implink", internetprint }, 150: { AF_PUP, "pup", 0 }, 151: { AF_CHAOS, "chaos", 0 }, 152: { AF_NS, "ns", 0 }, 153: { AF_NBS, "nbs", 0 }, 154: { AF_ECMA, "ecma", 0 }, 155: { AF_DATAKIT, "datakit", 0 }, 156: { AF_CCITT, "ccitt", 0 }, 157: { AF_SNA, "sna", 0 }, 158: { AF_DECnet, "DECnet", 0 }, 159: { AF_DLI, "dli", 0 }, 160: { AF_LAT, "lat", 0 }, 161: { AF_HYLINK, "hylink", 0 }, 162: { AF_APPLETALK, "apple", 0 }, 163: 0 164: }; 165: 166: int kmem, /* Global FD for core file */ 167: line; 168: int nflag = 0; /* Ineternet addresses as 1.2.3.4 ? */ 169: int aflag = 1; /* Display all connections ? */ 170: int Aflag = 1; /* Display pcb address ? */ 171: int tflag = 1; /* Display interface timer ? */ 172: char *interface = NULL; /* interface name */ 173: int unit; /* interface unit */ 174: 175: struct fetch fetchnet[] = { 176: "_mbstat", (char *) &mbstat, sizeof mbstat, 177: "_mbfree", (char *) &mbfree, sizeof mbfree, 178: "_mbend", (char *) &mbend, sizeof mbend, 179: "_mbcache", (char *) mbcache, sizeof mbcache, 180: "_alloct", (char *) &alloct, sizeof alloct, 181: "_in_ckod", (char *) &in_ckodd, sizeof in_ckodd, 182: END 183: }; 184: 185: struct display net_tab[] = { 186: "\nMBUFS:\tfree (low water mark)", (char *) &(mbstat.m_mbufs),DEC,0, 187: "\tfree (current)", (char *) &(mbstat.m_mbfree), DEC,0, 188: "\n\tmbufs in mbuf cache", (char *) &mbstat.m_incache, DEC,0, 189: "\tdrops", (char *) &(mbstat.m_drops), DEC,0, 190: "\nMBUFX area:\tStart click", (char *) &mbstat.m_mbxbase, MAD,0, 191: "\tEnd click", (char *) &mbend, MAD,0, 192: "\n\tSize in bytes", (char *) &mbstat.m_mbxsize, MAD,0, 193: "\tmbufx free list (mbfree)", (char *) &mbfree, MAD,0, 194: "\nARENA:\tallocs", (char *) &allocs, MAD,0, 195: "\talloct", (char *) &alloct, MAD,0, 196: "\n\tchars free (low water mark)",(char *) &(mbstat.m_clusters),DEC,0, 197: "\tchars free (current)", (char *) &(mbstat.m_clfree), DEC,0, 198: "\nMIO area:\tstart of free area", (char *) &mbstat.m_iobase, MAD,0, 199: "\tchars free", (char *) &mbstat.m_iosize, MAD,0, 200: "\nMISC:\tin_ckodd", (char *) &in_ckodd, DEC,0, 201: END 202: }; 203: 204: struct display mbuf_tab[] = { 205: "\nnext", (char *) &((struct mbuf *)0)->m_next, MAD,0, 206: "\toff", (char *) &((struct mbuf *)0)->m_off, MAD,0, 207: "\tlen", (char *) &((struct mbuf *)0)->m_len, MAD,0, 208: "\ttype", (char *) &((struct mbuf *)0)->m_type, MAD,0, 209: "\tclick", (char *) &((struct mbuf *)0)->m_click, MAD,0, 210: "\tact", (char *) &((struct mbuf *)0)->m_act, MAD,0, 211: END 212: }; 213: 214: struct display mbufx_tab[] = { 215: "\tm_mbuf", (char *) &((struct mbufxh *)0)->mh_mbuf,MAD,0, 216: "\tm_ref", (char *) &((struct mbufxh *)0)->mh_ref, DEC,0, 217: END 218: }; 219: 220: /* 221: * Display mbuf status info 222: */ 223: dispnet() 224: { 225: char arena[NWORDS*2]; 226: 227: subhead = "Network Data"; 228: arenap = &arena[0]; /* fill in static variables */ 229: fetch(fetchnet); 230: allocs = findv("_allocs"); /* fill in automatic variables */ 231: vf("_allocs",(char *)arena, sizeof arena); 232: newpage(); 233: display(net_tab,0); 234: putchar('\n'); /* misc checks */ 235: if (alloct-allocs != (NWORDS-1)*2) 236: printf("%s allocs/alloct inconsistent. Recompile ???\n", FWARN); 237: if (mbfree != 0 && !VALMBXA(mbfree)) 238: printf("%s mbfree pointer bad\n", FWARN); 239: if (mbstat.m_incache < 0 || mbstat.m_incache >= mbstat.m_totcache) 240: printf("%s mbcache pointer bad\n", FWARN); 241: 242: arenack(); 243: mbufpr(); 244: 245: newpage(); 246: protopr((off_t)findv("_tcb"), "tcp"); 247: protopr((off_t)findv("_udb"), "udp"); 248: rawpr(); 249: tcp_stats((off_t)findv("_tcpstat"), "tcp"); 250: udp_stats((off_t)findv("_udpstat"), "udp"); 251: ip_stats((off_t)findv("_ipstat"), "ip"); 252: icmp_stats((off_t)findv("_icmpstat"), "icmp"); 253: 254: intpr(0,(off_t)findv("_ifnet")); 255: 256: routepr((off_t)findv("_rthost"), 257: (off_t)findv("_rtnet"), 258: (off_t)findv("_rthashsize")); 259: rt_stats((off_t)findv("_rtstat")); 260: 261: #ifdef INET 262: queuepr("_ipintrq", "ip"); 263: #endif INET 264: queuepr("_rawintr", "raw"); 265: 266: orphans(); 267: clrars(); /* return memory to pool */ 268: } 269: 270: queuepr(qname, qlbl) 271: char *qname, *qlbl; 272: { 273: struct ifqueue ifqueue; /* packet input queue */ 274: 275: putchar('\n'); 276: if(vf(qlbl, (char *) &ifqueue, sizeof ifqueue)) { 277: chasedm(ifqueue.ifq_head,"input",ifqueue.ifq_len); 278: printf("%s input queue:\n", qname); 279: printf("--head=%o tail=%o len=%d maxlen=%d drops=%d\n", 280: ifqueue.ifq_head, ifqueue.ifq_tail, ifqueue.ifq_len, 281: ifqueue.ifq_maxlen, ifqueue.ifq_drops); 282: } 283: } 284: 285: rawpr() 286: { 287: register struct rawcb *prev, *next; 288: struct rawcb *pcbp; 289: struct rawcb *arawcb; 290: struct socket *sockp; 291: struct protosw proto; 292: struct rawcb rawcb; 293: int rcvct; /* number of mbufs in receive queue */ 294: int sndct; /* number of mbufs in send queue */ 295: 296: printf("raw:\n"); 297: if (!vf("_rawcb", (char *) &rawcb, sizeof rawcb)) return; 298: arawcb = (struct rawcb *)findv("_rawcb"); 299: pcbp = &rawcb; 300: prev = arawcb; 301: while (pcbp->rcb_next != arawcb) { 302: next = pcbp->rcb_next; 303: if (!VALADD(next, struct rawcb)) { 304: printf("bad rawcb address ("); 305: DUMP((unsigned)next); 306: puts(")"); 307: break; 308: } 309: (putars((unsigned)next,sizeof(struct rawcb), 310: AS_RAWCB))->as_ref++; 311: pcbp = XLATE(next, struct rawcb *); 312: if (pcbp->rcb_prev != prev) { 313: puts("???"); 314: break; 315: } 316: printf("%6o ", next); 317: if (!VALADD(pcbp->rcb_socket, struct socket)) { 318: printf("bad socket address ("); 319: DUMP((unsigned)pcbp->rcb_socket); 320: puts(")"); 321: break; 322: } 323: (putars((unsigned)pcbp->rcb_socket,sizeof(struct socket), 324: AS_SOCK))->as_ref++; 325: sockp = XLATE(pcbp->rcb_socket, struct socket *); 326: klseek(kmem, (off_t)sockp->so_proto, 0); 327: read(kmem, &proto, sizeof (proto)); 328: /* chase the chains of mbufs */ 329: rcvct = chasem(sockp->so_rcv.sb_mb,"recv",sockp->so_rcv.sb_cc); 330: sndct = chasem(sockp->so_snd.sb_mb,"send",sockp->so_snd.sb_cc); 331: printaddress(&pcbp->rcb_laddr); 332: printaddress(&pcbp->rcb_faddr); 333: printf(" %4d%3d %4d%3d ",sockp->so_rcv.sb_cc, rcvct, 334: sockp->so_snd.sb_cc, sndct); 335: printproto(&proto); 336: putchar('\n'); 337: prev = next; 338: } 339: } 340: 341: mbufpr() 342: { 343: struct mbufxh mbufx; 344: register i, j, k; 345: unsigned base; 346: int count; 347: int freect; 348: 349: line = 22; 350: printf("\n\t\t\tMbuf dump\n\nmbcache:"); 351: for (i=0, count=0; i<mbstat.m_totcache; i++) { 352: if ((count++)%4 == 0) { 353: putchar('\n'); 354: line++; 355: } 356: DUMP((unsigned)mbcache[i]); 357: fputs(VALMBA(mbcache[i]) ? " " : "(bad) ",stdout); 358: } 359: printf("\n\n"); 360: #ifdef DIAGNOSTIC 361: { char mbts[32]; 362: for(i=0, j=mbstat.m_tbindex; i<mbstat.m_tbcount; i++, j--) { 363: if (j < 0) 364: j = mbstat.m_tbcount - 1; 365: k = (mbstat.m_tbuf[j].mt_type>>4)&0x0fff; 366: printf("%3d %s %4x %4x(%2d) ", i, 367: ((k<NMBTMSGS) ? mbtmsgs[k] : 368: sprintf(mbts, "%16d", k)), 369: mbstat.m_tbuf[j].mt_arg, 370: mbstat.m_tbuf[j].mt_pc, 371: mbstat.m_tbuf[j].mt_type&0x0f); 372: symbol(mbstat.m_tbuf[j].mt_pc, ISYM, 373: mbstat.m_tbuf[j].mt_type&0x0f); 374: putchar('\n'); 375: } 376: } 377: #endif DIAGNOSTIC 378: /* print header */ 379: line += 6; 380: puts("\n\n\t\t\tMbufs\n\n click mbuf ref next off len act click(mbuf)\n\n"); 381: 382: base = mbstat.m_mbxbase; 383: for(i=0, freect=0; i<mbstat.m_total ; i++) { 384: lseek(kmem, ((long)base<<6), 0); 385: read(kmem, &mbufx, sizeof mbufx); 386: DUMP(base); 387: putchar(' '); 388: DUMP((unsigned)mbufx.mh_mbuf); 389: printf("%5d ",mbufx.mh_ref); 390: /* check for validity */ 391: if (mbufx.mh_ref == 0) { 392: /* free */ 393: freect++; 394: printf( "%sfree" , DASHES); 395: if (mbufx.mh_mbuf && !VALMBXA(mbufx.mh_mbuf)) 396: fputs(" (bad pointer)",stdout); 397: } else if (!VALMBA(mbufx.mh_mbuf)) { 398: printf( "%sbad mbuf pointer" , DASHES); 399: } else { 400: struct arenas *asp; 401: register int j; 402: int found = 0; 403: 404: asp = putars(mbufx.mh_mbuf,sizeof(struct mbuf),AS_MBUF); 405: for (j=0; j<mbstat.m_totcache && j<mbstat.m_incache; 406: j++) { 407: if(mbufx.mh_mbuf == mbcache[j]) { 408: found++; 409: break; 410: } 411: } 412: if (found) { 413: /* in free cache */ 414: freect++; 415: asp->as_ref++; 416: printf("%sin free cache",DASHES); 417: if (mbufx.mh_ref != 1) 418: fputs("--bad ref count",stdout); 419: } else { 420: struct mbuf *mbptr; 421: 422: mbptr = XLATE(mbufx.mh_mbuf, struct mbuf *); 423: DUMP(mbptr->m_next); 424: printf(" %5d ",mbptr->m_off); 425: printf(" %5d ",mbptr->m_len); 426: printf(" %5d ",mbptr->m_type); 427: DUMP(mbptr->m_act); 428: if ((mbptr->m_click) != base) { 429: putchar(' '); 430: DUMP(mbptr->m_click); 431: } 432: } 433: } 434: putchar('\n'); 435: line++; 436: if (line > LINESPERPAGE) { 437: newpage(); 438: puts("\n click mbuf ref next off len act click(mbuf)\n"); 439: } 440: base += (MSIZE >> 6); 441: } 442: if (freect != mbstat.m_mbfree) { 443: printf("\n%s free count discrepancy--\n", FWARN); 444: printf("\n\tmbufx survey is %d, mbstat.m_mbfree is %d\n", 445: freect, mbstat.m_mbfree); 446: } 447: } 448: 449: /* 450: * Dump mbuf information 451: * Flag mbufs as free or unaccounted for 452: */ 453: orphans() 454: { 455: register i; 456: struct arenas *ap; 457: 458: puts("\n\t\tMbufs Unaccounted For\n\n\n addr next off len click act\n"); 459: ap = &arenash; 460: while (ap = ap->as_next) { 461: struct mbuf *mbptr; 462: 463: if (ap->as_ref || 464: (!(ap->as_flags & AS_MBUF) && 465: ap->as_size != sizeof(struct mbuf))) 466: continue; 467: mbptr = XLATE(ap->as_addr, struct mbuf *); 468: DUMP(ap->as_addr); 469: putchar(' '); 470: DUMP(mbptr->m_next); 471: putchar(' '); 472: DUMP(mbptr->m_off); 473: printf(" %5d ",mbptr->m_len); 474: DUMP(mbptr->m_click); 475: putchar(' '); 476: DUMP(mbptr->m_act); 477: if (!(ap->as_flags & AS_MBUF)) 478: fputs(" no refs at all",stdout); 479: putchar('\n'); 480: } 481: puts("\n\t\tA Trip through the Arena\n"); 482: ap = &arenash; 483: while (ap = ap->as_next) { 484: if (ap->as_ref || (ap->as_flags & AS_MBUF) == AS_MBUF) continue; 485: printf("addr=%4x size=%d flags=%4x ", ap->as_addr, 486: ap->as_size, ap->as_flags); 487: switch (ap->as_size) { 488: case sizeof(struct ifnet): 489: puts("ifnet"); 490: break; 491: case sizeof(struct in_addr): 492: puts("in_addr"); 493: break; 494: case sizeof(struct in_ifaddr): 495: puts("in_ifaddr"); 496: break; 497: case sizeof(struct inpcb): 498: puts("inpcb"); 499: break; 500: case sizeof(struct ipasfrag): 501: puts("ipasfrag"); 502: break; 503: case sizeof(struct ipq): 504: puts("ipq"); 505: break; 506: case sizeof(struct mbuf): 507: puts("mbuf"); 508: break; 509: #ifdef notyet 510: case sizeof(struct ns_ifaddr): 511: puts("ns_ifaddr"); 512: break; 513: case sizeof(struct nspcb): 514: puts("nspcb"); 515: break; 516: case sizeof(struct sppcb): 517: puts("sppcb"); 518: break; 519: #endif 520: case sizeof(struct protosw): 521: puts("protosw"); 522: break; 523: case sizeof(struct rawcb): 524: puts("rawcb"); 525: break; 526: case sizeof(struct rtentry): 527: puts("rtentry"); 528: break; 529: case sizeof(struct sockaddr_in): 530: puts("sockaddr_in"); 531: break; 532: case sizeof(struct socket): 533: puts("socket"); 534: break; 535: case sizeof(struct tcpcb): 536: puts("tcpcb"); 537: break; 538: case sizeof(struct tcpiphdr): 539: puts("tcpiphdr"); 540: break; 541: case sizeof(struct unpcb): 542: puts("unpcb"); 543: break; 544: default: 545: puts("unknown size"); 546: break; 547: } 548: } 549: } 550: 551: printproto(sp) 552: register struct protosw *sp; 553: { 554: register struct pfname *pf = pfnames; 555: register struct prname *pr; 556: 557: #ifdef HACK 558: while (pf->pf_name) { 559: if (pf->pf_id == sp->pr_family) { 560: printf("%7s/", pf->pf_name); 561: if (pr = pf->pf_protos) 562: while (pr->pr_name) { 563: if (pr->pr_id == sp->pr_protocol) { 564: printf("%-5s", pr->pr_name); 565: return; 566: } 567: pr++; 568: } 569: printf("%-5d", sp->pr_protocol); 570: return; 571: } 572: pf++; 573: } 574: printf("%7d/%-5d", sp->pr_family, sp->pr_protocol); 575: #endif HACK 576: } 577: 578: printaddress(sa) 579: register struct sockaddr *sa; 580: { 581: register struct sockname *sn; 582: 583: for (sn = addrnames; sn->sa_name; sn++) 584: if (sn->sa_id == sa->sa_family) { 585: printf("%8s,", sn->sa_name); 586: if (!sn->sa_printer) goto generic; 587: (*sn->sa_printer)(sa); 588: return; 589: } 590: printf("%8d,", sa->sa_family); 591: generic: 592: printf("%-8s", "?"); 593: } 594: 595: internetprint(sin) 596: register struct sockaddr_in *sin; 597: { 598: inetprint(&sin->sin_addr, sin->sin_port, "tcp"); 599: } 600: 601: /* 602: * Chase list of mbufs, using m_next and m_act fields. 603: */ 604: chasedm(mbufp,str,cc) 605: register struct mbuf *mbufp; 606: char *str; 607: int cc; 608: { 609: register struct arenas *asp; 610: int count = 0; 611: int chcnt = 0; 612: register struct mbuf *mbptr; /* points into arena */ 613: 614: while (mbufp) { 615: count += chaseit(mbufp,str,&chcnt); 616: if (!VALMBA(mbufp)) { 617: printf("---------bad mbuf pointer in %s queue (=%o)\n", 618: str,mbufp); 619: break; 620: } 621: if (!(asp=getars(mbufp)) || 622: (asp->as_flags&AS_MBUF) != AS_MBUF) { 623: printf("---------mbuf in %s queue not in list (=%o)\n", 624: str,mbufp); 625: break; 626: } 627: mbptr = XLATE(mbufp, struct mbuf *); 628: mbufp = mbptr->m_act; 629: } 630: if (cc != chcnt) 631: printf( Fccd, DASHES, str, chcnt); 632: return(count); 633: } 634: 635: /* 636: * Chase list of mbufs, using only m_next field. 637: */ 638: chasem(mbufp,str,cc) 639: register struct mbuf *mbufp; 640: char *str; 641: int cc; 642: { 643: register struct arenas *asp; 644: int count = 0; 645: int chcnt = 0; 646: register struct mbuf *mbptr; /* points into arena */ 647: 648: count = chaseit(mbufp, str, &chcnt); 649: if (cc != chcnt) 650: printf( Fccd, DASHES, str, chcnt); 651: return(count); 652: } 653: 654: 655: chaseit(mbufp,str,achcnt) 656: register struct mbuf *mbufp; 657: char *str; 658: int *achcnt; 659: { 660: register struct arenas *asp; 661: int count = 0; 662: register struct mbuf *mbptr; /* points into arena */ 663: 664: while (mbufp) { 665: int err = 0; 666: 667: count++; 668: if (!VALMBA(mbufp)) { 669: printf("%sbad mbuf pointer in %s queue (=%o)\n", 670: DASHES, str,mbufp); 671: break; 672: } 673: else if (!(asp=getars(mbufp)) || 674: (asp->as_flags&AS_MBUF) != AS_MBUF) { 675: printf("%smbuf in %s queue not in list (=%o)\n", 676: DASHES, str,mbufp); 677: asp = putars(mbufp,sizeof(struct mbuf),AS_MBUF); 678: mbptr = XLATE(mbufp, struct mbuf *); 679: printf("%soff=%d len=%d type=%d act=%o click=%o",DASHES, 680: mbptr->m_off, mbptr->m_len, mbptr->m_type, 681: mbptr->m_act, mbptr->m_click); 682: if(!VALMBXA(mbptr->m_click)) 683: printf("(bad)"); 684: putchar('\n'); 685: } 686: asp->as_ref++; 687: mbptr = XLATE(mbufp, struct mbuf *); 688: if (mbptr->m_len < 0 || mbptr->m_len > MLEN) { 689: printf("---------bad mbuf length in %s queue;\n",str); 690: err++; 691: } 692: if (mbptr->m_off < MMINOFF || mbptr->m_off >MMAXOFF) { 693: printf("---------bad mbuf offset in %s queue;\n",str); 694: err++; 695: } 696: if (err) 697: printf("---------off=%d len=%d type=%d act=%o click=%o\n", 698: mbptr->m_off, mbptr->m_len, mbptr->m_type, 699: mbptr->m_act, mbptr->m_click); 700: *achcnt += mbptr->m_len; 701: mbufp = mbptr->m_next; 702: } 703: return(count); 704: } 705: 706: clrars() 707: { 708: register struct arenas *asp; 709: register struct arenas *next = arenash.as_next; 710: 711: while (asp = next) { 712: next = asp->as_next; 713: free(asp); 714: } 715: arenash.as_next = (struct arenas *) 0; 716: } 717: 718: /* 719: * Put entry for arena block in arena statistics list 720: * This version allows entries with the same address 721: */ 722: struct arenas * 723: putars(addr,size,flags) 724: register unsigned addr; 725: int size, flags; 726: { 727: register struct arenas *asp = &arenash; 728: register struct arenas *prev; 729: unsigned temp; 730: 731: /* calculate size and get busy flag from info in arena */ 732: 733: temp = *(int *)(arenap + (unsigned)addr - allocs - 2); 734: if (temp&01==0) /* make sure not marked as free */ 735: flags |= AS_FREE; 736: if ((temp&~01) - addr != size) 737: flags |= AS_BDSZ; 738: 739: while(1) { 740: prev = asp; 741: asp = asp->as_next; 742: if (asp == 0 || addr < asp->as_addr) { 743: if (!(prev->as_next = (struct arenas *)malloc(sizeof(struct arenas)))) barf("out of memory"); 744: prev = prev->as_next; 745: prev->as_next = asp; 746: prev->as_size = size; 747: prev->as_ref = 0; 748: prev->as_addr = addr; 749: prev->as_flags = flags; 750: return(prev); 751: } 752: if (addr == asp->as_addr && (!(asp->as_flags & ~AS_ARCK)) && asp->as_size == size && !asp->as_ref) { 753: asp->as_flags |= flags; 754: return(asp); 755: } 756: } 757: } 758: 759: /* 760: * Find arena stat structure in list 761: * Return zero if not found. 762: */ 763: struct arenas * 764: getars(addr) 765: register unsigned addr; 766: { 767: register struct arenas *asp = &arenash; 768: 769: while (asp=asp->as_next) { 770: if (asp->as_addr == addr) 771: return(asp); 772: } 773: return((struct arenas *)0); 774: } 775: 776: /* 777: * Check arena for consistency 778: */ 779: arenack() 780: { 781: unsigned ptr = allocs; 782: unsigned temp; 783: unsigned next; 784: int busy; 785: int size; 786: int fsize = 0; /* free size, should equal mbstat.clfree */ 787: 788: fputs("\narena check:",stdout); 789: for (;;) { 790: temp = *(int *)(ptr - allocs + (unsigned)arenap); 791: busy = temp & 01; 792: next = temp & ~01; 793: if (next < allocs || next > alloct || 794: (ptr > next && (ptr != alloct || next != allocs))){ 795: printf("\n%s arena clobbered; location: ", FWARN); 796: DUMP(ptr); 797: fputs(" pointer: ",stdout); 798: DUMP(temp); 799: return; 800: } 801: if (ptr > next) { 802: printf("\n\tfree count: %d.\n",fsize); 803: return; 804: } 805: size = next - ptr -2; 806: if (!busy) 807: fsize += (size+2); 808: else 809: putars(ptr+2,size,AS_ARCK); 810: ptr = next; 811: } 812: } 813: 814: char * 815: hoststr(addr) 816: long addr; 817: { 818: struct hostent *hp; 819: 820: hp = gethostbyaddr((char *) &addr, sizeof addr, AF_INET); 821: if (hp) 822: return(hp->h_name); 823: else 824: return(inet_ntoa(addr)); 825: } 826: 827: char * 828: getnet(addr) 829: union { 830: long a_long; 831: char a_octet[4]; 832: } addr; 833: { 834: char buf[32]; 835: struct netent *np; 836: 837: np = getnetbyaddr(inet_netof(addr.a_long), AF_INET); 838: if (np) 839: return(np->n_name); 840: else { 841: sprintf(buf, "%u", (unsigned)addr.a_octet[0]); 842: if((unsigned)addr.a_octet[0] >= 128) 843: sprintf(buf+strlen(buf), ".%u", (unsigned)addr.a_octet[1]); 844: if((unsigned)addr.a_octet[0] >= 192) 845: sprintf(buf+strlen(buf), ".%u", (unsigned)addr.a_octet[2]); 846: return(buf); 847: } 848: } 849: 850: char * 851: plural(n) 852: long n; 853: { 854: 855: return (n != 1 ? "s" : ""); 856: } 857: 858: #ifdef for_handy_reference 859: struct tcpcb { 860: struct tcpiphdr *seg_next; /* sequencing queue */ 861: struct tcpiphdr *seg_prev; 862: short t_state; /* state of this connection */ 863: short t_timer[TCPT_NTIMERS]; /* tcp timers */ 864: short t_rxtshift; /* log(2) of rexmt exp. backoff */ 865: struct mbuf *t_tcpopt; /* tcp options */ 866: u_short t_maxseg; /* maximum segment size */ 867: char t_force; /* 1 if forcing out a byte */ 868: u_char t_flags; 869: #define TF_ACKNOW 0x01 /* ack peer immediately */ 870: #define TF_DELACK 0x02 /* ack, but try to delay it */ 871: #define TF_NODELAY 0x04 /* don't delay packets to coalesce */ 872: #define TF_NOOPT 0x08 /* don't use tcp options */ 873: #define TF_SENTFIN 0x10 /* have sent FIN */ 874: struct tcpiphdr *t_template; /* skeletal packet for transmit */ 875: struct inpcb *t_inpcb; /* back pointer to internet pcb */ 876: /* 877: * The following fields are used as in the protocol specification. 878: * See RFC783, Dec. 1981, page 21. 879: */ 880: /* send sequence variables */ 881: tcp_seq snd_una; /* send unacknowledged */ 882: tcp_seq snd_nxt; /* send next */ 883: tcp_seq snd_up; /* send urgent pointer */ 884: tcp_seq snd_wl1; /* window update seg seq number */ 885: tcp_seq snd_wl2; /* window update seg ack number */ 886: tcp_seq iss; /* initial send sequence number */ 887: u_short snd_wnd; /* send window */ 888: /* receive sequence variables */ 889: u_short rcv_wnd; /* receive window */ 890: tcp_seq rcv_nxt; /* receive next */ 891: tcp_seq rcv_up; /* receive urgent pointer */ 892: tcp_seq irs; /* initial receive sequence number */ 893: /* 894: * Additional variables for this implementation. 895: */ 896: /* receive variables */ 897: tcp_seq rcv_adv; /* advertised window */ 898: /* retransmit variables */ 899: tcp_seq snd_max; /* highest sequence number sent 900: * used to recognize retransmits 901: */ 902: /* congestion control (for source quench) */ 903: u_short snd_cwnd; /* congestion-controlled window */ 904: /* transmit timing stuff */ 905: short t_idle; /* inactivity time */ 906: short t_rtt; /* round trip time */ 907: u_short max_rcvd; /* most peer has sent into window */ 908: tcp_seq t_rtseq; /* sequence number being timed */ 909: short t_srtt; /* smoothed round-trip time (*10) */ 910: u_short max_sndwnd; /* largest window peer has offered */ 911: /* out-of-band data */ 912: char t_oobflags; /* have some */ 913: char t_iobc; /* input character */ 914: #define TCPOOB_HAVEDATA 0x01 915: #define TCPOOB_HADDATA 0x02 916: }; 917: #endif for_handy_reference