#include <rpc/rpc.h> /* * Functions to compose RPC messages from XDR primitives */ bool_t xdr_call_msg_start( xdr_s_type *xdr, uint32 prog, uint32 ver, uint32 proc, opaque_auth *cred, opaque_auth *verf) { uint32 vers = RPC_MSG_VERSION; xdr->x_prog = prog; xdr->x_proc = proc; return (XDR_MSG_START(xdr, RPC_MSG_CALL) && XDR_SEND_UINT32(xdr, &vers) && XDR_SEND_UINT32(xdr, &prog) && XDR_SEND_UINT32(xdr, &ver) && XDR_SEND_UINT32(xdr, &proc) && xdr_send_auth(xdr, cred) && xdr_send_auth(xdr, verf)); } // xdr_call_msg_start bool_t xdr_reply_msg_start( xdr_s_type *xdr, opaque_auth *verf) { int32 stat = (int32) RPC_MSG_ACCEPTED; int32 accept = (int32) RPC_ACCEPT_SUCCESS; return(XDR_MSG_START(xdr, RPC_MSG_REPLY) && XDR_SEND_INT32(xdr, &stat) && xdr_send_auth(xdr, verf) && XDR_SEND_INT32(xdr, &accept)); } // xdr_reply_msg_start static bool_t xdr_send_accepted_reply_header( xdr_s_type *xdr, struct rpc_accepted_reply_header const *accreply) { if (!xdr_send_auth(xdr, &accreply->verf)) return FALSE; if (!XDR_SEND_ENUM(xdr, &accreply->stat)) return FALSE; switch ((*accreply).stat){ case RPC_PROG_MISMATCH: if (!XDR_SEND_UINT32(xdr, &accreply->u.versions.low)) return FALSE; if (!XDR_SEND_UINT32(xdr, &accreply->u.versions.high)) return FALSE; break; case RPC_ACCEPT_SUCCESS: case RPC_PROG_UNAVAIL: case RPC_PROC_UNAVAIL: case RPC_GARBAGE_ARGS: case RPC_SYSTEM_ERR: case RPC_PROG_LOCKED: // case ignored break; default: return FALSE; } return TRUE; } /* xdr_send_accepted_reply_header */ static bool_t xdr_send_denied_reply( xdr_s_type *xdr, struct rpc_denied_reply const *rejreply) { if (!XDR_SEND_ENUM(xdr, &rejreply->stat)) return FALSE; switch ((*rejreply).stat){ case RPC_MISMATCH: if (!XDR_SEND_UINT32(xdr, &rejreply->u.versions.low)) return FALSE; if (!XDR_SEND_UINT32(xdr, &rejreply->u.versions.high)) return FALSE; break; case RPC_AUTH_ERROR: if (!XDR_SEND_ENUM(xdr, &rejreply->u.why)) return FALSE; break; default: return FALSE; } return TRUE; } /* xdr_send_denied_reply */ bool_t xdr_send_reply_header( xdr_s_type *xdr, rpc_reply_header const *reply) { if (!XDR_SEND_ENUM(xdr, &reply->stat)) return FALSE; switch ((*reply).stat) { case RPC_MSG_ACCEPTED: if (!xdr_send_accepted_reply_header(xdr, &reply->u.ar)) return FALSE; break; case RPC_MSG_DENIED: if (!xdr_send_denied_reply(xdr, &reply->u.dr)) return FALSE; break; default: return FALSE; } return TRUE; } /* xdr_send_reply_header */ #include <stdio.h> bool_t xdr_send_auth(xdr_s_type *xdr, const opaque_auth *auth) { #define FAILIF(x) do { if (x) return FALSE; } while(0) switch (sizeof(auth->oa_flavor)) { case 1: FAILIF(!XDR_SEND_INT8(xdr, (int8_t *)&auth->oa_flavor)); break; case 2: FAILIF(!XDR_SEND_INT16(xdr, (int16_t *)&auth->oa_flavor)); break; case 4: FAILIF(!XDR_SEND_INT32(xdr, (int32_t *)&auth->oa_flavor)); break; default: return FALSE; } return (XDR_SEND_UINT(xdr, (uint32_t *)&auth->oa_length) && (auth->oa_length == 0 || XDR_SEND_BYTES(xdr, (uint8_t *)auth->oa_base, auth->oa_length))); } void xdr_free(xdrproc_t proc, char *objp) { XDR x; x.x_op = XDR_FREE; (*proc)(&x, objp); }