|
|
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.