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 verion supported */ 110 u_long high; /* highest verion 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