1313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* $USAGI: ninfod_core.c,v 1.29 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#if STDC_HEADERS 43313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <stdio.h> 44313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <stdlib.h> 45313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <stddef.h> 46313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else 47313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# if HAVE_STDLIB_H 48313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <stdlib.h> 49313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# endif 50313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 51313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_THREADS && HAVE_PTHREAD_H 52313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <pthread.h> 53313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 54313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_STRING_H 55313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# if !STDC_HEADERS && HAVE_MEMORY_H 56313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <memory.h> 57313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# endif 58313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <string.h> 59313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 60313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_STRINGS_H 61313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <strings.h> 62313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 63313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_INTTYPES_H 64313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <inttypes.h> 65313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else 66313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# if HAVE_STDINT_H 67313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <stdint.h> 68313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# endif 69313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 70313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_UNISTD_H 71313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <unistd.h> 72313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 73313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 74313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if TIME_WITH_SYS_TIME 75313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <sys/time.h> 76313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <time.h> 77313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else 78313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# if HAVE_SYS_TIME_H 79313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <sys/time.h> 80313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# else 81313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <time.h> 82313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# endif 83313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 84313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 85313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_SYS_UIO_H 86313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/uio.h> 87313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 88313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 89313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_NETINET_IN_H 90313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <netinet/in.h> 91313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 92313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 93313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_NETINET_ICMP6_H 94313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <netinet/icmp6.h> 95313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 96313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef HAVE_STRUCT_ICMP6_NODEINFO 97313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include "icmp6_nodeinfo.h" 98313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 99313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 100313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_NETDB_H 101313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <netdb.h> 102313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 103313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <errno.h> 104313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 105313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_SYSLOG_H 106313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <syslog.h> 107313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 108313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 109313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include "ninfod.h" 110313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 111313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef offsetof 112313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# define offsetof(aggregate,member) ((size_t)&((aggregate *)0)->member) 113313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 114313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 115313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 116313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 117313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 118313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ID */ 119313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic char *RCSID __attribute__ ((unused)) = "$USAGI: ninfod_core.c,v 1.29 2003-07-16 09:49:01 yoshfuji Exp $"; 120313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 121313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* Variables */ 122313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint initialized = 0; 123313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 124313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_THREADS && HAVE_LIBPTHREAD 125313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittipthread_attr_t pattr; 126313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 127313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 128313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic uint32_t suptypes[(MAX_SUPTYPES+31)>>5]; 129313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic size_t suptypes_len; 130313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 131313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 132313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct subjinfo { 133313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti uint8_t code; 134313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *name; 135313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int (*checksubj)(CHECKANDFILL_ARGS); 136313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int (*init)(INIT_ARGS); 137313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 138313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 139313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic struct subjinfo subjinfo_table [] = { 140313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti [ICMP6_NI_SUBJ_IPV6] = { 141313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .code = ICMP6_NI_SUBJ_IPV6, 142313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "IPv6", 143313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti //.init = init_nodeinfo_ipv6addr, 144313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .checksubj = pr_nodeinfo_ipv6addr, 145313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }, 146313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti [ICMP6_NI_SUBJ_FQDN] = { 147313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .code = ICMP6_NI_SUBJ_FQDN, 148313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "FQDN", 149313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti //.init = init_nodeinfo_nodename, 150313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .checksubj = pr_nodeinfo_nodename, 151313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }, 152313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti [ICMP6_NI_SUBJ_IPV4] = { 153313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .code = ICMP6_NI_SUBJ_IPV4, 154313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "IPv4", 155313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti //.init = init_nodeinfo_ipv4addr, 156313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .checksubj = pr_nodeinfo_ipv4addr, 157313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }, 158313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 159313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 160313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic struct subjinfo subjinfo_null = { 161313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "null", 162313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .checksubj = pr_nodeinfo_noop, 163313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 164313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 165313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic __inline__ struct subjinfo *subjinfo_lookup(int code) 166313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 167313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (code >= ARRAY_SIZE(subjinfo_table)) 168313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return NULL; 169313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subjinfo_table[code].name == NULL) 170313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return NULL; 171313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return &subjinfo_table[code]; 172313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 173313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 174313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 175313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define QTYPEINFO_F_RATELIMIT 0x1 176313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 177313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct qtypeinfo { 178313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti uint16_t qtype; 179313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *name; 180313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int (*getreply)(CHECKANDFILL_ARGS); 181313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti void (*init)(INIT_ARGS); 182313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int flags; 183313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 184313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 185313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic struct qtypeinfo qtypeinfo_table[] = { 186313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti [NI_QTYPE_NOOP] = { 187313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .qtype = NI_QTYPE_NOOP, 188313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "NOOP", 189313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .getreply = pr_nodeinfo_noop, 190313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }, 191313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_SUPTYPES 192313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti [NI_QTYPE_SUPTYPES] = { 193313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .qtype = NI_QTYPE_SUPTYPES, 194313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "SupTypes", 195313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .getreply = pr_nodeinfo_suptypes, 196313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .init = init_nodeinfo_suptypes, 197313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }, 198313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 199313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti [NI_QTYPE_DNSNAME] = { 200313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .qtype = NI_QTYPE_DNSNAME, 201313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "DnsName", 202313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .getreply = pr_nodeinfo_nodename, 203313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .init = init_nodeinfo_nodename, 204313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }, 205313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti [NI_QTYPE_NODEADDR] = { 206313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .qtype = NI_QTYPE_NODEADDR, 207313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "NodeAddr", 208313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .getreply = pr_nodeinfo_ipv6addr, 209313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .init = init_nodeinfo_ipv6addr, 210313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }, 211313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti [NI_QTYPE_IPV4ADDR] = { 212313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .qtype = NI_QTYPE_IPV4ADDR, 213313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "IPv4Addr", 214313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .getreply = pr_nodeinfo_ipv4addr, 215313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .init = init_nodeinfo_ipv4addr, 216313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }, 217313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 218313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 219313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic struct qtypeinfo qtypeinfo_unknown = { 220313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "unknown", 221313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .getreply = pr_nodeinfo_unknown, 222313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .flags = QTYPEINFO_F_RATELIMIT, 223313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 224313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 225313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic struct qtypeinfo qtypeinfo_refused = { 226313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .name = "refused", 227313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .getreply = pr_nodeinfo_refused, 228313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti .flags = QTYPEINFO_F_RATELIMIT, 229313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 230313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 231313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic __inline__ struct qtypeinfo *qtypeinfo_lookup(int qtype) 232313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 233313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (qtype >= ARRAY_SIZE(qtypeinfo_table)) 234313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return &qtypeinfo_unknown; 235313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (qtypeinfo_table[qtype].name == NULL) 236313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return &qtypeinfo_unknown; 237313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return &qtypeinfo_table[qtype]; 238313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 239313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 240313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 241313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* noop */ 242313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint pr_nodeinfo_noop(CHECKANDFILL_ARGS) 243313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 244313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s()\n", __func__); 245313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 246313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subjlen) { 247313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 248313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "%s(): invalid subject length(%zu)\n", 249313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, subjlen); 250313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 1; 251313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 252313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 253313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (reply) { 254313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_type = ICMP6_NI_REPLY; 255313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_code = ICMP6_NI_SUCCESS; 256313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_cksum = 0; 257313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_qtype = htons(NI_QTYPE_NOOP); 258313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_flags = flags; 259313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 260313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 261313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subj_if) 262313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *subj_if = 0; 263313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 264313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 265313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 266313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 267313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_SUPTYPES 268313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* suptypes */ 269313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint pr_nodeinfo_suptypes(CHECKANDFILL_ARGS) 270313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 271313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s()\n", __func__); 272313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 273313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subjlen) { 274313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, "%s(): invalid subject length(%zu)\n", 275313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, subjlen); 276313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 1; 277313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 278313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 279313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (reply) { 280313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_type = ICMP6_NI_REPLY; 281313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_code = ICMP6_NI_SUCCESS; 282313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_cksum = 0; 283313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_qtype = htons(NI_QTYPE_SUPTYPES); 284313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_flags = flags&~NI_SUPTYPE_FLAG_COMPRESS; 285313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 286313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydatalen = suptypes_len<<2; 287313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydata = ni_malloc(p->replydatalen); 288313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (p->replydata == NULL) { 289313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydatalen = -1; 290313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; /*XXX*/ 291313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 292313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 293313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(p->replydata, suptypes, p->replydatalen); 294313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 295313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 296313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 297313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 298313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid init_nodeinfo_suptypes(INIT_ARGS) 299313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 300313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti size_t w, b; 301313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 302313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 303313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!forced && initialized) 304313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 305313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 306313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(suptypes, 0, sizeof(suptypes)); 307313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti suptypes_len = 0; 308313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 309313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i=0; i < ARRAY_SIZE(qtypeinfo_table); i++) { 310313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned short qtype; 311313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 312313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (qtypeinfo_table[i].name == NULL) 313313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 314313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti qtype = qtypeinfo_table[i].qtype; 315313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti w = qtype>>5; 316313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti b = qtype&0x1f; 317313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (w >= ARRAY_SIZE(suptypes)) { 318313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* This is programming error. */ 319313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_ERR, "Warning: Too Large Supported Types\n"); 320313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 321313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 322313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti suptypes[w] |= htonl(1<<b); 323313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 324313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (suptypes_len < w) 325313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti suptypes_len = w; 326313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 327313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti suptypes_len++; 328313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 329313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 330313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 331313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 332313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* unknown qtype response */ 333313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint pr_nodeinfo_unknown(CHECKANDFILL_ARGS) 334313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 335313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!reply) 336313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; /*???*/ 337313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 338313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_type = ICMP6_NI_REPLY; 339313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_code = ICMP6_NI_UNKNOWN; 340313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_cksum = 0; 341313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti //p->reply.ni_qtype = 0; 342313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_flags = flags; 343313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 344313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydata = NULL; 345313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydatalen = 0; 346313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 347313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 348313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 349313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 350313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* refused response */ 351313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint pr_nodeinfo_refused(CHECKANDFILL_ARGS) 352313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 353313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!reply) 354313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; /*???*/ 355313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 356313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_type = ICMP6_NI_REPLY; 357313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_code = ICMP6_NI_REFUSED; 358313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_cksum = 0; 359313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti //p->reply.ni_qtype = 0; 360313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_flags = flags; 361313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 362313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydata = NULL; 363313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydatalen = 0; 364313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 365313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 366313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 367313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 368313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 369313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* Policy */ 370313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int ni_policy(struct packetcontext *p) 371313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 372313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti const struct in6_addr *saddr = &((const struct sockaddr_in6 *)&p->addr)->sin6_addr; 373313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 374313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 375313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * >0: reply 376313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 0: refused 377313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * <0: discard 378313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 379313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 380313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Default policy is to refuse queries from 381313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * non-local addresses; loopback, link-local or 382313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * site-local are okay 383313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 384313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!(IN6_IS_ADDR_LINKLOCAL(saddr) || 385313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti IN6_IS_ADDR_SITELOCAL(saddr) || 386313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti IN6_IS_ADDR_LOOPBACK(saddr))) 387313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 388313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 1; 389313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 390313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 391313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 392313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid init_core(int forced) 393313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 394313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 395313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 396313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s()\n", __func__); 397313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 398313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!initialized || forced) { 399313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct timeval tv; 400313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned int seed = 0; 401313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pid_t pid; 402313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 403313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (gettimeofday(&tv, NULL) < 0) { 404313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, "%s(): failed to gettimeofday()\n", __func__); 405313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 406313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti seed = (tv.tv_usec & 0xffffffff); 407313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 408313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 409313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pid = getpid(); 410313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti seed ^= (((unsigned long)pid) & 0xffffffff); 411313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 412313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti srand(seed); 413313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 414313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_THREADS && HAVE_LIBPTHREAD 415313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (initialized) 416313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pthread_attr_destroy(&pattr); 417313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 418313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pthread_attr_init(&pattr); 419313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED); 420313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 421313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 422313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 423313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i=0; i < ARRAY_SIZE(subjinfo_table); i++) { 424313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subjinfo_table[i].name == NULL) 425313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 426313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subjinfo_table[i].init) 427313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti subjinfo_table[i].init(forced); 428313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 429313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 430313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i=0; i < ARRAY_SIZE(qtypeinfo_table); i++) { 431313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (qtypeinfo_table[i].name == NULL) 432313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 433313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (qtypeinfo_table[i].init) 434313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti qtypeinfo_table[i].init(forced); 435313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 436313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 437313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti initialized = 1; 438313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 439313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 440313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 441313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 442313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_THREADS && HAVE_LIBPTHREAD 443313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic void *ni_send_thread(void *data) 444313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 445313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int ret; 446313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s(): thread=%ld\n", __func__, pthread_self()); 447313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ret = ni_send(data); 448313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s(): thread=%ld => %d\n", __func__, pthread_self(), ret); 449313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return NULL; 450313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 451313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else 452313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int ni_send_fork(struct packetcontext *p) 453313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 454313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pid_t child = fork(); 455313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (child < 0) 456313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 457313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (child == 0) { 458313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pid_t grandchild = fork(); 459313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (grandchild < 0) 460313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 461313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (grandchild == 0) { 462313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int ret; 463313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s(): worker=%d\n", 464313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, getpid()); 465313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ret = ni_send(p); 466313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s(): worker=%d => %d\n", 467313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, getpid(), ret); 468313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(ret > 0 ? 1 : 0); 469313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 470313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p->replydata); 471313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 472313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(0); 473313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 474313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti waitpid(child, NULL, 0); 475313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p->replydata); 476313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 477313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 478313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 479313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 480313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 481313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 482313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int ni_ratelimit(void) 483313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 484313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti static struct timeval last; 485313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct timeval tv, sub; 486313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 487313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (gettimeofday(&tv, NULL) < 0) { 488313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, "%s(): gettimeofday(): %s\n", 489313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, strerror(errno)); 490313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 491313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 492313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 493313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!timerisset(&last)) { 494313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti last = tv; 495313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 496313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 497313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 498313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti timersub(&tv, &last, &sub); 499313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 500313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (sub.tv_sec < 1) 501313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 1; 502313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 503313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti last = tv; 504313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 505313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 506313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 507313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint pr_nodeinfo(struct packetcontext *p) 508313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 509313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct icmp6_nodeinfo *query = (struct icmp6_nodeinfo *)p->query; 510313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 511313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *subject = (char *)(query + 1); 512313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti size_t subjlen; 513313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct subjinfo *subjinfo; 514313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct qtypeinfo *qtypeinfo; 515313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int replyonsubjcheck = 0; 516313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned int subj_if; 517313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_DEBUG 518313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char printbuf[128]; 519313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 520313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *cp; 521313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 522313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_THREADS && HAVE_PTHREAD_H 523313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pthread_t thread; 524313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 525313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int rc; 526313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 527313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 0: Check destination address 528313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * discard non-linklocal multicast 529313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * discard non-nigroup multicast address(?) 530313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 531313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (IN6_IS_ADDR_MULTICAST(&p->pktinfo.ipi6_addr)) { 532313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!IN6_IS_ADDR_MC_LINKLOCAL(&p->pktinfo.ipi6_addr)) { 533313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 534313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "Destination is non-link-local multicast address.\n"); 535313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 536313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 537313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 538313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if 0 539313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Do not discard NI Queries to multicast address 540313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * other than its own NI Group Address(es) by default. 541313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 542313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!check_nigroup(&p->pktinfo.ipi6_addr)) { 543313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 544313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "Destination is link-local multicast address other than " 545313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "NI Group address.\n"); 546313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 547313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 548313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 549313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 550313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 551313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 552313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 1: Check length */ 553313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (p->querylen < sizeof(struct icmp6_nodeinfo)) { 554313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, "Query too short\n"); 555313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 556313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 557313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 558313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 559313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_DEBUG 560313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti cp = printbuf; 561313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i = 0; i < sizeof(query->icmp6_ni_nonce); i++) { 562313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti cp += sprintf(cp, " %02x", query->icmp6_ni_nonce[i]); 563313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 564313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s(): qtype=%d, flags=0x%04x, nonce[] = {%s }\n", 565313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, 566313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ntohs(query->ni_qtype), ntohs(query->ni_flags), printbuf); 567313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 568313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 569313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti subjlen = p->querylen - sizeof(struct icmp6_nodeinfo); 570313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 571313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 2: Check Subject Code */ 572313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti switch(htons(query->ni_qtype)) { 573313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case NI_QTYPE_NOOP: 574313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case NI_QTYPE_SUPTYPES: 575313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (query->ni_code != ICMP6_NI_SUBJ_FQDN) { 576313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 577313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "%s(): invalid/unknown code %u\n", 578313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, query->ni_code); 579313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti subjlen = 0; 580313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 581313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti subjinfo = &subjinfo_null; 582313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 583313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti default: 584313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti subjinfo = subjinfo_lookup(query->ni_code); 585313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!subjinfo) { 586313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 587313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "%s(): unknown code %u\n", 588313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, query->ni_code); 589313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 590313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 591313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 592313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 593313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 594313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 3: Lookup Qtype */ 595313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti qtypeinfo = qtypeinfo_lookup(ntohs(query->ni_qtype)); 596313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 597313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 4: Check Subject 598313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * (And fill reply if it is available now) 599313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 600313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (qtypeinfo->getreply == subjinfo->checksubj) 601313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti replyonsubjcheck = 1; 602313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 603313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subjinfo->checksubj(p, 604313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti subject, subjlen, 605313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti query->ni_flags, 606313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti replyonsubjcheck ? NULL : &subj_if, 607313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti replyonsubjcheck)) { 608313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (p->replydatalen < 0) { 609313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 610313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "failed to make reply: %s\n", 611313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti strerror(errno)); 612313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 613313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 614313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 615313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 616313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 617313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* XXX: Step 5: Check the policy */ 618313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti rc = ni_policy(p); 619313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (rc <= 0) { 620313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p->replydata); 621313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydata = NULL; 622313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydatalen = 0; 623313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (rc < 0) { 624313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, "Ignored by policy.\n"); 625313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 626313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 627313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 628313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, "Refused by policy.\n"); 629313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti replyonsubjcheck = 0; 630313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti qtypeinfo = &qtypeinfo_refused; 631313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 632313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 633313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 6: Fill the reply if not yet done */ 634313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!replyonsubjcheck) { 635313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (qtypeinfo->getreply(p, 636313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti NULL, 0, 637313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti query->ni_flags, 638313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti &subj_if, 639313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 1)) { 640313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (p->replydatalen) { 641313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 642313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "failed to make reply: %s\n", 643313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti strerror(errno)); 644313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 645313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 646313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 647313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 648313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 649313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 650313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 7: Rate Limit */ 651313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (qtypeinfo->flags&QTYPEINFO_F_RATELIMIT && 652313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_ratelimit()) { 653313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p->replydata); 654313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 655313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 656313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 657313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 658313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 8: Fill Qtype / Nonce */ 659313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_qtype = query->ni_qtype; 660313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(p->reply.icmp6_ni_nonce, query->icmp6_ni_nonce, sizeof(p->reply.icmp6_ni_nonce)); 661313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 662313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 9: Source address selection */ 663313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (IN6_IS_ADDR_MULTICAST(&p->pktinfo.ipi6_addr)) { 664313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* if query was sent to multicast address, 665313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * use source address selection in kernel. 666313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * XXX: anycast? 667313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 668313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&p->pktinfo.ipi6_addr, 0, sizeof(p->pktinfo.ipi6_addr)); 669313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 670313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Random Delay between zero and MAX_ANYCAST_DELAY_TIME is 671313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * required if query was sent to anycast or multicast address. 672313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 673313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->delay = (int) (MAX_ANYCAST_DELAY_TIME*rand()/(RAND_MAX+1.0)); 674313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 675313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->delay = 0; 676313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 677313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 678313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Step 10: Send the reply 679313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * XXX: with possible random delay */ 680313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_THREADS && HAVE_LIBPTHREAD 681313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ni_send_thread() frees p */ 682313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (pthread_create(&thread, &pattr, ni_send_thread, p)) { 683313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p->replydata); 684313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 685313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 686313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 687313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else 688313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ni_send_fork() frees p */ 689313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ni_send_fork(p)) { 690313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p->replydata); 691313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ni_free(p); 692313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 693313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 694313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 695313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 696313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 697313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 698313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 699