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