/*
 * Copyright (c) 2009, Sun Microsystems, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code mut retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name of Sun Microsystems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Copyright (c) 1986-1991 by Sun Microsystems Inc.
 */

#include <config.h>
#include <sys/cdefs.h>

/*
 * rpc_generic.c, Miscl routines for RPC.
 *
 */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <rpc/types.h>
#include <misc/portable.h>
#include <rpc/rpc.h>
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <netdb.h>
#include <netconfig.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/nettype.h>

#include "rpc_com.h"

tirpc_pkg_params __ntirpc_pkg_params = {
	TIRPC_FLAG_NONE,
	TIRPC_DEBUG_FLAG_NONE,
	warnx
};

bool
tirpc_control(const u_int rq, void *in)
{
	switch (rq) {
	case TIRPC_GET_FLAGS:
		*(u_int *) in = __ntirpc_pkg_params.flags;
		break;
	case TIRPC_SET_FLAGS:
		__ntirpc_pkg_params.flags = *(int *)in;
		break;
	case TIRPC_GET_DEBUG_FLAGS:
		*(u_int *) in = __ntirpc_pkg_params.debug_flags;
		break;
	case TIRPC_SET_DEBUG_FLAGS:
		__ntirpc_pkg_params.debug_flags = *(int *)in;
		break;
	case TIRPC_GET_WARNX:
		*(warnx_t *) in = __ntirpc_pkg_params.warnx;
		break;
	case TIRPC_SET_WARNX:
		__ntirpc_pkg_params.warnx = *(warnx_t) in;
		break;
	default:
		return (false);
	}
	return (true);
}

struct handle {
	NCONF_HANDLE *nhandle;
	int nflag;		/* Whether NETPATH or NETCONFIG */
	int nettype;
};

static const struct _rpcnettype {
	const char *name;
	const int type;
} _rpctypelist[] = {
	{
	"netpath", _RPC_NETPATH}, {
	"visible", _RPC_VISIBLE}, {
	"circuit_v", _RPC_CIRCUIT_V}, {
	"datagram_v", _RPC_DATAGRAM_V}, {
	"circuit_n", _RPC_CIRCUIT_N}, {
	"datagram_n", _RPC_DATAGRAM_N}, {
	"tcp", _RPC_TCP}, {
	"udp", _RPC_UDP}, {
	0, _RPC_NONE}
};

struct netid_af {
	const char *netid;
	int af;
	int protocol;
};

static const struct netid_af na_cvt[] = {
	{"udp", AF_INET, IPPROTO_UDP},
	{"tcp", AF_INET, IPPROTO_TCP},
#ifdef INET6
	{"udp6", AF_INET6, IPPROTO_UDP},
	{"tcp6", AF_INET6, IPPROTO_TCP},
#endif
	{"local", AF_LOCAL, 0}
};

#if 0
static char *strlocase(char *);
#endif
static int getnettype(const char *);

/*
 * Cache the result of getrlimit(), so we don't have to do an
 * expensive call every time.
 */
int
__rpc_dtbsize(void)
{
	static int tbsize;
	struct rlimit rl;

	if (tbsize)
		return (tbsize);
	if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
		return (tbsize = (int)rl.rlim_max);
	/*
	 * Something wrong.  I'll try to save face by returning a
	 * pessimistic number.
	 */
	return (32);
}

/*
 * Find the appropriate buffer size
 */
u_int /*ARGSUSED*/
__rpc_get_t_size(int af, int proto, int size)
{
	int maxsize, defsize;

	maxsize = 256 * 1024;	/* XXX */
	switch (proto) {
	case IPPROTO_TCP:
		defsize = 64 * 1024;	/* XXX */
		break;
	case IPPROTO_UDP:
		defsize = UDPMSGSIZE;
		break;
	default:
		defsize = RPC_MAXDATASIZE;
		break;
	}
	if (size == 0)
		return defsize;

	/* Check whether the value is within the upper max limit */
	return (size > maxsize ? (u_int) maxsize : (u_int) size);
}

/*
 * Find the appropriate address buffer size
 */
