1*ba96d07fShrs /*- 2*ba96d07fShrs * Copyright (c) 2009, Sun Microsystems, Inc. 3*ba96d07fShrs * All rights reserved. 4ce0e08e2SPeter Avalos * 5*ba96d07fShrs * Redistribution and use in source and binary forms, with or without 6*ba96d07fShrs * modification, are permitted provided that the following conditions are met: 7*ba96d07fShrs * - Redistributions of source code must retain the above copyright notice, 8*ba96d07fShrs * this list of conditions and the following disclaimer. 9*ba96d07fShrs * - Redistributions in binary form must reproduce the above copyright notice, 10*ba96d07fShrs * this list of conditions and the following disclaimer in the documentation 11*ba96d07fShrs * and/or other materials provided with the distribution. 12*ba96d07fShrs * - Neither the name of Sun Microsystems, Inc. nor the names of its 13*ba96d07fShrs * contributors may be used to endorse or promote products derived 14*ba96d07fShrs * from this software without specific prior written permission. 15ce0e08e2SPeter Avalos * 16*ba96d07fShrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17*ba96d07fShrs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*ba96d07fShrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*ba96d07fShrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20*ba96d07fShrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*ba96d07fShrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*ba96d07fShrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23*ba96d07fShrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24*ba96d07fShrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25*ba96d07fShrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26*ba96d07fShrs * POSSIBILITY OF SUCH DAMAGE. 27ce0e08e2SPeter Avalos * 28ce0e08e2SPeter Avalos * @(#)rpc_soc.c 1.17 94/04/24 SMI; 1.41 89/05/02 Copyr 1988 Sun Micro 29ce0e08e2SPeter Avalos * $NetBSD: rpc_soc.c,v 1.6 2000/07/06 03:10:35 christos Exp $ 30ce0e08e2SPeter Avalos * $FreeBSD: src/lib/libc/rpc/rpc_soc.c,v 1.15 2006/02/27 22:10:59 deischen Exp $ 31ce0e08e2SPeter Avalos */ 32ce0e08e2SPeter Avalos 33ce0e08e2SPeter Avalos /* 34ce0e08e2SPeter Avalos * Copyright (c) 1986-1991 by Sun Microsystems Inc. 35ce0e08e2SPeter Avalos * In addition, portions of such source code were derived from Berkeley 36ce0e08e2SPeter Avalos * 4.3 BSD under license from the Regents of the University of 37ce0e08e2SPeter Avalos * California. 38ce0e08e2SPeter Avalos */ 39ce0e08e2SPeter Avalos 40ce0e08e2SPeter Avalos #ifdef PORTMAP 41ce0e08e2SPeter Avalos /* 42ce0e08e2SPeter Avalos * rpc_soc.c 43ce0e08e2SPeter Avalos * 44ce0e08e2SPeter Avalos * The backward compatibility routines for the earlier implementation 45ce0e08e2SPeter Avalos * of RPC, where the only transports supported were tcp/ip and udp/ip. 46ce0e08e2SPeter Avalos * Based on berkeley socket abstraction, now implemented on the top 47ce0e08e2SPeter Avalos * of TLI/Streams 48ce0e08e2SPeter Avalos */ 49ce0e08e2SPeter Avalos 50ce0e08e2SPeter Avalos #include "namespace.h" 51ce0e08e2SPeter Avalos #include "reentrant.h" 52ce0e08e2SPeter Avalos #include <sys/types.h> 53ce0e08e2SPeter Avalos #include <sys/socket.h> 54ce0e08e2SPeter Avalos #include <stdio.h> 55ce0e08e2SPeter Avalos #include <rpc/rpc.h> 56ce0e08e2SPeter Avalos #include <rpc/pmap_clnt.h> 57ce0e08e2SPeter Avalos #include <rpc/pmap_prot.h> 58ce0e08e2SPeter Avalos #include <rpc/nettype.h> 59ce0e08e2SPeter Avalos #include <syslog.h> 60ce0e08e2SPeter Avalos #include <netinet/in.h> 61ce0e08e2SPeter Avalos #include <netdb.h> 62ce0e08e2SPeter Avalos #include <errno.h> 63ce0e08e2SPeter Avalos #include <stdlib.h> 64ce0e08e2SPeter Avalos #include <string.h> 65ce0e08e2SPeter Avalos #include <unistd.h> 66ce0e08e2SPeter Avalos #include "un-namespace.h" 67ce0e08e2SPeter Avalos 68ce0e08e2SPeter Avalos #include "rpc_com.h" 69ce0e08e2SPeter Avalos #include "mt_misc.h" 70ce0e08e2SPeter Avalos 71ce0e08e2SPeter Avalos static CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, 72ce0e08e2SPeter Avalos int *, u_int, u_int, char *); 73ce0e08e2SPeter Avalos static SVCXPRT *svc_com_create(int, u_int, u_int, char *); 74ce0e08e2SPeter Avalos static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *); 75ce0e08e2SPeter Avalos 76ce0e08e2SPeter Avalos /* XXX */ 77ce0e08e2SPeter Avalos #define IN4_LOCALHOST_STRING "127.0.0.1" 78ce0e08e2SPeter Avalos #define IN6_LOCALHOST_STRING "::1" 79ce0e08e2SPeter Avalos 80ce0e08e2SPeter Avalos /* 81ce0e08e2SPeter Avalos * A common clnt create routine 82ce0e08e2SPeter Avalos */ 83ce0e08e2SPeter Avalos static CLIENT * 84ce0e08e2SPeter Avalos clnt_com_create(struct sockaddr_in *raddr, rpcprog_t prog, rpcvers_t vers, 85ce0e08e2SPeter Avalos int *sockp, u_int sendsz, u_int recvsz, char *tp) 86ce0e08e2SPeter Avalos { 87ce0e08e2SPeter Avalos CLIENT *cl; 88ce0e08e2SPeter Avalos int madefd = FALSE; 89ce0e08e2SPeter Avalos int fd = *sockp; 90ce0e08e2SPeter Avalos struct netconfig *nconf; 91ce0e08e2SPeter Avalos struct netbuf bindaddr; 92ce0e08e2SPeter Avalos 93ce0e08e2SPeter Avalos mutex_lock(&rpcsoc_lock); 94ce0e08e2SPeter Avalos if ((nconf = __rpc_getconfip(tp)) == NULL) { 95ce0e08e2SPeter Avalos rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 96ce0e08e2SPeter Avalos mutex_unlock(&rpcsoc_lock); 97ce0e08e2SPeter Avalos return (NULL); 98ce0e08e2SPeter Avalos } 99ce0e08e2SPeter Avalos if (fd == RPC_ANYSOCK) { 100ce0e08e2SPeter Avalos fd = __rpc_nconf2fd(nconf); 101ce0e08e2SPeter Avalos if (fd == -1) 102ce0e08e2SPeter Avalos goto syserror; 103ce0e08e2SPeter Avalos madefd = TRUE; 104ce0e08e2SPeter Avalos } 105ce0e08e2SPeter Avalos 106ce0e08e2SPeter Avalos if (raddr->sin_port == 0) { 107ce0e08e2SPeter Avalos u_int proto; 108ce0e08e2SPeter Avalos u_short sport; 109ce0e08e2SPeter Avalos 110ce0e08e2SPeter Avalos mutex_unlock(&rpcsoc_lock); /* pmap_getport is recursive */ 111ce0e08e2SPeter Avalos proto = strcmp(tp, "udp") == 0 ? IPPROTO_UDP : IPPROTO_TCP; 112ce0e08e2SPeter Avalos sport = pmap_getport(raddr, (u_long)prog, (u_long)vers, 113ce0e08e2SPeter Avalos proto); 114ce0e08e2SPeter Avalos if (sport == 0) { 115ce0e08e2SPeter Avalos goto err; 116ce0e08e2SPeter Avalos } 117ce0e08e2SPeter Avalos raddr->sin_port = htons(sport); 118ce0e08e2SPeter Avalos mutex_lock(&rpcsoc_lock); /* pmap_getport is recursive */ 119ce0e08e2SPeter Avalos } 120ce0e08e2SPeter Avalos 121ce0e08e2SPeter Avalos /* Transform sockaddr_in to netbuf */ 122ce0e08e2SPeter Avalos bindaddr.maxlen = bindaddr.len = sizeof (struct sockaddr_in); 123ce0e08e2SPeter Avalos bindaddr.buf = raddr; 124ce0e08e2SPeter Avalos 125ce0e08e2SPeter Avalos bindresvport(fd, NULL); 126ce0e08e2SPeter Avalos cl = clnt_tli_create(fd, nconf, &bindaddr, prog, vers, 127ce0e08e2SPeter Avalos sendsz, recvsz); 128ce0e08e2SPeter Avalos if (cl) { 129ce0e08e2SPeter Avalos if (madefd == TRUE) { 130ce0e08e2SPeter Avalos /* 131ce0e08e2SPeter Avalos * The fd should be closed while destroying the handle. 132ce0e08e2SPeter Avalos */ 133ce0e08e2SPeter Avalos CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); 134ce0e08e2SPeter Avalos *sockp = fd; 135ce0e08e2SPeter Avalos } 136ce0e08e2SPeter Avalos freenetconfigent(nconf); 137ce0e08e2SPeter Avalos mutex_unlock(&rpcsoc_lock); 138ce0e08e2SPeter Avalos return (cl); 139ce0e08e2SPeter Avalos } 140ce0e08e2SPeter Avalos goto err; 141ce0e08e2SPeter Avalos 142ce0e08e2SPeter Avalos syserror: 143ce0e08e2SPeter Avalos rpc_createerr.cf_stat = RPC_SYSTEMERROR; 144ce0e08e2SPeter Avalos rpc_createerr.cf_error.re_errno = errno; 145ce0e08e2SPeter Avalos 146ce0e08e2SPeter Avalos err: if (madefd == TRUE) 147ce0e08e2SPeter Avalos _close(fd); 148ce0e08e2SPeter Avalos freenetconfigent(nconf); 149ce0e08e2SPeter Avalos mutex_unlock(&rpcsoc_lock); 150ce0e08e2SPeter Avalos return (NULL); 151ce0e08e2SPeter Avalos } 152ce0e08e2SPeter Avalos 153ce0e08e2SPeter Avalos CLIENT * 154ce0e08e2SPeter Avalos clntudp_bufcreate(struct sockaddr_in *raddr, u_long prog, u_long vers, 155ce0e08e2SPeter Avalos struct timeval wait, int *sockp, u_int sendsz, u_int recvsz) 156ce0e08e2SPeter Avalos { 157ce0e08e2SPeter Avalos CLIENT *cl; 158ce0e08e2SPeter Avalos 159ce0e08e2SPeter Avalos cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 160ce0e08e2SPeter Avalos sendsz, recvsz, "udp"); 161ce0e08e2SPeter Avalos if (cl == NULL) { 162ce0e08e2SPeter Avalos return (NULL); 163ce0e08e2SPeter Avalos } 164ce0e08e2SPeter Avalos CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait); 165ce0e08e2SPeter Avalos return (cl); 166ce0e08e2SPeter Avalos } 167ce0e08e2SPeter Avalos 168ce0e08e2SPeter Avalos CLIENT * 169ce0e08e2SPeter Avalos clntudp_create(struct sockaddr_in *raddr, u_long program, u_long version, 170ce0e08e2SPeter Avalos struct timeval wait, int *sockp) 171ce0e08e2SPeter Avalos { 172ce0e08e2SPeter Avalos 173ce0e08e2SPeter Avalos return clntudp_bufcreate(raddr, program, version, wait, sockp, 174ce0e08e2SPeter Avalos UDPMSGSIZE, UDPMSGSIZE); 175ce0e08e2SPeter Avalos } 176ce0e08e2SPeter Avalos 177ce0e08e2SPeter Avalos CLIENT * 178ce0e08e2SPeter Avalos clnttcp_create(struct sockaddr_in *raddr, u_long prog, u_long vers, int *sockp, 179ce0e08e2SPeter Avalos u_int sendsz, u_int recvsz) 180ce0e08e2SPeter Avalos { 181ce0e08e2SPeter Avalos 182ce0e08e2SPeter Avalos return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 183ce0e08e2SPeter Avalos sendsz, recvsz, "tcp"); 184ce0e08e2SPeter Avalos } 185ce0e08e2SPeter Avalos 186ce0e08e2SPeter Avalos CLIENT * 187ce0e08e2SPeter Avalos clntraw_create(u_long prog, u_long vers) 188ce0e08e2SPeter Avalos { 189ce0e08e2SPeter Avalos 190ce0e08e2SPeter Avalos return clnt_raw_create((rpcprog_t)prog, (rpcvers_t)vers); 191ce0e08e2SPeter Avalos } 192ce0e08e2SPeter Avalos 193ce0e08e2SPeter Avalos /* 194ce0e08e2SPeter Avalos * A common server create routine 195ce0e08e2SPeter Avalos */ 196ce0e08e2SPeter Avalos static SVCXPRT * 197ce0e08e2SPeter Avalos svc_com_create(int fd, u_int sendsize, u_int recvsize, char *netid) 198ce0e08e2SPeter Avalos { 199ce0e08e2SPeter Avalos struct netconfig *nconf; 200ce0e08e2SPeter Avalos SVCXPRT *svc; 201ce0e08e2SPeter Avalos int madefd = FALSE; 202ce0e08e2SPeter Avalos int port; 203ce0e08e2SPeter Avalos struct sockaddr_in sin; 204ce0e08e2SPeter Avalos 205ce0e08e2SPeter Avalos if ((nconf = __rpc_getconfip(netid)) == NULL) { 206ce0e08e2SPeter Avalos syslog(LOG_ERR, "Could not get %s transport", netid); 207ce0e08e2SPeter Avalos return (NULL); 208ce0e08e2SPeter Avalos } 209ce0e08e2SPeter Avalos if (fd == RPC_ANYSOCK) { 210ce0e08e2SPeter Avalos fd = __rpc_nconf2fd(nconf); 211ce0e08e2SPeter Avalos if (fd == -1) { 212ce0e08e2SPeter Avalos freenetconfigent(nconf); 213ce0e08e2SPeter Avalos syslog(LOG_ERR, 214ce0e08e2SPeter Avalos "svc%s_create: could not open connection", netid); 215ce0e08e2SPeter Avalos return (NULL); 216ce0e08e2SPeter Avalos } 217ce0e08e2SPeter Avalos madefd = TRUE; 218ce0e08e2SPeter Avalos } 219ce0e08e2SPeter Avalos 220ce0e08e2SPeter Avalos memset(&sin, 0, sizeof sin); 221ce0e08e2SPeter Avalos sin.sin_family = AF_INET; 222ce0e08e2SPeter Avalos bindresvport(fd, &sin); 223ce0e08e2SPeter Avalos _listen(fd, SOMAXCONN); 224ce0e08e2SPeter Avalos svc = svc_tli_create(fd, nconf, NULL, sendsize, recvsize); 225ce0e08e2SPeter Avalos freenetconfigent(nconf); 226ce0e08e2SPeter Avalos if (svc == NULL) { 227ce0e08e2SPeter Avalos if (madefd) 228ce0e08e2SPeter Avalos _close(fd); 229ce0e08e2SPeter Avalos return (NULL); 230ce0e08e2SPeter Avalos } 231ce0e08e2SPeter Avalos port = (((struct sockaddr_in *)svc->xp_ltaddr.buf)->sin_port); 232ce0e08e2SPeter Avalos svc->xp_port = ntohs(port); 233ce0e08e2SPeter Avalos return (svc); 234ce0e08e2SPeter Avalos } 235ce0e08e2SPeter Avalos 236ce0e08e2SPeter Avalos SVCXPRT * 237ce0e08e2SPeter Avalos svctcp_create(int fd, u_int sendsize, u_int recvsize) 238ce0e08e2SPeter Avalos { 239ce0e08e2SPeter Avalos 240ce0e08e2SPeter Avalos return svc_com_create(fd, sendsize, recvsize, "tcp"); 241ce0e08e2SPeter Avalos } 242ce0e08e2SPeter Avalos 243ce0e08e2SPeter Avalos SVCXPRT * 244ce0e08e2SPeter Avalos svcudp_bufcreate(int fd, u_int sendsz, u_int recvsz) 245ce0e08e2SPeter Avalos { 246ce0e08e2SPeter Avalos 247ce0e08e2SPeter Avalos return svc_com_create(fd, sendsz, recvsz, "udp"); 248ce0e08e2SPeter Avalos } 249ce0e08e2SPeter Avalos 250ce0e08e2SPeter Avalos SVCXPRT * 251ce0e08e2SPeter Avalos svcfd_create(int fd, u_int sendsize, u_int recvsize) 252ce0e08e2SPeter Avalos { 253ce0e08e2SPeter Avalos 254ce0e08e2SPeter Avalos return svc_fd_create(fd, sendsize, recvsize); 255ce0e08e2SPeter Avalos } 256ce0e08e2SPeter Avalos 257ce0e08e2SPeter Avalos 258ce0e08e2SPeter Avalos SVCXPRT * 259ce0e08e2SPeter Avalos svcudp_create(int fd) 260ce0e08e2SPeter Avalos { 261ce0e08e2SPeter Avalos 262ce0e08e2SPeter Avalos return svc_com_create(fd, UDPMSGSIZE, UDPMSGSIZE, "udp"); 263ce0e08e2SPeter Avalos } 264ce0e08e2SPeter Avalos 265ce0e08e2SPeter Avalos SVCXPRT * 266ce0e08e2SPeter Avalos svcraw_create(void) 267ce0e08e2SPeter Avalos { 268ce0e08e2SPeter Avalos 269ce0e08e2SPeter Avalos return svc_raw_create(); 270ce0e08e2SPeter Avalos } 271ce0e08e2SPeter Avalos 272ce0e08e2SPeter Avalos int 273ce0e08e2SPeter Avalos get_myaddress(struct sockaddr_in *addr) 274ce0e08e2SPeter Avalos { 275ce0e08e2SPeter Avalos 276ce0e08e2SPeter Avalos memset((void *) addr, 0, sizeof(*addr)); 277ce0e08e2SPeter Avalos addr->sin_family = AF_INET; 278ce0e08e2SPeter Avalos addr->sin_port = htons(PMAPPORT); 279ce0e08e2SPeter Avalos addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); 280ce0e08e2SPeter Avalos return (0); 281ce0e08e2SPeter Avalos } 282ce0e08e2SPeter Avalos 283ce0e08e2SPeter Avalos /* 284ce0e08e2SPeter Avalos * For connectionless "udp" transport. Obsoleted by rpc_call(). 285ce0e08e2SPeter Avalos */ 286ce0e08e2SPeter Avalos int 287ce0e08e2SPeter Avalos callrpc(const char *host, int prognum, int versnum, int procnum, 288ce0e08e2SPeter Avalos xdrproc_t inproc, void *in, xdrproc_t outproc, void *out) 289ce0e08e2SPeter Avalos { 290ce0e08e2SPeter Avalos 291ce0e08e2SPeter Avalos return (int)rpc_call(host, (rpcprog_t)prognum, (rpcvers_t)versnum, 292ce0e08e2SPeter Avalos (rpcproc_t)procnum, inproc, in, outproc, out, "udp"); 293ce0e08e2SPeter Avalos } 294ce0e08e2SPeter Avalos 295ce0e08e2SPeter Avalos /* 296ce0e08e2SPeter Avalos * For connectionless kind of transport. Obsoleted by rpc_reg() 297ce0e08e2SPeter Avalos */ 298ce0e08e2SPeter Avalos int 299ce0e08e2SPeter Avalos registerrpc(int prognum, int versnum, int procnum, char *(*progname)(char *), 300ce0e08e2SPeter Avalos xdrproc_t inproc, xdrproc_t outproc) 301ce0e08e2SPeter Avalos { 302ce0e08e2SPeter Avalos 303ce0e08e2SPeter Avalos return rpc_reg((rpcprog_t)prognum, (rpcvers_t)versnum, 304ce0e08e2SPeter Avalos (rpcproc_t)procnum, progname, inproc, outproc, "udp"); 305ce0e08e2SPeter Avalos } 306ce0e08e2SPeter Avalos 307ce0e08e2SPeter Avalos /* 308ce0e08e2SPeter Avalos * All the following clnt_broadcast stuff is convulated; it supports 309ce0e08e2SPeter Avalos * the earlier calling style of the callback function 310ce0e08e2SPeter Avalos */ 311ce0e08e2SPeter Avalos static thread_key_t clnt_broadcast_key; 312ce0e08e2SPeter Avalos static resultproc_t clnt_broadcast_result_main; 313ce0e08e2SPeter Avalos 314ce0e08e2SPeter Avalos /* 315ce0e08e2SPeter Avalos * Need to translate the netbuf address into sockaddr_in address. 316ce0e08e2SPeter Avalos * Dont care about netid here. 317ce0e08e2SPeter Avalos */ 318ce0e08e2SPeter Avalos /* ARGSUSED */ 319ce0e08e2SPeter Avalos static bool_t 320ce0e08e2SPeter Avalos rpc_wrap_bcast(char *resultp, /* results of the call */ 321ce0e08e2SPeter Avalos struct netbuf *addr, /* address of the guy who responded */ 322ce0e08e2SPeter Avalos struct netconfig *nconf) /* Netconf of the transport */ 323ce0e08e2SPeter Avalos { 324ce0e08e2SPeter Avalos resultproc_t clnt_broadcast_result; 325ce0e08e2SPeter Avalos 326ce0e08e2SPeter Avalos if (strcmp(nconf->nc_netid, "udp")) 327ce0e08e2SPeter Avalos return (FALSE); 328ce0e08e2SPeter Avalos if (thr_main()) 329ce0e08e2SPeter Avalos clnt_broadcast_result = clnt_broadcast_result_main; 330ce0e08e2SPeter Avalos else 331ce0e08e2SPeter Avalos clnt_broadcast_result = (resultproc_t)thr_getspecific(clnt_broadcast_key); 332ce0e08e2SPeter Avalos return (*clnt_broadcast_result)(resultp, 333ce0e08e2SPeter Avalos (struct sockaddr_in *)addr->buf); 334ce0e08e2SPeter Avalos } 335ce0e08e2SPeter Avalos 336ce0e08e2SPeter Avalos /* 337ce0e08e2SPeter Avalos * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). 338ce0e08e2SPeter Avalos */ 339ce0e08e2SPeter Avalos enum clnt_stat 340ce0e08e2SPeter Avalos clnt_broadcast(u_long prog, /* program number */ 341ce0e08e2SPeter Avalos u_long vers, /* version number */ 342ce0e08e2SPeter Avalos u_long proc, /* procedure number */ 343ce0e08e2SPeter Avalos xdrproc_t xargs, /* xdr routine for args */ 344ce0e08e2SPeter Avalos void *argsp, /* pointer to args */ 345ce0e08e2SPeter Avalos xdrproc_t xresults, /* xdr routine for results */ 346ce0e08e2SPeter Avalos void *resultsp, /* pointer to results */ 347ce0e08e2SPeter Avalos resultproc_t eachresult) /* call with each result obtained */ 348ce0e08e2SPeter Avalos { 349ce0e08e2SPeter Avalos 350ce0e08e2SPeter Avalos if (thr_main()) 351ce0e08e2SPeter Avalos clnt_broadcast_result_main = eachresult; 352ce0e08e2SPeter Avalos else { 353ce0e08e2SPeter Avalos if (clnt_broadcast_key == 0) { 354ce0e08e2SPeter Avalos mutex_lock(&tsd_lock); 355ce0e08e2SPeter Avalos if (clnt_broadcast_key == 0) 356ce0e08e2SPeter Avalos thr_keycreate(&clnt_broadcast_key, free); 357ce0e08e2SPeter Avalos mutex_unlock(&tsd_lock); 358ce0e08e2SPeter Avalos } 359ce0e08e2SPeter Avalos thr_setspecific(clnt_broadcast_key, (void *) eachresult); 360ce0e08e2SPeter Avalos } 361ce0e08e2SPeter Avalos return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, 362ce0e08e2SPeter Avalos (rpcproc_t)proc, xargs, argsp, xresults, resultsp, 363ce0e08e2SPeter Avalos (resultproc_t) rpc_wrap_bcast, "udp"); 364ce0e08e2SPeter Avalos } 365ce0e08e2SPeter Avalos 366ce0e08e2SPeter Avalos /* 367ce0e08e2SPeter Avalos * Create the client des authentication object. Obsoleted by 368ce0e08e2SPeter Avalos * authdes_seccreate(). 369ce0e08e2SPeter Avalos */ 370ce0e08e2SPeter Avalos AUTH * 371ce0e08e2SPeter Avalos authdes_create(char *servername, /* network name of server */ 372ce0e08e2SPeter Avalos u_int window, /* time to live */ 373ce0e08e2SPeter Avalos struct sockaddr *syncaddr,/* optional hostaddr to sync with */ 374ce0e08e2SPeter Avalos des_block *ckey) /* optional conversation key to use */ 375ce0e08e2SPeter Avalos { 376ce0e08e2SPeter Avalos AUTH *dummy; 377ce0e08e2SPeter Avalos AUTH *nauth; 378ce0e08e2SPeter Avalos char hostname[NI_MAXHOST]; 379ce0e08e2SPeter Avalos 380ce0e08e2SPeter Avalos if (syncaddr) { 381ce0e08e2SPeter Avalos /* 382ce0e08e2SPeter Avalos * Change addr to hostname, because that is the way 383ce0e08e2SPeter Avalos * new interface takes it. 384ce0e08e2SPeter Avalos */ 385ce0e08e2SPeter Avalos if (getnameinfo(syncaddr, syncaddr->sa_len, hostname, 386ce0e08e2SPeter Avalos sizeof hostname, NULL, 0, 0) != 0) 387ce0e08e2SPeter Avalos goto fallback; 388ce0e08e2SPeter Avalos 389ce0e08e2SPeter Avalos nauth = authdes_seccreate(servername, window, hostname, ckey); 390ce0e08e2SPeter Avalos return (nauth); 391ce0e08e2SPeter Avalos } 392ce0e08e2SPeter Avalos fallback: 393ce0e08e2SPeter Avalos dummy = authdes_seccreate(servername, window, NULL, ckey); 394ce0e08e2SPeter Avalos return (dummy); 395ce0e08e2SPeter Avalos } 396ce0e08e2SPeter Avalos 397ce0e08e2SPeter Avalos /* 398ce0e08e2SPeter Avalos * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() 399ce0e08e2SPeter Avalos */ 400ce0e08e2SPeter Avalos CLIENT * 401ce0e08e2SPeter Avalos clntunix_create(struct sockaddr_un *raddr, u_long prog, u_long vers, int *sockp, 402ce0e08e2SPeter Avalos u_int sendsz, u_int recvsz) 403ce0e08e2SPeter Avalos { 404ce0e08e2SPeter Avalos struct netbuf *svcaddr; 405ce0e08e2SPeter Avalos struct netconfig *nconf; 406ce0e08e2SPeter Avalos CLIENT *cl; 407ce0e08e2SPeter Avalos int len; 408ce0e08e2SPeter Avalos 409ce0e08e2SPeter Avalos cl = NULL; 410ce0e08e2SPeter Avalos nconf = NULL; 411ce0e08e2SPeter Avalos svcaddr = NULL; 412ce0e08e2SPeter Avalos if ((raddr->sun_len == 0) || 413ce0e08e2SPeter Avalos ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || 414ce0e08e2SPeter Avalos ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { 415ce0e08e2SPeter Avalos if (svcaddr != NULL) 416ce0e08e2SPeter Avalos free(svcaddr); 417ce0e08e2SPeter Avalos rpc_createerr.cf_stat = RPC_SYSTEMERROR; 418ce0e08e2SPeter Avalos rpc_createerr.cf_error.re_errno = errno; 419ce0e08e2SPeter Avalos return(cl); 420ce0e08e2SPeter Avalos } 421ce0e08e2SPeter Avalos if (*sockp < 0) { 422ce0e08e2SPeter Avalos *sockp = _socket(AF_LOCAL, SOCK_STREAM, 0); 423ce0e08e2SPeter Avalos len = raddr->sun_len = SUN_LEN(raddr); 424ce0e08e2SPeter Avalos if ((*sockp < 0) || (_connect(*sockp, 425ce0e08e2SPeter Avalos (struct sockaddr *)raddr, len) < 0)) { 426ce0e08e2SPeter Avalos rpc_createerr.cf_stat = RPC_SYSTEMERROR; 427ce0e08e2SPeter Avalos rpc_createerr.cf_error.re_errno = errno; 428ce0e08e2SPeter Avalos if (*sockp != -1) 429ce0e08e2SPeter Avalos _close(*sockp); 430ce0e08e2SPeter Avalos goto done; 431ce0e08e2SPeter Avalos } 432ce0e08e2SPeter Avalos } 433ce0e08e2SPeter Avalos svcaddr->buf = raddr; 434ce0e08e2SPeter Avalos svcaddr->len = raddr->sun_len; 435ce0e08e2SPeter Avalos svcaddr->maxlen = sizeof (struct sockaddr_un); 436ce0e08e2SPeter Avalos cl = clnt_vc_create(*sockp, svcaddr, prog, 437ce0e08e2SPeter Avalos vers, sendsz, recvsz); 438ce0e08e2SPeter Avalos done: 439ce0e08e2SPeter Avalos free(svcaddr->buf); 440ce0e08e2SPeter Avalos free(svcaddr); 441ce0e08e2SPeter Avalos return(cl); 442ce0e08e2SPeter Avalos } 443ce0e08e2SPeter Avalos 444ce0e08e2SPeter Avalos /* 445ce0e08e2SPeter Avalos * Creates, registers, and returns a (rpc) unix based transporter. 446ce0e08e2SPeter Avalos * Obsoleted by svc_vc_create(). 447ce0e08e2SPeter Avalos */ 448ce0e08e2SPeter Avalos SVCXPRT * 449ce0e08e2SPeter Avalos svcunix_create(int sock, u_int sendsize, u_int recvsize, char *path) 450ce0e08e2SPeter Avalos { 451ce0e08e2SPeter Avalos struct netconfig *nconf; 452ce0e08e2SPeter Avalos void *localhandle; 453ce0e08e2SPeter Avalos struct sockaddr_un sun; 454ce0e08e2SPeter Avalos struct sockaddr *sa; 455ce0e08e2SPeter Avalos struct t_bind taddr; 456ce0e08e2SPeter Avalos SVCXPRT *xprt; 457ce0e08e2SPeter Avalos int addrlen; 458ce0e08e2SPeter Avalos 4592038fb68SSascha Wildner xprt = NULL; 460ce0e08e2SPeter Avalos localhandle = setnetconfig(); 461ce0e08e2SPeter Avalos while ((nconf = getnetconfig(localhandle)) != NULL) { 462ce0e08e2SPeter Avalos if (nconf->nc_protofmly != NULL && 463ce0e08e2SPeter Avalos strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 464ce0e08e2SPeter Avalos break; 465ce0e08e2SPeter Avalos } 466ce0e08e2SPeter Avalos if (nconf == NULL) 467ce0e08e2SPeter Avalos return(xprt); 468ce0e08e2SPeter Avalos 469ce0e08e2SPeter Avalos if ((sock = __rpc_nconf2fd(nconf)) < 0) 470ce0e08e2SPeter Avalos goto done; 471ce0e08e2SPeter Avalos 472ce0e08e2SPeter Avalos memset(&sun, 0, sizeof sun); 473ce0e08e2SPeter Avalos sun.sun_family = AF_LOCAL; 474ce0e08e2SPeter Avalos if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 475ce0e08e2SPeter Avalos sizeof(sun.sun_path)) 476ce0e08e2SPeter Avalos goto done; 477ce0e08e2SPeter Avalos sun.sun_len = SUN_LEN(&sun); 478ce0e08e2SPeter Avalos addrlen = sizeof (struct sockaddr_un); 479ce0e08e2SPeter Avalos sa = (struct sockaddr *)&sun; 480ce0e08e2SPeter Avalos 481ce0e08e2SPeter Avalos if (_bind(sock, sa, addrlen) < 0) 482ce0e08e2SPeter Avalos goto done; 483ce0e08e2SPeter Avalos 484ce0e08e2SPeter Avalos taddr.addr.len = taddr.addr.maxlen = addrlen; 485ce0e08e2SPeter Avalos taddr.addr.buf = malloc(addrlen); 486ce0e08e2SPeter Avalos if (taddr.addr.buf == NULL) 487ce0e08e2SPeter Avalos goto done; 488ce0e08e2SPeter Avalos memcpy(taddr.addr.buf, sa, addrlen); 489ce0e08e2SPeter Avalos 490ce0e08e2SPeter Avalos if (nconf->nc_semantics != NC_TPI_CLTS) { 491ce0e08e2SPeter Avalos if (_listen(sock, SOMAXCONN) < 0) { 492ce0e08e2SPeter Avalos free(taddr.addr.buf); 493ce0e08e2SPeter Avalos goto done; 494ce0e08e2SPeter Avalos } 495ce0e08e2SPeter Avalos } 496ce0e08e2SPeter Avalos 497ce0e08e2SPeter Avalos xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); 498ce0e08e2SPeter Avalos 499ce0e08e2SPeter Avalos done: 500ce0e08e2SPeter Avalos endnetconfig(localhandle); 501ce0e08e2SPeter Avalos return(xprt); 502ce0e08e2SPeter Avalos } 503ce0e08e2SPeter Avalos 504ce0e08e2SPeter Avalos /* 505ce0e08e2SPeter Avalos * Like svunix_create(), except the routine takes any *open* UNIX file 506ce0e08e2SPeter Avalos * descriptor as its first input. Obsoleted by svc_fd_create(); 507ce0e08e2SPeter Avalos */ 508ce0e08e2SPeter Avalos SVCXPRT * 509ce0e08e2SPeter Avalos svcunixfd_create(int fd, u_int sendsize, u_int recvsize) 510ce0e08e2SPeter Avalos { 511ce0e08e2SPeter Avalos return (svc_fd_create(fd, sendsize, recvsize)); 512ce0e08e2SPeter Avalos } 513ce0e08e2SPeter Avalos 514ce0e08e2SPeter Avalos #endif /* PORTMAP */ 515