174462Salfred/* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */ 274462Salfred 3261046Smav/*- 4261046Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261046Smav * All rights reserved. 68858Srgrimes * 7261046Smav * Redistribution and use in source and binary forms, with or without 8261046Smav * modification, are permitted provided that the following conditions are met: 9261046Smav * - Redistributions of source code must retain the above copyright notice, 10261046Smav * this list of conditions and the following disclaimer. 11261046Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261046Smav * this list of conditions and the following disclaimer in the documentation 13261046Smav * and/or other materials provided with the distribution. 14261046Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261046Smav * contributors may be used to endorse or promote products derived 16261046Smav * from this software without specific prior written permission. 178858Srgrimes * 18261046Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261046Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261046Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261046Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261046Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261046Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261046Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261046Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261046Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261046Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261046Smav * POSSIBILITY OF SUCH DAMAGE. 298858Srgrimes * 3074462Salfred * from: @(#)svc.h 1.35 88/12/17 SMI 3174462Salfred * from: @(#)svc.h 1.27 94/04/25 SMI 3250473Speter * $FreeBSD$ 331839Swollman */ 341839Swollman 351839Swollman/* 361839Swollman * svc.h, Server-side remote procedure call interface. 371839Swollman * 3874462Salfred * Copyright (C) 1986-1993 by Sun Microsystems, Inc. 391839Swollman */ 401839Swollman 411903Swollman#ifndef _RPC_SVC_H 421903Swollman#define _RPC_SVC_H 431903Swollman#include <sys/cdefs.h> 441839Swollman 451839Swollman/* 461839Swollman * This interface must manage two items concerning remote procedure calling: 471839Swollman * 481839Swollman * 1) An arbitrary number of transport connections upon which rpc requests 491839Swollman * are received. The two most notable transports are TCP and UDP; they are 501839Swollman * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; 511839Swollman * they in turn call xprt_register and xprt_unregister. 521839Swollman * 531839Swollman * 2) An arbitrary number of locally registered services. Services are 541839Swollman * described by the following four data: program number, version number, 551839Swollman * "service dispatch" function, a transport handle, and a boolean that 561839Swollman * indicates whether or not the exported program should be registered with a 571839Swollman * local binder service; if true the program's number and version and the 581839Swollman * port number from the transport handle are registered with the binder. 591839Swollman * These data are registered with the rpc svc system via svc_register. 601839Swollman * 611839Swollman * A service's dispatch function is called whenever an rpc request comes in 621839Swollman * on a transport. The request's program and version numbers must match 631839Swollman * those of the registered service. The dispatch function is passed two 641839Swollman * parameters, struct svc_req * and SVCXPRT *, defined below. 651839Swollman */ 661839Swollman 6774462Salfred/* 6874462Salfred * Service control requests 6974462Salfred */ 7074462Salfred#define SVCGET_VERSQUIET 1 7174462Salfred#define SVCSET_VERSQUIET 2 72109359Smbr#define SVCGET_CONNMAXREC 3 73109359Smbr#define SVCSET_CONNMAXREC 4 7474462Salfred 75109359Smbr/* 76109359Smbr * Operations for rpc_control(). 77109359Smbr */ 78109359Smbr#define RPC_SVC_CONNMAXREC_SET 0 /* set max rec size, enable nonblock */ 79109359Smbr#define RPC_SVC_CONNMAXREC_GET 1 8074462Salfred 811839Swollmanenum xprt_stat { 821839Swollman XPRT_DIED, 831839Swollman XPRT_MOREREQS, 841839Swollman XPRT_IDLE 851839Swollman}; 861839Swollman 871839Swollman/* 881839Swollman * Server side transport handle 891839Swollman */ 9021059Spetertypedef struct __rpc_svcxprt { 9174462Salfred int xp_fd; 921839Swollman u_short xp_port; /* associated port number */ 9374462Salfred const struct xp_ops { 9421059Speter /* receive incoming requests */ 9593032Simp bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *); 9621059Speter /* get transport status */ 9793032Simp enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *); 9821059Speter /* get arguments */ 9993032Simp bool_t (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t, 10095658Sdes void *); 10121059Speter /* send reply */ 10293032Simp bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *); 10321059Speter /* free mem allocated for args */ 10493032Simp bool_t (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t, 10595658Sdes void *); 10621059Speter /* destroy this struct */ 10793032Simp void (*xp_destroy)(struct __rpc_svcxprt *); 1081839Swollman } *xp_ops; 1091839Swollman int xp_addrlen; /* length of remote address */ 11074462Salfred struct sockaddr_in xp_raddr; /* remote addr. (backward ABI compat) */ 11174462Salfred /* XXX - fvdl stick this here for ABI backward compat reasons */ 11274462Salfred const struct xp_ops2 { 11374462Salfred /* catch-all function */ 11493032Simp bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, 11593032Simp void *); 11674462Salfred } *xp_ops2; 11774462Salfred char *xp_tp; /* transport provider device name */ 11874462Salfred char *xp_netid; /* network token */ 11974462Salfred struct netbuf xp_ltaddr; /* local transport address */ 12074462Salfred struct netbuf xp_rtaddr; /* remote transport address */ 1211839Swollman struct opaque_auth xp_verf; /* raw response verifier */ 12274462Salfred void *xp_p1; /* private: for use by svc ops */ 12374462Salfred void *xp_p2; /* private: for use by svc ops */ 12474462Salfred void *xp_p3; /* private: for use by svc lib */ 12574462Salfred int xp_type; /* transport type */ 1261839Swollman} SVCXPRT; 1271839Swollman 1281839Swollman/* 129181344Sdfr * Interface to server-side authentication flavors. 130181344Sdfr */ 131181344Sdfrtypedef struct __rpc_svcauth { 132181344Sdfr struct svc_auth_ops { 133181344Sdfr int (*svc_ah_wrap)(struct __rpc_svcauth *, XDR *, 134181344Sdfr xdrproc_t, caddr_t); 135181344Sdfr int (*svc_ah_unwrap)(struct __rpc_svcauth *, XDR *, 136181344Sdfr xdrproc_t, caddr_t); 137181344Sdfr } *svc_ah_ops; 138181344Sdfr void *svc_ah_private; 139181344Sdfr} SVCAUTH; 140181344Sdfr 141181344Sdfr/* 142181344Sdfr * Server transport extensions (accessed via xp_p3). 143181344Sdfr */ 144181344Sdfrtypedef struct __rpc_svcxprt_ext { 145181344Sdfr int xp_flags; /* versquiet */ 146181344Sdfr SVCAUTH xp_auth; /* interface to auth methods */ 147181344Sdfr} SVCXPRT_EXT; 148181344Sdfr 149181344Sdfr/* 15074462Salfred * Service request 15174462Salfred */ 15274462Salfredstruct svc_req { 15374462Salfred u_int32_t rq_prog; /* service program number */ 15474462Salfred u_int32_t rq_vers; /* service protocol version */ 15574462Salfred u_int32_t rq_proc; /* the desired procedure */ 15674462Salfred struct opaque_auth rq_cred; /* raw creds from the wire */ 15774462Salfred void *rq_clntcred; /* read only cooked cred */ 15874462Salfred SVCXPRT *rq_xprt; /* associated transport */ 15974462Salfred}; 16074462Salfred 16174462Salfred/* 1621839Swollman * Approved way of getting address of caller 1631839Swollman */ 16474462Salfred#define svc_getrpccaller(x) (&(x)->xp_rtaddr) 1651839Swollman 1661839Swollman/* 1671839Swollman * Operations defined on an SVCXPRT handle 1681839Swollman * 1691839Swollman * SVCXPRT *xprt; 1701839Swollman * struct rpc_msg *msg; 1711839Swollman * xdrproc_t xargs; 17295658Sdes * void * argsp; 1731839Swollman */ 1741839Swollman#define SVC_RECV(xprt, msg) \ 1751839Swollman (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 1761839Swollman#define svc_recv(xprt, msg) \ 1771839Swollman (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 1781839Swollman 1791839Swollman#define SVC_STAT(xprt) \ 1801839Swollman (*(xprt)->xp_ops->xp_stat)(xprt) 1811839Swollman#define svc_stat(xprt) \ 1821839Swollman (*(xprt)->xp_ops->xp_stat)(xprt) 1831839Swollman 1841839Swollman#define SVC_GETARGS(xprt, xargs, argsp) \ 1851839Swollman (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 1861839Swollman#define svc_getargs(xprt, xargs, argsp) \ 1871839Swollman (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 1881839Swollman 1891839Swollman#define SVC_REPLY(xprt, msg) \ 1901839Swollman (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 1911839Swollman#define svc_reply(xprt, msg) \ 1921839Swollman (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 1931839Swollman 1941839Swollman#define SVC_FREEARGS(xprt, xargs, argsp) \ 1951839Swollman (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 1961839Swollman#define svc_freeargs(xprt, xargs, argsp) \ 1971839Swollman (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 1981839Swollman 1991839Swollman#define SVC_DESTROY(xprt) \ 2001839Swollman (*(xprt)->xp_ops->xp_destroy)(xprt) 2011839Swollman#define svc_destroy(xprt) \ 2021839Swollman (*(xprt)->xp_ops->xp_destroy)(xprt) 2031839Swollman 20474462Salfred#define SVC_CONTROL(xprt, rq, in) \ 20574462Salfred (*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in)) 2061839Swollman 207181344Sdfr#define SVC_EXT(xprt) \ 208181344Sdfr ((SVCXPRT_EXT *) xprt->xp_p3) 209181344Sdfr 210181344Sdfr#define SVC_AUTH(xprt) \ 211181344Sdfr (SVC_EXT(xprt)->xp_auth) 212181344Sdfr 2131839Swollman/* 214181344Sdfr * Operations defined on an SVCAUTH handle 215181344Sdfr */ 216181344Sdfr#define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere) \ 217181344Sdfr ((auth)->svc_ah_ops->svc_ah_wrap(auth, xdrs, xfunc, xwhere)) 218181344Sdfr#define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \ 219181344Sdfr ((auth)->svc_ah_ops->svc_ah_unwrap(auth, xdrs, xfunc, xwhere)) 220181344Sdfr 221181344Sdfr/* 2221839Swollman * Service registration 2231839Swollman * 22474462Salfred * svc_reg(xprt, prog, vers, dispatch, nconf) 22574462Salfred * const SVCXPRT *xprt; 22674462Salfred * const rpcprog_t prog; 22774462Salfred * const rpcvers_t vers; 228231678Stijl * const void (*dispatch)(struct svc_req *, SVCXPRT *); 22974462Salfred * const struct netconfig *nconf; 2301839Swollman */ 23174462Salfred 2321903Swollman__BEGIN_DECLS 23393032Simpextern bool_t svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t, 23493032Simp void (*)(struct svc_req *, SVCXPRT *), 23593032Simp const struct netconfig *); 2361903Swollman__END_DECLS 2371839Swollman 2381839Swollman/* 2391839Swollman * Service un-registration 2401839Swollman * 24174462Salfred * svc_unreg(prog, vers) 24274462Salfred * const rpcprog_t prog; 24374462Salfred * const rpcvers_t vers; 2441839Swollman */ 24574462Salfred 2461903Swollman__BEGIN_DECLS 24793032Simpextern void svc_unreg(const rpcprog_t, const rpcvers_t); 2481903Swollman__END_DECLS 2491839Swollman 2501839Swollman/* 2511839Swollman * Transport registration. 2521839Swollman * 2531839Swollman * xprt_register(xprt) 2541839Swollman * SVCXPRT *xprt; 2551839Swollman */ 2561903Swollman__BEGIN_DECLS 25793032Simpextern void xprt_register(SVCXPRT *); 2581903Swollman__END_DECLS 2591839Swollman 2601839Swollman/* 2611839Swollman * Transport un-register 2621839Swollman * 2631839Swollman * xprt_unregister(xprt) 2641839Swollman * SVCXPRT *xprt; 2651839Swollman */ 2661903Swollman__BEGIN_DECLS 26793032Simpextern void xprt_unregister(SVCXPRT *); 2681903Swollman__END_DECLS 2691839Swollman 2701839Swollman 2711839Swollman/* 2721839Swollman * When the service routine is called, it must first check to see if it 2731839Swollman * knows about the procedure; if not, it should call svcerr_noproc 2748858Srgrimes * and return. If so, it should deserialize its arguments via 2751839Swollman * SVC_GETARGS (defined above). If the deserialization does not work, 2761839Swollman * svcerr_decode should be called followed by a return. Successful 2771839Swollman * decoding of the arguments should be followed the execution of the 2781839Swollman * procedure's code and a call to svc_sendreply. 2791839Swollman * 2801839Swollman * Also, if the service refuses to execute the procedure due to too- 2811839Swollman * weak authentication parameters, svcerr_weakauth should be called. 2821839Swollman * Note: do not confuse access-control failure with weak authentication! 2831839Swollman * 2841839Swollman * NB: In pure implementations of rpc, the caller always waits for a reply 2858858Srgrimes * msg. This message is sent when svc_sendreply is called. 2861839Swollman * Therefore pure service implementations should always call 2871839Swollman * svc_sendreply even if the function logically returns void; use 2881839Swollman * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows 2891839Swollman * for the abuse of pure rpc via batched calling or pipelining. In the 2901839Swollman * case of a batched call, svc_sendreply should NOT be called since 2911839Swollman * this would send a return message, which is what batching tries to avoid. 2921839Swollman * It is the service/protocol writer's responsibility to know which calls are 2931839Swollman * batched and which are not. Warning: responding to batch calls may 2941839Swollman * deadlock the caller and server processes! 2951839Swollman */ 2961839Swollman 2971903Swollman__BEGIN_DECLS 29895658Sdesextern bool_t svc_sendreply(SVCXPRT *, xdrproc_t, void *); 29993032Simpextern void svcerr_decode(SVCXPRT *); 30093032Simpextern void svcerr_weakauth(SVCXPRT *); 30193032Simpextern void svcerr_noproc(SVCXPRT *); 30293032Simpextern void svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t); 30393032Simpextern void svcerr_auth(SVCXPRT *, enum auth_stat); 30493032Simpextern void svcerr_noprog(SVCXPRT *); 30593032Simpextern void svcerr_systemerr(SVCXPRT *); 30693032Simpextern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t, 30793032Simp char *(*)(char *), xdrproc_t, xdrproc_t, 30893032Simp char *); 3091903Swollman__END_DECLS 3108858Srgrimes 3111839Swollman/* 3121839Swollman * Lowest level dispatching -OR- who owns this process anyway. 3131839Swollman * Somebody has to wait for incoming requests and then call the correct 3141839Swollman * service routine. The routine svc_run does infinite waiting; i.e., 3151839Swollman * svc_run never returns. 316229781Suqs * Since another (co-existent) package may wish to selectively wait for 3171839Swollman * incoming calls or other events outside of the rpc architecture, the 3181839Swollman * routine svc_getreq is provided. It must be passed readfds, the 3191839Swollman * "in-place" results of a select system call (see select, section 2). 3201839Swollman */ 3211839Swollman 3221839Swollman/* 3231839Swollman * Global keeper of rpc service descriptors in use 3248858Srgrimes * dynamic; must be inspected before each call to select 3251839Swollman */ 32621059Speterextern int svc_maxfd; 32774462Salfred#ifdef FD_SETSIZE 3281839Swollmanextern fd_set svc_fdset; 3291839Swollman#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ 33074462Salfred#else 33174462Salfredextern int svc_fds; 33274462Salfred#endif /* def FD_SETSIZE */ 3331839Swollman 3341839Swollman/* 335181344Sdfr * A set of null auth methods used by any authentication protocols 336181344Sdfr * that don't need to inspect or modify the message body. 337181344Sdfr */ 338181344Sdfrextern SVCAUTH _svc_auth_null; 339181344Sdfr 340181344Sdfr/* 3411839Swollman * a small program implemented by the svc_rpc implementation itself; 3421839Swollman * also see clnt.h for protocol numbers. 3431839Swollman */ 34474462Salfred__BEGIN_DECLS 34593032Simpextern void rpctest_service(void); 34674462Salfred__END_DECLS 3471839Swollman 3481903Swollman__BEGIN_DECLS 349181344Sdfrextern SVCXPRT *svc_xprt_alloc(void); 350181344Sdfrextern void svc_xprt_free(SVCXPRT *); 35193032Simpextern void svc_getreq(int); 35293032Simpextern void svc_getreqset(fd_set *); 35393032Simpextern void svc_getreq_common(int); 35474462Salfredstruct pollfd; 35593032Simpextern void svc_getreq_poll(struct pollfd *, int); 35674462Salfred 35793032Simpextern void svc_run(void); 35893032Simpextern void svc_exit(void); 3591903Swollman__END_DECLS 3601839Swollman 3611839Swollman/* 3621839Swollman * Socket to use on svcxxx_create call to get default socket 3631839Swollman */ 3641839Swollman#define RPC_ANYSOCK -1 36574462Salfred#define RPC_ANYFD RPC_ANYSOCK 3661839Swollman 3671839Swollman/* 3681839Swollman * These are the existing service side transport implementations 3691839Swollman */ 3701839Swollman 37174462Salfred__BEGIN_DECLS 3721839Swollman/* 37374462Salfred * Transport independent svc_create routine. 3741839Swollman */ 37593032Simpextern int svc_create(void (*)(struct svc_req *, SVCXPRT *), 37693032Simp const rpcprog_t, const rpcvers_t, const char *); 37774462Salfred/* 378231678Stijl * void (*dispatch)(struct svc_req *, SVCXPRT *); 37974462Salfred * const rpcprog_t prognum; -- program number 38074462Salfred * const rpcvers_t versnum; -- version number 38174462Salfred * const char *nettype; -- network type 38274462Salfred */ 3831839Swollman 3841903Swollman 3851839Swollman/* 38674462Salfred * Generic server creation routine. It takes a netconfig structure 38774462Salfred * instead of a nettype. 3881839Swollman */ 3891839Swollman 39093032Simpextern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *), 39174462Salfred const rpcprog_t, const rpcvers_t, 39293032Simp const struct netconfig *); 39374462Salfred /* 394231678Stijl * void (*dispatch)(struct svc_req *, SVCXPRT *); 39574462Salfred * const rpcprog_t prognum; -- program number 39674462Salfred * const rpcvers_t versnum; -- version number 39774462Salfred * const struct netconfig *nconf; -- netconfig structure 39874462Salfred */ 3991903Swollman 40074462Salfred 4011839Swollman/* 40274462Salfred * Generic TLI create routine 4031839Swollman */ 40493032Simpextern SVCXPRT *svc_tli_create(const int, const struct netconfig *, 40593032Simp const struct t_bind *, const u_int, 40693032Simp const u_int); 40774462Salfred/* 40874462Salfred * const int fd; -- connection end point 40974462Salfred * const struct netconfig *nconf; -- netconfig structure for network 41074462Salfred * const struct t_bind *bindaddr; -- local bind address 41174462Salfred * const u_int sendsz; -- max sendsize 41274462Salfred * const u_int recvsz; -- max recvsize 41374462Salfred */ 4141839Swollman 41521059Speter/* 41674462Salfred * Connectionless and connectionful create routines 41721059Speter */ 41874462Salfred 41993032Simpextern SVCXPRT *svc_vc_create(const int, const u_int, const u_int); 42074462Salfred/* 42174462Salfred * const int fd; -- open connection end point 42274462Salfred * const u_int sendsize; -- max send size 42374462Salfred * const u_int recvsize; -- max recv size 42474462Salfred */ 42574462Salfred 42684487Swpaul/* 42784487Swpaul * Added for compatibility to old rpc 4.0. Obsoleted by svc_vc_create(). 42884487Swpaul */ 42993032Simpextern SVCXPRT *svcunix_create(int, u_int, u_int, char *); 43084487Swpaul 43193032Simpextern SVCXPRT *svc_dg_create(const int, const u_int, const u_int); 43274462Salfred /* 43374462Salfred * const int fd; -- open connection 43474462Salfred * const u_int sendsize; -- max send size 43574462Salfred * const u_int recvsize; -- max recv size 43674462Salfred */ 43774462Salfred 43874462Salfred 43974462Salfred/* 44074462Salfred * the routine takes any *open* connection 44174462Salfred * descriptor as its first input and is used for open connections. 44274462Salfred */ 44393032Simpextern SVCXPRT *svc_fd_create(const int, const u_int, const u_int); 44474462Salfred/* 44574462Salfred * const int fd; -- open connection end point 44674462Salfred * const u_int sendsize; -- max send size 44774462Salfred * const u_int recvsize; -- max recv size 44874462Salfred */ 44974462Salfred 45074462Salfred/* 45184487Swpaul * Added for compatibility to old rpc 4.0. Obsoleted by svc_fd_create(). 45284487Swpaul */ 45393032Simpextern SVCXPRT *svcunixfd_create(int, u_int, u_int); 45484487Swpaul 45584487Swpaul/* 45674462Salfred * Memory based rpc (for speed check and testing) 45774462Salfred */ 45893032Simpextern SVCXPRT *svc_raw_create(void); 45974462Salfred 46074462Salfred/* 46174462Salfred * svc_dg_enable_cache() enables the cache on dg transports. 46274462Salfred */ 46393032Simpint svc_dg_enablecache(SVCXPRT *, const u_int); 46474462Salfred 46590232Sdesint __rpc_get_local_uid(SVCXPRT *_transp, uid_t *_uid); 46674658Salfred 46721059Speter__END_DECLS 46821059Speter 46974462Salfred 47074462Salfred/* for backward compatibility */ 47174462Salfred#include <rpc/svc_soc.h> 47274462Salfred 4731903Swollman#endif /* !_RPC_SVC_H */ 474