Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
		default:
72
			if(sunUint32Pack(a, ea, &a, (x=MsgDenied, &x)) < 0)
73
				goto Err;
74
			break;
75
		}
76
 
77
		switch(rpc->status){
78
		case SunSuccess:
79
			if(sunUint32Pack(a, ea, &a, (x=MsgSuccess, &x)) < 0
80
			|| sunFixedOpaquePack(a, ea, &a, rpc->data, rpc->ndata) < 0)
81
				goto Err;
82
			break;
83
		case SunRpcMismatch:
84
		case SunProgMismatch:
85
			if(sunUint32Pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0
86
			|| sunUint32Pack(a, ea, &a, &rpc->low) < 0
87
			|| sunUint32Pack(a, ea, &a, &rpc->high) < 0)
88
				goto Err;
89
			break;
90
		default:
91
			if(sunUint32Pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0)
92
				goto Err;
93
			break;
94
		}
95
	}
96
	*pa = a;
97
	return SunSuccess;
98
 
99
Err:
100
	*pa = ea;
101
	return SunGarbageArgs;
102
}
103
 
104
uint
105
sunRpcSize(SunRpc *rpc)
106
{
107
	uint a;
108
 
109
	a = 4;
110
	if(rpc->iscall){
111
		a += 5*4;
112
		a += sunAuthInfoSize(&rpc->cred);
113
		a += sunAuthInfoSize(&rpc->verf);
114
		a += sunFixedOpaqueSize(rpc->ndata);
115
	}else{
116
		a += 4;
117
		switch(rpc->status&0xF0000){
118
		case 0:
119
		case SunAcceptError:
120
			a += 4+sunAuthInfoSize(&rpc->verf);
121
			break;
122
		default:
123
			a += 4;
124
			break;
125
		}
126
 
127
		switch(rpc->status){
128
		case SunSuccess:
129
			a += 4+sunFixedOpaqueSize(rpc->ndata);
130
			break;
131
		case SunRpcMismatch:
132
		case SunProgMismatch:
133
			a += 3*4;
134
		default:
135
			a += 4;
136
		}
137
	}
138
	return a;
139
}
140
 
141
SunStatus
142
sunRpcUnpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
143
{
144
	u32int x;
145
 
146
	memset(rpc, 0, sizeof *rpc);
147
	if(sunUint32Unpack(a, ea, &a, &rpc->xid) < 0
148
	|| sunUint32Unpack(a, ea, &a, &x) < 0)
149
		goto Err;
150
 
151
	switch(x){
152
	default:
153
		goto Err;
154
	case MsgCall:
155
		rpc->iscall = 1;
156
		if(sunUint32Unpack(a, ea, &a, &x) < 0 || x != RpcVersion
157
		|| sunUint32Unpack(a, ea, &a, &rpc->prog) < 0
158
		|| sunUint32Unpack(a, ea, &a, &rpc->vers) < 0
159
		|| sunUint32Unpack(a, ea, &a, &rpc->proc) < 0
160
		|| sunAuthInfoUnpack(a, ea, &a, &rpc->cred) < 0
161
		|| sunAuthInfoUnpack(a, ea, &a, &rpc->verf) < 0)
162
			goto Err;
163
		rpc->ndata = ea-a;
164
		rpc->data = a;
165
		a = ea;
166
		break;
167
 
168
	case MsgReply:
169
		rpc->iscall = 0;
170
		if(sunUint32Unpack(a, ea, &a, &x) < 0)
171
			goto Err;
172
		switch(x){
173
		default:
174
			goto Err;
175
		case MsgAccepted:
176
			if(sunAuthInfoUnpack(a, ea, &a, &rpc->verf) < 0
177
			|| sunUint32Unpack(a, ea, &a, &x) < 0)
178
				goto Err;
179
			switch(x){
180
			case MsgSuccess:
181
				rpc->status = SunSuccess;
182
				rpc->ndata = ea-a;
183
				rpc->data = a;
184
				a = ea;
185
				break;
186
			case MsgProgUnavail:
187
			case MsgProcUnavail:
188
			case MsgGarbageArgs:
189
			case MsgSystemErr:
190
				rpc->status = SunAcceptError | x;
191
				break;
192
			case MsgProgMismatch:
193
				rpc->status = SunAcceptError | x;
194
				if(sunUint32Unpack(a, ea, &a, &rpc->low) < 0
195
				|| sunUint32Unpack(a, ea, &a, &rpc->high) < 0)
196
					goto Err;
197
				break;
198
			}
199
			break;
200
		case MsgDenied:
201
			if(sunUint32Unpack(a, ea, &a, &x) < 0)
202
				goto Err;
203
			switch(x){
204
			default:
205
				goto Err;
206
			case MsgAuthError:
207
				if(sunUint32Unpack(a, ea, &a, &x) < 0)
208
					goto Err;
209
				rpc->status = SunAuthError | x;
210
				break;
211
			case MsgRpcMismatch:
212
				rpc->status = SunRejectError | x;
213
				if(sunUint32Unpack(a, ea, &a, &rpc->low) < 0
214
				|| sunUint32Unpack(a, ea, &a, &rpc->high) < 0)
215
					goto Err;
216
				break;
217
			}
218
			break;
219
		}
220
	}
221
	*pa = a;
222
	return SunSuccess;
223
 
224
Err:
225
	*pa = ea;
226
	return SunGarbageArgs;
227
}
228
 
