|
|
1.1 ! root 1: /* ! 2: * ip device driver; each minor device is one protocol. ! 3: * so tcp would be placed on top of ip minor device #6. ! 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: ! 12: extern int ipcnt; /* number of ip devices */ ! 13: long ipdopen(); ! 14: int ipdclose(), ipdput(), ipdosrv(); ! 15: static struct qinit ipdrinit = { noput, NULL, ipdopen, ipdclose, 0, 0 }; ! 16: struct qinit ipdwinit = { ipdput, ipdosrv, ipdopen, ipdclose, ! 17: IP_BODY_LIMIT, 129 }; ! 18: struct streamtab ipdinfo = { &ipdrinit, &ipdwinit }; ! 19: ! 20: struct cdevsw ipcdev = cstrinit(&ipdinfo); ! 21: ! 22: struct queue *ipdstate[256]; ! 23: int ipprintfs; ! 24: ! 25: long ! 26: ipdopen(q, dev) ! 27: register struct queue *q; ! 28: dev_t dev; ! 29: { ! 30: dev = minor(dev); ! 31: if(ipdstate[dev]) ! 32: return(0); ! 33: ipdstate[dev] = q; ! 34: q->ptr = (caddr_t)dev; ! 35: q->flag |= QDELIM; ! 36: WR(q)->ptr = (caddr_t)dev; ! 37: WR(q)->flag |= QNOENB; ! 38: return(1); ! 39: } ! 40: ! 41: ipdclose(q) ! 42: register struct queue *q; ! 43: { ! 44: ipdstate[(int)q->ptr] = 0; ! 45: } ! 46: ! 47: ipdput(q, bp) ! 48: register struct queue *q; ! 49: register struct block *bp; ! 50: { ! 51: struct foo{ ! 52: u_long dst; ! 53: u_long gate; ! 54: } foo; ! 55: int i; ! 56: struct block *bp1; ! 57: ! 58: switch(bp->type){ ! 59: case M_DATA: ! 60: putq(q, bp); ! 61: if (bp->class&S_DELIM) ! 62: qenable(q); ! 63: return; ! 64: ! 65: case M_IOCTL: ! 66: bp->type = M_IOCACK; ! 67: switch(stiocom(bp)){ ! 68: case IPIOROUTE: ! 69: bcopy(stiodata(bp), &foo, sizeof(struct foo)); ! 70: if(ip_doroute(foo.dst, foo.gate)) ! 71: bp->type = M_IOCNAK; ! 72: break; ! 73: case IPIOGETIFS: ! 74: i = *(int *)(stiodata(bp)); ! 75: if(i>=ipcnt) { ! 76: bp->type = M_IOCNAK; ! 77: break; ! 78: } ! 79: bp1 = allocb(sizeof(struct ipif)); ! 80: if (bp1 == 0) { ! 81: bp->type = M_IOCNAK; ! 82: break; ! 83: } ! 84: freeb(bp); ! 85: bp = bp1; ! 86: bp->type = M_IOCACK; ! 87: bp->wptr = (u_char *)stiodata(bp); ! 88: *(struct ipif *)(bp->wptr) = ipif[i]; ! 89: bp->wptr += sizeof(struct ipif); ! 90: break; ! 91: default: ! 92: bp->type = M_IOCNAK; ! 93: break; ! 94: } ! 95: qreply(q, bp); ! 96: return; ! 97: ! 98: default: ! 99: freeb(bp); ! 100: return; ! 101: } ! 102: } ! 103: ! 104: ipdrint(bp, dev) ! 105: register struct block *bp; ! 106: unsigned dev; ! 107: { ! 108: register struct block *bp1; ! 109: register struct queue *nq; ! 110: ! 111: if ((nq = ipdstate[dev]) == NULL) { ! 112: bp_free(bp); ! 113: return; ! 114: } ! 115: nq = nq->next; /* optimization */ ! 116: if(nq->flag&QFULL){ ! 117: bp_free(bp); ! 118: if(ipprintfs) ! 119: printf("ipdrint: QFULL\n"); ! 120: ipstat.ips_qfull++; ! 121: return; ! 122: } ! 123: while(bp){ ! 124: bp1 = bp->next; ! 125: if (bp1==NULL) ! 126: bp->class |= S_DELIM; ! 127: else ! 128: bp->class &=~ S_DELIM; ! 129: (*nq->qinfo->putp)(nq, bp); ! 130: bp = bp1; ! 131: } ! 132: } ! 133: ! 134: ipdosrv(q) ! 135: struct queue *q; ! 136: { ! 137: register struct block *bp, *tail, *head; ! 138: ! 139: head = tail = NULL; ! 140: while(bp = getq(q)){ ! 141: if (bp->type != M_DATA) ! 142: panic("ipdosrv"); ! 143: bp->next = NULL; ! 144: if (head == NULL) ! 145: head = bp; ! 146: else ! 147: tail->next = bp; ! 148: tail = bp; ! 149: if (bp->class&S_DELIM) { ! 150: ip_output(head, (struct block *)0, 0); ! 151: head = tail = NULL; ! 152: } ! 153: } ! 154: if (head) ! 155: bp_putback(q, head); ! 156: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.