199064799SGarrett Wollman /* 299064799SGarrett Wollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 399064799SGarrett Wollman * unrestricted use provided that this legend is included on all tape 499064799SGarrett Wollman * media and as a part of the software program in whole or part. Users 599064799SGarrett Wollman * may copy or modify Sun RPC without charge, but are not authorized 699064799SGarrett Wollman * to license or distribute it to anyone else except as part of a product or 799064799SGarrett Wollman * program developed by the user. 899064799SGarrett Wollman * 999064799SGarrett Wollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1099064799SGarrett Wollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1199064799SGarrett Wollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1299064799SGarrett Wollman * 1399064799SGarrett Wollman * Sun RPC is provided with no support and without any obligation on the 1499064799SGarrett Wollman * part of Sun Microsystems, Inc. to assist in its use, correction, 1599064799SGarrett Wollman * modification or enhancement. 1699064799SGarrett Wollman * 1799064799SGarrett Wollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1899064799SGarrett Wollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 1999064799SGarrett Wollman * OR ANY PART THEREOF. 2099064799SGarrett Wollman * 2199064799SGarrett Wollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2299064799SGarrett Wollman * or profits or other special, indirect and consequential damages, even if 2399064799SGarrett Wollman * Sun has been advised of the possibility of such damages. 2499064799SGarrett Wollman * 2599064799SGarrett Wollman * Sun Microsystems, Inc. 2699064799SGarrett Wollman * 2550 Garcia Avenue 2799064799SGarrett Wollman * Mountain View, California 94043 2899064799SGarrett Wollman */ 2999064799SGarrett Wollman 3099064799SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 3199064799SGarrett Wollman /*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/ 3299064799SGarrett Wollman /*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/ 334c3af266SPoul-Henning Kamp static char *rcsid = "$Id: svc.c,v 1.2 1995/05/30 05:41:31 rgrimes Exp $"; 3499064799SGarrett Wollman #endif 3599064799SGarrett Wollman 3699064799SGarrett Wollman /* 3799064799SGarrett Wollman * svc.c, Server-side remote procedure call interface. 3899064799SGarrett Wollman * 3999064799SGarrett Wollman * There are two sets of procedures here. The xprt routines are 4099064799SGarrett Wollman * for handling transport handles. The svc routines handle the 4199064799SGarrett Wollman * list of service routines. 4299064799SGarrett Wollman * 4399064799SGarrett Wollman * Copyright (C) 1984, Sun Microsystems, Inc. 4499064799SGarrett Wollman */ 4599064799SGarrett Wollman 464c3af266SPoul-Henning Kamp #include <string.h> 474c3af266SPoul-Henning Kamp #include <stdlib.h> 4899064799SGarrett Wollman #include <sys/errno.h> 4999064799SGarrett Wollman #include <rpc/rpc.h> 5099064799SGarrett Wollman #include <rpc/pmap_clnt.h> 5199064799SGarrett Wollman 5299064799SGarrett Wollman extern int errno; 5399064799SGarrett Wollman 5499064799SGarrett Wollman #ifdef FD_SETSIZE 5599064799SGarrett Wollman static SVCXPRT **xports; 5699064799SGarrett Wollman #else 5799064799SGarrett Wollman #define NOFILE 32 5899064799SGarrett Wollman 5999064799SGarrett Wollman static SVCXPRT *xports[NOFILE]; 6099064799SGarrett Wollman #endif /* def FD_SETSIZE */ 6199064799SGarrett Wollman 6299064799SGarrett Wollman #define NULL_SVC ((struct svc_callout *)0) 6399064799SGarrett Wollman #define RQCRED_SIZE 400 /* this size is excessive */ 6499064799SGarrett Wollman 6599064799SGarrett Wollman /* 6699064799SGarrett Wollman * The services list 6799064799SGarrett Wollman * Each entry represents a set of procedures (an rpc program). 6899064799SGarrett Wollman * The dispatch routine takes request structs and runs the 6999064799SGarrett Wollman * apropriate procedure. 7099064799SGarrett Wollman */ 7199064799SGarrett Wollman static struct svc_callout { 7299064799SGarrett Wollman struct svc_callout *sc_next; 7399064799SGarrett Wollman u_long sc_prog; 7499064799SGarrett Wollman u_long sc_vers; 7599064799SGarrett Wollman void (*sc_dispatch)(); 7699064799SGarrett Wollman } *svc_head; 7799064799SGarrett Wollman 7899064799SGarrett Wollman static struct svc_callout *svc_find(); 7999064799SGarrett Wollman 8099064799SGarrett Wollman /* *************** SVCXPRT related stuff **************** */ 8199064799SGarrett Wollman 8299064799SGarrett Wollman /* 8399064799SGarrett Wollman * Activate a transport handle. 8499064799SGarrett Wollman */ 8599064799SGarrett Wollman void 8699064799SGarrett Wollman xprt_register(xprt) 8799064799SGarrett Wollman SVCXPRT *xprt; 8899064799SGarrett Wollman { 8999064799SGarrett Wollman register int sock = xprt->xp_sock; 9099064799SGarrett Wollman 9199064799SGarrett Wollman #ifdef FD_SETSIZE 9299064799SGarrett Wollman if (xports == NULL) { 9399064799SGarrett Wollman xports = (SVCXPRT **) 9499064799SGarrett Wollman mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); 9599064799SGarrett Wollman } 9699064799SGarrett Wollman if (sock < _rpc_dtablesize()) { 9799064799SGarrett Wollman xports[sock] = xprt; 9899064799SGarrett Wollman FD_SET(sock, &svc_fdset); 9999064799SGarrett Wollman } 10099064799SGarrett Wollman #else 10199064799SGarrett Wollman if (sock < NOFILE) { 10299064799SGarrett Wollman xports[sock] = xprt; 10399064799SGarrett Wollman svc_fds |= (1 << sock); 10499064799SGarrett Wollman } 10599064799SGarrett Wollman #endif /* def FD_SETSIZE */ 10699064799SGarrett Wollman 10799064799SGarrett Wollman } 10899064799SGarrett Wollman 10999064799SGarrett Wollman /* 11099064799SGarrett Wollman * De-activate a transport handle. 11199064799SGarrett Wollman */ 11299064799SGarrett Wollman void 11399064799SGarrett Wollman xprt_unregister(xprt) 11499064799SGarrett Wollman SVCXPRT *xprt; 11599064799SGarrett Wollman { 11699064799SGarrett Wollman register int sock = xprt->xp_sock; 11799064799SGarrett Wollman 11899064799SGarrett Wollman #ifdef FD_SETSIZE 11999064799SGarrett Wollman if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) { 12099064799SGarrett Wollman xports[sock] = (SVCXPRT *)0; 12199064799SGarrett Wollman FD_CLR(sock, &svc_fdset); 12299064799SGarrett Wollman } 12399064799SGarrett Wollman #else 12499064799SGarrett Wollman if ((sock < NOFILE) && (xports[sock] == xprt)) { 12599064799SGarrett Wollman xports[sock] = (SVCXPRT *)0; 12699064799SGarrett Wollman svc_fds &= ~(1 << sock); 12799064799SGarrett Wollman } 12899064799SGarrett Wollman #endif /* def FD_SETSIZE */ 12999064799SGarrett Wollman } 13099064799SGarrett Wollman 13199064799SGarrett Wollman 13299064799SGarrett Wollman /* ********************** CALLOUT list related stuff ************* */ 13399064799SGarrett Wollman 13499064799SGarrett Wollman /* 13599064799SGarrett Wollman * Add a service program to the callout list. 13699064799SGarrett Wollman * The dispatch routine will be called when a rpc request for this 13799064799SGarrett Wollman * program number comes in. 13899064799SGarrett Wollman */ 13999064799SGarrett Wollman bool_t 14099064799SGarrett Wollman svc_register(xprt, prog, vers, dispatch, protocol) 14199064799SGarrett Wollman SVCXPRT *xprt; 14299064799SGarrett Wollman u_long prog; 14399064799SGarrett Wollman u_long vers; 14499064799SGarrett Wollman void (*dispatch)(); 14599064799SGarrett Wollman int protocol; 14699064799SGarrett Wollman { 14799064799SGarrett Wollman struct svc_callout *prev; 14899064799SGarrett Wollman register struct svc_callout *s; 14999064799SGarrett Wollman 15099064799SGarrett Wollman if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) { 15199064799SGarrett Wollman if (s->sc_dispatch == dispatch) 15299064799SGarrett Wollman goto pmap_it; /* he is registering another xptr */ 15399064799SGarrett Wollman return (FALSE); 15499064799SGarrett Wollman } 15599064799SGarrett Wollman s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout)); 15699064799SGarrett Wollman if (s == (struct svc_callout *)0) { 15799064799SGarrett Wollman return (FALSE); 15899064799SGarrett Wollman } 15999064799SGarrett Wollman s->sc_prog = prog; 16099064799SGarrett Wollman s->sc_vers = vers; 16199064799SGarrett Wollman s->sc_dispatch = dispatch; 16299064799SGarrett Wollman s->sc_next = svc_head; 16399064799SGarrett Wollman svc_head = s; 16499064799SGarrett Wollman pmap_it: 16599064799SGarrett Wollman /* now register the information with the local binder service */ 16699064799SGarrett Wollman if (protocol) { 16799064799SGarrett Wollman return (pmap_set(prog, vers, protocol, xprt->xp_port)); 16899064799SGarrett Wollman } 16999064799SGarrett Wollman return (TRUE); 17099064799SGarrett Wollman } 17199064799SGarrett Wollman 17299064799SGarrett Wollman /* 17399064799SGarrett Wollman * Remove a service program from the callout list. 17499064799SGarrett Wollman */ 17599064799SGarrett Wollman void 17699064799SGarrett Wollman svc_unregister(prog, vers) 17799064799SGarrett Wollman u_long prog; 17899064799SGarrett Wollman u_long vers; 17999064799SGarrett Wollman { 18099064799SGarrett Wollman struct svc_callout *prev; 18199064799SGarrett Wollman register struct svc_callout *s; 18299064799SGarrett Wollman 18399064799SGarrett Wollman if ((s = svc_find(prog, vers, &prev)) == NULL_SVC) 18499064799SGarrett Wollman return; 18599064799SGarrett Wollman if (prev == NULL_SVC) { 18699064799SGarrett Wollman svc_head = s->sc_next; 18799064799SGarrett Wollman } else { 18899064799SGarrett Wollman prev->sc_next = s->sc_next; 18999064799SGarrett Wollman } 19099064799SGarrett Wollman s->sc_next = NULL_SVC; 19199064799SGarrett Wollman mem_free((char *) s, (u_int) sizeof(struct svc_callout)); 19299064799SGarrett Wollman /* now unregister the information with the local binder service */ 19399064799SGarrett Wollman (void)pmap_unset(prog, vers); 19499064799SGarrett Wollman } 19599064799SGarrett Wollman 19699064799SGarrett Wollman /* 19799064799SGarrett Wollman * Search the callout list for a program number, return the callout 19899064799SGarrett Wollman * struct. 19999064799SGarrett Wollman */ 20099064799SGarrett Wollman static struct svc_callout * 20199064799SGarrett Wollman svc_find(prog, vers, prev) 20299064799SGarrett Wollman u_long prog; 20399064799SGarrett Wollman u_long vers; 20499064799SGarrett Wollman struct svc_callout **prev; 20599064799SGarrett Wollman { 20699064799SGarrett Wollman register struct svc_callout *s, *p; 20799064799SGarrett Wollman 20899064799SGarrett Wollman p = NULL_SVC; 20999064799SGarrett Wollman for (s = svc_head; s != NULL_SVC; s = s->sc_next) { 21099064799SGarrett Wollman if ((s->sc_prog == prog) && (s->sc_vers == vers)) 21199064799SGarrett Wollman goto done; 21299064799SGarrett Wollman p = s; 21399064799SGarrett Wollman } 21499064799SGarrett Wollman done: 21599064799SGarrett Wollman *prev = p; 21699064799SGarrett Wollman return (s); 21799064799SGarrett Wollman } 21899064799SGarrett Wollman 21999064799SGarrett Wollman /* ******************* REPLY GENERATION ROUTINES ************ */ 22099064799SGarrett Wollman 22199064799SGarrett Wollman /* 22299064799SGarrett Wollman * Send a reply to an rpc request 22399064799SGarrett Wollman */ 22499064799SGarrett Wollman bool_t 22599064799SGarrett Wollman svc_sendreply(xprt, xdr_results, xdr_location) 22699064799SGarrett Wollman register SVCXPRT *xprt; 22799064799SGarrett Wollman xdrproc_t xdr_results; 22899064799SGarrett Wollman caddr_t xdr_location; 22999064799SGarrett Wollman { 23099064799SGarrett Wollman struct rpc_msg rply; 23199064799SGarrett Wollman 23299064799SGarrett Wollman rply.rm_direction = REPLY; 23399064799SGarrett Wollman rply.rm_reply.rp_stat = MSG_ACCEPTED; 23499064799SGarrett Wollman rply.acpted_rply.ar_verf = xprt->xp_verf; 23599064799SGarrett Wollman rply.acpted_rply.ar_stat = SUCCESS; 23699064799SGarrett Wollman rply.acpted_rply.ar_results.where = xdr_location; 23799064799SGarrett Wollman rply.acpted_rply.ar_results.proc = xdr_results; 23899064799SGarrett Wollman return (SVC_REPLY(xprt, &rply)); 23999064799SGarrett Wollman } 24099064799SGarrett Wollman 24199064799SGarrett Wollman /* 24299064799SGarrett Wollman * No procedure error reply 24399064799SGarrett Wollman */ 24499064799SGarrett Wollman void 24599064799SGarrett Wollman svcerr_noproc(xprt) 24699064799SGarrett Wollman register SVCXPRT *xprt; 24799064799SGarrett Wollman { 24899064799SGarrett Wollman struct rpc_msg rply; 24999064799SGarrett Wollman 25099064799SGarrett Wollman rply.rm_direction = REPLY; 25199064799SGarrett Wollman rply.rm_reply.rp_stat = MSG_ACCEPTED; 25299064799SGarrett Wollman rply.acpted_rply.ar_verf = xprt->xp_verf; 25399064799SGarrett Wollman rply.acpted_rply.ar_stat = PROC_UNAVAIL; 25499064799SGarrett Wollman SVC_REPLY(xprt, &rply); 25599064799SGarrett Wollman } 25699064799SGarrett Wollman 25799064799SGarrett Wollman /* 25899064799SGarrett Wollman * Can't decode args error reply 25999064799SGarrett Wollman */ 26099064799SGarrett Wollman void 26199064799SGarrett Wollman svcerr_decode(xprt) 26299064799SGarrett Wollman register SVCXPRT *xprt; 26399064799SGarrett Wollman { 26499064799SGarrett Wollman struct rpc_msg rply; 26599064799SGarrett Wollman 26699064799SGarrett Wollman rply.rm_direction = REPLY; 26799064799SGarrett Wollman rply.rm_reply.rp_stat = MSG_ACCEPTED; 26899064799SGarrett Wollman rply.acpted_rply.ar_verf = xprt->xp_verf; 26999064799SGarrett Wollman rply.acpted_rply.ar_stat = GARBAGE_ARGS; 27099064799SGarrett Wollman SVC_REPLY(xprt, &rply); 27199064799SGarrett Wollman } 27299064799SGarrett Wollman 27399064799SGarrett Wollman /* 27499064799SGarrett Wollman * Some system error 27599064799SGarrett Wollman */ 27699064799SGarrett Wollman void 27799064799SGarrett Wollman svcerr_systemerr(xprt) 27899064799SGarrett Wollman register SVCXPRT *xprt; 27999064799SGarrett Wollman { 28099064799SGarrett Wollman struct rpc_msg rply; 28199064799SGarrett Wollman 28299064799SGarrett Wollman rply.rm_direction = REPLY; 28399064799SGarrett Wollman rply.rm_reply.rp_stat = MSG_ACCEPTED; 28499064799SGarrett Wollman rply.acpted_rply.ar_verf = xprt->xp_verf; 28599064799SGarrett Wollman rply.acpted_rply.ar_stat = SYSTEM_ERR; 28699064799SGarrett Wollman SVC_REPLY(xprt, &rply); 28799064799SGarrett Wollman } 28899064799SGarrett Wollman 28999064799SGarrett Wollman /* 29099064799SGarrett Wollman * Authentication error reply 29199064799SGarrett Wollman */ 29299064799SGarrett Wollman void 29399064799SGarrett Wollman svcerr_auth(xprt, why) 29499064799SGarrett Wollman SVCXPRT *xprt; 29599064799SGarrett Wollman enum auth_stat why; 29699064799SGarrett Wollman { 29799064799SGarrett Wollman struct rpc_msg rply; 29899064799SGarrett Wollman 29999064799SGarrett Wollman rply.rm_direction = REPLY; 30099064799SGarrett Wollman rply.rm_reply.rp_stat = MSG_DENIED; 30199064799SGarrett Wollman rply.rjcted_rply.rj_stat = AUTH_ERROR; 30299064799SGarrett Wollman rply.rjcted_rply.rj_why = why; 30399064799SGarrett Wollman SVC_REPLY(xprt, &rply); 30499064799SGarrett Wollman } 30599064799SGarrett Wollman 30699064799SGarrett Wollman /* 30799064799SGarrett Wollman * Auth too weak error reply 30899064799SGarrett Wollman */ 30999064799SGarrett Wollman void 31099064799SGarrett Wollman svcerr_weakauth(xprt) 31199064799SGarrett Wollman SVCXPRT *xprt; 31299064799SGarrett Wollman { 31399064799SGarrett Wollman 31499064799SGarrett Wollman svcerr_auth(xprt, AUTH_TOOWEAK); 31599064799SGarrett Wollman } 31699064799SGarrett Wollman 31799064799SGarrett Wollman /* 31899064799SGarrett Wollman * Program unavailable error reply 31999064799SGarrett Wollman */ 32099064799SGarrett Wollman void 32199064799SGarrett Wollman svcerr_noprog(xprt) 32299064799SGarrett Wollman register SVCXPRT *xprt; 32399064799SGarrett Wollman { 32499064799SGarrett Wollman struct rpc_msg rply; 32599064799SGarrett Wollman 32699064799SGarrett Wollman rply.rm_direction = REPLY; 32799064799SGarrett Wollman rply.rm_reply.rp_stat = MSG_ACCEPTED; 32899064799SGarrett Wollman rply.acpted_rply.ar_verf = xprt->xp_verf; 32999064799SGarrett Wollman rply.acpted_rply.ar_stat = PROG_UNAVAIL; 33099064799SGarrett Wollman SVC_REPLY(xprt, &rply); 33199064799SGarrett Wollman } 33299064799SGarrett Wollman 33399064799SGarrett Wollman /* 33499064799SGarrett Wollman * Program version mismatch error reply 33599064799SGarrett Wollman */ 33699064799SGarrett Wollman void 33799064799SGarrett Wollman svcerr_progvers(xprt, low_vers, high_vers) 33899064799SGarrett Wollman register SVCXPRT *xprt; 33999064799SGarrett Wollman u_long low_vers; 34099064799SGarrett Wollman u_long high_vers; 34199064799SGarrett Wollman { 34299064799SGarrett Wollman struct rpc_msg rply; 34399064799SGarrett Wollman 34499064799SGarrett Wollman rply.rm_direction = REPLY; 34599064799SGarrett Wollman rply.rm_reply.rp_stat = MSG_ACCEPTED; 34699064799SGarrett Wollman rply.acpted_rply.ar_verf = xprt->xp_verf; 34799064799SGarrett Wollman rply.acpted_rply.ar_stat = PROG_MISMATCH; 34899064799SGarrett Wollman rply.acpted_rply.ar_vers.low = low_vers; 34999064799SGarrett Wollman rply.acpted_rply.ar_vers.high = high_vers; 35099064799SGarrett Wollman SVC_REPLY(xprt, &rply); 35199064799SGarrett Wollman } 35299064799SGarrett Wollman 35399064799SGarrett Wollman /* ******************* SERVER INPUT STUFF ******************* */ 35499064799SGarrett Wollman 35599064799SGarrett Wollman /* 35699064799SGarrett Wollman * Get server side input from some transport. 35799064799SGarrett Wollman * 35899064799SGarrett Wollman * Statement of authentication parameters management: 35999064799SGarrett Wollman * This function owns and manages all authentication parameters, specifically 36099064799SGarrett Wollman * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and 36199064799SGarrett Wollman * the "cooked" credentials (rqst->rq_clntcred). 36299064799SGarrett Wollman * However, this function does not know the structure of the cooked 36399064799SGarrett Wollman * credentials, so it make the following assumptions: 36499064799SGarrett Wollman * a) the structure is contiguous (no pointers), and 36599064799SGarrett Wollman * b) the cred structure size does not exceed RQCRED_SIZE bytes. 36699064799SGarrett Wollman * In all events, all three parameters are freed upon exit from this routine. 36799064799SGarrett Wollman * The storage is trivially management on the call stack in user land, but 36899064799SGarrett Wollman * is mallocated in kernel land. 36999064799SGarrett Wollman */ 37099064799SGarrett Wollman 37199064799SGarrett Wollman void 37299064799SGarrett Wollman svc_getreq(rdfds) 37399064799SGarrett Wollman int rdfds; 37499064799SGarrett Wollman { 37599064799SGarrett Wollman #ifdef FD_SETSIZE 37699064799SGarrett Wollman fd_set readfds; 37799064799SGarrett Wollman 37899064799SGarrett Wollman FD_ZERO(&readfds); 37999064799SGarrett Wollman readfds.fds_bits[0] = rdfds; 38099064799SGarrett Wollman svc_getreqset(&readfds); 38199064799SGarrett Wollman #else 38299064799SGarrett Wollman int readfds = rdfds & svc_fds; 38399064799SGarrett Wollman 38499064799SGarrett Wollman svc_getreqset(&readfds); 38599064799SGarrett Wollman #endif /* def FD_SETSIZE */ 38699064799SGarrett Wollman } 38799064799SGarrett Wollman 38899064799SGarrett Wollman void 38999064799SGarrett Wollman svc_getreqset(readfds) 39099064799SGarrett Wollman #ifdef FD_SETSIZE 39199064799SGarrett Wollman fd_set *readfds; 39299064799SGarrett Wollman { 39399064799SGarrett Wollman #else 39499064799SGarrett Wollman int *readfds; 39599064799SGarrett Wollman { 39699064799SGarrett Wollman int readfds_local = *readfds; 39799064799SGarrett Wollman #endif /* def FD_SETSIZE */ 39899064799SGarrett Wollman enum xprt_stat stat; 39999064799SGarrett Wollman struct rpc_msg msg; 40099064799SGarrett Wollman int prog_found; 40199064799SGarrett Wollman u_long low_vers; 40299064799SGarrett Wollman u_long high_vers; 40399064799SGarrett Wollman struct svc_req r; 40499064799SGarrett Wollman register SVCXPRT *xprt; 40599064799SGarrett Wollman register u_long mask; 40699064799SGarrett Wollman register int bit; 40799064799SGarrett Wollman register u_long *maskp; 40899064799SGarrett Wollman register int setsize; 40999064799SGarrett Wollman register int sock; 41099064799SGarrett Wollman char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE]; 41199064799SGarrett Wollman msg.rm_call.cb_cred.oa_base = cred_area; 41299064799SGarrett Wollman msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); 41399064799SGarrett Wollman r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]); 41499064799SGarrett Wollman 41599064799SGarrett Wollman 41699064799SGarrett Wollman #ifdef FD_SETSIZE 41799064799SGarrett Wollman setsize = _rpc_dtablesize(); 41899064799SGarrett Wollman maskp = (u_long *)readfds->fds_bits; 41999064799SGarrett Wollman for (sock = 0; sock < setsize; sock += NFDBITS) { 42099064799SGarrett Wollman for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) { 42199064799SGarrett Wollman /* sock has input waiting */ 42299064799SGarrett Wollman xprt = xports[sock + bit - 1]; 42399064799SGarrett Wollman #else 42499064799SGarrett Wollman for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) { 42599064799SGarrett Wollman if ((readfds_local & 1) != 0) { 42699064799SGarrett Wollman /* sock has input waiting */ 42799064799SGarrett Wollman xprt = xports[sock]; 42899064799SGarrett Wollman #endif /* def FD_SETSIZE */ 42999064799SGarrett Wollman /* now receive msgs from xprtprt (support batch calls) */ 43099064799SGarrett Wollman do { 43199064799SGarrett Wollman if (SVC_RECV(xprt, &msg)) { 43299064799SGarrett Wollman 43399064799SGarrett Wollman /* now find the exported program and call it */ 43499064799SGarrett Wollman register struct svc_callout *s; 43599064799SGarrett Wollman enum auth_stat why; 43699064799SGarrett Wollman 43799064799SGarrett Wollman r.rq_xprt = xprt; 43899064799SGarrett Wollman r.rq_prog = msg.rm_call.cb_prog; 43999064799SGarrett Wollman r.rq_vers = msg.rm_call.cb_vers; 44099064799SGarrett Wollman r.rq_proc = msg.rm_call.cb_proc; 44199064799SGarrett Wollman r.rq_cred = msg.rm_call.cb_cred; 44299064799SGarrett Wollman /* first authenticate the message */ 44399064799SGarrett Wollman if ((why= _authenticate(&r, &msg)) != AUTH_OK) { 44499064799SGarrett Wollman svcerr_auth(xprt, why); 44599064799SGarrett Wollman goto call_done; 44699064799SGarrett Wollman } 44799064799SGarrett Wollman /* now match message with a registered service*/ 44899064799SGarrett Wollman prog_found = FALSE; 44999064799SGarrett Wollman low_vers = 0 - 1; 45099064799SGarrett Wollman high_vers = 0; 45199064799SGarrett Wollman for (s = svc_head; s != NULL_SVC; s = s->sc_next) { 45299064799SGarrett Wollman if (s->sc_prog == r.rq_prog) { 45399064799SGarrett Wollman if (s->sc_vers == r.rq_vers) { 45499064799SGarrett Wollman (*s->sc_dispatch)(&r, xprt); 45599064799SGarrett Wollman goto call_done; 45699064799SGarrett Wollman } /* found correct version */ 45799064799SGarrett Wollman prog_found = TRUE; 45899064799SGarrett Wollman if (s->sc_vers < low_vers) 45999064799SGarrett Wollman low_vers = s->sc_vers; 46099064799SGarrett Wollman if (s->sc_vers > high_vers) 46199064799SGarrett Wollman high_vers = s->sc_vers; 46299064799SGarrett Wollman } /* found correct program */ 46399064799SGarrett Wollman } 46499064799SGarrett Wollman /* 46599064799SGarrett Wollman * if we got here, the program or version 46699064799SGarrett Wollman * is not served ... 46799064799SGarrett Wollman */ 46899064799SGarrett Wollman if (prog_found) 46999064799SGarrett Wollman svcerr_progvers(xprt, 47099064799SGarrett Wollman low_vers, high_vers); 47199064799SGarrett Wollman else 47299064799SGarrett Wollman svcerr_noprog(xprt); 47399064799SGarrett Wollman /* Fall through to ... */ 47499064799SGarrett Wollman } 47599064799SGarrett Wollman call_done: 47699064799SGarrett Wollman if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ 47799064799SGarrett Wollman SVC_DESTROY(xprt); 47899064799SGarrett Wollman break; 47999064799SGarrett Wollman } 48099064799SGarrett Wollman } while (stat == XPRT_MOREREQS); 48199064799SGarrett Wollman } 48299064799SGarrett Wollman } 48399064799SGarrett Wollman } 484