u_int
__rpc_get_a_size(int af)
{
	switch (af) {
	case AF_INET:
		return sizeof(struct sockaddr_in);
#ifdef INET6
	case AF_INET6:
		return sizeof(struct sockaddr_in6);
#endif
	case AF_LOCAL:
		return sizeof(struct sockaddr_un);
	default:
		break;
	}

	return ((u_int) RPC_MAXADDRSIZE);
}

#if 0
static char *
strlocase(char *p)
{
	char *t = p;

	for (; *p; p++)
		if (isupper(*p))
			*p = tolower(*p);
	return (t);
}
#endif

/*
 * Returns the type of the network as defined in <rpc/nettype.h>
 * If nettype is NULL, it defaults to NETPATH.
 */
static int
getnettype(const char *nettype)
{
	int i;

	if ((nettype == NULL) || (nettype[0] == 0))
		return (_RPC_NETPATH);	/* Default */
#if 0
	nettype = strlocase(nettype);
#endif
	for (i = 0; _rpctypelist[i].name; i++) {
		if (strcasecmp(nettype, _rpctypelist[i].name) == 0)
			return (_rpctypelist[i].type);
	}

	return (_rpctypelist[i].type);
}

/*
 * For the given nettype (tcp or udp only), return the first structure found.
 * This should be freed by calling freenetconfigent()
 */
struct netconfig *
__rpc_getconfip(const char *nettype)
{
	char *netid;
	char *netid_tcp = (char *)NULL;
	char *netid_udp = (char *)NULL;
	struct netconfig *dummy;
	extern thread_key_t tcp_key, udp_key;
	extern mutex_t tsd_lock;

	if (tcp_key == -1) {
		mutex_lock(&tsd_lock);
		if (tcp_key == -1)
			thr_keycreate(&tcp_key, free);	/* XXX */
		mutex_unlock(&tsd_lock);
	}
	netid_tcp = (char *)thr_getspecific(tcp_key);
	if (udp_key == -1) {
		mutex_lock(&tsd_lock);
		if (udp_key == -1)
			thr_keycreate(&udp_key, free);
		mutex_unlock(&tsd_lock);
	}
	netid_udp = (char *)thr_getspecific(udp_key);
	if (!netid_udp && !netid_tcp) {
		struct netconfig *nconf;
		void *confighandle;

		confighandle = setnetconfig();
		if (!confighandle) {
			__warnx(TIRPC_DEBUG_FLAG_DEFAULT,
				"rpc: failed to open %s", NETCONFIG);
			return (NULL);
		}
		while ((nconf = getnetconfig(confighandle)) != NULL) {
			if (strcmp(nconf->nc_protofmly, NC_INET) == 0
			    || strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
				if (strcmp(nconf->nc_proto, NC_TCP) == 0
				    && netid_tcp == NULL) {
					netid_tcp = rpc_strdup(nconf->nc_netid);
					thr_setspecific(tcp_key,
							(void *)netid_tcp);
				} else if (strcmp(nconf->nc_proto, NC_UDP) == 0
					   && netid_udp == NULL) {
					netid_udp = rpc_strdup(nconf->nc_netid);
					thr_setspecific(udp_key,
							(void *)netid_udp);
				}
			}
		}
		endnetconfig(confighandle);
	}
	if (strcmp(nettype, "udp") == 0)
		netid = netid_udp;
	else if (strcmp(nettype, "tcp") == 0)
		netid = netid_tcp;
	else
		return (NULL);
	if ((netid == NULL) || (netid[0] == 0))
		return (NULL);
	dummy = getnetconfigent(netid);

	return (dummy);
}

/*
 * Returns the type of the nettype, which should then be used with
 * __rpc_getconf().
 */
void *
__rpc_setconf(const char *nettype)
{
	struct handle *handle;

	handle = (struct handle *)mem_zalloc(sizeof(struct handle));
	if (handle == NULL)
		return (NULL);
	switch (handle->nettype = getnettype(nettype)) {
	case _RPC_NETPATH:
	case _RPC_CIRCUIT_N:
	case _RPC_DATAGRAM_N:
		handle->nhandle = setnetpath();
		if (!handle->nhandle) {
			mem_free(handle, 0);	/* XXX */
			return (NULL);
		}
		handle->nflag = true;
		break;
	case _RPC_VISIBLE:
	case _RPC_CIRCUIT_V:
	case _RPC_DATAGRAM_V:
	case _RPC_TCP:
	case _RPC_UDP:
		handle->nhandle = setnetconfig();
		if (!handle->nhandle) {
			__warnx(TIRPC_DEBUG_FLAG_DEFAULT,
				"rpc: failed to open %s", NETCONFIG);
			mem_free(handle, 0);
			return (NULL);
		}
		handle->nflag = false;
		break;
	default:
		mem_free(handle, 0);
		return (NULL);
	}

	return (handle);
}

