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