|
|
1.1 ! root 1: #include "inet.h" ! 2: #if NINET > 0 ! 3: ! 4: #include "../h/param.h" ! 5: #include "../h/stream.h" ! 6: #include "../h/conf.h" ! 7: #include "../h/inet/in.h" ! 8: #include "../h/inet/ip.h" ! 9: #include "../h/inet/ip_var.h" ! 10: #include "../h/inet/mbuf.h" ! 11: #include "sparam.h" ! 12: ! 13: #define NBLOCK (NBLKBIG+NBLK64+NBLK16+NBLK4) ! 14: ! 15: struct block * ! 16: bp_get() ! 17: { ! 18: register struct block *bp; ! 19: ! 20: bp = allocb(64); ! 21: if(bp) ! 22: bp->next = 0; ! 23: return(bp); ! 24: } ! 25: ! 26: bp_check(bp) ! 27: register struct block *bp; ! 28: { ! 29: extern struct block cblock[]; ! 30: ! 31: while(bp){ ! 32: if(bp < cblock || cblock >= &cblock[NBLOCK]) ! 33: panic("bp_check bad bp"); ! 34: if(bp->rptr == 0 || bp->wptr == 0 || bp->base == 0 || bp->lim == 0) ! 35: panic("bp_check 0"); ! 36: if(bp->rptr >= bp->lim || bp->rptr < bp->base) ! 37: panic("bp_check rptr"); ! 38: if(bp->wptr > bp->lim || bp->wptr < bp->base) ! 39: panic("bp_check wptr"); ! 40: bp = bp->next; ! 41: } ! 42: } ! 43: ! 44: /* given a char *, come up with the block that holds it. yuk. */ ! 45: int dtom_hits, dtom_misses; ! 46: u_char *xfirst16, *xfirst64, *xfirst1024, *xp; ! 47: struct block *xbp; ! 48: ! 49: struct block * ! 50: bp_dtom(p) ! 51: u_char *p; ! 52: { ! 53: extern struct block cblock[]; ! 54: extern u_char blkdata[]; ! 55: register u_char *first16, *first64, *first1024; ! 56: register struct block *bp; ! 57: ! 58: /* guess. the order of things in blkdata is NBLK4, NBLK16, ... */ ! 59: first16 = &blkdata[4 * NBLK4]; ! 60: first64 = &first16[16 * NBLK16]; ! 61: first1024 = &first64[64 * NBLK64]; ! 62: if(p < first16){ ! 63: bp = &cblock[(p - blkdata) / 4]; ! 64: } else if(p < first64){ ! 65: bp = &cblock[NBLK4 + (p - first16) / 16]; ! 66: } else if(p < first1024){ ! 67: bp = &cblock[NBLK4 + NBLK16 + (p - first64) / 64]; ! 68: } else { ! 69: bp = &cblock[NBLK4 + NBLK16 + NBLK64 + (p - first1024) / 1024]; ! 70: } ! 71: if(bp->base && bp->lim && bp->rptr && bp->wptr ! 72: && (p >= bp->base) && (p < bp->lim)){ ! 73: dtom_hits++; ! 74: return(bp); ! 75: } ! 76: xfirst16 = first16; ! 77: xfirst64 = first64; ! 78: xfirst1024 = first1024; ! 79: xp = p; ! 80: xbp = bp; ! 81: dtom_misses++; ! 82: for(bp = &cblock[NBLOCK-1]; bp >= &cblock[0]; --bp){ ! 83: if(bp->base == 0 || bp->lim == 0 || bp->rptr == 0 || bp->wptr == 0) ! 84: continue; ! 85: if((p >= bp->base) && (p < bp->lim)){ ! 86: return(bp); ! 87: } ! 88: } ! 89: panic("bp_dtom"); ! 90: /* NOTREACHED */ ! 91: } ! 92: ! 93: /* bp_pullup: make the first block have at least len bytes */ ! 94: struct block * ! 95: bp_pullup(bp, len) ! 96: register struct block *bp; ! 97: { ! 98: register struct block *m, *n, *nn; ! 99: int count; ! 100: ! 101: n = bp; ! 102: if(len > MAXBLEN) ! 103: goto bad; ! 104: m = allocb(MAXBLEN); ! 105: if(m == 0) ! 106: goto bad; ! 107: do{ ! 108: count = MIN(BSZ(m) - BLEN(m), len); ! 109: if(count > BLEN(n)) ! 110: count = BLEN(n); ! 111: bcopy(n->rptr, m->wptr, (unsigned)count); ! 112: len -= count; ! 113: m->wptr += count; ! 114: n->rptr += count; ! 115: if(BLEN(n)) ! 116: break; ! 117: nn = n->next; ! 118: freeb(n); ! 119: n = nn; ! 120: } while(n); ! 121: if(len){ ! 122: freeb(m); ! 123: goto bad; ! 124: } ! 125: m->next = n; ! 126: return(m); ! 127: bad: ! 128: printf("m_pullup bad\n"); ! 129: bp_free(n); ! 130: return(0); ! 131: } ! 132: ! 133: bp_free(bp) ! 134: register struct block *bp; ! 135: { ! 136: register struct block *p; ! 137: ! 138: while(bp){ ! 139: p = bp->next; ! 140: /* ! 141: if((bp->rptr >= bp->lim) || (bp->wptr > bp->lim)) ! 142: panic("bp_free"); ! 143: if((bp->rptr < bp->base) || (bp->wptr < bp->base)){ ! 144: printf("bp 0x%x, rptr 0x%x\n", bp, bp->rptr); ! 145: panic("bp_free1"); ! 146: } ! 147: */ ! 148: freeb(bp); ! 149: bp = p; ! 150: } ! 151: } ! 152: ! 153: struct block * ! 154: bp_copy(m, off, len) ! 155: register struct block *m; ! 156: int off; ! 157: register int len; ! 158: { ! 159: register struct block *n, **np; ! 160: struct block *top; ! 161: ! 162: if(len == 0) ! 163: return(0); ! 164: if(off < 0 || len < 0) ! 165: panic("m_copy"); ! 166: while(off > 0){ ! 167: if(m == 0) ! 168: panic("m_copy 1"); ! 169: if(off < BLEN(m)) ! 170: break; ! 171: off -= BLEN(m); ! 172: m = m->m_next; ! 173: } ! 174: np = ⊤ ! 175: top = 0; ! 176: while(len > 0){ ! 177: if(m == 0) ! 178: panic("m_copy 2"); ! 179: #undef FAKE ! 180: #ifdef FAKE ! 181: n = allocb(1); /* fake block, will adjust pointers */ ! 182: #else ! 183: n = allocb(len); ! 184: #endif FAKE ! 185: *np = n; ! 186: if(n == 0) ! 187: goto nospace; ! 188: n->next = 0; ! 189: #ifdef FAKE ! 190: /* fake them up */ ! 191: n->rptr = mtod(m, u_char *)+off; ! 192: n->wptr = n->rptr + MIN(len, BLEN(m) - off); ! 193: /* pu meht ekaf */ ! 194: #else ! 195: n->wptr += MIN(len, BLEN(m) - off); ! 196: bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t), ! 197: (unsigned)BLEN(n)); ! 198: #endif FAKE ! 199: len -= BLEN(n); ! 200: off = 0; ! 201: m = m->next; ! 202: np = &n->m_next; ! 203: } ! 204: return(top); ! 205: nospace: ! 206: m_freem(top); ! 207: return(0); ! 208: } ! 209: ! 210: m_adj(mp, len) ! 211: struct block *mp; ! 212: register int len; ! 213: { ! 214: register struct block *m, *n; ! 215: ! 216: if((m = mp) == NULL) ! 217: return; ! 218: if(len >= 0){ ! 219: while(m && len > 0){ ! 220: if(BLEN(m) <= len){ ! 221: len -= BLEN(m); ! 222: m->wptr = m->rptr; ! 223: m = m->m_next; ! 224: } else { ! 225: m->rptr += len; ! 226: break; ! 227: } ! 228: } ! 229: } else { ! 230: len = -len; ! 231: while(len > 0 && m && BLEN(m) != 0){ ! 232: while(m && BLEN(m) != 0){ ! 233: n = m; ! 234: m = m->next; ! 235: } ! 236: if(BLEN(n) <= len){ ! 237: len -= BLEN(n); ! 238: n->wptr = n->rptr; ! 239: m = mp; ! 240: } else { ! 241: n->wptr -= len; ! 242: break; ! 243: } ! 244: } ! 245: } ! 246: } ! 247: ! 248: m_cat(m, n) ! 249: register struct mbuf *m, *n; ! 250: { ! 251: register struct mbuf *xn; ! 252: ! 253: while(m->m_next) ! 254: m = m->m_next; ! 255: ! 256: while(n){ ! 257: if((m->wptr + BLEN(n)) >= m->lim){ ! 258: /* just join the two chains */ ! 259: m->m_next = n; ! 260: return; ! 261: } ! 262: /* splat the data from one into the other */ ! 263: bcopy(mtod(n, caddr_t), m->wptr, BLEN(n)); ! 264: m->wptr += BLEN(n); ! 265: xn = n->next; ! 266: m_free(n); ! 267: n = xn; ! 268: } ! 269: } ! 270: ! 271: ! 272: /* in_cksum.c 6.1 83/07/29 */ ! 273: /* ! 274: * yuck, but i can't get it right myself. ! 275: */ ! 276: ! 277: /* ! 278: * Checksum routine for Internet Protocol family headers (VAX Version). ! 279: * ! 280: * This routine is very heavily used in the network ! 281: * code and should be modified for each CPU to be as fast as possible. ! 282: */ ! 283: ! 284: in_cksum(m, len) ! 285: register struct mbuf *m; ! 286: register int len; ! 287: { ! 288: register u_short *w; /* on vax, known to be r9 */ ! 289: register int sum = 0; /* on vax, known to be r8 */ ! 290: register int mlen = 0; ! 291: ! 292: for (;;) { ! 293: /* ! 294: * Each trip around loop adds in ! 295: * word from one mbuf segment. ! 296: */ ! 297: w = mtod(m, u_short *); ! 298: if (mlen == -1) { ! 299: /* ! 300: * There is a byte left from the last segment; ! 301: * add it into the checksum. Don't have to worry ! 302: * about a carry-out here because we make sure ! 303: * that high part of (32 bit) sum is small below. ! 304: */ ! 305: sum += *(u_char *)w << 8; ! 306: w = (u_short *)((char *)w + 1); ! 307: mlen = BLEN(m) - 1; ! 308: len--; ! 309: } else ! 310: mlen = BLEN(m); ! 311: m = m->m_next; ! 312: if (len < mlen) ! 313: mlen = len; ! 314: len -= mlen; ! 315: /* ! 316: * Force to long boundary so we do longword aligned ! 317: * memory operations. It is too hard to do byte ! 318: * adjustment, do only word adjustment. ! 319: */ ! 320: if (((int)w&0x2) && mlen >= 2) { ! 321: sum += *w++; ! 322: mlen -= 2; ! 323: } ! 324: /* ! 325: * Do as much of the checksum as possible 32 bits at at time. ! 326: * In fact, this loop is unrolled to make overhead from ! 327: * branches &c small. ! 328: * ! 329: * We can do a 16 bit ones complement sum 32 bits at a time ! 330: * because the 32 bit register is acting as two 16 bit ! 331: * registers for adding, with carries from the low added ! 332: * into the high (by normal carry-chaining) and carries ! 333: * from the high carried into the low on the next word ! 334: * by use of the adwc instruction. This lets us run ! 335: * this loop at almost memory speed. ! 336: * ! 337: * Here there is the danger of high order carry out, and ! 338: * we carefully use adwc. ! 339: */ ! 340: while ((mlen -= 32) >= 0) { ! 341: #undef ADD ! 342: asm("clrl r0"); /* clears carry */ ! 343: #define ADD asm("adwc (r9)+,r8;"); ! 344: ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD; ! 345: asm("adwc $0,r8"); ! 346: } ! 347: mlen += 32; ! 348: while ((mlen -= 8) >= 0) { ! 349: asm("clrl r0"); ! 350: ADD; ADD; ! 351: asm("adwc $0,r8"); ! 352: } ! 353: mlen += 8; ! 354: /* ! 355: * Now eliminate the possibility of carry-out's by ! 356: * folding back to a 16 bit number (adding high and ! 357: * low parts together.) Then mop up trailing words ! 358: * and maybe an odd byte. ! 359: */ ! 360: { asm("ashl $-16,r8,r0; addw2 r0,r8"); ! 361: asm("adwc $0,r8; movzwl r8,r8"); } ! 362: while ((mlen -= 2) >= 0) { ! 363: asm("movzwl (r9)+,r0; addl2 r0,r8"); ! 364: } ! 365: if (mlen == -1) { ! 366: sum += *(u_char *)w; ! 367: } ! 368: if (len == 0) ! 369: break; ! 370: /* ! 371: * Locate the next block with some data. ! 372: * If there is a word split across a boundary we ! 373: * will wrap to the top with mlen == -1 and ! 374: * then add it in shifted appropriately. ! 375: */ ! 376: for (;;) { ! 377: if (m == 0) { ! 378: printf("cksum: out of data\n"); ! 379: goto done; ! 380: } ! 381: if (BLEN(m)) ! 382: break; ! 383: m = m->m_next; ! 384: } ! 385: } ! 386: done: ! 387: /* ! 388: * Add together high and low parts of sum ! 389: * and carry to get cksum. ! 390: * Have to be careful to not drop the last ! 391: * carry here. ! 392: */ ! 393: { asm("ashl $-16,r8,r0; addw2 r0,r8; adwc $0,r8"); ! 394: asm("mcoml r8,r8; movzwl r8,r8"); } ! 395: return (sum); ! 396: } ! 397: ! 398: in_addr ! 399: in_netof(x) ! 400: in_addr x; ! 401: { ! 402: if(IN_CLASSC(x)) ! 403: return(x&IN_CLASSC_NET); ! 404: else if(IN_CLASSB(x)) ! 405: return(x&IN_CLASSB_NET); ! 406: else ! 407: return(x&IN_CLASSA_NET); ! 408: } ! 409: ! 410: in_addr ! 411: in_hostof(x) ! 412: in_addr x; ! 413: { ! 414: if(IN_CLASSC(x)) ! 415: return(x&IN_CLASSC_HOST); ! 416: else if(IN_CLASSB(x)) ! 417: return(x&IN_CLASSB_HOST); ! 418: else ! 419: return(x&IN_CLASSA_HOST); ! 420: } ! 421: ! 422: /* ! 423: * Routes are kept in a circular list. Ip_default_route points to the ! 424: * "first" position in the list. On each acess, the accessed element is ! 425: * moved to this first position. ! 426: */ ! 427: #define NROUTES 50 ! 428: struct ip_route ip_routes[NROUTES]; ! 429: int Nip_route = NROUTES; /* let netstat know number of routes */ ! 430: struct ip_route ip_default_route = { 0, 0, &ip_default_route }; ! 431: ! 432: ip_doroute(dst, gate) ! 433: in_addr dst, gate; ! 434: { ! 435: register struct ip_route *rp, *save; ! 436: register struct ipif *ifp; ! 437: ! 438: if(gate){ ! 439: /* no-ops are ignored */ ! 440: if (dst == gate) ! 441: return(0); ! 442: ! 443: /* don't accept an indirect route, if we have a direct one */ ! 444: for(ifp = ipif; ifp < &ipif[NINET]; ifp++){ ! 445: if((ifp->flags&IFF_UP) ! 446: && ifp->that == dst) ! 447: return(0); ! 448: } ! 449: } ! 450: /* look through existing routes (looks at ip_default_route first)*/ ! 451: rp = &ip_default_route; ! 452: do { ! 453: if (dst == rp->next->dst) { ! 454: if (gate) { ! 455: rp->next->gate = gate; ! 456: } else { ! 457: rp->next->dst = rp->next->gate = 0; ! 458: rp->next = rp->next->next; ! 459: } ! 460: return(0); ! 461: } ! 462: rp = rp->next; ! 463: } while (rp != &ip_default_route); ! 464: if (gate == 0) ! 465: return(0); ! 466: /* add a new route */ ! 467: for(rp = &ip_routes[0]; rp < &ip_routes[NROUTES]; rp++) ! 468: if(rp->dst == 0) { ! 469: rp->dst = dst; ! 470: rp->gate = gate; ! 471: rp->next = ip_default_route.next; ! 472: ip_default_route.next = rp; ! 473: return(0); ! 474: } ! 475: return(1); ! 476: } ! 477: ! 478: /* Look for a route on the circular list. If the route is found, move ! 479: * it to the beginning of the list. ! 480: */ ! 481: struct ip_route_info ! 482: ip_route(dst) ! 483: in_addr dst; ! 484: { ! 485: extern unsigned long in_netof(); ! 486: unsigned long netof_dst; ! 487: register struct ip_route *rp, *trp; ! 488: struct ip_route_info info; ! 489: ! 490: /* look for host routes (start after ip_default_route) */ ! 491: for(rp = &ip_default_route; rp->next != &ip_default_route; rp=rp->next) ! 492: if (dst == rp->next->dst) { ! 493: /* make sure the interface exists */ ! 494: info.addr = rp->next->gate; ! 495: info.ifp = ip_ifonnetof(info.addr); ! 496: if(info.ifp == 0) ! 497: break; ! 498: /* move to first */ ! 499: trp = rp->next; ! 500: rp->next = rp->next->next; ! 501: trp->next = ip_default_route.next; ! 502: ip_default_route.next = trp; ! 503: return(info); ! 504: } ! 505: /* now try nets (start after ip_default_route) */ ! 506: netof_dst = in_netof(dst); ! 507: for (rp = &ip_default_route; rp->next != &ip_default_route; rp=rp->next) ! 508: if(netof_dst == rp->next->dst){ ! 509: /* make sure the interface exists */ ! 510: info.addr = rp->next->gate; ! 511: info.ifp = ip_ifonnetof(info.addr); ! 512: if(info.ifp == 0) ! 513: break; ! 514: /* move to first */ ! 515: trp = rp->next; ! 516: rp->next = rp->next->next; ! 517: trp->next = ip_default_route.next; ! 518: ip_default_route.next = trp; ! 519: return(info); ! 520: } ! 521: /* try a network to which we are directly connected */ ! 522: info.addr = dst; ! 523: info.ifp = ip_ifonnetof(dst); ! 524: if (info.ifp) ! 525: return info; ! 526: /* if all else fails, use default route */ ! 527: info.addr = ip_default_route.gate; ! 528: info.ifp = ip_ifonnetof(info.addr); ! 529: return(info); ! 530: } ! 531: ! 532: bp_len(bp) ! 533: register struct block *bp; ! 534: { ! 535: int n; ! 536: ! 537: n = 0; ! 538: while(bp){ ! 539: n += BLEN(bp); ! 540: bp = bp->next; ! 541: } ! 542: return(n); ! 543: } ! 544: ! 545: in_addr ! 546: ip_hoston(dst) ! 547: in_addr dst; ! 548: { ! 549: struct ip_route_info info; ! 550: ! 551: info = ip_route(dst); ! 552: if(info.ifp == 0) ! 553: return(0); ! 554: return(info.ifp->thishost); ! 555: } ! 556: ! 557: in_lnaof(i) ! 558: register u_long i; ! 559: { ! 560: ! 561: if(IN_CLASSA(i)) ! 562: return((i)&IN_CLASSA_HOST); ! 563: else if(IN_CLASSB(i)) ! 564: return((i)&IN_CLASSB_HOST); ! 565: else ! 566: return((i)&IN_CLASSC_HOST); ! 567: } ! 568: #endif NINET
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.