|
|
1.1 root 1: #include "u.h"
2: #include "../port/lib.h"
3: #include "mem.h"
4: #include "dat.h"
5: #include "fns.h"
6: #include "../port/error.h"
7: #include "arp.h"
8: #include "../port/ipdat.h"
9:
10: #include "devtab.h"
11:
12: static Streamput icmpoput;
13: static Streamopen icmpstopen;
14: static Streamclose icmpstclose;
15: static void icmprcvmsg(Ipifc*, Block*);
16:
17: Qinfo icmpinfo = { 0, icmpoput, icmpstopen, icmpstclose, "icmp" };
18:
19: static struct {
20: QLock;
21: Queue *rq;
22: Ipifc *ifc;
23: } icmp;
24:
25: Ipifc *ipifc[];
26:
27: /*
28: * device interface
29: */
30: Dirtab icmptab[]={
31: "icmp", {Sdataqid}, 0, 0666,
32: };
33: #define Nicmptab (sizeof(icmptab)/sizeof(Dirtab))
34:
35: void
36: icmpreset(void)
37: {
38: }
39:
40: void
41: icmpinit(void)
42: {
43: Ipifc **p;
44:
45: /* add into protocol list */
46: for(p = ipifc; *p; p++)
47: ;
48: icmp.ifc = *p = xalloc(sizeof(Ipifc));
49: icmp.ifc->name = "icmp";
50: }
51:
52: Chan *
53: icmpattach(char *spec)
54: {
55: return devattach('Q', spec);
56: }
57:
58: Chan *
59: icmpclone(Chan *c, Chan *nc)
60: {
61: return devclone(c, nc);
62: }
63:
64: int
65: icmpwalk(Chan *c, char *name)
66: {
67: return devwalk(c, name, icmptab, (long)Nicmptab, devgen);
68: }
69:
70: void
71: icmpstat(Chan *c, char *db)
72: {
73: devstat(c, db, icmptab, (long)Nicmptab, devgen);
74: }
75:
76: Chan *
77: icmpopen(Chan *c, int omode)
78: {
79: if(c->qid.path == CHDIR){
80: if(omode != OREAD)
81: error(Eperm);
82: } else
83: streamopen(c, &icmpinfo);
84: c->mode = openmode(omode);
85: c->flag |= COPEN;
86: c->offset = 0;
87: return c;
88: }
89:
90: void
91: icmpcreate(Chan *c, char *name, int omode, ulong perm)
92: {
93: USED(c, name, omode, perm);
94: error(Eperm);
95: }
96:
97: void
98: icmpremove(Chan *c)
99: {
100: USED(c);
101: error(Eperm);
102: }
103:
104: void
105: icmpwstat(Chan *c, char *dp)
106: {
107: USED(c, dp);
108: error(Eperm);
109: }
110:
111: void
112: icmpclose(Chan *c)
113: {
114: if((c->qid.path&CHDIR) == 0)
115: streamclose(c);
116: }
117:
118: long
119: icmpread(Chan *c, void *a, long n, ulong offset)
120: {
121: USED(offset);
122:
123: if(c->qid.path&CHDIR)
124: return devdirread(c, a, n, icmptab, Nicmptab, devgen);
125: return streamread(c, a, n);
126: }
127:
128: long
129: icmpwrite(Chan *c, char *a, long n, ulong offset)
130: {
131: USED(offset);
132:
133: return streamwrite(c, a, n, 1);
134: }
135:
136: static void
137: icmpstclose(Queue *q)
138: {
139: USED(q);
140: qlock(&icmp);
141: icmp.rq = 0;
142: qunlock(&icmp);
143: }
144:
145: static void
146: icmpstopen(Queue *q, Stream *s)
147: {
148: USED(s);
149: initipifc(icmp.ifc, IP_ICMPPROTO, icmprcvmsg);
150: icmp.rq = q;
151: }
152:
153: static void
154: icmprcvmsg(Ipifc *ifc, Block *bp)
155: {
156: USED(ifc);
157:
158: qlock(&icmp);
159: if(icmp.rq == 0 || QFULL(icmp.rq->next))
160: freeb(bp);
161: else
162: PUTNEXT(icmp.rq, bp);
163: qunlock(&icmp);
164: }
165:
166: static void
167: icmpoput(Queue *q, Block *bp)
168: {
169: USED(q);
170: ipmuxoput(0, bp);
171: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.