1ce0e08e2SPeter Avalos /* 2ce0e08e2SPeter Avalos * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3ce0e08e2SPeter Avalos * unrestricted use provided that this legend is included on all tape 4ce0e08e2SPeter Avalos * media and as a part of the software program in whole or part. Users 5ce0e08e2SPeter Avalos * may copy or modify Sun RPC without charge, but are not authorized 6ce0e08e2SPeter Avalos * to license or distribute it to anyone else except as part of a product or 7ce0e08e2SPeter Avalos * program developed by the user. 8ce0e08e2SPeter Avalos * 9ce0e08e2SPeter Avalos * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 10ce0e08e2SPeter Avalos * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 11ce0e08e2SPeter Avalos * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 12ce0e08e2SPeter Avalos * 13ce0e08e2SPeter Avalos * Sun RPC is provided with no support and without any obligation on the 14ce0e08e2SPeter Avalos * part of Sun Microsystems, Inc. to assist in its use, correction, 15ce0e08e2SPeter Avalos * modification or enhancement. 16ce0e08e2SPeter Avalos * 17ce0e08e2SPeter Avalos * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 18ce0e08e2SPeter Avalos * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 19ce0e08e2SPeter Avalos * OR ANY PART THEREOF. 20ce0e08e2SPeter Avalos * 21ce0e08e2SPeter Avalos * In no event will Sun Microsystems, Inc. be liable for any lost revenue 22ce0e08e2SPeter Avalos * or profits or other special, indirect and consequential damages, even if 23ce0e08e2SPeter Avalos * Sun has been advised of the possibility of such damages. 24ce0e08e2SPeter Avalos * 25ce0e08e2SPeter Avalos * Sun Microsystems, Inc. 26ce0e08e2SPeter Avalos * 2550 Garcia Avenue 27ce0e08e2SPeter Avalos * Mountain View, California 94043 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 <syslog.h> 64ce0e08e2SPeter Avalos #include <stdlib.h> 65ce0e08e2SPeter Avalos #include <string.h> 66ce0e08e2SPeter Avalos #include <unistd.h> 67ce0e08e2SPeter Avalos #include "un-namespace.h" 68ce0e08e2SPeter Avalos 69ce0e08e2SPeter Avalos #include "rpc_com.h" 70ce0e08e2SPeter Avalos #include "mt_misc.h" 71ce0e08e2SPeter Avalos 72ce0e08e2SPeter Avalos static CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, 73ce0e08e2SPeter Avalos int *, u_int, u_int, char *); 74ce0e08e2SPeter Avalos static SVCXPRT *svc_com_create(int, u_int, u_int, char *); 75ce0e08e2SPeter Avalos static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *); 76ce0e08e2SPeter Avalos 77ce0e08e2SPeter Avalos /* XXX */ 78ce0e08e2SPeter Avalos #define IN4_LOCALHOST_STRING "127.0.0.1" 79ce0e08e2SPeter Avalos #define IN6_LOCALHOST_STRING "::1" 80ce0e08e2SPeter Avalos 81ce0e08e2SPeter Avalos /* 82ce0e08e2SPeter Avalos * A common clnt create routine 83ce0e08e2SPeter Avalos */ 84ce0e08e2SPeter Avalos static CLIENT * 85ce0e08e2SPeter Avalos clnt_com_create(struct sockaddr_in *raddr, rpcprog_t prog, rpcvers_t vers, 86ce0e08e2SPeter Avalos int *sockp, u_int sendsz, u_int recvsz, char *tp) 87ce0e08e2SPeter Avalos { 88ce0e08e2SPeter Avalos CLIENT *cl; 89ce0e08e2SPeter Avalos int madefd = FALSE; 90ce0e08e2SPeter Avalos int fd = *sockp; 91ce0e08e2SPeter Avalos struct netconfig *nconf; 92ce0e08e2SPeter Avalos struct netbuf bindaddr; 93ce0e08e2SPeter Avalos 94ce0e08e2SPeter Avalos mutex_lock(&rpcsoc_lock); 95ce0e08e2SPeter Avalos if ((nconf = __rpc_getconfip(tp)) == NULL) { 96ce0e08e2SPeter Avalos rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 97ce0e08e2SPeter Avalos mutex_unlock(&rpcsoc_lock); 98ce0e08e2SPeter Avalos return (NULL); 99ce0e08e2SPeter Avalos } 100ce0e08e2SPeter Avalos if (fd == RPC_ANYSOCK) { 101ce0e08e2SPeter Avalos fd = __rpc_nconf2fd(nconf); 102ce0e08e2SPeter Avalos if (fd == -1) 103ce0e08e2SPeter Avalos goto syserror; 104ce0e08e2SPeter Avalos madefd = TRUE; 105ce0e08e2SPeter Avalos } 106ce0e08e2SPeter Avalos 107ce0e08e2SPeter Avalos if (raddr->sin_port == 0) { 108ce0e08e2SPeter Avalos u_int proto; 109ce0e08e2SPeter Avalos u_short sport; 110ce0e08e2SPeter Avalos 111ce0e08e2SPeter Avalos mutex_unlock(&rpcsoc_lock); /* pmap_getport is recursive */ 112ce0e08e2SPeter Avalos proto = strcmp(tp, "udp") == 0 ? IPPROTO_UDP : IPPROTO_TCP; 113ce0e08e2SPeter Avalos sport = pmap_getport(raddr, (u_long)prog, (u_long)vers, 114ce0e08e2SPeter Avalos proto); 115ce0e08e2SPeter Avalos if (sport == 0) { 116ce0e08e2SPeter Avalos goto err; 117ce0e08e2SPeter Avalos } 118ce0e08e2SPeter Avalos raddr->sin_port = htons(sport); 119ce0e08e2SPeter Avalos mutex_lock(&rpcsoc_lock); /* pmap_getport is recursive */ 120ce0e08e2SPeter Avalos } 121ce0e08e2SPeter Avalos 122ce0e08e2SPeter Avalos /* Transform sockaddr_in to netbuf */ 123ce0e08e2SPeter Avalos bindaddr.maxlen = bindaddr.len = sizeof (struct sockaddr_in); 124ce0e08e2SPeter Avalos bindaddr.buf = raddr; 125ce0e08e2SPeter Avalos 126ce0e08e2SPeter Avalos bindresvport(fd, NULL); 127ce0e08e2SPeter Avalos cl = clnt_tli_create(fd, nconf, &bindaddr, prog, vers, 128ce0e08e2SPeter Avalos sendsz, recvsz); 129ce0e08e2SPeter Avalos if (cl) { 130ce0e08e2SPeter Avalos if (madefd == TRUE) { 131ce0e08e2SPeter Avalos /* 132ce0e08e2SPeter Avalos * The fd should be closed while destroying the handle. 133ce0e08e2SPeter Avalos */ 134ce0e08e2SPeter Avalos CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); 135ce0e08e2SPeter Avalos *sockp = fd; 136ce0e08e2SPeter Avalos } 137ce0e08e2SPeter Avalos freenetconfigent(nconf); 138ce0e08e2SPeter Avalos mutex_unlock(&rpcsoc_lock); 139ce0e08e2SPeter Avalos return (cl); 140ce0e08e2SPeter Avalos } 141ce0e08e2SPeter Avalos goto err; 142ce0e08e2SPeter Avalos 143ce0e08e2SPeter Avalos syserror: 144ce0e08e2SPeter Avalos rpc_createerr.cf_stat = RPC_SYSTEMERROR; 145ce0e08e2SPeter Avalos rpc_createerr.cf_error.re_errno = errno; 146ce0e08e2SPeter Avalos 147ce0e08e2SPeter Avalos err: if (madefd == TRUE) 148ce0e08e2SPeter Avalos _close(fd); 149ce0e08e2SPeter Avalos freenetconfigent(nconf); 150ce0e08e2SPeter Avalos mutex_unlock(&rpcsoc_lock); 151ce0e08e2SPeter Avalos return (NULL); 152ce0e08e2SPeter Avalos } 153ce0e08e2SPeter Avalos 154ce0e08e2SPeter Avalos CLIENT * 155ce0e08e2SPeter Avalos clntudp_bufcreate(struct sockaddr_in *raddr, u_long prog, u_long vers, 156ce0e08e2SPeter Avalos struct timeval wait, int *sockp, u_int sendsz, u_int recvsz) 157ce0e08e2SPeter Avalos { 158ce0e08e2SPeter Avalos CLIENT *cl; 159ce0e08e2SPeter Avalos 160ce0e08e2SPeter Avalos cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 161ce0e08e2SPeter Avalos sendsz, recvsz, "udp"); 162ce0e08e2SPeter Avalos if (cl == NULL) { 163ce0e08e2SPeter Avalos return (NULL); 164ce0e08e2SPeter Avalos } 165ce0e08e2SPeter Avalos CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait); 166ce0e08e2SPeter Avalos return (cl); 167ce0e08e2SPeter Avalos } 168ce0e08e2SPeter Avalos 169ce0e08e2SPeter Avalos CLIENT * 170ce0e08e2SPeter Avalos clntudp_create(struct sockaddr_in *raddr, u_long program, u_long version, 171ce0e08e2SPeter Avalos struct timeval wait, int *sockp) 172ce0e08e2SPeter Avalos { 173ce0e08e2SPeter Avalos 174ce0e08e2SPeter Avalos return clntudp_bufcreate(raddr, program, version, wait, sockp, 175ce0e08e2SPeter Avalos UDPMSGSIZE, UDPMSGSIZE); 176ce0e08e2SPeter Avalos } 177ce0e08e2SPeter Avalos 178ce0e08e2SPeter Avalos CLIENT * 179ce0e08e2SPeter Avalos clnttcp_create(struct sockaddr_in *raddr, u_long prog, u_long vers, int *sockp, 180ce0e08e2SPeter Avalos u_int sendsz, u_int recvsz) 181ce0e08e2SPeter Avalos { 182ce0e08e2SPeter Avalos 183ce0e08e2SPeter Avalos return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 184ce0e08e2SPeter Avalos sendsz, recvsz, "tcp"); 185ce0e08e2SPeter Avalos } 186ce0e08e2SPeter Avalos 187ce0e08e2SPeter Avalos CLIENT * 188ce0e08e2SPeter Avalos clntraw_create(u_long prog, u_long vers) 189ce0e08e2SPeter Avalos { 190ce0e08e2SPeter Avalos 191ce0e08e2SPeter Avalos return clnt_raw_create((rpcprog_t)prog, (rpcvers_t)vers); 192ce0e08e2SPeter Avalos } 193ce0e08e2SPeter Avalos 194ce0e08e2SPeter Avalos /* 195ce0e08e2SPeter Avalos * A common server create routine 196ce0e08e2SPeter Avalos */ 197ce0e08e2SPeter Avalos static SVCXPRT * 198ce0e08e2SPeter Avalos svc_com_create(int fd, u_int sendsize, u_int recvsize, char *netid) 199ce0e08e2SPeter Avalos { 200ce0e08e2SPeter Avalos struct netconfig *nconf; 201ce0e08e2SPeter Avalos SVCXPRT *svc; 202ce0e08e2SPeter Avalos int madefd = FALSE; 203ce0e08e2SPeter Avalos int port; 204ce0e08e2SPeter Avalos struct sockaddr_in sin; 205ce0e08e2SPeter Avalos 206ce0e08e2SPeter Avalos if ((nconf = __rpc_getconfip(netid)) == NULL) { 207ce0e08e2SPeter Avalos syslog(LOG_ERR, "Could not get %s transport", netid); 208ce0e08e2SPeter Avalos return (NULL); 209ce0e08e2SPeter Avalos } 210ce0e08e2SPeter Avalos if (fd == RPC_ANYSOCK) { 211ce0e08e2SPeter Avalos fd = __rpc_nconf2fd(nconf); 212ce0e08e2SPeter Avalos if (fd == -1) { 213ce0e08e2SPeter Avalos freenetconfigent(nconf); 214ce0e08e2SPeter Avalos syslog(LOG_ERR, 215ce0e08e2SPeter Avalos "svc%s_create: could not open connection", netid); 216ce0e08e2SPeter Avalos return (NULL); 217ce0e08e2SPeter Avalos } 218ce0e08e2SPeter Avalos madefd = TRUE; 219ce0e08e2SPeter Avalos } 220ce0e08e2SPeter Avalos 221ce0e08e2SPeter Avalos memset(&sin, 0, sizeof sin); 222ce0e08e2SPeter Avalos sin.sin_family = AF_INET; 223ce0e08e2SPeter Avalos bindresvport(fd, &sin); 224ce0e08e2SPeter Avalos _listen(fd, SOMAXCONN); 225ce0e08e2SPeter Avalos svc = svc_tli_create(fd, nconf, NULL, sendsize, recvsize); 226ce0e08e2SPeter Avalos freenetconfigent(nconf); 227ce0e08e2SPeter Avalos if (svc == NULL) { 228ce0e08e2SPeter Avalos if (madefd) 229ce0e08e2SPeter Avalos _close(fd); 230ce0e08e2SPeter Avalos return (NULL); 231ce0e08e2SPeter Avalos } 232ce0e08e2SPeter Avalos port = (((struct sockaddr_in *)svc->xp_ltaddr.buf)->sin_port); 233ce0e08e2SPeter Avalos svc->xp_port = ntohs(port); 234ce0e08e2SPeter Avalos return (svc); 235ce0e08e2SPeter Avalos } 236ce0e08e2SPeter Avalos 237ce0e08e2SPeter Avalos SVCXPRT * 238ce0e08e2SPeter Avalos svctcp_create(int fd, u_int sendsize, u_int recvsize) 239ce0e08e2SPeter Avalos { 240ce0e08e2SPeter Avalos 241ce0e08e2SPeter Avalos return svc_com_create(fd, sendsize, recvsize, "tcp"); 242ce0e08e2SPeter Avalos } 243ce0e08e2SPeter Avalos 244ce0e08e2SPeter Avalos SVCXPRT * 245ce0e08e2SPeter Avalos svcudp_bufcreate(int fd, u_int sendsz, u_int recvsz) 246ce0e08e2SPeter Avalos { 247ce0e08e2SPeter Avalos 248ce0e08e2SPeter Avalos return svc_com_create(fd, sendsz, recvsz, "udp"); 249ce0e08e2SPeter Avalos } 250ce0e08e2SPeter Avalos 251ce0e08e2SPeter Avalos SVCXPRT * 252ce0e08e2SPeter Avalos svcfd_create(int fd, u_int sendsize, u_int recvsize) 253ce0e08e2SPeter Avalos { 254ce0e08e2SPeter Avalos 255ce0e08e2SPeter Avalos return svc_fd_create(fd, sendsize, recvsize); 256ce0e08e2SPeter Avalos } 257ce0e08e2SPeter Avalos 258ce0e08e2SPeter Avalos 259ce0e08e2SPeter Avalos SVCXPRT * 260ce0e08e2SPeter Avalos svcudp_create(int fd) 261ce0e08e2SPeter Avalos { 262ce0e08e2SPeter Avalos 263ce0e08e2SPeter Avalos return svc_com_create(fd, UDPMSGSIZE, UDPMSGSIZE, "udp"); 264ce0e08e2SPeter Avalos } 265ce0e08e2SPeter Avalos 266ce0e08e2SPeter Avalos SVCXPRT * 267ce0e08e2SPeter Avalos svcraw_create(void) 268ce0e08e2SPeter Avalos { 269ce0e08e2SPeter Avalos 270ce0e08e2SPeter Avalos return svc_raw_create(); 271ce0e08e2SPeter Avalos } 272ce0e08e2SPeter Avalos 273ce0e08e2SPeter Avalos int 274ce0e08e2SPeter Avalos get_myaddress(struct sockaddr_in *addr) 275ce0e08e2SPeter Avalos { 276ce0e08e2SPeter Avalos 277ce0e08e2SPeter Avalos memset((void *) addr, 0, sizeof(*addr)); 278ce0e08e2SPeter Avalos addr->sin_family = AF_INET; 279ce0e08e2SPeter Avalos addr->sin_port = htons(PMAPPORT); 280ce0e08e2SPeter Avalos addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); 281ce0e08e2SPeter Avalos return (0); 282ce0e08e2SPeter Avalos } 283ce0e08e2SPeter Avalos 284ce0e08e2SPeter Avalos /* 285ce0e08e2SPeter Avalos * For connectionless "udp" transport. Obsoleted by rpc_call(). 286ce0e08e2SPeter Avalos */ 287ce0e08e2SPeter Avalos int 288ce0e08e2SPeter Avalos callrpc(const char *host, int prognum, int versnum, int procnum, 289ce0e08e2SPeter Avalos xdrproc_t inproc, void *in, xdrproc_t outproc, void *out) 290ce0e08e2SPeter Avalos { 291ce0e08e2SPeter Avalos 292ce0e08e2SPeter Avalos return (int)rpc_call(host, (rpcprog_t)prognum, (rpcvers_t)versnum, 293ce0e08e2SPeter Avalos (rpcproc_t)procnum, inproc, in, outproc, out, "udp"); 294ce0e08e2SPeter Avalos } 295ce0e08e2SPeter Avalos 296ce0e08e2SPeter Avalos /* 297ce0e08e2SPeter Avalos * For connectionless kind of transport. Obsoleted by rpc_reg() 298ce0e08e2SPeter Avalos */ 299ce0e08e2SPeter Avalos int 300ce0e08e2SPeter Avalos registerrpc(int prognum, int versnum, int procnum, char *(*progname)(char *), 301ce0e08e2SPeter Avalos xdrproc_t inproc, xdrproc_t outproc) 302ce0e08e2SPeter Avalos { 303ce0e08e2SPeter Avalos 304ce0e08e2SPeter Avalos return rpc_reg((rpcprog_t)prognum, (rpcvers_t)versnum, 305ce0e08e2SPeter Avalos (rpcproc_t)procnum, progname, inproc, outproc, "udp"); 306ce0e08e2SPeter Avalos } 307ce0e08e2SPeter Avalos 308ce0e08e2SPeter Avalos /* 309ce0e08e2SPeter Avalos * All the following clnt_broadcast stuff is convulated; it supports 310ce0e08e2SPeter Avalos * the earlier calling style of the callback function 311ce0e08e2SPeter Avalos */ 312ce0e08e2SPeter Avalos static thread_key_t clnt_broadcast_key; 313ce0e08e2SPeter Avalos static resultproc_t clnt_broadcast_result_main; 314ce0e08e2SPeter Avalos 315ce0e08e2SPeter Avalos /* 316ce0e08e2SPeter Avalos * Need to translate the netbuf address into sockaddr_in address. 317ce0e08e2SPeter Avalos * Dont care about netid here. 318ce0e08e2SPeter Avalos */ 319ce0e08e2SPeter Avalos /* ARGSUSED */ 320ce0e08e2SPeter Avalos static bool_t 321ce0e08e2SPeter Avalos rpc_wrap_bcast(char *resultp, /* results of the call */ 322ce0e08e2SPeter Avalos struct netbuf *addr, /* address of the guy who responded */ 323ce0e08e2SPeter Avalos struct netconfig *nconf) /* Netconf of the transport */ 324ce0e08e2SPeter Avalos { 325ce0e08e2SPeter Avalos resultproc_t clnt_broadcast_result; 326ce0e08e2SPeter Avalos 327ce0e08e2SPeter Avalos if (strcmp(nconf->nc_netid, "udp")) 328ce0e08e2SPeter Avalos return (FALSE); 329ce0e08e2SPeter Avalos if (thr_main()) 330ce0e08e2SPeter Avalos clnt_broadcast_result = clnt_broadcast_result_main; 331ce0e08e2SPeter Avalos else 332ce0e08e2SPeter Avalos clnt_broadcast_result = (resultproc_t)thr_getspecific(clnt_broadcast_key); 333ce0e08e2SPeter Avalos return (*clnt_broadcast_result)(resultp, 334ce0e08e2SPeter Avalos (struct sockaddr_in *)addr->buf); 335ce0e08e2SPeter Avalos } 336ce0e08e2SPeter Avalos 337ce0e08e2SPeter Avalos /* 338ce0e08e2SPeter Avalos * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). 339ce0e08e2SPeter Avalos */ 340ce0e08e2SPeter Avalos enum clnt_stat 341ce0e08e2SPeter Avalos clnt_broadcast(u_long prog, /* program number */ 342ce0e08e2SPeter Avalos u_long vers, /* version number */ 343ce0e08e2SPeter Avalos u_long proc, /* procedure number */ 344ce0e08e2SPeter Avalos xdrproc_t xargs, /* xdr routine for args */ 345ce0e08e2SPeter Avalos void *argsp, /* pointer to args */ 346ce0e08e2SPeter Avalos xdrproc_t xresults, /* xdr routine for results */ 347ce0e08e2SPeter Avalos void *resultsp, /* pointer to results */ 348ce0e08e2SPeter Avalos resultproc_t eachresult) /* call with each result obtained */ 349ce0e08e2SPeter Avalos { 350ce0e08e2SPeter Avalos 351ce0e08e2SPeter Avalos if (thr_main()) 352ce0e08e2SPeter Avalos clnt_broadcast_result_main = eachresult; 353ce0e08e2SPeter Avalos else { 354ce0e08e2SPeter Avalos if (clnt_broadcast_key == 0) { 355ce0e08e2SPeter Avalos mutex_lock(&tsd_lock); 356ce0e08e2SPeter Avalos if (clnt_broadcast_key == 0) 357ce0e08e2SPeter Avalos thr_keycreate(&clnt_broadcast_key, free); 358ce0e08e2SPeter Avalos mutex_unlock(&tsd_lock); 359ce0e08e2SPeter Avalos } 360ce0e08e2SPeter Avalos thr_setspecific(clnt_broadcast_key, (void *) eachresult); 361ce0e08e2SPeter Avalos } 362ce0e08e2SPeter Avalos return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, 363ce0e08e2SPeter Avalos (rpcproc_t)proc, xargs, argsp, xresults, resultsp, 364ce0e08e2SPeter Avalos (resultproc_t) rpc_wrap_bcast, "udp"); 365ce0e08e2SPeter Avalos } 366ce0e08e2SPeter Avalos 367ce0e08e2SPeter Avalos /* 368ce0e08e2SPeter Avalos * Create the client des authentication object. Obsoleted by 369ce0e08e2SPeter Avalos * authdes_seccreate(). 370ce0e08e2SPeter Avalos */ 371ce0e08e2SPeter Avalos AUTH * 372ce0e08e2SPeter Avalos authdes_create(char *servername, /* network name of server */ 373ce0e08e2SPeter Avalos u_int window, /* time to live */ 374ce0e08e2SPeter Avalos struct sockaddr *syncaddr,/* optional hostaddr to sync with */ 375ce0e08e2SPeter Avalos des_block *ckey) /* optional conversation key to use */ 376ce0e08e2SPeter Avalos { 377ce0e08e2SPeter Avalos AUTH *dummy; 378ce0e08e2SPeter Avalos AUTH *nauth; 379ce0e08e2SPeter Avalos char hostname[NI_MAXHOST]; 380ce0e08e2SPeter Avalos 381ce0e08e2SPeter Avalos if (syncaddr) { 382ce0e08e2SPeter Avalos /* 383ce0e08e2SPeter Avalos * Change addr to hostname, because that is the way 384ce0e08e2SPeter Avalos * new interface takes it. 385ce0e08e2SPeter Avalos */ 386ce0e08e2SPeter Avalos if (getnameinfo(syncaddr, syncaddr->sa_len, hostname, 387ce0e08e2SPeter Avalos sizeof hostname, NULL, 0, 0) != 0) 388ce0e08e2SPeter Avalos goto fallback; 389ce0e08e2SPeter Avalos 390ce0e08e2SPeter Avalos nauth = authdes_seccreate(servername, window, hostname, ckey); 391ce0e08e2SPeter Avalos return (nauth); 392ce0e08e2SPeter Avalos } 393ce0e08e2SPeter Avalos fallback: 394ce0e08e2SPeter Avalos dummy = authdes_seccreate(servername, window, NULL, ckey); 395ce0e08e2SPeter Avalos return (dummy); 396ce0e08e2SPeter Avalos } 397ce0e08e2SPeter Avalos 398ce0e08e2SPeter Avalos /* 399ce0e08e2SPeter Avalos * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() 400ce0e08e2SPeter Avalos */ 401ce0e08e2SPeter Avalos CLIENT * 402ce0e08e2SPeter Avalos clntunix_create(struct sockaddr_un *raddr, u_long prog, u_long vers, int *sockp, 403ce0e08e2SPeter Avalos u_int sendsz, u_int recvsz) 404ce0e08e2SPeter Avalos { 405ce0e08e2SPeter Avalos struct netbuf *svcaddr; 406ce0e08e2SPeter Avalos struct netconfig *nconf; 407ce0e08e2SPeter Avalos CLIENT *cl; 408ce0e08e2SPeter Avalos int len; 409ce0e08e2SPeter Avalos 410ce0e08e2SPeter Avalos cl = NULL; 411ce0e08e2SPeter Avalos nconf = NULL; 412ce0e08e2SPeter Avalos svcaddr = NULL; 413ce0e08e2SPeter Avalos if ((raddr->sun_len == 0) || 414ce0e08e2SPeter Avalos ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || 415ce0e08e2SPeter Avalos ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { 416ce0e08e2SPeter Avalos if (svcaddr != NULL) 417ce0e08e2SPeter Avalos free(svcaddr); 418ce0e08e2SPeter Avalos rpc_createerr.cf_stat = RPC_SYSTEMERROR; 419ce0e08e2SPeter Avalos rpc_createerr.cf_error.re_errno = errno; 420ce0e08e2SPeter Avalos return(cl); 421ce0e08e2SPeter Avalos } 422ce0e08e2SPeter Avalos if (*sockp < 0) { 423ce0e08e2SPeter Avalos *sockp = _socket(AF_LOCAL, SOCK_STREAM, 0); 424ce0e08e2SPeter Avalos len = raddr->sun_len = SUN_LEN(raddr); 425ce0e08e2SPeter Avalos if ((*sockp < 0) || (_connect(*sockp, 426ce0e08e2SPeter Avalos (struct sockaddr *)raddr, len) < 0)) { 427ce0e08e2SPeter Avalos rpc_createerr.cf_stat = RPC_SYSTEMERROR; 428ce0e08e2SPeter Avalos rpc_createerr.cf_error.re_errno = errno; 429ce0e08e2SPeter Avalos if (*sockp != -1) 430ce0e08e2SPeter Avalos _close(*sockp); 431ce0e08e2SPeter Avalos goto done; 432ce0e08e2SPeter Avalos } 433ce0e08e2SPeter Avalos } 434ce0e08e2SPeter Avalos svcaddr->buf = raddr; 435ce0e08e2SPeter Avalos svcaddr->len = raddr->sun_len; 436ce0e08e2SPeter Avalos svcaddr->maxlen = sizeof (struct sockaddr_un); 437ce0e08e2SPeter Avalos cl = clnt_vc_create(*sockp, svcaddr, prog, 438ce0e08e2SPeter Avalos vers, sendsz, recvsz); 439ce0e08e2SPeter Avalos done: 440ce0e08e2SPeter Avalos free(svcaddr->buf); 441ce0e08e2SPeter Avalos free(svcaddr); 442ce0e08e2SPeter Avalos return(cl); 443ce0e08e2SPeter Avalos } 444ce0e08e2SPeter Avalos 445ce0e08e2SPeter Avalos /* 446ce0e08e2SPeter Avalos * Creates, registers, and returns a (rpc) unix based transporter. 447ce0e08e2SPeter Avalos * Obsoleted by svc_vc_create(). 448ce0e08e2SPeter Avalos */ 449ce0e08e2SPeter Avalos SVCXPRT * 450ce0e08e2SPeter Avalos svcunix_create(int sock, u_int sendsize, u_int recvsize, char *path) 451ce0e08e2SPeter Avalos { 452ce0e08e2SPeter Avalos struct netconfig *nconf; 453ce0e08e2SPeter Avalos void *localhandle; 454ce0e08e2SPeter Avalos struct sockaddr_un sun; 455ce0e08e2SPeter Avalos struct sockaddr *sa; 456ce0e08e2SPeter Avalos struct t_bind taddr; 457ce0e08e2SPeter Avalos SVCXPRT *xprt; 458ce0e08e2SPeter Avalos int addrlen; 459ce0e08e2SPeter Avalos 460*2038fb68SSascha Wildner xprt = NULL; 461ce0e08e2SPeter Avalos localhandle = setnetconfig(); 462ce0e08e2SPeter Avalos while ((nconf = getnetconfig(localhandle)) != NULL) { 463ce0e08e2SPeter Avalos if (nconf->nc_protofmly != NULL && 464ce0e08e2SPeter Avalos strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 465ce0e08e2SPeter Avalos break; 466ce0e08e2SPeter Avalos } 467ce0e08e2SPeter Avalos if (nconf == NULL) 468ce0e08e2SPeter Avalos return(xprt); 469ce0e08e2SPeter Avalos 470ce0e08e2SPeter Avalos if ((sock = __rpc_nconf2fd(nconf)) < 0) 471ce0e08e2SPeter Avalos goto done; 472ce0e08e2SPeter Avalos 473ce0e08e2SPeter Avalos memset(&sun, 0, sizeof sun); 474ce0e08e2SPeter Avalos sun.sun_family = AF_LOCAL; 475ce0e08e2SPeter Avalos if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 476ce0e08e2SPeter Avalos sizeof(sun.sun_path)) 477ce0e08e2SPeter Avalos goto done; 478ce0e08e2SPeter Avalos sun.sun_len = SUN_LEN(&sun); 479ce0e08e2SPeter Avalos addrlen = sizeof (struct sockaddr_un); 480ce0e08e2SPeter Avalos sa = (struct sockaddr *)&sun; 481ce0e08e2SPeter Avalos 482ce0e08e2SPeter Avalos if (_bind(sock, sa, addrlen) < 0) 483ce0e08e2SPeter Avalos goto done; 484ce0e08e2SPeter Avalos 485ce0e08e2SPeter Avalos taddr.addr.len = taddr.addr.maxlen = addrlen; 486ce0e08e2SPeter Avalos taddr.addr.buf = malloc(addrlen); 487ce0e08e2SPeter Avalos if (taddr.addr.buf == NULL) 488ce0e08e2SPeter Avalos goto done; 489ce0e08e2SPeter Avalos memcpy(taddr.addr.buf, sa, addrlen); 490ce0e08e2SPeter Avalos 491ce0e08e2SPeter Avalos if (nconf->nc_semantics != NC_TPI_CLTS) { 492ce0e08e2SPeter Avalos if (_listen(sock, SOMAXCONN) < 0) { 493ce0e08e2SPeter Avalos free(taddr.addr.buf); 494ce0e08e2SPeter Avalos goto done; 495ce0e08e2SPeter Avalos } 496ce0e08e2SPeter Avalos } 497ce0e08e2SPeter Avalos 498ce0e08e2SPeter Avalos xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); 499ce0e08e2SPeter Avalos 500ce0e08e2SPeter Avalos done: 501ce0e08e2SPeter Avalos endnetconfig(localhandle); 502ce0e08e2SPeter Avalos return(xprt); 503ce0e08e2SPeter Avalos } 504ce0e08e2SPeter Avalos 505ce0e08e2SPeter Avalos /* 506ce0e08e2SPeter Avalos * Like svunix_create(), except the routine takes any *open* UNIX file 507ce0e08e2SPeter Avalos * descriptor as its first input. Obsoleted by svc_fd_create(); 508ce0e08e2SPeter Avalos */ 509ce0e08e2SPeter Avalos SVCXPRT * 510ce0e08e2SPeter Avalos svcunixfd_create(int fd, u_int sendsize, u_int recvsize) 511ce0e08e2SPeter Avalos { 512ce0e08e2SPeter Avalos return (svc_fd_create(fd, sendsize, recvsize)); 513ce0e08e2SPeter Avalos } 514ce0e08e2SPeter Avalos 515ce0e08e2SPeter Avalos #endif /* PORTMAP */ 516