Annotation of researchv8dc/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: #define NBLOCK (NBLKBIG+NBLK64+NBLK16+NBLK4)
                     14: 
                     15: struct block *
                     16: bp_get()
                     17: {
                     18:        register struct block *bp;
                     19: 
                     20:        bp = allocb(64);
                     21:        if(bp)
                     22:                bp->next = 0;
                     23:        return(bp);
                     24: }
                     25: 
                     26: bp_check(bp)
                     27: register struct block *bp;
                     28: {
                     29:        extern struct block cblock[];
                     30: 
                     31:        while(bp){
                     32:                if(bp < cblock || cblock >= &cblock[NBLOCK])
                     33:                        panic("bp_check bad bp");
                     34:                if(bp->rptr == 0 || bp->wptr == 0 || bp->base == 0 || bp->lim == 0)
                     35:                        panic("bp_check 0");
                     36:                if(bp->rptr >= bp->lim || bp->rptr < bp->base)
                     37:                        panic("bp_check rptr");
                     38:                if(bp->wptr > bp->lim || bp->wptr < bp->base)
                     39:                        panic("bp_check wptr");
                     40:                bp = bp->next;
                     41:        }
                     42: }
                     43: 
                     44: /* given a char *, come up with the block that holds it. yuk. */
                     45: int dtom_hits, dtom_misses;
                     46: u_char *xfirst16, *xfirst64, *xfirst1024, *xp;
                     47: struct block *xbp;
                     48: 
                     49: struct block *
                     50: bp_dtom(p)
                     51: u_char *p;
                     52: {
                     53:        extern struct block cblock[];
                     54:        extern u_char blkdata[];
                     55:        register u_char *first16, *first64, *first1024;
                     56:        register struct block *bp;
                     57: 
                     58:        /* guess. the order of things in blkdata is NBLK4, NBLK16, ... */
                     59:        first16 = &blkdata[4 * NBLK4];
                     60:        first64 = &first16[16 * NBLK16];
                     61:        first1024 = &first64[64 * NBLK64];
                     62:        if(p < first16){
                     63:                bp = &cblock[(p - blkdata) / 4];
                     64:        } else if(p < first64){
                     65:                bp = &cblock[NBLK4 + (p - first16) / 16];
                     66:        } else if(p < first1024){
                     67:                bp = &cblock[NBLK4 + NBLK16 + (p - first64) / 64];
                     68:        } else {
                     69:                bp = &cblock[NBLK4 + NBLK16 + NBLK64 + (p - first1024) / 1024];
                     70:        }
                     71:        if(bp->base && bp->lim && bp->rptr && bp->wptr
                     72:           && (p >= bp->base) && (p < bp->lim)){
                     73:                dtom_hits++;
                     74:                return(bp);
                     75:        }
                     76:        xfirst16 = first16;
                     77:        xfirst64 = first64;
                     78:        xfirst1024 = first1024;
                     79:        xp = p;
                     80:        xbp = bp;
                     81:        dtom_misses++;
                     82:        for(bp = &cblock[NBLOCK-1]; bp >= &cblock[0]; --bp){
                     83:                if(bp->base == 0 || bp->lim == 0 || bp->rptr == 0 || bp->wptr == 0)
                     84:                        continue;
                     85:                if((p >= bp->base) && (p < bp->lim)){
                     86:                        return(bp);
                     87:                }
                     88:        }
                     89:        panic("bp_dtom");
                     90:        /* NOTREACHED */
                     91: }
                     92: 
                     93: /* bp_pullup: make the first block have at least len bytes */
                     94: struct block *
                     95: bp_pullup(bp, len)
                     96: register struct block *bp;
                     97: {
                     98:        register struct block *m, *n, *nn;
                     99:        int count;
                    100: 
                    101:        n = bp;
                    102:        if(len > MAXBLEN)
                    103:                goto bad;
                    104:        m = allocb(MAXBLEN);
                    105:        if(m == 0)
                    106:                goto bad;
                    107:        do{
                    108:                count = MIN(BSZ(m) - BLEN(m), len);
                    109:                if(count > BLEN(n))
                    110:                        count = BLEN(n);
                    111:                bcopy(n->rptr, m->wptr, (unsigned)count);
                    112:                len -= count;
                    113:                m->wptr += count;
                    114:                n->rptr += count;
                    115:                if(BLEN(n))
                    116:                        break;
                    117:                nn = n->next;
                    118:                freeb(n);
                    119:                n = nn;
                    120:        } while(n);
                    121:        if(len){
                    122:                freeb(m);
                    123:                goto bad;
                    124:        }
                    125:        m->next = n;
                    126:        return(m);
                    127: bad:
                    128:        printf("m_pullup bad\n");
                    129:        bp_free(n);
                    130:        return(0);
                    131: }
                    132: 
                    133: bp_free(bp)
                    134: register struct block *bp;
                    135: {
                    136:        register struct block *p;
                    137: 
                    138:        while(bp){
                    139:                p = bp->next;
                    140: /*
                    141:                if((bp->rptr >= bp->lim) || (bp->wptr > bp->lim))
                    142:                        panic("bp_free");
                    143:                if((bp->rptr < bp->base) || (bp->wptr < bp->base)){
                    144:                        printf("bp 0x%x, rptr 0x%x\n", bp, bp->rptr);
                    145:                        panic("bp_free1");
                    146:                }
                    147: */
                    148:                freeb(bp);
                    149:                bp = p;
                    150:        }
                    151: }
                    152: 
                    153: struct block *
                    154: bp_copy(m, off, len)
                    155: register struct block *m;
                    156: int off;
                    157: register int len;
                    158: {
                    159:        register struct block *n, **np;
                    160:        struct block *top;
                    161: 
                    162:        if(len == 0)
                    163:                return(0);
                    164:        if(off < 0 || len < 0)
                    165:                panic("m_copy");
                    166:        while(off > 0){
                    167:                if(m == 0)
                    168:                        panic("m_copy 1");
                    169:                if(off < BLEN(m))
                    170:                        break;
                    171:                off -= BLEN(m);
                    172:                m = m->m_next;
                    173:        }
                    174:        np = &top;
                    175:        top = 0;
                    176:        while(len > 0){
                    177:                if(m == 0)
                    178:                        panic("m_copy 2");
                    179: #undef FAKE
                    180: #ifdef FAKE
                    181:                n = allocb(1);  /* fake block, will adjust pointers */
                    182: #else
                    183:                n = allocb(len);
                    184: #endif FAKE
                    185:                *np = n;
                    186:                if(n == 0)
                    187:                        goto nospace;
                    188:                n->next = 0;
                    189: #ifdef FAKE
                    190:                /* fake them up */
                    191:                n->rptr = mtod(m, u_char *)+off;
                    192:                n->wptr = n->rptr + MIN(len, BLEN(m) - off);
                    193:                /* pu meht ekaf */
                    194: #else
                    195:                n->wptr += MIN(len, BLEN(m) - off);
                    196:                bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
                    197:                        (unsigned)BLEN(n));
                    198: #endif FAKE
                    199:                len -= BLEN(n);
                    200:                off = 0;
                    201:                m = m->next;
                    202:                np  = &n->m_next;
                    203:        }
                    204:        return(top);
                    205: nospace:
                    206:        m_freem(top);
                    207:        return(0);
                    208: }
                    209: 
                    210: m_adj(mp, len)
                    211: struct block *mp;
                    212: register int len;
                    213: {
                    214:        register struct block *m, *n;
                    215: 
                    216:        if((m = mp) == NULL)
                    217:                return;
                    218:        if(len >= 0){
                    219:                while(m && len > 0){
                    220:                        if(BLEN(m) <= len){
                    221:                                len -= BLEN(m);
                    222:                                m->wptr = m->rptr;
                    223:                                m = m->m_next;
                    224:                        } else {
                    225:                                m->rptr += len;
                    226:                                break;
                    227:                        }
                    228:                }
                    229:        } else {
                    230:                len = -len;
                    231:                while(len > 0 && m && BLEN(m) != 0){
                    232:                        while(m && BLEN(m) != 0){
                    233:                                n = m;
                    234:                                m = m->next;
                    235:                        }
                    236:                        if(BLEN(n) <= len){
                    237:                                len -= BLEN(n);
                    238:                                n->wptr = n->rptr;
                    239:                                m = mp;
                    240:                        } else {
                    241:                                n->wptr -= len;
                    242:                                break;
                    243:                        }
                    244:                }
                    245:        }
                    246: }
                    247: 
                    248: m_cat(m, n)
                    249: register struct mbuf *m, *n;
                    250: {
                    251:        register struct mbuf *xn;
                    252: 
                    253:        while(m->m_next)
                    254:                m = m->m_next;
                    255: 
                    256:        while(n){
                    257:                if((m->wptr + BLEN(n)) >= m->lim){
                    258:                        /* just join the two chains */
                    259:                        m->m_next = n;
                    260:                        return;
                    261:                }
                    262:                /* splat the data from one into the other */
                    263:                bcopy(mtod(n, caddr_t), m->wptr, BLEN(n));
                    264:                m->wptr += BLEN(n);
                    265:                xn = n->next;
                    266:                m_free(n);
                    267:                n = xn;
                    268:        }
                    269: }
                    270: 
                    271: 
                    272: /*     in_cksum.c      6.1     83/07/29        */
                    273: /*
                    274:  * yuck, but i can't get it right myself.
                    275:  */
                    276: 
                    277: /*
                    278:  * Checksum routine for Internet Protocol family headers (VAX Version).
                    279:  *
                    280:  * This routine is very heavily used in the network
                    281:  * code and should be modified for each CPU to be as fast as possible.
                    282:  */
                    283: 
                    284: in_cksum(m, len)
                    285:        register struct mbuf *m;
                    286:        register int len;
                    287: {
                    288:        register u_short *w;            /* on vax, known to be r9 */
                    289:        register int sum = 0;           /* on vax, known to be r8 */
                    290:        register int mlen = 0;
                    291: 
                    292:        for (;;) {
                    293:                /*
                    294:                 * Each trip around loop adds in
                    295:                 * word from one mbuf segment.
                    296:                 */
                    297:                w = mtod(m, u_short *);
                    298:                if (mlen == -1) {
                    299:                        /*
                    300:                         * There is a byte left from the last segment;
                    301:                         * add it into the checksum.  Don't have to worry
                    302:                         * about a carry-out here because we make sure
                    303:                         * that high part of (32 bit) sum is small below.
                    304:                         */
                    305:                        sum += *(u_char *)w << 8;
                    306:                        w = (u_short *)((char *)w + 1);
                    307:                        mlen = BLEN(m) - 1;
                    308:                        len--;
                    309:                } else
                    310:                        mlen = BLEN(m);
                    311:                m = m->m_next;
                    312:                if (len < mlen)
                    313:                        mlen = len;
                    314:                len -= mlen;
                    315:                /*
                    316:                 * Force to long boundary so we do longword aligned
                    317:                 * memory operations.  It is too hard to do byte
                    318:                 * adjustment, do only word adjustment.
                    319:                 */
                    320:                if (((int)w&0x2) && mlen >= 2) {
                    321:                        sum += *w++;
                    322:                        mlen -= 2;
                    323:                }
                    324:                /*
                    325:                 * Do as much of the checksum as possible 32 bits at at time.
                    326:                 * In fact, this loop is unrolled to make overhead from
                    327:                 * branches &c small.
                    328:                 *
                    329:                 * We can do a 16 bit ones complement sum 32 bits at a time
                    330:                 * because the 32 bit register is acting as two 16 bit
                    331:                 * registers for adding, with carries from the low added
                    332:                 * into the high (by normal carry-chaining) and carries
                    333:                 * from the high carried into the low on the next word
                    334:                 * by use of the adwc instruction.  This lets us run
                    335:                 * this loop at almost memory speed.
                    336:                 *
                    337:                 * Here there is the danger of high order carry out, and
                    338:                 * we carefully use adwc.
                    339:                 */
                    340:                while ((mlen -= 32) >= 0) {
                    341: #undef ADD
                    342:                        asm("clrl r0");         /* clears carry */
                    343: #define ADD            asm("adwc (r9)+,r8;");
                    344:                        ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
                    345:                        asm("adwc $0,r8");
                    346:                }
                    347:                mlen += 32;
                    348:                while ((mlen -= 8) >= 0) {
                    349:                        asm("clrl r0");
                    350:                        ADD; ADD;
                    351:                        asm("adwc $0,r8");
                    352:                }
                    353:                mlen += 8;
                    354:                /*
                    355:                 * Now eliminate the possibility of carry-out's by
                    356:                 * folding back to a 16 bit number (adding high and
                    357:                 * low parts together.)  Then mop up trailing words
                    358:                 * and maybe an odd byte.
                    359:                 */
                    360:                { asm("ashl $-16,r8,r0; addw2 r0,r8");
                    361:                  asm("adwc $0,r8; movzwl r8,r8"); }
                    362:                while ((mlen -= 2) >= 0) {
                    363:                        asm("movzwl (r9)+,r0; addl2 r0,r8");
                    364:                }
                    365:                if (mlen == -1) {
                    366:                        sum += *(u_char *)w;
                    367:                }
                    368:                if (len == 0)
                    369:                        break;
                    370:                /*
                    371:                 * Locate the next block with some data.
                    372:                 * If there is a word split across a boundary we
                    373:                 * will wrap to the top with mlen == -1 and
                    374:                 * then add it in shifted appropriately.
                    375:                 */
                    376:                for (;;) {
                    377:                        if (m == 0) {
                    378:                                printf("cksum: out of data\n");
                    379:                                goto done;
                    380:                        }
                    381:                        if (BLEN(m))
                    382:                                break;
                    383:                        m = m->m_next;
                    384:                }
                    385:        }
                    386: done:
                    387:        /*
                    388:         * Add together high and low parts of sum
                    389:         * and carry to get cksum.
                    390:         * Have to be careful to not drop the last
                    391:         * carry here.
                    392:         */
                    393:        { asm("ashl $-16,r8,r0; addw2 r0,r8; adwc $0,r8");
                    394:          asm("mcoml r8,r8; movzwl r8,r8"); }
                    395:        return (sum);
                    396: }
                    397: 
                    398: in_addr
                    399: in_netof(x)
                    400: in_addr x;
                    401: {
                    402:        if(IN_CLASSC(x))
                    403:                return(x&IN_CLASSC_NET);
                    404:        else if(IN_CLASSB(x))
                    405:                return(x&IN_CLASSB_NET);
                    406:        else
                    407:                return(x&IN_CLASSA_NET);
                    408: }
                    409: 
                    410: in_addr
                    411: in_hostof(x)
                    412: in_addr x;
                    413: {
                    414:        if(IN_CLASSC(x))
                    415:                return(x&IN_CLASSC_HOST);
                    416:        else if(IN_CLASSB(x))
                    417:                return(x&IN_CLASSB_HOST);
                    418:        else
                    419:                return(x&IN_CLASSA_HOST);
                    420: }
                    421: 
                    422: /*
                    423:  *  Routes are kept in a circular list.  Ip_default_route points to the
                    424:  *  "first" position in the list.  On each acess, the accessed element is
                    425:  *  moved to this first position.
                    426:  */
                    427: #define NROUTES 50
                    428: struct ip_route ip_routes[NROUTES];
                    429: int Nip_route = NROUTES;               /* let netstat know number of routes */
                    430: struct ip_route ip_default_route = { 0, 0, &ip_default_route };
                    431: 
                    432: ip_doroute(dst, gate)
                    433: in_addr dst, gate;
                    434: {
                    435:        register struct ip_route *rp, *save;
                    436:        register struct ipif *ifp;
                    437: 
                    438:        if(gate){
                    439:                /* no-ops are ignored */
                    440:                if (dst == gate)
                    441:                        return(0);
                    442: 
                    443:                /* don't accept an indirect route, if we have a direct one */
                    444:                for(ifp = ipif; ifp < &ipif[NINET]; ifp++){
                    445:                        if((ifp->flags&IFF_UP)
                    446:                           && ifp->that == dst)
                    447:                                return(0);
                    448:                }
                    449:        }
                    450:        /* look through existing routes (looks at ip_default_route first)*/
                    451:        rp = &ip_default_route;
                    452:        do {
                    453:                if (dst == rp->next->dst) {
                    454:                        if (gate) {
                    455:                                rp->next->gate = gate;
                    456:                        } else {
                    457:                                rp->next->dst = rp->next->gate = 0;
                    458:                                rp->next = rp->next->next;
                    459:                        }
                    460:                        return(0);
                    461:                }
                    462:                rp = rp->next;
                    463:        } while (rp != &ip_default_route);
                    464:        if (gate == 0)
                    465:                return(0);
                    466:        /* add a new route */
                    467:        for(rp = &ip_routes[0]; rp < &ip_routes[NROUTES]; rp++)
                    468:                if(rp->dst == 0) {
                    469:                        rp->dst = dst;
                    470:                        rp->gate = gate;
                    471:                        rp->next = ip_default_route.next;
                    472:                        ip_default_route.next = rp;
                    473:                        return(0);
                    474:                }
                    475:        return(1);
                    476: }
                    477: 
                    478: /* Look for a route on the circular list.  If the route is found, move
                    479:  * it to the beginning of the list.
                    480:  */
                    481: struct ip_route_info
                    482: ip_route(dst)
                    483: in_addr dst;
                    484: {
                    485:        extern unsigned long in_netof();
                    486:        unsigned long netof_dst;
                    487:        register struct ip_route *rp, *trp;
                    488:        struct ip_route_info info;
                    489: 
                    490:        /* look for host routes (start after ip_default_route) */
                    491:        for(rp = &ip_default_route; rp->next != &ip_default_route; rp=rp->next)
                    492:                if (dst == rp->next->dst) {
                    493:                        /* make sure the interface exists */
                    494:                        info.addr = rp->next->gate;
                    495:                        info.ifp = ip_ifonnetof(info.addr);
                    496:                        if(info.ifp == 0)
                    497:                                break;
                    498:                        /* move to first */
                    499:                        trp = rp->next;
                    500:                        rp->next = rp->next->next;
                    501:                        trp->next = ip_default_route.next;
                    502:                        ip_default_route.next = trp;
                    503:                        return(info);
                    504:                }
                    505:        /* now try nets (start after ip_default_route) */
                    506:        netof_dst = in_netof(dst);
                    507:        for (rp = &ip_default_route; rp->next != &ip_default_route; rp=rp->next)
                    508:                if(netof_dst == rp->next->dst){
                    509:                        /* make sure the interface exists */
                    510:                        info.addr = rp->next->gate;
                    511:                        info.ifp = ip_ifonnetof(info.addr);
                    512:                        if(info.ifp == 0)
                    513:                                break;
                    514:                        /* move to first */
                    515:                        trp = rp->next;
                    516:                        rp->next = rp->next->next;
                    517:                        trp->next = ip_default_route.next;
                    518:                        ip_default_route.next = trp;
                    519:                        return(info);
                    520:                }
                    521:        /* try a network to which we are directly connected */
                    522:        info.addr = dst;
                    523:        info.ifp = ip_ifonnetof(dst);
                    524:        if (info.ifp)
                    525:                return info;
                    526:        /* if all else fails, use default route */
                    527:        info.addr = ip_default_route.gate;
                    528:        info.ifp = ip_ifonnetof(info.addr);
                    529:        return(info);
                    530: }
                    531: 
                    532: bp_len(bp)
                    533: register struct block *bp;
                    534: {
                    535:        int n;
                    536: 
                    537:        n = 0;
                    538:        while(bp){
                    539:                n += BLEN(bp);
                    540:                bp = bp->next;
                    541:        }
                    542:        return(n);
                    543: }
                    544: 
                    545: in_addr
                    546: ip_hoston(dst)
                    547: in_addr dst;
                    548: {
                    549:        struct ip_route_info info;
                    550: 
                    551:        info = ip_route(dst);
                    552:        if(info.ifp == 0)
                    553:                return(0);
                    554:        return(info.ifp->thishost);
                    555: }
                    556: 
                    557: in_lnaof(i)
                    558: register u_long i;
                    559: {
                    560: 
                    561:        if(IN_CLASSA(i))
                    562:                return((i)&IN_CLASSA_HOST);
                    563:        else if(IN_CLASSB(i))
                    564:                return((i)&IN_CLASSB_HOST);
                    565:        else
                    566:                return((i)&IN_CLASSC_HOST);
                    567: }
                    568: #endif NINET

unix.superglobalmegacorp.com

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