]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/9nfs/rpc.c
9bootfat: rename open() to fileinit and make it static as its really a internal funct...
[plan9front.git] / sys / src / cmd / 9nfs / rpc.c
1 #include "all.h"
2
3 #define SHORT(x)        r->x = (p[1] | (p[0]<<8)); p += 2
4 #define LONG(x)         r->x = (p[3] | (p[2]<<8) |\
5                                 (p[1]<<16) | (p[0]<<24)); p += 4
6 #define SKIPLONG        p += 4
7 #define PTR(x, n)       r->x = (void *)(p); p += ROUNDUP(n)
8
9 int
10 rpcM2S(void *ap, Rpccall *r, int n)
11 {
12         int k;
13         uchar *p;
14         Udphdr *up;
15
16         /* copy IPv4 header fields from Udphdr */
17         up = ap;
18         p = &up->raddr[IPaddrlen - IPv4addrlen];
19         LONG(host);
20         USED(p);
21         p = &up->laddr[IPaddrlen - IPv4addrlen];
22         LONG(lhost);
23         USED(p);
24         /* ignore up->ifcaddr */
25         p = up->rport;
26         SHORT(port);
27         SHORT(lport);
28
29         LONG(xid);
30         LONG(mtype);
31         switch(r->mtype){
32         case CALL:
33                 LONG(rpcvers);
34                 if(r->rpcvers != 2)
35                         break;
36                 LONG(prog);
37                 LONG(vers);
38                 LONG(proc);
39                 LONG(cred.flavor);
40                 LONG(cred.count);
41                 PTR(cred.data, r->cred.count);
42                 LONG(verf.flavor);
43                 LONG(verf.count);
44                 PTR(verf.data, r->verf.count);
45                 r->up = 0;
46                 k = n - (p - (uchar *)ap);
47                 if(k < 0)
48                         break;
49                 PTR(args, k);
50                 break;
51         case REPLY:
52                 LONG(stat);
53                 switch(r->stat){
54                 case MSG_ACCEPTED:
55                         LONG(averf.flavor);
56                         LONG(averf.count);
57                         PTR(averf.data, r->averf.count);
58                         LONG(astat);
59                         switch(r->astat){
60                         case SUCCESS:
61                                 k = n - (p - (uchar *)ap);
62                                 if(k < 0)
63                                         break;
64                                 PTR(results, k);
65                                 break;
66                         case PROG_MISMATCH:
67                                 LONG(plow);
68                                 LONG(phigh);
69                                 break;
70                         }
71                         break;
72                 case MSG_DENIED:
73                         LONG(rstat);
74                         switch(r->rstat){
75                         case RPC_MISMATCH:
76                                 LONG(rlow);
77                                 LONG(rhigh);
78                                 break;
79                         case AUTH_ERROR:
80                                 LONG(authstat);
81                                 break;
82                         }
83                         break;
84                 }
85                 break;
86         }
87         n -= p - (uchar *)ap;
88         return n;
89 }
90
91 int
92 auth2unix(Auth *arg, Authunix *r)
93 {
94         int i, n;
95         uchar *p;
96
97         if(arg->flavor != AUTH_UNIX)
98                 return -1;
99         p = arg->data;
100         LONG(stamp);
101         LONG(mach.n);
102         PTR(mach.s, r->mach.n);
103         LONG(uid);
104         LONG(gid);
105         LONG(gidlen);
106         n = r->gidlen;
107         for(i=0; i<n && i < nelem(r->gids); i++){
108                 LONG(gids[i]);
109         }
110         for(; i<n; i++){
111                 SKIPLONG;
112         }
113         return arg->count - (p - (uchar *)arg->data);
114 }
115
116 int
117 string2S(void *arg, String *r)
118 {
119         uchar *p;
120         char *s;
121
122         p = arg;
123         LONG(n);
124         PTR(s, r->n);
125         /* must NUL terminate */
126         s = malloc(r->n+1);
127         if(s == nil)
128                 panic("malloc(%ld) failed in string2S\n", r->n+1);
129         memmove(s, r->s, r->n);
130         s[r->n] = '\0';
131         r->s = strstore(s);
132         free(s);
133         return p - (uchar *)arg;
134 }
135
136 #undef  SHORT
137 #undef  LONG
138 #undef  PTR
139
140 #define SHORT(x)        p[1] = r->x; p[0] = r->x>>8; p += 2
141 #define LONG(x)         p[3] = r->x; p[2] = r->x>>8; p[1] = r->x>>16; p[0] = r->x>>24; p += 4
142
143 #define PTR(x,n)        memmove(p, r->x, n); p += ROUNDUP(n)
144
145 int
146 rpcS2M(Rpccall *r, int ndata, void *ap)
147 {
148         uchar *p;
149         Udphdr *up;
150
151         /* copy header fields to Udphdr */
152         up = ap;
153         memmove(up->raddr, v4prefix, IPaddrlen);
154         p = &up->raddr[IPaddrlen - IPv4addrlen];
155         LONG(host);
156         USED(p);
157         memmove(up->laddr, v4prefix, IPaddrlen);
158         p = &up->laddr[IPaddrlen - IPv4addrlen];
159         LONG(lhost);
160         USED(p);
161         memmove(up->ifcaddr, IPnoaddr, sizeof up->ifcaddr);
162         p = up->rport;
163         SHORT(port);
164         SHORT(lport);
165
166         LONG(xid);
167         LONG(mtype);
168         switch(r->mtype){
169         case CALL:
170                 LONG(rpcvers);
171                 LONG(prog);
172                 LONG(vers);
173                 LONG(proc);
174                 LONG(cred.flavor);
175                 LONG(cred.count);
176                 PTR(cred.data, r->cred.count);
177                 LONG(verf.flavor);
178                 LONG(verf.count);
179                 PTR(verf.data, r->verf.count);
180                 PTR(args, ndata);
181                 break;
182         case REPLY:
183                 LONG(stat);
184                 switch(r->stat){
185                 case MSG_ACCEPTED:
186                         LONG(averf.flavor);
187                         LONG(averf.count);
188                         PTR(averf.data, r->averf.count);
189                         LONG(astat);
190                         switch(r->astat){
191                         case SUCCESS:
192                                 PTR(results, ndata);
193                                 break;
194                         case PROG_MISMATCH:
195                                 LONG(plow);
196                                 LONG(phigh);
197                                 break;
198                         }
199                         break;
200                 case MSG_DENIED:
201                         LONG(rstat);
202                         switch(r->rstat){
203                         case RPC_MISMATCH:
204                                 LONG(rlow);
205                                 LONG(rhigh);
206                                 break;
207                         case AUTH_ERROR:
208                                 LONG(authstat);
209                                 break;
210                         }
211                         break;
212                 }
213                 break;
214         }
215         return p - (uchar *)ap;
216 }
217
218 #undef  SHORT
219 #undef  LONG
220 #undef  PTR
221
222 #define LONG(m, x)      fprint(fd, "%s = %ld\n", m, r->x)
223
224 #define PTR(m, count)   fprint(fd, "%s [%ld]\n", m, count)
225
226 void
227 rpcprint(int fd, Rpccall *r)
228 {
229         fprint(fd, "%s: host = %I, port = %ld\n", 
230                 argv0, r->host, r->port);
231         LONG("xid", xid);
232         LONG("mtype", mtype);
233         switch(r->mtype){
234         case CALL:
235                 LONG("rpcvers", rpcvers);
236                 LONG("prog", prog);
237                 LONG("vers", vers);
238                 LONG("proc", proc);
239                 LONG("cred.flavor", cred.flavor);
240                 PTR("cred.data", r->cred.count);
241                 LONG("verf.flavor", verf.flavor);
242                 PTR("verf.data", r->verf.count);
243                 fprint(fd, "args...\n");
244                 break;
245         case REPLY:
246                 LONG("stat", stat);
247                 switch(r->stat){
248                 case MSG_ACCEPTED:
249                         LONG("averf.flavor", averf.flavor);
250                         PTR("averf.data", r->averf.count);
251                         LONG("astat", astat);
252                         switch(r->astat){
253                         case SUCCESS:
254                                 fprint(fd, "results...\n");
255                                 break;
256                         case PROG_MISMATCH:
257                                 LONG("plow", plow);
258                                 LONG("phigh", phigh);
259                                 break;
260                         }
261                         break;
262                 case MSG_DENIED:
263                         LONG("rstat", rstat);
264                         switch(r->rstat){
265                         case RPC_MISMATCH:
266                                 LONG("rlow", rlow);
267                                 LONG("rhigh", rhigh);
268                                 break;
269                         case AUTH_ERROR:
270                                 LONG("authstat", authstat);
271                                 break;
272                         }
273                         break;
274                 }
275         }
276 }
277
278 void
279 showauth(Auth *ap)
280 {
281         Authunix au;
282         int i;
283
284         if(auth2unix(ap, &au) != 0){
285                 chat("auth flavor=%ld, count=%ld",
286                         ap->flavor, ap->count);
287                 for(i=0; i<ap->count; i++)
288                         chat(" %.2ux", ((uchar *)ap->data)[i]);
289         }else{
290                 chat("auth: %ld %.*s u=%ld g=%ld",
291                         au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
292                 for(i=0; i<au.gidlen; i++)
293                         chat(", %ld", au.gids[i]);
294         }
295         chat("...");
296 }
297
298 int
299 garbage(Rpccall *reply, char *msg)
300 {
301         chat("%s\n", msg ? msg : "garbage");
302         reply->astat = GARBAGE_ARGS;
303         return 0;
304 }
305
306 int
307 error(Rpccall *reply, int errno)
308 {
309         uchar *dataptr = reply->results;
310
311         chat("error %d\n", errno);
312         PLONG(errno);
313         return dataptr - (uchar *)reply->results;
314 }