229
void
230
sunRpcPrint(Fmt *fmt, SunRpc *rpc)
231
{
232
	fmtprint(fmt, "xid=%#ux", rpc->xid);
233
	if(rpc->iscall){
234
		fmtprint(fmt, " prog %#ux vers %#ux proc %#ux [", rpc->prog, rpc->vers, rpc->proc);
235
		sunAuthInfoPrint(fmt, &rpc->cred);
236
		fmtprint(fmt, "] [");
237
		sunAuthInfoPrint(fmt, &rpc->verf);
238
		fmtprint(fmt, "]");
239
	}else{
240
		fmtprint(fmt, " status %#ux [", rpc->status);
241
		sunAuthInfoPrint(fmt, &rpc->verf);
242
		fmtprint(fmt, "] low %#ux high %#ux", rpc->low, rpc->high);
243
	}
244
}
245
 
246
void
247
sunAuthInfoPrint(Fmt *fmt, SunAuthInfo *ai)
248
{
249
	switch(ai->flavor){
250
	case SunAuthNone:
251
		fmtprint(fmt, "none");
252
		break;
253
	case SunAuthShort:
254
		fmtprint(fmt, "short");
255
		break;
256
	case SunAuthSys:
257
		fmtprint(fmt, "sys");
258
		break;
259
	default:
260
		fmtprint(fmt, "%#ux", ai->flavor);
261
		break;
262
	}
263
//	if(ai->ndata)
264
//		fmtprint(fmt, " %.*H", ai->ndata, ai->data);
265
}
266
 
267
uint
268
sunAuthInfoSize(SunAuthInfo *ai)
269
{
270
	return 4 + sunVarOpaqueSize(ai->ndata);
271
}
272
 
