1313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* $USAGI: ninfod_addrs.c,v 1.18 2003-07-16 09:49:01 yoshfuji Exp $ */
2313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*
3313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Copyright (C) 2002 USAGI/WIDE Project.
4313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * All rights reserved.
5313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *
6313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Redistribution and use in source and binary forms, with or without
7313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * modification, are permitted provided that the following conditions
8313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * are met:
9313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 1. Redistributions of source code must retain the above copyright
10313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    notice, this list of conditions and the following disclaimer.
11313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 2. Redistributions in binary form must reproduce the above copyright
12313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    notice, this list of conditions and the following disclaimer in the
13313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    documentation and/or other materials provided with the distribution.
14313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 3. Neither the name of the project nor the names of its contributors
15313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    may be used to endorse or promote products derived from this software
16313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    without specific prior written permission.
17313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *
18313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * SUCH DAMAGE.
29313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
30313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*
31313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Author:
32313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 	YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
33313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
34313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
35313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_CONFIG_H
36313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include "config.h"
37313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
38313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
39313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_SYS_TYPES_H
40313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <sys/types.h>
41313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
42313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
43313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if STDC_HEADERS
44313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <stdio.h>
45313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <stdlib.h>
46313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <stddef.h>
47313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else
48313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# if HAVE_STDLIB_H
49313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#  include <stdlib.h>
50313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# endif
51313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
52313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_STRING_H
53313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# if !STDC_HEADERS && HAVE_MEMORY_H
54313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#  include <memory.h>
55313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# endif
56313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <string.h>
57313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
58313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_STRINGS_H
59313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <strings.h>
60313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
61313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_INTTYPES_H
62313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <inttypes.h>
63313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else
64313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# if HAVE_STDINT_H
65313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#  include <stdint.h>
66313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# endif
67313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
68313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_UNISTD_H
69313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <unistd.h>
70313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
71313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
72313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if TIME_WITH_SYS_TIME
73313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <sys/time.h>
74313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <time.h>
75313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else
76313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# if HAVE_SYS_TIME_H
77313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#  include <sys/time.h>
78313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# else
79313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#  include <time.h>
80313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# endif
81313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
82313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
83313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_SYS_UIO_H
84313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/uio.h>
85313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
86313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
87313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/socket.h>
88313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_LINUX_RTNETLINK_H
89313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <asm/types.h>
90313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/rtnetlink.h>
91313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
92313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
93313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_NETINET_IN_H
94313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <netinet/in.h>
95313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
96313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
97313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_NETINET_IP6_H
98313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <netinet/ip6.h>
99313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
100313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
101313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_NETINET_ICMP6_H
102313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <netinet/icmp6.h>
103313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
104313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef HAVE_STRUCT_ICMP6_NODEINFO
105313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include "icmp6_nodeinfo.h"
106313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
107313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
108313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_NETDB_H
109313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <netdb.h>
110313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
111313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <errno.h>
112313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
113313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_SYSLOG_H
114313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <syslog.h>
115313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
116313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
117313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include "ninfod.h"
118313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include "ni_ifaddrs.h"
119313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
120313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef offsetof
121313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# define offsetof(aggregate,member)	((size_t)&((aggregate *)0)->member)
122313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
123313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
124313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */
125313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ID */
126313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic char *RCSID __attribute__ ((unused)) = "$USAGI: ninfod_addrs.c,v 1.18 2003-07-16 09:49:01 yoshfuji Exp $";
127313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
128313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */
129313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ipv6 address */
130313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid init_nodeinfo_ipv6addr(INIT_ARGS)
131313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
132313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	DEBUG(LOG_DEBUG, "%s()\n", __func__);
133313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return;
134313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
135313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
136313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint filter_ipv6addr(const struct in6_addr *ifaddr, unsigned int flags)
137313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
138313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (IN6_IS_ADDR_UNSPECIFIED(ifaddr) ||
139313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	    IN6_IS_ADDR_LOOPBACK(ifaddr)) {
140313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return 1;
141313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	} else if (IN6_IS_ADDR_V4COMPAT(ifaddr) ||
142313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		   IN6_IS_ADDR_V4MAPPED(ifaddr)) {
143313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return !(flags & NI_NODEADDR_FLAG_COMPAT);
144313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	} else if (IN6_IS_ADDR_LINKLOCAL(ifaddr)) {
145313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return !(flags & NI_NODEADDR_FLAG_LINKLOCAL);
146313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	} else if (IN6_IS_ADDR_SITELOCAL(ifaddr)) {
147313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return !(flags & NI_NODEADDR_FLAG_SITELOCAL);
148313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
149313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return !(flags & NI_NODEADDR_FLAG_GLOBAL);
150313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
151313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
152313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint pr_nodeinfo_ipv6addr(CHECKANDFILL_ARGS)
153313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
154313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	struct ni_ifaddrs *ifa0;
155313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	unsigned int ifindex = 0;
156313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
157313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	DEBUG(LOG_DEBUG, "%s()\n", __func__);
158313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
159313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (subject && subjlen != sizeof(struct in6_addr)) {
160313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		DEBUG(LOG_INFO,
161313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		      "%s(): invalid subject length %zu for IPv6 Address Subject\n",
162313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		      __func__, subjlen);
163313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return 1;
164313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
165313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (ni_ifaddrs(&ifa0, AF_INET6))
166313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return -1;	/* failed to get addresses */
167313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
168313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	/* pass 0: consider subject and determine subjected interface */
169313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (subject) {
170313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		struct ni_ifaddrs *ifa;
171313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
172313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		for (ifa = ifa0; ifa; ifa = ifa->ifa_next) {
173313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!ifa->ifa_addr)
174313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
175313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_flags & (IFA_F_TENTATIVE|IFA_F_SECONDARY))
176313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
177313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!ifindex &&
178313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			    IN6_ARE_ADDR_EQUAL(&p->pktinfo.ipi6_addr,
179313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti					       (struct in6_addr *)subject)) {
180313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				/*
181313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 * if subject is equal to destination
182313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 * address, receiving interface is
183313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 * the candidate subject interface.
184313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 */
185313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				ifindex = p->pktinfo.ipi6_ifindex;
186313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			}
187313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!IN6_IS_ADDR_LOOPBACK((struct in6_addr *)subject) &&
188313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			    IN6_ARE_ADDR_EQUAL((struct in6_addr *)ifa->ifa_addr,
189313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti					       (struct in6_addr *)subject)) {
190313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				/*
191313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 * address is assigned on some interface.
192313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 * if multiple interfaces have the same interface,
193313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 *  1) prefer receiving interface
194313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 *  2) use first found one
195313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 */
196313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				if (!ifindex ||
197313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				    (p->pktinfo.ipi6_ifindex == ifindex))
198313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti					ifindex = ifa->ifa_ifindex;
199313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			}
200313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
201313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (!ifindex) {
202313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			ni_freeifaddrs(ifa0);
203313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			return 1;	/* subject not found */
204313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
205313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (subj_if)
206313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			*subj_if = ifindex;
207313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	} else {
208313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		ifindex = subj_if ? *subj_if : 0;
209313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (ifindex == 0)
210313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			ifindex = p->pktinfo.ipi6_ifindex;
211313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (ifindex == 0) {
212313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			ni_freeifaddrs(ifa0);
213313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			return 1;	/* XXX */
214313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
215313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
216313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
217313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (reply) {
218313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		struct ni_ifaddrs *ifa;
219313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		unsigned int addrs0 = 0, paddrs0 = 0;
220313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		unsigned int addrs, paddrs = 0, daddrs = 0;
221313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
222313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		flags &= ~NI_NODEADDR_FLAG_TRUNCATE;
223313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
224313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		/* pass 1: count addresses and preferred addresses to be returned */
225313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		for (ifa = ifa0; ifa; ifa = ifa->ifa_next) {
226313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!ifa->ifa_addr)
227313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
228313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_flags & (IFA_F_TENTATIVE|IFA_F_SECONDARY))
229313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
230313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!(flags & NI_NODEADDR_FLAG_ALL) &&
231313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			    ifa->ifa_ifindex != ifindex)
232313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
233313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (filter_ipv6addr((struct in6_addr *)ifa->ifa_addr, flags))
234313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
235313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
236313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (addrs0 + 1 >= ((MAX_REPLY_SIZE - sizeof(struct icmp6_nodeinfo)) / (sizeof(uint32_t) + sizeof(struct in6_addr)))) {
237313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				flags |= ~NI_NODEADDR_FLAG_TRUNCATE;
238313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				break;
239313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			}
240313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
241313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			addrs0++;
242313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!(ifa->ifa_flags & IFA_F_DEPRECATED))
243313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				paddrs0++;
244313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
245313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
246313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_type = ICMP6_NI_REPLY;
247313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_code = ICMP6_NI_SUCCESS;
248313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_cksum = 0;
249313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_qtype = htons(NI_QTYPE_NODEADDR);
250313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_flags = flags&(NI_NODEADDR_FLAG_COMPAT|
251313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti					   NI_NODEADDR_FLAG_LINKLOCAL|
252313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti					   NI_NODEADDR_FLAG_SITELOCAL|
253313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti					   NI_NODEADDR_FLAG_GLOBAL);
254313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
255313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		/* pass 2: store addresses */
256313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->replydatalen = (sizeof(uint32_t)+sizeof(struct in6_addr)) * addrs0;
257313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->replydata = p->replydatalen ? ni_malloc(p->replydatalen) : NULL;
258313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
259313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (p->replydatalen && !p->replydata) {
260313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			p->reply.ni_flags |= NI_NODEADDR_FLAG_TRUNCATE;
261313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			addrs0 = paddrs0 = 0;
262313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
263313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
264313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		for (ifa = ifa0, addrs = 0;
265313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		     ifa && addrs < addrs0;
266313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		     ifa = ifa->ifa_next) {
267313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			char *cp;
268313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			uint32_t ttl;
269313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
270313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!ifa->ifa_addr)
271313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
272313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_flags & (IFA_F_TENTATIVE|IFA_F_SECONDARY))
273313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
274313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!(flags & NI_NODEADDR_FLAG_ALL) &&
275313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			    ((subj_if && *subj_if) ? (ifa->ifa_ifindex != *subj_if) :
276313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti						     (ifa->ifa_ifindex != p->pktinfo.ipi6_ifindex)))
277313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
278313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (filter_ipv6addr((struct in6_addr *)ifa->ifa_addr, flags))
279313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
280313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
281313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_TTL
282313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_cacheinfo) {
283313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				ttl = ifa->ifa_cacheinfo->ifa_valid > 0x7fffffff ?
284313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				      htonl(0x7fffffff) : htonl(ifa->ifa_cacheinfo->ifa_valid);
285313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			} else {
286313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				ttl = (ifa->ifa_flags & IFA_F_PERMANENT) ? htonl(0x7fffffff) : 0;
287313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			}
288313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else
289313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			ttl = 0;
290313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
291313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
292313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			cp = p->replydata +
293313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			     (sizeof(uint32_t)+sizeof(struct in6_addr)) * (ifa->ifa_flags & IFA_F_DEPRECATED ? paddrs0+daddrs : paddrs);
294313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			memcpy(cp, &ttl, sizeof(ttl));
295313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			memcpy(cp + sizeof(ttl), ifa->ifa_addr, sizeof(struct in6_addr));
296313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
297313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			addrs++;
298313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_flags & IFA_F_DEPRECATED)
299313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				daddrs++;
300313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			else
301313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				paddrs++;
302313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
303313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
304313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
305313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	ni_freeifaddrs(ifa0);
306313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return 0;
307313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
308313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
309313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ipv4 address */
310313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid init_nodeinfo_ipv4addr(INIT_ARGS)
311313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
312313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	DEBUG(LOG_DEBUG, "%s()\n", __func__);
313313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return;
314313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
315313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
316313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint filter_ipv4addr(const struct in_addr *ifaddr, unsigned int flags)
317313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
318313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return 0;
319313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
320313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
321313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint pr_nodeinfo_ipv4addr(CHECKANDFILL_ARGS)
322313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
323313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	struct ni_ifaddrs *ifa0;
324313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	unsigned int ifindex = 0;
325313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
326313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	DEBUG(LOG_DEBUG, "%s()\n", __func__);
327313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
328313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (subject && subjlen != sizeof(struct in_addr)) {
329313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		DEBUG(LOG_INFO,
330313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		      "%s(): invalid subject length %zu for IPv4 Address Subject\n",
331313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		      __func__, subjlen);
332313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return 1;
333313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
334313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (ni_ifaddrs(&ifa0, AF_INET))
335313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return -1;	/* failed to get addresses */
336313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
337313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	/* pass 0: consider subject and determine subjected interface */
338313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (subject) {
339313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		struct ni_ifaddrs *ifa;
340313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
341313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		for (ifa = ifa0; ifa; ifa = ifa->ifa_next) {
342313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!ifa->ifa_addr)
343313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
344313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_flags & (IFA_F_TENTATIVE|IFA_F_SECONDARY))
345313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
346313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if ((((struct in_addr *)subject)->s_addr != htonl(INADDR_LOOPBACK)) &&
347313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			    memcmp((struct in_addr *)ifa->ifa_addr,
348313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				   (struct in_addr *)subject,
349313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				   sizeof(struct in_addr)) == 0) {
350313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				/*
351313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 * address is assigned on some interface.
352313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 * if multiple interfaces have the same interface,
353313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 *  1) prefer receiving interface
354313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 *  2) use first found one
355313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				 */
356313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				if (!ifindex ||
357313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				    (p->pktinfo.ipi6_ifindex == ifindex))
358313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti					ifindex = ifa->ifa_ifindex;
359313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			}
360313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
361313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (!ifindex) {
362313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			ni_freeifaddrs(ifa0);
363313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			return 1;	/* subject not found */
364313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
365313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (subj_if)
366313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			*subj_if = ifindex;
367313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	} else {
368313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		ifindex = subj_if ? *subj_if : 0;
369313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (ifindex == 0)
370313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			ifindex = p->pktinfo.ipi6_ifindex;
371313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (ifindex == 0) {
372313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			ni_freeifaddrs(ifa0);
373313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			return 1;	/* XXX */
374313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
375313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
376313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
377313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (reply) {
378313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		struct ni_ifaddrs *ifa;
379313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		unsigned int addrs0 = 0, paddrs0 = 0;
380313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		unsigned int addrs, paddrs = 0, daddrs = 0;
381313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
382313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		flags &= ~NI_IPV4ADDR_FLAG_TRUNCATE;
383313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
384313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		/* pass 1: count addresses and preferred addresses to be returned */
385313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		for (ifa = ifa0; ifa; ifa = ifa->ifa_next) {
386313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!ifa->ifa_addr)
387313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
388313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if 1	/* not used in kernel */
389313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_flags & (IFA_F_TENTATIVE))
390313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
391313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
392313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!(flags & NI_NODEADDR_FLAG_ALL) &&
393313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			    ((subj_if && *subj_if) ? (ifa->ifa_ifindex != *subj_if) :
394313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti						     (ifa->ifa_ifindex != p->pktinfo.ipi6_ifindex)))
395313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
396313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (filter_ipv4addr((struct in_addr *)ifa->ifa_addr, flags))
397313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
398313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
399313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (addrs0 + 1 >= ((MAX_REPLY_SIZE - sizeof(struct icmp6_nodeinfo)) / (sizeof(uint32_t) + sizeof(struct in_addr)))) {
400313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				flags |= NI_IPV4ADDR_FLAG_TRUNCATE;
401313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				break;
402313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			}
403313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
404313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			addrs0++;
405313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!(ifa->ifa_flags & IFA_F_DEPRECATED))
406313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				paddrs0++;
407313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
408313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
409313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_type = ICMP6_NI_REPLY;
410313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_code = ICMP6_NI_SUCCESS;
411313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_cksum = 0;
412313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_qtype = htons(NI_QTYPE_IPV4ADDR);
413313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->reply.ni_flags = flags & NI_IPV4ADDR_FLAG_ALL;
414313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
415313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		/* pass 2: store addresses */
416313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->replydatalen = (sizeof(uint32_t)+sizeof(struct in_addr)) * addrs0;
417313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		p->replydata = addrs0 ? ni_malloc(p->replydatalen) : NULL;
418313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
419313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (p->replydatalen && !p->replydata) {
420313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			p->reply.ni_flags |= NI_NODEADDR_FLAG_TRUNCATE;
421313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			addrs0 = paddrs0 = 0;
422313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
423313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
424313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		for (ifa = ifa0, addrs = 0;
425313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		     ifa && addrs < addrs0;
426313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		     ifa = ifa->ifa_next) {
427313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			char *cp;
428313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			uint32_t ttl;
429313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
430313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!ifa->ifa_addr)
431313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
432313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if 1	/* not used in kernel */
433313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_flags & (IFA_F_TENTATIVE))
434313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
435313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
436313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (!(flags & NI_NODEADDR_FLAG_ALL) &&
437313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			    (ifa->ifa_ifindex != ifindex))
438313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
439313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (filter_ipv4addr((struct in_addr *)ifa->ifa_addr, flags))
440313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				continue;
441313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
442313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_TTL
443313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_cacheinfo) {
444313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				ttl = ifa->ifa_cacheinfo->ifa_valid > 0x7fffffff ?
445313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				      htonl(0x7fffffff) : htonl(ifa->ifa_cacheinfo->ifa_valid);
446313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			} else {
447313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				ttl = 0;	/*XXX*/
448313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			}
449313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else
450313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			ttl = 0;
451313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
452313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
453313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			cp = (p->replydata +
454313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			      (sizeof(uint32_t)+sizeof(struct in_addr)) * (ifa->ifa_flags & IFA_F_DEPRECATED ? paddrs0+daddrs : paddrs));
455313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			memcpy(cp, &ttl, sizeof(ttl));
456313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			memcpy(cp + sizeof(ttl), ifa->ifa_addr, sizeof(struct in_addr));
457313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
458313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			addrs++;
459313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (ifa->ifa_flags & IFA_F_DEPRECATED)
460313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				daddrs++;
461313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			else
462313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				paddrs++;
463313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
464313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
465313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
466313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	ni_freeifaddrs(ifa0);
467313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return 0;
468313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
469313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
470