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 "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
}