1 #include <rpc/rpc.h>
2
3 /*
4 * Functions to compose RPC messages from XDR primitives
5 */
6
xdr_call_msg_start(xdr_s_type * xdr,uint32 prog,uint32 ver,uint32 proc,opaque_auth * cred,opaque_auth * verf)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
xdr_reply_msg_start(xdr_s_type * xdr,opaque_auth * verf)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
xdr_send_accepted_reply_header(xdr_s_type * xdr,struct rpc_accepted_reply_header const * accreply)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
xdr_send_denied_reply(xdr_s_type * xdr,struct rpc_denied_reply const * rejreply)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
xdr_send_reply_header(xdr_s_type * xdr,rpc_reply_header const * reply)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
xdr_send_auth(xdr_s_type * xdr,const opaque_auth * auth)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
xdr_free(xdrproc_t proc,char * objp)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