1/* $OpenBSD: clnt.h,v 1.14 2022/12/27 07:44:56 jmc Exp $ */
2/* $NetBSD: clnt.h,v 1.6 1995/04/29 05:27:58 cgd Exp $ */
3
4/*
5 * Copyright (c) 2010, Oracle America, Inc.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 * * Neither the name of the "Oracle America, Inc." nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
28 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 * from: @(#)clnt.h 1.31 88/02/08 SMI
35 * @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC
36 */
37
38/*
39 * clnt.h - Client side remote procedure call interface.
40 */
41
42#ifndef _RPC_CLNT_H_
43#define _RPC_CLNT_H_
44#include <sys/cdefs.h>
45
46/*
47 * Rpc calls return an enum clnt_stat. This should be looked at more,
48 * since each implementation is required to live with this (implementation
49 * independent) list of errors.
50 */
51enum clnt_stat {
52 RPC_SUCCESS=0, /* call succeeded */
53 /*
54 * local errors
55 */
56 RPC_CANTENCODEARGS=1, /* can't encode arguments */
57 RPC_CANTDECODERES=2, /* can't decode results */
58 RPC_CANTSEND=3, /* failure in sending call */
59 RPC_CANTRECV=4, /* failure in receiving result */
60 RPC_TIMEDOUT=5, /* call timed out */
61 /*
62 * remote errors
63 */
64 RPC_VERSMISMATCH=6, /* rpc versions not compatible */
65 RPC_AUTHERROR=7, /* authentication error */
66 RPC_PROGUNAVAIL=8, /* program not available */
67 RPC_PROGVERSMISMATCH=9, /* program version mismatched */
68 RPC_PROCUNAVAIL=10, /* procedure unavailable */
69 RPC_CANTDECODEARGS=11, /* decode arguments error */
70 RPC_SYSTEMERROR=12, /* generic "other problem" */
71
72 /*
73 * callrpc & clnt_create errors
74 */
75 RPC_UNKNOWNHOST=13, /* unknown host name */
76 RPC_UNKNOWNPROTO=17, /* unknown protocol */
77
78 /*
79 * _ create errors
80 */
81 RPC_PMAPFAILURE=14, /* the pmapper failed in its call */
82 RPC_PROGNOTREGISTERED=15, /* remote program is not registered */
83 /*
84 * unspecified error
85 */
86 RPC_FAILED=16
87};
88
89
90/*
91 * Error info.
92 */
93struct rpc_err {
94 enum clnt_stat re_status;
95 union {
96 int RE_errno; /* related system error */
97 enum auth_stat RE_why; /* why the auth error occurred */
98 struct {
99 u_int32_t low; /* lowest version supported */
100 u_int32_t high; /* highest version supported */
101 } RE_vers;
102 struct { /* maybe meaningful if RPC_FAILED */
103 int32_t s1;
104 int32_t s2;
105 } RE_lb; /* life boot & debugging only */
106 } ru;
107#define re_errno ru.RE_errno
108#define re_why ru.RE_why
109#define re_vers ru.RE_vers
110#define re_lb ru.RE_lb
111};
112
113
114/*
115 * Client rpc handle.
116 * Created by individual implementations, see e.g. rpc_udp.c.
117 * Client is responsible for initializing auth, see e.g. auth_none.c.
118 */
119typedef struct __rpc_client {
120 AUTH *cl_auth; /* authenticator */
121 const struct clnt_ops {
122 /* call remote procedure */
123 enum clnt_stat (*cl_call)(struct __rpc_client *,
124 unsigned long, xdrproc_t, caddr_t,
125 xdrproc_t, caddr_t, struct timeval);
126 /* abort a call */
127 void (*cl_abort)(struct __rpc_client *);
128 /* get specific error code */
129 void (*cl_geterr)(struct __rpc_client *,
130 struct rpc_err *);
131 /* frees results */
132 bool_t (*cl_freeres)(struct __rpc_client *,
133 xdrproc_t, caddr_t);
134 /* destroy this structure */
135 void (*cl_destroy)(struct __rpc_client *);
136 /* the ioctl() of rpc */
137 bool_t (*cl_control)(struct __rpc_client *,
138 unsigned int, void *);
139 } *cl_ops;
140 caddr_t cl_private; /* private stuff */
141} CLIENT;
142
143
144/*
145 * client side rpc interface ops
146 *
147 * Parameter types are:
148 *
149 */
150
151/*
152 * enum clnt_stat
153 * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
154 * CLIENT *rh;
155 * unsigned long proc;
156 * xdrproc_t xargs;
157 * caddr_t argsp;
158 * xdrproc_t xres;
159 * caddr_t resp;
160 * struct timeval timeout;
161 */
162#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
163 ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \
164 xres, (caddr_t)resp, secs))
165#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
166 ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \
167 xres, (caddr_t)resp, secs))
168
169/*
170 * void
171 * CLNT_ABORT(rh);
172 * CLIENT *rh;
173 */
174#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh))
175#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh))
176
177/*
178 * struct rpc_err
179 * CLNT_GETERR(rh);
180 * CLIENT *rh;
181 */
182#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
183#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
184
185
186/*
187 * bool_t
188 * CLNT_FREERES(rh, xres, resp);
189 * CLIENT *rh;
190 * xdrproc_t xres;
191 * caddr_t resp;
192 */
193#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
194#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
195
196/*
197 * bool_t
198 * CLNT_CONTROL(cl, request, info)
199 * CLIENT *cl;
200 * unsigned int request;
201 * char *info;
202 */
203#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
204#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
205
206/*
207 * control operations that apply to both udp and tcp transports
208 */
209#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
210#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
211#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
212/*
213 * udp only control operations
214 */
215#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */
216#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */
217#define CLSET_CONNECTED 6 /* socket is connected, so use send() */
218
219/*
220 * void
221 * CLNT_DESTROY(rh);
222 * CLIENT *rh;
223 */
224#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
225#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
226
227
228/*
229 * RPCTEST is a test program which is accessible on every rpc
230 * transport/port. It is used for testing, performance evaluation,
231 * and network administration.
232 */
233
234#define RPCTEST_PROGRAM ((unsigned long)1)
235#define RPCTEST_VERSION ((unsigned long)1)
236#define RPCTEST_NULL_PROC ((unsigned long)2)
237#define RPCTEST_NULL_BATCH_PROC ((unsigned long)3)
238
239/*
240 * By convention, procedure 0 takes null arguments and returns them
241 */
242
243#define NULLPROC ((unsigned int)0)
244
245/*
246 * Below are the client handle creation routines for the various
247 * implementations of client side rpc. They can return NULL if a
248 * creation failure occurs.
249 */
250
251/*
252 * Memory based rpc (for speed check and testing)
253 * CLIENT *
254 * clntraw_create(prog, vers)
255 * unsigned long prog;
256 * unsigned long vers;
257 */
258__BEGIN_DECLS
259extern CLIENT *clntraw_create(unsigned long, unsigned long);
260__END_DECLS
261
262
263/*
264 * Generic client creation routine. Supported protocols are "udp" and "tcp"
265 * CLIENT *
266 * clnt_create(host, prog, vers, prot);
267 * char *host; -- hostname
268 * unsigned long prog; -- program number
269 * unsigned long vers; -- version number
270 * char *prot; -- protocol
271 */
272__BEGIN_DECLS
273extern CLIENT *clnt_create(char *, unsigned long, unsigned long, char *);
274__END_DECLS
275
276
277/*
278 * TCP based rpc
279 * CLIENT *
280 * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
281 * struct sockaddr_in *raddr;
282 * unsigned long prog;
283 * unsigned long version;
284 * int *sockp;
285 * unsigned int sendsz;
286 * unsigned int recvsz;
287 */
288__BEGIN_DECLS
289extern CLIENT *clnttcp_create(struct sockaddr_in *, unsigned long,
290 unsigned long, int *, unsigned int, unsigned int);
291__END_DECLS
292
293
294/*
295 * UDP based rpc.
296 * CLIENT *
297 * clntudp_create(raddr, program, version, wait, sockp)
298 * struct sockaddr_in *raddr;
299 * unsigned long program;
300 * unsigned long version;
301 * struct timeval wait;
302 * int *sockp;
303 *
304 * Same as above, but you specify max packet sizes.
305 * CLIENT *
306 * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
307 * struct sockaddr_in *raddr;
308 * unsigned long program;
309 * unsigned long version;
310 * struct timeval wait;
311 * int *sockp;
312 * unsigned int sendsz;
313 * unsigned int recvsz;
314 */
315__BEGIN_DECLS
316extern CLIENT *clntudp_create(struct sockaddr_in *, unsigned long,
317 unsigned long, struct timeval, int *);
318extern CLIENT *clntudp_bufcreate(struct sockaddr_in *, unsigned long,
319 unsigned long, struct timeval, int *, unsigned int, unsigned int);
320__END_DECLS
321
322
323/*
324 * Print why creation failed
325 */
326__BEGIN_DECLS
327extern void clnt_pcreateerror(char *); /* stderr */
328extern char *clnt_spcreateerror(char *); /* string */
329__END_DECLS
330
331/*
332 * Like clnt_perror(), but is more verbose in its output
333 */
334__BEGIN_DECLS
335extern void clnt_perrno(enum clnt_stat); /* stderr */
336extern char *clnt_sperrno(enum clnt_stat); /* string */
337__END_DECLS
338
339/*
340 * Print an English error message, given the client error code
341 */
342__BEGIN_DECLS
343extern void clnt_perror(CLIENT *, char *); /* stderr */
344extern char *clnt_sperror(CLIENT *, char *); /* string */
345__END_DECLS
346
347
348/*
349 * If a creation fails, the following allows the user to figure out why.
350 */
351struct rpc_createerr {
352 enum clnt_stat cf_stat;
353 struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
354};
355
356extern struct rpc_createerr rpc_createerr;
357
358
359#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
360#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
361
362#endif /* !_RPC_CLNT_H */