xref: /aosp_15_r20/external/iputils/ninfod/ninfod_name.c (revision bd1f8aeb6080fa6544ec30aeca3eb4da100f359f)
1*bd1f8aebSAndroid Build Coastguard Worker /* $USAGI: ninfod_name.c,v 1.15 2003-01-11 14:33:28 yoshfuji Exp $ */
2*bd1f8aebSAndroid Build Coastguard Worker /*
3*bd1f8aebSAndroid Build Coastguard Worker  * Copyright (C) 2002 USAGI/WIDE Project.
4*bd1f8aebSAndroid Build Coastguard Worker  * All rights reserved.
5*bd1f8aebSAndroid Build Coastguard Worker  *
6*bd1f8aebSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
7*bd1f8aebSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
8*bd1f8aebSAndroid Build Coastguard Worker  * are met:
9*bd1f8aebSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
10*bd1f8aebSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
11*bd1f8aebSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
12*bd1f8aebSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
13*bd1f8aebSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
14*bd1f8aebSAndroid Build Coastguard Worker  * 3. Neither the name of the project nor the names of its contributors
15*bd1f8aebSAndroid Build Coastguard Worker  *    may be used to endorse or promote products derived from this software
16*bd1f8aebSAndroid Build Coastguard Worker  *    without specific prior written permission.
17*bd1f8aebSAndroid Build Coastguard Worker  *
18*bd1f8aebSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19*bd1f8aebSAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*bd1f8aebSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*bd1f8aebSAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22*bd1f8aebSAndroid Build Coastguard Worker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23*bd1f8aebSAndroid Build Coastguard Worker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24*bd1f8aebSAndroid Build Coastguard Worker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25*bd1f8aebSAndroid Build Coastguard Worker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26*bd1f8aebSAndroid Build Coastguard Worker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27*bd1f8aebSAndroid Build Coastguard Worker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*bd1f8aebSAndroid Build Coastguard Worker  * SUCH DAMAGE.
29*bd1f8aebSAndroid Build Coastguard Worker  */
30*bd1f8aebSAndroid Build Coastguard Worker /*
31*bd1f8aebSAndroid Build Coastguard Worker  * Author:
32*bd1f8aebSAndroid Build Coastguard Worker  * 	YOSHIFUJI Hideaki <[email protected]>
33*bd1f8aebSAndroid Build Coastguard Worker  */
34*bd1f8aebSAndroid Build Coastguard Worker 
35*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_CONFIG_H
36*bd1f8aebSAndroid Build Coastguard Worker #include "config.h"
37*bd1f8aebSAndroid Build Coastguard Worker #endif
38*bd1f8aebSAndroid Build Coastguard Worker 
39*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_SYS_TYPES_H
40*bd1f8aebSAndroid Build Coastguard Worker # include <sys/types.h>
41*bd1f8aebSAndroid Build Coastguard Worker #endif
42*bd1f8aebSAndroid Build Coastguard Worker #if STDC_HEADERS
43*bd1f8aebSAndroid Build Coastguard Worker # include <stdio.h>
44*bd1f8aebSAndroid Build Coastguard Worker # include <stdlib.h>
45*bd1f8aebSAndroid Build Coastguard Worker # include <stddef.h>
46*bd1f8aebSAndroid Build Coastguard Worker # include <ctype.h>
47*bd1f8aebSAndroid Build Coastguard Worker #else
48*bd1f8aebSAndroid Build Coastguard Worker # if HAVE_STDLIB_H
49*bd1f8aebSAndroid Build Coastguard Worker #  include <stdlib.h>
50*bd1f8aebSAndroid Build Coastguard Worker # endif
51*bd1f8aebSAndroid Build Coastguard Worker #endif
52*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_STRING_H
53*bd1f8aebSAndroid Build Coastguard Worker # if !STDC_HEADERS && HAVE_MEMORY_H
54*bd1f8aebSAndroid Build Coastguard Worker #  include <memory.h>
55*bd1f8aebSAndroid Build Coastguard Worker # endif
56*bd1f8aebSAndroid Build Coastguard Worker # include <string.h>
57*bd1f8aebSAndroid Build Coastguard Worker #endif
58*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_STRINGS_H
59*bd1f8aebSAndroid Build Coastguard Worker # include <strings.h>
60*bd1f8aebSAndroid Build Coastguard Worker #endif
61*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_INTTYPES_H
62*bd1f8aebSAndroid Build Coastguard Worker # include <inttypes.h>
63*bd1f8aebSAndroid Build Coastguard Worker #else
64*bd1f8aebSAndroid Build Coastguard Worker # if HAVE_STDINT_H
65*bd1f8aebSAndroid Build Coastguard Worker #  include <stdint.h>
66*bd1f8aebSAndroid Build Coastguard Worker # endif
67*bd1f8aebSAndroid Build Coastguard Worker #endif
68*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_UNISTD_H
69*bd1f8aebSAndroid Build Coastguard Worker # include <unistd.h>
70*bd1f8aebSAndroid Build Coastguard Worker #endif
71*bd1f8aebSAndroid Build Coastguard Worker 
72*bd1f8aebSAndroid Build Coastguard Worker #if TIME_WITH_SYS_TIME
73*bd1f8aebSAndroid Build Coastguard Worker # include <sys/time.h>
74*bd1f8aebSAndroid Build Coastguard Worker # include <time.h>
75*bd1f8aebSAndroid Build Coastguard Worker #else
76*bd1f8aebSAndroid Build Coastguard Worker # if HAVE_SYS_TIME_H
77*bd1f8aebSAndroid Build Coastguard Worker #  include <sys/time.h>
78*bd1f8aebSAndroid Build Coastguard Worker # else
79*bd1f8aebSAndroid Build Coastguard Worker #  include <time.h>
80*bd1f8aebSAndroid Build Coastguard Worker # endif
81*bd1f8aebSAndroid Build Coastguard Worker #endif
82*bd1f8aebSAndroid Build Coastguard Worker 
83*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_SYS_UIO_H
84*bd1f8aebSAndroid Build Coastguard Worker #include <sys/uio.h>
85*bd1f8aebSAndroid Build Coastguard Worker #endif
86*bd1f8aebSAndroid Build Coastguard Worker 
87*bd1f8aebSAndroid Build Coastguard Worker #include <sys/socket.h>
88*bd1f8aebSAndroid Build Coastguard Worker 
89*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_NETINET_IN_H
90*bd1f8aebSAndroid Build Coastguard Worker # include <netinet/in.h>
91*bd1f8aebSAndroid Build Coastguard Worker #endif
92*bd1f8aebSAndroid Build Coastguard Worker 
93*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_NETINET_ICMP6_H
94*bd1f8aebSAndroid Build Coastguard Worker # include <netinet/icmp6.h>
95*bd1f8aebSAndroid Build Coastguard Worker #endif
96*bd1f8aebSAndroid Build Coastguard Worker #ifndef HAVE_STRUCT_ICMP6_NODEINFO
97*bd1f8aebSAndroid Build Coastguard Worker # include "icmp6_nodeinfo.h"
98*bd1f8aebSAndroid Build Coastguard Worker #endif
99*bd1f8aebSAndroid Build Coastguard Worker 
100*bd1f8aebSAndroid Build Coastguard Worker #include <arpa/inet.h>
101*bd1f8aebSAndroid Build Coastguard Worker 
102*bd1f8aebSAndroid Build Coastguard Worker #if defined(HAVE_GNUTLS_OPENSSL_H)
103*bd1f8aebSAndroid Build Coastguard Worker # include <gnutls/openssl.h>
104*bd1f8aebSAndroid Build Coastguard Worker #elif defined(HAVE_OPENSSL_MD5_H)
105*bd1f8aebSAndroid Build Coastguard Worker # include <openssl/md5.h>
106*bd1f8aebSAndroid Build Coastguard Worker #endif
107*bd1f8aebSAndroid Build Coastguard Worker 
108*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_SYS_UTSNAME_H
109*bd1f8aebSAndroid Build Coastguard Worker # include <sys/utsname.h>
110*bd1f8aebSAndroid Build Coastguard Worker #endif
111*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_NETDB_H
112*bd1f8aebSAndroid Build Coastguard Worker # include <netdb.h>
113*bd1f8aebSAndroid Build Coastguard Worker #endif
114*bd1f8aebSAndroid Build Coastguard Worker #include <errno.h>
115*bd1f8aebSAndroid Build Coastguard Worker 
116*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_SYSLOG_H
117*bd1f8aebSAndroid Build Coastguard Worker # include <syslog.h>
118*bd1f8aebSAndroid Build Coastguard Worker #endif
119*bd1f8aebSAndroid Build Coastguard Worker 
120*bd1f8aebSAndroid Build Coastguard Worker #include "ninfod.h"
121*bd1f8aebSAndroid Build Coastguard Worker 
122*bd1f8aebSAndroid Build Coastguard Worker #ifndef offsetof
123*bd1f8aebSAndroid Build Coastguard Worker # define offsetof(aggregate,member)	((size_t)&((aggregate *)0)->member)
124*bd1f8aebSAndroid Build Coastguard Worker #endif
125*bd1f8aebSAndroid Build Coastguard Worker 
126*bd1f8aebSAndroid Build Coastguard Worker /* Hmm,,, */
127*bd1f8aebSAndroid Build Coastguard Worker #ifndef IPV6_JOIN_GROUP
128*bd1f8aebSAndroid Build Coastguard Worker # define IPV6_JOIN_GROUP	IPV6_ADD_MEMBERSHIP
129*bd1f8aebSAndroid Build Coastguard Worker # define IPV6_LEAVE_GROUP	IPV6_DROP_MEMBERSHIP
130*bd1f8aebSAndroid Build Coastguard Worker #endif
131*bd1f8aebSAndroid Build Coastguard Worker 
132*bd1f8aebSAndroid Build Coastguard Worker /* ---------- */
133*bd1f8aebSAndroid Build Coastguard Worker /* ID */
134*bd1f8aebSAndroid Build Coastguard Worker static char *RCSID __attribute__ ((unused)) = "$USAGI: ninfod_name.c,v 1.15 2003-01-11 14:33:28 yoshfuji Exp $";
135*bd1f8aebSAndroid Build Coastguard Worker 
136*bd1f8aebSAndroid Build Coastguard Worker /* Variables */
137*bd1f8aebSAndroid Build Coastguard Worker static struct utsname utsname;
138*bd1f8aebSAndroid Build Coastguard Worker static char *uts_nodename = utsname.nodename;
139*bd1f8aebSAndroid Build Coastguard Worker 
140*bd1f8aebSAndroid Build Coastguard Worker char nodename[MAX_DNSNAME_SIZE];
141*bd1f8aebSAndroid Build Coastguard Worker static size_t nodenamelen;
142*bd1f8aebSAndroid Build Coastguard Worker 
143*bd1f8aebSAndroid Build Coastguard Worker static struct ipv6_mreq nigroup;
144*bd1f8aebSAndroid Build Coastguard Worker 
145*bd1f8aebSAndroid Build Coastguard Worker /* ---------- */
146*bd1f8aebSAndroid Build Coastguard Worker /* Functions */
check_nigroup(const struct in6_addr * addr)147*bd1f8aebSAndroid Build Coastguard Worker int check_nigroup(const struct in6_addr *addr)
148*bd1f8aebSAndroid Build Coastguard Worker {
149*bd1f8aebSAndroid Build Coastguard Worker 	return IN6_IS_ADDR_MULTICAST(&nigroup.ipv6mr_multiaddr) &&
150*bd1f8aebSAndroid Build Coastguard Worker 	       IN6_ARE_ADDR_EQUAL(&nigroup.ipv6mr_multiaddr, addr);
151*bd1f8aebSAndroid Build Coastguard Worker }
152*bd1f8aebSAndroid Build Coastguard Worker 
encode_dnsname(const char * name,char * buf,size_t buflen,int fqdn)153*bd1f8aebSAndroid Build Coastguard Worker static int encode_dnsname(const char *name,
154*bd1f8aebSAndroid Build Coastguard Worker 			  char *buf, size_t buflen,
155*bd1f8aebSAndroid Build Coastguard Worker 			  int fqdn)
156*bd1f8aebSAndroid Build Coastguard Worker {
157*bd1f8aebSAndroid Build Coastguard Worker 	size_t namelen;
158*bd1f8aebSAndroid Build Coastguard Worker 	int i;
159*bd1f8aebSAndroid Build Coastguard Worker 
160*bd1f8aebSAndroid Build Coastguard Worker 	if (buflen < 0)
161*bd1f8aebSAndroid Build Coastguard Worker 		return -1;
162*bd1f8aebSAndroid Build Coastguard Worker 
163*bd1f8aebSAndroid Build Coastguard Worker 	namelen = strlen(name);
164*bd1f8aebSAndroid Build Coastguard Worker 	if (namelen == 0)
165*bd1f8aebSAndroid Build Coastguard Worker 		return 0;
166*bd1f8aebSAndroid Build Coastguard Worker 	if (namelen > 255 || buflen < namelen+1)
167*bd1f8aebSAndroid Build Coastguard Worker 		return -1;
168*bd1f8aebSAndroid Build Coastguard Worker 
169*bd1f8aebSAndroid Build Coastguard Worker 	i = 0;
170*bd1f8aebSAndroid Build Coastguard Worker 	while(i <= namelen) {
171*bd1f8aebSAndroid Build Coastguard Worker 		const char *e;
172*bd1f8aebSAndroid Build Coastguard Worker 		int llen, ii;
173*bd1f8aebSAndroid Build Coastguard Worker 
174*bd1f8aebSAndroid Build Coastguard Worker 		e = strchr(&name[i], '.');
175*bd1f8aebSAndroid Build Coastguard Worker 		if (e == NULL)
176*bd1f8aebSAndroid Build Coastguard Worker 			e = name + namelen;
177*bd1f8aebSAndroid Build Coastguard Worker 		llen = e - &name[i];
178*bd1f8aebSAndroid Build Coastguard Worker 		if (llen == 0) {
179*bd1f8aebSAndroid Build Coastguard Worker 			if (*e)
180*bd1f8aebSAndroid Build Coastguard Worker 				return -1;
181*bd1f8aebSAndroid Build Coastguard Worker 			if (fqdn < 0)
182*bd1f8aebSAndroid Build Coastguard Worker 				return -1;
183*bd1f8aebSAndroid Build Coastguard Worker 			fqdn = 1;
184*bd1f8aebSAndroid Build Coastguard Worker 			break;
185*bd1f8aebSAndroid Build Coastguard Worker 		}
186*bd1f8aebSAndroid Build Coastguard Worker 		if (llen >= 0x40)
187*bd1f8aebSAndroid Build Coastguard Worker 			return -1;
188*bd1f8aebSAndroid Build Coastguard Worker 		buf[i] = llen;
189*bd1f8aebSAndroid Build Coastguard Worker 		for (ii = 0; ii < llen; ii++) {
190*bd1f8aebSAndroid Build Coastguard Worker 			if (!isascii(name[i+ii]))
191*bd1f8aebSAndroid Build Coastguard Worker 				return -1;
192*bd1f8aebSAndroid Build Coastguard Worker 			if (ii == 0 || ii == llen-1) {
193*bd1f8aebSAndroid Build Coastguard Worker 				if (!isalpha(name[i+ii]) && !isdigit(name[i+ii]))
194*bd1f8aebSAndroid Build Coastguard Worker 					return -1;
195*bd1f8aebSAndroid Build Coastguard Worker 			} else if (!isalnum(name[i+ii]) && name[i+ii] != '-')
196*bd1f8aebSAndroid Build Coastguard Worker 				return -1;
197*bd1f8aebSAndroid Build Coastguard Worker 			buf[i+ii+1] = isupper(name[i+ii]) ? tolower(name[i+ii]) : name[i+ii];
198*bd1f8aebSAndroid Build Coastguard Worker 		}
199*bd1f8aebSAndroid Build Coastguard Worker 		i += llen + 1;
200*bd1f8aebSAndroid Build Coastguard Worker 	}
201*bd1f8aebSAndroid Build Coastguard Worker 	if (buflen < i + 1 + !(fqdn > 0))
202*bd1f8aebSAndroid Build Coastguard Worker 		return -1;
203*bd1f8aebSAndroid Build Coastguard Worker 	buf[i++] = 0;
204*bd1f8aebSAndroid Build Coastguard Worker 	if (!(fqdn > 0))
205*bd1f8aebSAndroid Build Coastguard Worker 		buf[i++] = 0;
206*bd1f8aebSAndroid Build Coastguard Worker 	return i;
207*bd1f8aebSAndroid Build Coastguard Worker }
208*bd1f8aebSAndroid Build Coastguard Worker 
compare_dnsname(const char * s,size_t slen,const char * n,size_t nlen)209*bd1f8aebSAndroid Build Coastguard Worker static int compare_dnsname(const char *s, size_t slen,
210*bd1f8aebSAndroid Build Coastguard Worker 			   const char *n, size_t nlen)
211*bd1f8aebSAndroid Build Coastguard Worker {
212*bd1f8aebSAndroid Build Coastguard Worker 	const char *s0 = s, *n0 = n;
213*bd1f8aebSAndroid Build Coastguard Worker 	int done = 0, retcode = 0;
214*bd1f8aebSAndroid Build Coastguard Worker 	if (slen < 1 || nlen < 1)
215*bd1f8aebSAndroid Build Coastguard Worker 		return -1;	/* invalid length */
216*bd1f8aebSAndroid Build Coastguard Worker 	/* simple case */
217*bd1f8aebSAndroid Build Coastguard Worker 	if (slen == nlen && memcmp(s, n, slen) == 0)
218*bd1f8aebSAndroid Build Coastguard Worker 		return 0;
219*bd1f8aebSAndroid Build Coastguard Worker 	if (*(s0 + slen - 1) || *(n0 + nlen - 1))
220*bd1f8aebSAndroid Build Coastguard Worker 		return -1;	/* invalid termination */
221*bd1f8aebSAndroid Build Coastguard Worker 	while (s < s0 + slen && n < n0 + nlen) {
222*bd1f8aebSAndroid Build Coastguard Worker 		if (*s >= 0x40 || *n >= 0x40)
223*bd1f8aebSAndroid Build Coastguard Worker 			return -1;	/* DNS compression is not allowed here */
224*bd1f8aebSAndroid Build Coastguard Worker 		if (s + *s + 1 > s0 + slen || n + *n + 1 > n0 + nlen)
225*bd1f8aebSAndroid Build Coastguard Worker 			return -1;	/* overrun */
226*bd1f8aebSAndroid Build Coastguard Worker 		if (*s == '\0') {
227*bd1f8aebSAndroid Build Coastguard Worker 			if (s == s0 + slen - 1)
228*bd1f8aebSAndroid Build Coastguard Worker 				break;	/* FQDN */
229*bd1f8aebSAndroid Build Coastguard Worker 			else if (s + 1 == s0 + slen - 1)
230*bd1f8aebSAndroid Build Coastguard Worker 				return retcode;	/* truncated */
231*bd1f8aebSAndroid Build Coastguard Worker 			else
232*bd1f8aebSAndroid Build Coastguard Worker 				return -1;	/* more than one subject */
233*bd1f8aebSAndroid Build Coastguard Worker 		}
234*bd1f8aebSAndroid Build Coastguard Worker 		if (!done) {
235*bd1f8aebSAndroid Build Coastguard Worker 			if (*n == '\0') {
236*bd1f8aebSAndroid Build Coastguard Worker 				if (n == n0 + nlen - 1) {
237*bd1f8aebSAndroid Build Coastguard Worker 					done = 1;	/* FQDN */
238*bd1f8aebSAndroid Build Coastguard Worker 				} else if (n + 1 == n0 + nlen - 1) {
239*bd1f8aebSAndroid Build Coastguard Worker 					retcode = 1;	// trunc
240*bd1f8aebSAndroid Build Coastguard Worker 					done = 1;
241*bd1f8aebSAndroid Build Coastguard Worker 				} else
242*bd1f8aebSAndroid Build Coastguard Worker 					return -1;
243*bd1f8aebSAndroid Build Coastguard Worker 			} else {
244*bd1f8aebSAndroid Build Coastguard Worker 				if (*s != *n) {
245*bd1f8aebSAndroid Build Coastguard Worker 					done = 1;
246*bd1f8aebSAndroid Build Coastguard Worker 					retcode = 1;
247*bd1f8aebSAndroid Build Coastguard Worker 				} else {
248*bd1f8aebSAndroid Build Coastguard Worker 					if (memcmp(s+1, n+1, *s)) {
249*bd1f8aebSAndroid Build Coastguard Worker 						done = 1;
250*bd1f8aebSAndroid Build Coastguard Worker 						retcode = 1;
251*bd1f8aebSAndroid Build Coastguard Worker 					}
252*bd1f8aebSAndroid Build Coastguard Worker 				}
253*bd1f8aebSAndroid Build Coastguard Worker 			}
254*bd1f8aebSAndroid Build Coastguard Worker 		}
255*bd1f8aebSAndroid Build Coastguard Worker 		s += *s + 1;
256*bd1f8aebSAndroid Build Coastguard Worker 		n += done ? 0 : (*n + 1);
257*bd1f8aebSAndroid Build Coastguard Worker 	}
258*bd1f8aebSAndroid Build Coastguard Worker 	return retcode;
259*bd1f8aebSAndroid Build Coastguard Worker }
260*bd1f8aebSAndroid Build Coastguard Worker 
nodeinfo_group(const char * dnsname,int namelen,struct in6_addr * nigroup)261*bd1f8aebSAndroid Build Coastguard Worker static int nodeinfo_group(const char *dnsname, int namelen,
262*bd1f8aebSAndroid Build Coastguard Worker 			  struct in6_addr *nigroup)
263*bd1f8aebSAndroid Build Coastguard Worker {
264*bd1f8aebSAndroid Build Coastguard Worker 	MD5_CTX ctxt;
265*bd1f8aebSAndroid Build Coastguard Worker 	unsigned char digest[16];
266*bd1f8aebSAndroid Build Coastguard Worker 
267*bd1f8aebSAndroid Build Coastguard Worker 	if (!dnsname || !nigroup)
268*bd1f8aebSAndroid Build Coastguard Worker 		return -1;
269*bd1f8aebSAndroid Build Coastguard Worker 
270*bd1f8aebSAndroid Build Coastguard Worker 	MD5_Init(&ctxt);
271*bd1f8aebSAndroid Build Coastguard Worker 	MD5_Update(&ctxt, dnsname, *dnsname);
272*bd1f8aebSAndroid Build Coastguard Worker 	MD5_Final(digest, &ctxt);
273*bd1f8aebSAndroid Build Coastguard Worker 
274*bd1f8aebSAndroid Build Coastguard Worker #ifdef s6_addr32
275*bd1f8aebSAndroid Build Coastguard Worker 	nigroup->s6_addr32[0] = htonl(0xff020000);
276*bd1f8aebSAndroid Build Coastguard Worker 	nigroup->s6_addr32[1] = 0;
277*bd1f8aebSAndroid Build Coastguard Worker 	nigroup->s6_addr32[2] = htonl(0x00000002);
278*bd1f8aebSAndroid Build Coastguard Worker #else
279*bd1f8aebSAndroid Build Coastguard Worker 	memset(nigroup, 0, sizeof(*nigroup));
280*bd1f8aebSAndroid Build Coastguard Worker 	nigroup->s6_addr[ 0] = 0xff;
281*bd1f8aebSAndroid Build Coastguard Worker 	nigroup->s6_addr[ 1] = 0x02;
282*bd1f8aebSAndroid Build Coastguard Worker 	nigroup->s6_addr[11] = 0x02;
283*bd1f8aebSAndroid Build Coastguard Worker #endif
284*bd1f8aebSAndroid Build Coastguard Worker 	memcpy(&nigroup->s6_addr[12], digest, 4);
285*bd1f8aebSAndroid Build Coastguard Worker 
286*bd1f8aebSAndroid Build Coastguard Worker 	return 0;
287*bd1f8aebSAndroid Build Coastguard Worker }
288*bd1f8aebSAndroid Build Coastguard Worker 
289*bd1f8aebSAndroid Build Coastguard Worker /* ---------- */
init_nodeinfo_nodename(int forced)290*bd1f8aebSAndroid Build Coastguard Worker void init_nodeinfo_nodename(int forced)
291*bd1f8aebSAndroid Build Coastguard Worker {
292*bd1f8aebSAndroid Build Coastguard Worker 	struct utsname newname;
293*bd1f8aebSAndroid Build Coastguard Worker 	int len;
294*bd1f8aebSAndroid Build Coastguard Worker 	int changed = 0;
295*bd1f8aebSAndroid Build Coastguard Worker 
296*bd1f8aebSAndroid Build Coastguard Worker 	DEBUG(LOG_DEBUG, "%s()\n", __func__);
297*bd1f8aebSAndroid Build Coastguard Worker 
298*bd1f8aebSAndroid Build Coastguard Worker 	uname(&newname);
299*bd1f8aebSAndroid Build Coastguard Worker 	changed = strcmp(newname.nodename, utsname.nodename);
300*bd1f8aebSAndroid Build Coastguard Worker 
301*bd1f8aebSAndroid Build Coastguard Worker 	if (!changed && !forced)
302*bd1f8aebSAndroid Build Coastguard Worker 		return;
303*bd1f8aebSAndroid Build Coastguard Worker 
304*bd1f8aebSAndroid Build Coastguard Worker 	memcpy(&utsname, &newname, sizeof(newname));
305*bd1f8aebSAndroid Build Coastguard Worker 
306*bd1f8aebSAndroid Build Coastguard Worker 	/* leave old group */
307*bd1f8aebSAndroid Build Coastguard Worker 	if ((changed || forced) && !IN6_IS_ADDR_UNSPECIFIED(&nigroup.ipv6mr_multiaddr)) {
308*bd1f8aebSAndroid Build Coastguard Worker 		if (setsockopt(sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &nigroup, sizeof(nigroup)) < 0) {
309*bd1f8aebSAndroid Build Coastguard Worker #if ENABLE_DEBUG
310*bd1f8aebSAndroid Build Coastguard Worker 			char niaddrbuf[INET6_ADDRSTRLEN];
311*bd1f8aebSAndroid Build Coastguard Worker 			if (inet_ntop(AF_INET6, &nigroup, niaddrbuf, sizeof(niaddrbuf)) == NULL)
312*bd1f8aebSAndroid Build Coastguard Worker 				strcpy(niaddrbuf, "???");
313*bd1f8aebSAndroid Build Coastguard Worker #endif
314*bd1f8aebSAndroid Build Coastguard Worker 			DEBUG(LOG_WARNING,
315*bd1f8aebSAndroid Build Coastguard Worker 			      "%s(): failed to leave group %s.\n",
316*bd1f8aebSAndroid Build Coastguard Worker 			      __func__, niaddrbuf);
317*bd1f8aebSAndroid Build Coastguard Worker 			memset(&nigroup, 0, sizeof(nigroup));
318*bd1f8aebSAndroid Build Coastguard Worker 		}
319*bd1f8aebSAndroid Build Coastguard Worker 	}
320*bd1f8aebSAndroid Build Coastguard Worker 
321*bd1f8aebSAndroid Build Coastguard Worker 	len = encode_dnsname(uts_nodename,
322*bd1f8aebSAndroid Build Coastguard Worker 			     nodename,
323*bd1f8aebSAndroid Build Coastguard Worker 			     sizeof(nodename),
324*bd1f8aebSAndroid Build Coastguard Worker 			     0);
325*bd1f8aebSAndroid Build Coastguard Worker 
326*bd1f8aebSAndroid Build Coastguard Worker 	/* setup ni reply */
327*bd1f8aebSAndroid Build Coastguard Worker 	nodenamelen = len > 0 ? len : 0;
328*bd1f8aebSAndroid Build Coastguard Worker 
329*bd1f8aebSAndroid Build Coastguard Worker 	/* setup ni group */
330*bd1f8aebSAndroid Build Coastguard Worker 	if (changed || forced) {
331*bd1f8aebSAndroid Build Coastguard Worker 		if (nodenamelen) {
332*bd1f8aebSAndroid Build Coastguard Worker 			memset(&nigroup, 0, sizeof(nigroup));
333*bd1f8aebSAndroid Build Coastguard Worker 			nodeinfo_group(nodename, len, &nigroup.ipv6mr_multiaddr);
334*bd1f8aebSAndroid Build Coastguard Worker 			nigroup.ipv6mr_interface = 0;
335*bd1f8aebSAndroid Build Coastguard Worker 			if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &nigroup, sizeof(nigroup)) < 0) {
336*bd1f8aebSAndroid Build Coastguard Worker #if ENABLE_DEBUG
337*bd1f8aebSAndroid Build Coastguard Worker 				char niaddrbuf[INET6_ADDRSTRLEN];
338*bd1f8aebSAndroid Build Coastguard Worker 				if (inet_ntop(AF_INET6, &nigroup, niaddrbuf, sizeof(niaddrbuf)) == NULL)
339*bd1f8aebSAndroid Build Coastguard Worker 					strcpy(niaddrbuf, "???");
340*bd1f8aebSAndroid Build Coastguard Worker #endif
341*bd1f8aebSAndroid Build Coastguard Worker 				DEBUG(LOG_WARNING,
342*bd1f8aebSAndroid Build Coastguard Worker 				      "%s(): failed to join group %s.\n",
343*bd1f8aebSAndroid Build Coastguard Worker 				      __func__, niaddrbuf);
344*bd1f8aebSAndroid Build Coastguard Worker 				memset(&nigroup, 0, sizeof(nigroup));
345*bd1f8aebSAndroid Build Coastguard Worker 			}
346*bd1f8aebSAndroid Build Coastguard Worker 		} else {
347*bd1f8aebSAndroid Build Coastguard Worker 			memset(&nigroup, 0, sizeof(nigroup));
348*bd1f8aebSAndroid Build Coastguard Worker 		}
349*bd1f8aebSAndroid Build Coastguard Worker 	}
350*bd1f8aebSAndroid Build Coastguard Worker 
351*bd1f8aebSAndroid Build Coastguard Worker 	return;
352*bd1f8aebSAndroid Build Coastguard Worker }
353*bd1f8aebSAndroid Build Coastguard Worker 
354*bd1f8aebSAndroid Build Coastguard Worker /* ---------- */
355*bd1f8aebSAndroid Build Coastguard Worker /* nodename */
pr_nodeinfo_nodename(CHECKANDFILL_ARGS)356*bd1f8aebSAndroid Build Coastguard Worker int pr_nodeinfo_nodename(CHECKANDFILL_ARGS)
357*bd1f8aebSAndroid Build Coastguard Worker {
358*bd1f8aebSAndroid Build Coastguard Worker 	DEBUG(LOG_DEBUG, "%s()\n", __func__);
359*bd1f8aebSAndroid Build Coastguard Worker 
360*bd1f8aebSAndroid Build Coastguard Worker 	if (subject) {
361*bd1f8aebSAndroid Build Coastguard Worker 		if (!nodenamelen ||
362*bd1f8aebSAndroid Build Coastguard Worker 		    compare_dnsname(subject, subjlen,
363*bd1f8aebSAndroid Build Coastguard Worker 				    nodename,
364*bd1f8aebSAndroid Build Coastguard Worker 				    nodenamelen))
365*bd1f8aebSAndroid Build Coastguard Worker 			return 1;
366*bd1f8aebSAndroid Build Coastguard Worker 		if (subj_if)
367*bd1f8aebSAndroid Build Coastguard Worker 			*subj_if = p->pktinfo.ipi6_ifindex;
368*bd1f8aebSAndroid Build Coastguard Worker 	}
369*bd1f8aebSAndroid Build Coastguard Worker 
370*bd1f8aebSAndroid Build Coastguard Worker 	if (reply) {
371*bd1f8aebSAndroid Build Coastguard Worker 		uint32_t ttl = 0;
372*bd1f8aebSAndroid Build Coastguard Worker 
373*bd1f8aebSAndroid Build Coastguard Worker 		p->reply.ni_type = ICMP6_NI_REPLY;
374*bd1f8aebSAndroid Build Coastguard Worker 		p->reply.ni_code = ICMP6_NI_SUCCESS;
375*bd1f8aebSAndroid Build Coastguard Worker 		p->reply.ni_cksum = 0;
376*bd1f8aebSAndroid Build Coastguard Worker 		p->reply.ni_qtype = htons(NI_QTYPE_DNSNAME);
377*bd1f8aebSAndroid Build Coastguard Worker 		p->reply.ni_flags = 0;
378*bd1f8aebSAndroid Build Coastguard Worker 
379*bd1f8aebSAndroid Build Coastguard Worker 		p->replydatalen = nodenamelen ? sizeof(ttl)+nodenamelen : 0;
380*bd1f8aebSAndroid Build Coastguard Worker 		p->replydata = nodenamelen ? ni_malloc(p->replydatalen) : NULL;
381*bd1f8aebSAndroid Build Coastguard Worker 		if (p->replydata) {
382*bd1f8aebSAndroid Build Coastguard Worker 			memcpy(p->replydata, &ttl, sizeof(ttl));
383*bd1f8aebSAndroid Build Coastguard Worker 			memcpy(p->replydata + sizeof(ttl), &nodename, nodenamelen);
384*bd1f8aebSAndroid Build Coastguard Worker 		}
385*bd1f8aebSAndroid Build Coastguard Worker 	}
386*bd1f8aebSAndroid Build Coastguard Worker 
387*bd1f8aebSAndroid Build Coastguard Worker 	return 0;
388*bd1f8aebSAndroid Build Coastguard Worker }
389*bd1f8aebSAndroid Build Coastguard Worker 
390