source: rtems/cpukit/librpc/src/rpc/rpc_prot.c @ b6e23ea7

4.104.114.95
Last change on this file since b6e23ea7 was b6e23ea7, checked in by Ralf Corsepius <ralf.corsepius@…>, on 08/01/08 at 06:19:45

Misc. ansifications.

  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*
2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part.  Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
8 *
9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12 *
13 * Sun RPC is provided with no support and without any obligation on the
14 * part of Sun Microsystems, Inc. to assist in its use, correction,
15 * modification or enhancement.
16 *
17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19 * OR ANY PART THEREOF.
20 *
21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22 * or profits or other special, indirect and consequential damages, even if
23 * Sun has been advised of the possibility of such damages.
24 *
25 * Sun Microsystems, Inc.
26 * 2550 Garcia Avenue
27 * Mountain View, California  94043
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/
32/*static char *sccsid = "from: @(#)rpc_prot.c   2.3 88/08/07 4.0 RPCSRC";*/
33static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_prot.c,v 1.8 1999/08/28 00:00:46 peter Exp $";
34#endif
35
36/*
37 * rpc_prot.c
38 *
39 * Copyright (C) 1984, Sun Microsystems, Inc.
40 *
41 * This set of routines implements the rpc message definition,
42 * its serializer and some common rpc utility routines.
43 * The routines are meant for various implementations of rpc -
44 * they are NOT for the rpc client or rpc service implementations!
45 * Because authentication stuff is easy and is part of rpc, the opaque
46 * routines are also in this program.
47 */
48
49#include <sys/param.h>
50
51#include <rpc/rpc.h>
52
53static void accepted(enum accept_stat, struct rpc_err *);
54static void rejected(enum reject_stat, struct rpc_err *);
55
56/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
57
58extern struct opaque_auth _null_auth;
59
60/*
61 * XDR an opaque authentication struct
62 * (see auth.h)
63 */
64bool_t
65xdr_opaque_auth(
66        XDR *xdrs,
67        struct opaque_auth *ap)
68{
69
70        if (xdr_enum(xdrs, &(ap->oa_flavor)))
71                return (xdr_bytes(xdrs, &ap->oa_base,
72                        &ap->oa_length, MAX_AUTH_BYTES));
73        return (FALSE);
74}
75
76/*
77 * XDR a DES block
78 */
79bool_t
80xdr_des_block(
81        XDR *xdrs,
82        des_block *blkp)
83{
84        return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
85}
86
87/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
88
89/*
90 * XDR the MSG_ACCEPTED part of a reply message union
91 */
92bool_t
93xdr_accepted_reply(
94        XDR *xdrs,
95        struct accepted_reply *ar)
96{
97
98        /* personalized union, rather than calling xdr_union */
99        if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
100                return (FALSE);
101        if (! xdr_enum(xdrs, (enum_t *)(void *)&(ar->ar_stat)))
102                return (FALSE);
103        switch (ar->ar_stat) {
104
105        case SUCCESS:
106                return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
107
108        case PROG_MISMATCH:
109                if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
110                        return (FALSE);
111                return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
112
113        case GARBAGE_ARGS:
114        case SYSTEM_ERR:
115        case PROC_UNAVAIL:
116        case PROG_UNAVAIL:
117/*      default: */
118                break;
119        }
120        return (TRUE);  /* TRUE => open ended set of problems */
121}
122
123/*
124 * XDR the MSG_DENIED part of a reply message union
125 */
126bool_t
127xdr_rejected_reply(
128        XDR *xdrs,
129        struct rejected_reply *rr )
130{
131
132        /* personalized union, rather than calling xdr_union */
133        if (! xdr_enum(xdrs, (enum_t *)(void *)&(rr->rj_stat)))
134                return (FALSE);
135        switch (rr->rj_stat) {
136
137        case RPC_MISMATCH:
138                if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low)))
139                        return (FALSE);
140                return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high)));
141
142        case AUTH_ERROR:
143                return (xdr_enum(xdrs, (enum_t *)(void *)&(rr->rj_why)));
144        }
145        return (FALSE);
146}
147
148static const struct xdr_discrim reply_dscrm[3] = {
149        { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply },
150        { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply },
151        { __dontcare__, NULL_xdrproc_t } };
152
153/*
154 * XDR a reply message
155 */
156bool_t
157xdr_replymsg(
158        XDR *xdrs,
159        struct rpc_msg *rmsg)
160{
161        if (
162            xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
163            xdr_enum(xdrs, (enum_t *)(void *)&(rmsg->rm_direction)) &&
164            (rmsg->rm_direction == REPLY) )
165                return (xdr_union(xdrs, (enum_t *)(void *)&(rmsg->rm_reply.rp_stat),
166                   (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
167        return (FALSE);
168}
169
170
171/*
172 * Serializes the "static part" of a call message header.
173 * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
174 * The rm_xid is not really static, but the user can easily munge on the fly.
175 */
176bool_t
177xdr_callhdr(
178        XDR *xdrs,
179        struct rpc_msg *cmsg)
180{
181
182        cmsg->rm_direction = CALL;
183        cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
184        if (
185            (xdrs->x_op == XDR_ENCODE) &&
186            xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
187            xdr_enum(xdrs, (enum_t *)(void *)&(cmsg->rm_direction)) &&
188            xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
189            xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
190            return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
191        return (FALSE);
192}
193
194/* ************************** Client utility routine ************* */
195
196static void
197accepted(
198        enum accept_stat acpt_stat,
199        struct rpc_err *error)
200{
201
202        switch (acpt_stat) {
203
204        case PROG_UNAVAIL:
205                error->re_status = RPC_PROGUNAVAIL;
206                return;
207
208        case PROG_MISMATCH:
209                error->re_status = RPC_PROGVERSMISMATCH;
210                return;
211
212        case PROC_UNAVAIL:
213                error->re_status = RPC_PROCUNAVAIL;
214                return;
215
216        case GARBAGE_ARGS:
217                error->re_status = RPC_CANTDECODEARGS;
218                return;
219
220        case SYSTEM_ERR:
221                error->re_status = RPC_SYSTEMERROR;
222                return;
223
224        case SUCCESS:
225                error->re_status = RPC_SUCCESS;
226                return;
227        }
228        /* something's wrong, but we don't know what ... */
229        error->re_status = RPC_FAILED;
230        error->re_lb.s1 = (long)MSG_ACCEPTED;
231        error->re_lb.s2 = (long)acpt_stat;
232}
233
234static void
235rejected(
236        enum reject_stat rjct_stat,
237        struct rpc_err *error)
238{
239
240        switch (rjct_stat) {
241
242        case RPC_VERSMISMATCH:
243                error->re_status = RPC_VERSMISMATCH;
244                return;
245
246        case AUTH_ERROR:
247                error->re_status = RPC_AUTHERROR;
248                return;
249        default:
250                break;
251        }
252        /* something's wrong, but we don't know what ... */
253        error->re_status = RPC_FAILED;
254        error->re_lb.s1 = (long)MSG_DENIED;
255        error->re_lb.s2 = (long)rjct_stat;
256}
257
258/*
259 * given a reply message, fills in the error
260 */
261void
262_seterr_reply(
263        struct rpc_msg *msg,
264        struct rpc_err *error)
265{
266
267        /* optimized for normal, SUCCESSful case */
268        switch (msg->rm_reply.rp_stat) {
269
270        case MSG_ACCEPTED:
271                if (msg->acpted_rply.ar_stat == SUCCESS) {
272                        error->re_status = RPC_SUCCESS;
273                        return;
274                }
275                accepted(msg->acpted_rply.ar_stat, error);
276                break;
277
278        case MSG_DENIED:
279                rejected(msg->rjcted_rply.rj_stat, error);
280                break;
281
282        default:
283                error->re_status = RPC_FAILED;
284                error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
285                break;
286        }
287        switch (error->re_status) {
288
289        case RPC_VERSMISMATCH:
290                error->re_vers.low = msg->rjcted_rply.rj_vers.low;
291                error->re_vers.high = msg->rjcted_rply.rj_vers.high;
292                break;
293
294        case RPC_AUTHERROR:
295                error->re_why = msg->rjcted_rply.rj_why;
296                break;
297
298        case RPC_PROGVERSMISMATCH:
299                error->re_vers.low = msg->acpted_rply.ar_vers.low;
300                error->re_vers.high = msg->acpted_rply.ar_vers.high;
301                break;
302
303        case RPC_FAILED:
304        case RPC_SUCCESS:
305        case RPC_PROGNOTREGISTERED:
306        case RPC_PMAPFAILURE:
307        case RPC_UNKNOWNPROTO:
308        case RPC_UNKNOWNHOST:
309        case RPC_SYSTEMERROR:
310        case RPC_CANTDECODEARGS:
311        case RPC_PROCUNAVAIL:
312        case RPC_PROGUNAVAIL:
313        case RPC_TIMEDOUT:
314        case RPC_CANTRECV:
315        case RPC_CANTSEND:
316        case RPC_CANTDECODERES:
317        case RPC_CANTENCODEARGS:
318        default:
319                break;
320        }
321}
Note: See TracBrowser for help on using the repository browser.