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