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

1.1     ! root        1: /*
        !             2:  * ip line discipline, to be pushed on an ethernet controller.
        !             3:  * collects data till a delim, passes it to ip_input().
        !             4:  */
        !             5: 
        !             6: #include "sys/param.h"
        !             7: #include "sys/stream.h"
        !             8: #include "sys/conf.h"
        !             9: #include "sys/inet/in.h"
        !            10: #include "sys/inet/ip_var.h"
        !            11: #include "sys/inet/ethernet.h"
        !            12: 
        !            13: extern struct ipif ipif[];
        !            14: extern struct ipif *ipifsort[];
        !            15: extern int ipcnt;                      /* number of ip's */
        !            16: extern int arpcnt;
        !            17: 
        !            18: int     ipiput(), ipisrv(), ipclose();
        !            19: long   ipopen();
        !            20: int    iposrv();
        !            21: static struct qinit iprinit = { ipiput, ipisrv, ipopen, ipclose, IP_MSG_LIMIT, 64};
        !            22: static struct qinit ipwinit = { putq, iposrv, ipopen, ipclose, 2*IP_MSG_LIMIT, 64 };
        !            23: struct streamtab ipstream = { &iprinit, &ipwinit };
        !            24: 
        !            25: long
        !            26: ipopen(q, dev)
        !            27: register struct queue *q;
        !            28: {
        !            29:        static int timing;
        !            30:        register struct ipif *fp, *ifend;
        !            31: 
        !            32:        if (q->ptr)
        !            33:                return(1);
        !            34:        if(!timing){
        !            35:                timing = 1;
        !            36:                ip_slowtimo();
        !            37:        }
        !            38:        ifend = &ipif[ipcnt];
        !            39:        for (fp = ipif; fp < ifend; fp++)
        !            40:                if (fp->queue == NULL)
        !            41:                        break;
        !            42:        if (fp >= ifend)
        !            43:                return(0);
        !            44:        fp->queue = q;  /* that's the RD q */
        !            45:        fp->flags = IFF_UP;
        !            46:        fp->that = fp->thishost = 0;
        !            47:        fp->ipackets = fp->opackets = fp->ierrors = fp->oerrors = 0;
        !            48:        fp->mtu = 1500;
        !            49:        fp->arp = -1;
        !            50:        fp->dev = dev;
        !            51:        q->flag |= QDELIM;
        !            52:        WR(q)->flag |= QDELIM;
        !            53:        q->ptr = (caddr_t)fp;
        !            54:        WR(q)->ptr = (caddr_t)fp;
        !            55:        q->flag |= QNOENB;      /* ipiput calls qenable() */
        !            56:        return(1);
        !            57: }
        !            58: 
        !            59: ipclose(q)
        !            60: struct queue *q;
        !            61: {
        !            62:        register struct ipif *ifp;
        !            63: 
        !            64:        ifp = (struct ipif *)q->ptr;
        !            65:        ip_ifremove(ifp);
        !            66:        ifp->queue = 0;
        !            67:        ifp->flags = 0;
        !            68: }
        !            69: 
        !            70: ipisrv(q)
        !            71: register struct queue *q;
        !            72: {
        !            73:        register struct block *bp, *head, *tail;
        !            74:        register struct ipif *ifp;
        !            75: 
        !            76:        /* there is now a whole packet waiting
        !            77:         * on this queue; strip it off and pass to ip_input().
        !            78:         * things other than data or delims are forwarded directly
        !            79:         * by ipiput().
        !            80:         */
        !            81:        head = tail = (struct block *) 0;
        !            82:        ifp = (struct ipif *)q->ptr;
        !            83:        while(bp = getq(q)){
        !            84:                if (bp->type != M_DATA)
        !            85:                        panic("ipisrv");
        !            86:                bp->next = NULL;
        !            87:                if (head == NULL)
        !            88:                        head = bp;
        !            89:                else
        !            90:                        tail->next = bp;
        !            91:                tail = bp;
        !            92:                if (bp->class&S_DELIM) {
        !            93:                        bp->class &=~ S_DELIM;
        !            94:                        MCHECK(head);
        !            95:                        if((ifp->flags & IFF_ARP)
        !            96:                           && (head->wptr-head->rptr) >= sizeof(struct etherpup)){
        !            97:                                /* strip off ether header */
        !            98:                                head->rptr += sizeof(struct etherpup);
        !            99:                        }
        !           100:                        ip_input(head);
        !           101:                        ifp->ipackets++;
        !           102:                        head = tail = NULL;
        !           103:                }
        !           104:        }
        !           105:        if(head)
        !           106:                bp_putback(q, head);
        !           107: }
        !           108: 
        !           109: 
        !           110: ipiput(q, bp)
        !           111: register struct queue *q;
        !           112: register struct block *bp;
        !           113: {
        !           114:        switch(bp->type){
        !           115:        case M_DATA:
        !           116:                putq(q, bp);
        !           117:                if (bp->class&S_DELIM)
        !           118:                        qenable(q);
        !           119:                break;
        !           120:        default:
        !           121:                (*q->next->qinfo->putp)(q->next, bp);
        !           122:                break;
        !           123:        }
        !           124:                
        !           125: }
        !           126: 
        !           127: 
        !           128: /*
        !           129:  *  set our many broadcast addresses
        !           130:  */
        !           131: static
        !           132: setbcast(ifp)
        !           133:        struct ipif *ifp;
        !           134: {
        !           135:        int i;
        !           136: 
        !           137:        /* official style */
        !           138:        ifp->bcast[0] = ifp->that|~ifp->mask;                   /* subnet */
        !           139:        ifp->bcast[1] = ifp->that|~IN_CLASS_NMASK(ifp->that);   /* net */
        !           140:        ifp->bcast[2] = 0xffffffff;                             /* undirected */
        !           141: 
        !           142:        /* old BSD style */
        !           143:        ifp->bcast[3] = ifp->that&ifp->mask;                    /* subnet */
        !           144:        ifp->bcast[4] = ifp->that&IN_CLASS_NMASK(ifp->that);    /* net */
        !           145:        ifp->bcast[5] = 0;                                      /* undirected */
        !           146: 
        !           147:        if(ifp->flags & IFF_HOST)
        !           148:                for(i = 0; i < 6; i++)
        !           149:                        ifp->bcast[i] = 0;
        !           150: }
        !           151: 
        !           152: iposrv(q)
        !           153: register struct queue *q;
        !           154: {
        !           155:        struct x{
        !           156:                unsigned int in;
        !           157:                unsigned char en[6];
        !           158:        } *xp;
        !           159:        register struct block *bp;
        !           160:        register struct ipif *ifp;
        !           161:        register long *intp;
        !           162: 
        !           163:        ifp = (struct ipif *)q->ptr;
        !           164:        while(bp = getq(q)){
        !           165:                switch (bp->type) {
        !           166:                case M_IOCTL:
        !           167:                        switch(stiocom(bp)){
        !           168:                        case IPIOARP:
        !           169:                                ifp->flags |= IFF_ARP;
        !           170:                                bp->type = M_IOCACK;
        !           171:                                bp->wptr = bp->rptr;
        !           172:                                qreply(q, bp);
        !           173:                                break;
        !           174:                        case IPIORESOLVE:
        !           175:                                xp = (struct x *)(stiodata(bp));
        !           176:                                if (arpcnt > 0)
        !           177:                                        arp_install(xp->in, xp->en);
        !           178:                                bp->wptr = bp->rptr;
        !           179:                                bp->type = M_IOCACK;
        !           180:                                qreply(q, bp);
        !           181:                                break;
        !           182:                        case IPIOHOST:
        !           183:                                intp = (long *)(stiodata(bp));
        !           184:                                ifp->that = *intp;
        !           185:                                ifp->flags |= IFF_HOST;
        !           186:                                ifp->mask = 0xffffffff;
        !           187:                                setbcast(ifp);
        !           188:                                ip_ifinsert(ifp);
        !           189:                                bp->type = M_IOCACK;
        !           190:                                qreply(q, bp);
        !           191:                                ip_doroute(ifp->that, 0);
        !           192:                                break;
        !           193:                        case IPIOMTU:
        !           194:                                intp = (long *)(stiodata(bp));
        !           195:                                ifp->mtu = *intp;
        !           196:                                bp->type = M_IOCACK;
        !           197:                                qreply(q, bp);
        !           198:                                break;
        !           199:                        case IPIONET:
        !           200:                                intp = (long *)(stiodata(bp));
        !           201:                                ifp->that = *intp;
        !           202:                                ifp->mask = IN_CLASS_NMASK(ifp->that);
        !           203:                                setbcast(ifp);
        !           204:                                ip_ifinsert(ifp);
        !           205:                                ifp->flags &= (~IFF_HOST);
        !           206:                                bp->type = M_IOCACK;
        !           207:                                qreply(q, bp);
        !           208:                                ip_doroute(ifp->that, 0);
        !           209:                                break;
        !           210:                        case IPIOMASK:
        !           211:                                intp = (long *)(stiodata(bp));
        !           212:                                /*
        !           213:                                 *  the mask has to be a superset of the class mask
        !           214:                                 */
        !           215:                                if((*intp&ifp->mask)==ifp->mask)
        !           216:                                        ifp->mask = *intp;
        !           217:                                setbcast(ifp);
        !           218:                                ip_ifinsert(ifp);
        !           219:                                bp->type = M_IOCACK;
        !           220:                                qreply(q, bp);
        !           221:                                break;
        !           222:                        case IPIOLOCAL:
        !           223:                                intp = (long *)(stiodata(bp));
        !           224:                                ifp->thishost = *intp;
        !           225:                                setbcast(ifp);
        !           226:                                bp->type = M_IOCACK;
        !           227:                                qreply(q, bp);
        !           228:                                break;
        !           229:                        default:
        !           230:                                (*q->next->qinfo->putp)(q->next, bp);
        !           231:                                break;
        !           232:                        }
        !           233:                        continue;
        !           234: 
        !           235:                default:
        !           236:                        if (q->next->flag & QFULL) {
        !           237:                                putbq(q, bp);
        !           238:                                return;
        !           239:                        }
        !           240:                        if(bp->class&S_DELIM)
        !           241:                                ifp->opackets++;
        !           242:                        (*q->next->qinfo->putp)(q->next, bp);
        !           243:                        continue;
        !           244:                }
        !           245:        }
        !           246: }
        !           247: 
        !           248: /*
        !           249:  *  Insert an entry into ipifsort.  Entries are sorted by mask length,
        !           250:  *  longest first.
        !           251:  */
        !           252: ip_ifinsert(ifp)
        !           253:        struct ipif *ifp;
        !           254: {
        !           255:        int s = spl6();
        !           256:        register int i, j;
        !           257: 
        !           258:        /*
        !           259:         *  First try to remove it.  This may be a reordering.
        !           260:         */
        !           261:        ip_ifremove(ifp);
        !           262: 
        !           263:        /*
        !           264:         *  Now (re)insert it in the correct place
        !           265:         */
        !           266:        for(i=0; i<ipcnt; i++){
        !           267:                if(ipifsort[i]==ifp)
        !           268:                        panic("ip_ifinsert duplcate");
        !           269:                if(ipifsort[i]==0 || (ifp->mask & ipifsort[i]->mask)!=ifp->mask)
        !           270:                        break;
        !           271:        }
        !           272:        if(i>=ipcnt)
        !           273:                panic("ip_ifinsert no room");
        !           274:        for(j=ipcnt-1; j>i; j--)
        !           275:                ipifsort[j] = ipifsort[j-1];
        !           276:        ipifsort[i] = ifp;
        !           277:        splx(s);
        !           278: }
        !           279: 
        !           280: /*
        !           281:  *  Remove an entry from ipifsort.  Compress list to fill gap.
        !           282:  *  It may not already be there.
        !           283:  */
        !           284: ip_ifremove(ifp)
        !           285:        struct ipif *ifp;
        !           286: {
        !           287:        int s = spl6();
        !           288:        register int i;
        !           289: 
        !           290:        for(i=0; i<ipcnt; i++)
        !           291:                if(ipifsort[i]==ifp)
        !           292:                        break;
        !           293:        if(i<ipcnt){
        !           294:                for(; i<ipcnt-1; i++)
        !           295:                        ipifsort[i] = ipifsort[i+1];
        !           296:                ipifsort[i] = 0;
        !           297:        }
        !           298:        splx(s);
        !           299: }
        !           300: 
        !           301: /*
        !           302:  *  Find the interface to use for sending messages to `dst'.
        !           303:  *  ipifsort is sorted into priority order;
        !           304:  *  first match found is best.
        !           305:  */
        !           306: struct ipif *
        !           307: ip_ifonnetof(dst)
        !           308:        register unsigned long dst;
        !           309: {
        !           310:        extern ipprintfs;
        !           311:        register struct ipif *ifp;
        !           312:        register int i;
        !           313:        register int Ipcnt = ipcnt;     /* optimization */
        !           314: 
        !           315:        /*
        !           316:         *  first look for a match against addresses
        !           317:         */
        !           318:        for(i=0; i < Ipcnt; i++){
        !           319:                if((ifp = ipifsort[i])==0)
        !           320:                        break;
        !           321:                if(ifp->flags & IFF_UP)
        !           322:                        if((dst & ifp->mask) == ifp->that)
        !           323:                                return(ifp);
        !           324:        }
        !           325: 
        !           326:        /*
        !           327:         *  now try to match against the local host's addresses
        !           328:         */
        !           329:        ifp = ip_ifwithaddr(dst);
        !           330:        if(ifp)
        !           331:                return(ifp);
        !           332: 
        !           333:        /*
        !           334:         *  no match
        !           335:         */
        !           336:        if(ipprintfs)
        !           337:                printf("ifonnetof %x?\n", dst);
        !           338:        return(0);
        !           339: }
        !           340: 
        !           341: /*
        !           342:  *  return the interface for which addr is a local address.  if non
        !           343:  *  such exists, return 0.
        !           344:  *
        !           345:  *  This routine assumes that ipifsort is sorted in priority order
        !           346:  *  so that the first match found is the best match.
        !           347:  */
        !           348: struct ipif *
        !           349: ip_ifwithaddr(addr)
        !           350:        register u_long addr;
        !           351: {
        !           352:        register int i, j;
        !           353:        register u_long net, mask;
        !           354:        register struct ipif *ifp;
        !           355:        register int Ipcnt = ipcnt;     /* optimization */
        !           356: 
        !           357:        net = in_netof(addr);
        !           358:        for(i=0; i < Ipcnt; i++){
        !           359:                if((ifp = ipifsort[i])==0)
        !           360:                        break;
        !           361:                if(ifp->flags & IFF_UP) {
        !           362: 
        !           363:                        /* address of this host */
        !           364:                        if(addr == ifp->thishost)
        !           365:                                return(ifp);
        !           366: 
        !           367:                        for(j = 0; j < 6; j++)
        !           368:                                if(addr == ifp->bcast[j])
        !           369:                                        return(ifp);
        !           370: 
        !           371:                        /* address on a network simulated by this node */
        !           372:                        if(net == ifp->thishost)
        !           373:                                return(ifp);
        !           374:                }
        !           375:        }
        !           376:        return(0);
        !           377: }
        !           378: 
        !           379: /*
        !           380:  * output list bp onto interface ifp
        !           381:  * for better buffering, put it on ip's queue first;
        !           382:  * iposrv will dribble it out as there's room
        !           383:  */
        !           384: ip_ldout(bp, dst, ifp)
        !           385: register struct block *bp;
        !           386: unsigned long dst;             /* host byte order */
        !           387: register struct ipif *ifp;
        !           388: {
        !           389:        extern struct block *arp_resolve();
        !           390:        register struct block *bp1;
        !           391:        register struct queue *q;
        !           392: 
        !           393:        if(ifp->queue == 0){
        !           394:                printf("ifp but no queue in ip_ldout\n");
        !           395:                bp_free(bp);
        !           396:                return(0);
        !           397:        }
        !           398:        q = WR(ifp->queue);
        !           399:        if(q->flag & QFULL){
        !           400:                bp_free(bp);
        !           401:                ifp->oerrors++;
        !           402:                return(1);
        !           403:        }
        !           404:        if(arpcnt > 0 && (ifp->flags & IFF_ARP)){
        !           405:                bp = arp_resolve(ifp->queue, bp, dst);
        !           406:                if(bp == 0)
        !           407:                        return(1);
        !           408:        }
        !           409:        MCHECK(bp);
        !           410:        while(bp){
        !           411:                bp1 = bp->next;
        !           412:                if (bp1==NULL)
        !           413:                        bp->class |= S_DELIM;
        !           414:                (*q->qinfo->putp)(q, bp);
        !           415:                bp = bp1;
        !           416:        }
        !           417:        return(0);
        !           418: }

unix.superglobalmegacorp.com

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