1 #include <rpc/rpc.h> 2 3 /* 4 * Functions to compose RPC messages from XDR primitives 5 */ 6 7 bool_t xdr_call_msg_start( 8 xdr_s_type *xdr, 9 uint32 prog, 10 uint32 ver, 11 uint32 proc, 12 opaque_auth *cred, 13 opaque_auth *verf) 14 { 15 uint32 vers = RPC_MSG_VERSION; 16 17 xdr->x_prog = prog; 18 xdr->x_proc = proc; 19 20 return (XDR_MSG_START(xdr, RPC_MSG_CALL) && 21 XDR_SEND_UINT32(xdr, &vers) && 22 XDR_SEND_UINT32(xdr, &prog) && 23 XDR_SEND_UINT32(xdr, &ver) && 24 XDR_SEND_UINT32(xdr, &proc) && 25 xdr_send_auth(xdr, cred) && 26 xdr_send_auth(xdr, verf)); 27 } // xdr_call_msg_start 28 29 bool_t xdr_reply_msg_start( 30 xdr_s_type *xdr, 31 opaque_auth *verf) 32 { 33 int32 stat = (int32) RPC_MSG_ACCEPTED; 34 int32 accept = (int32) RPC_ACCEPT_SUCCESS; 35 36 return(XDR_MSG_START(xdr, RPC_MSG_REPLY) && 37 XDR_SEND_INT32(xdr, &stat) && 38 xdr_send_auth(xdr, verf) && 39 XDR_SEND_INT32(xdr, &accept)); 40 } // xdr_reply_msg_start 41 42 static bool_t xdr_send_accepted_reply_header( 43 xdr_s_type *xdr, 44 struct rpc_accepted_reply_header const *accreply) 45 { 46 if (!xdr_send_auth(xdr, &accreply->verf)) 47 return FALSE; 48 49 if (!XDR_SEND_ENUM(xdr, &accreply->stat)) 50 return FALSE; 51 52 switch ((*accreply).stat){ 53 case RPC_PROG_MISMATCH: 54 if (!XDR_SEND_UINT32(xdr, &accreply->u.versions.low)) 55 return FALSE; 56 57 if (!XDR_SEND_UINT32(xdr, &accreply->u.versions.high)) 58 return FALSE; 59 break; 60 61 case RPC_ACCEPT_SUCCESS: 62 case RPC_PROG_UNAVAIL: 63 case RPC_PROC_UNAVAIL: 64 case RPC_GARBAGE_ARGS: 65 case RPC_SYSTEM_ERR: 66 case RPC_PROG_LOCKED: 67 // case ignored 68 break; 69 70 default: 71 return FALSE; 72 } 73 74 return TRUE; 75 } /* xdr_send_accepted_reply_header */ 76 77 static bool_t xdr_send_denied_reply( 78 xdr_s_type *xdr, 79 struct rpc_denied_reply const *rejreply) 80 { 81 if (!XDR_SEND_ENUM(xdr, &rejreply->stat)) 82 return FALSE; 83 84 switch ((*rejreply).stat){ 85 case RPC_MISMATCH: 86 if (!XDR_SEND_UINT32(xdr, &rejreply->u.versions.low)) 87 return FALSE; 88 if (!XDR_SEND_UINT32(xdr, &rejreply->u.versions.high)) 89 return FALSE; 90 break; 91 case RPC_AUTH_ERROR: 92 if (!XDR_SEND_ENUM(xdr, &rejreply->u.why)) 93 return FALSE; 94 break; 95 default: 96 return FALSE; 97 } 98 99 return TRUE; 100 } /* xdr_send_denied_reply */ 101 102 bool_t xdr_send_reply_header( 103 xdr_s_type *xdr, 104 rpc_reply_header const *reply) 105 { 106 if (!XDR_SEND_ENUM(xdr, &reply->stat)) 107 return FALSE; 108 109 switch ((*reply).stat) { 110 case RPC_MSG_ACCEPTED: 111 if (!xdr_send_accepted_reply_header(xdr, &reply->u.ar)) 112 return FALSE; 113 break; 114 case RPC_MSG_DENIED: 115 if (!xdr_send_denied_reply(xdr, &reply->u.dr)) 116 return FALSE; 117 break; 118 default: 119 return FALSE; 120 } 121 122 return TRUE; 123 } /* xdr_send_reply_header */ 124 125 #include <stdio.h> 126 127 bool_t 128 xdr_send_auth(xdr_s_type *xdr, const opaque_auth *auth) 129 { 130 #define FAILIF(x) do { if (x) return FALSE; } while(0) 131 132 switch (sizeof(auth->oa_flavor)) { 133 case 1: 134 FAILIF(!XDR_SEND_INT8(xdr, (int8_t *)&auth->oa_flavor)); 135 break; 136 case 2: 137 FAILIF(!XDR_SEND_INT16(xdr, (int16_t *)&auth->oa_flavor)); 138 break; 139 case 4: 140 FAILIF(!XDR_SEND_INT32(xdr, (int32_t *)&auth->oa_flavor)); 141 break; 142 default: 143 return FALSE; 144 } 145 146 return (XDR_SEND_UINT(xdr, (uint32_t *)&auth->oa_length) && 147 (auth->oa_length == 0 || 148 XDR_SEND_BYTES(xdr, (uint8_t *)auth->oa_base, auth->oa_length))); 149 } 150 151 void xdr_free(xdrproc_t proc, char *objp) 152 { 153 XDR x; 154 x.x_op = XDR_FREE; 155 (*proc)(&x, objp); 156 } 157