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