1313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* $USAGI: ninfod_name.c,v 1.15 2003-01-11 14:33:28 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# include <ctype.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 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#include <arpa/inet.h> 101313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 102313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if defined(HAVE_GNUTLS_OPENSSL_H) 103313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <gnutls/openssl.h> 104313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#elif defined(HAVE_OPENSSL_MD5_H) 105313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <openssl/md5.h> 106313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 107313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 108313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_SYS_UTSNAME_H 109313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <sys/utsname.h> 110313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 111313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_NETDB_H 112313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <netdb.h> 113313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 114313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <errno.h> 115313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 116313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if HAVE_SYSLOG_H 117313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# include <syslog.h> 118313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 119313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 120313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include "ninfod.h" 121313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 122313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef offsetof 123313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# define offsetof(aggregate,member) ((size_t)&((aggregate *)0)->member) 124313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 125313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 126313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* Hmm,,, */ 127313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef IPV6_JOIN_GROUP 128313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP 129313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti# define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP 130313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 131313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 132313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 133313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ID */ 134313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic char *RCSID __attribute__ ((unused)) = "$USAGI: ninfod_name.c,v 1.15 2003-01-11 14:33:28 yoshfuji Exp $"; 135313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 136313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* Variables */ 137313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic struct utsname utsname; 138313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic char *uts_nodename = utsname.nodename; 139313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 140313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar nodename[MAX_DNSNAME_SIZE]; 141313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic size_t nodenamelen; 142313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 143313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic struct ipv6_mreq nigroup; 144313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 145313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 146313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* Functions */ 147313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint check_nigroup(const struct in6_addr *addr) 148313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 149313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return IN6_IS_ADDR_MULTICAST(&nigroup.ipv6mr_multiaddr) && 150313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti IN6_ARE_ADDR_EQUAL(&nigroup.ipv6mr_multiaddr, addr); 151313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 152313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 153313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int encode_dnsname(const char *name, 154313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *buf, size_t buflen, 155313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int fqdn) 156313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 157313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti size_t namelen; 158313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 159313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 160313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (buflen < 0) 161313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 162313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 163313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti namelen = strlen(name); 164313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (namelen == 0) 165313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 166313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (namelen > 255 || buflen < namelen+1) 167313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 168313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 169313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti i = 0; 170313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti while(i <= namelen) { 171313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti const char *e; 172313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int llen, ii; 173313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 174313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti e = strchr(&name[i], '.'); 175313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (e == NULL) 176313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti e = name + namelen; 177313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti llen = e - &name[i]; 178313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (llen == 0) { 179313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (*e) 180313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 181313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (fqdn < 0) 182313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 183313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fqdn = 1; 184313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 185313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 186313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (llen >= 0x40) 187313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 188313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti buf[i] = llen; 189313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ii = 0; ii < llen; ii++) { 190313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!isascii(name[i+ii])) 191313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 192313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ii == 0 || ii == llen-1) { 193313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!isalpha(name[i+ii]) && !isdigit(name[i+ii])) 194313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 195313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else if (!isalnum(name[i+ii]) && name[i+ii] != '-') 196313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 197313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti buf[i+ii+1] = isupper(name[i+ii]) ? tolower(name[i+ii]) : name[i+ii]; 198313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 199313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti i += llen + 1; 200313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 201313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (buflen < i + 1 + !(fqdn > 0)) 202313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 203313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti buf[i++] = 0; 204313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!(fqdn > 0)) 205313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti buf[i++] = 0; 206313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return i; 207313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 208313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 209313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int compare_dnsname(const char *s, size_t slen, 210313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti const char *n, size_t nlen) 211313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 212313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti const char *s0 = s, *n0 = n; 213313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int done = 0, retcode = 0; 214313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (slen < 1 || nlen < 1) 215313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; /* invalid length */ 216313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* simple case */ 217313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (slen == nlen && memcmp(s, n, slen) == 0) 218313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 219313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (*(s0 + slen - 1) || *(n0 + nlen - 1)) 220313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; /* invalid termination */ 221313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti while (s < s0 + slen && n < n0 + nlen) { 222313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (*s >= 0x40 || *n >= 0x40) 223313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; /* DNS compression is not allowed here */ 224313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (s + *s + 1 > s0 + slen || n + *n + 1 > n0 + nlen) 225313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; /* overrun */ 226313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (*s == '\0') { 227313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (s == s0 + slen - 1) 228313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; /* FQDN */ 229313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti else if (s + 1 == s0 + slen - 1) 230313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return retcode; /* truncated */ 231313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti else 232313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; /* more than one subject */ 233313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 234313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!done) { 235313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (*n == '\0') { 236313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (n == n0 + nlen - 1) { 237313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti done = 1; /* FQDN */ 238313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else if (n + 1 == n0 + nlen - 1) { 239313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti retcode = 1; // trunc 240313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti done = 1; 241313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else 242313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 243313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 244313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (*s != *n) { 245313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti done = 1; 246313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti retcode = 1; 247313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 248313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (memcmp(s+1, n+1, *s)) { 249313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti done = 1; 250313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti retcode = 1; 251313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 252313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 253313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 254313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 255313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti s += *s + 1; 256313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti n += done ? 0 : (*n + 1); 257313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 258313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return retcode; 259313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 260313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 261313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int nodeinfo_group(const char *dnsname, int namelen, 262313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct in6_addr *nigroup) 263313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 264313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti MD5_CTX ctxt; 265313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned char digest[16]; 266313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 267313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!dnsname || !nigroup) 268313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 269313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 270313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti MD5_Init(&ctxt); 271313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti MD5_Update(&ctxt, dnsname, *dnsname); 272313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti MD5_Final(digest, &ctxt); 273313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 274313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef s6_addr32 275313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nigroup->s6_addr32[0] = htonl(0xff020000); 276313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nigroup->s6_addr32[1] = 0; 277313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nigroup->s6_addr32[2] = htonl(0x00000002); 278313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else 279313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(nigroup, 0, sizeof(*nigroup)); 280313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nigroup->s6_addr[ 0] = 0xff; 281313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nigroup->s6_addr[ 1] = 0x02; 282313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nigroup->s6_addr[11] = 0x02; 283313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 284313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(&nigroup->s6_addr[12], digest, 4); 285313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 286313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 287313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 288313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 289313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 290313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid init_nodeinfo_nodename(int forced) 291313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 292313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct utsname newname; 293313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int len; 294313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int changed = 0; 295313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 296313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s()\n", __func__); 297313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 298313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti uname(&newname); 299313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti changed = strcmp(newname.nodename, utsname.nodename); 300313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 301313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!changed && !forced) 302313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 303313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 304313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(&utsname, &newname, sizeof(newname)); 305313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 306313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* leave old group */ 307313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if ((changed || forced) && !IN6_IS_ADDR_UNSPECIFIED(&nigroup.ipv6mr_multiaddr)) { 308313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (setsockopt(sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &nigroup, sizeof(nigroup)) < 0) { 309313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_DEBUG 310313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char niaddrbuf[INET6_ADDRSTRLEN]; 311313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (inet_ntop(AF_INET6, &nigroup, niaddrbuf, sizeof(niaddrbuf)) == NULL) 312313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti strcpy(niaddrbuf, "???"); 313313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 314313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 315313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "%s(): failed to leave group %s.\n", 316313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, niaddrbuf); 317313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&nigroup, 0, sizeof(nigroup)); 318313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 319313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 320313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 321313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti len = encode_dnsname(uts_nodename, 322313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nodename, 323313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sizeof(nodename), 324313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 0); 325313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 326313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* setup ni reply */ 327313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nodenamelen = len > 0 ? len : 0; 328313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 329313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* setup ni group */ 330313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (changed || forced) { 331313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (nodenamelen) { 332313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&nigroup, 0, sizeof(nigroup)); 333313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nodeinfo_group(nodename, len, &nigroup.ipv6mr_multiaddr); 334313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nigroup.ipv6mr_interface = 0; 335313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &nigroup, sizeof(nigroup)) < 0) { 336313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if ENABLE_DEBUG 337313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char niaddrbuf[INET6_ADDRSTRLEN]; 338313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (inet_ntop(AF_INET6, &nigroup, niaddrbuf, sizeof(niaddrbuf)) == NULL) 339313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti strcpy(niaddrbuf, "???"); 340313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 341313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_WARNING, 342313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "%s(): failed to join group %s.\n", 343313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __func__, niaddrbuf); 344313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&nigroup, 0, sizeof(nigroup)); 345313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 346313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 347313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&nigroup, 0, sizeof(nigroup)); 348313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 349313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 350313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 351313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 352313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 353313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 354313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* ---------- */ 355313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* nodename */ 356313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint pr_nodeinfo_nodename(CHECKANDFILL_ARGS) 357313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 358313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DEBUG(LOG_DEBUG, "%s()\n", __func__); 359313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 360313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subject) { 361313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!nodenamelen || 362313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti compare_dnsname(subject, subjlen, 363313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nodename, 364313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nodenamelen)) 365313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 1; 366313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (subj_if) 367313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *subj_if = p->pktinfo.ipi6_ifindex; 368313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 369313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 370313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (reply) { 371313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti uint32_t ttl = 0; 372313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 373313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_type = ICMP6_NI_REPLY; 374313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_code = ICMP6_NI_SUCCESS; 375313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_cksum = 0; 376313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_qtype = htons(NI_QTYPE_DNSNAME); 377313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->reply.ni_flags = 0; 378313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 379313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydatalen = nodenamelen ? sizeof(ttl)+nodenamelen : 0; 380313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p->replydata = nodenamelen ? ni_malloc(p->replydatalen) : NULL; 381313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (p->replydata) { 382313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(p->replydata, &ttl, sizeof(ttl)); 383313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(p->replydata + sizeof(ttl), &nodename, nodenamelen); 384313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 385313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 386313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 387313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 388313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 389313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 390