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