Add sunrpc.
This commit is contained in:
parent
fa256eecfa
commit
551445b92c
16 changed files with 7163 additions and 0 deletions
528
src/libsunrpc/rpc.c
Normal file
528
src/libsunrpc/rpc.c
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <thread.h>
|
||||
#include <sunrpc.h>
|
||||
|
||||
/*
|
||||
* RPC protocol constants
|
||||
*/
|
||||
enum
|
||||
{
|
||||
RpcVersion = 2,
|
||||
|
||||
/* msg type */
|
||||
MsgCall = 0,
|
||||
MsgReply = 1,
|
||||
|
||||
/* reply stat */
|
||||
MsgAccepted = 0,
|
||||
MsgDenied = 1,
|
||||
|
||||
/* accept stat */
|
||||
MsgSuccess = 0,
|
||||
MsgProgUnavail = 1,
|
||||
MsgProgMismatch = 2,
|
||||
MsgProcUnavail = 3,
|
||||
MsgGarbageArgs = 4,
|
||||
MsgSystemErr = 5,
|
||||
|
||||
/* reject stat */
|
||||
MsgRpcMismatch = 0,
|
||||
MsgAuthError = 1,
|
||||
|
||||
/* msg auth xxx */
|
||||
MsgAuthOk = 0,
|
||||
MsgAuthBadCred = 1,
|
||||
MsgAuthRejectedCred = 2,
|
||||
MsgAuthBadVerf = 3,
|
||||
MsgAuthRejectedVerf = 4,
|
||||
MsgAuthTooWeak = 5,
|
||||
MsgAuthInvalidResp = 6,
|
||||
MsgAuthFailed = 7,
|
||||
};
|
||||
|
||||
SunStatus
|
||||
sunrpcpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
|
||||
{
|
||||
u32int x;
|
||||
|
||||
if(sunuint32pack(a, ea, &a, &rpc->xid) < 0)
|
||||
goto Err;
|
||||
if(rpc->iscall){
|
||||
if(sunuint32pack(a, ea, &a, (x=MsgCall, &x)) < 0
|
||||
|| sunuint32pack(a, ea, &a, (x=RpcVersion, &x)) < 0
|
||||
|| sunuint32pack(a, ea, &a, &rpc->prog) < 0
|
||||
|| sunuint32pack(a, ea, &a, &rpc->vers) < 0
|
||||
|| sunuint32pack(a, ea, &a, &rpc->proc) < 0
|
||||
|| sunauthinfopack(a, ea, &a, &rpc->cred) < 0
|
||||
|| sunauthinfopack(a, ea, &a, &rpc->verf) < 0
|
||||
|| sunfixedopaquepack(a, ea, &a, rpc->data, rpc->ndata) < 0)
|
||||
goto Err;
|
||||
}else{
|
||||
if(sunuint32pack(a, ea, &a, (x=MsgReply, &x)) < 0)
|
||||
goto Err;
|
||||
switch(rpc->status&0xF0000){
|
||||
case 0:
|
||||
case SunAcceptError:
|
||||
if(sunuint32pack(a, ea, &a, (x=MsgAccepted, &x)) < 0
|
||||
|| sunauthinfopack(a, ea, &a, &rpc->verf) < 0)
|
||||
goto Err;
|
||||
break;
|
||||
default:
|
||||
if(sunuint32pack(a, ea, &a, (x=MsgDenied, &x)) < 0)
|
||||
goto Err;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(rpc->status){
|
||||
case SunSuccess:
|
||||
if(sunuint32pack(a, ea, &a, (x=MsgSuccess, &x)) < 0
|
||||
|| sunfixedopaquepack(a, ea, &a, rpc->data, rpc->ndata) < 0)
|
||||
goto Err;
|
||||
break;
|
||||
case SunRpcMismatch:
|
||||
case SunProgMismatch:
|
||||
if(sunuint32pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0
|
||||
|| sunuint32pack(a, ea, &a, &rpc->low) < 0
|
||||
|| sunuint32pack(a, ea, &a, &rpc->high) < 0)
|
||||
goto Err;
|
||||
break;
|
||||
default:
|
||||
if(sunuint32pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0)
|
||||
goto Err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*pa = a;
|
||||
return SunSuccess;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return SunGarbageArgs;
|
||||
}
|
||||
|
||||
uint
|
||||
sunrpcsize(SunRpc *rpc)
|
||||
{
|
||||
uint a;
|
||||
|
||||
a = 4;
|
||||
if(rpc->iscall){
|
||||
a += 5*4;
|
||||
a += sunauthinfosize(&rpc->cred);
|
||||
a += sunauthinfosize(&rpc->verf);
|
||||
a += sunfixedopaquesize(rpc->ndata);
|
||||
}else{
|
||||
a += 4;
|
||||
switch(rpc->status&0xF0000){
|
||||
case 0:
|
||||
case SunAcceptError:
|
||||
a += 4+sunauthinfosize(&rpc->verf);
|
||||
break;
|
||||
default:
|
||||
a += 4;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(rpc->status){
|
||||
case SunSuccess:
|
||||
a += 4+sunfixedopaquesize(rpc->ndata);
|
||||
break;
|
||||
case SunRpcMismatch:
|
||||
case SunProgMismatch:
|
||||
a += 3*4;
|
||||
default:
|
||||
a += 4;
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
SunStatus
|
||||
sunrpcunpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
|
||||
{
|
||||
u32int x;
|
||||
|
||||
memset(rpc, 0, sizeof *rpc);
|
||||
if(sunuint32unpack(a, ea, &a, &rpc->xid) < 0
|
||||
|| sunuint32unpack(a, ea, &a, &x) < 0)
|
||||
goto Err;
|
||||
|
||||
switch(x){
|
||||
default:
|
||||
goto Err;
|
||||
case MsgCall:
|
||||
rpc->iscall = 1;
|
||||
if(sunuint32unpack(a, ea, &a, &x) < 0 || x != RpcVersion
|
||||
|| sunuint32unpack(a, ea, &a, &rpc->prog) < 0
|
||||
|| sunuint32unpack(a, ea, &a, &rpc->vers) < 0
|
||||
|| sunuint32unpack(a, ea, &a, &rpc->proc) < 0
|
||||
|| sunauthinfounpack(a, ea, &a, &rpc->cred) < 0
|
||||
|| sunauthinfounpack(a, ea, &a, &rpc->verf) < 0)
|
||||
goto Err;
|
||||
rpc->ndata = ea-a;
|
||||
rpc->data = a;
|
||||
a = ea;
|
||||
break;
|
||||
|
||||
case MsgReply:
|
||||
rpc->iscall = 0;
|
||||
if(sunuint32unpack(a, ea, &a, &x) < 0)
|
||||
goto Err;
|
||||
switch(x){
|
||||
default:
|
||||
goto Err;
|
||||
case MsgAccepted:
|
||||
if(sunauthinfounpack(a, ea, &a, &rpc->verf) < 0
|
||||
|| sunuint32unpack(a, ea, &a, &x) < 0)
|
||||
goto Err;
|
||||
switch(x){
|
||||
case MsgSuccess:
|
||||
rpc->status = SunSuccess;
|
||||
rpc->ndata = ea-a;
|
||||
rpc->data = a;
|
||||
a = ea;
|
||||
break;
|
||||
case MsgProgUnavail:
|
||||
case MsgProcUnavail:
|
||||
case MsgGarbageArgs:
|
||||
case MsgSystemErr:
|
||||
rpc->status = SunAcceptError | x;
|
||||
break;
|
||||
case MsgProgMismatch:
|
||||
rpc->status = SunAcceptError | x;
|
||||
if(sunuint32unpack(a, ea, &a, &rpc->low) < 0
|
||||
|| sunuint32unpack(a, ea, &a, &rpc->high) < 0)
|
||||
goto Err;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MsgDenied:
|
||||
if(sunuint32unpack(a, ea, &a, &x) < 0)
|
||||
goto Err;
|
||||
switch(x){
|
||||
default:
|
||||
goto Err;
|
||||
case MsgAuthError:
|
||||
if(sunuint32unpack(a, ea, &a, &x) < 0)
|
||||
goto Err;
|
||||
rpc->status = SunAuthError | x;
|
||||
break;
|
||||
case MsgRpcMismatch:
|
||||
rpc->status = SunRejectError | x;
|
||||
if(sunuint32unpack(a, ea, &a, &rpc->low) < 0
|
||||
|| sunuint32unpack(a, ea, &a, &rpc->high) < 0)
|
||||
goto Err;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*pa = a;
|
||||
return SunSuccess;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return SunGarbageArgs;
|
||||
}
|
||||
|
||||
void
|
||||
sunrpcprint(Fmt *fmt, SunRpc *rpc)
|
||||
{
|
||||
fmtprint(fmt, "xid=%#ux", rpc->xid);
|
||||
if(rpc->iscall){
|
||||
fmtprint(fmt, " prog %#ux vers %#ux proc %#ux [", rpc->prog, rpc->vers, rpc->proc);
|
||||
sunauthinfoprint(fmt, &rpc->cred);
|
||||
fmtprint(fmt, "] [");
|
||||
sunauthinfoprint(fmt, &rpc->verf);
|
||||
fmtprint(fmt, "]");
|
||||
}else{
|
||||
fmtprint(fmt, " status %#ux [", rpc->status);
|
||||
sunauthinfoprint(fmt, &rpc->verf);
|
||||
fmtprint(fmt, "] low %#ux high %#ux", rpc->low, rpc->high);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sunauthinfoprint(Fmt *fmt, SunAuthInfo *ai)
|
||||
{
|
||||
switch(ai->flavor){
|
||||
case SunAuthNone:
|
||||
fmtprint(fmt, "none");
|
||||
break;
|
||||
case SunAuthShort:
|
||||
fmtprint(fmt, "short");
|
||||
break;
|
||||
case SunAuthSys:
|
||||
fmtprint(fmt, "sys");
|
||||
break;
|
||||
default:
|
||||
fmtprint(fmt, "%#ux", ai->flavor);
|
||||
break;
|
||||
}
|
||||
// if(ai->ndata)
|
||||
// fmtprint(fmt, " %.*H", ai->ndata, ai->data);
|
||||
}
|
||||
|
||||
uint
|
||||
sunauthinfosize(SunAuthInfo *ai)
|
||||
{
|
||||
return 4 + sunvaropaquesize(ai->ndata);
|
||||
}
|
||||
|
||||
int
|
||||
sunauthinfopack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
|
||||
{
|
||||
if(sunuint32pack(a, ea, &a, &ai->flavor) < 0
|
||||
|| sunvaropaquepack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
|
||||
goto Err;
|
||||
*pa = a;
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sunauthinfounpack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
|
||||
{
|
||||
if(sunuint32unpack(a, ea, &a, &ai->flavor) < 0
|
||||
|| sunvaropaqueunpack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
|
||||
goto Err;
|
||||
*pa = a;
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sunenumpack(uchar *a, uchar *ea, uchar **pa, int *e)
|
||||
{
|
||||
u32int x;
|
||||
|
||||
x = *e;
|
||||
return sunuint32pack(a, ea, pa, &x);
|
||||
}
|
||||
|
||||
int
|
||||
sunuint1pack(uchar *a, uchar *ea, uchar **pa, u1int *u)
|
||||
{
|
||||
u32int x;
|
||||
|
||||
x = *u;
|
||||
return sunuint32pack(a, ea, pa, &x);
|
||||
}
|
||||
|
||||
int
|
||||
sunuint32pack(uchar *a, uchar *ea, uchar **pa, u32int *u)
|
||||
{
|
||||
u32int x;
|
||||
|
||||
if(ea-a < 4)
|
||||
goto Err;
|
||||
|
||||
x = *u;
|
||||
*a++ = x>>24;
|
||||
*a++ = x>>16;
|
||||
*a++ = x>>8;
|
||||
*a++ = x;
|
||||
*pa = a;
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sunenumunpack(uchar *a, uchar *ea, uchar **pa, int *e)
|
||||
{
|
||||
u32int x;
|
||||
if(sunuint32unpack(a, ea, pa, &x) < 0)
|
||||
return -1;
|
||||
*e = x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sunuint1unpack(uchar *a, uchar *ea, uchar **pa, u1int *u)
|
||||
{
|
||||
u32int x;
|
||||
if(sunuint32unpack(a, ea, pa, &x) < 0 || (x!=0 && x!=1)){
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
*u = x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sunuint32unpack(uchar *a, uchar *ea, uchar **pa, u32int *u)
|
||||
{
|
||||
u32int x;
|
||||
|
||||
if(ea-a < 4)
|
||||
goto Err;
|
||||
x = *a++ << 24;
|
||||
x |= *a++ << 16;
|
||||
x |= *a++ << 8;
|
||||
x |= *a++;
|
||||
*pa = a;
|
||||
*u = x;
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sunuint64unpack(uchar *a, uchar *ea, uchar **pa, u64int *u)
|
||||
{
|
||||
u32int x, y;
|
||||
|
||||
if(sunuint32unpack(a, ea, &a, &x) < 0
|
||||
|| sunuint32unpack(a, ea, &a, &y) < 0)
|
||||
goto Err;
|
||||
*u = ((uvlong)x<<32) | y;
|
||||
*pa = a;
|
||||
return 0;
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sunuint64pack(uchar *a, uchar *ea, uchar **pa, u64int *u)
|
||||
{
|
||||
u32int x, y;
|
||||
|
||||
x = *u >> 32;
|
||||
y = *u;
|
||||
if(sunuint32pack(a, ea, &a, &x) < 0
|
||||
|| sunuint32pack(a, ea, &a, &y) < 0)
|
||||
goto Err;
|
||||
*pa = a;
|
||||
return 0;
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint
|
||||
sunstringsize(char *s)
|
||||
{
|
||||
return (4+strlen(s)+3) & ~3;
|
||||
}
|
||||
|
||||
int
|
||||
sunstringunpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
|
||||
{
|
||||
uchar *dat;
|
||||
u32int n;
|
||||
|
||||
if(sunvaropaqueunpack(a, ea, pa, &dat, &n, max) < 0)
|
||||
goto Err;
|
||||
/* slide string down over length to make room for NUL */
|
||||
memmove(dat-1, dat, n);
|
||||
dat[-1+n] = 0;
|
||||
*s = (char*)(dat-1);
|
||||
return 0;
|
||||
Err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sunstringpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
|
||||
{
|
||||
u32int n;
|
||||
|
||||
n = strlen(*s);
|
||||
return sunvaropaquepack(a, ea, pa, (uchar**)s, &n, max);
|
||||
}
|
||||
|
||||
uint
|
||||
sunvaropaquesize(u32int n)
|
||||
{
|
||||
return (4+n+3) & ~3;
|
||||
}
|
||||
|
||||
int
|
||||
sunvaropaquepack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
|
||||
{
|
||||
if(*ndat > max || sunuint32pack(a, ea, &a, ndat) < 0
|
||||
|| sunfixedopaquepack(a, ea, &a, *dat, *ndat) < 0)
|
||||
goto Err;
|
||||
*pa = a;
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sunvaropaqueunpack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
|
||||
{
|
||||
if(sunuint32unpack(a, ea, &a, ndat) < 0
|
||||
|| *ndat > max)
|
||||
goto Err;
|
||||
*dat = a;
|
||||
a += (*ndat+3)&~3;
|
||||
if(a > ea)
|
||||
goto Err;
|
||||
*pa = a;
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint
|
||||
sunfixedopaquesize(u32int n)
|
||||
{
|
||||
return (n+3) & ~3;
|
||||
}
|
||||
|
||||
int
|
||||
sunfixedopaquepack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
|
||||
{
|
||||
uint nn;
|
||||
|
||||
nn = (n+3)&~3;
|
||||
if(a+nn > ea)
|
||||
goto Err;
|
||||
memmove(a, dat, n);
|
||||
if(nn > n)
|
||||
memset(a+n, 0, nn-n);
|
||||
a += nn;
|
||||
*pa = a;
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sunfixedopaqueunpack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
|
||||
{
|
||||
uint nn;
|
||||
|
||||
nn = (n+3)&~3;
|
||||
if(a+nn > ea)
|
||||
goto Err;
|
||||
memmove(dat, a, n);
|
||||
a += nn;
|
||||
*pa = a;
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
*pa = ea;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue