summaryrefslogtreecommitdiff
path: root/sys/src/cmd/9nfs/rpc.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/9nfs/rpc.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/9nfs/rpc.c')
-rwxr-xr-xsys/src/cmd/9nfs/rpc.c314
1 files changed, 314 insertions, 0 deletions
diff --git a/sys/src/cmd/9nfs/rpc.c b/sys/src/cmd/9nfs/rpc.c
new file mode 100755
index 000000000..91086c91a
--- /dev/null
+++ b/sys/src/cmd/9nfs/rpc.c
@@ -0,0 +1,314 @@
+#include "all.h"
+
+#define SHORT(x) r->x = (p[1] | (p[0]<<8)); p += 2
+#define LONG(x) r->x = (p[3] | (p[2]<<8) |\
+ (p[1]<<16) | (p[0]<<24)); p += 4
+#define SKIPLONG p += 4
+#define PTR(x, n) r->x = (void *)(p); p += ROUNDUP(n)
+
+int
+rpcM2S(void *ap, Rpccall *r, int n)
+{
+ int k;
+ uchar *p;
+ Udphdr *up;
+
+ /* copy IPv4 header fields from Udphdr */
+ up = ap;
+ p = &up->raddr[IPaddrlen - IPv4addrlen];
+ LONG(host);
+ USED(p);
+ p = &up->laddr[IPaddrlen - IPv4addrlen];
+ LONG(lhost);
+ USED(p);
+ /* ignore up->ifcaddr */
+ p = up->rport;
+ SHORT(port);
+ SHORT(lport);
+
+ LONG(xid);
+ LONG(mtype);
+ switch(r->mtype){
+ case CALL:
+ LONG(rpcvers);
+ if(r->rpcvers != 2)
+ break;
+ LONG(prog);
+ LONG(vers);
+ LONG(proc);
+ LONG(cred.flavor);
+ LONG(cred.count);
+ PTR(cred.data, r->cred.count);
+ LONG(verf.flavor);
+ LONG(verf.count);
+ PTR(verf.data, r->verf.count);
+ r->up = 0;
+ k = n - (p - (uchar *)ap);
+ if(k < 0)
+ break;
+ PTR(args, k);
+ break;
+ case REPLY:
+ LONG(stat);
+ switch(r->stat){
+ case MSG_ACCEPTED:
+ LONG(averf.flavor);
+ LONG(averf.count);
+ PTR(averf.data, r->averf.count);
+ LONG(astat);
+ switch(r->astat){
+ case SUCCESS:
+ k = n - (p - (uchar *)ap);
+ if(k < 0)
+ break;
+ PTR(results, k);
+ break;
+ case PROG_MISMATCH:
+ LONG(plow);
+ LONG(phigh);
+ break;
+ }
+ break;
+ case MSG_DENIED:
+ LONG(rstat);
+ switch(r->rstat){
+ case RPC_MISMATCH:
+ LONG(rlow);
+ LONG(rhigh);
+ break;
+ case AUTH_ERROR:
+ LONG(authstat);
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ n -= p - (uchar *)ap;
+ return n;
+}
+
+int
+auth2unix(Auth *arg, Authunix *r)
+{
+ int i, n;
+ uchar *p;
+
+ if(arg->flavor != AUTH_UNIX)
+ return -1;
+ p = arg->data;
+ LONG(stamp);
+ LONG(mach.n);
+ PTR(mach.s, r->mach.n);
+ LONG(uid);
+ LONG(gid);
+ LONG(gidlen);
+ n = r->gidlen;
+ for(i=0; i<n && i < nelem(r->gids); i++){
+ LONG(gids[i]);
+ }
+ for(; i<n; i++){
+ SKIPLONG;
+ }
+ return arg->count - (p - (uchar *)arg->data);
+}
+
+int
+string2S(void *arg, String *r)
+{
+ uchar *p;
+ char *s;
+
+ p = arg;
+ LONG(n);
+ PTR(s, r->n);
+ /* must NUL terminate */
+ s = malloc(r->n+1);
+ if(s == nil)
+ panic("malloc(%ld) failed in string2S\n", r->n+1);
+ memmove(s, r->s, r->n);
+ s[r->n] = '\0';
+ r->s = strstore(s);
+ free(s);
+ return p - (uchar *)arg;
+}
+
+#undef SHORT
+#undef LONG
+#undef PTR
+
+#define SHORT(x) p[1] = r->x; p[0] = r->x>>8; p += 2
+#define LONG(x) p[3] = r->x; p[2] = r->x>>8; p[1] = r->x>>16; p[0] = r->x>>24; p += 4
+
+#define PTR(x,n) memmove(p, r->x, n); p += ROUNDUP(n)
+
+int
+rpcS2M(Rpccall *r, int ndata, void *ap)
+{
+ uchar *p;
+ Udphdr *up;
+
+ /* copy header fields to Udphdr */
+ up = ap;
+ memmove(up->raddr, v4prefix, IPaddrlen);
+ p = &up->raddr[IPaddrlen - IPv4addrlen];
+ LONG(host);
+ USED(p);
+ memmove(up->laddr, v4prefix, IPaddrlen);
+ p = &up->laddr[IPaddrlen - IPv4addrlen];
+ LONG(lhost);
+ USED(p);
+ memmove(up->ifcaddr, IPnoaddr, sizeof up->ifcaddr);
+ p = up->rport;
+ SHORT(port);
+ SHORT(lport);
+
+ LONG(xid);
+ LONG(mtype);
+ switch(r->mtype){
+ case CALL:
+ LONG(rpcvers);
+ LONG(prog);
+ LONG(vers);
+ LONG(proc);
+ LONG(cred.flavor);
+ LONG(cred.count);
+ PTR(cred.data, r->cred.count);
+ LONG(verf.flavor);
+ LONG(verf.count);
+ PTR(verf.data, r->verf.count);
+ PTR(args, ndata);
+ break;
+ case REPLY:
+ LONG(stat);
+ switch(r->stat){
+ case MSG_ACCEPTED:
+ LONG(averf.flavor);
+ LONG(averf.count);
+ PTR(averf.data, r->averf.count);
+ LONG(astat);
+ switch(r->astat){
+ case SUCCESS:
+ PTR(results, ndata);
+ break;
+ case PROG_MISMATCH:
+ LONG(plow);
+ LONG(phigh);
+ break;
+ }
+ break;
+ case MSG_DENIED:
+ LONG(rstat);
+ switch(r->rstat){
+ case RPC_MISMATCH:
+ LONG(rlow);
+ LONG(rhigh);
+ break;
+ case AUTH_ERROR:
+ LONG(authstat);
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ return p - (uchar *)ap;
+}
+
+#undef SHORT
+#undef LONG
+#undef PTR
+
+#define LONG(m, x) fprint(fd, "%s = %ld\n", m, r->x)
+
+#define PTR(m, count) fprint(fd, "%s [%ld]\n", m, count)
+
+void
+rpcprint(int fd, Rpccall *r)
+{
+ fprint(fd, "%s: host = %I, port = %ld\n",
+ argv0, r->host, r->port);
+ LONG("xid", xid);
+ LONG("mtype", mtype);
+ switch(r->mtype){
+ case CALL:
+ LONG("rpcvers", rpcvers);
+ LONG("prog", prog);
+ LONG("vers", vers);
+ LONG("proc", proc);
+ LONG("cred.flavor", cred.flavor);
+ PTR("cred.data", r->cred.count);
+ LONG("verf.flavor", verf.flavor);
+ PTR("verf.data", r->verf.count);
+ fprint(fd, "args...\n");
+ break;
+ case REPLY:
+ LONG("stat", stat);
+ switch(r->stat){
+ case MSG_ACCEPTED:
+ LONG("averf.flavor", averf.flavor);
+ PTR("averf.data", r->averf.count);
+ LONG("astat", astat);
+ switch(r->astat){
+ case SUCCESS:
+ fprint(fd, "results...\n");
+ break;
+ case PROG_MISMATCH:
+ LONG("plow", plow);
+ LONG("phigh", phigh);
+ break;
+ }
+ break;
+ case MSG_DENIED:
+ LONG("rstat", rstat);
+ switch(r->rstat){
+ case RPC_MISMATCH:
+ LONG("rlow", rlow);
+ LONG("rhigh", rhigh);
+ break;
+ case AUTH_ERROR:
+ LONG("authstat", authstat);
+ break;
+ }
+ break;
+ }
+ }
+}
+
+void
+showauth(Auth *ap)
+{
+ Authunix au;
+ int i;
+
+ if(auth2unix(ap, &au) != 0){
+ chat("auth flavor=%ld, count=%ld",
+ ap->flavor, ap->count);
+ for(i=0; i<ap->count; i++)
+ chat(" %.2ux", ((uchar *)ap->data)[i]);
+ }else{
+ chat("auth: %ld %.*s u=%ld g=%ld",
+ au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
+ for(i=0; i<au.gidlen; i++)
+ chat(", %ld", au.gids[i]);
+ }
+ chat("...");
+}
+
+int
+garbage(Rpccall *reply, char *msg)
+{
+ chat("%s\n", msg ? msg : "garbage");
+ reply->astat = GARBAGE_ARGS;
+ return 0;
+}
+
+int
+error(Rpccall *reply, int errno)
+{
+ uchar *dataptr = reply->results;
+
+ chat("error %d\n", errno);
+ PLONG(errno);
+ return dataptr - (uchar *)reply->results;
+}