273
int
274
sunAuthInfoPack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
275
{
276
	if(sunUint32Pack(a, ea, &a, &ai->flavor) < 0
277
	|| sunVarOpaquePack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
278
		goto Err;
279
	*pa = a;
280
	return 0;
281
 
282
Err:
283
	*pa = ea;
284
	return -1;
285
}
286
 
287
int
288
sunAuthInfoUnpack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
289
{
290
	if(sunUint32Unpack(a, ea, &a, &ai->flavor) < 0
291
	|| sunVarOpaqueUnpack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
292
		goto Err;
293
	*pa = a;
294
	return 0;
295
 
296
Err:
297
	*pa = ea;
298
	return -1;
299
}
300
 
301
int
302
sunEnumPack(uchar *a, uchar *ea, uchar **pa, int *e)
303
{
304
	u32int x;
305
 
306
	x = *e;
307
	return sunUint32Pack(a, ea, pa, &x);
308
}
309
 
310
int
311
sunUint1Pack(uchar *a, uchar *ea, uchar **pa, u1int *u)
312
{
313
	u32int x;
314
 
315
	x = *u;
316
	return sunUint32Pack(a, ea, pa, &x);
317
}
318
 
319
int
320
sunUint32Pack(uchar *a, uchar *ea, uchar **pa, u32int *u)
321
{
322
	u32int x;
323
 
324
	if(ea-a < 4)
325
		goto Err;
326
 
327
	x = *u;
328
	*a++ = x>>24;
329
	*a++ = x>>16;
330
	*a++ = x>>8;
331
	*a++ = x;
332
	*pa = a;
333
	return 0;
334
 
335
Err:
336
	*pa = ea;
337
	return -1;
338
}
339
 
340
int
341
sunEnumUnpack(uchar *a, uchar *ea, uchar **pa, int *e)
342
{
343
	u32int x;
344
	if(sunUint32Unpack(a, ea, pa, &x) < 0)
345
		return -1;
346
	*e = x;
347
	return 0;
348
}
349
 
350
int
351
sunUint1Unpack(uchar *a, uchar *ea, uchar **pa, u1int *u)
352
{
353
	u32int x;
354
	if(sunUint32Unpack(a, ea, pa, &x) < 0 || (x!=0 && x!=1)){
355
		*pa = ea;
356
		return -1;
357
	}
358
	*u = x;
359
	return 0;
360
}
361
 
362
int
363
sunUint32Unpack(uchar *a, uchar *ea, uchar **pa, u32int *u)
364
{
365
	u32int x;
366
 
367
	if(ea-a < 4)
368
		goto Err;
369
	x = *a++ << 24;
370
	x |= *a++ << 16;
371
	x |= *a++ << 8;
372
	x |= *a++;
373
	*pa = a;
374
	*u = x;
375
	return 0;
376
 
377
Err:
378
	*pa = ea;
379
	return -1;
380
}
381
 
382
int
383
sunUint64Unpack(uchar *a, uchar *ea, uchar **pa, u64int *u)
384
{
385
	u32int x, y;
386
 
387
	if(sunUint32Unpack(a, ea, &a, &x) < 0
388
	|| sunUint32Unpack(a, ea, &a, &y) < 0)
389
		goto Err;
390
	*u = ((uvlong)x<<32) | y;
391
	*pa = a;
392
	return 0;
393
Err:
394
	*pa = ea;
395
	return -1;
396
}
397
 
398
int
399
sunUint64Pack(uchar *a, uchar *ea, uchar **pa, u64int *u)
400
{
401
	u32int x, y;
402
 
403
	x = *u >> 32;
404
	y = *u;
405
	if(sunUint32Pack(a, ea, &a, &x) < 0
406
	|| sunUint32Pack(a, ea, &a, &y) < 0)
407
		goto Err;
408
	*pa = a;
409
	return 0;
410
Err:
411
	*pa = ea;
412
	return -1;
413
}
414
 
415
uint
416
sunStringSize(char *s)
417
{
418
	return (4+strlen(s)+3) & ~3;
419
}
420
 
421
int
422
sunStringUnpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
423
{
424
	uchar *dat;
425
	u32int n;
426
 
427
	if(sunVarOpaqueUnpack(a, ea, pa, &dat, &n, max) < 0)
428
		goto Err;
429
	/* slide string down over length to make room for NUL */
430
	memmove(dat-1, dat, n);
431
	dat[-1+n] = 0;
432
	*s = (char*)(dat-1);
433
	return 0;
434
Err:
435
	return -1;
436
}
437
 
438
int
439
sunStringPack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
440
{
441
	u32int n;
442
 
443
	n = strlen(*s);
444
	return sunVarOpaquePack(a, ea, pa, (uchar**)s, &n, max);
445
}
446
 
447
uint
448
sunVarOpaqueSize(u32int n)
449
{
450
	return (4+n+3) & ~3;
451
}
452
 
453
int
454
sunVarOpaquePack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
455
{
456
	if(*ndat > max || sunUint32Pack(a, ea, &a, ndat) < 0
457
	|| sunFixedOpaquePack(a, ea, &a, *dat, *ndat) < 0)
458
		goto Err;
459
	*pa = a;
460
	return 0;
461
 
462
Err:
463
	*pa = ea;
464
	return -1;
465
}
466
 
467
int
468
sunVarOpaqueUnpack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
469
{
470
	if(sunUint32Unpack(a, ea, &a, ndat) < 0
471
	|| *ndat > max)
472
		goto Err;
473
	*dat = a;
474
	a += (*ndat+3)&~3;
475
	if(a > ea)
476
		goto Err;
477
	*pa = a;
478
	return 0;
479
 
480
Err:
481
	*pa = ea;
482
	return -1;
483
}
484
 
485
uint
486
sunFixedOpaqueSize(u32int n)
487
{
488
	return (n+3) & ~3;
489
}
490
 
491
int
492
sunFixedOpaquePack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
493
{
494
	uint nn;
495
 
496
	nn = (n+3)&~3;
497
	if(a+nn > ea)
498
		goto Err;
499
	memmove(a, dat, n);
500
	if(nn > n)
501
		memset(a+n, 0, nn-n);
502
	a += nn;
503
	*pa = a;
504
	return 0;
505
 
506
Err:
507
	*pa = ea;
508
	return -1;
509
}
510
 
511
int
512
sunFixedOpaqueUnpack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
513
{
514
	uint nn;
515
 
516
	nn = (n+3)&~3;
517
	if(a+nn > ea)
518
		goto Err;
519
	memmove(dat, a, n);
520
	a += nn;
521
	*pa = a;
522
	return 0;
523
 
524
Err:
525
	*pa = ea;
526
	return -1;
527
}
528