18360efbdSAlfred Perlstein /* $NetBSD: rpc_soc.c,v 1.6 2000/07/06 03:10:35 christos Exp $ */ 28360efbdSAlfred Perlstein 38360efbdSAlfred Perlstein /* 48360efbdSAlfred Perlstein * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 58360efbdSAlfred Perlstein * unrestricted use provided that this legend is included on all tape 68360efbdSAlfred Perlstein * media and as a part of the software program in whole or part. Users 78360efbdSAlfred Perlstein * may copy or modify Sun RPC without charge, but are not authorized 88360efbdSAlfred Perlstein * to license or distribute it to anyone else except as part of a product or 98360efbdSAlfred Perlstein * program developed by the user. 108360efbdSAlfred Perlstein * 118360efbdSAlfred Perlstein * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 128360efbdSAlfred Perlstein * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 138360efbdSAlfred Perlstein * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 148360efbdSAlfred Perlstein * 158360efbdSAlfred Perlstein * Sun RPC is provided with no support and without any obligation on the 168360efbdSAlfred Perlstein * part of Sun Microsystems, Inc. to assist in its use, correction, 178360efbdSAlfred Perlstein * modification or enhancement. 188360efbdSAlfred Perlstein * 198360efbdSAlfred Perlstein * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 208360efbdSAlfred Perlstein * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 218360efbdSAlfred Perlstein * OR ANY PART THEREOF. 228360efbdSAlfred Perlstein * 238360efbdSAlfred Perlstein * In no event will Sun Microsystems, Inc. be liable for any lost revenue 248360efbdSAlfred Perlstein * or profits or other special, indirect and consequential damages, even if 258360efbdSAlfred Perlstein * Sun has been advised of the possibility of such damages. 268360efbdSAlfred Perlstein * 278360efbdSAlfred Perlstein * Sun Microsystems, Inc. 288360efbdSAlfred Perlstein * 2550 Garcia Avenue 298360efbdSAlfred Perlstein * Mountain View, California 94043 308360efbdSAlfred Perlstein */ 318360efbdSAlfred Perlstein 328360efbdSAlfred Perlstein /* #ident "@(#)rpc_soc.c 1.17 94/04/24 SMI" */ 338360efbdSAlfred Perlstein 348360efbdSAlfred Perlstein /* 358360efbdSAlfred Perlstein * Copyright (c) 1986-1991 by Sun Microsystems Inc. 368360efbdSAlfred Perlstein * In addition, portions of such source code were derived from Berkeley 378360efbdSAlfred Perlstein * 4.3 BSD under license from the Regents of the University of 388360efbdSAlfred Perlstein * California. 398360efbdSAlfred Perlstein */ 408360efbdSAlfred Perlstein 418360efbdSAlfred Perlstein #if !defined(lint) && defined(SCCSIDS) 428360efbdSAlfred Perlstein static char sccsid[] = "@(#)rpc_soc.c 1.41 89/05/02 Copyr 1988 Sun Micro"; 438360efbdSAlfred Perlstein #endif 44d3d20c82SDavid E. O'Brien #include <sys/cdefs.h> 45d3d20c82SDavid E. O'Brien __FBSDID("$FreeBSD$"); 468360efbdSAlfred Perlstein 478360efbdSAlfred Perlstein #ifdef PORTMAP 488360efbdSAlfred Perlstein /* 498360efbdSAlfred Perlstein * rpc_soc.c 508360efbdSAlfred Perlstein * 518360efbdSAlfred Perlstein * The backward compatibility routines for the earlier implementation 528360efbdSAlfred Perlstein * of RPC, where the only transports supported were tcp/ip and udp/ip. 538360efbdSAlfred Perlstein * Based on berkeley socket abstraction, now implemented on the top 548360efbdSAlfred Perlstein * of TLI/Streams 558360efbdSAlfred Perlstein */ 568360efbdSAlfred Perlstein 578360efbdSAlfred Perlstein #include "namespace.h" 589f5afc13SIan Dowse #include "reentrant.h" 598360efbdSAlfred Perlstein #include <sys/types.h> 608360efbdSAlfred Perlstein #include <sys/socket.h> 618360efbdSAlfred Perlstein #include <stdio.h> 628360efbdSAlfred Perlstein #include <rpc/rpc.h> 638360efbdSAlfred Perlstein #include <rpc/pmap_clnt.h> 648360efbdSAlfred Perlstein #include <rpc/pmap_prot.h> 658360efbdSAlfred Perlstein #include <rpc/nettype.h> 668360efbdSAlfred Perlstein #include <syslog.h> 678360efbdSAlfred Perlstein #include <netinet/in.h> 688360efbdSAlfred Perlstein #include <netdb.h> 698360efbdSAlfred Perlstein #include <errno.h> 708360efbdSAlfred Perlstein #include <syslog.h> 718360efbdSAlfred Perlstein #include <stdlib.h> 728360efbdSAlfred Perlstein #include <string.h> 738360efbdSAlfred Perlstein #include <unistd.h> 748360efbdSAlfred Perlstein #include "un-namespace.h" 758360efbdSAlfred Perlstein 768360efbdSAlfred Perlstein #include "rpc_com.h" 778360efbdSAlfred Perlstein 788360efbdSAlfred Perlstein extern mutex_t rpcsoc_lock; 798360efbdSAlfred Perlstein 801372519bSDavid E. O'Brien static CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, 811372519bSDavid E. O'Brien int *, u_int, u_int, char *); 82c05ac53bSDavid E. O'Brien static SVCXPRT *svc_com_create(int, u_int, u_int, char *); 83c05ac53bSDavid E. O'Brien static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *); 848360efbdSAlfred Perlstein 858360efbdSAlfred Perlstein /* XXX */ 868360efbdSAlfred Perlstein #define IN4_LOCALHOST_STRING "127.0.0.1" 878360efbdSAlfred Perlstein #define IN6_LOCALHOST_STRING "::1" 888360efbdSAlfred Perlstein 898360efbdSAlfred Perlstein /* 908360efbdSAlfred Perlstein * A common clnt create routine 918360efbdSAlfred Perlstein */ 928360efbdSAlfred Perlstein static CLIENT * 938360efbdSAlfred Perlstein clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp) 948360efbdSAlfred Perlstein struct sockaddr_in *raddr; 958360efbdSAlfred Perlstein rpcprog_t prog; 968360efbdSAlfred Perlstein rpcvers_t vers; 978360efbdSAlfred Perlstein int *sockp; 988360efbdSAlfred Perlstein u_int sendsz; 998360efbdSAlfred Perlstein u_int recvsz; 1008360efbdSAlfred Perlstein char *tp; 1018360efbdSAlfred Perlstein { 1028360efbdSAlfred Perlstein CLIENT *cl; 1038360efbdSAlfred Perlstein int madefd = FALSE; 1048360efbdSAlfred Perlstein int fd = *sockp; 1058360efbdSAlfred Perlstein struct netconfig *nconf; 1068360efbdSAlfred Perlstein struct netbuf bindaddr; 1078360efbdSAlfred Perlstein 1088360efbdSAlfred Perlstein mutex_lock(&rpcsoc_lock); 1098360efbdSAlfred Perlstein if ((nconf = __rpc_getconfip(tp)) == NULL) { 1108360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 1118360efbdSAlfred Perlstein mutex_unlock(&rpcsoc_lock); 1128360efbdSAlfred Perlstein return (NULL); 1138360efbdSAlfred Perlstein } 1148360efbdSAlfred Perlstein if (fd == RPC_ANYSOCK) { 1158360efbdSAlfred Perlstein fd = __rpc_nconf2fd(nconf); 1168360efbdSAlfred Perlstein if (fd == -1) 1178360efbdSAlfred Perlstein goto syserror; 1188360efbdSAlfred Perlstein madefd = TRUE; 1198360efbdSAlfred Perlstein } 1208360efbdSAlfred Perlstein 1218360efbdSAlfred Perlstein if (raddr->sin_port == 0) { 1228360efbdSAlfred Perlstein u_int proto; 1238360efbdSAlfred Perlstein u_short sport; 1248360efbdSAlfred Perlstein 1258360efbdSAlfred Perlstein mutex_unlock(&rpcsoc_lock); /* pmap_getport is recursive */ 1268360efbdSAlfred Perlstein proto = strcmp(tp, "udp") == 0 ? IPPROTO_UDP : IPPROTO_TCP; 1278360efbdSAlfred Perlstein sport = pmap_getport(raddr, (u_long)prog, (u_long)vers, 1288360efbdSAlfred Perlstein proto); 1298360efbdSAlfred Perlstein if (sport == 0) { 1308360efbdSAlfred Perlstein goto err; 1318360efbdSAlfred Perlstein } 1328360efbdSAlfred Perlstein raddr->sin_port = htons(sport); 1338360efbdSAlfred Perlstein mutex_lock(&rpcsoc_lock); /* pmap_getport is recursive */ 1348360efbdSAlfred Perlstein } 1358360efbdSAlfred Perlstein 1368360efbdSAlfred Perlstein /* Transform sockaddr_in to netbuf */ 1378360efbdSAlfred Perlstein bindaddr.maxlen = bindaddr.len = sizeof (struct sockaddr_in); 1388360efbdSAlfred Perlstein bindaddr.buf = raddr; 1398360efbdSAlfred Perlstein 1408360efbdSAlfred Perlstein bindresvport(fd, NULL); 1418360efbdSAlfred Perlstein cl = clnt_tli_create(fd, nconf, &bindaddr, prog, vers, 1428360efbdSAlfred Perlstein sendsz, recvsz); 1438360efbdSAlfred Perlstein if (cl) { 1448360efbdSAlfred Perlstein if (madefd == TRUE) { 1458360efbdSAlfred Perlstein /* 1468360efbdSAlfred Perlstein * The fd should be closed while destroying the handle. 1478360efbdSAlfred Perlstein */ 1488360efbdSAlfred Perlstein (void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); 1498360efbdSAlfred Perlstein *sockp = fd; 1508360efbdSAlfred Perlstein } 1518360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 1528360efbdSAlfred Perlstein mutex_unlock(&rpcsoc_lock); 1538360efbdSAlfred Perlstein return (cl); 1548360efbdSAlfred Perlstein } 1558360efbdSAlfred Perlstein goto err; 1568360efbdSAlfred Perlstein 1578360efbdSAlfred Perlstein syserror: 1588360efbdSAlfred Perlstein rpc_createerr.cf_stat = RPC_SYSTEMERROR; 1598360efbdSAlfred Perlstein rpc_createerr.cf_error.re_errno = errno; 1608360efbdSAlfred Perlstein 1618360efbdSAlfred Perlstein err: if (madefd == TRUE) 1628360efbdSAlfred Perlstein (void)_close(fd); 1638360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 1648360efbdSAlfred Perlstein mutex_unlock(&rpcsoc_lock); 1658360efbdSAlfred Perlstein return (NULL); 1668360efbdSAlfred Perlstein } 1678360efbdSAlfred Perlstein 1688360efbdSAlfred Perlstein CLIENT * 1698360efbdSAlfred Perlstein clntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz) 1708360efbdSAlfred Perlstein struct sockaddr_in *raddr; 1718360efbdSAlfred Perlstein u_long prog; 1728360efbdSAlfred Perlstein u_long vers; 1738360efbdSAlfred Perlstein struct timeval wait; 1748360efbdSAlfred Perlstein int *sockp; 1758360efbdSAlfred Perlstein u_int sendsz; 1768360efbdSAlfred Perlstein u_int recvsz; 1778360efbdSAlfred Perlstein { 1788360efbdSAlfred Perlstein CLIENT *cl; 1798360efbdSAlfred Perlstein 1808360efbdSAlfred Perlstein cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 1818360efbdSAlfred Perlstein sendsz, recvsz, "udp"); 1828360efbdSAlfred Perlstein if (cl == NULL) { 1838360efbdSAlfred Perlstein return (NULL); 1848360efbdSAlfred Perlstein } 185f249dbccSDag-Erling Smørgrav (void) CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait); 1868360efbdSAlfred Perlstein return (cl); 1878360efbdSAlfred Perlstein } 1888360efbdSAlfred Perlstein 1898360efbdSAlfred Perlstein CLIENT * 1908360efbdSAlfred Perlstein clntudp_create(raddr, program, version, wait, sockp) 1918360efbdSAlfred Perlstein struct sockaddr_in *raddr; 1928360efbdSAlfred Perlstein u_long program; 1938360efbdSAlfred Perlstein u_long version; 1948360efbdSAlfred Perlstein struct timeval wait; 1958360efbdSAlfred Perlstein int *sockp; 1968360efbdSAlfred Perlstein { 1978360efbdSAlfred Perlstein 1988360efbdSAlfred Perlstein return clntudp_bufcreate(raddr, program, version, wait, sockp, 1998360efbdSAlfred Perlstein UDPMSGSIZE, UDPMSGSIZE); 2008360efbdSAlfred Perlstein } 2018360efbdSAlfred Perlstein 2028360efbdSAlfred Perlstein CLIENT * 2038360efbdSAlfred Perlstein clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) 2048360efbdSAlfred Perlstein struct sockaddr_in *raddr; 2058360efbdSAlfred Perlstein u_long prog; 2068360efbdSAlfred Perlstein u_long vers; 2078360efbdSAlfred Perlstein int *sockp; 2088360efbdSAlfred Perlstein u_int sendsz; 2098360efbdSAlfred Perlstein u_int recvsz; 2108360efbdSAlfred Perlstein { 2118360efbdSAlfred Perlstein 2128360efbdSAlfred Perlstein return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 2138360efbdSAlfred Perlstein sendsz, recvsz, "tcp"); 2148360efbdSAlfred Perlstein } 2158360efbdSAlfred Perlstein 2168360efbdSAlfred Perlstein CLIENT * 2178360efbdSAlfred Perlstein clntraw_create(prog, vers) 2188360efbdSAlfred Perlstein u_long prog; 2198360efbdSAlfred Perlstein u_long vers; 2208360efbdSAlfred Perlstein { 2218360efbdSAlfred Perlstein 2228360efbdSAlfred Perlstein return clnt_raw_create((rpcprog_t)prog, (rpcvers_t)vers); 2238360efbdSAlfred Perlstein } 2248360efbdSAlfred Perlstein 2258360efbdSAlfred Perlstein /* 2268360efbdSAlfred Perlstein * A common server create routine 2278360efbdSAlfred Perlstein */ 2288360efbdSAlfred Perlstein static SVCXPRT * 2298360efbdSAlfred Perlstein svc_com_create(fd, sendsize, recvsize, netid) 2308360efbdSAlfred Perlstein int fd; 2318360efbdSAlfred Perlstein u_int sendsize; 2328360efbdSAlfred Perlstein u_int recvsize; 2338360efbdSAlfred Perlstein char *netid; 2348360efbdSAlfred Perlstein { 2358360efbdSAlfred Perlstein struct netconfig *nconf; 2368360efbdSAlfred Perlstein SVCXPRT *svc; 2378360efbdSAlfred Perlstein int madefd = FALSE; 2388360efbdSAlfred Perlstein int port; 2398360efbdSAlfred Perlstein struct sockaddr_in sin; 2408360efbdSAlfred Perlstein 2418360efbdSAlfred Perlstein if ((nconf = __rpc_getconfip(netid)) == NULL) { 2428360efbdSAlfred Perlstein (void) syslog(LOG_ERR, "Could not get %s transport", netid); 2438360efbdSAlfred Perlstein return (NULL); 2448360efbdSAlfred Perlstein } 2458360efbdSAlfred Perlstein if (fd == RPC_ANYSOCK) { 2468360efbdSAlfred Perlstein fd = __rpc_nconf2fd(nconf); 2478360efbdSAlfred Perlstein if (fd == -1) { 2488360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 2498360efbdSAlfred Perlstein (void) syslog(LOG_ERR, 2508360efbdSAlfred Perlstein "svc%s_create: could not open connection", netid); 2518360efbdSAlfred Perlstein return (NULL); 2528360efbdSAlfred Perlstein } 2538360efbdSAlfred Perlstein madefd = TRUE; 2548360efbdSAlfred Perlstein } 2558360efbdSAlfred Perlstein 2568360efbdSAlfred Perlstein memset(&sin, 0, sizeof sin); 2578360efbdSAlfred Perlstein sin.sin_family = AF_INET; 2588360efbdSAlfred Perlstein bindresvport(fd, &sin); 2598360efbdSAlfred Perlstein _listen(fd, SOMAXCONN); 2608360efbdSAlfred Perlstein svc = svc_tli_create(fd, nconf, NULL, sendsize, recvsize); 2618360efbdSAlfred Perlstein (void) freenetconfigent(nconf); 2628360efbdSAlfred Perlstein if (svc == NULL) { 2638360efbdSAlfred Perlstein if (madefd) 2648360efbdSAlfred Perlstein (void)_close(fd); 2658360efbdSAlfred Perlstein return (NULL); 2668360efbdSAlfred Perlstein } 2678360efbdSAlfred Perlstein port = (((struct sockaddr_in *)svc->xp_ltaddr.buf)->sin_port); 2688360efbdSAlfred Perlstein svc->xp_port = ntohs(port); 2698360efbdSAlfred Perlstein return (svc); 2708360efbdSAlfred Perlstein } 2718360efbdSAlfred Perlstein 2728360efbdSAlfred Perlstein SVCXPRT * 2738360efbdSAlfred Perlstein svctcp_create(fd, sendsize, recvsize) 2748360efbdSAlfred Perlstein int fd; 2758360efbdSAlfred Perlstein u_int sendsize; 2768360efbdSAlfred Perlstein u_int recvsize; 2778360efbdSAlfred Perlstein { 2788360efbdSAlfred Perlstein 2798360efbdSAlfred Perlstein return svc_com_create(fd, sendsize, recvsize, "tcp"); 2808360efbdSAlfred Perlstein } 2818360efbdSAlfred Perlstein 2828360efbdSAlfred Perlstein SVCXPRT * 2838360efbdSAlfred Perlstein svcudp_bufcreate(fd, sendsz, recvsz) 2848360efbdSAlfred Perlstein int fd; 2858360efbdSAlfred Perlstein u_int sendsz, recvsz; 2868360efbdSAlfred Perlstein { 2878360efbdSAlfred Perlstein 2888360efbdSAlfred Perlstein return svc_com_create(fd, sendsz, recvsz, "udp"); 2898360efbdSAlfred Perlstein } 2908360efbdSAlfred Perlstein 2918360efbdSAlfred Perlstein SVCXPRT * 2928360efbdSAlfred Perlstein svcfd_create(fd, sendsize, recvsize) 2938360efbdSAlfred Perlstein int fd; 2948360efbdSAlfred Perlstein u_int sendsize; 2958360efbdSAlfred Perlstein u_int recvsize; 2968360efbdSAlfred Perlstein { 2978360efbdSAlfred Perlstein 2988360efbdSAlfred Perlstein return svc_fd_create(fd, sendsize, recvsize); 2998360efbdSAlfred Perlstein } 3008360efbdSAlfred Perlstein 3018360efbdSAlfred Perlstein 3028360efbdSAlfred Perlstein SVCXPRT * 3038360efbdSAlfred Perlstein svcudp_create(fd) 3048360efbdSAlfred Perlstein int fd; 3058360efbdSAlfred Perlstein { 3068360efbdSAlfred Perlstein 3078360efbdSAlfred Perlstein return svc_com_create(fd, UDPMSGSIZE, UDPMSGSIZE, "udp"); 3088360efbdSAlfred Perlstein } 3098360efbdSAlfred Perlstein 3108360efbdSAlfred Perlstein SVCXPRT * 3118360efbdSAlfred Perlstein svcraw_create() 3128360efbdSAlfred Perlstein { 3138360efbdSAlfred Perlstein 3148360efbdSAlfred Perlstein return svc_raw_create(); 3158360efbdSAlfred Perlstein } 3168360efbdSAlfred Perlstein 3178360efbdSAlfred Perlstein int 3188360efbdSAlfred Perlstein get_myaddress(addr) 3198360efbdSAlfred Perlstein struct sockaddr_in *addr; 3208360efbdSAlfred Perlstein { 3218360efbdSAlfred Perlstein 3228360efbdSAlfred Perlstein memset((void *) addr, 0, sizeof(*addr)); 3238360efbdSAlfred Perlstein addr->sin_family = AF_INET; 3248360efbdSAlfred Perlstein addr->sin_port = htons(PMAPPORT); 3258360efbdSAlfred Perlstein addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); 3268360efbdSAlfred Perlstein return (0); 3278360efbdSAlfred Perlstein } 3288360efbdSAlfred Perlstein 3298360efbdSAlfred Perlstein /* 3308360efbdSAlfred Perlstein * For connectionless "udp" transport. Obsoleted by rpc_call(). 3318360efbdSAlfred Perlstein */ 3328360efbdSAlfred Perlstein int 3338360efbdSAlfred Perlstein callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) 334b275d8feSAlfred Perlstein const char *host; 3358360efbdSAlfred Perlstein int prognum, versnum, procnum; 3368360efbdSAlfred Perlstein xdrproc_t inproc, outproc; 337cc74aaddSAlfred Perlstein void *in, *out; 3388360efbdSAlfred Perlstein { 3398360efbdSAlfred Perlstein 3408360efbdSAlfred Perlstein return (int)rpc_call(host, (rpcprog_t)prognum, (rpcvers_t)versnum, 3418360efbdSAlfred Perlstein (rpcproc_t)procnum, inproc, in, outproc, out, "udp"); 3428360efbdSAlfred Perlstein } 3438360efbdSAlfred Perlstein 3448360efbdSAlfred Perlstein /* 3458360efbdSAlfred Perlstein * For connectionless kind of transport. Obsoleted by rpc_reg() 3468360efbdSAlfred Perlstein */ 3478360efbdSAlfred Perlstein int 3488360efbdSAlfred Perlstein registerrpc(prognum, versnum, procnum, progname, inproc, outproc) 3498360efbdSAlfred Perlstein int prognum, versnum, procnum; 350c05ac53bSDavid E. O'Brien char *(*progname)(char [UDPMSGSIZE]); 3518360efbdSAlfred Perlstein xdrproc_t inproc, outproc; 3528360efbdSAlfred Perlstein { 3538360efbdSAlfred Perlstein 3548360efbdSAlfred Perlstein return rpc_reg((rpcprog_t)prognum, (rpcvers_t)versnum, 3558360efbdSAlfred Perlstein (rpcproc_t)procnum, progname, inproc, outproc, "udp"); 3568360efbdSAlfred Perlstein } 3578360efbdSAlfred Perlstein 3588360efbdSAlfred Perlstein /* 3598360efbdSAlfred Perlstein * All the following clnt_broadcast stuff is convulated; it supports 3608360efbdSAlfred Perlstein * the earlier calling style of the callback function 3618360efbdSAlfred Perlstein */ 3628360efbdSAlfred Perlstein static thread_key_t clnt_broadcast_key; 3638360efbdSAlfred Perlstein static resultproc_t clnt_broadcast_result_main; 3648360efbdSAlfred Perlstein 3658360efbdSAlfred Perlstein /* 3668360efbdSAlfred Perlstein * Need to translate the netbuf address into sockaddr_in address. 3678360efbdSAlfred Perlstein * Dont care about netid here. 3688360efbdSAlfred Perlstein */ 3698360efbdSAlfred Perlstein /* ARGSUSED */ 3708360efbdSAlfred Perlstein static bool_t 3718360efbdSAlfred Perlstein rpc_wrap_bcast(resultp, addr, nconf) 3728360efbdSAlfred Perlstein char *resultp; /* results of the call */ 3738360efbdSAlfred Perlstein struct netbuf *addr; /* address of the guy who responded */ 3748360efbdSAlfred Perlstein struct netconfig *nconf; /* Netconf of the transport */ 3758360efbdSAlfred Perlstein { 3768360efbdSAlfred Perlstein resultproc_t clnt_broadcast_result; 3778360efbdSAlfred Perlstein 3788360efbdSAlfred Perlstein if (strcmp(nconf->nc_netid, "udp")) 3798360efbdSAlfred Perlstein return (FALSE); 3808360efbdSAlfred Perlstein if (thr_main()) 3818360efbdSAlfred Perlstein clnt_broadcast_result = clnt_broadcast_result_main; 3828360efbdSAlfred Perlstein else 3838360efbdSAlfred Perlstein clnt_broadcast_result = (resultproc_t)thr_getspecific(clnt_broadcast_key); 3848360efbdSAlfred Perlstein return (*clnt_broadcast_result)(resultp, 3858360efbdSAlfred Perlstein (struct sockaddr_in *)addr->buf); 3868360efbdSAlfred Perlstein } 3878360efbdSAlfred Perlstein 3888360efbdSAlfred Perlstein /* 3898360efbdSAlfred Perlstein * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). 3908360efbdSAlfred Perlstein */ 3918360efbdSAlfred Perlstein enum clnt_stat 3928360efbdSAlfred Perlstein clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) 3938360efbdSAlfred Perlstein u_long prog; /* program number */ 3948360efbdSAlfred Perlstein u_long vers; /* version number */ 3958360efbdSAlfred Perlstein u_long proc; /* procedure number */ 3968360efbdSAlfred Perlstein xdrproc_t xargs; /* xdr routine for args */ 397f249dbccSDag-Erling Smørgrav void *argsp; /* pointer to args */ 3988360efbdSAlfred Perlstein xdrproc_t xresults; /* xdr routine for results */ 399f249dbccSDag-Erling Smørgrav void *resultsp; /* pointer to results */ 4008360efbdSAlfred Perlstein resultproc_t eachresult; /* call with each result obtained */ 4018360efbdSAlfred Perlstein { 4028360efbdSAlfred Perlstein extern mutex_t tsd_lock; 4038360efbdSAlfred Perlstein 4048360efbdSAlfred Perlstein if (thr_main()) 4058360efbdSAlfred Perlstein clnt_broadcast_result_main = eachresult; 4068360efbdSAlfred Perlstein else { 4078360efbdSAlfred Perlstein if (clnt_broadcast_key == 0) { 4088360efbdSAlfred Perlstein mutex_lock(&tsd_lock); 4098360efbdSAlfred Perlstein if (clnt_broadcast_key == 0) 4108360efbdSAlfred Perlstein thr_keycreate(&clnt_broadcast_key, free); 4118360efbdSAlfred Perlstein mutex_unlock(&tsd_lock); 4128360efbdSAlfred Perlstein } 4138360efbdSAlfred Perlstein thr_setspecific(clnt_broadcast_key, (void *) eachresult); 4148360efbdSAlfred Perlstein } 4158360efbdSAlfred Perlstein return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, 4168360efbdSAlfred Perlstein (rpcproc_t)proc, xargs, argsp, xresults, resultsp, 4178360efbdSAlfred Perlstein (resultproc_t) rpc_wrap_bcast, "udp"); 4188360efbdSAlfred Perlstein } 4198360efbdSAlfred Perlstein 4208360efbdSAlfred Perlstein /* 4218360efbdSAlfred Perlstein * Create the client des authentication object. Obsoleted by 4228360efbdSAlfred Perlstein * authdes_seccreate(). 4238360efbdSAlfred Perlstein */ 4248360efbdSAlfred Perlstein AUTH * 4258360efbdSAlfred Perlstein authdes_create(servername, window, syncaddr, ckey) 4268360efbdSAlfred Perlstein char *servername; /* network name of server */ 4278360efbdSAlfred Perlstein u_int window; /* time to live */ 4288360efbdSAlfred Perlstein struct sockaddr *syncaddr; /* optional hostaddr to sync with */ 4298360efbdSAlfred Perlstein des_block *ckey; /* optional conversation key to use */ 4308360efbdSAlfred Perlstein { 4318360efbdSAlfred Perlstein AUTH *dummy; 4328360efbdSAlfred Perlstein AUTH *nauth; 4338360efbdSAlfred Perlstein char hostname[NI_MAXHOST]; 4348360efbdSAlfred Perlstein 4358360efbdSAlfred Perlstein if (syncaddr) { 4368360efbdSAlfred Perlstein /* 4378360efbdSAlfred Perlstein * Change addr to hostname, because that is the way 4388360efbdSAlfred Perlstein * new interface takes it. 4398360efbdSAlfred Perlstein */ 4408360efbdSAlfred Perlstein if (getnameinfo(syncaddr, syncaddr->sa_len, hostname, 4418360efbdSAlfred Perlstein sizeof hostname, NULL, 0, 0) != 0) 4428360efbdSAlfred Perlstein goto fallback; 4438360efbdSAlfred Perlstein 4448360efbdSAlfred Perlstein nauth = authdes_seccreate(servername, window, hostname, ckey); 4458360efbdSAlfred Perlstein return (nauth); 4468360efbdSAlfred Perlstein } 4478360efbdSAlfred Perlstein fallback: 4488360efbdSAlfred Perlstein dummy = authdes_seccreate(servername, window, NULL, ckey); 4498360efbdSAlfred Perlstein return (dummy); 4508360efbdSAlfred Perlstein } 4518360efbdSAlfred Perlstein 452e6f9ad07SBill Paul /* 453e6f9ad07SBill Paul * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() 454e6f9ad07SBill Paul */ 455e6f9ad07SBill Paul CLIENT * 456e6f9ad07SBill Paul clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz) 457e6f9ad07SBill Paul struct sockaddr_un *raddr; 458e6f9ad07SBill Paul u_long prog; 459e6f9ad07SBill Paul u_long vers; 4608fb3f3f6SDavid E. O'Brien int *sockp; 461e6f9ad07SBill Paul u_int sendsz; 462e6f9ad07SBill Paul u_int recvsz; 463e6f9ad07SBill Paul { 464e6f9ad07SBill Paul struct netbuf *svcaddr; 465e6f9ad07SBill Paul struct netconfig *nconf; 466e6f9ad07SBill Paul CLIENT *cl; 467e6f9ad07SBill Paul int len; 468e6f9ad07SBill Paul 469e6f9ad07SBill Paul cl = NULL; 4708d630135SAlfred Perlstein nconf = NULL; 4718d630135SAlfred Perlstein svcaddr = NULL; 472e6f9ad07SBill Paul if ((raddr->sun_len == 0) || 473e6f9ad07SBill Paul ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || 474e6f9ad07SBill Paul ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { 475e6f9ad07SBill Paul if (svcaddr != NULL) 476e6f9ad07SBill Paul free(svcaddr); 477e6f9ad07SBill Paul rpc_createerr.cf_stat = RPC_SYSTEMERROR; 478e6f9ad07SBill Paul rpc_createerr.cf_error.re_errno = errno; 479e6f9ad07SBill Paul return(cl); 480e6f9ad07SBill Paul } 481e6f9ad07SBill Paul if (*sockp < 0) { 482e6f9ad07SBill Paul *sockp = _socket(AF_LOCAL, SOCK_STREAM, 0); 483e6f9ad07SBill Paul len = raddr->sun_len = SUN_LEN(raddr); 484e6f9ad07SBill Paul if ((*sockp < 0) || (_connect(*sockp, 485e6f9ad07SBill Paul (struct sockaddr *)raddr, len) < 0)) { 486e6f9ad07SBill Paul rpc_createerr.cf_stat = RPC_SYSTEMERROR; 487e6f9ad07SBill Paul rpc_createerr.cf_error.re_errno = errno; 488e6f9ad07SBill Paul if (*sockp != -1) 489e6f9ad07SBill Paul (void)_close(*sockp); 490e6f9ad07SBill Paul goto done; 491e6f9ad07SBill Paul } 492e6f9ad07SBill Paul } 493e6f9ad07SBill Paul svcaddr->buf = raddr; 494e6f9ad07SBill Paul svcaddr->len = raddr->sun_len; 495e6f9ad07SBill Paul svcaddr->maxlen = sizeof (struct sockaddr_un); 496e6f9ad07SBill Paul cl = clnt_vc_create(*sockp, svcaddr, prog, 497e6f9ad07SBill Paul vers, sendsz, recvsz); 498e6f9ad07SBill Paul done: 499e6f9ad07SBill Paul free(svcaddr->buf); 500e6f9ad07SBill Paul free(svcaddr); 501e6f9ad07SBill Paul return(cl); 502e6f9ad07SBill Paul } 503e6f9ad07SBill Paul 504e6f9ad07SBill Paul /* 505e6f9ad07SBill Paul * Creates, registers, and returns a (rpc) unix based transporter. 506e6f9ad07SBill Paul * Obsoleted by svc_vc_create(). 507e6f9ad07SBill Paul */ 508e6f9ad07SBill Paul SVCXPRT * 509e6f9ad07SBill Paul svcunix_create(sock, sendsize, recvsize, path) 5108fb3f3f6SDavid E. O'Brien int sock; 511e6f9ad07SBill Paul u_int sendsize; 512e6f9ad07SBill Paul u_int recvsize; 513e6f9ad07SBill Paul char *path; 514e6f9ad07SBill Paul { 515e6f9ad07SBill Paul struct netconfig *nconf; 516e6f9ad07SBill Paul void *localhandle; 517e6f9ad07SBill Paul struct sockaddr_un sun; 518e6f9ad07SBill Paul struct sockaddr *sa; 519e6f9ad07SBill Paul struct t_bind taddr; 520e6f9ad07SBill Paul SVCXPRT *xprt; 521e6f9ad07SBill Paul int addrlen; 522e6f9ad07SBill Paul 523e6f9ad07SBill Paul xprt = (SVCXPRT *)NULL; 524e6f9ad07SBill Paul localhandle = setnetconfig(); 525e6f9ad07SBill Paul while ((nconf = getnetconfig(localhandle)) != NULL) { 526e6f9ad07SBill Paul if (nconf->nc_protofmly != NULL && 527e6f9ad07SBill Paul strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 528e6f9ad07SBill Paul break; 529e6f9ad07SBill Paul } 530e6f9ad07SBill Paul if (nconf == NULL) 531e6f9ad07SBill Paul return(xprt); 532e6f9ad07SBill Paul 533e6f9ad07SBill Paul if ((sock = __rpc_nconf2fd(nconf)) < 0) 534e6f9ad07SBill Paul goto done; 535e6f9ad07SBill Paul 536e6f9ad07SBill Paul memset(&sun, 0, sizeof sun); 537e6f9ad07SBill Paul sun.sun_family = AF_LOCAL; 538e6f9ad07SBill Paul if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 539e6f9ad07SBill Paul sizeof(sun.sun_path)) 540e6f9ad07SBill Paul goto done; 541e6f9ad07SBill Paul sun.sun_len = SUN_LEN(&sun); 542e6f9ad07SBill Paul addrlen = sizeof (struct sockaddr_un); 543e6f9ad07SBill Paul sa = (struct sockaddr *)&sun; 544e6f9ad07SBill Paul 545e6f9ad07SBill Paul if (_bind(sock, sa, addrlen) < 0) 546e6f9ad07SBill Paul goto done; 547e6f9ad07SBill Paul 548e6f9ad07SBill Paul taddr.addr.len = taddr.addr.maxlen = addrlen; 549e6f9ad07SBill Paul taddr.addr.buf = malloc(addrlen); 550e6f9ad07SBill Paul if (taddr.addr.buf == NULL) 551e6f9ad07SBill Paul goto done; 552e6f9ad07SBill Paul memcpy(taddr.addr.buf, sa, addrlen); 553e6f9ad07SBill Paul 554e6f9ad07SBill Paul if (nconf->nc_semantics != NC_TPI_CLTS) { 555e6f9ad07SBill Paul if (_listen(sock, SOMAXCONN) < 0) { 556e6f9ad07SBill Paul free(taddr.addr.buf); 557e6f9ad07SBill Paul goto done; 558e6f9ad07SBill Paul } 559e6f9ad07SBill Paul } 560e6f9ad07SBill Paul 561e6f9ad07SBill Paul xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); 562e6f9ad07SBill Paul 563e6f9ad07SBill Paul done: 564e6f9ad07SBill Paul endnetconfig(localhandle); 565e6f9ad07SBill Paul return(xprt); 566e6f9ad07SBill Paul } 567e6f9ad07SBill Paul 568e6f9ad07SBill Paul /* 569e6f9ad07SBill Paul * Like svunix_create(), except the routine takes any *open* UNIX file 570e6f9ad07SBill Paul * descriptor as its first input. Obsoleted by svc_fd_create(); 571e6f9ad07SBill Paul */ 572e6f9ad07SBill Paul SVCXPRT * 573e6f9ad07SBill Paul svcunixfd_create(fd, sendsize, recvsize) 574e6f9ad07SBill Paul int fd; 575e6f9ad07SBill Paul u_int sendsize; 576e6f9ad07SBill Paul u_int recvsize; 577e6f9ad07SBill Paul { 578e6f9ad07SBill Paul return (svc_fd_create(fd, sendsize, recvsize)); 579e6f9ad07SBill Paul } 580e6f9ad07SBill Paul 5818360efbdSAlfred Perlstein #endif /* PORTMAP */ 582