xref: /plan9/sys/src/cmd/9nfs/rpc.c (revision 883a8c51bed350ea85a0220461d31e311550db04)
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
rpcM2S(void * ap,Rpccall * r,int n)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
auth2unix(Auth * arg,Authunix * r)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
string2S(void * arg,String * r)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
rpcS2M(Rpccall * r,int ndata,void * ap)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
rpcprint(int fd,Rpccall * r)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
showauth(Auth * ap)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
garbage(Rpccall * reply,char * msg)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
error(Rpccall * reply,int errno)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 }
315