rpc.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 }