URI:
       trpc.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       trpc.c (9502B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <thread.h>
            4 #include <sunrpc.h>
            5 
            6 /*
            7  * RPC protocol constants
            8  */
            9 enum
           10 {
           11         RpcVersion = 2,
           12 
           13         /* msg type */
           14         MsgCall = 0,
           15         MsgReply = 1,
           16 
           17         /* reply stat */
           18         MsgAccepted = 0,
           19         MsgDenied = 1,
           20 
           21         /* accept stat */
           22         MsgSuccess = 0,
           23         MsgProgUnavail = 1,
           24         MsgProgMismatch = 2,
           25         MsgProcUnavail = 3,
           26         MsgGarbageArgs = 4,
           27         MsgSystemErr = 5,
           28 
           29         /* reject stat */
           30         MsgRpcMismatch = 0,
           31         MsgAuthError = 1,
           32 
           33         /* msg auth xxx */
           34         MsgAuthOk = 0,
           35         MsgAuthBadCred = 1,
           36         MsgAuthRejectedCred = 2,
           37         MsgAuthBadVerf = 3,
           38         MsgAuthRejectedVerf = 4,
           39         MsgAuthTooWeak = 5,
           40         MsgAuthInvalidResp = 6,
           41         MsgAuthFailed = 7
           42 };
           43 
           44 SunStatus
           45 sunrpcpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
           46 {
           47         u32int x;
           48 
           49         if(sunuint32pack(a, ea, &a, &rpc->xid) < 0)
           50                 goto Err;
           51         if(rpc->iscall){
           52                 if(sunuint32pack(a, ea, &a, (x=MsgCall, &x)) < 0
           53                 || sunuint32pack(a, ea, &a, (x=RpcVersion, &x)) < 0
           54                 || sunuint32pack(a, ea, &a, &rpc->prog) < 0
           55                 || sunuint32pack(a, ea, &a, &rpc->vers) < 0
           56                 || sunuint32pack(a, ea, &a, &rpc->proc) < 0
           57                 || sunauthinfopack(a, ea, &a, &rpc->cred) < 0
           58                 || sunauthinfopack(a, ea, &a, &rpc->verf) < 0
           59                 || sunfixedopaquepack(a, ea, &a, rpc->data, rpc->ndata) < 0)
           60                         goto Err;
           61         }else{
           62                 if(sunuint32pack(a, ea, &a, (x=MsgReply, &x)) < 0)
           63                         goto Err;
           64                 switch(rpc->status&0xF0000){
           65                 case 0:
           66                 case SunAcceptError:
           67                         if(sunuint32pack(a, ea, &a, (x=MsgAccepted, &x)) < 0
           68                         || sunauthinfopack(a, ea, &a, &rpc->verf) < 0)
           69                                 goto Err;
           70                         break;
           71                 case SunAuthError:
           72                         if(sunuint32pack(a, ea, &a, (x=MsgDenied, &x)) < 0
           73                         || sunuint32pack(a, ea, &a, (x=MsgAuthError, &x)) < 0)
           74                                 goto Err;
           75                         break;
           76                 default:
           77                         if(sunuint32pack(a, ea, &a, (x=MsgDenied, &x)) < 0)
           78                                 goto Err;
           79                         break;
           80                 }
           81 
           82                 switch(rpc->status){
           83                 case SunSuccess:
           84                         if(sunuint32pack(a, ea, &a, (x=MsgSuccess, &x)) < 0
           85                         || sunfixedopaquepack(a, ea, &a, rpc->data, rpc->ndata) < 0)
           86                                 goto Err;
           87                         break;
           88                 case SunRpcMismatch:
           89                 case SunProgMismatch:
           90                         if(sunuint32pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0
           91                         || sunuint32pack(a, ea, &a, &rpc->low) < 0
           92                         || sunuint32pack(a, ea, &a, &rpc->high) < 0)
           93                                 goto Err;
           94                         break;
           95                 default:
           96                         if(sunuint32pack(a, ea, &a, (x=rpc->status&0xFFFF, &x)) < 0)
           97                                 goto Err;
           98 
           99                         break;
          100                 }
          101         }
          102         *pa = a;
          103         return SunSuccess;
          104 
          105 Err:
          106         *pa = ea;
          107         return SunGarbageArgs;
          108 }
          109 
          110 uint
          111 sunrpcsize(SunRpc *rpc)
          112 {
          113         uint a;
          114 
          115         a = 4;
          116         if(rpc->iscall){
          117                 a += 5*4;
          118                 a += sunauthinfosize(&rpc->cred);
          119                 a += sunauthinfosize(&rpc->verf);
          120                 a += sunfixedopaquesize(rpc->ndata);
          121         }else{
          122                 a += 4;
          123                 switch(rpc->status&0xF0000){
          124                 case 0:
          125                 case SunAcceptError:
          126                         a += 4+sunauthinfosize(&rpc->verf);
          127                         break;
          128                 case SunAuthError:
          129                         a += 4+4;
          130                         break;
          131                 default:
          132                         a += 4;
          133                         break;
          134                 }
          135 
          136                 switch(rpc->status){
          137                 case SunSuccess:
          138                         a += 4+sunfixedopaquesize(rpc->ndata);
          139                         break;
          140                 case SunRpcMismatch:
          141                 case SunProgMismatch:
          142                         a += 3*4;
          143                         break;
          144                 default:
          145                         a += 4;
          146                 }
          147         }
          148         return a;
          149 }
          150 
          151 SunStatus
          152 sunrpcunpack(uchar *a, uchar *ea, uchar **pa, SunRpc *rpc)
          153 {
          154         u32int x;
          155 
          156         memset(rpc, 0, sizeof *rpc);
          157         if(sunuint32unpack(a, ea, &a, &rpc->xid) < 0
          158         || sunuint32unpack(a, ea, &a, &x) < 0)
          159                 goto Err;
          160 
          161         switch(x){
          162         default:
          163                 goto Err;
          164         case MsgCall:
          165                 rpc->iscall = 1;
          166                 if(sunuint32unpack(a, ea, &a, &x) < 0 || x != RpcVersion
          167                 || sunuint32unpack(a, ea, &a, &rpc->prog) < 0
          168                 || sunuint32unpack(a, ea, &a, &rpc->vers) < 0
          169                 || sunuint32unpack(a, ea, &a, &rpc->proc) < 0
          170                 || sunauthinfounpack(a, ea, &a, &rpc->cred) < 0
          171                 || sunauthinfounpack(a, ea, &a, &rpc->verf) < 0)
          172                         goto Err;
          173                 rpc->ndata = ea-a;
          174                 rpc->data = a;
          175                 a = ea;
          176                 break;
          177 
          178         case MsgReply:
          179                 rpc->iscall = 0;
          180                 if(sunuint32unpack(a, ea, &a, &x) < 0)
          181                         goto Err;
          182 fprint(2, "x %x\n", x);
          183                 switch(x){
          184                 default:
          185                         goto Err;
          186                 case MsgAccepted:
          187                         if(sunauthinfounpack(a, ea, &a, &rpc->verf) < 0
          188                         || sunuint32unpack(a, ea, &a, &x) < 0)
          189                                 goto Err;
          190                         switch(x){
          191                         case MsgSuccess:
          192                                 rpc->status = SunSuccess;
          193                                 rpc->ndata = ea-a;
          194                                 rpc->data = a;
          195                                 a = ea;
          196                                 break;
          197                         case MsgProgUnavail:
          198                         case MsgProcUnavail:
          199                         case MsgGarbageArgs:
          200                         case MsgSystemErr:
          201                                 rpc->status = SunAcceptError | x;
          202                                 break;
          203                         case MsgProgMismatch:
          204                                 rpc->status = SunAcceptError | x;
          205                                 if(sunuint32unpack(a, ea, &a, &rpc->low) < 0
          206                                 || sunuint32unpack(a, ea, &a, &rpc->high) < 0)
          207                                         goto Err;
          208                                 break;
          209                         }
          210                         break;
          211                 case MsgDenied:
          212                         if(sunuint32unpack(a, ea, &a, &x) < 0)
          213                                 goto Err;
          214 fprint(2, "xx %ux\n", x);
          215                         switch(x){
          216                         default:
          217                                 goto Err;
          218                         case MsgAuthError:
          219                                 if(sunuint32unpack(a, ea, &a, &x) < 0)
          220                                         goto Err;
          221                                 rpc->status = SunAuthError | x;
          222                                 break;
          223                         case MsgRpcMismatch:
          224                                 rpc->status = SunRejectError | x;
          225                                 if(sunuint32unpack(a, ea, &a, &rpc->low) < 0
          226                                 || sunuint32unpack(a, ea, &a, &rpc->high) < 0)
          227                                         goto Err;
          228                                 break;
          229                         }
          230                         break;
          231                 }
          232         }
          233         *pa = a;
          234         return SunSuccess;
          235 
          236 Err:
          237         *pa = ea;
          238         return SunGarbageArgs;
          239 }
          240 
          241 void
          242 sunrpcprint(Fmt *fmt, SunRpc *rpc)
          243 {
          244         fmtprint(fmt, "xid=%#ux", rpc->xid);
          245         if(rpc->iscall){
          246                 fmtprint(fmt, " prog %#ux vers %#ux proc %#ux [", rpc->prog, rpc->vers, rpc->proc);
          247                 sunauthinfoprint(fmt, &rpc->cred);
          248                 fmtprint(fmt, "] [");
          249                 sunauthinfoprint(fmt, &rpc->verf);
          250                 fmtprint(fmt, "]");
          251         }else{
          252                 fmtprint(fmt, " status %#ux [", rpc->status);
          253                 sunauthinfoprint(fmt, &rpc->verf);
          254                 fmtprint(fmt, "] low %#ux high %#ux", rpc->low, rpc->high);
          255         }
          256 }
          257 
          258 void
          259 sunauthinfoprint(Fmt *fmt, SunAuthInfo *ai)
          260 {
          261         switch(ai->flavor){
          262         case SunAuthNone:
          263                 fmtprint(fmt, "none");
          264                 break;
          265         case SunAuthShort:
          266                 fmtprint(fmt, "short");
          267                 break;
          268         case SunAuthSys:
          269                 fmtprint(fmt, "sys");
          270                 break;
          271         default:
          272                 fmtprint(fmt, "%#ux", ai->flavor);
          273                 break;
          274         }
          275 /*        if(ai->ndata) */
          276 /*                fmtprint(fmt, " %.*H", ai->ndata, ai->data); */
          277 }
          278 
          279 uint
          280 sunauthinfosize(SunAuthInfo *ai)
          281 {
          282         return 4 + sunvaropaquesize(ai->ndata);
          283 }
          284 
          285 int
          286 sunauthinfopack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
          287 {
          288         if(sunuint32pack(a, ea, &a, &ai->flavor) < 0
          289         || sunvaropaquepack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
          290                 goto Err;
          291         *pa = a;
          292         return 0;
          293 
          294 Err:
          295         *pa = ea;
          296         return -1;
          297 }
          298 
          299 int
          300 sunauthinfounpack(uchar *a, uchar *ea, uchar **pa, SunAuthInfo *ai)
          301 {
          302         if(sunuint32unpack(a, ea, &a, &ai->flavor) < 0
          303         || sunvaropaqueunpack(a, ea, &a, &ai->data, &ai->ndata, 400) < 0)
          304                 goto Err;
          305         *pa = a;
          306         return 0;
          307 
          308 Err:
          309         *pa = ea;
          310         return -1;
          311 }
          312 
          313 int
          314 sunenumpack(uchar *a, uchar *ea, uchar **pa, int *e)
          315 {
          316         u32int x;
          317 
          318         x = *e;
          319         return sunuint32pack(a, ea, pa, &x);
          320 }
          321 
          322 int
          323 sunuint1pack(uchar *a, uchar *ea, uchar **pa, u1int *u)
          324 {
          325         u32int x;
          326 
          327         x = *u;
          328         return sunuint32pack(a, ea, pa, &x);
          329 }
          330 
          331 int
          332 sunuint32pack(uchar *a, uchar *ea, uchar **pa, u32int *u)
          333 {
          334         u32int x;
          335 
          336         if(ea-a < 4)
          337                 goto Err;
          338 
          339         x = *u;
          340         *a++ = x>>24;
          341         *a++ = x>>16;
          342         *a++ = x>>8;
          343         *a++ = x;
          344         *pa = a;
          345         return 0;
          346 
          347 Err:
          348         *pa = ea;
          349         return -1;
          350 }
          351 
          352 int
          353 sunenumunpack(uchar *a, uchar *ea, uchar **pa, int *e)
          354 {
          355         u32int x;
          356         if(sunuint32unpack(a, ea, pa, &x) < 0)
          357                 return -1;
          358         *e = x;
          359         return 0;
          360 }
          361 
          362 int
          363 sunuint1unpack(uchar *a, uchar *ea, uchar **pa, u1int *u)
          364 {
          365         u32int x;
          366         if(sunuint32unpack(a, ea, pa, &x) < 0 || (x!=0 && x!=1)){
          367                 *pa = ea;
          368                 return -1;
          369         }
          370         *u = x;
          371         return 0;
          372 }
          373 
          374 int
          375 sunuint32unpack(uchar *a, uchar *ea, uchar **pa, u32int *u)
          376 {
          377         u32int x;
          378 
          379         if(ea-a < 4)
          380                 goto Err;
          381         x = *a++ << 24;
          382         x |= *a++ << 16;
          383         x |= *a++ << 8;
          384         x |= *a++;
          385         *pa = a;
          386         *u = x;
          387         return 0;
          388 
          389 Err:
          390         *pa = ea;
          391         return -1;
          392 }
          393 
          394 int
          395 sunuint64unpack(uchar *a, uchar *ea, uchar **pa, u64int *u)
          396 {
          397         u32int x, y;
          398 
          399         if(sunuint32unpack(a, ea, &a, &x) < 0
          400         || sunuint32unpack(a, ea, &a, &y) < 0)
          401                 goto Err;
          402         *u = ((uvlong)x<<32) | y;
          403         *pa = a;
          404         return 0;
          405 Err:
          406         *pa = ea;
          407         return -1;
          408 }
          409 
          410 int
          411 sunuint64pack(uchar *a, uchar *ea, uchar **pa, u64int *u)
          412 {
          413         u32int x, y;
          414 
          415         x = *u >> 32;
          416         y = *u;
          417         if(sunuint32pack(a, ea, &a, &x) < 0
          418         || sunuint32pack(a, ea, &a, &y) < 0)
          419                 goto Err;
          420         *pa = a;
          421         return 0;
          422 Err:
          423         *pa = ea;
          424         return -1;
          425 }
          426 
          427 uint
          428 sunstringsize(char *s)
          429 {
          430         return (4+strlen(s)+3) & ~3;
          431 }
          432 
          433 int
          434 sunstringunpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
          435 {
          436         uchar *dat;
          437         u32int n;
          438 
          439         if(sunvaropaqueunpack(a, ea, pa, &dat, &n, max) < 0)
          440                 goto Err;
          441         /* slide string down over length to make room for NUL */
          442         dat--;
          443         memmove(dat, dat+1, n);
          444         dat[n] = 0;
          445         *s = (char*)dat;
          446         return 0;
          447 Err:
          448         return -1;
          449 }
          450 
          451 int
          452 sunstringpack(uchar *a, uchar *ea, uchar **pa, char **s, u32int max)
          453 {
          454         u32int n;
          455 
          456         n = strlen(*s);
          457         return sunvaropaquepack(a, ea, pa, (uchar**)s, &n, max);
          458 }
          459 
          460 uint
          461 sunvaropaquesize(u32int n)
          462 {
          463         return (4+n+3) & ~3;
          464 }
          465 
          466 int
          467 sunvaropaquepack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
          468 {
          469         if(*ndat > max || sunuint32pack(a, ea, &a, ndat) < 0
          470         || sunfixedopaquepack(a, ea, &a, *dat, *ndat) < 0)
          471                 goto Err;
          472         *pa = a;
          473         return 0;
          474 
          475 Err:
          476         *pa = ea;
          477         return -1;
          478 }
          479 
          480 int
          481 sunvaropaqueunpack(uchar *a, uchar *ea, uchar **pa, uchar **dat, u32int *ndat, u32int max)
          482 {
          483         if(sunuint32unpack(a, ea, &a, ndat) < 0
          484         || *ndat > max)
          485                 goto Err;
          486         *dat = a;
          487         a += (*ndat+3)&~3;
          488         if(a > ea)
          489                 goto Err;
          490         *pa = a;
          491         return 0;
          492 
          493 Err:
          494         *pa = ea;
          495         return -1;
          496 }
          497 
          498 uint
          499 sunfixedopaquesize(u32int n)
          500 {
          501         return (n+3) & ~3;
          502 }
          503 
          504 int
          505 sunfixedopaquepack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
          506 {
          507         uint nn;
          508 
          509         nn = (n+3)&~3;
          510         if(a+nn > ea)
          511                 goto Err;
          512         memmove(a, dat, n);
          513         if(nn > n)
          514                 memset(a+n, 0, nn-n);
          515         a += nn;
          516         *pa = a;
          517         return 0;
          518 
          519 Err:
          520         *pa = ea;
          521         return -1;
          522 }
          523 
          524 int
          525 sunfixedopaqueunpack(uchar *a, uchar *ea, uchar **pa, uchar *dat, u32int n)
          526 {
          527         uint nn;
          528 
          529         nn = (n+3)&~3;
          530         if(a+nn > ea)
          531                 goto Err;
          532         memmove(dat, a, n);
          533         a += nn;
          534         *pa = a;
          535         return 0;
          536 
          537 Err:
          538         *pa = ea;
          539         return -1;
          540 }