|
|
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 "inet.h" ! 7: #include "uarp.h" ! 8: #if NINET ! 9: #include "../h/param.h" ! 10: #include "../h/systm.h" ! 11: #include "../h/stream.h" ! 12: #include "../h/ioctl.h" ! 13: #include "../h/buf.h" ! 14: #include "../h/conf.h" ! 15: #include "../h/inet/in.h" ! 16: #include "../h/inet/ip_var.h" ! 17: #include "../h/ttyld.h" ! 18: ! 19: int nodev(), ipdopen(), ipdclose(), ipdput(), ipdosrv(); ! 20: static struct qinit ipdrinit = { nodev, NULL, ipdopen, ipdclose, 0, 0 }; ! 21: struct qinit ipdwinit = { ipdput, ipdosrv, ipdopen, ipdclose, ! 22: IP_BODY_LIMIT, 129 }; ! 23: struct streamtab ipdinfo = { &ipdrinit, &ipdwinit }; ! 24: ! 25: struct queue *ipdstate[256]; ! 26: int ipprintfs; ! 27: ! 28: ipdopen(q, dev) ! 29: register struct queue *q; ! 30: dev_t dev; ! 31: { ! 32: dev = minor(dev); ! 33: ! 34: if(ipdstate[dev]){ ! 35: return(0); ! 36: } ! 37: ipdstate[dev] = q; ! 38: q->ptr = (caddr_t)dev; ! 39: q->flag |= QDELIM; ! 40: WR(q)->ptr = (caddr_t)dev; ! 41: WR(q)->flag |= QNOENB; ! 42: return(1); ! 43: } ! 44: ! 45: ipdclose(q) ! 46: register struct queue *q; ! 47: { ! 48: int dev; ! 49: ! 50: dev = (int)q->ptr; ! 51: ipdstate[dev] = 0; ! 52: } ! 53: ! 54: ipdput(q, bp) ! 55: register struct queue *q; ! 56: register struct block *bp; ! 57: { ! 58: union stmsg *sp; ! 59: struct foo{ ! 60: u_long dst; ! 61: u_long gate; ! 62: } foo; ! 63: int i; ! 64: struct block *bp1; ! 65: ! 66: switch(bp->type){ ! 67: case M_IOCTL: ! 68: sp = (union stmsg *)(bp->rptr); ! 69: bp->type = M_IOCACK; ! 70: switch(sp->ioc0.com){ ! 71: case IPIOROUTE: ! 72: bcopy(sp->iocx.xxx, &foo, sizeof(struct foo)); ! 73: if(ip_doroute(foo.dst, foo.gate)) ! 74: bp->type = M_IOCNAK; ! 75: break; ! 76: case IPIOGETIFS: ! 77: i = *(int *)(sp->iocx.xxx); ! 78: if(i>=NINET) { ! 79: bp->type = M_IOCNAK; ! 80: break; ! 81: } ! 82: bp1 = allocb(64); ! 83: if (bp1 == 0) { ! 84: bp->type = M_IOCNAK; ! 85: break; ! 86: } ! 87: freeb(bp); ! 88: bp = bp1; ! 89: bp->type = M_IOCACK; ! 90: sp = (struct stmsg *)(bp->rptr); ! 91: bp->wptr = (u_char *)sp->iocx.xxx; ! 92: *(struct ipif *)(bp->wptr) = ipif[i]; ! 93: bp->wptr += sizeof(struct ipif); ! 94: break; ! 95: default: ! 96: bp->type = M_IOCNAK; ! 97: break; ! 98: } ! 99: qreply(q, bp); ! 100: return; ! 101: case M_DATA: ! 102: putq(q, bp); ! 103: break; ! 104: case M_DELIM: ! 105: putq(q, bp); ! 106: qenable(q); ! 107: break; ! 108: default: ! 109: freeb(bp); ! 110: break; ! 111: } ! 112: } ! 113: ! 114: ipdrint(bp, dev) ! 115: register struct block *bp; ! 116: unsigned dev; ! 117: { ! 118: register struct block *bp1; ! 119: register struct queue *q; ! 120: ! 121: q = ipdstate[dev]; ! 122: if(q){ ! 123: if(q->next->flag&QFULL){ ! 124: bp_free(bp); ! 125: if(ipprintfs) ! 126: printf("ipdrint: QFULL\n"); ! 127: ipstat.ips_qfull++; ! 128: return; ! 129: } ! 130: while(bp){ ! 131: bp1 = bp->next; ! 132: (*q->next->qinfo->putp)(q->next, bp); ! 133: bp = bp1; ! 134: } ! 135: bp = allocb(0); ! 136: if(bp){ ! 137: bp->type = M_DELIM; ! 138: (*q->next->qinfo->putp)(q->next, bp); ! 139: } else { ! 140: printf("ipdrint: no allocb for DELIM\n"); ! 141: } ! 142: } else { ! 143: bp_free(bp); ! 144: } ! 145: } ! 146: ! 147: ipdosrv(q) ! 148: register struct queue *q; ! 149: { ! 150: register struct block *bp, *tail, *head; ! 151: ! 152: head = tail = 0; ! 153: while(bp = getq(q)){ ! 154: bp->next = 0; ! 155: if(bp->type != M_DATA){ ! 156: freeb(bp); ! 157: if(head) ! 158: ip_output(head, 0, 0); ! 159: else ! 160: printf("osrv, DELIM & no DATA\n"); ! 161: head = tail = 0; ! 162: } else if(head == 0){ ! 163: head = tail = bp; ! 164: } else { ! 165: tail->next = bp; ! 166: tail = bp; ! 167: } ! 168: } ! 169: if (head) ! 170: bp_putback(q, head); ! 171: } ! 172: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.