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

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

unix.superglobalmegacorp.com

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