REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) ------------------------------------------------------------------------------- Remote Procedure Call (RPC) PURPOSE Allows machines to make procedure calls to other network machines. LIBRARY Standard C Library (libc.a) SYNTAX #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include DESCRIPTION Remote Procedure Call (RPC) is a remote procedure call specification that provides a procedure-oriented interface to remote services. RPC is used in networks to provide programs that enable communication between machines. For example, a network file service can be composed of programs that deal with high-level applications such as file access control and programs that deal with low-level applications such as read or write. The programs are accessible through a machine designated as a network server. A client of the network file service can call the procedures associated with the programs on behalf of a user logged in to the client machine. A client is a computer or process that accesses the services or resources of another process or computer on the network. A server is a computer that Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 1 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) provides services and resources, as well as implements network services. Each network service is a collection of remote programs. A remote program implements remote procedures. The procedures, along with their parameters and results, are documented in the specific program's protocol specification. A server can support more than one version of a remote program in order to be compatible with changing protocols. In RPC, each server supplies a program that is a set of procedures. The combination of a host address, a program number, and a procedure number specifies one remote service procedure. THE RPC COMMUNICATION PARADIGM: Programs that communicate over a network need a paradigm for communication. The RPC paradigm is based on the remote procedure call model, which is similar to the local procedure call model. A local procedure call involves the caller placing arguments to a procedure in a defined location, such as a result register, and transferring control to the procedure. The caller eventually gains back control and extracts the results of the procedure from the defined location before continuing execution. A remote procedure call is similar, except that one thread of control winds through two processes: a caller process and a server process. That is, the caller process sends a call message to the server process and waits for (or blocks) a reply message. The call message contains information that includes the parameters of the procedure. The reply message contains information that includes the results of the procedure. When the caller receives the reply message, it extracts the results of the procedure and resumes execution. On the server side, a process is dormant awaiting the arrival of a call message. When one arrives, the server process extracts the procedure's parameters, computes the results, sends a reply message, and waits for the next call message. Only one of the two processes is active at any given time. That is, the RPC protocol does not explicitly support multithreading of caller or server processes. EXTERNAL DATA REPRESENTATION (XDR): RPC uses External Data Representation (XDR) to establish uniform representations for data types in order to transfer the call message data between machines without regard to their manufacturers, operating systems, or architectures. For basic data types such as integers and strings, XDR provides primitives that serialize, or translate, information from the local host's representation to XDR's representation, and deserialize, or translate, from the XDR representation to the local host's representation. XDR also uses constructor primitives that allow the use of the basic data types to create more complex data types, such as arrays and discriminated unions. RPC input and output data structures are described using XDR's data description language, which resembles the C programming language. Many of the constructs are identical to those in the C language. XDR additionally uses a construct called a discriminated union. The discriminated union is a union data structure which holds various objects with one of the objects identified directly by a discriminant, or arm, that is the first item to be serialized or Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 2 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) deserialized. The syntax for XDR routines that are called directly by RPC routines are included in "RPC Subroutines." For more detailed information about XDR and the other XDR routines, see "XDR (External Data Representation)." DATA TRANSPORTS AND SEMANTICS: RPC deals with the specification and interpretation of messages, not with the method used to pass messages from one process to the other. It does not depend on services provided by specific transport protocols. Although specific semantics, or meanings, are not attached to remote procedures or their execution, certain semantics can be inferred from the protocol of the underlying data transport that is used. For example, passing RPC messages with the UDP/IP data transport is unreliable. If the caller retransmits RPC call messages after short timeouts, the only thing it can infer from no reply message is that the remote procedure was executed zero or more times (and from a reply message, one or more times). In contrast, passing RPC messages with TCP/IP is reliable. No reply message means the remote procedure was executed one time at most, and a reply message means that the remote procedure was executed exactly once. BINDING AND RENDEZVOUS INDEPENDENCE: RPC does not bind a client to a service as part of its protocol. This required function is left up to a higher level software. However, the network software can use RPC to accomplish the tasks involved with binding clients to services. MESSAGE AUTHENTICATION: The RPC protocol provides the fields required for a client to identify itself to a service and for a service to identify itself to the client. The contents of RPC authentication parameters for these fields are determined by the type, sometimes called flavor, of the authentication used by the server and the client. A server can support multiple types of authentication at one time. You can build additional security and access controls on top of the message authentication. The RPC Protocol RPC is primarily a tool for calling remote procedures. By providing a unique specification for calling the remote procedures, RPC can match a reply message to each request (or call) message. Each RPC call message contains the following unsigned fields to uniquely identify the procedure to be called: o Remote program number o Remote program version number o Remote procedure number. ASSIGNING PROGRAM NUMBERS TO PROTOCOLS: Program numbers are assigned in groups of 0x20000000 (536870912) as shown in Figure 2: Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 3 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) +-----------------------------------------------------------------------------+ |Figure 2. How to Assign Program Numbers | +---------------------+----------------+--------------------------------------+ |Program Number | How Assigned | Use | +---------------------+----------------+--------------------------------------+ |0 - 1fffffff | Defined by | System authority (the product | | | system | licensor) administers this first | | | authority | group of numbers. This group should | | | | be identical for all system | | | | customers. | +---------------------+----------------+--------------------------------------+ |20000000 - 3fffffff | Defined by | Use this group for applications you | | | user | develop and for debugging new | | | | programs. | +---------------------+----------------+--------------------------------------+ |40000000 - 5fffffff | Transient | Use the third group for applications | | | | that generate program numbers | | | | dynamically. | +---------------------+----------------+--------------------------------------+ ASSIGNING VERSION NUMBERS TO PROGRAMS: As programs evolve into more stable and mature protocols, version numbers are assigned. The first implementation of a remote program is usually designated as version number 1 (or a similar form). The version number identifies which version of the protocol the caller is using. Version numbers make it possible to use old and new protocols through the same server. ASSIGNING PROCEDURE NUMBERS TO PROGRAMS: The procedure numbers are documented in each program's protocol specification. For example, a file service protocol's specification can list the read procedure as procedure number "5" and write as procedure number "12". THE RPC MESSAGE PROTOCOL The RPC message protocol consists of two distinct forms: the call message and the reply message. A client makes a remote procedure call to a network server and receives a reply containing the results of the procedure's execution. RPC message protocols are defined in the XDR data description language. Call and reply messages have the following values: enum msg_type { CALL = 0, REPLY = 1 }; Message Protocol Structure The initial message structure appears as follows: Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 4 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) struct rpc_msg { unsigned xid; union switch (enum msg_type) { CALL: struct call_body; REPLY; struct reply_body; }; }; Both the RPC call and reply messages start with an xid, the transaction identifier, followed the two-armed discriminated union enum msg_type. The reply messages' xids are matched to the xids of the call messages. It is important to note that the xids are used only by the clients when matching reply messages to call messages. The initial structure is followed by the body of the message. The body of a call message has a single form. The body of a reply message takes one of two forms depending on whether a call is accepted or rejected by the server. CALL MESSAGES: The body of an RPC call message is structured as follows: struct call_body { unsigned rpcvers; unsigned prog; unsigned vers; unsigned proc; struct opaque_auth cred; struct opaque_auth verf; #1 parameter #2 parameter... }; The structure is explained in the following: rpcvers RPC protocol specification version number. prog Number that identifies a remote program. This is an assigned number represented in a protocol that identifies the program needed to call a remote procedure. Program numbers are administered by a central authority and are documented in the program's protocol specification. vers Number that identifies the remote program's version. As a remote program's protocols are implemented, they evolve and change. Version numbers are assigned to identify different stages of a protocol's evolution. Servers can service requests for different versions of the same protocol simultaneously. proc Number of the procedure associated with the remote program being called. These numbers are documented in the specific program's protocol specification. For example, a protocol's specification can list the read procedure as procedure number "5" or write as procedure number "12". Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 5 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) cred Credentials authentication parameter that identifies the caller as having permission to call the remote program. It is passed as an opaque data structure, which means the data is not interpreted as it is passed from the client to the server. verf Verifier authentication parameter that identifies the caller to the server. It is passed as an opaque data structure which means the data is not interpreted as it is passed from the client to the server. Note: Procedure specific parameters appear at the end of the call body. REPLY MESSAGES: RPC reply messages take one of two forms to show that the call message was accepted by a network server or that it was rejected by the server. The discriminant enum reply_stat acts as a switch to the rejected or accepted reply message form. enum reply_stat { MSG_ACCEPTED = 0, MSG_DENIED = 1 }; A reply to an RPC request accepted by the network server takes the following form: struct accepted_reply { struct opaque_auth verf; union switch (enum accept_stat) { SUCCESS: struct { return values }; PROG_MISMATCH: struct { unsigned low; unsigned high; }; default: struct { }; }; }; The structures in the accepted reply are specified by the following: opaque_auth verf; Authentication verifier generated by the server to identify itself to the caller. enum accept_stat A discriminant that acts as a switch to one of the following structures: Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 6 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) SUCCESS Defines the results or return values of the procedure. PROG_MISMATCH Specifies the lowest and highest version numbers of the remote program that are supported by the server. default Lists errors that occur even though the request was accepted. The default structure can take any of the following values: PROG_UNAVAIL The remote server has not exported the program. PROG_MISMATCH The remote server cannot support the client's version number. PROC_UNAVAIL The program cannot support the requested procedure. GARBAGE_ARGS The procedure cannot decode the parameters specified in the call. A reply to an RPC request that is rejected by the server takes the following form: struct rejected_reply { union switch (enum reject_stat) { RPC_MISMATCH: struct { unsigned low; unsigned high; }; AUTH_ERROR: enum auth_stat; }; }; The discriminant, enum reject_stat, acts as a switch to one of the following: RPC_MISMATCH The server is not running a compatible version of the RPC protocol. The server returns the lowest and highest version numbers available. AUTH_ERROR The server refuses to authenticate the caller and returns a failure status with the value enum auth_stat. The enum auth_stat status returned is one of the following: AUTH_BADCRED The caller had bad credentials. AUTH_REJECTEDCRED The client must begin a new session. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 7 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) AUTH_BADVERF The clients verifier was bad. AUTH_REJECTEDVERF The verifier expired or replayed. AUTH_TOOWEAK The authentication credentials were rejected for security reasons. Multiple Reply Messages: A client can broadcast its message across the network and wait for many replies by using broadcast RPC with the UDP/IP transport. Servers that support broadcast protocols only respond when the request is successfully processed. Otherwise they are silent. No Reply Message Needed: In cases where the client does not need a reply, RPC can batch, or send, a large sequence of call messages to a server using the TCP/IP transport. The batch sequence is terminated by another RPC that is called to clear the pipeline. Record Marking in the Messages When RPC messages are passed using the TCP/IP byte stream protocol for data transport, it is important to identify the end of one message and the start of the next one by record marking (rm). A record is composed of one or more record fragments. A record fragment is a 4-byte header. The header is followed by "0" to "2(32)-1" bytes of fragment data. The bytes encode an unsigned binary number, similar to XDR integers. The order of bytes is from highest to lowest. This binary number encodes a Boolean and an unsigned binary value of 31 bits. The Boolean value is the highest-order bit of the header. If the Boolean value is value is 1, the fragment is the last fragment of the record. The unsigned binary value is the length in bytes of the fragment's data. Authentication RPC provides the opaque_auth structure for the verifier parameter so that a client can identify itself to the server receiving the call message, and for the server to identify itself to the client in the response message. In addition, RPC provides the auth_unix structure for the credentials parameter so that client access permission to the remote program can be checked by the server. These RPC authentication parameters are opaque data type structures. That is, they pass through the messages without being interpreted. See the "Opaque Data" for more detailed information about this data type. If neither the caller or the server require permission checking, AUTH_NULL can be used for the RPC message credentials and verifier parameters. These routines are discussed in alphabetical order in "RPC Subroutines." Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 8 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) AIX handles the structure of the credentials parameter in a shorthand form. The caller of a remote procedure can use this shorthand representation by using AUTH_UNIX as the value of the credentials parameter. The bytes of the credentials string encode the following XDR structure: struct auth_unix { unsigned stamp; string machinename<255>; unsigned uid; unsigned gid; unsigned gids<10>; }; The parameters in the structure are defined as follows: stamp Arbitrary ID generated by the caller's machine. machinename<255> Name of the caller's machine. The name must not exceed 255 bytes in length. uid Caller's effective user ID. gid Caller's effective group ID. gids<10> Counted array of groups which contain the caller as a member. A maximum of 10 groups is allowed. The value of the response verifier's discriminant in the reply message (oa_flavor in the opaque_auth structure) from the server is either AUTH_NULL or AUTH_SHORT. If the value is AUTH_SHORT, the bytes of the verf string encode an auth_opaque structure. The auth_opaque structure can then be passed to the server in place of the original AUTH_UNIX credentials. The server keeps a cache that maps the auth_opque structures to the credentials of the caller. The caller requires less network bandwidth and server CPU time when the shorthand credentials are used. Note: The server can eliminate, or flush, the shorthand auth_opaque structures at any time. If this happens, an RPC message's rejection is listed as an authentication error. The original AUTH_UNIX must be used to generate the shorthand version again. The Portmap Program RPC uses a portmap daemon, also known as the portmapper, to map the RPC program version numbers to UDP/IP or TCP/IP port numbers. This maximizes the efficiency of remote program bindings since the range of reserved port numbers is small compared to the number of remote programs possible. The portmap daemon runs on a reserved port, answering client queries regarding the location of the port numbers of the remote programs. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 9 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) RPC Subroutines The RPC subroutines are listed alphabetically in this section. Each subroutine is introduced by its syntax and followed by a brief discussion of its purpose, parameters, and return value. A NOTE ABOUT THE PARAMETERS: RPC uses the following common parameters to identify the remote procedure called in each routine: prognum Number of the remote program. Program numbers are administered by a central authority. versnum Version number of the remote program. As remote program's protocols are implemented, they evolve and change. Version numbers are assigned to identify different stages of the protocols evolution. Servers can service requests for different versions of the same protocol simultaneously. procnum Procedure numbers that identify the procedure to be called. These numbers are documented in the specific program's protocol specification. For example, a protocol's specification can list the read procedure as procedure number "5" or write as procedure number "12". Note: The structure of these parameters is discussed in "Call Messages." Other parameters specific to the routines are identified in the discussion of each routine. void auth_destroy (auth) AUTH *auth; The auth_destroy macro destroys the authentication information structure pointed to by the auth parameter. Destroying the structure deallocates private data structures associated with it. The use of auth is undefined after calling this macro. AUTH * authnone_create ( ) The authnone_create subroutine creates and returns an RPC authentication handle that passes no usable authentication with each remote procedure call. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 10 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) AUTH * authunix_create (host, uid, gid, len, aup_gids) char *host; int uid, gid, len; int *aup_gids; The authunix_create subroutine creates and returns an RPC authentication handle with AIX permissions. The host parameter points to the name of the machine on which the permissions were created. The uid parameter specifies the user's userid. The gid parameter specifies the current group ID of the user, while the aup_gids parameter points to the counted array of groups to which the user belongs. The length of the groups array is specified by the len parameter. AUTH * void authunix_create_default ( ) The authunix_create_default subroutine calls the authunix_create subroutine to create and return the default AIX authentication handle. callrpc (host, prognum, versnum, procnum, inproc, in, outproc, out) char *host; u_long prognum, versnum, procnum; xdrproc_t inproc; char *in; xdrproc_t outproc; char *out; The callrpc subroutine calls a remote procedure associated with the prognum, versnum, and procnum parameters on the machine pointed to by the host parameter. The inproc parameter specifies the procedure that encodes the procedure's parameters. The in parameter points to the address of the procedure's arguments. The outproc parameter specifies the procedure that decodes the procedure's results. The out parameter points to the address where results are placed. Upon successful completion, this routine returns the value 0. Otherwise, a nonzero value of the type enum clnt_stat is returned. Note: Calling remote procedures with this routine uses UDP/IP as a transport. If the server is a TCP/IP supported server only, you cannot get a connection. See the clnttcp_create subroutine to open TCP/IP sockets. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 11 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) enum clnt_stat clnt_broadcast (prognum, versnum, procnum, inproc, in, outproc, out, eachresult) u_long prognum, versnum, procnum; xdrproc_t inproc; char *in; xdrproc_t outproc; char *out; resultproc_t eachresult; The clnt_broadcast subroutine broadcasts a remote procedure call to all locally connected networks. The remote procedure is identified by the prognum, versnum, and procnum parameters on the machine identified by the parameter host. The inproc parameter specifies the procedure that encodes the procedure's parameters. The in parameter points to the address of the procedure's arguments. The outproc parameter specifies the procedure that decodes the procedure's results. The out parameter points to the address where results are placed. When a client broadcasts a remote procedure call over the network, a number of server processes respond. Each time it receives a response, this routine calls the eachresult routine to point to the function that is called. The eachresult routine takes the following form: eachresult (out, addr) char *out; struct sockaddr_in *addr; The out parameter points to the address where the procedure's results are decoded and placed. The addr parameter points to the address of the machine that sent the results. If eachresult returns 0, the clnt_broadcast subroutine waits for more replies. Otherwise, it returns with the appropriate results. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 12 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) enum clnt_stat clnt_call (clnt, procnum; inproc, in, outproc, out, tout) CLIENT *clnt; long procnum; xdrproc_t inproc; char *in; xdrproc_t outproc; char *out; struct timeval tout; The clnt_call macro calls the remote procedure associated with a client handle pointed to by the clnt parameter. The clnt parameter is the result of an RPC client creation routine, such as clntudp_create, which opens a UDP/IP socket. The procnum parameter identifies the remote procedure on the host machine associated with the client handle. The inproc parameter specifies the procedure that encodes the procedure's parameters. The in parameter points to the address of the procedure's arguments. The outproc parameter specifies the procedure that decodes the procedure's results. The out parameter points to the address where results are placed. The tout parameter sets the time allowed for results to come back. clnt_destroy (clnt) CLIENT *clnt; The clnt_destroy macro destroys the client's RPC handle. The clnt parameter is the result of an RPC client creation routine, such as clntudp_create which opens a UDP/IP socket. Destroying the client's RPC handle deallocates private data structures, including the clnt structure itself. The use of clnt is undefined after calling the clnt_destroy macro. The user must close the sockets associated with the clnt structure. clnt_freeres (clnt, outproc, out) CLIENT *clnt; xdrpoc_t outproc; char *out; Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 13 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) The clnt_freeres macro frees data that was allocated by the RPC/XDR system when it decoded the results of an RPC call. The clnt parameter points to the structure of the client handle. The outproc parameter specifies the XDR routine that describes the results in simple decoding primitives. The out parameter points to the address where the results are placed. Upon successful completion, this routine returns the value TRUE. Otherwise, it returns the value FALSE. void clnt_geterr (clnt, errp) CLIENT *clnt; struct rpc_err *errp; The clnt_geterr macro copies error information from a client handle to an error structure. The clnt parameter points to the client handle. The errp parameter points to the address of the error structure. void clnt_pcreateerror (s) char *s; The clnt_pcreateerror subroutine writes a message to standard error indicating why a client RPC handle could not be created. The s parameter points to a character string that represents the error text. This subroutine is used after a clntraw_create, clnttcp_create, or clntudp_create call. void clnt_perrno (stat) enum clnt_stat stat; The clnt_perrno subroutine writes a message to standard error corresponding to the condition specified by the stat parameter. This subroutine is used after a callrpc subroutine. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 14 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) clnt_perror (clnt, s) CLIENT *clnt; char *s; The clnt_perror subroutine writes a message to standard error indicating why a remote procedure call failed. The clnt parameter is the client handle used to make the call. The s parameter points to a character string that represents the error text. This routine is used after a clnt_call subroutine. CLIENT * clntraw_create (prognum, versnum) u_long prognum, versnum; The clntraw_create subroutine creates a toy RPC client for simulation of the remote program specified by the prognum and versnum parameters. The client uses a buffer located within the address space of the process as the transport to pass messages to the service. If the corresponding RPC server lives in the same address space, simulation of RPC and acquisition of RPC overheads, such as round-trip times, are done without kernel interference. (See the svcraw_create subroutine.) On successful completion, this subroutine returns a pointer to a valid RPC client. If this subroutine fails, it returns the value NULL. CLIENT * clnttcp_create (addr, prognum, versnum, sockp, sendsz, recvsz) struct sockaddr_in *addr; u_long prognum, versnum; int *sockp; u_int sendsz, recvsz; The clnttcp_create subroutine creates an RPC client for a remote program identified by the prognum and versnum parameters. The client uses TCP/IP as the transport to pass messages to the service. The addr parameter points to the Internet address of the remote program. If port number for this Internet address (addr->sin_port) is 0, then addr is set to the actual port that the remote program is listening on. The client making the remote procedure call consults the remote portmap daemon for this information. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 15 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) The sockp parameter is a pointer to a socket. If sockp is RPC_ANYSOCK, the clnttcp_create subroutine opens a new socket and sets the sockp pointer to it. Since TCP/IP remote procedure calls use buffered I/O, users can set the size of the send and receive buffers with the sendsz and recvsz parameters. If the size of either buffer is set as 0, the subroutine picks suitable default values. Upon successful completion, this routine returns a valid TCP/IP client. If it fails, it returns the value NULL. CLIENT * clntudp_create (addr, prognum, versnum, wait, sockp) struct sockaddr_in *addr; u_long prognum, versnum; struct timeval wait; int *sockp; The clntudp_create subroutine creates an RPC client for a remote program identified by the prognum and versnum parameters. The client uses UDP/IP as the transport to pass messages to the service. The addr parameter points to the Internet address of the remote program. If port number for this Interenet Address (addr->sin_port) is 0, then addr is set to the actual port that the remote program is listening on. The clntudp_create subroutine consults the remote portmap daemon for this information. The sockp parameter is a pointer to a socket. If sockp is RPC_ANYSOCK, the clntudp_create subroutine opens a new socket and sets the sockp pointer to it. The wait parameter sets the amount of time that the UDP/IP transport waits until a response is received before it resends the remote procedure call or the remote procedure call times out. The total time for the call to time out is set by the clnt_call subroutine. Note: RPC messages transported by UDP/IP can hold up to 8K bytes of encoded data. Use this transport for procedures that take arguments or return results of less than 8K bytes. void get_myaddress (addr) struct sockaddr_in *addr; Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 16 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) The get_myaddress subroutine gets the machine's IP address without consulting the library routines that access the /etc/hosts file. The addr parameter points to an address where the machine's IP address is placed. The port number is set to "htons(PMAPPORT)". struct pmaplist * pmap_getmaps (addr) struct sockaddr_in *addr; The pmap_getmaps subroutine acts as the user interface to the portmap daemon to return a list of the current RPC program-to-port mappings on the host located at the IP address pointed to by the addr parameter. This routine can return the value NULL. Note: The command rpcinfo -p uses this routine. See AIX Operating System Commands Reference for more information about this command. u_short pmap_getport (addr, prognum, versnum, protocol) struct sockaddr_in *addr; u_long prognum, versnum, protocol; The pmap_getport subroutine acts as the user interface to the portmap daemon to return the port number on which a service waits. The addr parameter points to the IP address of the host where the remote program that supports the waiting service resides. The prognum and versnum parameters identify the remote program that supports the waiting service. The protocol parameter specifies the transport protocol that the service recognizes. If the routine returns a value of 0, the mapping does not exist or the RPC system did not contact the remote portmap daemon. If the remote portmap daemon was not contacted, the rpc_createerr global variable contains the RPC status. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 17 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) enum clnt_stat pmap_rmtcall (addr, prognum, vernsum, procnum, inproc, in, outproc, out, tout, portp) struct sockaddr_in *addr; u_long prognum, versnum, procnum; xdrproc_t inproc; char *in; xdrproc_t outproc; char *out; struct timeval tout; u_long *portp; The pmap_rmtcall subroutine instructs the portmap daemon on the host at the IP address pointed to by the addr parameter to make a remote procedure call on behalf of the caller to a procedure on that host. The portp parameter is modified to the program's port number if the procedure succeeds. The prognum, versnum, and procnum parameters identify the program associated with the remote procedure. The inproc parameter specifies the XDR routine that encodes the remote procedure's parameters. The in parameter points to the address of the procedure's arguments. The outproc parameter specifies the XDR routine that decodes the remote procedure's results. The tout parameter sets the time the routine waits for the results to return before resending the call. Notes: 1. Use this procedure for a ping command only. See Interface Program for use with TCP/IP for information on ping. 2. Also see the clnt_broadcast subroutine in this book. pmap_set (prognum, versnum, protocol, port) u_long prognum, versnum, protocol; u_short port; The pmap_set subroutine acts as a user interface to the portmap daemon to map a remote procedure to a port on the machine's portmap daemon. The port on the machine's portmap daemon is specified by the port parameter. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 18 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) The prognum, versnum, and protocol parameters identify the remote procedure call. The values for the protocol parameter can be "IPPROTO_UDP" or "IPPROTO_TCP". Upon successful completion, this routine returns the value TRUE. Otherwise, it returns the value FALSE. Note: The pmap_set subroutine is called by the svc_register. pmap_unset (prognum, versnum) u_long prognum, versnum; The pmap_unset subroutine destroys mappings between the remote procedure call and the ports on the machine's portmap daemon. The prognum and versnum parameters identify the remote procedure call. Upon successful completion, this routine returns the value TRUE. Otherwise, it returns the value FALSE. registerrpc (prognum, versnum, procnum, procname, inproc, outproc) u_long prognum versnum, procnum; char * (*procname) (); xdrproc_t inproc, outproc; The registerrpc subroutine registers a procedure identified by the procname parameter with the RPC service package. If a request arrives that matches the values of the prognum, versnum, and procnum parameters, procname is called with a pointer to its parameters, and returns a pointer to its static results. The inproc parameter specifies the XDR routine that decodes the procedure's parameters. The outproc parameter specifies the XDR routine that encodes the procedure's results. Upon successful completion, this routine returns the value 0. Otherwise, it returns the value of -1. Note: Remote procedures registered in this form are accessed using the UDP/IP transport protocol only. See the svcudp_create subroutine for restrictions. struct rpc_createerr rpc_createerr; Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 19 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) The rpc_createerr global variable is set by any RPC client creation routine that does not succeed. Use the clnt_pcreateerror subroutine to write to standard output the reason why the client was not created. svc_destroy (xprt) SVCXPRT *xprt; The svc_destroy macro destroys the RPC service transport handle pointed to by the xprt parameter. Destroying the handle involves deallocating the private data structures, including xprt itself. Use of xprt is undefined after calling this routine. int svc_fds; The svc_fds global variable reflects the RPC service's file descriptor bit mask. This variable is used to manually run asynchronous processing in a program instead of calling the svc_run procedure that sets the asynchronous processing automatically. This is a read-only variable, but its value can change as a result of the svc_getargs or a creation routine. Do not pass the address of this variable to the select system call. svc_freeargs (xprt, inproc, in) SVCXPRT *xprt; xdrproc_t inproc; char *in; The svc_freeargs macro frees data allocated by the RPC/XDR system when it decoded the arguments to a service procedure using the svc_getargs routine. The xprt parameter points to the RPC service transport handle. The inproc parameter specifies the XDR routine that decodes the arguments. The in parameter points to the address where the procedure's arguments are placed. If this routine successfully frees the results, it returns the value TRUE. Otherwise, it returns the value FALSE. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 20 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) svc_getargs (xprt, inproc, in) SVCXPRT *xprt; xdrproc_t inproc; char *in; The svc_getargs macro decodes the arguments of an RPC request associated with the RPC service transport pointed to by the xprt parameter. The inproc parameter specifies the XDR routine that decodes the arguments. The in parameter points to the address where the arguments are placed. If this routine successfully frees the results, it returns the value TRUE. Otherwise, it returns the value FALSE. struct sockaddr_in svc_getcaller (xprt) SVCXPRT *xprt; The svc_getcaller subroutine gets the network address of the caller of a procedure associated with the RPC service transport handle that is pointed to by the xprt parameter. svc_getreq (rdfds) int rdfds; The svc_getreq subroutine is called when the select system call has determined an RPC request to service the RPC sockets associated with the value of the rdfds parameter. The rdfds parameter is the read-file descriptor bit mask. The svc_getreq subroutine returns when all associated sockets with the value rdfds have been serviced. Note: This routine is used to manually set asynchronous event processing in a program instead of calling the svc_run to automatically set it. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 21 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) svc_register (xprt, prognum, versnum, dispatch, protocol) SVCXPRT *xprt; u_long prognum, versnum; void (*dispatch) (); u_long protocol; The svc_register subroutine maps a remote procedure with a service dispatch procedure pointed to by the dispatch parameter. The xprt parameter points to an RPC service transport handle. The prognum and versnum parameters identify the remote program associated with the remote procedure. The protocol parameter specifies the data transport used by the service. If protocol is 0, the service is not registered with the portmap daemon. If protocol is not 0 (or is "IPPROTO_UDP" or "IPPROTO_TCP"), the remote procedure triple [prognum, versnum, and protocol] is mapped to the xprt->xp_port port. The dispatch procedure takes the following form: dispatch (request, xprt) struct svc_req *request; SVCXPRT *xprt; Upon successful completion, this routine returns the value TRUE. Otherwise, it returns the value FALSE. svc_run ( ) The svc_run subroutine waits for RPC service requests to arrive. When a request arrives, svc_run calls the appropriate service procedure using the svc_getreq subroutine. This procedure is usually waiting for a select system call to return. The svc_run subroutine never returns. svc_sendreply (xprt, outproc, out) SVCXPRT *xprt; xdrproc_t outproc; char *out; Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 22 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) The svc_sendreply subroutine sends back the results of a remote procedure call. This routine is called by an RPC service's dispatch routine. The xprt parameter points to the RPC service transport handle of the caller. The outproc parameter specifies the XDR routine that encodes the results. The out parameter points to the address where results are placed. Upon successful completion, this routine returns the value TRUE. Otherwise, it returns the value FALSE. void svc_unregister (prognum, versnum) u_long prognum, versnum; The svc_unregister subroutine removes mappings between procedures and objects. It removes the mapping of the service procedure identified by the prognum and versnum parameters to dispatch routines. It also removes the mapping of the service procedure identified by the prognum and versnum parameters to a port number. void svcerr_auth (xprt, why) SVCXPRT *xprt; enum auth_stat why; The svcerr_auth subroutine is called by a service dispatch routine that refuses to perform a remote procedure call because of an authentication error. The xprt parameter points to the RPC service transport handle. The why parameter specifies the authentication error. void svcerr_decode (xprt) SVCXPRT *xprt; The svcerr_decode subroutine is called by a service dispatch routine that cannot decode its parameters. The xprt parameter points to the RPC service transport handle. Note: See the svc_getargs subroutine. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 23 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) void svcerr_noproc (xprt) SVCXPRT *xprt; The svcerr_noproc subroutine is called by a service dispatch routine that does not implement the procedure number the caller requested. The xprt parameter points to the RPC service transport handle. void svcerr_noprog (xprt) SVCXPRT *xprt; The svcerr_noprog subroutine is called when the requested program is not registered with the RPC package. The xprt parameter points to the RPC service transport handle. Note: Service implementors do not usually need this routine. void svcerr_progvers (xprt) SVCXPRT *xprt; The svcerr_progvers subroutine is called when the requested version of a program is not registered with the RPC package. The xprt parameter points to the RPC service transport handle. Note: Service implementors do not usually need this routine. void svcerr_systemerr (xprt) SVCXPRT *xprt; The svcerr_systemerr subroutine is called by a service dispatch routine when it detects a system error not covered by a protocol. For example, a service calls this routine if it can no longer allocate storage. The xprt parameter points to the RPC service transport handle. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 24 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) void svcerr_weakauth (xprt) SVCXPRT *xprt; The svcerr_weakauth subroutine is called by a service dispatch routine that cannot make the remote procedure call because the supplied authentication parameters were insufficient. It is called even if the given parameters are correct. The xprt parameter points to the RPC service transport handle. The svcerr_weakauth subroutine calls the svc_auth routine using the correct RPC service transport handle (xprt) and as the authentication error the argument AUTH_TOOWEAK. SVCXPRT * svcraw_create ( ) The svcraw_create subroutine creates a toy RPC service transport. The service transport is located within the address space of the process. If the corresponding RPC server resides in the same address space, simulation of RPC and acquisition of RPC overheads, such as round-trip times, are done without kernel interference. (See the clntraw_create routine on page 15.) Upon successful completion, this routine returns a pointer to a valid RPC client. Otherwise, it returns the value NULL. SVCXPRT * svctcp_create (sock, sendsz, recvsz) int sock; u_int sendsz, rcvcsz; The svctcp_create subroutine creates a RPC service transport based on TCP/IP and returns a pointer to it. The sock parameter specifies the socket associated with the transport. If the sock parameter is RPC_ANYSOCK, the routine creates a new socket. The transport's socket number is set to xprt->xp_sock. If the socket is not bound to a local TCP/IP port, this routine binds it to an arbitrary port. Its port number is set to xprt->xp_port. Since TCP/IP remote procedure calls use buffered I/O, users can set the size of the send and receive buffers with the sendsz and recvsz Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 25 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) parameters. If the size of either buffer is set to 0, the routine picks suitable default values. On successful completion, this routine returns a valid RPC service transport. If it fails, it returns the value NULL. SVCXPRT * svcudp_create (sock) int sock; The svcudp_create subroutine creates an RPC service transport based on a UDP/IP and returns a pointer to it. The sock parameter specifies the socket associated with the transport. If the sock parameter is RPC_ANYSOCK, the routine creates a new socket. The transport's socket number is set to xprt->xp_sock. If the socket is not bound to a local UDP/IP port, this routine binds it to an arbitrary port. Its port number is set to xprt->xp_port. On successful completion, this routine returns a valid RPC service transport. If it fails, it returns the value NULL. Note: Use this transport for procedures that take up to 8K bytes of encoded arguments or results only. xdr_accepted_reply (xdrs, ar) XDR *xdrs; struct accepted_reply *ar; The xdr_accepted_reply routine describes RPC messages externally. Use this routine to generate message replies similar to RPC's message replies without using the RPC program. The xdrs parameter points to the XDR stream handle. The ar parameter points to the address of the structure that contains the reply. xdr_authunix_parms (xdrs, app) XDR *xdrs; struct authunix_parms *app; The xdr_accepted_reply routine describes credentials externally. Use this routine to generate credentials without using the RPC authentication program. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 26 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) The xdrs parameter points to the XDR stream handle. The app parameter points to the structure that contains the authentication credentials. void xdr_callhdr (xdrs, chdr) XDR *xdrs; struct rpc_msg *chdr; The xdr_callhdr routine describes RPC call headers externally. Use this routine to generate call headers that are similar to RPC's call headers without using the RPC program. The xdrs parameter points to the XDR stream handle. The chdr parameter points to the structure that contains the header for the call message. xdr_callmsg (xdrs, cmsg) XDR *xdrs; struct rpc_msg *cmsg; The xdr_callmsg routine describes RPC messages externally. Use this routine to generate messages that are similar to RPC's messages without using the RPC program. The xdrs parameter points to the XDR stream handle. The cmsg parameter points to the structure that contains the text of the call message. xdr_opaque_auth (xdrs, ap) XDR *xdrs; struct opaque_auth *ap; The xdr_opaque_auth routine describes RPC messages externally. Use this routine to generate opaque message data without using the RPC program. The xdrs parameter points to the XDR stream handle. The ap parameter points to the structure that contains the message text. xdr_pmap (xdrs, regs) XDR *xdrs; struct pmap *regs; Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 27 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) The xdr_pmap routine describes parameters for portmap procedures externally. Use this routine to generate portmap parameters without using the portmap interface. The xdrs parameter points to the XDR stream handle. The regs parameter points to the buffer, or register, where the portmap daemon stores the information. xdr_pmaplist (xdrs, rp) XDR *xdrs; struct pmaplist **rp; The xdr_pmaplist routine describes a list of port mappings externally. Use this routine to generate the port mappings to RPC ports without using the portmap interface. The xdrs parameter points to the XDR stream handle. The rp parameter is a pointer to the structure that contains the portmap listings. xdr_rejected_reply (xdrs, rr) XDR *xdrs; struct rejected_reply *rr; The xdr_rejected_reply routine describes RPC message rejection replies externally. Use this routine to generate rejection replies similar to RPC's rejection without using the RPC program. The xdrs parameter points to the XDR stream handle. The rr parameter points to the structure that contains the rejected reply. xdr_replymsg (xdrs, rmsg) XDR *xdrs; struct rpc_msg *rmsg; The xdr_replymsg routine describes RPC message replies externally. Use this routine to generate message replies similar to RPC's replies without using the RPC program. The xdrs parameter points to the XDR stream handle. The rmsg parameter points to the structure containing the parameters of the reply message. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 28 REMOTE PROCEDURE CALL (RPC)(3n,L) REMOTE PROCEDURE CALL (RPC)(3n,L) xprt_register (xprt) SVCXPRT *xprt; The xprt_register routine registers an RPC service transport handle with the RPC program after the transport has been created. The xprt parameter points to the newly created RPC service transport handle. This routine modifies the svc_fds global variable. Note: Service implementors do not usually need this routine. void xprt_unregister (xprt) SVCXPRT *xprt; The xprt_unregister routine removes an RPC service transport handle from the RPC service program before the transport handle can be destroyed. The xprt parameter points to the RPC service transport handle to be destroyed. This routine modifies the svc_fds global variable. Note: Service implementors do not usually need this routine. RELATED INFORMATION In this book: "Remote Procedure Call Service Routines" and "XDR (External Data Representation)." The Network File System section in Managing the AIX Operating System. Processed Oct. 11, 1991 REMOTE PROCEDURE CALL (RPC)(3n,L) 29