Annotation of researchv9/sys/inet/ip_subr.c, revision 1.1.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.