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