/*
 * Returns the next netconfig struct for the given "net" type.
 * __rpc_setconf() should have been called previously.
 */
struct netconfig *
__rpc_getconf(void *vhandle)
{
	struct handle *handle;
	struct netconfig *nconf;

	handle = (struct handle *)vhandle;
	if (handle == NULL)
		return (NULL);
	for (;;) {
		if (handle->nflag)
			nconf = getnetpath(handle->nhandle);
		else
			nconf = getnetconfig(handle->nhandle);
		if (nconf == NULL)
			break;
		if ((nconf->nc_semantics != NC_TPI_CLTS)
		    && (nconf->nc_semantics != NC_TPI_COTS)
		    && (nconf->nc_semantics != NC_TPI_COTS_ORD))
			continue;
		switch (handle->nettype) {
		case _RPC_VISIBLE:
			if (!(nconf->nc_flag & NC_VISIBLE))
				continue;
			/* FALLTHROUGH */
		case _RPC_NETPATH:	/* Be happy */
			break;
		case _RPC_CIRCUIT_V:
			if (!(nconf->nc_flag & NC_VISIBLE))
				continue;
			/* FALLTHROUGH */
		case _RPC_CIRCUIT_N:
			if ((nconf->nc_semantics != NC_TPI_COTS)
			    && (nconf->nc_semantics != NC_TPI_COTS_ORD))
				continue;
			break;
		case _RPC_DATAGRAM_V:
			if (!(nconf->nc_flag & NC_VISIBLE))
				continue;
			/* FALLTHROUGH */
		case _RPC_DATAGRAM_N:
			if (nconf->nc_semantics != NC_TPI_CLTS)
				continue;
			break;
		case _RPC_TCP:
			if (((nconf->nc_semantics != NC_TPI_COTS)
			     && (nconf->nc_semantics != NC_TPI_COTS_ORD))
			    || (strcmp(nconf->nc_protofmly, NC_INET)
#ifdef INET6
				&& strcmp(nconf->nc_protofmly, NC_INET6))
#else
			    )
#endif
			    || strcmp(nconf->nc_proto, NC_TCP))
				continue;
			break;
		case _RPC_UDP:
			if ((nconf->nc_semantics != NC_TPI_CLTS)
			    || (strcmp(nconf->nc_protofmly, NC_INET)
#ifdef INET6
				&& strcmp(nconf->nc_protofmly, NC_INET6))
#else
			    )
#endif
			    || strcmp(nconf->nc_proto, NC_UDP))
				continue;
			break;
		}
		break;
	}
	return (nconf);
}

void
__rpc_endconf(void *vhandle)
{
	struct handle *handle;

	handle = (struct handle *)vhandle;
	if (handle == NULL)
		return;
	if (handle->nflag)
		endnetpath(handle->nhandle);
	else
		endnetconfig(handle->nhandle);
	mem_free(handle, 0);
}

/*
 * Used to ping the NULL procedure for clnt handle.
 * Returns NULL if fails, else a non-NULL pointer.
 */
