|
|
1.1 ! root 1: /* ! 2: * udp line discipline; only one, to be pushed on /dev/ip17. ! 3: */ ! 4: ! 5: #include "sys/param.h" ! 6: #include "sys/stream.h" ! 7: #include "sys/conf.h" ! 8: ! 9: #include "sys/inet/in.h" ! 10: #include "sys/inet/ip.h" ! 11: #include "sys/inet/ip_var.h" ! 12: #include "sys/inet/udp.h" ! 13: #include "sys/inet/udp_var.h" ! 14: ! 15: struct queue *udpqueue; ! 16: ! 17: int udpiput(), udpisrv(), udpclose(); ! 18: long udpopen(); ! 19: int udposrv(), udpoput(); ! 20: static struct qinit udprinit = { udpiput, udpisrv, udpopen, udpclose, ! 21: 4*UDP_MSG_LIMIT, 512 }; ! 22: static struct qinit udpwinit = { putq, udposrv, udpopen, udpclose, ! 23: UDP_MSG_LIMIT, 64 }; ! 24: struct streamtab udpstream = { &udprinit, &udpwinit }; ! 25: ! 26: long ! 27: udpopen(q, dev) ! 28: register struct queue *q; ! 29: { ! 30: if (q->ptr) ! 31: return(0); ! 32: udpqueue = q; /* RD queue */ ! 33: q->flag |= QDELIM; ! 34: WR(q)->flag |= QDELIM; ! 35: q->ptr = (caddr_t)1; ! 36: WR(q)->ptr = (caddr_t)1; ! 37: q->flag |= QNOENB; /* ipiput calls qenable() */ ! 38: return(1); ! 39: } ! 40: ! 41: udpclose(q) ! 42: register struct queue *q; ! 43: { ! 44: if(udpqueue == q) ! 45: udpqueue = 0; ! 46: } ! 47: ! 48: udpisrv(q) ! 49: register struct queue *q; ! 50: { ! 51: register struct block *bp, *head, *tail; ! 52: ! 53: head = tail = NULL; ! 54: while(bp = getq(q)){ ! 55: if (bp->type != M_DATA) ! 56: panic("udpisrv"); ! 57: bp->next = NULL; ! 58: if (head == NULL) ! 59: head = bp; ! 60: else ! 61: tail->next = bp; ! 62: tail = bp; ! 63: if (bp->class&S_DELIM) { ! 64: bp->class &=~ S_DELIM; ! 65: MCHECK(head); ! 66: udp_input(head); ! 67: head = tail = NULL; ! 68: } ! 69: } ! 70: if (head) ! 71: bp_putback(q, head); ! 72: } ! 73: ! 74: ! 75: udpiput(q, bp) ! 76: register struct queue *q; ! 77: register struct block *bp; ! 78: { ! 79: switch(bp->type){ ! 80: case M_DATA: ! 81: putq(q, bp); ! 82: if (bp->class&S_DELIM) ! 83: qenable(q); ! 84: break; ! 85: default: ! 86: (*q->next->qinfo->putp)(q->next, bp); ! 87: break; ! 88: } ! 89: ! 90: } ! 91: ! 92: udposrv(q) ! 93: register struct queue *q; ! 94: { ! 95: register struct block *bp; ! 96: ! 97: while(bp = getq(q)){ ! 98: if (q->next->flag & QFULL) { ! 99: putbq(q, bp); ! 100: break; ! 101: } ! 102: (*q->next->qinfo->putp)(q->next, bp); ! 103: } ! 104: } ! 105: ! 106: udp_ldout(bp) ! 107: register struct block *bp; ! 108: { ! 109: register struct block *bp1; ! 110: register struct queue *q; ! 111: ! 112: if(udpqueue == 0){ ! 113: bp_free(bp); ! 114: return; ! 115: } ! 116: q = WR(udpqueue); ! 117: if(q->next->flag&QFULL){ ! 118: printf("udp_ldout: QFULL\n"); ! 119: bp_free(bp); ! 120: return; ! 121: } ! 122: MCHECK(bp); ! 123: while(bp){ ! 124: bp1 = bp->next; ! 125: if (bp1==NULL) ! 126: bp->class |= S_DELIM; ! 127: (*q->next->qinfo->putp)(q->next, bp); ! 128: bp = bp1; ! 129: } ! 130: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.