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