void *
rpc_nullproc(CLIENT *clnt)
{
	struct timeval TIMEOUT = { 25, 0 };
	AUTH *auth;

	auth = authnone_create();	/* idempotent */
	if (clnt_call
	    (clnt, auth, NULLPROC, (xdrproc_t) xdr_void, NULL,
	     (xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS) {
		return (NULL);
	}

	return ((void *)clnt);
}

/*
 * Try all possible transports until
 * one succeeds in finding the netconf for the given fd.
 */
struct netconfig *
__rpcgettp(int fd)
{
	const char *netid;
	struct __rpc_sockinfo si;

	if (!__rpc_fd2sockinfo(fd, &si))
		return NULL;

	if (!__rpc_sockinfo2netid(&si, &netid))
		return NULL;

	/*LINTED const castaway */
	return getnetconfigent((char *)netid);
}

int
__rpc_fd2sockinfo(int fd, struct __rpc_sockinfo *sip)
{
	socklen_t len;
	int type, proto;
	struct sockaddr_storage ss;

	len = sizeof(ss);
	if (getsockname(fd, (struct sockaddr *)&ss, &len) < 0)
		return 0;
	sip->si_alen = len;

	len = sizeof(type);
	if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
		return 0;

	/* XXX */
	if (ss.ss_family != AF_LOCAL) {
		if (type == SOCK_STREAM)
			proto = IPPROTO_TCP;
		else if (type == SOCK_DGRAM)
			proto = IPPROTO_UDP;
		else
			return 0;
	} else
		proto = 0;

	sip->si_af = ss.ss_family;
	sip->si_proto = proto;
	sip->si_socktype = type;

	return 1;
}

/*
 * Linear search, but the number of entries is small.
 */
int
__rpc_nconf2sockinfo(const struct netconfig *nconf,
		     struct __rpc_sockinfo *sip)
{
	int i;

	for (i = 0; i < (sizeof(na_cvt)) / (sizeof(struct netid_af)); i++)
		if (strcmp(na_cvt[i].netid, nconf->nc_netid) == 0
		    || (strcmp(nconf->nc_netid, "unix") == 0
			&& strcmp(na_cvt[i].netid, "local") == 0)) {
			sip->si_af = na_cvt[i].af;
			sip->si_proto = na_cvt[i].protocol;
			sip->si_socktype =
			    __rpc_seman2socktype((int)nconf->nc_semantics);
			if (sip->si_socktype == -1)
				return 0;
			sip->si_alen = __rpc_get_a_size(sip->si_af);
			return 1;
		}

	return 0;
}

int
__rpc_nconf2fd_flags(const struct netconfig *nconf, int flags)
{
	struct __rpc_sockinfo si;
	int fd;

	if (!__rpc_nconf2sockinfo(nconf, &si))
		return 0;

	fd = socket(si.si_af, si.si_socktype | flags, si.si_proto);
	if ((fd >= 0) &&
	    (si.si_af == AF_INET6)) {
#ifdef SOL_IPV6
		int val = 1;
		(void) setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, &val,
				  sizeof(val));
#endif
	}

	return fd;
}

int
__rpc_nconf2fd(const struct netconfig *nconf)
{
	return __rpc_nconf2fd_flags(nconf, 0);
}

int
__rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid)
{
	int i;
	struct netconfig *nconf;

	nconf = getnetconfigent("local");

	for (i = 0; i < (sizeof(na_cvt)) / (sizeof(struct netid_af)); i++) {
		if (na_cvt[i].af == sip->si_af
		    && na_cvt[i].protocol == sip->si_proto) {
			if (strcmp(na_cvt[i].netid, "local") == 0
			    && nconf == NULL) {
				if (netid)
					*netid = "unix";
			} else {
				if (netid)
					*netid = na_cvt[i].netid;
			}
			if (nconf != NULL)
				freenetconfigent(nconf);
			return 1;
		}
	}
	if (nconf != NULL)
		freenetconfigent(nconf);

	return 0;
}

char *
taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf)
{
	struct __rpc_sockinfo si;

	if (!__rpc_nconf2sockinfo(nconf, &si))
		return NULL;
	return __rpc_taddr2uaddr_af(si.si_af, nbuf);
}

struct netbuf *
uaddr2taddr(const struct netconfig *nconf, const char *uaddr)
{
	struct __rpc_sockinfo si;

	if (!__rpc_nconf2sockinfo(nconf, &si))
		return NULL;
	return __rpc_uaddr2taddr_af(si.si_af, uaddr);
}

