summaryrefslogtreecommitdiff
path: root/usr/src/lib/librdc/common/netaddrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/librdc/common/netaddrs.c')
-rw-r--r--usr/src/lib/librdc/common/netaddrs.c670
1 files changed, 0 insertions, 670 deletions
diff --git a/usr/src/lib/librdc/common/netaddrs.c b/usr/src/lib/librdc/common/netaddrs.c
deleted file mode 100644
index ed90358618..0000000000
--- a/usr/src/lib/librdc/common/netaddrs.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <locale.h>
-#include <stdio.h>
-#include <string.h>
-#include <memory.h>
-#include <varargs.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <sys/param.h>
-#include <rpc/rpc.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <netdb.h>
-#include <sys/pathconf.h>
-#include <netdir.h>
-#include <netconfig.h>
-#include <sys/sockio.h>
-#include <net/if.h>
-#include <syslog.h>
-#include <netinet/in.h>
-#include <nfs/nfs_sec.h>
-#include <strings.h>
-#include <sys/nsctl/rdc_prot.h>
-#include <nsctl.h>
-
-#include "librdc.h"
-
-#define MAXIFS 32
-
-/* number of transports to try */
-#define MNT_PREF_LISTLEN 2
-#define FIRST_TRY 1
-#define SECOND_TRY 2
-
-
-int
-Is_ipv6present(void)
-{
-#ifdef AF_INET6
- int sock;
- struct lifnum lifn;
-
- sock = socket(AF_INET6, SOCK_DGRAM, 0);
- if (sock < 0)
- return (0);
-
- lifn.lifn_family = AF_INET6;
- lifn.lifn_flags = 0;
- if (ioctl(sock, SIOCGLIFNUM, (char *)&lifn) < 0) {
- close(sock);
- return (0);
- }
- close(sock);
- if (lifn.lifn_count == 0)
- return (0);
- return (1);
-#else
- return (0);
-#endif
-}
-
-/*
- * The following is stolen from autod_nfs.c
- */
-static void
-getmyaddrs(struct ifconf *ifc)
-{
- int sock;
- int numifs;
- char *buf;
- int family;
-
- ifc->ifc_buf = NULL;
- ifc->ifc_len = 0;
-
-#ifdef AF_INET6
- family = AF_INET6;
-#else
- family = AF_INET;
-#endif
- if ((sock = socket(family, SOCK_DGRAM, 0)) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): socket");
-#endif
- return;
- }
-
- if (ioctl(sock, SIOCGIFNUM, (char *)&numifs) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): SIOCGIFNUM");
-#endif
- numifs = MAXIFS;
- }
-
- buf = (char *)malloc(numifs * sizeof (struct ifreq));
- if (buf == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "getmyaddrs(): malloc failed\n");
-#endif
- (void) close(sock);
- return;
- }
-
- ifc->ifc_buf = buf;
- ifc->ifc_len = numifs * sizeof (struct ifreq);
-
- if (ioctl(sock, SIOCGIFCONF, (char *)ifc) < 0) {
-#ifdef DEBUG
- perror("getmyaddrs(): SIOCGIFCONF");
-#else
- ;
- /*EMPTY*/
-#endif
- }
-
- (void) close(sock);
-}
-
-int
-self_check(char *hostname)
-{
- int n;
- struct sockaddr_in *s1, *s2;
- struct ifreq *ifr;
- struct nd_hostserv hs;
- struct nd_addrlist *retaddrs;
- struct netconfig *nconfp;
- struct ifconf *ifc;
- int retval;
-
- ifc = malloc(sizeof (struct ifconf));
- if (ifc == NULL)
- return (0);
- memset((char *)ifc, 0, sizeof (struct ifconf));
- getmyaddrs(ifc);
- /*
- * Get the IP address for hostname
- */
- nconfp = getnetconfigent("udp");
- if (nconfp == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "self_check(): getnetconfigent failed\n");
-#endif
- retval = 0;
- goto out;
- }
- hs.h_host = hostname;
- hs.h_serv = "rpcbind";
- if (netdir_getbyname(nconfp, &hs, &retaddrs) != ND_OK) {
- freenetconfigent(nconfp);
- retval = 0;
- goto out;
- }
- freenetconfigent(nconfp);
- /* LINTED pointer alignment */
- s1 = (struct sockaddr_in *)retaddrs->n_addrs->buf;
-
- /*
- * Now compare it against the list of
- * addresses for the interfaces on this
- * host.
- */
- ifr = ifc->ifc_req;
- n = ifc->ifc_len / sizeof (struct ifreq);
- s2 = NULL;
- for (; n > 0; n--, ifr++) {
- if (ifr->ifr_addr.sa_family != AF_INET)
- continue;
-
- /* LINTED pointer alignment */
- s2 = (struct sockaddr_in *)&ifr->ifr_addr;
-
- if (memcmp((char *)&s2->sin_addr,
- (char *)&s1->sin_addr, sizeof (s1->sin_addr)) == 0) {
- netdir_free((void *)retaddrs, ND_ADDRLIST);
- retval = 1;
- goto out; /* it's me */
- }
- }
- netdir_free((void *)retaddrs, ND_ADDRLIST);
- retval = 0;
-
-out:
- if (ifc->ifc_buf != NULL)
- free(ifc->ifc_buf);
- free(ifc);
- return (retval);
-}
-
-
-int
-convert_nconf_to_knconf(struct netconfig *nconf, struct knetconfig *knconf)
-{
- struct stat sb;
-
- if (stat(nconf->nc_device, &sb) < 0) {
- (void) syslog(LOG_ERR, "can't find device for transport %s\n",
- nconf->nc_device);
- return (-1);
- }
-#ifdef DEBUG_ADDR
- printf("lib knconf %x %s %s %x\n", nconf->nc_semantics,
- nconf->nc_protofmly, nconf->nc_proto, sb.st_rdev);
-#endif
-
- knconf->knc_semantics = nconf->nc_semantics;
- knconf->knc_protofmly = nconf->nc_protofmly;
- knconf->knc_proto = nconf->nc_proto;
- knconf->knc_rdev = sb.st_rdev;
-
- return (0);
-}
-
-struct hostent *
-gethost_byname(const char *name)
-{
- int errnum;
-#ifdef AF_INET6
- return (getipnodebyname(name, AF_INET6, AI_DEFAULT, &errnum));
-#else /* !AF_INET6 */
- return (gethostbyname(name));
-#endif /* AF_INET6 */
-}
-
-int
-gethost_netaddrs(char *fromhost, char *tohost,
- char *fromnetaddr, char *tonetaddr)
-{
- struct hostent *host;
- int j;
- int errnum;
-
-#ifdef AF_INET6
- host = getipnodebyname(fromhost, AF_INET6, AI_DEFAULT, &errnum);
- if (host == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), fromhost);
-#endif
- return (-1);
- }
- for (j = 0; j < host->h_length; j++)
- fromnetaddr[j] = host->h_addr[j];
- freehostent(host);
-#else /* !AF_INET6 */
- host = gethostbyname(fromhost);
- if (host == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), fromhost);
-#endif
- return (-1);
- }
-
- if (host->h_length < 4) {
-#ifdef DEBUG
- fprintf(stderr, "host->h_length(%d) < 4!\n", host->h_length);
-#endif
- return (-1);
- }
-
- for (j = 0; j < host->h_length; j++)
- fromnetaddr[j] = host->h_addr[j];
-#endif /* AF_INET6 */
-
-#ifdef AF_INET6
- host = getipnodebyname(tohost, AF_INET6, AI_DEFAULT, &errnum);
- if (host == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), tohost);
-#endif
- return (-1);
- }
- for (j = 0; j < host->h_length; j++)
- tonetaddr[j] = host->h_addr[j];
- freehostent(host);
-#else /* !AF_INET6 */
- host = gethostbyname(tohost);
- if (host == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), tohost);
-#endif
- return (-1);
- }
-
- if (host->h_length < 4) {
-#ifdef DEBUG
- fprintf(stderr, "host->h_length(%d) < 4!\n", host->h_length);
-#endif
- return (-1);
- }
-
- for (j = 0; j < host->h_length; j++)
- tonetaddr[j] = host->h_addr[j];
-#endif /* AF_INET6 */
- return (0);
-}
-
-/*
- * Get the network address on "hostname" for program "prog"
- * with version "vers" by using the nconf configuration data
- * passed in.
- *
- * If the address of a netconfig pointer is null then
- * information is not sufficient and no netbuf will be returned.
- *
- * Finally, ping the null procedure of that service.
- *
- */
-static struct netbuf *
-get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
- struct netconfig *nconf, ushort_t port, struct t_info *tinfo,
- int portmap)
-{
- struct netbuf *nb = NULL;
- struct t_bind *tbind = NULL;
- CLIENT *cl = NULL;
- struct timeval tv;
- int fd = -1;
- AUTH *ah = NULL;
-
- if (nconf == NULL)
- return (NULL);
-
- if ((fd = t_open(nconf->nc_device, O_RDWR, tinfo)) == -1)
- goto done;
-
- /* LINTED pointer alignment */
- if ((tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR)) == NULL)
- goto done;
-
- if (portmap) { /* contact rpcbind */
- if (rpcb_getaddr(prog, vers, nconf, &tbind->addr,
- hostname) == FALSE) {
- goto done;
- }
-
- if (port) {
- if (strcmp(nconf->nc_protofmly, NC_INET) == 0)
- /* LINTED pointer alignment */
- ((struct sockaddr_in *)tbind->addr.buf)->sin_port
- = port;
-#ifdef NC_INET6
- else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0)
- /* LINTED pointer alignment */
- ((struct sockaddr_in6 *)tbind->addr.buf)->sin6_port
- = port;
-#endif
- }
-
- /* Simon -- we never use the client we create?! */
- cl = clnt_tli_create(fd, nconf, &tbind->addr, prog, vers, 0, 0);
- if (cl == NULL)
- goto done;
-
- ah = authsys_create_default();
- if (ah != NULL)
- cl->cl_auth = ah;
-
- tv.tv_sec = 5;
- tv.tv_usec = 0;
-
- (void) clnt_control(cl, CLSET_TIMEOUT, (char *)&tv);
- } else { /* create our own address and skip rpcbind */
- struct netbuf *nb;
- struct hostent *hp;
- int j;
- int errnum;
- unsigned short family;
- nb = &(tbind->addr);
-
-#ifdef AF_INET6
- if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
- hp = getipnodebyname(hostname, AF_INET6, 0, &errnum);
- family = AF_INET6;
- nb->len = nb->maxlen = sizeof (struct sockaddr_in6);
- } else {
- hp = getipnodebyname(hostname, AF_INET, 0, &errnum);
- family = AF_INET;
- nb->len = nb->maxlen = sizeof (struct sockaddr_in);
- }
- if (hp == NULL) {
-#ifdef DEBUG_ADDR
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s\n"), hostname);
-#endif
- goto done;
- }
- nb->buf = (char *)calloc(1, nb->maxlen);
- if (nb->buf == NULL) {
- (void) printf(dgettext("sndr", "no memory\n"));
- goto done;
- }
-
- if (family == AF_INET) {
- for (j = 0; j < hp->h_length; j++)
- nb->buf[j+4] = hp->h_addr[j];
- /* LINTED pointer alignment */
- ((struct sockaddr_in *)(nb->buf))->sin_port = port;
- /* LINTED pointer alignment */
- ((struct sockaddr_in *)(nb->buf))->sin_family = AF_INET;
- } else {
- for (j = 0; j < hp->h_length; j++)
- nb->buf[j+8] = hp->h_addr[j];
- /* LINTED pointer alignment */
- ((struct sockaddr_in6 *)(nb->buf))->sin6_port = port;
- /* LINTED pointer alignment */
- ((struct sockaddr_in6 *)(nb->buf))->sin6_family =
- AF_INET6;
- }
- freehostent(hp);
-#else
- hp = gethostbyname(hostname);
- if (hp == NULL) {
-#ifdef DEBUG
- (void) fprintf(stderr, dgettext("sndr",
- "Could not find host %s"), hostname);
-#endif
- goto done;
- }
-
- nb->len = nb->maxlen = sizeof (struct sockaddr_in);
- nb->buf = (char *)calloc(1, nb->maxlen);
- if (nb->buf == NULL) {
- (void) printf(dgettext("sndr", "no memory\n"));
- free(nb);
- nb = NULL;
- goto done;
- }
-
- for (j = 0; j < hp->h_length; j++)
- nb->buf[j+4] = hp->h_addr[j];
-
- if (hp->h_addrtype == AF_INET) {
- ((struct sockaddr_in *)(nb->buf))->sin_port = port;
- ((struct sockaddr_in *)(nb->buf))->sin_family = AF_INET;
- }
-#endif
- }
-
- /*
- * Make a copy of the netbuf to return
- */
- nb = (struct netbuf *)calloc(1, sizeof (*nb));
- if (nb == NULL) {
- (void) printf(dgettext("sndr", "no memory\n"));
- goto done;
- }
-
- *nb = tbind->addr; /* structure copy */
-
- nb->buf = (char *)calloc(1, nb->maxlen);
- if (nb->buf == NULL) {
- (void) printf(dgettext("sndr", "no memory\n"));
- free(nb);
- nb = NULL;
- goto done;
- }
-
- (void) memcpy(nb->buf, tbind->addr.buf, tbind->addr.len);
-
-done:
- if (cl) {
- if (ah != NULL) {
- AUTH_DESTROY(cl->cl_auth);
- cl->cl_auth = NULL;
- }
-
- clnt_destroy(cl);
- cl = NULL;
- }
-
- if (tbind) {
- t_free((char *)tbind, T_BIND);
- tbind = NULL;
- }
-
- if (fd >= 0)
- (void) t_close(fd);
- return (nb);
-}
-
-/*
- * Get a network address on "hostname" for program "prog"
- * with version "vers". If the port number is specified (non zero)
- * then try for a TCP/UDP transport and set the port number of the
- * resulting IP address.
- *
- * If the address of a netconfig pointer was passed and
- * if it's not null, use it as the netconfig otherwise
- * assign the address of the netconfig that was used to
- * establish contact with the service.
- * If portmap is false, we return a similiar address and we do not
- * contact rpcbind
- *
- */
-struct netbuf *
-get_addr(char *hostname, ulong_t prog, ulong_t vers, struct netconfig **nconfp,
- char *proto, char *srvport, struct t_info *tinfo, int portmap)
-{
- struct netbuf *nb = NULL;
- struct netconfig *nconf = NULL;
- NCONF_HANDLE *nc = NULL;
- int nthtry = FIRST_TRY;
- struct servent *svp;
- ushort_t port;
-
- /*
- * First lets get the requested port
- */
-
- if ((svp = getservbyname(srvport, proto)) == NULL)
- goto done;
- port = svp->s_port;
- /*
- * No nconf passed in.
- *
- * Try to get a nconf from /etc/netconfig filtered by
- * the NETPATH environment variable.
- * First search for COTS, second for CLTS unless proto
- * is specified. When we retry, we reset the
- * netconfig list so that we would search the whole list
- * all over again.
- */
- if ((nc = setnetpath()) == NULL)
- goto done;
-
- /*
- * If proto is specified, then only search for the match,
- * otherwise try COTS first, if failed, try CLTS.
- */
- if (proto) {
- while (nconf = getnetpath(nc)) {
- if (strcmp(nconf->nc_netid, proto) == 0) {
- /*
- * If the port number is specified then TCP/UDP
- * is needed. Otherwise any cots/clts will do.
- */
- if (port == 0)
- break;
-
- if ((strcmp(nconf->nc_protofmly, NC_INET) == 0
-#ifdef NC_INET6
- /* CSTYLED */
- || strcmp(nconf->nc_protofmly, NC_INET6) == 0
-#endif
- /* CSTYLED */
- ) &&
- (strcmp(nconf->nc_proto, NC_TCP) == 0 ||
- strcmp(nconf->nc_proto, NC_UDP) == 0))
- break;
- else {
- nconf = NULL;
- break;
- }
- }
- }
- if (nconf == NULL)
- goto done;
- if ((nb = get_the_addr(hostname, prog, vers, nconf, port,
- tinfo, portmap)) == NULL) {
- goto done;
- }
- } else {
-retry:
- while (nconf = getnetpath(nc)) {
- if (nconf->nc_flag & NC_VISIBLE) {
- if (nthtry == FIRST_TRY) {
- if ((nconf->nc_semantics == NC_TPI_COTS_ORD) ||
- (nconf->nc_semantics == NC_TPI_COTS)) {
- if (port == 0)
- break;
- if ((strcmp(nconf->nc_protofmly,
- NC_INET) == 0
-#ifdef NC_INET6
- /* CSTYLED */
- || strcmp(nconf->nc_protofmly,
- NC_INET6) == 0
-#endif
- /* CSTYLED */
- ) &&
- (strcmp(nconf->nc_proto, NC_TCP) == 0))
- break;
- }
- }
- }
- } /* while */
- if (nconf == NULL) {
- if (++nthtry <= MNT_PREF_LISTLEN) {
- endnetpath(nc);
- if ((nc = setnetpath()) == NULL)
- goto done;
- goto retry;
- } else
- goto done;
- } else {
- if ((nb = get_the_addr(hostname, prog, vers, nconf,
- port, tinfo, portmap)) == NULL) {
- /*
- * Continue the same search path in the
- * netconfig db until no more matched
- * nconf (nconf == NULL).
- */
- goto retry;
- }
-#ifdef AF_INET6
- if ((nb->len == 8) &&
- (strcmp(nconf->nc_protofmly, NC_INET6) == 0)) {
- /*
- * We have a mismatch in the netconfig retry
- */
- free(nb);
- goto retry;
- }
-#endif
- }
- }
-
- /*
- * Got nconf and nb. Now dup the netconfig structure (nconf)
- * and return it thru nconfp.
- */
- *nconfp = getnetconfigent(nconf->nc_netid);
- if (*nconfp == NULL) {
- syslog(LOG_ERR, "no memory\n");
- free(nb);
- nb = NULL;
- }
-done:
- if (nc)
- endnetpath(nc);
- return (nb);
-}
-
-
-/* return values as for nsc_check_release() */
-int
-rdc_check_release(char **reqd)
-{
- /* librdc.so must be built on the runtime OS release */
- return (nsc_check_release(BUILD_REV_STR, NULL, reqd));
-}