Annotation of researchv9/sys/inet/ip_ld.c, revision 1.1.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 "inet.h"
                      7: #include "arp.h"
                      8: #include "uarp.h"
                      9: #include "../h/param.h"
                     10: #include "../h/systm.h"
                     11: #include "../h/stream.h"
                     12: #include "../h/ioctl.h"
                     13: #include "../h/ttyld.h"
                     14: #include "../h/map.h"
                     15: #include "../h/buf.h"
                     16: /*#include "../h/ubavar.h"*/
                     17: #include "../h/conf.h"
                     18: #include "../h/inet/in.h"
                     19: #include "../h/inet/ip_var.h"
                     20: #include "../h/inet/mbuf.h"
                     21: #include "../h/ethernet.h"
                     22: 
                     23: struct ipif ipif[NINET];
                     24: int Ninet = NINET;             /* let netstat find the number of interfaces */
                     25: 
                     26: int    ipopen(), ipiput(), ipisrv(), ipclose();
                     27: int    iposrv();
                     28: static struct qinit iprinit = { ipiput, ipisrv, ipopen, ipclose, IP_MSG_LIMIT, 64};
                     29: static struct qinit ipwinit = { putq, iposrv, ipopen, ipclose, 1024, 64 };
                     30: struct streamtab ipinfo = { &iprinit, &ipwinit };
                     31: 
                     32: ipopen(q, dev)
                     33: register struct queue *q;
                     34: {
                     35:        static int timing;
                     36:        register i;
                     37:        register struct ipif *fp;
                     38: 
                     39:        if (q->ptr)
                     40:                return(1);
                     41:        if(!timing){
                     42:                timing = 1;
                     43:                ip_slowtimo();
                     44:        }
                     45:        for (i=0; ipif[i].queue!=0 && i<NINET; i++)
                     46:                ;
                     47:        if (i >= NINET)
                     48:                return(0);
                     49:        fp = &ipif[i];
                     50:        fp->queue = q;  /* that's the RD q */
                     51:        fp->flags = IFF_UP;
                     52:        fp->that = fp->thishost = 0;
                     53:        fp->ipackets = fp->opackets = fp->ierrors = fp->oerrors = 0;
                     54:        fp->mtu = 1500;
                     55:        fp->arp = -1;
                     56:        fp->dev = dev;
                     57:        q->flag |= QDELIM;
                     58:        WR(q)->flag |= QDELIM;
                     59:        q->ptr = (caddr_t)fp;
                     60:        WR(q)->ptr = (caddr_t)fp;
                     61:        q->flag |= QNOENB;      /* ipiput calls qenable() */
                     62:        return(1);
                     63: }
                     64: 
                     65: ipclose(q)
                     66: register struct queue *q;
                     67: {
                     68:        register struct ipif *ifp;
                     69: 
                     70:        ifp = (struct ipif *)q->ptr;
                     71: #if NARP > 0
                     72:        if (ifp->arp >= 0)
                     73:                arp_disable(ifp->arp);
                     74: #endif
                     75:        ifp->queue = 0;
                     76:        ifp->flags = 0;
                     77: }
                     78: 
                     79: ipisrv(q)
                     80: register struct queue *q;
                     81: {
                     82:        register struct block *bp, *head, *tail;
                     83:        register struct ipif *ifp;
                     84: 
                     85:        /* there is now a whole packet waiting
                     86:         * on this queue; strip it off and pass to ip_input().
                     87:         * things other than data or delims are forwarded directly
                     88:         * by ipiput().
                     89:         */
                     90:        head = tail = (struct block *) 0;
                     91:        ifp = (struct ipif *)q->ptr;
                     92:        while(bp = getq(q)){
                     93:                if(bp->type == M_DELIM){
                     94:                        freeb(bp);
                     95:                        if(head){
                     96:                                MCHECK(head);
                     97:                                if((ifp->flags & IFF_ARP)
                     98:                                   && (head->wptr - head->rptr) >= sizeof(struct etherpup)){
                     99:                                        /* blow away ether header */
                    100:                                        head->rptr += sizeof(struct etherpup);
                    101:                                }
                    102:                                ip_input(head);
                    103:                                ifp->ipackets++;
                    104:                        } else {
                    105:                                printf("ipisrv: no data\n");
                    106:                                ifp->ierrors++;
                    107:                        }
                    108:                        head = tail = (struct block *) 0;
                    109:                } else if(bp->type == M_DATA){
                    110:                        bp->next = (struct block *) 0;
                    111:                        if(head == (struct block *) 0){
                    112:                                head = bp;
                    113:                        } else {
                    114:                                tail->next = bp;
                    115:                        }
                    116:                        tail = bp;
                    117:                } else {
                    118:                        printf("ipisrv: weird type %d\n", bp->type);
                    119:                        (*q->next->qinfo->putp)(q->next, bp);
                    120:                }       
                    121:        }
                    122:        if(head)
                    123:                bp_putback(q, head);
                    124: }
                    125: 
                    126: 
                    127: ipiput(q, bp)
                    128: register struct queue *q;
                    129: register struct block *bp;
                    130: {
                    131:        switch(bp->type){
                    132:        case M_DATA:
                    133:                putq(q, bp);    /* putq does compression into blocks */
                    134:                break;
                    135:        case M_DELIM:
                    136:                putq(q, bp);
                    137:                qenable(q);
                    138:                break;
                    139:        default:
                    140:                (*q->next->qinfo->putp)(q->next, bp);
                    141:                break;
                    142:        }
                    143:                
                    144: }
                    145: 
                    146: iposrv(q)
                    147: register struct queue *q;
                    148: {
                    149:        struct x{
                    150:                unsigned int in;
                    151:                unsigned char en[6];
                    152:        } *xp;
                    153:        register union stmsg *sp;
                    154:        register struct block *bp;
                    155:        register struct ipif *ifp;
                    156:        register int *intp;
                    157: 
                    158:        ifp = (struct ipif *)q->ptr;
                    159:        while(bp = getq(q)){
                    160:                if(bp->type == M_IOCTL){
                    161:                        sp = (union stmsg *)bp->rptr;
                    162:                        switch(sp->ioc0.com){
                    163:                        case IPIOARP:
                    164: #if NARP > 0
                    165:                                if (ifp->arp >= 0)
                    166:                                        printf("IP: already arping\n");
                    167:                                else {
                    168:                                        ifp->arp = arp_enable(ifp->dev,
                    169:                                                        ETHERPUP_IPTYPE,
                    170:                                                        sizeof(u_long), 1,
                    171:                                                        &ifp->thishost);
                    172:                                        if (ifp->arp == -1) {
                    173:                                                bp->type = M_IOCNAK;
                    174:                                                qreply(q, bp);
                    175:                                                break;
                    176:                                        }
                    177:                                }
                    178: #endif
                    179:                                ifp->flags |= IFF_ARP;
                    180:                                bp->type = M_IOCACK;
                    181:                                bp->wptr = bp->rptr;
                    182:                                qreply(q, bp);
                    183:                                break;
                    184:                        case IPIORESOLVE:
                    185:                                xp = (struct x *)(sp->iocx.xxx);
                    186: #if NUARP > 0
                    187:                                arp_install(xp->in, xp->en);
                    188: #endif
                    189:                                bp->wptr = bp->rptr;
                    190:                                bp->type = M_IOCACK;
                    191:                                qreply(q, bp);
                    192:                                break;
                    193:                        case IPIOHOST:
                    194:                                intp = (int *)(sp->iocx.xxx);
                    195:                                ifp->that = *intp;
                    196:                                ifp->flags |= IFF_HOST;
                    197:                                bp->type = M_IOCACK;
                    198:                                qreply(q, bp);
                    199:                                ip_doroute(ifp->that, 0);
                    200:                                break;
                    201:                        case IPIOMTU:
                    202:                                intp = (int *)(sp->iocx.xxx);
                    203:                                ifp->that = *intp;
                    204:                                ifp->mtu = *intp;
                    205:                                bp->type = M_IOCACK;
                    206:                                qreply(q, bp);
                    207:                                break;
                    208:                        case IPIONET:
                    209:                                intp = (long *)(sp->iocx.xxx);
                    210:                                ifp->that = *intp;
                    211:                                ifp->mask = 0;
                    212:                                ifp->flags &= (~IFF_HOST);
                    213:                                bp->type = M_IOCACK;
                    214:                                qreply(q, bp);
                    215:                                ip_doroute(ifp->that, 0);
                    216:                                break;
                    217:                        case IPIOMASK:
                    218:                                intp = (long *)(sp->iocx.xxx);
                    219:                                ifp->mask = *intp;
                    220:                                bp->type = M_IOCACK;
                    221:                                qreply(q, bp);
                    222:                                ip_doroute(ifp->that, 0);
                    223:                                break;
                    224:                        case IPIOLOCAL:
                    225:                                intp = (int *)(sp->iocx.xxx);
                    226:                                ifp->thishost = *intp;
                    227:                                bp->type = M_IOCACK;
                    228:                                qreply(q, bp);
                    229:                                break;
                    230:                        default:
                    231:                                (*q->next->qinfo->putp)(q->next, bp);
                    232:                                break;
                    233:                        }
                    234:                } else {
                    235:                        (*q->next->qinfo->putp)(q->next, bp);
                    236:                        if(bp->type == M_DELIM)
                    237:                                ifp->opackets++;
                    238:                }
                    239:        }
                    240: }
                    241: 
                    242: struct ipif *
                    243: ip_ifonnetof(dst)
                    244: unsigned long dst;
                    245: {
                    246:        extern ipprintfs;
                    247:        struct ipif *ifp;
                    248: 
                    249:        /* point-to-point links first */
                    250:        for(ifp = &ipif[0]; ifp < &ipif[NINET]; ifp++){
                    251:                if((ifp->flags & IFF_UP) && (ifp->flags & IFF_HOST)){
                    252:                        if(dst == ifp->that)
                    253:                                return(ifp);
                    254:                }
                    255:        }
                    256:        /* now normal nets */
                    257:        for(ifp = &ipif[0]; ifp < &ipif[NINET]; ifp++){
                    258:                if((ifp->flags & (IFF_UP|IFF_HOST)) == IFF_UP){
                    259:                        if(in_netof(dst) == ifp->that)
                    260:                                return(ifp);
                    261:                }
                    262:        }
                    263:        if(ipprintfs)
                    264:                printf("ifonnetof %x?\n", dst);
                    265:        return(0);
                    266: }
                    267: 
                    268: struct ipif *
                    269: ip_ifwithaddr(addr)
                    270: unsigned long addr;
                    271: {
                    272:        struct ipif *ifp;
                    273:        unsigned long net;
                    274: 
                    275:        net = in_netof(addr);
                    276:        for(ifp = &ipif[0]; ifp < &ipif[NINET]; ifp++){
                    277:                if(ifp->flags & IFF_UP){
                    278:                        /* address of this host */
                    279:                        if(addr == ifp->thishost)
                    280:                                return(ifp);
                    281:                        /* address of this host's network */
                    282:                        if(addr == in_netof(ifp->thishost))
                    283:                                return(ifp);
                    284:                        /* address on a network simulated by this node */
                    285:                        if(net == ifp->thishost)
                    286:                                return(ifp);
                    287:                }
                    288:        }
                    289:        return(0);
                    290: }
                    291: 
                    292: ip_ldout(bp, dst, ifp)
                    293: register struct block *bp;
                    294: unsigned long dst;             /* host byte order */
                    295: register struct ipif *ifp;
                    296: {
                    297: #if NARP > 0 || NUARP > 0
                    298:        extern struct block *arp_resolve();
                    299: #endif
                    300:        register struct block *bp1;
                    301:        register struct queue *q;
                    302: 
                    303:        if(ifp->queue == 0){
                    304:                printf("ifp but no queue in ip_ldout\n");
                    305:                bp_free(bp);
                    306:                return(0);
                    307:        }
                    308:        q = WR(ifp->queue);
                    309:        if(q->next->flag & QFULL){
                    310:                bp_free(bp);
                    311:                ifp->oerrors++;
                    312:                return(1);
                    313:        }
                    314: #if NARP > 0
                    315:        if(ifp->flags & IFF_ARP){
                    316:                bp = arp_resolve(ifp->arp, bp, &dst);
                    317:                if(bp == 0)
                    318:                        return(1);
                    319:        }
                    320: #endif
                    321: #if NUARP > 0
                    322:        if(ifp->flags & IFF_ARP){
                    323:                bp = arp_resolve(ifp->queue, bp, dst);
                    324:                if(bp == 0)
                    325:                        return(1);
                    326:        }
                    327: #endif
                    328:        MCHECK(bp);
                    329:        while(bp){
                    330:                bp1 = bp->next;
                    331:                (*q->next->qinfo->putp)(q->next, bp);
                    332:                bp = bp1;
                    333:        }
                    334:        bp1 = allocb(0);
                    335:        if(bp1){
                    336:                bp1->type = M_DELIM;
                    337:                (*q->next->qinfo->putp)(q->next, bp1);
                    338:                ifp->opackets++;
                    339:        } else {
                    340:                printf("ip_ldout: no allocb for delim\n");
                    341:                ifp->oerrors++;
                    342:        }
                    343:        return(0);
                    344: }

unix.superglobalmegacorp.com

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