xref: /onnv-gate/usr/src/lib/librdc/common/netaddrs.c (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM  */
25*7836SJohn.Forte@Sun.COM 
26*7836SJohn.Forte@Sun.COM #include <locale.h>
27*7836SJohn.Forte@Sun.COM #include <stdio.h>
28*7836SJohn.Forte@Sun.COM #include <string.h>
29*7836SJohn.Forte@Sun.COM #include <memory.h>
30*7836SJohn.Forte@Sun.COM #include <varargs.h>
31*7836SJohn.Forte@Sun.COM #include <unistd.h>
32*7836SJohn.Forte@Sun.COM #include <ctype.h>
33*7836SJohn.Forte@Sun.COM #include <stdlib.h>
34*7836SJohn.Forte@Sun.COM #include <signal.h>
35*7836SJohn.Forte@Sun.COM #include <sys/param.h>
36*7836SJohn.Forte@Sun.COM #include <rpc/rpc.h>
37*7836SJohn.Forte@Sun.COM #include <errno.h>
38*7836SJohn.Forte@Sun.COM #include <sys/stat.h>
39*7836SJohn.Forte@Sun.COM #include <netdb.h>
40*7836SJohn.Forte@Sun.COM #include <sys/pathconf.h>
41*7836SJohn.Forte@Sun.COM #include <netdir.h>
42*7836SJohn.Forte@Sun.COM #include <netconfig.h>
43*7836SJohn.Forte@Sun.COM #include <sys/sockio.h>
44*7836SJohn.Forte@Sun.COM #include <net/if.h>
45*7836SJohn.Forte@Sun.COM #include <syslog.h>
46*7836SJohn.Forte@Sun.COM #include <netinet/in.h>
47*7836SJohn.Forte@Sun.COM #include <nfs/nfs_sec.h>
48*7836SJohn.Forte@Sun.COM #include <strings.h>
49*7836SJohn.Forte@Sun.COM #include <sys/nsctl/rdc_prot.h>
50*7836SJohn.Forte@Sun.COM #include <nsctl.h>
51*7836SJohn.Forte@Sun.COM 
52*7836SJohn.Forte@Sun.COM #include "librdc.h"
53*7836SJohn.Forte@Sun.COM 
54*7836SJohn.Forte@Sun.COM #define	MAXIFS 32
55*7836SJohn.Forte@Sun.COM 
56*7836SJohn.Forte@Sun.COM /* number of transports to try */
57*7836SJohn.Forte@Sun.COM #define	MNT_PREF_LISTLEN	2
58*7836SJohn.Forte@Sun.COM #define	FIRST_TRY		1
59*7836SJohn.Forte@Sun.COM #define	SECOND_TRY		2
60*7836SJohn.Forte@Sun.COM 
61*7836SJohn.Forte@Sun.COM 
62*7836SJohn.Forte@Sun.COM int
Is_ipv6present(void)63*7836SJohn.Forte@Sun.COM Is_ipv6present(void)
64*7836SJohn.Forte@Sun.COM {
65*7836SJohn.Forte@Sun.COM #ifdef AF_INET6
66*7836SJohn.Forte@Sun.COM 	int sock;
67*7836SJohn.Forte@Sun.COM 	struct lifnum lifn;
68*7836SJohn.Forte@Sun.COM 
69*7836SJohn.Forte@Sun.COM 	sock = socket(AF_INET6, SOCK_DGRAM, 0);
70*7836SJohn.Forte@Sun.COM 	if (sock < 0)
71*7836SJohn.Forte@Sun.COM 		return (0);
72*7836SJohn.Forte@Sun.COM 
73*7836SJohn.Forte@Sun.COM 	lifn.lifn_family = AF_INET6;
74*7836SJohn.Forte@Sun.COM 	lifn.lifn_flags = 0;
75*7836SJohn.Forte@Sun.COM 	if (ioctl(sock, SIOCGLIFNUM, (char *)&lifn) < 0) {
76*7836SJohn.Forte@Sun.COM 		close(sock);
77*7836SJohn.Forte@Sun.COM 		return (0);
78*7836SJohn.Forte@Sun.COM 	}
79*7836SJohn.Forte@Sun.COM 	close(sock);
80*7836SJohn.Forte@Sun.COM 	if (lifn.lifn_count == 0)
81*7836SJohn.Forte@Sun.COM 		return (0);
82*7836SJohn.Forte@Sun.COM 	return (1);
83*7836SJohn.Forte@Sun.COM #else
84*7836SJohn.Forte@Sun.COM 	return (0);
85*7836SJohn.Forte@Sun.COM #endif
86*7836SJohn.Forte@Sun.COM }
87*7836SJohn.Forte@Sun.COM 
88*7836SJohn.Forte@Sun.COM /*
89*7836SJohn.Forte@Sun.COM  * The following is stolen from autod_nfs.c
90*7836SJohn.Forte@Sun.COM  */
91*7836SJohn.Forte@Sun.COM static void
getmyaddrs(struct ifconf * ifc)92*7836SJohn.Forte@Sun.COM getmyaddrs(struct ifconf *ifc)
93*7836SJohn.Forte@Sun.COM {
94*7836SJohn.Forte@Sun.COM 	int sock;
95*7836SJohn.Forte@Sun.COM 	int numifs;
96*7836SJohn.Forte@Sun.COM 	char *buf;
97*7836SJohn.Forte@Sun.COM 	int family;
98*7836SJohn.Forte@Sun.COM 
99*7836SJohn.Forte@Sun.COM 	ifc->ifc_buf = NULL;
100*7836SJohn.Forte@Sun.COM 	ifc->ifc_len = 0;
101*7836SJohn.Forte@Sun.COM 
102*7836SJohn.Forte@Sun.COM #ifdef AF_INET6
103*7836SJohn.Forte@Sun.COM 	family = AF_INET6;
104*7836SJohn.Forte@Sun.COM #else
105*7836SJohn.Forte@Sun.COM 	family = AF_INET;
106*7836SJohn.Forte@Sun.COM #endif
107*7836SJohn.Forte@Sun.COM 	if ((sock = socket(family, SOCK_DGRAM, 0)) < 0) {
108*7836SJohn.Forte@Sun.COM #ifdef DEBUG
109*7836SJohn.Forte@Sun.COM 		perror("getmyaddrs(): socket");
110*7836SJohn.Forte@Sun.COM #endif
111*7836SJohn.Forte@Sun.COM 		return;
112*7836SJohn.Forte@Sun.COM 	}
113*7836SJohn.Forte@Sun.COM 
114*7836SJohn.Forte@Sun.COM 	if (ioctl(sock, SIOCGIFNUM, (char *)&numifs) < 0) {
115*7836SJohn.Forte@Sun.COM #ifdef DEBUG
116*7836SJohn.Forte@Sun.COM 		perror("getmyaddrs(): SIOCGIFNUM");
117*7836SJohn.Forte@Sun.COM #endif
118*7836SJohn.Forte@Sun.COM 		numifs = MAXIFS;
119*7836SJohn.Forte@Sun.COM 	}
120*7836SJohn.Forte@Sun.COM 
121*7836SJohn.Forte@Sun.COM 	buf = (char *)malloc(numifs * sizeof (struct ifreq));
122*7836SJohn.Forte@Sun.COM 	if (buf == NULL) {
123*7836SJohn.Forte@Sun.COM #ifdef DEBUG
124*7836SJohn.Forte@Sun.COM 		fprintf(stderr, "getmyaddrs(): malloc failed\n");
125*7836SJohn.Forte@Sun.COM #endif
126*7836SJohn.Forte@Sun.COM 		(void) close(sock);
127*7836SJohn.Forte@Sun.COM 		return;
128*7836SJohn.Forte@Sun.COM 	}
129*7836SJohn.Forte@Sun.COM 
130*7836SJohn.Forte@Sun.COM 	ifc->ifc_buf = buf;
131*7836SJohn.Forte@Sun.COM 	ifc->ifc_len = numifs * sizeof (struct ifreq);
132*7836SJohn.Forte@Sun.COM 
133*7836SJohn.Forte@Sun.COM 	if (ioctl(sock, SIOCGIFCONF, (char *)ifc) < 0) {
134*7836SJohn.Forte@Sun.COM #ifdef DEBUG
135*7836SJohn.Forte@Sun.COM 		perror("getmyaddrs(): SIOCGIFCONF");
136*7836SJohn.Forte@Sun.COM #else
137*7836SJohn.Forte@Sun.COM 		;
138*7836SJohn.Forte@Sun.COM 		/*EMPTY*/
139*7836SJohn.Forte@Sun.COM #endif
140*7836SJohn.Forte@Sun.COM 	}
141*7836SJohn.Forte@Sun.COM 
142*7836SJohn.Forte@Sun.COM 	(void) close(sock);
143*7836SJohn.Forte@Sun.COM }
144*7836SJohn.Forte@Sun.COM 
145*7836SJohn.Forte@Sun.COM int
self_check(char * hostname)146*7836SJohn.Forte@Sun.COM self_check(char *hostname)
147*7836SJohn.Forte@Sun.COM {
148*7836SJohn.Forte@Sun.COM 	int n;
149*7836SJohn.Forte@Sun.COM 	struct sockaddr_in *s1, *s2;
150*7836SJohn.Forte@Sun.COM 	struct ifreq *ifr;
151*7836SJohn.Forte@Sun.COM 	struct nd_hostserv hs;
152*7836SJohn.Forte@Sun.COM 	struct nd_addrlist *retaddrs;
153*7836SJohn.Forte@Sun.COM 	struct netconfig *nconfp;
154*7836SJohn.Forte@Sun.COM 	struct ifconf *ifc;
155*7836SJohn.Forte@Sun.COM 	int retval;
156*7836SJohn.Forte@Sun.COM 
157*7836SJohn.Forte@Sun.COM 	ifc = malloc(sizeof (struct ifconf));
158*7836SJohn.Forte@Sun.COM 	if (ifc == NULL)
159*7836SJohn.Forte@Sun.COM 		return (0);
160*7836SJohn.Forte@Sun.COM 	memset((char *)ifc, 0, sizeof (struct ifconf));
161*7836SJohn.Forte@Sun.COM 	getmyaddrs(ifc);
162*7836SJohn.Forte@Sun.COM 	/*
163*7836SJohn.Forte@Sun.COM 	 * Get the IP address for hostname
164*7836SJohn.Forte@Sun.COM 	 */
165*7836SJohn.Forte@Sun.COM 	nconfp = getnetconfigent("udp");
166*7836SJohn.Forte@Sun.COM 	if (nconfp == NULL) {
167*7836SJohn.Forte@Sun.COM #ifdef DEBUG
168*7836SJohn.Forte@Sun.COM 		fprintf(stderr, "self_check(): getnetconfigent failed\n");
169*7836SJohn.Forte@Sun.COM #endif
170*7836SJohn.Forte@Sun.COM 		retval = 0;
171*7836SJohn.Forte@Sun.COM 		goto out;
172*7836SJohn.Forte@Sun.COM 	}
173*7836SJohn.Forte@Sun.COM 	hs.h_host = hostname;
174*7836SJohn.Forte@Sun.COM 	hs.h_serv = "rpcbind";
175*7836SJohn.Forte@Sun.COM 	if (netdir_getbyname(nconfp, &hs, &retaddrs) != ND_OK) {
176*7836SJohn.Forte@Sun.COM 		freenetconfigent(nconfp);
177*7836SJohn.Forte@Sun.COM 		retval = 0;
178*7836SJohn.Forte@Sun.COM 		goto out;
179*7836SJohn.Forte@Sun.COM 	}
180*7836SJohn.Forte@Sun.COM 	freenetconfigent(nconfp);
181*7836SJohn.Forte@Sun.COM 	/* LINTED pointer alignment */
182*7836SJohn.Forte@Sun.COM 	s1 = (struct sockaddr_in *)retaddrs->n_addrs->buf;
183*7836SJohn.Forte@Sun.COM 
184*7836SJohn.Forte@Sun.COM 	/*
185*7836SJohn.Forte@Sun.COM 	 * Now compare it against the list of
186*7836SJohn.Forte@Sun.COM 	 * addresses for the interfaces on this
187*7836SJohn.Forte@Sun.COM 	 * host.
188*7836SJohn.Forte@Sun.COM 	 */
189*7836SJohn.Forte@Sun.COM 	ifr = ifc->ifc_req;
190*7836SJohn.Forte@Sun.COM 	n = ifc->ifc_len / sizeof (struct ifreq);
191*7836SJohn.Forte@Sun.COM 	s2 = NULL;
192*7836SJohn.Forte@Sun.COM 	for (; n > 0; n--, ifr++) {
193*7836SJohn.Forte@Sun.COM 		if (ifr->ifr_addr.sa_family != AF_INET)
194*7836SJohn.Forte@Sun.COM 			continue;
195*7836SJohn.Forte@Sun.COM 
196*7836SJohn.Forte@Sun.COM 		/* LINTED pointer alignment */
197*7836SJohn.Forte@Sun.COM 		s2 = (struct sockaddr_in *)&ifr->ifr_addr;
198*7836SJohn.Forte@Sun.COM 
199*7836SJohn.Forte@Sun.COM 		if (memcmp((char *)&s2->sin_addr,
200*7836SJohn.Forte@Sun.COM 			(char *)&s1->sin_addr, sizeof (s1->sin_addr)) == 0) {
201*7836SJohn.Forte@Sun.COM 			netdir_free((void *)retaddrs, ND_ADDRLIST);
202*7836SJohn.Forte@Sun.COM 			retval = 1;
203*7836SJohn.Forte@Sun.COM 			goto out;	/* it's me */
204*7836SJohn.Forte@Sun.COM 		}
205*7836SJohn.Forte@Sun.COM 	}
206*7836SJohn.Forte@Sun.COM 	netdir_free((void *)retaddrs, ND_ADDRLIST);
207*7836SJohn.Forte@Sun.COM 	retval = 0;
208*7836SJohn.Forte@Sun.COM 
209*7836SJohn.Forte@Sun.COM out:
210*7836SJohn.Forte@Sun.COM 	if (ifc->ifc_buf != NULL)
211*7836SJohn.Forte@Sun.COM 		free(ifc->ifc_buf);
212*7836SJohn.Forte@Sun.COM 	free(ifc);
213*7836SJohn.Forte@Sun.COM 	return (retval);
214*7836SJohn.Forte@Sun.COM }
215*7836SJohn.Forte@Sun.COM 
216*7836SJohn.Forte@Sun.COM 
217*7836SJohn.Forte@Sun.COM int
convert_nconf_to_knconf(struct netconfig * nconf,struct knetconfig * knconf)218*7836SJohn.Forte@Sun.COM convert_nconf_to_knconf(struct netconfig *nconf, struct knetconfig *knconf)
219*7836SJohn.Forte@Sun.COM {
220*7836SJohn.Forte@Sun.COM 	struct stat sb;
221*7836SJohn.Forte@Sun.COM 
222*7836SJohn.Forte@Sun.COM 	if (stat(nconf->nc_device, &sb) < 0) {
223*7836SJohn.Forte@Sun.COM 		(void) syslog(LOG_ERR, "can't find device for transport %s\n",
224*7836SJohn.Forte@Sun.COM 				nconf->nc_device);
225*7836SJohn.Forte@Sun.COM 		return (-1);
226*7836SJohn.Forte@Sun.COM 	}
227*7836SJohn.Forte@Sun.COM #ifdef DEBUG_ADDR
228*7836SJohn.Forte@Sun.COM 	printf("lib knconf %x %s %s %x\n", nconf->nc_semantics,
229*7836SJohn.Forte@Sun.COM 		nconf->nc_protofmly, nconf->nc_proto, sb.st_rdev);
230*7836SJohn.Forte@Sun.COM #endif
231*7836SJohn.Forte@Sun.COM 
232*7836SJohn.Forte@Sun.COM 	knconf->knc_semantics = nconf->nc_semantics;
233*7836SJohn.Forte@Sun.COM 	knconf->knc_protofmly = nconf->nc_protofmly;
234*7836SJohn.Forte@Sun.COM 	knconf->knc_proto = nconf->nc_proto;
235*7836SJohn.Forte@Sun.COM 	knconf->knc_rdev = sb.st_rdev;
236*7836SJohn.Forte@Sun.COM 
237*7836SJohn.Forte@Sun.COM 	return (0);
238*7836SJohn.Forte@Sun.COM }
239*7836SJohn.Forte@Sun.COM 
240*7836SJohn.Forte@Sun.COM struct hostent *
gethost_byname(const char * name)241*7836SJohn.Forte@Sun.COM gethost_byname(const char *name)
242*7836SJohn.Forte@Sun.COM {
243*7836SJohn.Forte@Sun.COM 	int errnum;
244*7836SJohn.Forte@Sun.COM #ifdef AF_INET6
245*7836SJohn.Forte@Sun.COM 	return (getipnodebyname(name, AF_INET6, AI_DEFAULT, &errnum));
246*7836SJohn.Forte@Sun.COM #else /* !AF_INET6 */
247*7836SJohn.Forte@Sun.COM 	return (gethostbyname(name));
248*7836SJohn.Forte@Sun.COM #endif /* AF_INET6 */
249*7836SJohn.Forte@Sun.COM }
250*7836SJohn.Forte@Sun.COM 
251*7836SJohn.Forte@Sun.COM int
gethost_netaddrs(char * fromhost,char * tohost,char * fromnetaddr,char * tonetaddr)252*7836SJohn.Forte@Sun.COM gethost_netaddrs(char *fromhost, char *tohost,
253*7836SJohn.Forte@Sun.COM 	char *fromnetaddr, char *tonetaddr)
254*7836SJohn.Forte@Sun.COM {
255*7836SJohn.Forte@Sun.COM 	struct hostent *host;
256*7836SJohn.Forte@Sun.COM 	int j;
257*7836SJohn.Forte@Sun.COM 	int errnum;
258*7836SJohn.Forte@Sun.COM 
259*7836SJohn.Forte@Sun.COM #ifdef AF_INET6
260*7836SJohn.Forte@Sun.COM 	host = getipnodebyname(fromhost, AF_INET6, AI_DEFAULT, &errnum);
261*7836SJohn.Forte@Sun.COM 	if (host == NULL) {
262*7836SJohn.Forte@Sun.COM #ifdef DEBUG
263*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, dgettext("sndr",
264*7836SJohn.Forte@Sun.COM 		    "Could not find host %s"), fromhost);
265*7836SJohn.Forte@Sun.COM #endif
266*7836SJohn.Forte@Sun.COM 		return (-1);
267*7836SJohn.Forte@Sun.COM 	}
268*7836SJohn.Forte@Sun.COM 	for (j = 0; j < host->h_length; j++)
269*7836SJohn.Forte@Sun.COM 		fromnetaddr[j] = host->h_addr[j];
270*7836SJohn.Forte@Sun.COM 	freehostent(host);
271*7836SJohn.Forte@Sun.COM #else /* !AF_INET6 */
272*7836SJohn.Forte@Sun.COM 	host = gethostbyname(fromhost);
273*7836SJohn.Forte@Sun.COM 	if (host == NULL) {
274*7836SJohn.Forte@Sun.COM #ifdef DEBUG
275*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, dgettext("sndr",
276*7836SJohn.Forte@Sun.COM 		    "Could not find host %s"), fromhost);
277*7836SJohn.Forte@Sun.COM #endif
278*7836SJohn.Forte@Sun.COM 		return (-1);
279*7836SJohn.Forte@Sun.COM 	}
280*7836SJohn.Forte@Sun.COM 
281*7836SJohn.Forte@Sun.COM 	if (host->h_length < 4) {
282*7836SJohn.Forte@Sun.COM #ifdef DEBUG
283*7836SJohn.Forte@Sun.COM 		fprintf(stderr, "host->h_length(%d) < 4!\n", host->h_length);
284*7836SJohn.Forte@Sun.COM #endif
285*7836SJohn.Forte@Sun.COM 		return (-1);
286*7836SJohn.Forte@Sun.COM 	}
287*7836SJohn.Forte@Sun.COM 
288*7836SJohn.Forte@Sun.COM 	for (j = 0; j < host->h_length; j++)
289*7836SJohn.Forte@Sun.COM 		fromnetaddr[j] = host->h_addr[j];
290*7836SJohn.Forte@Sun.COM #endif /* AF_INET6 */
291*7836SJohn.Forte@Sun.COM 
292*7836SJohn.Forte@Sun.COM #ifdef AF_INET6
293*7836SJohn.Forte@Sun.COM 	host = getipnodebyname(tohost, AF_INET6, AI_DEFAULT, &errnum);
294*7836SJohn.Forte@Sun.COM 	if (host == NULL) {
295*7836SJohn.Forte@Sun.COM #ifdef DEBUG
296*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, dgettext("sndr",
297*7836SJohn.Forte@Sun.COM 		    "Could not find host %s"), tohost);
298*7836SJohn.Forte@Sun.COM #endif
299*7836SJohn.Forte@Sun.COM 		return (-1);
300*7836SJohn.Forte@Sun.COM 	}
301*7836SJohn.Forte@Sun.COM 	for (j = 0; j < host->h_length; j++)
302*7836SJohn.Forte@Sun.COM 		tonetaddr[j] = host->h_addr[j];
303*7836SJohn.Forte@Sun.COM 	freehostent(host);
304*7836SJohn.Forte@Sun.COM #else /* !AF_INET6 */
305*7836SJohn.Forte@Sun.COM 	host = gethostbyname(tohost);
306*7836SJohn.Forte@Sun.COM 	if (host == NULL) {
307*7836SJohn.Forte@Sun.COM #ifdef DEBUG
308*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, dgettext("sndr",
309*7836SJohn.Forte@Sun.COM 		    "Could not find host %s"), tohost);
310*7836SJohn.Forte@Sun.COM #endif
311*7836SJohn.Forte@Sun.COM 		return (-1);
312*7836SJohn.Forte@Sun.COM 	}
313*7836SJohn.Forte@Sun.COM 
314*7836SJohn.Forte@Sun.COM 	if (host->h_length < 4) {
315*7836SJohn.Forte@Sun.COM #ifdef DEBUG
316*7836SJohn.Forte@Sun.COM 		fprintf(stderr, "host->h_length(%d) < 4!\n", host->h_length);
317*7836SJohn.Forte@Sun.COM #endif
318*7836SJohn.Forte@Sun.COM 		return (-1);
319*7836SJohn.Forte@Sun.COM 	}
320*7836SJohn.Forte@Sun.COM 
321*7836SJohn.Forte@Sun.COM 	for (j = 0; j < host->h_length; j++)
322*7836SJohn.Forte@Sun.COM 		tonetaddr[j] = host->h_addr[j];
323*7836SJohn.Forte@Sun.COM #endif /* AF_INET6 */
324*7836SJohn.Forte@Sun.COM 	return (0);
325*7836SJohn.Forte@Sun.COM }
326*7836SJohn.Forte@Sun.COM 
327*7836SJohn.Forte@Sun.COM /*
328*7836SJohn.Forte@Sun.COM  * Get the network address on "hostname" for program "prog"
329*7836SJohn.Forte@Sun.COM  * with version "vers" by using the nconf configuration data
330*7836SJohn.Forte@Sun.COM  * passed in.
331*7836SJohn.Forte@Sun.COM  *
332*7836SJohn.Forte@Sun.COM  * If the address of a netconfig pointer is null then
333*7836SJohn.Forte@Sun.COM  * information is not sufficient and no netbuf will be returned.
334*7836SJohn.Forte@Sun.COM  *
335*7836SJohn.Forte@Sun.COM  * Finally, ping the null procedure of that service.
336*7836SJohn.Forte@Sun.COM  *
337*7836SJohn.Forte@Sun.COM  */
338*7836SJohn.Forte@Sun.COM 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)339*7836SJohn.Forte@Sun.COM get_the_addr(char *hostname, ulong_t prog, ulong_t vers,
340*7836SJohn.Forte@Sun.COM 	struct netconfig *nconf, ushort_t port, struct t_info *tinfo,
341*7836SJohn.Forte@Sun.COM 	int portmap)
342*7836SJohn.Forte@Sun.COM {
343*7836SJohn.Forte@Sun.COM 	struct netbuf *nb = NULL;
344*7836SJohn.Forte@Sun.COM 	struct t_bind *tbind = NULL;
345*7836SJohn.Forte@Sun.COM 	CLIENT *cl = NULL;
346*7836SJohn.Forte@Sun.COM 	struct timeval tv;
347*7836SJohn.Forte@Sun.COM 	int fd = -1;
348*7836SJohn.Forte@Sun.COM 	AUTH *ah = NULL;
349*7836SJohn.Forte@Sun.COM 
350*7836SJohn.Forte@Sun.COM 	if (nconf == NULL)
351*7836SJohn.Forte@Sun.COM 		return (NULL);
352*7836SJohn.Forte@Sun.COM 
353*7836SJohn.Forte@Sun.COM 	if ((fd = t_open(nconf->nc_device, O_RDWR, tinfo)) == -1)
354*7836SJohn.Forte@Sun.COM 		    goto done;
355*7836SJohn.Forte@Sun.COM 
356*7836SJohn.Forte@Sun.COM 	/* LINTED pointer alignment */
357*7836SJohn.Forte@Sun.COM 	if ((tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR)) == NULL)
358*7836SJohn.Forte@Sun.COM 		goto done;
359*7836SJohn.Forte@Sun.COM 
360*7836SJohn.Forte@Sun.COM 	if (portmap) { /* contact rpcbind */
361*7836SJohn.Forte@Sun.COM 		if (rpcb_getaddr(prog, vers, nconf, &tbind->addr,
362*7836SJohn.Forte@Sun.COM 		    hostname) == FALSE) {
363*7836SJohn.Forte@Sun.COM 			goto done;
364*7836SJohn.Forte@Sun.COM 		}
365*7836SJohn.Forte@Sun.COM 
366*7836SJohn.Forte@Sun.COM 		if (port) {
367*7836SJohn.Forte@Sun.COM 			if (strcmp(nconf->nc_protofmly, NC_INET) == 0)
368*7836SJohn.Forte@Sun.COM 			    /* LINTED pointer alignment */
369*7836SJohn.Forte@Sun.COM 			    ((struct sockaddr_in *)tbind->addr.buf)->sin_port
370*7836SJohn.Forte@Sun.COM 					= port;
371*7836SJohn.Forte@Sun.COM #ifdef NC_INET6
372*7836SJohn.Forte@Sun.COM 			else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0)
373*7836SJohn.Forte@Sun.COM 			    /* LINTED pointer alignment */
374*7836SJohn.Forte@Sun.COM 			    ((struct sockaddr_in6 *)tbind->addr.buf)->sin6_port
375*7836SJohn.Forte@Sun.COM 					= port;
376*7836SJohn.Forte@Sun.COM #endif
377*7836SJohn.Forte@Sun.COM 		}
378*7836SJohn.Forte@Sun.COM 
379*7836SJohn.Forte@Sun.COM 		/* Simon -- we never use the client we create?! */
380*7836SJohn.Forte@Sun.COM 		cl = clnt_tli_create(fd, nconf, &tbind->addr, prog, vers, 0, 0);
381*7836SJohn.Forte@Sun.COM 		if (cl == NULL)
382*7836SJohn.Forte@Sun.COM 			goto done;
383*7836SJohn.Forte@Sun.COM 
384*7836SJohn.Forte@Sun.COM 		ah = authsys_create_default();
385*7836SJohn.Forte@Sun.COM 		if (ah != NULL)
386*7836SJohn.Forte@Sun.COM 			cl->cl_auth = ah;
387*7836SJohn.Forte@Sun.COM 
388*7836SJohn.Forte@Sun.COM 		tv.tv_sec = 5;
389*7836SJohn.Forte@Sun.COM 		tv.tv_usec = 0;
390*7836SJohn.Forte@Sun.COM 
391*7836SJohn.Forte@Sun.COM 		(void) clnt_control(cl, CLSET_TIMEOUT, (char *)&tv);
392*7836SJohn.Forte@Sun.COM 	} else { /* create our own address and skip rpcbind */
393*7836SJohn.Forte@Sun.COM 		struct netbuf *nb;
394*7836SJohn.Forte@Sun.COM 		struct hostent *hp;
395*7836SJohn.Forte@Sun.COM 		int j;
396*7836SJohn.Forte@Sun.COM 		int errnum;
397*7836SJohn.Forte@Sun.COM 		unsigned short family;
398*7836SJohn.Forte@Sun.COM 		nb = &(tbind->addr);
399*7836SJohn.Forte@Sun.COM 
400*7836SJohn.Forte@Sun.COM #ifdef AF_INET6
401*7836SJohn.Forte@Sun.COM 		if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
402*7836SJohn.Forte@Sun.COM 			hp = getipnodebyname(hostname, AF_INET6, 0, &errnum);
403*7836SJohn.Forte@Sun.COM 			family = AF_INET6;
404*7836SJohn.Forte@Sun.COM 			nb->len = nb->maxlen = sizeof (struct sockaddr_in6);
405*7836SJohn.Forte@Sun.COM 		} else {
406*7836SJohn.Forte@Sun.COM 			hp = getipnodebyname(hostname, AF_INET, 0, &errnum);
407*7836SJohn.Forte@Sun.COM 			family = AF_INET;
408*7836SJohn.Forte@Sun.COM 			nb->len = nb->maxlen = sizeof (struct sockaddr_in);
409*7836SJohn.Forte@Sun.COM 		}
410*7836SJohn.Forte@Sun.COM 		if (hp == NULL) {
411*7836SJohn.Forte@Sun.COM #ifdef DEBUG_ADDR
412*7836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, dgettext("sndr",
413*7836SJohn.Forte@Sun.COM 				    "Could not find host %s\n"), hostname);
414*7836SJohn.Forte@Sun.COM #endif
415*7836SJohn.Forte@Sun.COM 				goto done;
416*7836SJohn.Forte@Sun.COM 		}
417*7836SJohn.Forte@Sun.COM 		nb->buf = (char *)calloc(1, nb->maxlen);
418*7836SJohn.Forte@Sun.COM 		if (nb->buf == NULL) {
419*7836SJohn.Forte@Sun.COM 			(void) printf(dgettext("sndr", "no memory\n"));
420*7836SJohn.Forte@Sun.COM 			goto done;
421*7836SJohn.Forte@Sun.COM 		}
422*7836SJohn.Forte@Sun.COM 
423*7836SJohn.Forte@Sun.COM 		if (family == AF_INET) {
424*7836SJohn.Forte@Sun.COM 			for (j = 0; j < hp->h_length; j++)
425*7836SJohn.Forte@Sun.COM 				nb->buf[j+4] = hp->h_addr[j];
426*7836SJohn.Forte@Sun.COM 			/* LINTED pointer alignment */
427*7836SJohn.Forte@Sun.COM 			((struct sockaddr_in *)(nb->buf))->sin_port = port;
428*7836SJohn.Forte@Sun.COM 			/* LINTED pointer alignment */
429*7836SJohn.Forte@Sun.COM 			((struct sockaddr_in *)(nb->buf))->sin_family = AF_INET;
430*7836SJohn.Forte@Sun.COM 		} else {
431*7836SJohn.Forte@Sun.COM 			for (j = 0; j < hp->h_length; j++)
432*7836SJohn.Forte@Sun.COM 				nb->buf[j+8] = hp->h_addr[j];
433*7836SJohn.Forte@Sun.COM 			/* LINTED pointer alignment */
434*7836SJohn.Forte@Sun.COM 			((struct sockaddr_in6 *)(nb->buf))->sin6_port = port;
435*7836SJohn.Forte@Sun.COM 			/* LINTED pointer alignment */
436*7836SJohn.Forte@Sun.COM 			((struct sockaddr_in6 *)(nb->buf))->sin6_family =
437*7836SJohn.Forte@Sun.COM 			    AF_INET6;
438*7836SJohn.Forte@Sun.COM 		}
439*7836SJohn.Forte@Sun.COM 		freehostent(hp);
440*7836SJohn.Forte@Sun.COM #else
441*7836SJohn.Forte@Sun.COM 		hp = gethostbyname(hostname);
442*7836SJohn.Forte@Sun.COM 		if (hp == NULL) {
443*7836SJohn.Forte@Sun.COM #ifdef DEBUG
444*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, dgettext("sndr",
445*7836SJohn.Forte@Sun.COM 			    "Could not find host %s"), hostname);
446*7836SJohn.Forte@Sun.COM #endif
447*7836SJohn.Forte@Sun.COM 			goto done;
448*7836SJohn.Forte@Sun.COM 		}
449*7836SJohn.Forte@Sun.COM 
450*7836SJohn.Forte@Sun.COM 		nb->len = nb->maxlen = sizeof (struct sockaddr_in);
451*7836SJohn.Forte@Sun.COM 		nb->buf = (char *)calloc(1, nb->maxlen);
452*7836SJohn.Forte@Sun.COM 		if (nb->buf == NULL) {
453*7836SJohn.Forte@Sun.COM 			(void) printf(dgettext("sndr", "no memory\n"));
454*7836SJohn.Forte@Sun.COM 			free(nb);
455*7836SJohn.Forte@Sun.COM 			nb = NULL;
456*7836SJohn.Forte@Sun.COM 			goto done;
457*7836SJohn.Forte@Sun.COM 		}
458*7836SJohn.Forte@Sun.COM 
459*7836SJohn.Forte@Sun.COM 		for (j = 0; j < hp->h_length; j++)
460*7836SJohn.Forte@Sun.COM 			nb->buf[j+4] = hp->h_addr[j];
461*7836SJohn.Forte@Sun.COM 
462*7836SJohn.Forte@Sun.COM 		if (hp->h_addrtype == AF_INET) {
463*7836SJohn.Forte@Sun.COM 			((struct sockaddr_in *)(nb->buf))->sin_port = port;
464*7836SJohn.Forte@Sun.COM 			((struct sockaddr_in *)(nb->buf))->sin_family = AF_INET;
465*7836SJohn.Forte@Sun.COM 		}
466*7836SJohn.Forte@Sun.COM #endif
467*7836SJohn.Forte@Sun.COM 	}
468*7836SJohn.Forte@Sun.COM 
469*7836SJohn.Forte@Sun.COM 	/*
470*7836SJohn.Forte@Sun.COM 	 * Make a copy of the netbuf to return
471*7836SJohn.Forte@Sun.COM 	 */
472*7836SJohn.Forte@Sun.COM 	nb = (struct netbuf *)calloc(1, sizeof (*nb));
473*7836SJohn.Forte@Sun.COM 	if (nb == NULL) {
474*7836SJohn.Forte@Sun.COM 		(void) printf(dgettext("sndr", "no memory\n"));
475*7836SJohn.Forte@Sun.COM 		goto done;
476*7836SJohn.Forte@Sun.COM 	}
477*7836SJohn.Forte@Sun.COM 
478*7836SJohn.Forte@Sun.COM 	*nb = tbind->addr;	/* structure copy */
479*7836SJohn.Forte@Sun.COM 
480*7836SJohn.Forte@Sun.COM 	nb->buf = (char *)calloc(1, nb->maxlen);
481*7836SJohn.Forte@Sun.COM 	if (nb->buf == NULL) {
482*7836SJohn.Forte@Sun.COM 		(void) printf(dgettext("sndr", "no memory\n"));
483*7836SJohn.Forte@Sun.COM 		free(nb);
484*7836SJohn.Forte@Sun.COM 		nb = NULL;
485*7836SJohn.Forte@Sun.COM 		goto done;
486*7836SJohn.Forte@Sun.COM 	}
487*7836SJohn.Forte@Sun.COM 
488*7836SJohn.Forte@Sun.COM 	(void) memcpy(nb->buf, tbind->addr.buf, tbind->addr.len);
489*7836SJohn.Forte@Sun.COM 
490*7836SJohn.Forte@Sun.COM done:
491*7836SJohn.Forte@Sun.COM 	if (cl) {
492*7836SJohn.Forte@Sun.COM 		if (ah != NULL) {
493*7836SJohn.Forte@Sun.COM 		    AUTH_DESTROY(cl->cl_auth);
494*7836SJohn.Forte@Sun.COM 		    cl->cl_auth = NULL;
495*7836SJohn.Forte@Sun.COM 		}
496*7836SJohn.Forte@Sun.COM 
497*7836SJohn.Forte@Sun.COM 		clnt_destroy(cl);
498*7836SJohn.Forte@Sun.COM 		cl = NULL;
499*7836SJohn.Forte@Sun.COM 	}
500*7836SJohn.Forte@Sun.COM 
501*7836SJohn.Forte@Sun.COM 	if (tbind) {
502*7836SJohn.Forte@Sun.COM 		t_free((char *)tbind, T_BIND);
503*7836SJohn.Forte@Sun.COM 		tbind = NULL;
504*7836SJohn.Forte@Sun.COM 	}
505*7836SJohn.Forte@Sun.COM 
506*7836SJohn.Forte@Sun.COM 	if (fd >= 0)
507*7836SJohn.Forte@Sun.COM 		(void) t_close(fd);
508*7836SJohn.Forte@Sun.COM 	return (nb);
509*7836SJohn.Forte@Sun.COM }
510*7836SJohn.Forte@Sun.COM 
511*7836SJohn.Forte@Sun.COM /*
512*7836SJohn.Forte@Sun.COM  * Get a network address on "hostname" for program "prog"
513*7836SJohn.Forte@Sun.COM  * with version "vers".  If the port number is specified (non zero)
514*7836SJohn.Forte@Sun.COM  * then try for a TCP/UDP transport and set the port number of the
515*7836SJohn.Forte@Sun.COM  * resulting IP address.
516*7836SJohn.Forte@Sun.COM  *
517*7836SJohn.Forte@Sun.COM  * If the address of a netconfig pointer was passed and
518*7836SJohn.Forte@Sun.COM  * if it's not null, use it as the netconfig otherwise
519*7836SJohn.Forte@Sun.COM  * assign the address of the netconfig that was used to
520*7836SJohn.Forte@Sun.COM  * establish contact with the service.
521*7836SJohn.Forte@Sun.COM  * If portmap is false, we return a similiar address and we do not
522*7836SJohn.Forte@Sun.COM  * contact rpcbind
523*7836SJohn.Forte@Sun.COM  *
524*7836SJohn.Forte@Sun.COM  */
525*7836SJohn.Forte@Sun.COM 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)526*7836SJohn.Forte@Sun.COM get_addr(char *hostname, ulong_t prog, ulong_t vers, struct netconfig **nconfp,
527*7836SJohn.Forte@Sun.COM 	char *proto, char *srvport, struct t_info *tinfo, int portmap)
528*7836SJohn.Forte@Sun.COM {
529*7836SJohn.Forte@Sun.COM 	struct netbuf *nb = NULL;
530*7836SJohn.Forte@Sun.COM 	struct netconfig *nconf = NULL;
531*7836SJohn.Forte@Sun.COM 	NCONF_HANDLE *nc = NULL;
532*7836SJohn.Forte@Sun.COM 	int nthtry = FIRST_TRY;
533*7836SJohn.Forte@Sun.COM 	struct servent *svp;
534*7836SJohn.Forte@Sun.COM 	ushort_t port;
535*7836SJohn.Forte@Sun.COM 
536*7836SJohn.Forte@Sun.COM 	/*
537*7836SJohn.Forte@Sun.COM 	 * First lets get the requested port
538*7836SJohn.Forte@Sun.COM 	 */
539*7836SJohn.Forte@Sun.COM 
540*7836SJohn.Forte@Sun.COM 	if ((svp = getservbyname(srvport, proto)) == NULL)
541*7836SJohn.Forte@Sun.COM 		goto done;
542*7836SJohn.Forte@Sun.COM 	port = svp->s_port;
543*7836SJohn.Forte@Sun.COM 	/*
544*7836SJohn.Forte@Sun.COM 	 * No nconf passed in.
545*7836SJohn.Forte@Sun.COM 	 *
546*7836SJohn.Forte@Sun.COM 	 * Try to get a nconf from /etc/netconfig filtered by
547*7836SJohn.Forte@Sun.COM 	 * the NETPATH environment variable.
548*7836SJohn.Forte@Sun.COM 	 * First search for COTS, second for CLTS unless proto
549*7836SJohn.Forte@Sun.COM 	 * is specified.  When we retry, we reset the
550*7836SJohn.Forte@Sun.COM 	 * netconfig list so that we would search the whole list
551*7836SJohn.Forte@Sun.COM 	 * all over again.
552*7836SJohn.Forte@Sun.COM 	 */
553*7836SJohn.Forte@Sun.COM 	if ((nc = setnetpath()) == NULL)
554*7836SJohn.Forte@Sun.COM 		goto done;
555*7836SJohn.Forte@Sun.COM 
556*7836SJohn.Forte@Sun.COM 	/*
557*7836SJohn.Forte@Sun.COM 	 * If proto is specified, then only search for the match,
558*7836SJohn.Forte@Sun.COM 	 * otherwise try COTS first, if failed, try CLTS.
559*7836SJohn.Forte@Sun.COM 	 */
560*7836SJohn.Forte@Sun.COM 	if (proto) {
561*7836SJohn.Forte@Sun.COM 		while (nconf = getnetpath(nc)) {
562*7836SJohn.Forte@Sun.COM 			if (strcmp(nconf->nc_netid, proto) == 0) {
563*7836SJohn.Forte@Sun.COM 				/*
564*7836SJohn.Forte@Sun.COM 				 * If the port number is specified then TCP/UDP
565*7836SJohn.Forte@Sun.COM 				 * is needed. Otherwise any cots/clts will do.
566*7836SJohn.Forte@Sun.COM 				 */
567*7836SJohn.Forte@Sun.COM 				if (port == 0)
568*7836SJohn.Forte@Sun.COM 					break;
569*7836SJohn.Forte@Sun.COM 
570*7836SJohn.Forte@Sun.COM 				if ((strcmp(nconf->nc_protofmly, NC_INET) == 0
571*7836SJohn.Forte@Sun.COM #ifdef NC_INET6
572*7836SJohn.Forte@Sun.COM 				/* CSTYLED */
573*7836SJohn.Forte@Sun.COM 				|| strcmp(nconf->nc_protofmly, NC_INET6) == 0
574*7836SJohn.Forte@Sun.COM #endif
575*7836SJohn.Forte@Sun.COM 				/* CSTYLED */
576*7836SJohn.Forte@Sun.COM 				) &&
577*7836SJohn.Forte@Sun.COM 				(strcmp(nconf->nc_proto, NC_TCP) == 0 ||
578*7836SJohn.Forte@Sun.COM 				strcmp(nconf->nc_proto, NC_UDP) == 0))
579*7836SJohn.Forte@Sun.COM 					break;
580*7836SJohn.Forte@Sun.COM 				else {
581*7836SJohn.Forte@Sun.COM 					nconf = NULL;
582*7836SJohn.Forte@Sun.COM 					break;
583*7836SJohn.Forte@Sun.COM 				}
584*7836SJohn.Forte@Sun.COM 			}
585*7836SJohn.Forte@Sun.COM 		}
586*7836SJohn.Forte@Sun.COM 		if (nconf == NULL)
587*7836SJohn.Forte@Sun.COM 			goto done;
588*7836SJohn.Forte@Sun.COM 		if ((nb = get_the_addr(hostname, prog, vers, nconf, port,
589*7836SJohn.Forte@Sun.COM 				tinfo, portmap)) == NULL) {
590*7836SJohn.Forte@Sun.COM 			goto done;
591*7836SJohn.Forte@Sun.COM 		}
592*7836SJohn.Forte@Sun.COM 	} else {
593*7836SJohn.Forte@Sun.COM retry:
594*7836SJohn.Forte@Sun.COM 		while (nconf = getnetpath(nc)) {
595*7836SJohn.Forte@Sun.COM 			if (nconf->nc_flag & NC_VISIBLE) {
596*7836SJohn.Forte@Sun.COM 			    if (nthtry == FIRST_TRY) {
597*7836SJohn.Forte@Sun.COM 				if ((nconf->nc_semantics == NC_TPI_COTS_ORD) ||
598*7836SJohn.Forte@Sun.COM 					(nconf->nc_semantics == NC_TPI_COTS)) {
599*7836SJohn.Forte@Sun.COM 				    if (port == 0)
600*7836SJohn.Forte@Sun.COM 					break;
601*7836SJohn.Forte@Sun.COM 				    if ((strcmp(nconf->nc_protofmly,
602*7836SJohn.Forte@Sun.COM 					NC_INET) == 0
603*7836SJohn.Forte@Sun.COM #ifdef NC_INET6
604*7836SJohn.Forte@Sun.COM 					/* CSTYLED */
605*7836SJohn.Forte@Sun.COM 					|| strcmp(nconf->nc_protofmly,
606*7836SJohn.Forte@Sun.COM 					NC_INET6) == 0
607*7836SJohn.Forte@Sun.COM #endif
608*7836SJohn.Forte@Sun.COM 					/* CSTYLED */
609*7836SJohn.Forte@Sun.COM 					) &&
610*7836SJohn.Forte@Sun.COM 					(strcmp(nconf->nc_proto, NC_TCP) == 0))
611*7836SJohn.Forte@Sun.COM 					break;
612*7836SJohn.Forte@Sun.COM 				}
613*7836SJohn.Forte@Sun.COM 			    }
614*7836SJohn.Forte@Sun.COM 			}
615*7836SJohn.Forte@Sun.COM 		} /* while */
616*7836SJohn.Forte@Sun.COM 		if (nconf == NULL) {
617*7836SJohn.Forte@Sun.COM 			if (++nthtry <= MNT_PREF_LISTLEN) {
618*7836SJohn.Forte@Sun.COM 				endnetpath(nc);
619*7836SJohn.Forte@Sun.COM 				if ((nc = setnetpath()) == NULL)
620*7836SJohn.Forte@Sun.COM 					goto done;
621*7836SJohn.Forte@Sun.COM 				goto retry;
622*7836SJohn.Forte@Sun.COM 			} else
623*7836SJohn.Forte@Sun.COM 				goto done;
624*7836SJohn.Forte@Sun.COM 		} else {
625*7836SJohn.Forte@Sun.COM 			if ((nb = get_the_addr(hostname, prog, vers, nconf,
626*7836SJohn.Forte@Sun.COM 			    port, tinfo, portmap)) == NULL) {
627*7836SJohn.Forte@Sun.COM 				/*
628*7836SJohn.Forte@Sun.COM 				 * Continue the same search path in the
629*7836SJohn.Forte@Sun.COM 				 * netconfig db until no more matched
630*7836SJohn.Forte@Sun.COM 				 * nconf (nconf == NULL).
631*7836SJohn.Forte@Sun.COM 				 */
632*7836SJohn.Forte@Sun.COM 				goto retry;
633*7836SJohn.Forte@Sun.COM 			}
634*7836SJohn.Forte@Sun.COM #ifdef AF_INET6
635*7836SJohn.Forte@Sun.COM 			if ((nb->len == 8) &&
636*7836SJohn.Forte@Sun.COM 			    (strcmp(nconf->nc_protofmly, NC_INET6) == 0)) {
637*7836SJohn.Forte@Sun.COM 				/*
638*7836SJohn.Forte@Sun.COM 				 * We have a mismatch in the netconfig retry
639*7836SJohn.Forte@Sun.COM 				 */
640*7836SJohn.Forte@Sun.COM 				free(nb);
641*7836SJohn.Forte@Sun.COM 				goto retry;
642*7836SJohn.Forte@Sun.COM 			}
643*7836SJohn.Forte@Sun.COM #endif
644*7836SJohn.Forte@Sun.COM 		}
645*7836SJohn.Forte@Sun.COM 	}
646*7836SJohn.Forte@Sun.COM 
647*7836SJohn.Forte@Sun.COM 	/*
648*7836SJohn.Forte@Sun.COM 	 * Got nconf and nb.  Now dup the netconfig structure (nconf)
649*7836SJohn.Forte@Sun.COM 	 * and return it thru nconfp.
650*7836SJohn.Forte@Sun.COM 	 */
651*7836SJohn.Forte@Sun.COM 	*nconfp = getnetconfigent(nconf->nc_netid);
652*7836SJohn.Forte@Sun.COM 	if (*nconfp == NULL) {
653*7836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "no memory\n");
654*7836SJohn.Forte@Sun.COM 		free(nb);
655*7836SJohn.Forte@Sun.COM 		nb = NULL;
656*7836SJohn.Forte@Sun.COM 	}
657*7836SJohn.Forte@Sun.COM done:
658*7836SJohn.Forte@Sun.COM 	if (nc)
659*7836SJohn.Forte@Sun.COM 		endnetpath(nc);
660*7836SJohn.Forte@Sun.COM 	return (nb);
661*7836SJohn.Forte@Sun.COM }
662*7836SJohn.Forte@Sun.COM 
663*7836SJohn.Forte@Sun.COM 
664*7836SJohn.Forte@Sun.COM /* return values as for nsc_check_release() */
665*7836SJohn.Forte@Sun.COM int
rdc_check_release(char ** reqd)666*7836SJohn.Forte@Sun.COM rdc_check_release(char **reqd)
667*7836SJohn.Forte@Sun.COM {
668*7836SJohn.Forte@Sun.COM 	/* librdc.so must be built on the runtime OS release */
669*7836SJohn.Forte@Sun.COM 	return (nsc_check_release(BUILD_REV_STR, NULL, reqd));
670*7836SJohn.Forte@Sun.COM }
671