trpc.c - plan9port - [fork] Plan 9 from user space
HTML git clone git://src.adamsgaard.dk/plan9port
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
trpc.c (9502B)
---
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include <sunrpc.h>
5
6 /*
7 * RPC protocol constants
8 */
9 enum
10 {
11 RpcVersion = 2,
12
13 /* msg type */
14 MsgCall = 0,
15 MsgReply = 1,
16
17 /* reply stat */
18 MsgAccepted = 0,
19 MsgDenied = 1,
20
21 /* accept stat */
22 MsgSuccess = 0,
23 MsgProgUnavail = 1,
24 MsgProgMismatch = 2,
25 MsgProcUnavail = 3,
26 MsgGarbageArgs = 4,
27 MsgSystemErr = 5,
28
29 /* reject stat */
30 MsgRpcMismatch = 0,
31 MsgAuthError = 1,
32
33 /* msg auth xxx */
34 MsgAuthOk = 0,
35 MsgAuthBadCred = 1,
36 MsgAuthRejectedCred = 2,
37 MsgAuthBadVerf = 3,
38 MsgAuthRejectedVerf = 4,
39 MsgAuthTooWeak = 5,
40 MsgAuthInvalidResp = 6,
41 MsgAuthFailed = 7
42 };
43
44 SunStatus
45 sunrpcpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
46 {
47 u32int x;
48
49 if(sunuint32pack(a, ea, &a, &rpc->xid) < 0)
50 goto Err;
51 if(rpc->iscall){
52 if(sunuint32pack(a, ea, &a, (x=MsgCall, &x)) < 0
53 || sunuint32pack(a, ea, &a, (x=RpcVersion, &x)) < 0
54 || sunuint32pack(a, ea, &a, &rpc->prog) < 0
55 || sunuint32pack(a, ea, &a, &rpc->vers) < 0
56 || sunuint32pack(a, ea, &a, &rpc->proc) < 0
57 || sunauthinfopack(a, ea, &a, &rpc->cred) < 0
58 || sunauthinfopack(a, ea, &a, &rpc->verf) < 0
59 || sunfixedopaquepack(a, ea, &a, rpc->data, rpc->ndata) < 0)
60 goto Err;
61 }else{
62 if(sunuint32pack(a, ea, &a, (x=MsgReply, &x)) < 0)
63 goto Err;
64 switch(rpc->status&0xF0000){
65 case 0:
66 case SunAcceptError:
67 if(sunuint32pack(a, ea, &a, (x=MsgAccepted, &x)) < 0
68 || sunauthinfopack(a, ea, &a, &rpc->verf) < 0)
69 goto Err;
70 break;
71 case SunAuthError:
72 if(sunuint32pack(a, ea, &a, (x=MsgDenied, &x)) < 0
73 || sunuint32pack(a, ea, &a, (x=MsgAuthError, &x)) < 0)
74 goto Err;
75 break;
76 default:
77 if(sunuint32pack(a, ea, &a, (x=MsgDenied, &x)) < 0)
78 goto Err;
79 break;
80 }
81
82 switch(rpc->status){
83 case SunSuccess:
84 if(sunuint32pack(a, ea, &a, (x=MsgSuccess, &x)) < 0
85 || sunfixedopaquepack(a, ea, &a, rpc->data, rpc->ndata) < 0)
86 goto Err;
87 break;
88 case SunRpcMismatch:
89 case SunProgMismatch:
90 if(sunuint32pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0
91 || sunuint32pack(a, ea, &a, &rpc->low) < 0
92 || sunuint32pack(a, ea, &a, &rpc->high) < 0)
93 goto Err;
94 break;
95 default:
96 if(sunuint32pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0)
97 goto Err;
98
99 break;
100 }
101 }
102 *pa = a;
103 return SunSuccess;
104
105 Err:
106 *pa = ea;
107 return SunGarbageArgs;
108 }
109
110 uint
111 sunrpcsize(SunRpc *rpc)
112 {
113 uint a;
114
115 a = 4;
116 if(rpc->iscall){
117 a += 5*4;
118 a += sunauthinfosize(&rpc->cred);
119 a += sunauthinfosize(&rpc->verf);
120 a += sunfixedopaquesize(rpc->ndata);
121 }else{
122 a += 4;
123 switch(rpc->status&0xF0000){
124 case 0:
125 case SunAcceptError:
126 a += 4+sunauthinfosize(&rpc->verf);
127 break;
128 case SunAuthError:
129 a += 4+4;
130 break;
131 default:
132 a += 4;
133 break;
134 }
135
136 switch(rpc->status){
137 case SunSuccess:
138 a += 4+sunfixedopaquesize(rpc->ndata);
139 break;
140 case SunRpcMismatch:
141 case SunProgMismatch:
142 a += 3*4;
143 break;
144 default:
145 a += 4;
146 }
147 }
148 return a;
149 }
150
151 SunStatus
152 sunrpcunpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
153 {
154 u32int x;
155
156 memset(rpc, 0, sizeof *rpc);
157 if(sunuint32unpack(a, ea, &a, &rpc->xid) < 0
158 || sunuint32unpack(a, ea, &a, &x) < 0)
159 goto Err;
160
161 switch(x){
162 default:
163 goto Err;
164 case MsgCall:
165 rpc->iscall = 1;
166 if(sunuint32unpack(a, ea, &a, &x) < 0 || x != RpcVersion
167 || sunuint32unpack(a, ea, &a, &rpc->prog) < 0
168 || sunuint32unpack(a, ea, &a, &rpc->vers) < 0
169 || sunuint32unpack(a, ea, &a, &rpc->proc) < 0
170 || sunauthinfounpack(a, ea, &a, &rpc->cred) < 0
171 || sunauthinfounpack(a, ea, &a, &rpc->verf) < 0)
172 goto Err;
173 rpc->ndata = ea-a;
174 rpc->data = a;
175 a = ea;
176 break;
177
178 case MsgReply:
179 rpc->iscall = 0;
180 if(sunuint32unpack(a, ea, &a, &x) < 0)
181 goto Err;
182 fprint(2, "x %x\n", x);
183 switch(x){
184 default:
185 goto Err;
186 case MsgAccepted:
187 if(sunauthinfounpack(a, ea, &a, &rpc->verf) < 0
188 || sunuint32unpack(a, ea, &a, &x) < 0)
189 goto Err;
190 switch(x){
191 case MsgSuccess:
192 rpc->status = SunSuccess;
193 rpc->ndata = ea-a;
194 rpc->data = a;
195 a = ea;
196 break;
197 case MsgProgUnavail:
198 case MsgProcUnavail:
199 case MsgGarbageArgs:
200 case MsgSystemErr:
201 rpc->status = SunAcceptError | x;
202 break;
203 case MsgProgMismatch:
204 rpc->status = SunAcceptError | x;
205 if(sunuint32unpack(a, ea, &a, &rpc->low) < 0
206 || sunuint32unpack(a, ea, &a, &rpc->high) < 0)
207 goto Err;
208 break;
209 }
210 break;
211 case MsgDenied:
212 if(sunuint32unpack(a, ea, &a, &x) < 0)
213 goto Err;
214 fprint(2, "xx %ux\n", x);
215 switch(x){
216 default:
217 goto Err;
218 case MsgAuthError:
219 if(sunuint32unpack(a, ea, &a, &x) < 0)
220 goto Err;
221 rpc->status = SunAuthError | x;
222 break;
223 case MsgRpcMismatch:
224 rpc->status = SunRejectError | x;
225 if(sunuint32unpack(a, ea, &a, &rpc->low) < 0
226 || sunuint32unpack(a, ea, &a, &rpc->high) < 0)
227 goto Err;
228 break;
229 }
230 break;
231 }
232 }
233 *pa = a;
234 return SunSuccess;
235
236 Err:
237 *pa = ea;
238 return SunGarbageArgs;
239 }
240
241 void
242 sunrpcprint(Fmt *fmt, SunRpc *rpc)
243 {
244 fmtprint(fmt, "xid=%#ux", rpc->xid);
245 if(rpc->iscall){
246 fmtprint(fmt, " prog %#ux vers %#ux proc %#ux [", rpc->prog, rpc->vers, rpc->proc);
247 sunauthinfoprint(fmt, &rpc->cred);
248 fmtprint(fmt, "] [");
249 sunauthinfoprint(fmt, &rpc->verf);
250 fmtprint(fmt, "]");
251 }else{
252 fmtprint(fmt, " status %#ux [", rpc->status);
253 sunauthinfoprint(fmt, &rpc->verf);
254 fmtprint(fmt, "] low %#ux high %#ux", rpc->low, rpc->high);
255 }
256 }
257
258 void
259 sunauthinfoprint(Fmt *fmt, SunAuthInfo *ai)
260 {
261 switch(ai->flavor){
262 case SunAuthNone:
263 fmtprint(fmt, "none");
264 break;
265 case SunAuthShort:
266 fmtprint(fmt, "short");
267 break;
268 case SunAuthSys:
269 fmtprint(fmt, "sys");
270 break;
271 default:
272 fmtprint(fmt, "%#ux", ai->flavor);
273 break;
274 }
275 /* if(ai->ndata) */
276 /* fmtprint(fmt, " %.*H", ai->ndata, ai->data); */
277 }
278
279 uint
280 sunauthinfosize(SunAuthInfo *ai)
281 {
282 return 4 + sunvaropaquesize(ai->ndata);
283 }
284
285 int
286 sunauthinfopack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
287 {
288 if(sunuint32pack(a, ea, &a, &ai->flavor) < 0
289 || sunvaropaquepack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
290 goto Err;
291 *pa = a;
292 return 0;
293
294 Err:
295 *pa = ea;
296 return -1;
297 }
298
299 int
300 sunauthinfounpack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
301 {
302 if(sunuint32unpack(a, ea, &a, &ai->flavor) < 0
303 || sunvaropaqueunpack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
304 goto Err;
305 *pa = a;
306 return 0;
307
308 Err:
309 *pa = ea;
310 return -1;
311 }
312
313 int
314 sunenumpack(uchar *a, uchar *ea, uchar **pa, int *e)
315 {
316 u32int x;
317
318 x = *e;
319 return sunuint32pack(a, ea, pa, &x);
320 }
321
322 int
323 sunuint1pack(uchar *a, uchar *ea, uchar **pa, u1int *u)
324 {
325 u32int x;
326
327 x = *u;
328 return sunuint32pack(a, ea, pa, &x);
329 }
330
331 int
332 sunuint32pack(uchar *a, uchar *ea, uchar **pa, u32int *u)
333 {
334 u32int x;
335
336 if(ea-a < 4)
337 goto Err;
338
339 x = *u;
340 *a++ = x>>24;
341 *a++ = x>>16;
342 *a++ = x>>8;
343 *a++ = x;
344 *pa = a;
345 return 0;
346
347 Err:
348 *pa = ea;
349 return -1;
350 }
351
352 int
353 sunenumunpack(uchar *a, uchar *ea, uchar **pa, int *e)
354 {
355 u32int x;
356 if(sunuint32unpack(a, ea, pa, &x) < 0)
357 return -1;
358 *e = x;
359 return 0;
360 }
361
362 int
363 sunuint1unpack(uchar *a, uchar *ea, uchar **pa, u1int *u)
364 {
365 u32int x;
366 if(sunuint32unpack(a, ea, pa, &x) < 0 || (x!=0 && x!=1)){
367 *pa = ea;
368 return -1;
369 }
370 *u = x;
371 return 0;
372 }
373
374 int
375 sunuint32unpack(uchar *a, uchar *ea, uchar **pa, u32int *u)
376 {
377 u32int x;
378
379 if(ea-a < 4)
380 goto Err;
381 x = *a++ << 24;
382 x |= *a++ << 16;
383 x |= *a++ << 8;
384 x |= *a++;
385 *pa = a;
386 *u = x;
387 return 0;
388
389 Err:
390 *pa = ea;
391 return -1;
392 }
393
394 int
395 sunuint64unpack(uchar *a, uchar *ea, uchar **pa, u64int *u)
396 {
397 u32int x, y;
398
399 if(sunuint32unpack(a, ea, &a, &x) < 0
400 || sunuint32unpack(a, ea, &a, &y) < 0)
401 goto Err;
402 *u = ((uvlong)x<<32) | y;
403 *pa = a;
404 return 0;
405 Err:
406 *pa = ea;
407 return -1;
408 }
409
410 int
411 sunuint64pack(uchar *a, uchar *ea, uchar **pa, u64int *u)
412 {
413 u32int x, y;
414
415 x = *u >> 32;
416 y = *u;
417 if(sunuint32pack(a, ea, &a, &x) < 0
418 || sunuint32pack(a, ea, &a, &y) < 0)
419 goto Err;
420 *pa = a;
421 return 0;
422 Err:
423 *pa = ea;
424 return -1;
425 }
426
427 uint
428 sunstringsize(char *s)
429 {
430 return (4+strlen(s)+3) & ~3;
431 }
432
433 int
434 sunstringunpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
435 {
436 uchar *dat;
437 u32int n;
438
439 if(sunvaropaqueunpack(a, ea, pa, &dat, &n, max) < 0)
440 goto Err;
441 /* slide string down over length to make room for NUL */
442 dat--;
443 memmove(dat, dat+1, n);
444 dat[n] = 0;
445 *s = (char*)dat;
446 return 0;
447 Err:
448 return -1;
449 }
450
451 int
452 sunstringpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
453 {
454 u32int n;
455
456 n = strlen(*s);
457 return sunvaropaquepack(a, ea, pa, (uchar**)s, &n, max);
458 }
459
460 uint
461 sunvaropaquesize(u32int n)
462 {
463 return (4+n+3) & ~3;
464 }
465
466 int
467 sunvaropaquepack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
468 {
469 if(*ndat > max || sunuint32pack(a, ea, &a, ndat) < 0
470 || sunfixedopaquepack(a, ea, &a, *dat, *ndat) < 0)
471 goto Err;
472 *pa = a;
473 return 0;
474
475 Err:
476 *pa = ea;
477 return -1;
478 }
479
480 int
481 sunvaropaqueunpack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
482 {
483 if(sunuint32unpack(a, ea, &a, ndat) < 0
484 || *ndat > max)
485 goto Err;
486 *dat = a;
487 a += (*ndat+3)&~3;
488 if(a > ea)
489 goto Err;
490 *pa = a;
491 return 0;
492
493 Err:
494 *pa = ea;
495 return -1;
496 }
497
498 uint
499 sunfixedopaquesize(u32int n)
500 {
501 return (n+3) & ~3;
502 }
503
504 int
505 sunfixedopaquepack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
506 {
507 uint nn;
508
509 nn = (n+3)&~3;
510 if(a+nn > ea)
511 goto Err;
512 memmove(a, dat, n);
513 if(nn > n)
514 memset(a+n, 0, nn-n);
515 a += nn;
516 *pa = a;
517 return 0;
518
519 Err:
520 *pa = ea;
521 return -1;
522 }
523
524 int
525 sunfixedopaqueunpack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
526 {
527 uint nn;
528
529 nn = (n+3)&~3;
530 if(a+nn > ea)
531 goto Err;
532 memmove(dat, a, n);
533 a += nn;
534 *pa = a;
535 return 0;
536
537 Err:
538 *pa = ea;
539 return -1;
540 }