1 /* $NetBSD: clnt_raw.c,v 1.3 1995/02/25 03:01:40 cgd Exp $ */ 2 3 /* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or 9 * program developed by the user. 10 * 11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14 * 15 * Sun RPC is provided with no support and without any obligation on the 16 * part of Sun Microsystems, Inc. to assist in its use, correction, 17 * modification or enhancement. 18 * 19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21 * OR ANY PART THEREOF. 22 * 23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24 * or profits or other special, indirect and consequential damages, even if 25 * Sun has been advised of the possibility of such damages. 26 * 27 * Sun Microsystems, Inc. 28 * 2550 Garcia Avenue 29 * Mountain View, California 94043 30 */ 31 32 #if defined(LIBC_SCCS) && !defined(lint) 33 /*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/ 34 /*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/ 35 static char *rcsid = "$NetBSD: clnt_raw.c,v 1.3 1995/02/25 03:01:40 cgd Exp $"; 36 #endif 37 38 /* 39 * clnt_raw.c 40 * 41 * Copyright (C) 1984, Sun Microsystems, Inc. 42 * 43 * Memory based rpc for simple testing and timing. 44 * Interface to create an rpc client and server in the same process. 45 * This lets us similate rpc and get round trip overhead, without 46 * any interference from the kernal. 47 */ 48 49 #include <stdlib.h> 50 #include <rpc/rpc.h> 51 52 #define MCALL_MSG_SIZE 24 53 54 /* 55 * This is the "network" we will be moving stuff over. 56 */ 57 static struct clntraw_private { 58 CLIENT client_object; 59 XDR xdr_stream; 60 char _raw_buf[UDPMSGSIZE]; 61 char mashl_callmsg[MCALL_MSG_SIZE]; 62 u_int mcnt; 63 } *clntraw_private; 64 65 static enum clnt_stat clntraw_call(); 66 static void clntraw_abort(); 67 static void clntraw_geterr(); 68 static bool_t clntraw_freeres(); 69 static bool_t clntraw_control(); 70 static void clntraw_destroy(); 71 72 static struct clnt_ops client_ops = { 73 clntraw_call, 74 clntraw_abort, 75 clntraw_geterr, 76 clntraw_freeres, 77 clntraw_destroy, 78 clntraw_control 79 }; 80 81 void svc_getreq(); 82 83 /* 84 * Create a client handle for memory based rpc. 85 */ 86 CLIENT * 87 clntraw_create(prog, vers) 88 u_long prog; 89 u_long vers; 90 { 91 register struct clntraw_private *clp = clntraw_private; 92 struct rpc_msg call_msg; 93 XDR *xdrs = &clp->xdr_stream; 94 CLIENT *client = &clp->client_object; 95 96 if (clp == 0) { 97 clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); 98 if (clp == 0) 99 return (0); 100 clntraw_private = clp; 101 } 102 /* 103 * pre-serialize the staic part of the call msg and stash it away 104 */ 105 call_msg.rm_direction = CALL; 106 call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; 107 call_msg.rm_call.cb_prog = prog; 108 call_msg.rm_call.cb_vers = vers; 109 xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); 110 if (! xdr_callhdr(xdrs, &call_msg)) { 111 perror("clnt_raw.c - Fatal header serialization error."); 112 } 113 clp->mcnt = XDR_GETPOS(xdrs); 114 XDR_DESTROY(xdrs); 115 116 /* 117 * Set xdrmem for client/server shared buffer 118 */ 119 xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE); 120 121 /* 122 * create client handle 123 */ 124 client->cl_ops = &client_ops; 125 client->cl_auth = authnone_create(); 126 return (client); 127 } 128 129 static enum clnt_stat 130 clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) 131 CLIENT *h; 132 u_long proc; 133 xdrproc_t xargs; 134 caddr_t argsp; 135 xdrproc_t xresults; 136 caddr_t resultsp; 137 struct timeval timeout; 138 { 139 register struct clntraw_private *clp = clntraw_private; 140 register XDR *xdrs = &clp->xdr_stream; 141 struct rpc_msg msg; 142 enum clnt_stat status; 143 struct rpc_err error; 144 145 if (clp == 0) 146 return (RPC_FAILED); 147 call_again: 148 /* 149 * send request 150 */ 151 xdrs->x_op = XDR_ENCODE; 152 XDR_SETPOS(xdrs, 0); 153 ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ; 154 if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) || 155 (! XDR_PUTLONG(xdrs, &proc)) || 156 (! AUTH_MARSHALL(h->cl_auth, xdrs)) || 157 (! (*xargs)(xdrs, argsp))) { 158 return (RPC_CANTENCODEARGS); 159 } 160 (void)XDR_GETPOS(xdrs); /* called just to cause overhead */ 161 162 /* 163 * We have to call server input routine here because this is 164 * all going on in one process. Yuk. 165 */ 166 svc_getreq(1); 167 168 /* 169 * get results 170 */ 171 xdrs->x_op = XDR_DECODE; 172 XDR_SETPOS(xdrs, 0); 173 msg.acpted_rply.ar_verf = _null_auth; 174 msg.acpted_rply.ar_results.where = resultsp; 175 msg.acpted_rply.ar_results.proc = xresults; 176 if (! xdr_replymsg(xdrs, &msg)) 177 return (RPC_CANTDECODERES); 178 _seterr_reply(&msg, &error); 179 status = error.re_status; 180 181 if (status == RPC_SUCCESS) { 182 if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { 183 status = RPC_AUTHERROR; 184 } 185 } /* end successful completion */ 186 else { 187 if (AUTH_REFRESH(h->cl_auth)) 188 goto call_again; 189 } /* end of unsuccessful completion */ 190 191 if (status == RPC_SUCCESS) { 192 if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { 193 status = RPC_AUTHERROR; 194 } 195 if (msg.acpted_rply.ar_verf.oa_base != NULL) { 196 xdrs->x_op = XDR_FREE; 197 (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf)); 198 } 199 } 200 201 return (status); 202 } 203 204 static void 205 clntraw_geterr() 206 { 207 } 208 209 210 static bool_t 211 clntraw_freeres(cl, xdr_res, res_ptr) 212 CLIENT *cl; 213 xdrproc_t xdr_res; 214 caddr_t res_ptr; 215 { 216 register struct clntraw_private *clp = clntraw_private; 217 register XDR *xdrs = &clp->xdr_stream; 218 bool_t rval; 219 220 if (clp == 0) 221 { 222 rval = (bool_t) RPC_FAILED; 223 return (rval); 224 } 225 xdrs->x_op = XDR_FREE; 226 return ((*xdr_res)(xdrs, res_ptr)); 227 } 228 229 static void 230 clntraw_abort() 231 { 232 } 233 234 static bool_t 235 clntraw_control() 236 { 237 return (FALSE); 238 } 239 240 static void 241 clntraw_destroy() 242 { 243 } 244