174462Salfred/* $NetBSD: rpc_soc.c,v 1.6 2000/07/06 03:10:35 christos Exp $ */ 274462Salfred 3261057Smav/*- 4261057Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261057Smav * All rights reserved. 6261057Smav * 7261057Smav * Redistribution and use in source and binary forms, with or without 8261057Smav * modification, are permitted provided that the following conditions are met: 9261057Smav * - Redistributions of source code must retain the above copyright notice, 10261057Smav * this list of conditions and the following disclaimer. 11261057Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261057Smav * this list of conditions and the following disclaimer in the documentation 13261057Smav * and/or other materials provided with the distribution. 14261057Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261057Smav * contributors may be used to endorse or promote products derived 16261057Smav * from this software without specific prior written permission. 1774462Salfred * 18261057Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261057Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261057Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261057Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261057Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261057Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261057Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261057Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261057Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261057Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261057Smav * POSSIBILITY OF SUCH DAMAGE. 2974462Salfred */ 3074462Salfred 3174462Salfred/* #ident "@(#)rpc_soc.c 1.17 94/04/24 SMI" */ 3274462Salfred 3374462Salfred/* 3474462Salfred * Copyright (c) 1986-1991 by Sun Microsystems Inc. 3574462Salfred * In addition, portions of such source code were derived from Berkeley 3674462Salfred * 4.3 BSD under license from the Regents of the University of 3774462Salfred * California. 3874462Salfred */ 3974462Salfred 40136581Sobrien#if defined(LIBC_SCCS) && !defined(lint) 4174462Salfredstatic char sccsid[] = "@(#)rpc_soc.c 1.41 89/05/02 Copyr 1988 Sun Micro"; 4274462Salfred#endif 4392990Sobrien#include <sys/cdefs.h> 4492990Sobrien__FBSDID("$FreeBSD$"); 4574462Salfred 4674462Salfred#ifdef PORTMAP 4774462Salfred/* 4874462Salfred * rpc_soc.c 4974462Salfred * 5074462Salfred * The backward compatibility routines for the earlier implementation 5174462Salfred * of RPC, where the only transports supported were tcp/ip and udp/ip. 5274462Salfred * Based on berkeley socket abstraction, now implemented on the top 5374462Salfred * of TLI/Streams 5474462Salfred */ 5574462Salfred 5675094Siedowse#include "namespace.h" 5774462Salfred#include "reentrant.h" 5874462Salfred#include <sys/types.h> 5974462Salfred#include <sys/socket.h> 6074462Salfred#include <stdio.h> 6174462Salfred#include <rpc/rpc.h> 6274462Salfred#include <rpc/pmap_clnt.h> 6374462Salfred#include <rpc/pmap_prot.h> 6474462Salfred#include <rpc/nettype.h> 6574462Salfred#include <syslog.h> 6674462Salfred#include <netinet/in.h> 6774462Salfred#include <netdb.h> 6874462Salfred#include <errno.h> 6974462Salfred#include <syslog.h> 7074462Salfred#include <stdlib.h> 7174462Salfred#include <string.h> 7274462Salfred#include <unistd.h> 7374462Salfred#include "un-namespace.h" 7474462Salfred 7574462Salfred#include "rpc_com.h" 76156090Sdeischen#include "mt_misc.h" 7774462Salfred 7892941Sobrienstatic CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, 7992941Sobrien int *, u_int, u_int, char *); 8092905Sobrienstatic SVCXPRT *svc_com_create(int, u_int, u_int, char *); 8192905Sobrienstatic bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *); 8274462Salfred 8374462Salfred/* XXX */ 8474462Salfred#define IN4_LOCALHOST_STRING "127.0.0.1" 8574462Salfred#define IN6_LOCALHOST_STRING "::1" 8674462Salfred 8774462Salfred/* 8874462Salfred * A common clnt create routine 8974462Salfred */ 9074462Salfredstatic CLIENT * 9174462Salfredclnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp) 9274462Salfred struct sockaddr_in *raddr; 9374462Salfred rpcprog_t prog; 9474462Salfred rpcvers_t vers; 9574462Salfred int *sockp; 9674462Salfred u_int sendsz; 9774462Salfred u_int recvsz; 9874462Salfred char *tp; 9974462Salfred{ 10074462Salfred CLIENT *cl; 10174462Salfred int madefd = FALSE; 10274462Salfred int fd = *sockp; 10374462Salfred struct netconfig *nconf; 10474462Salfred struct netbuf bindaddr; 10574462Salfred 10674462Salfred mutex_lock(&rpcsoc_lock); 10774462Salfred if ((nconf = __rpc_getconfip(tp)) == NULL) { 10874462Salfred rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 10974462Salfred mutex_unlock(&rpcsoc_lock); 11074462Salfred return (NULL); 11174462Salfred } 11274462Salfred if (fd == RPC_ANYSOCK) { 11374462Salfred fd = __rpc_nconf2fd(nconf); 11474462Salfred if (fd == -1) 11574462Salfred goto syserror; 11674462Salfred madefd = TRUE; 11774462Salfred } 11874462Salfred 11974462Salfred if (raddr->sin_port == 0) { 12074462Salfred u_int proto; 12174462Salfred u_short sport; 12274462Salfred 12374462Salfred mutex_unlock(&rpcsoc_lock); /* pmap_getport is recursive */ 12474462Salfred proto = strcmp(tp, "udp") == 0 ? IPPROTO_UDP : IPPROTO_TCP; 12574462Salfred sport = pmap_getport(raddr, (u_long)prog, (u_long)vers, 12674462Salfred proto); 12774462Salfred if (sport == 0) { 12874462Salfred goto err; 12974462Salfred } 13074462Salfred raddr->sin_port = htons(sport); 13174462Salfred mutex_lock(&rpcsoc_lock); /* pmap_getport is recursive */ 13274462Salfred } 13374462Salfred 13474462Salfred /* Transform sockaddr_in to netbuf */ 13574462Salfred bindaddr.maxlen = bindaddr.len = sizeof (struct sockaddr_in); 13674462Salfred bindaddr.buf = raddr; 13774462Salfred 13874462Salfred bindresvport(fd, NULL); 13974462Salfred cl = clnt_tli_create(fd, nconf, &bindaddr, prog, vers, 14074462Salfred sendsz, recvsz); 14174462Salfred if (cl) { 14274462Salfred if (madefd == TRUE) { 14374462Salfred /* 14474462Salfred * The fd should be closed while destroying the handle. 14574462Salfred */ 14674462Salfred (void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); 14774462Salfred *sockp = fd; 14874462Salfred } 14974462Salfred (void) freenetconfigent(nconf); 15074462Salfred mutex_unlock(&rpcsoc_lock); 15174462Salfred return (cl); 15274462Salfred } 15374462Salfred goto err; 15474462Salfred 15574462Salfredsyserror: 15674462Salfred rpc_createerr.cf_stat = RPC_SYSTEMERROR; 15774462Salfred rpc_createerr.cf_error.re_errno = errno; 15874462Salfred 15974462Salfrederr: if (madefd == TRUE) 16074462Salfred (void)_close(fd); 16174462Salfred (void) freenetconfigent(nconf); 16274462Salfred mutex_unlock(&rpcsoc_lock); 16374462Salfred return (NULL); 16474462Salfred} 16574462Salfred 16674462SalfredCLIENT * 16774462Salfredclntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz) 16874462Salfred struct sockaddr_in *raddr; 16974462Salfred u_long prog; 17074462Salfred u_long vers; 17174462Salfred struct timeval wait; 17274462Salfred int *sockp; 17374462Salfred u_int sendsz; 17474462Salfred u_int recvsz; 17574462Salfred{ 17674462Salfred CLIENT *cl; 17774462Salfred 17874462Salfred cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 17974462Salfred sendsz, recvsz, "udp"); 18074462Salfred if (cl == NULL) { 18174462Salfred return (NULL); 18274462Salfred } 18395658Sdes (void) CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait); 18474462Salfred return (cl); 18574462Salfred} 18674462Salfred 18774462SalfredCLIENT * 18874462Salfredclntudp_create(raddr, program, version, wait, sockp) 18974462Salfred struct sockaddr_in *raddr; 19074462Salfred u_long program; 19174462Salfred u_long version; 19274462Salfred struct timeval wait; 19374462Salfred int *sockp; 19474462Salfred{ 19574462Salfred 19674462Salfred return clntudp_bufcreate(raddr, program, version, wait, sockp, 19774462Salfred UDPMSGSIZE, UDPMSGSIZE); 19874462Salfred} 19974462Salfred 20074462SalfredCLIENT * 20174462Salfredclnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) 20274462Salfred struct sockaddr_in *raddr; 20374462Salfred u_long prog; 20474462Salfred u_long vers; 20574462Salfred int *sockp; 20674462Salfred u_int sendsz; 20774462Salfred u_int recvsz; 20874462Salfred{ 20974462Salfred 21074462Salfred return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 21174462Salfred sendsz, recvsz, "tcp"); 21274462Salfred} 21374462Salfred 21474462SalfredCLIENT * 21574462Salfredclntraw_create(prog, vers) 21674462Salfred u_long prog; 21774462Salfred u_long vers; 21874462Salfred{ 21974462Salfred 22074462Salfred return clnt_raw_create((rpcprog_t)prog, (rpcvers_t)vers); 22174462Salfred} 22274462Salfred 22374462Salfred/* 22474462Salfred * A common server create routine 22574462Salfred */ 22674462Salfredstatic SVCXPRT * 22774462Salfredsvc_com_create(fd, sendsize, recvsize, netid) 22874462Salfred int fd; 22974462Salfred u_int sendsize; 23074462Salfred u_int recvsize; 23174462Salfred char *netid; 23274462Salfred{ 23374462Salfred struct netconfig *nconf; 23474462Salfred SVCXPRT *svc; 23574462Salfred int madefd = FALSE; 23674462Salfred int port; 23774462Salfred struct sockaddr_in sin; 23874462Salfred 23974462Salfred if ((nconf = __rpc_getconfip(netid)) == NULL) { 24074462Salfred (void) syslog(LOG_ERR, "Could not get %s transport", netid); 24174462Salfred return (NULL); 24274462Salfred } 24374462Salfred if (fd == RPC_ANYSOCK) { 24474462Salfred fd = __rpc_nconf2fd(nconf); 24574462Salfred if (fd == -1) { 24674462Salfred (void) freenetconfigent(nconf); 24774462Salfred (void) syslog(LOG_ERR, 24874462Salfred "svc%s_create: could not open connection", netid); 24974462Salfred return (NULL); 25074462Salfred } 25174462Salfred madefd = TRUE; 25274462Salfred } 25374462Salfred 25474462Salfred memset(&sin, 0, sizeof sin); 25574462Salfred sin.sin_family = AF_INET; 25674462Salfred bindresvport(fd, &sin); 25774462Salfred _listen(fd, SOMAXCONN); 25874462Salfred svc = svc_tli_create(fd, nconf, NULL, sendsize, recvsize); 25974462Salfred (void) freenetconfigent(nconf); 26074462Salfred if (svc == NULL) { 26174462Salfred if (madefd) 26274462Salfred (void)_close(fd); 26374462Salfred return (NULL); 26474462Salfred } 26574462Salfred port = (((struct sockaddr_in *)svc->xp_ltaddr.buf)->sin_port); 26674462Salfred svc->xp_port = ntohs(port); 26774462Salfred return (svc); 26874462Salfred} 26974462Salfred 27074462SalfredSVCXPRT * 27174462Salfredsvctcp_create(fd, sendsize, recvsize) 27274462Salfred int fd; 27374462Salfred u_int sendsize; 27474462Salfred u_int recvsize; 27574462Salfred{ 27674462Salfred 27774462Salfred return svc_com_create(fd, sendsize, recvsize, "tcp"); 27874462Salfred} 27974462Salfred 28074462SalfredSVCXPRT * 28174462Salfredsvcudp_bufcreate(fd, sendsz, recvsz) 28274462Salfred int fd; 28374462Salfred u_int sendsz, recvsz; 28474462Salfred{ 28574462Salfred 28674462Salfred return svc_com_create(fd, sendsz, recvsz, "udp"); 28774462Salfred} 28874462Salfred 28974462SalfredSVCXPRT * 29074462Salfredsvcfd_create(fd, sendsize, recvsize) 29174462Salfred int fd; 29274462Salfred u_int sendsize; 29374462Salfred u_int recvsize; 29474462Salfred{ 29574462Salfred 29674462Salfred return svc_fd_create(fd, sendsize, recvsize); 29774462Salfred} 29874462Salfred 29974462Salfred 30074462SalfredSVCXPRT * 30174462Salfredsvcudp_create(fd) 30274462Salfred int fd; 30374462Salfred{ 30474462Salfred 30574462Salfred return svc_com_create(fd, UDPMSGSIZE, UDPMSGSIZE, "udp"); 30674462Salfred} 30774462Salfred 30874462SalfredSVCXPRT * 30974462Salfredsvcraw_create() 31074462Salfred{ 31174462Salfred 31274462Salfred return svc_raw_create(); 31374462Salfred} 31474462Salfred 31574462Salfredint 31674462Salfredget_myaddress(addr) 31774462Salfred struct sockaddr_in *addr; 31874462Salfred{ 31974462Salfred 32074462Salfred memset((void *) addr, 0, sizeof(*addr)); 32174462Salfred addr->sin_family = AF_INET; 32274462Salfred addr->sin_port = htons(PMAPPORT); 32374462Salfred addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); 32474462Salfred return (0); 32574462Salfred} 32674462Salfred 32774462Salfred/* 32874462Salfred * For connectionless "udp" transport. Obsoleted by rpc_call(). 32974462Salfred */ 33074462Salfredint 33174462Salfredcallrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) 33292968Salfred const char *host; 33374462Salfred int prognum, versnum, procnum; 33474462Salfred xdrproc_t inproc, outproc; 33574695Salfred void *in, *out; 33674462Salfred{ 33774462Salfred 33874462Salfred return (int)rpc_call(host, (rpcprog_t)prognum, (rpcvers_t)versnum, 33974462Salfred (rpcproc_t)procnum, inproc, in, outproc, out, "udp"); 34074462Salfred} 34174462Salfred 34274462Salfred/* 34374462Salfred * For connectionless kind of transport. Obsoleted by rpc_reg() 34474462Salfred */ 34574462Salfredint 34674462Salfredregisterrpc(prognum, versnum, procnum, progname, inproc, outproc) 34774462Salfred int prognum, versnum, procnum; 34892905Sobrien char *(*progname)(char [UDPMSGSIZE]); 34974462Salfred xdrproc_t inproc, outproc; 35074462Salfred{ 35174462Salfred 35274462Salfred return rpc_reg((rpcprog_t)prognum, (rpcvers_t)versnum, 35374462Salfred (rpcproc_t)procnum, progname, inproc, outproc, "udp"); 35474462Salfred} 35574462Salfred 35674462Salfred/* 35774462Salfred * All the following clnt_broadcast stuff is convulated; it supports 35874462Salfred * the earlier calling style of the callback function 35974462Salfred */ 36074462Salfredstatic thread_key_t clnt_broadcast_key; 36174462Salfredstatic resultproc_t clnt_broadcast_result_main; 362204950Sjhbstatic once_t clnt_broadcast_once = ONCE_INITIALIZER; 36374462Salfred 364204950Sjhbstatic void 365204950Sjhbclnt_broadcast_key_init(void) 366204950Sjhb{ 367204950Sjhb 368204950Sjhb thr_keycreate(&clnt_broadcast_key, free); 369204950Sjhb} 370204950Sjhb 37174462Salfred/* 37274462Salfred * Need to translate the netbuf address into sockaddr_in address. 37374462Salfred * Dont care about netid here. 37474462Salfred */ 37574462Salfred/* ARGSUSED */ 37674462Salfredstatic bool_t 37774462Salfredrpc_wrap_bcast(resultp, addr, nconf) 37874462Salfred char *resultp; /* results of the call */ 37974462Salfred struct netbuf *addr; /* address of the guy who responded */ 38074462Salfred struct netconfig *nconf; /* Netconf of the transport */ 38174462Salfred{ 38274462Salfred resultproc_t clnt_broadcast_result; 38374462Salfred 38474462Salfred if (strcmp(nconf->nc_netid, "udp")) 38574462Salfred return (FALSE); 38674462Salfred if (thr_main()) 38774462Salfred clnt_broadcast_result = clnt_broadcast_result_main; 38874462Salfred else 38974462Salfred clnt_broadcast_result = (resultproc_t)thr_getspecific(clnt_broadcast_key); 39074462Salfred return (*clnt_broadcast_result)(resultp, 39174462Salfred (struct sockaddr_in *)addr->buf); 39274462Salfred} 39374462Salfred 39474462Salfred/* 39574462Salfred * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). 39674462Salfred */ 39774462Salfredenum clnt_stat 39874462Salfredclnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) 39974462Salfred u_long prog; /* program number */ 40074462Salfred u_long vers; /* version number */ 40174462Salfred u_long proc; /* procedure number */ 40274462Salfred xdrproc_t xargs; /* xdr routine for args */ 40395658Sdes void *argsp; /* pointer to args */ 40474462Salfred xdrproc_t xresults; /* xdr routine for results */ 40595658Sdes void *resultsp; /* pointer to results */ 40674462Salfred resultproc_t eachresult; /* call with each result obtained */ 40774462Salfred{ 40874462Salfred 40974462Salfred if (thr_main()) 41074462Salfred clnt_broadcast_result_main = eachresult; 41174462Salfred else { 412204950Sjhb thr_once(&clnt_broadcast_once, clnt_broadcast_key_init); 41374462Salfred thr_setspecific(clnt_broadcast_key, (void *) eachresult); 41474462Salfred } 41574462Salfred return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, 41674462Salfred (rpcproc_t)proc, xargs, argsp, xresults, resultsp, 41774462Salfred (resultproc_t) rpc_wrap_bcast, "udp"); 41874462Salfred} 41974462Salfred 42074462Salfred/* 42174462Salfred * Create the client des authentication object. Obsoleted by 42274462Salfred * authdes_seccreate(). 42374462Salfred */ 42474462SalfredAUTH * 42574462Salfredauthdes_create(servername, window, syncaddr, ckey) 42674462Salfred char *servername; /* network name of server */ 42774462Salfred u_int window; /* time to live */ 42874462Salfred struct sockaddr *syncaddr; /* optional hostaddr to sync with */ 42974462Salfred des_block *ckey; /* optional conversation key to use */ 43074462Salfred{ 43174462Salfred AUTH *dummy; 43274462Salfred AUTH *nauth; 43374462Salfred char hostname[NI_MAXHOST]; 43474462Salfred 43574462Salfred if (syncaddr) { 43674462Salfred /* 43774462Salfred * Change addr to hostname, because that is the way 43874462Salfred * new interface takes it. 43974462Salfred */ 44074462Salfred if (getnameinfo(syncaddr, syncaddr->sa_len, hostname, 44174462Salfred sizeof hostname, NULL, 0, 0) != 0) 44274462Salfred goto fallback; 44374462Salfred 44474462Salfred nauth = authdes_seccreate(servername, window, hostname, ckey); 44574462Salfred return (nauth); 44674462Salfred } 44774462Salfredfallback: 44874462Salfred dummy = authdes_seccreate(servername, window, NULL, ckey); 44974462Salfred return (dummy); 45074462Salfred} 45174462Salfred 45284487Swpaul/* 45384487Swpaul * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() 45484487Swpaul */ 45584487SwpaulCLIENT * 45684487Swpaulclntunix_create(raddr, prog, vers, sockp, sendsz, recvsz) 45784487Swpaul struct sockaddr_un *raddr; 45884487Swpaul u_long prog; 45984487Swpaul u_long vers; 46092889Sobrien int *sockp; 46184487Swpaul u_int sendsz; 46284487Swpaul u_int recvsz; 46384487Swpaul{ 46484487Swpaul struct netbuf *svcaddr; 46584487Swpaul struct netconfig *nconf; 46684487Swpaul CLIENT *cl; 46784487Swpaul int len; 46884487Swpaul 46990271Salfred cl = NULL; 47084487Swpaul nconf = NULL; 47190271Salfred svcaddr = NULL; 47284487Swpaul if ((raddr->sun_len == 0) || 47384487Swpaul ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || 47484487Swpaul ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { 47584487Swpaul if (svcaddr != NULL) 47684487Swpaul free(svcaddr); 47784487Swpaul rpc_createerr.cf_stat = RPC_SYSTEMERROR; 47884487Swpaul rpc_createerr.cf_error.re_errno = errno; 47984487Swpaul return(cl); 48084487Swpaul } 48184487Swpaul if (*sockp < 0) { 48284487Swpaul *sockp = _socket(AF_LOCAL, SOCK_STREAM, 0); 48384487Swpaul len = raddr->sun_len = SUN_LEN(raddr); 48484487Swpaul if ((*sockp < 0) || (_connect(*sockp, 48584487Swpaul (struct sockaddr *)raddr, len) < 0)) { 48684487Swpaul rpc_createerr.cf_stat = RPC_SYSTEMERROR; 48784487Swpaul rpc_createerr.cf_error.re_errno = errno; 48884487Swpaul if (*sockp != -1) 48984487Swpaul (void)_close(*sockp); 49084487Swpaul goto done; 49184487Swpaul } 49284487Swpaul } 49384487Swpaul svcaddr->buf = raddr; 49484487Swpaul svcaddr->len = raddr->sun_len; 49584487Swpaul svcaddr->maxlen = sizeof (struct sockaddr_un); 49684487Swpaul cl = clnt_vc_create(*sockp, svcaddr, prog, 49784487Swpaul vers, sendsz, recvsz); 49884487Swpauldone: 49984487Swpaul free(svcaddr->buf); 50084487Swpaul free(svcaddr); 50184487Swpaul return(cl); 50284487Swpaul} 50384487Swpaul 50484487Swpaul/* 50584487Swpaul * Creates, registers, and returns a (rpc) unix based transporter. 50684487Swpaul * Obsoleted by svc_vc_create(). 50784487Swpaul */ 50884487SwpaulSVCXPRT * 50984487Swpaulsvcunix_create(sock, sendsize, recvsize, path) 51092889Sobrien int sock; 51184487Swpaul u_int sendsize; 51284487Swpaul u_int recvsize; 51384487Swpaul char *path; 51484487Swpaul{ 51584487Swpaul struct netconfig *nconf; 51684487Swpaul void *localhandle; 51784487Swpaul struct sockaddr_un sun; 51884487Swpaul struct sockaddr *sa; 51984487Swpaul struct t_bind taddr; 52084487Swpaul SVCXPRT *xprt; 52184487Swpaul int addrlen; 52284487Swpaul 52384487Swpaul xprt = (SVCXPRT *)NULL; 52484487Swpaul localhandle = setnetconfig(); 52584487Swpaul while ((nconf = getnetconfig(localhandle)) != NULL) { 52684487Swpaul if (nconf->nc_protofmly != NULL && 52784487Swpaul strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 52884487Swpaul break; 52984487Swpaul } 53084487Swpaul if (nconf == NULL) 53184487Swpaul return(xprt); 53284487Swpaul 53384487Swpaul if ((sock = __rpc_nconf2fd(nconf)) < 0) 53484487Swpaul goto done; 53584487Swpaul 53684487Swpaul memset(&sun, 0, sizeof sun); 53784487Swpaul sun.sun_family = AF_LOCAL; 538114443Snectar if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 53984487Swpaul sizeof(sun.sun_path)) 54084487Swpaul goto done; 54184487Swpaul sun.sun_len = SUN_LEN(&sun); 54284487Swpaul addrlen = sizeof (struct sockaddr_un); 54384487Swpaul sa = (struct sockaddr *)&sun; 54484487Swpaul 54584487Swpaul if (_bind(sock, sa, addrlen) < 0) 54684487Swpaul goto done; 54784487Swpaul 54884487Swpaul taddr.addr.len = taddr.addr.maxlen = addrlen; 54984487Swpaul taddr.addr.buf = malloc(addrlen); 55084487Swpaul if (taddr.addr.buf == NULL) 55184487Swpaul goto done; 55284487Swpaul memcpy(taddr.addr.buf, sa, addrlen); 55384487Swpaul 55484487Swpaul if (nconf->nc_semantics != NC_TPI_CLTS) { 55584487Swpaul if (_listen(sock, SOMAXCONN) < 0) { 55684487Swpaul free(taddr.addr.buf); 55784487Swpaul goto done; 55884487Swpaul } 55984487Swpaul } 56084487Swpaul 56184487Swpaul xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); 56284487Swpaul 56384487Swpauldone: 56484487Swpaul endnetconfig(localhandle); 56584487Swpaul return(xprt); 56684487Swpaul} 56784487Swpaul 56884487Swpaul/* 56984487Swpaul * Like svunix_create(), except the routine takes any *open* UNIX file 57084487Swpaul * descriptor as its first input. Obsoleted by svc_fd_create(); 57184487Swpaul */ 57284487SwpaulSVCXPRT * 57384487Swpaulsvcunixfd_create(fd, sendsize, recvsize) 57484487Swpaul int fd; 57584487Swpaul u_int sendsize; 57684487Swpaul u_int recvsize; 57784487Swpaul{ 57884487Swpaul return (svc_fd_create(fd, sendsize, recvsize)); 57984487Swpaul} 58084487Swpaul 58174462Salfred#endif /* PORTMAP */ 582