xref: /onnv-gate/usr/src/cmd/fs.d/nfs/lib/selfcheck.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * 	selfcheck.c
24*0Sstevel@tonic-gate  *      Copyright (c) 1999 Sun Microsystems Inc.
25*0Sstevel@tonic-gate  *      All Rights Reserved.
26*0Sstevel@tonic-gate  */
27*0Sstevel@tonic-gate 
28*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #include <errno.h>
31*0Sstevel@tonic-gate #include <syslog.h>
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #include <strings.h>
34*0Sstevel@tonic-gate #include <malloc.h>
35*0Sstevel@tonic-gate #include <stdio.h>
36*0Sstevel@tonic-gate #include <unistd.h>
37*0Sstevel@tonic-gate #include <sys/sockio.h>
38*0Sstevel@tonic-gate #include <netinet/in.h>
39*0Sstevel@tonic-gate #include <sys/socket.h>
40*0Sstevel@tonic-gate #include <netdb.h>
41*0Sstevel@tonic-gate #include <net/if.h>
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate int
44*0Sstevel@tonic-gate self_check(hostname)
45*0Sstevel@tonic-gate 	char *hostname;
46*0Sstevel@tonic-gate {
47*0Sstevel@tonic-gate 	int s, res = 0;
48*0Sstevel@tonic-gate 	struct sioc_addrreq areq;
49*0Sstevel@tonic-gate 
50*0Sstevel@tonic-gate 	struct hostent *hostinfo;
51*0Sstevel@tonic-gate 	int family;
52*0Sstevel@tonic-gate 	int flags;
53*0Sstevel@tonic-gate 	int error_num;
54*0Sstevel@tonic-gate 	char **hostptr;
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate 	struct sockaddr_in6 ipv6addr;
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate 	family = AF_INET6;
59*0Sstevel@tonic-gate 	flags = AI_DEFAULT;
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate 	if ((s = socket(family, SOCK_DGRAM, 0)) < 0) {
62*0Sstevel@tonic-gate 		syslog(LOG_ERR, "self_check: socket: %m");
63*0Sstevel@tonic-gate 		return (0);
64*0Sstevel@tonic-gate 	}
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate 	if ((hostinfo = getipnodebyname(hostname, family, flags,
67*0Sstevel@tonic-gate 	    &error_num)) == NULL) {
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate 		if (error_num == TRY_AGAIN)
70*0Sstevel@tonic-gate 			syslog(LOG_DEBUG,
71*0Sstevel@tonic-gate 			    "self_check: unknown host: %s (try again later)\n",
72*0Sstevel@tonic-gate 			    hostname);
73*0Sstevel@tonic-gate 		else
74*0Sstevel@tonic-gate 			syslog(LOG_DEBUG,
75*0Sstevel@tonic-gate 			    "self_check: unknown host: %s\n", hostname);
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 		(void) close(s);
78*0Sstevel@tonic-gate 		return (0);
79*0Sstevel@tonic-gate 	}
80*0Sstevel@tonic-gate 
81*0Sstevel@tonic-gate 	for (hostptr = hostinfo->h_addr_list; *hostptr; hostptr++) {
82*0Sstevel@tonic-gate 		bzero(&ipv6addr, sizeof (ipv6addr));
83*0Sstevel@tonic-gate 		ipv6addr.sin6_family = AF_INET6;
84*0Sstevel@tonic-gate 		ipv6addr.sin6_addr = *((struct in6_addr *)(*hostptr));
85*0Sstevel@tonic-gate 		memcpy(&areq.sa_addr, (void *)&ipv6addr, sizeof (ipv6addr));
86*0Sstevel@tonic-gate 		areq.sa_res = -1;
87*0Sstevel@tonic-gate 		(void) ioctl(s, SIOCTMYADDR, (caddr_t)&areq);
88*0Sstevel@tonic-gate 		if (areq.sa_res == 1) {
89*0Sstevel@tonic-gate 			res = 1;
90*0Sstevel@tonic-gate 			break;
91*0Sstevel@tonic-gate 		}
92*0Sstevel@tonic-gate 	}
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate 	freehostent(hostinfo);
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate 	(void) close(s);
97*0Sstevel@tonic-gate 	return (res);
98*0Sstevel@tonic-gate }
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate #define	MAXIFS	32
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate /*
103*0Sstevel@tonic-gate  * create an ifconf structure that represents all the interfaces
104*0Sstevel@tonic-gate  * configured for this host.  Two buffers are allcated here:
105*0Sstevel@tonic-gate  *	lifc - the ifconf structure returned
106*0Sstevel@tonic-gate  *	lifc->lifc_buf - the list of ifreq structures
107*0Sstevel@tonic-gate  * Both of the buffers must be freed by the calling routine.
108*0Sstevel@tonic-gate  * A NULL pointer is returned upon failure.  In this case any
109*0Sstevel@tonic-gate  * data that was allocated before the failure has already been
110*0Sstevel@tonic-gate  * freed.
111*0Sstevel@tonic-gate  */
112*0Sstevel@tonic-gate struct lifconf *
113*0Sstevel@tonic-gate getmyaddrs()
114*0Sstevel@tonic-gate {
115*0Sstevel@tonic-gate 	int sock;
116*0Sstevel@tonic-gate 	struct lifnum lifn;
117*0Sstevel@tonic-gate 	int numifs;
118*0Sstevel@tonic-gate 	char *buf;
119*0Sstevel@tonic-gate 	struct lifconf *lifc;
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate 	if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
122*0Sstevel@tonic-gate 		syslog(LOG_ERR, "statd:getmyaddrs socket: %m");
123*0Sstevel@tonic-gate 		return ((struct lifconf *)NULL);
124*0Sstevel@tonic-gate 	}
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	lifn.lifn_family = AF_UNSPEC;
127*0Sstevel@tonic-gate 	lifn.lifn_flags = 0;
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 	if (ioctl(sock, SIOCGLIFNUM, (char *)&lifn) < 0) {
130*0Sstevel@tonic-gate 		syslog(LOG_ERR,
131*0Sstevel@tonic-gate 		"statd:getmyaddrs, get number of interfaces, error: %m");
132*0Sstevel@tonic-gate 		numifs = MAXIFS;
133*0Sstevel@tonic-gate 	}
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	numifs = lifn.lifn_count;
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate 	lifc = (struct lifconf *)malloc(sizeof (struct lifconf));
138*0Sstevel@tonic-gate 	lifc = malloc(sizeof (struct lifconf));
139*0Sstevel@tonic-gate 	if (lifc == NULL) {
140*0Sstevel@tonic-gate 		syslog(LOG_ERR,
141*0Sstevel@tonic-gate 			"statd:getmyaddrs, malloc for lifconf failed: %m");
142*0Sstevel@tonic-gate 		(void) close(sock);
143*0Sstevel@tonic-gate 		return ((struct lifconf *)NULL);
144*0Sstevel@tonic-gate 	}
145*0Sstevel@tonic-gate 	buf = (char *)malloc(numifs * sizeof (struct lifreq));
146*0Sstevel@tonic-gate 	if (buf == NULL) {
147*0Sstevel@tonic-gate 		syslog(LOG_ERR,
148*0Sstevel@tonic-gate 			"statd:getmyaddrs, malloc for lifreq failed: %m");
149*0Sstevel@tonic-gate 		(void) close(sock);
150*0Sstevel@tonic-gate 		free(lifc);
151*0Sstevel@tonic-gate 		return ((struct lifconf *)NULL);
152*0Sstevel@tonic-gate 	}
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate 	lifc->lifc_family = AF_UNSPEC;
155*0Sstevel@tonic-gate 	lifc->lifc_flags = 0;
156*0Sstevel@tonic-gate 	lifc->lifc_buf = buf;
157*0Sstevel@tonic-gate 	lifc->lifc_len = numifs * sizeof (struct lifreq);
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate 	if (ioctl(sock, SIOCGLIFCONF, (char *)lifc) < 0) {
160*0Sstevel@tonic-gate 		syslog(LOG_ERR, "statd:getmyaddrs, SIOCGLIFCONF, error: %m");
161*0Sstevel@tonic-gate 		(void) close(sock);
162*0Sstevel@tonic-gate 		free(buf);
163*0Sstevel@tonic-gate 		free(lifc);
164*0Sstevel@tonic-gate 		return ((struct lifconf *)NULL);
165*0Sstevel@tonic-gate 	}
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	(void) close(sock);
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 	return (lifc);
170*0Sstevel@tonic-gate }
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate int
173*0Sstevel@tonic-gate Is_ipv6present(void)
174*0Sstevel@tonic-gate {
175*0Sstevel@tonic-gate 	int sock;
176*0Sstevel@tonic-gate 	struct lifnum lifn;
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 	sock = socket(AF_INET6, SOCK_DGRAM, 0);
179*0Sstevel@tonic-gate 	if (sock < 0)
180*0Sstevel@tonic-gate 		return (0);
181*0Sstevel@tonic-gate 
182*0Sstevel@tonic-gate 	lifn.lifn_family = AF_INET6;
183*0Sstevel@tonic-gate 	lifn.lifn_flags = 0;
184*0Sstevel@tonic-gate 	if (ioctl(sock, SIOCGLIFNUM, (char *)&lifn) < 0) {
185*0Sstevel@tonic-gate 		close(sock);
186*0Sstevel@tonic-gate 		return (0);
187*0Sstevel@tonic-gate 	}
188*0Sstevel@tonic-gate 	close(sock);
189*0Sstevel@tonic-gate 	if (lifn.lifn_count == 0)
190*0Sstevel@tonic-gate 		return (0);
191*0Sstevel@tonic-gate 	return (1);
192*0Sstevel@tonic-gate }
193