xref: /plan9/sys/src/cmd/9nfs/rpc.c (revision 883a8c51bed350ea85a0220461d31e311550db04)
19a747e4fSDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier 
39a747e4fSDavid du Colombier #define	SHORT(x)	r->x = (p[1] | (p[0]<<8)); p += 2
49a747e4fSDavid du Colombier #define	LONG(x)		r->x = (p[3] | (p[2]<<8) |\
59a747e4fSDavid du Colombier 				(p[1]<<16) | (p[0]<<24)); p += 4
69a747e4fSDavid du Colombier #define SKIPLONG	p += 4
79a747e4fSDavid du Colombier #define	PTR(x, n)	r->x = (void *)(p); p += ROUNDUP(n)
89a747e4fSDavid du Colombier 
99a747e4fSDavid du Colombier int
rpcM2S(void * ap,Rpccall * r,int n)109a747e4fSDavid du Colombier rpcM2S(void *ap, Rpccall *r, int n)
119a747e4fSDavid du Colombier {
129a747e4fSDavid du Colombier 	int k;
13*883a8c51SDavid du Colombier 	uchar *p;
14*883a8c51SDavid du Colombier 	Udphdr *up;
159a747e4fSDavid du Colombier 
16*883a8c51SDavid du Colombier 	/* copy IPv4 header fields from Udphdr */
17*883a8c51SDavid du Colombier 	up = ap;
18*883a8c51SDavid du Colombier 	p = &up->raddr[IPaddrlen - IPv4addrlen];
199a747e4fSDavid du Colombier 	LONG(host);
20*883a8c51SDavid du Colombier 	USED(p);
21*883a8c51SDavid du Colombier 	p = &up->laddr[IPaddrlen - IPv4addrlen];
229a747e4fSDavid du Colombier 	LONG(lhost);
23*883a8c51SDavid du Colombier 	USED(p);
24*883a8c51SDavid du Colombier 	/* ignore up->ifcaddr */
25*883a8c51SDavid du Colombier 	p = up->rport;
269a747e4fSDavid du Colombier 	SHORT(port);
279a747e4fSDavid du Colombier 	SHORT(lport);
28*883a8c51SDavid du Colombier 
299a747e4fSDavid du Colombier 	LONG(xid);
309a747e4fSDavid du Colombier 	LONG(mtype);
319a747e4fSDavid du Colombier 	switch(r->mtype){
329a747e4fSDavid du Colombier 	case CALL:
339a747e4fSDavid du Colombier 		LONG(rpcvers);
349a747e4fSDavid du Colombier 		if(r->rpcvers != 2)
359a747e4fSDavid du Colombier 			break;
369a747e4fSDavid du Colombier 		LONG(prog);
379a747e4fSDavid du Colombier 		LONG(vers);
389a747e4fSDavid du Colombier 		LONG(proc);
399a747e4fSDavid du Colombier 		LONG(cred.flavor);
409a747e4fSDavid du Colombier 		LONG(cred.count);
419a747e4fSDavid du Colombier 		PTR(cred.data, r->cred.count);
429a747e4fSDavid du Colombier 		LONG(verf.flavor);
439a747e4fSDavid du Colombier 		LONG(verf.count);
449a747e4fSDavid du Colombier 		PTR(verf.data, r->verf.count);
459a747e4fSDavid du Colombier 		r->up = 0;
469a747e4fSDavid du Colombier 		k = n - (p - (uchar *)ap);
479a747e4fSDavid du Colombier 		if(k < 0)
489a747e4fSDavid du Colombier 			break;
499a747e4fSDavid du Colombier 		PTR(args, k);
509a747e4fSDavid du Colombier 		break;
519a747e4fSDavid du Colombier 	case REPLY:
529a747e4fSDavid du Colombier 		LONG(stat);
539a747e4fSDavid du Colombier 		switch(r->stat){
549a747e4fSDavid du Colombier 		case MSG_ACCEPTED:
559a747e4fSDavid du Colombier 			LONG(averf.flavor);
569a747e4fSDavid du Colombier 			LONG(averf.count);
579a747e4fSDavid du Colombier 			PTR(averf.data, r->averf.count);
589a747e4fSDavid du Colombier 			LONG(astat);
599a747e4fSDavid du Colombier 			switch(r->astat){
609a747e4fSDavid du Colombier 			case SUCCESS:
619a747e4fSDavid du Colombier 				k = n - (p - (uchar *)ap);
629a747e4fSDavid du Colombier 				if(k < 0)
639a747e4fSDavid du Colombier 					break;
649a747e4fSDavid du Colombier 				PTR(results, k);
659a747e4fSDavid du Colombier 				break;
669a747e4fSDavid du Colombier 			case PROG_MISMATCH:
679a747e4fSDavid du Colombier 				LONG(plow);
689a747e4fSDavid du Colombier 				LONG(phigh);
699a747e4fSDavid du Colombier 				break;
709a747e4fSDavid du Colombier 			}
719a747e4fSDavid du Colombier 			break;
729a747e4fSDavid du Colombier 		case MSG_DENIED:
739a747e4fSDavid du Colombier 			LONG(rstat);
749a747e4fSDavid du Colombier 			switch(r->rstat){
759a747e4fSDavid du Colombier 			case RPC_MISMATCH:
769a747e4fSDavid du Colombier 				LONG(rlow);
779a747e4fSDavid du Colombier 				LONG(rhigh);
789a747e4fSDavid du Colombier 				break;
799a747e4fSDavid du Colombier 			case AUTH_ERROR:
809a747e4fSDavid du Colombier 				LONG(authstat);
819a747e4fSDavid du Colombier 				break;
829a747e4fSDavid du Colombier 			}
839a747e4fSDavid du Colombier 			break;
849a747e4fSDavid du Colombier 		}
859a747e4fSDavid du Colombier 		break;
869a747e4fSDavid du Colombier 	}
879a747e4fSDavid du Colombier 	n -= p - (uchar *)ap;
889a747e4fSDavid du Colombier 	return n;
899a747e4fSDavid du Colombier }
909a747e4fSDavid du Colombier 
919a747e4fSDavid du Colombier int
auth2unix(Auth * arg,Authunix * r)929a747e4fSDavid du Colombier auth2unix(Auth *arg, Authunix *r)
939a747e4fSDavid du Colombier {
949a747e4fSDavid du Colombier 	int i, n;
959a747e4fSDavid du Colombier 	uchar *p;
969a747e4fSDavid du Colombier 
979a747e4fSDavid du Colombier 	if(arg->flavor != AUTH_UNIX)
989a747e4fSDavid du Colombier 		return -1;
999a747e4fSDavid du Colombier 	p = arg->data;
1009a747e4fSDavid du Colombier 	LONG(stamp);
1019a747e4fSDavid du Colombier 	LONG(mach.n);
1029a747e4fSDavid du Colombier 	PTR(mach.s, r->mach.n);
1039a747e4fSDavid du Colombier 	LONG(uid);
1049a747e4fSDavid du Colombier 	LONG(gid);
1059a747e4fSDavid du Colombier 	LONG(gidlen);
1069a747e4fSDavid du Colombier 	n = r->gidlen;
1079a747e4fSDavid du Colombier 	for(i=0; i<n && i < nelem(r->gids); i++){
1089a747e4fSDavid du Colombier 		LONG(gids[i]);
1099a747e4fSDavid du Colombier 	}
1109a747e4fSDavid du Colombier 	for(; i<n; i++){
1119a747e4fSDavid du Colombier 		SKIPLONG;
1129a747e4fSDavid du Colombier 	}
1139a747e4fSDavid du Colombier 	return arg->count - (p - (uchar *)arg->data);
1149a747e4fSDavid du Colombier }
1159a747e4fSDavid du Colombier 
1169a747e4fSDavid du Colombier int
string2S(void * arg,String * r)1179a747e4fSDavid du Colombier string2S(void *arg, String *r)
1189a747e4fSDavid du Colombier {
1199a747e4fSDavid du Colombier 	uchar *p;
1209a747e4fSDavid du Colombier 	char *s;
1219a747e4fSDavid du Colombier 
1229a747e4fSDavid du Colombier 	p = arg;
1239a747e4fSDavid du Colombier 	LONG(n);
1249a747e4fSDavid du Colombier 	PTR(s, r->n);
1259a747e4fSDavid du Colombier 	/* must NUL terminate */
1269a747e4fSDavid du Colombier 	s = malloc(r->n+1);
1279a747e4fSDavid du Colombier 	if(s == nil)
1289a747e4fSDavid du Colombier 		panic("malloc(%ld) failed in string2S\n", r->n+1);
1299a747e4fSDavid du Colombier 	memmove(s, r->s, r->n);
1309a747e4fSDavid du Colombier 	s[r->n] = '\0';
1319a747e4fSDavid du Colombier 	r->s = strstore(s);
1329a747e4fSDavid du Colombier 	free(s);
1339a747e4fSDavid du Colombier 	return p - (uchar *)arg;
1349a747e4fSDavid du Colombier }
1359a747e4fSDavid du Colombier 
1369a747e4fSDavid du Colombier #undef	SHORT
1379a747e4fSDavid du Colombier #undef	LONG
1389a747e4fSDavid du Colombier #undef	PTR
1399a747e4fSDavid du Colombier 
1409a747e4fSDavid du Colombier #define	SHORT(x)	p[1] = r->x; p[0] = r->x>>8; p += 2
1419a747e4fSDavid 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
1429a747e4fSDavid du Colombier 
1439a747e4fSDavid du Colombier #define	PTR(x,n)	memmove(p, r->x, n); p += ROUNDUP(n)
1449a747e4fSDavid du Colombier 
1459a747e4fSDavid du Colombier int
rpcS2M(Rpccall * r,int ndata,void * ap)1469a747e4fSDavid du Colombier rpcS2M(Rpccall *r, int ndata, void *ap)
1479a747e4fSDavid du Colombier {
148*883a8c51SDavid du Colombier 	uchar *p;
149*883a8c51SDavid du Colombier 	Udphdr *up;
1509a747e4fSDavid du Colombier 
151*883a8c51SDavid du Colombier 	/* copy header fields to Udphdr */
152*883a8c51SDavid du Colombier 	up = ap;
153*883a8c51SDavid du Colombier 	memmove(up->raddr, v4prefix, IPaddrlen);
154*883a8c51SDavid du Colombier 	p = &up->raddr[IPaddrlen - IPv4addrlen];
1559a747e4fSDavid du Colombier 	LONG(host);
156*883a8c51SDavid du Colombier 	USED(p);
157*883a8c51SDavid du Colombier 	memmove(up->laddr, v4prefix, IPaddrlen);
158*883a8c51SDavid du Colombier 	p = &up->laddr[IPaddrlen - IPv4addrlen];
1599a747e4fSDavid du Colombier 	LONG(lhost);
160*883a8c51SDavid du Colombier 	USED(p);
161*883a8c51SDavid du Colombier 	memmove(up->ifcaddr, IPnoaddr, sizeof up->ifcaddr);
162*883a8c51SDavid du Colombier 	p = up->rport;
1639a747e4fSDavid du Colombier 	SHORT(port);
1649a747e4fSDavid du Colombier 	SHORT(lport);
165*883a8c51SDavid du Colombier 
1669a747e4fSDavid du Colombier 	LONG(xid);
1679a747e4fSDavid du Colombier 	LONG(mtype);
1689a747e4fSDavid du Colombier 	switch(r->mtype){
1699a747e4fSDavid du Colombier 	case CALL:
1709a747e4fSDavid du Colombier 		LONG(rpcvers);
1719a747e4fSDavid du Colombier 		LONG(prog);
1729a747e4fSDavid du Colombier 		LONG(vers);
1739a747e4fSDavid du Colombier 		LONG(proc);
1749a747e4fSDavid du Colombier 		LONG(cred.flavor);
1759a747e4fSDavid du Colombier 		LONG(cred.count);
1769a747e4fSDavid du Colombier 		PTR(cred.data, r->cred.count);
1779a747e4fSDavid du Colombier 		LONG(verf.flavor);
1789a747e4fSDavid du Colombier 		LONG(verf.count);
1799a747e4fSDavid du Colombier 		PTR(verf.data, r->verf.count);
1809a747e4fSDavid du Colombier 		PTR(args, ndata);
1819a747e4fSDavid du Colombier 		break;
1829a747e4fSDavid du Colombier 	case REPLY:
1839a747e4fSDavid du Colombier 		LONG(stat);
1849a747e4fSDavid du Colombier 		switch(r->stat){
1859a747e4fSDavid du Colombier 		case MSG_ACCEPTED:
1869a747e4fSDavid du Colombier 			LONG(averf.flavor);
1879a747e4fSDavid du Colombier 			LONG(averf.count);
1889a747e4fSDavid du Colombier 			PTR(averf.data, r->averf.count);
1899a747e4fSDavid du Colombier 			LONG(astat);
1909a747e4fSDavid du Colombier 			switch(r->astat){
1919a747e4fSDavid du Colombier 			case SUCCESS:
1929a747e4fSDavid du Colombier 				PTR(results, ndata);
1939a747e4fSDavid du Colombier 				break;
1949a747e4fSDavid du Colombier 			case PROG_MISMATCH:
1959a747e4fSDavid du Colombier 				LONG(plow);
1969a747e4fSDavid du Colombier 				LONG(phigh);
1979a747e4fSDavid du Colombier 				break;
1989a747e4fSDavid du Colombier 			}
1999a747e4fSDavid du Colombier 			break;
2009a747e4fSDavid du Colombier 		case MSG_DENIED:
2019a747e4fSDavid du Colombier 			LONG(rstat);
2029a747e4fSDavid du Colombier 			switch(r->rstat){
2039a747e4fSDavid du Colombier 			case RPC_MISMATCH:
2049a747e4fSDavid du Colombier 				LONG(rlow);
2059a747e4fSDavid du Colombier 				LONG(rhigh);
2069a747e4fSDavid du Colombier 				break;
2079a747e4fSDavid du Colombier 			case AUTH_ERROR:
2089a747e4fSDavid du Colombier 				LONG(authstat);
2099a747e4fSDavid du Colombier 				break;
2109a747e4fSDavid du Colombier 			}
2119a747e4fSDavid du Colombier 			break;
2129a747e4fSDavid du Colombier 		}
2139a747e4fSDavid du Colombier 		break;
2149a747e4fSDavid du Colombier 	}
2159a747e4fSDavid du Colombier 	return p - (uchar *)ap;
2169a747e4fSDavid du Colombier }
2179a747e4fSDavid du Colombier 
2189a747e4fSDavid du Colombier #undef	SHORT
2199a747e4fSDavid du Colombier #undef	LONG
2209a747e4fSDavid du Colombier #undef	PTR
2219a747e4fSDavid du Colombier 
2229a747e4fSDavid du Colombier #define	LONG(m, x)	fprint(fd, "%s = %ld\n", m, r->x)
2239a747e4fSDavid du Colombier 
2249a747e4fSDavid du Colombier #define	PTR(m, count)	fprint(fd, "%s [%ld]\n", m, count)
2259a747e4fSDavid du Colombier 
2269a747e4fSDavid du Colombier void
rpcprint(int fd,Rpccall * r)2279a747e4fSDavid du Colombier rpcprint(int fd, Rpccall *r)
2289a747e4fSDavid du Colombier {
2299a747e4fSDavid du Colombier 	fprint(fd, "%s: host = %I, port = %ld\n",
2309a747e4fSDavid du Colombier 		argv0, r->host, r->port);
2319a747e4fSDavid du Colombier 	LONG("xid", xid);
2329a747e4fSDavid du Colombier 	LONG("mtype", mtype);
2339a747e4fSDavid du Colombier 	switch(r->mtype){
2349a747e4fSDavid du Colombier 	case CALL:
2359a747e4fSDavid du Colombier 		LONG("rpcvers", rpcvers);
2369a747e4fSDavid du Colombier 		LONG("prog", prog);
2379a747e4fSDavid du Colombier 		LONG("vers", vers);
2389a747e4fSDavid du Colombier 		LONG("proc", proc);
2399a747e4fSDavid du Colombier 		LONG("cred.flavor", cred.flavor);
2409a747e4fSDavid du Colombier 		PTR("cred.data", r->cred.count);
2419a747e4fSDavid du Colombier 		LONG("verf.flavor", verf.flavor);
2429a747e4fSDavid du Colombier 		PTR("verf.data", r->verf.count);
2439a747e4fSDavid du Colombier 		fprint(fd, "args...\n");
2449a747e4fSDavid du Colombier 		break;
2459a747e4fSDavid du Colombier 	case REPLY:
2469a747e4fSDavid du Colombier 		LONG("stat", stat);
2479a747e4fSDavid du Colombier 		switch(r->stat){
2489a747e4fSDavid du Colombier 		case MSG_ACCEPTED:
2499a747e4fSDavid du Colombier 			LONG("averf.flavor", averf.flavor);
2509a747e4fSDavid du Colombier 			PTR("averf.data", r->averf.count);
2519a747e4fSDavid du Colombier 			LONG("astat", astat);
2529a747e4fSDavid du Colombier 			switch(r->astat){
2539a747e4fSDavid du Colombier 			case SUCCESS:
2549a747e4fSDavid du Colombier 				fprint(fd, "results...\n");
2559a747e4fSDavid du Colombier 				break;
2569a747e4fSDavid du Colombier 			case PROG_MISMATCH:
2579a747e4fSDavid du Colombier 				LONG("plow", plow);
2589a747e4fSDavid du Colombier 				LONG("phigh", phigh);
2599a747e4fSDavid du Colombier 				break;
2609a747e4fSDavid du Colombier 			}
2619a747e4fSDavid du Colombier 			break;
2629a747e4fSDavid du Colombier 		case MSG_DENIED:
2639a747e4fSDavid du Colombier 			LONG("rstat", rstat);
2649a747e4fSDavid du Colombier 			switch(r->rstat){
2659a747e4fSDavid du Colombier 			case RPC_MISMATCH:
2669a747e4fSDavid du Colombier 				LONG("rlow", rlow);
2679a747e4fSDavid du Colombier 				LONG("rhigh", rhigh);
2689a747e4fSDavid du Colombier 				break;
2699a747e4fSDavid du Colombier 			case AUTH_ERROR:
2709a747e4fSDavid du Colombier 				LONG("authstat", authstat);
2719a747e4fSDavid du Colombier 				break;
2729a747e4fSDavid du Colombier 			}
2739a747e4fSDavid du Colombier 			break;
2749a747e4fSDavid du Colombier 		}
2759a747e4fSDavid du Colombier 	}
2769a747e4fSDavid du Colombier }
2779a747e4fSDavid du Colombier 
2789a747e4fSDavid du Colombier void
showauth(Auth * ap)2799a747e4fSDavid du Colombier showauth(Auth *ap)
2809a747e4fSDavid du Colombier {
2819a747e4fSDavid du Colombier 	Authunix au;
2829a747e4fSDavid du Colombier 	int i;
2839a747e4fSDavid du Colombier 
2849a747e4fSDavid du Colombier 	if(auth2unix(ap, &au) != 0){
2859a747e4fSDavid du Colombier 		chat("auth flavor=%ld, count=%ld",
2869a747e4fSDavid du Colombier 			ap->flavor, ap->count);
2879a747e4fSDavid du Colombier 		for(i=0; i<ap->count; i++)
2889a747e4fSDavid du Colombier 			chat(" %.2ux", ((uchar *)ap->data)[i]);
2899a747e4fSDavid du Colombier 	}else{
2909a747e4fSDavid du Colombier 		chat("auth: %ld %.*s u=%ld g=%ld",
2919a747e4fSDavid du Colombier 			au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
2929a747e4fSDavid du Colombier 		for(i=0; i<au.gidlen; i++)
2939a747e4fSDavid du Colombier 			chat(", %ld", au.gids[i]);
2949a747e4fSDavid du Colombier 	}
2959a747e4fSDavid du Colombier 	chat("...");
2969a747e4fSDavid du Colombier }
2979a747e4fSDavid du Colombier 
2989a747e4fSDavid du Colombier int
garbage(Rpccall * reply,char * msg)2999a747e4fSDavid du Colombier garbage(Rpccall *reply, char *msg)
3009a747e4fSDavid du Colombier {
3019a747e4fSDavid du Colombier 	chat("%s\n", msg ? msg : "garbage");
3029a747e4fSDavid du Colombier 	reply->astat = GARBAGE_ARGS;
3039a747e4fSDavid du Colombier 	return 0;
3049a747e4fSDavid du Colombier }
3059a747e4fSDavid du Colombier 
3069a747e4fSDavid du Colombier int
error(Rpccall * reply,int errno)3079a747e4fSDavid du Colombier error(Rpccall *reply, int errno)
3089a747e4fSDavid du Colombier {
3099a747e4fSDavid du Colombier 	uchar *dataptr = reply->results;
3109a747e4fSDavid du Colombier 
3119a747e4fSDavid du Colombier 	chat("error %d\n", errno);
3129a747e4fSDavid du Colombier 	PLONG(errno);
3139a747e4fSDavid du Colombier 	return dataptr - (uchar *)reply->results;
3149a747e4fSDavid du Colombier }
315