| 1 |  |  | /*	$OpenBSD: svc_simple.c,v 1.13 2015/09/01 19:54:01 deraadt Exp $ */ | 
    
    | 2 |  |  |  | 
    
    | 3 |  |  | /* | 
    
    | 4 |  |  |  * Copyright (c) 2010, Oracle America, Inc. | 
    
    | 5 |  |  |  * | 
    
    | 6 |  |  |  * Redistribution and use in source and binary forms, with or without | 
    
    | 7 |  |  |  * modification, are permitted provided that the following conditions are | 
    
    | 8 |  |  |  * met: | 
    
    | 9 |  |  |  * | 
    
    | 10 |  |  |  *     * Redistributions of source code must retain the above copyright | 
    
    | 11 |  |  |  *       notice, this list of conditions and the following disclaimer. | 
    
    | 12 |  |  |  *     * Redistributions in binary form must reproduce the above | 
    
    | 13 |  |  |  *       copyright notice, this list of conditions and the following | 
    
    | 14 |  |  |  *       disclaimer in the documentation and/or other materials | 
    
    | 15 |  |  |  *       provided with the distribution. | 
    
    | 16 |  |  |  *     * Neither the name of the "Oracle America, Inc." nor the names of its | 
    
    | 17 |  |  |  *       contributors may be used to endorse or promote products derived | 
    
    | 18 |  |  |  *       from this software without specific prior written permission. | 
    
    | 19 |  |  |  * | 
    
    | 20 |  |  |  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
    
    | 21 |  |  |  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
    
    | 22 |  |  |  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 
    
    | 23 |  |  |  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 
    
    | 24 |  |  |  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | 
    
    | 25 |  |  |  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
    
    | 26 |  |  |  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | 
    
    | 27 |  |  |  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 
    
    | 28 |  |  |  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 
    
    | 29 |  |  |  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 
    
    | 30 |  |  |  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
    
    | 31 |  |  |  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
    
    | 32 |  |  |  */ | 
    
    | 33 |  |  |  | 
    
    | 34 |  |  | /* | 
    
    | 35 |  |  |  * svc_simple.c | 
    
    | 36 |  |  |  * Simplified front end to rpc. | 
    
    | 37 |  |  |  */ | 
    
    | 38 |  |  |  | 
    
    | 39 |  |  | #include <stdio.h> | 
    
    | 40 |  |  | #include <stdlib.h> | 
    
    | 41 |  |  | #include <string.h> | 
    
    | 42 |  |  | #include <rpc/rpc.h> | 
    
    | 43 |  |  | #include <rpc/pmap_clnt.h> | 
    
    | 44 |  |  | #include <sys/socket.h> | 
    
    | 45 |  |  | #include <netdb.h> | 
    
    | 46 |  |  |  | 
    
    | 47 |  |  | static struct proglst { | 
    
    | 48 |  |  | 	char *(*p_progname)(); | 
    
    | 49 |  |  | 	int  p_prognum; | 
    
    | 50 |  |  | 	int  p_procnum; | 
    
    | 51 |  |  | 	xdrproc_t p_inproc, p_outproc; | 
    
    | 52 |  |  | 	struct proglst *p_nxt; | 
    
    | 53 |  |  | } *proglst; | 
    
    | 54 |  |  | static void universal(struct svc_req *, SVCXPRT *); | 
    
    | 55 |  |  | static SVCXPRT *transp; | 
    
    | 56 |  |  |  | 
    
    | 57 |  |  | int | 
    
    | 58 |  |  | registerrpc(int prognum, int versnum, int procnum, char *(*progname)(), | 
    
    | 59 |  |  |     xdrproc_t inproc, xdrproc_t outproc) | 
    
    | 60 |  |  | { | 
    
    | 61 |  |  | 	struct proglst *pl; | 
    
    | 62 |  |  |  | 
    
    | 63 |  |  | 	if (procnum == NULLPROC) | 
    
    | 64 |  |  | 		return (-1); | 
    
    | 65 |  |  | 	if (transp == NULL) { | 
    
    | 66 |  |  | 		transp = svcudp_create(RPC_ANYSOCK); | 
    
    | 67 |  |  | 		if (transp == NULL) | 
    
    | 68 |  |  | 			return (-1); | 
    
    | 69 |  |  | 	} | 
    
    | 70 |  |  | 	(void) pmap_unset((u_long)prognum, (u_long)versnum); | 
    
    | 71 |  |  | 	if (!svc_register(transp, (u_long)prognum, (u_long)versnum, | 
    
    | 72 |  |  | 	    universal, IPPROTO_UDP)) | 
    
    | 73 |  |  | 		return (-1); | 
    
    | 74 |  |  | 	pl = malloc(sizeof(struct proglst)); | 
    
    | 75 |  |  | 	if (pl == NULL) | 
    
    | 76 |  |  | 		return (-1); | 
    
    | 77 |  |  | 	pl->p_progname = progname; | 
    
    | 78 |  |  | 	pl->p_prognum = prognum; | 
    
    | 79 |  |  | 	pl->p_procnum = procnum; | 
    
    | 80 |  |  | 	pl->p_inproc = inproc; | 
    
    | 81 |  |  | 	pl->p_outproc = outproc; | 
    
    | 82 |  |  | 	pl->p_nxt = proglst; | 
    
    | 83 |  |  | 	proglst = pl; | 
    
    | 84 |  |  | 	return (0); | 
    
    | 85 |  |  | } | 
    
    | 86 |  |  |  | 
    
    | 87 |  |  | static void | 
    
    | 88 |  |  | universal(struct svc_req *rqstp, SVCXPRT *transp) | 
    
    | 89 |  |  | { | 
    
    | 90 |  |  | 	int prog, proc; | 
    
    | 91 |  |  | 	char *outdata; | 
    
    | 92 |  |  | 	char xdrbuf[UDPMSGSIZE]; | 
    
    | 93 |  |  | 	struct proglst *pl; | 
    
    | 94 |  |  |  | 
    
    | 95 |  |  | 	/* | 
    
    | 96 |  |  | 	 * enforce "procnum 0 is echo" convention | 
    
    | 97 |  |  | 	 */ | 
    
    | 98 |  |  | 	if (rqstp->rq_proc == NULLPROC) { | 
    
    | 99 |  |  | 		if (svc_sendreply(transp, xdr_void, NULL) == FALSE) | 
    
    | 100 |  |  | 			exit(1); | 
    
    | 101 |  |  | 		return; | 
    
    | 102 |  |  | 	} | 
    
    | 103 |  |  | 	prog = rqstp->rq_prog; | 
    
    | 104 |  |  | 	proc = rqstp->rq_proc; | 
    
    | 105 |  |  | 	for (pl = proglst; pl != NULL; pl = pl->p_nxt) | 
    
    | 106 |  |  | 		if (pl->p_prognum == prog && pl->p_procnum == proc) { | 
    
    | 107 |  |  | 			/* decode arguments into a CLEAN buffer */ | 
    
    | 108 |  |  | 			memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */ | 
    
    | 109 |  |  | 			if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) { | 
    
    | 110 |  |  | 				svcerr_decode(transp); | 
    
    | 111 |  |  | 				return; | 
    
    | 112 |  |  | 			} | 
    
    | 113 |  |  | 			outdata = (*(pl->p_progname))(xdrbuf); | 
    
    | 114 |  |  | 			if (outdata == NULL && | 
    
    | 115 |  |  | 			    pl->p_outproc != xdr_void) | 
    
    | 116 |  |  | 				/* there was an error */ | 
    
    | 117 |  |  | 				return; | 
    
    | 118 |  |  | 			if (!svc_sendreply(transp, pl->p_outproc, outdata)) | 
    
    | 119 |  |  | 				exit(1); | 
    
    | 120 |  |  | 			/* free the decoded arguments */ | 
    
    | 121 |  |  | 			(void)svc_freeargs(transp, pl->p_inproc, xdrbuf); | 
    
    | 122 |  |  | 			return; | 
    
    | 123 |  |  | 		} | 
    
    | 124 |  |  | 	exit(1); | 
    
    | 125 |  |  | } | 
    
    | 126 |  |  |  |