char *
__rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
{
	char *ret = NULL;
	struct sockaddr_in *sin;
	struct sockaddr_un *sun;
	char namebuf[INET_ADDRSTRLEN];
#ifdef INET6
	struct sockaddr_in6 *sin6;
	char namebuf6[INET6_ADDRSTRLEN];
#endif
	u_int16_t port;

	if (nbuf->len <= 0)
		goto out;

	/* XXX check (fix) this */
	ret = mem_zalloc(INET6_ADDRSTRLEN + (2 * 6) + 1);
	if (!ret)
		return (NULL);

	switch (af) {
	case AF_INET:
		sin = nbuf->buf;
		if (inet_ntop(af, &sin->sin_addr, namebuf, sizeof(namebuf))
		    == NULL)
			return NULL;
		port = ntohs(sin->sin_port);
		if (sprintf
		    (ret, "%s.%u.%u", namebuf, ((u_int32_t) port) >> 8,
		     port & 0xff) < 0) {
			mem_free(ret, 0);
			return NULL;
		}
		break;
#ifdef INET6
	case AF_INET6:
		sin6 = nbuf->buf;
		if (inet_ntop(af, &sin6->sin6_addr, namebuf6, sizeof(namebuf6))
		    == NULL) {
			mem_free(ret, 0);
			return NULL;
		}
		port = ntohs(sin6->sin6_port);
		if (sprintf
		    (ret, "%s.%u.%u", namebuf6, ((u_int32_t) port) >> 8,
		     port & 0xff) < 0) {
			mem_free(ret, 0);
			return NULL;
		}
		break;
#endif
	case AF_LOCAL:
		sun = nbuf->buf;
		/* if (asprintf(&ret, "%.*s", (int)(sun->sun_len -
		   offsetof(struct sockaddr_un, sun_path)),
		   sun->sun_path) < 0) */
		if (sprintf(ret, "%.*s",
			    (int)(sizeof(*sun) -
				  offsetof(struct sockaddr_un, sun_path)),
			    sun->sun_path) < 0) {
			mem_free(ret, 0);
			return NULL;
		}
		break;
	default:
		mem_free(ret, 0);
		return NULL;
	}

 out:
	return ret;
}

struct netbuf *
__rpc_uaddr2taddr_af(int af, const char *uaddr)
{
	struct netbuf *ret = NULL;
	char *addrstr, *p;
	unsigned port, portlo, porthi;
	struct sockaddr_in *sin;
#ifdef INET6
	struct sockaddr_in6 *sin6;
#endif
	struct sockaddr_un *sun;

	port = 0;
	sin = NULL;
	addrstr = rpc_strdup(uaddr);
	if (addrstr == NULL)
		return NULL;

	/*
	 * AF_LOCAL addresses are expected to be absolute
	 * pathnames, anything else will be AF_INET or AF_INET6.
	 */
	if (*addrstr != '/') {
		p = strrchr(addrstr, '.');
		if (p == NULL)
			goto out;
		portlo = (unsigned)atoi(p + 1);
		*p = '\0';

		p = strrchr(addrstr, '.');
		if (p == NULL)
			goto out;
		porthi = (unsigned)atoi(p + 1);
		*p = '\0';
		port = (porthi << 8) | portlo;
	}

	ret = (struct netbuf *)mem_zalloc(sizeof(*ret));
	if (ret == NULL)
		goto out;

	switch (af) {
	case AF_INET:
		sin = (struct sockaddr_in *)mem_zalloc(sizeof(*sin));
		if (sin == NULL)
			goto out;
		memset(sin, 0, sizeof(*sin));
		sin->sin_family = AF_INET;
		sin->sin_port = htons(port);
		if (inet_pton(AF_INET, addrstr, &sin->sin_addr) <= 0) {
			mem_free(sin, 0);	/* XXX */
			mem_free(ret, 0);
			ret = NULL;
			goto out;
		}
		ret->maxlen = ret->len = sizeof(*sin);
		ret->buf = sin;
		break;
#ifdef INET6
	case AF_INET6:
		sin6 = (struct sockaddr_in6 *)mem_zalloc(sizeof(*sin6));
		if (sin6 == NULL)
			goto out;
		memset(sin6, 0, sizeof(*sin6));
		sin6->sin6_family = AF_INET6;
		sin6->sin6_port = htons(port);
		if (inet_pton(AF_INET6, addrstr, &sin6->sin6_addr) <= 0) {
			mem_free(sin6, 0);
			mem_free(ret, 0);
			ret = NULL;
			goto out;
		}
		ret->maxlen = ret->len = sizeof(*sin6);
		ret->buf = sin6;
		break;
#endif
	case AF_LOCAL:
		sun = (struct sockaddr_un *)mem_zalloc(sizeof(*sun));
		if (sun == NULL)
			goto out;
		memset(sun, 0, sizeof(*sun));
		sun->sun_family = AF_LOCAL;
		strncpy(sun->sun_path, addrstr, sizeof(sun->sun_path) - 1);
		ret->len = SUN_LEN(sun);
		ret->maxlen = sizeof(struct sockaddr_un);
		ret->buf = sun;
		break;
	default:
		mem_free(ret, 0);
		ret = NULL;
		break;
	}
 out:
	mem_free(addrstr, 0);
	return ret;
}

