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