Annotation of researchv9/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: extern long time;
        !            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:        while(bp){
        !            30:                BLOCKCHK(bp);
        !            31:                bp = bp->next;
        !            32:        }
        !            33: }
        !            34: 
        !            35: /* given a char *, come up with the block that holds it. yuk. */
        !            36: int dtom_hits, dtom_misses;
        !            37: static u_char *xfirst16, *xfirst64, *xfirst1024, *xp;
        !            38: struct block *xbp;
        !            39: 
        !            40: struct block *
        !            41: bp_dtom(p)
        !            42: u_char *p;
        !            43: {
        !            44:        extern struct block cblock[];
        !            45:        extern u_char blkdata[];
        !            46:        register u_char *first16, *first64, *first1024;
        !            47:        register struct block *bp;
        !            48: 
        !            49:        /* guess. the order of things in blkdata is NBLK4, NBLK16, ... */
        !            50: #ifdef CHKBLK
        !            51:        first16 = &blkdata[5 * NBLK4];
        !            52:        first64 = &first16[17 * NBLK16];
        !            53:        first1024 = &first64[65 * NBLK64];
        !            54:        if(p < first16){
        !            55:                bp = &cblock[(p - blkdata) / 5];
        !            56:        } else if(p < first64){
        !            57:                bp = &cblock[NBLK4 + (p - first16) / 17];
        !            58:        } else if(p < first1024){
        !            59:                bp = &cblock[NBLK4 + NBLK16 + (p - first64) / 65];
        !            60:        } else {
        !            61:                bp = &cblock[NBLK4 + NBLK16 + NBLK64 + (p - first1024) / 1025];
        !            62:        }
        !            63: #else
        !            64:        first16 = &blkdata[4 * NBLK4];
        !            65:        first64 = &first16[16 * NBLK16];
        !            66:        first1024 = &first64[64 * NBLK64];
        !            67:        if(p < first16){
        !            68:                bp = &cblock[(p - blkdata) / 4];
        !            69:        } else if(p < first64){
        !            70:                bp = &cblock[NBLK4 + (p - first16) / 16];
        !            71:        } else if(p < first1024){
        !            72:                bp = &cblock[NBLK4 + NBLK16 + (p - first64) / 64];
        !            73:        } else {
        !            74:                bp = &cblock[NBLK4 + NBLK16 + NBLK64 + (p - first1024) / 1024];
        !            75:        }
        !            76: #endif CHKBLK
        !            77:        if(bp->base && bp->lim && bp->rptr && bp->wptr
        !            78:           && (p >= bp->base) && (p < bp->lim)){
        !            79:                BLOCKCHK(bp);
        !            80:                dtom_hits++;
        !            81:                return(bp);
        !            82:        }
        !            83:        xfirst16 = first16;
        !            84:        xfirst64 = first64;
        !            85:        xfirst1024 = first1024;
        !            86:        xp = p;
        !            87:        xbp = bp;
        !            88:        dtom_misses++;
        !            89:        for(bp = &cblock[NBLOCK-1]; bp >= &cblock[0]; --bp){
        !            90:                if(bp->base == 0 || bp->lim == 0 || bp->rptr == 0 || bp->wptr == 0)
        !            91:                        continue;
        !            92:                if((p >= bp->base) && (p < bp->lim)){
        !            93:                        return(bp);
        !            94:                }
        !            95:        }
        !            96:        panic("bp_dtom");
        !            97:        /* NOTREACHED */
        !            98: }
        !            99: 
        !           100: /* bp_pullup: make the first block have at least len bytes */
        !           101: struct block *
        !           102: bp_pullup(bp, len)
        !           103: register struct block *bp;
        !           104: {
        !           105:        register struct block *m, *n, *nn;
        !           106:        int count;
        !           107: 
        !           108:        n = bp;
        !           109:        if(len > MAXBLEN)
        !           110:                goto bad;
        !           111:        m = allocb(MAXBLEN);
        !           112:        if(m == 0)
        !           113:                goto bad;
        !           114:        do{
        !           115:                count = len;
        !           116:                if (m->lim - m->wptr < count)
        !           117:                        count = m->lim - m->wptr;
        !           118:                if (BLEN(n) < count)
        !           119:                        count = BLEN(n);
        !           120:                bcopy(n->rptr, m->wptr, (unsigned)count);
        !           121:                len -= count;
        !           122:                m->wptr += count;
        !           123:                n->rptr += count;
        !           124:                if(BLEN(n))
        !           125:                        break;
        !           126:                nn = n->next;
        !           127:                freeb(n);
        !           128:                n = nn;
        !           129:        } while(n);
        !           130:        if(len){
        !           131:                freeb(m);
        !           132:                goto bad;
        !           133:        }
        !           134:        m->next = n;
        !           135:        MCHECK(m);
        !           136:        return(m);
        !           137: bad:
        !           138:        printf("m_pullup bad\n");
        !           139:        bp_free(n);
        !           140:        return(0);
        !           141: }
        !           142: 
        !           143: bp_free(bp)
        !           144: register struct block *bp;
        !           145: {
        !           146:        register struct block *p;
        !           147: 
        !           148:        while(bp){
        !           149:                p = bp->next;
        !           150:                BLOCKCHK(bp);
        !           151:                freeb(bp);
        !           152:                bp = p;
        !           153:        }
        !           154: }
        !           155: 
        !           156: struct block *
        !           157: bp_copy(m, off, len)
        !           158: register struct block *m;
        !           159: int off;
        !           160: register int len;
        !           161: {
        !           162:        register struct block *n, **np;
        !           163:        struct block *top;
        !           164:        register int clen;
        !           165: 
        !           166:        MCHECK(m);
        !           167:        if(len == 0)
        !           168:                return(0);
        !           169:        if(off < 0 || len < 0)
        !           170:                panic("m_copy");
        !           171:        while(off > 0){
        !           172:                if(m == 0)
        !           173:                        panic("m_copy 1");
        !           174:                if(off < BLEN(m))
        !           175:                        break;
        !           176:                off -= BLEN(m);
        !           177:                m = m->next;
        !           178:        }
        !           179:        np = &top;
        !           180:        top = 0;
        !           181:        while(len > 0){
        !           182:                if(m == 0)
        !           183:                        panic("m_copy 2");
        !           184:                n = allocb(len);
        !           185:                *np = n;
        !           186:                if(n == 0)
        !           187:                        goto nospace;
        !           188:                n->next = 0;
        !           189:                np = &n->next;
        !           190:                do {
        !           191:                        clen = len;
        !           192:                        if (BLEN(m) - off < clen)
        !           193:                                clen = BLEN(m) - off;
        !           194:                        if (n->lim - n->wptr < clen)
        !           195:                                clen = n->lim - n->wptr;
        !           196:                        bcopy((caddr_t)m->rptr+off, (caddr_t)n->wptr, clen);
        !           197:                        n->wptr += clen;
        !           198:                        len -= clen;
        !           199:                        if (len <= 0) {
        !           200:                                MCHECK(top);
        !           201:                                return (top);
        !           202:                        }
        !           203:                        if (m->rptr + off + clen < m->wptr)
        !           204:                                off += clen;
        !           205:                        else {
        !           206:                                off = 0;
        !           207:                                m = m->next;
        !           208:                        }
        !           209:                } while (n->wptr < n->lim);
        !           210:        }
        !           211:        MCHECK(top);
        !           212:        return(top);
        !           213: nospace:
        !           214:        bp_free(top);
        !           215:        return(0);
        !           216: }
        !           217: 
        !           218: bp_adj(m, len)
        !           219: register struct block *m;
        !           220: register int len;
        !           221: {
        !           222: 
        !           223:        if (m == NULL)
        !           224:                return;
        !           225:        MCHECK(m);
        !           226:        if (len > 0) {
        !           227:                while(m && len > 0){
        !           228:                        if(BLEN(m) <= len){
        !           229:                                len -= BLEN(m);
        !           230:                                m->wptr = m->rptr;
        !           231:                                m = m->next;
        !           232:                        } else {
        !           233:                                m->rptr += len;
        !           234:                                break;
        !           235:                        }
        !           236:                }
        !           237:        }
        !           238:        else if (len < 0) {
        !           239:                len = bp_len(m) + len;
        !           240:                if (len <= 0) {
        !           241:                        if (m->next)
        !           242:                                bp_free(m->next);
        !           243:                        m->next = 0;
        !           244:                        m->wptr = m->rptr;
        !           245:                        return;
        !           246:                }
        !           247:                while ((len -= BLEN(m)) > 0) {
        !           248:                        if ((m = m->next) == NULL)
        !           249:                                return;
        !           250:                }
        !           251:                m->wptr += len;         /* len is <= 0 */
        !           252:                bp_free(m->next);
        !           253:                m->next = 0;
        !           254:        }
        !           255:        MCHECK(m);
        !           256: }
        !           257: 
        !           258: m_cat(m, n)
        !           259: register struct block *m, *n;
        !           260: {
        !           261:        struct mbuf *xn;
        !           262: 
        !           263:        MCHECK(m); MCHECK(n);
        !           264:        while(m->next)
        !           265:                m = m->next;
        !           266:        while(n){
        !           267:                if((m->wptr + BLEN(n)) >= m->lim){
        !           268:                        /* just join the two chains */
        !           269:                        m->next = n;
        !           270:                        break;
        !           271:                }
        !           272:                /* splat the data from one into the other */
        !           273:                bcopy(n->rptr, m->wptr, BLEN(n));
        !           274:                m->wptr += BLEN(n);
        !           275:                xn = n->next;
        !           276:                freeb(n);
        !           277:                n = xn;
        !           278:        }
        !           279:        MCHECK(m);
        !           280: }
        !           281: 
        !           282: /* C version of 4.2bsd's Internet checksum routine */
        !           283: /* This version assumes that no message exceeds 2^16 words */
        !           284: in_cksum(m, len)
        !           285:        register struct mbuf *m;
        !           286:        register int len;
        !           287: {
        !           288:        register u_short *w;
        !           289:        register u_long sum = 0;
        !           290:        register int mlen = 0;
        !           291: 
        !           292:        MCHECK(m);
        !           293:        for (; len!=0; m=m->m_next) {
        !           294:                if (m == NULL) {
        !           295:                        printf("cksum: out of data\n");
        !           296:                        break;
        !           297:                }
        !           298:                w = mtod(m, u_short *);
        !           299:                if (mlen == -1) {
        !           300:                        /* last block ended on an odd numbered byte */
        !           301:                        sum += *(u_char *)w << 8;
        !           302:                        w = (u_short *)((char *)w + 1);
        !           303:                        mlen = BLEN(m) - 1;
        !           304:                        len--;
        !           305:                } else
        !           306:                        mlen = BLEN(m);
        !           307:                if (len < mlen)
        !           308:                        mlen = len;
        !           309:                len -= mlen;
        !           310:                /* vecadd returns a 16-bit checksum of the block + sum */
        !           311:                sum = vecadd(w, mlen, sum);
        !           312:        }
        !           313:        /* return complement of sum */
        !           314:        return sum^0xffff;
        !           315: }
        !           316: 
        !           317: in_addr
        !           318: in_netof(x)
        !           319: in_addr x;
        !           320: {
        !           321:        in_addr netmask;
        !           322:        struct ipif *ifp;
        !           323: 
        !           324:        if(IN_CLASSC(x))
        !           325:                netmask = IN_CLASSC_NET;
        !           326:        else if(IN_CLASSB(x))
        !           327:                netmask = IN_CLASSB_NET;
        !           328:        else
        !           329:                netmask = IN_CLASSA_NET;
        !           330: 
        !           331:        /* look for an interface for this network and use its subnet mask */
        !           332:        for(ifp = &ipif[0]; ifp < &ipif[NINET]; ifp++){
        !           333:                if(ifp->flags & IFF_UP){
        !           334:                        if(netmask&x == netmask&ifp->that)
        !           335:                                if (ifp->mask==0)
        !           336:                                        return(x&netmask);
        !           337:                                else
        !           338:                                        return(x&ifp->mask);
        !           339:                }
        !           340:        }
        !           341: 
        !           342:        /* no interface for this network, assume no subnetting */
        !           343:        return x&netmask;
        !           344: }
        !           345: 
        !           346: /*
        !           347:  * Hash table for route entries.  Collision resolution is linear search until
        !           348:  * encountering a hole.  Replacement is LRU.
        !           349:  */
        !           350: #define NROUTES 128
        !           351: struct ip_route ip_routes[NROUTES];
        !           352: int Nip_route = NROUTES;               /* let netstat know number of routes */
        !           353: #define HASH(x) (((x)+((x)>>8))%NROUTES)
        !           354: struct ip_route ip_default_route;
        !           355: 
        !           356: ip_doroute(dst, gate)
        !           357:        in_addr dst, gate;
        !           358: {
        !           359:        register struct ip_route *rp, *sp, *op;
        !           360:        register struct ipif *ifp;
        !           361: 
        !           362:        /* default is a special case */
        !           363:        if (dst == 0){
        !           364:                ip_default_route.gate = gate;
        !           365:                return(0);
        !           366:        }
        !           367: 
        !           368:        /* look for what should be a noop */
        !           369:        if(gate){
        !           370:                /* don't accept an indirect route, if we have a direct one */
        !           371:                for(ifp = ipif; ifp < &ipif[NINET]; ifp++){
        !           372:                        if((ifp->flags&IFF_UP) && ifp->that==dst)
        !           373:                                return(0);
        !           374:                }
        !           375:        } else
        !           376:                gate = dst;
        !           377: 
        !           378:        /* look through existing routes */
        !           379:        op = sp = rp = &ip_routes[HASH(dst)];
        !           380:        do {
        !           381:                if (rp->dst==0 || rp->dst==dst) {
        !           382:                        op = rp;
        !           383:                        break;
        !           384:                }
        !           385:                if (rp->time<op->time)
        !           386:                        op = rp;
        !           387:                if (++rp==&ip_routes[NROUTES])
        !           388:                        rp = ip_routes;
        !           389:        } while (rp != sp);
        !           390: 
        !           391:        /* add a new route */
        !           392:        op->dst = dst;
        !           393:        op->gate = gate;
        !           394:        op->time = time;
        !           395:        return(0);
        !           396: }
        !           397: 
        !           398: /* Look for a route on the circular list.  If the route is found, move
        !           399:  * it to the beginning of the list.
        !           400:  */
        !           401: struct ip_route_info
        !           402: ip_route(dst)
        !           403:        in_addr dst;
        !           404: {
        !           405:        register struct ip_route *rp, *sp;
        !           406:        extern unsigned long in_netof();
        !           407:        unsigned long netof_dst;
        !           408:        struct ip_route_info info;
        !           409: 
        !           410:        /* try a network to which we are directly connected */
        !           411:        info.addr = dst;
        !           412:        info.ifp = ip_ifonnetof(dst);
        !           413:        if (info.ifp)
        !           414:                return info;
        !           415: 
        !           416:        /* look for host routes */
        !           417:        sp = rp = &ip_routes[HASH(dst)];
        !           418:        do {
        !           419:                if (dst==rp->dst && rp->dst!=rp->gate) {
        !           420:                        info.addr = rp->gate;
        !           421:                        info.ifp = ip_ifonnetof(info.addr);
        !           422:                        rp->time = time;
        !           423:                        return(info);
        !           424:                }
        !           425:                if (rp->dst==0)
        !           426:                        break;
        !           427:                if (++rp==&ip_routes[NROUTES])
        !           428:                        rp = ip_routes;
        !           429:        } while (rp != sp);
        !           430: 
        !           431:        /* now try nets */
        !           432:        netof_dst = in_netof(dst);
        !           433:        sp = rp = &ip_routes[HASH(netof_dst)];
        !           434:        do {
        !           435:                if (netof_dst==rp->dst && rp->dst!=rp->gate) {
        !           436:                        info.addr = rp->gate;
        !           437:                        info.ifp = ip_ifonnetof(info.addr);
        !           438:                        rp->time = time;
        !           439:                        return(info);
        !           440:                }
        !           441:                if (rp->dst==0)
        !           442:                        break;
        !           443:                if (++rp==&ip_routes[NROUTES])
        !           444:                        rp = ip_routes;
        !           445:        } while (rp != sp);
        !           446: 
        !           447:        /* if all else fails, use default route */
        !           448:        /* N.B.  If the gate is a network, don't change the destination
        !           449:         *      address.  This allows multiple networks on one wire by
        !           450:         *      making that wire the default.
        !           451:         */
        !           452:        if (ip_default_route.gate!=in_netof(ip_default_route.gate))
        !           453:                info.addr = ip_default_route.gate;
        !           454:        else
        !           455:                info.addr = dst;
        !           456:        info.ifp = ip_ifonnetof(ip_default_route.gate);
        !           457:        return(info);
        !           458: }
        !           459: 
        !           460: bp_len(bp)
        !           461: register struct block *bp;
        !           462: {
        !           463:        register int n;
        !           464: 
        !           465:        n = 0;
        !           466:        while(bp){
        !           467:                n += BLEN(bp);
        !           468:                bp = bp->next;
        !           469:        }
        !           470:        return(n);
        !           471: }
        !           472: 
        !           473: bp_putback(q, list)
        !           474: struct queue *q;
        !           475: struct block *list;
        !           476: {
        !           477:        register struct block *bp;
        !           478:        register struct block *prev, *next;
        !           479: 
        !           480:        /*
        !           481:         * reverse the list, to keep data in order
        !           482:         */
        !           483:        prev = next = NULL;
        !           484:        for (bp = list; bp; bp = next) {
        !           485:                next = bp->next;
        !           486:                bp->next = prev;
        !           487:                prev = bp;
        !           488:        }
        !           489:        for (bp = prev; bp; bp = next) {
        !           490:                next = bp->next;
        !           491:                putbq(q, bp);
        !           492:        }
        !           493: }
        !           494: 
        !           495: in_addr
        !           496: ip_hoston(dst)
        !           497: in_addr dst;
        !           498: {
        !           499:        struct ip_route_info info;
        !           500: 
        !           501:        info = ip_route(dst);
        !           502:        if(info.ifp == 0)
        !           503:                return(0);
        !           504:        return(info.ifp->thishost);
        !           505: }
        !           506: 
        !           507: in_lnaof(i)
        !           508: register u_long i;
        !           509: {
        !           510: 
        !           511:        if(IN_CLASSA(i))
        !           512:                return((i)&IN_CLASSA_HOST);
        !           513:        else if(IN_CLASSB(i))
        !           514:                return((i)&IN_CLASSB_HOST);
        !           515:        else
        !           516:                return((i)&IN_CLASSC_HOST);
        !           517: }
        !           518: #endif NINET

unix.superglobalmegacorp.com

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