Annotation of researchv8dc/sys/inet/ip_subr.c, revision 1.1

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 = &top;
        !           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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.