int
__rpc_seman2socktype(int semantics)
{
	switch (semantics) {
	case NC_TPI_CLTS:
		return SOCK_DGRAM;
	case NC_TPI_COTS_ORD:
		return SOCK_STREAM;
	case NC_TPI_RAW:
		return SOCK_RAW;
	default:
		break;
	}

	return -1;
}

int
__rpc_socktype2seman(int socktype)
{
	switch (socktype) {
	case SOCK_DGRAM:
		return NC_TPI_CLTS;
	case SOCK_STREAM:
		return NC_TPI_COTS_ORD;
	case SOCK_RAW:
		return NC_TPI_RAW;
	default:
		break;
	}

	return -1;
}

/*
 * XXXX - IPv6 scope IDs can't be handled in universal addresses.
 * Here, we compare the original server address to that of the RPC
 * service we just received back from a call to rpcbind on the remote
 * machine. If they are both "link local" or "site local", copy
 * the scope id of the server address over to the service address.
 */
int
__rpc_fixup_addr(struct netbuf *new, const struct netbuf *svc)
{
#ifdef INET6
	struct sockaddr *sa_new, *sa_svc;
	struct sockaddr_in6 *sin6_new, *sin6_svc;

	sa_svc = (struct sockaddr *)svc->buf;
	sa_new = (struct sockaddr *)new->buf;

	if (sa_new->sa_family == sa_svc->sa_family
	    && sa_new->sa_family == AF_INET6) {
		sin6_new = (struct sockaddr_in6 *)new->buf;
		sin6_svc = (struct sockaddr_in6 *)svc->buf;

		if ((IN6_IS_ADDR_LINKLOCAL(&sin6_new->sin6_addr)
		     && IN6_IS_ADDR_LINKLOCAL(&sin6_svc->sin6_addr))
		    || (IN6_IS_ADDR_SITELOCAL(&sin6_new->sin6_addr)
			&& IN6_IS_ADDR_SITELOCAL(&sin6_svc->sin6_addr))) {
			sin6_new->sin6_scope_id = sin6_svc->sin6_scope_id;
		}
	}
#endif
	return 1;
}

int __rpc_sockisbound(int fd)
{
	struct sockaddr_storage ss;
	union {
		struct sockaddr_in sin;
		struct sockaddr_in6 sin6;
		struct sockaddr_un usin;
	} u_addr;
	socklen_t slen;

	slen = sizeof(struct sockaddr_storage);
	if (getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0)
		return 0;

	switch (ss.ss_family) {
	case AF_INET:
		memcpy(&u_addr.sin, &ss, sizeof(u_addr.sin));
		return (u_addr.sin.sin_port != 0);
#ifdef INET6
	case AF_INET6:
		memcpy(&u_addr.sin6, &ss, sizeof(u_addr.sin6));
		return (u_addr.sin6.sin6_port != 0);
#endif
	case AF_LOCAL:
		/* XXX check this */
		memcpy(&u_addr.usin, &ss, sizeof(u_addr.usin));
		return (u_addr.usin.sun_path[0] != 0);
	default:
		break;
	}

	return 0;
}

/*
 * Helper function to set up a netbuf
 */
struct netbuf *
__rpc_set_netbuf(struct netbuf *nb, const void *ptr, size_t len)
{
	if (nb->len != len) {
		if (nb->len)
			mem_free(nb->buf, nb->len);
		nb->buf = mem_zalloc(len);
		if (nb->buf == NULL)
			return NULL;

		nb->maxlen = nb->len = len;
	}
	memcpy(nb->buf, ptr, len);
	return nb;
}
