| #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); |
| } |