1511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * All rights reserved. 4511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 5511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Redistribution and use in source and binary forms, with or without 6511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * modification, are permitted provided that the following conditions 7511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * are met: 8511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 1. Redistributions of source code must retain the above copyright 9511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * notice, this list of conditions and the following disclaimer. 10511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2. Redistributions in binary form must reproduce the above copyright 11511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * notice, this list of conditions and the following disclaimer in the 12511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * documentation and/or other materials provided with the distribution. 13511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 3. Neither the name of the project nor the names of its contributors 14511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * may be used to endorse or promote products derived from this software 15511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * without specific prior written permission. 16511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 17511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * SUCH DAMAGE. 28511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 29511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 30511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. 32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Issues to be discussed: 34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * - Thread safe-ness must be checked. 35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * - Return values. There are nonstandard return values defined and used 36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in the source code. This is because RFC2553 is silent about which error 37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * code must be returned for which situation. 38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Note: 39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * - We use getipnodebyname() just for thread-safeness. There's no intent 40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to 41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * getipnodebyname(). 42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * - The code filters out AFs that are not supported by the kernel, 43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * when globbing NULL hostname (to loopback, or wildcard). Is it the right 44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG 45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * in ai_flags? 46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 48511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Mingw64 has its own implementation of getaddrinfo, mingw32 no 50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 51511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef __MINGW64__ 52511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 53511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 54511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_CONFIG_H 55511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <config.h> 56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 57511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 58511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef lint 59511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char rcsid[] _U_ = 60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "@(#) $Header: /tcpdump/master/libpcap/Win32/Src/getaddrinfo.c,v 1.3 2008-09-15 23:37:51 guy Exp $"; 61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <pcap-stdinc.h> 64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if 0 65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/sysctl.h> 66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef __MINGW32__ 68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <arpa/nameser.h> 69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <string.h> 71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdlib.h> 72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stddef.h> 73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <ctype.h> 74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdio.h> 75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <errno.h> 76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef HAVE_PORTABLE_PROTOTYPE 78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "cdecl_ext.h" 79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef HAVE_U_INT32_T 82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "bittypes.h" 83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef HAVE_SOCKADDR_STORAGE 86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef __MINGW32__ 87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "sockstorage.h" 88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef NEED_ADDRINFO_H 92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "addrinfo.h" 93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef WIN32 94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "ip6_misc.h" 95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if defined(__KAME__) && defined(INET6) 100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall# define FAITH 101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define SUCCESS 0 104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define ANY 0 105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define YES 1 106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define NO 0 107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef FAITH 109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int translate = NO; 110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct in6_addr faith_prefix = IN6ADDR_ANY_INIT; 111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char in_addrany[] = { 0, 0, 0, 0 }; 114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char in6_addrany[] = { 115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}; 117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char in_loopback[] = { 127, 0, 0, 1 }; 118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char in6_loopback[] = { 119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}; 121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct sockinet { 123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_char si_len; 124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_char si_family; 125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_short si_port; 126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_int32_t si_scope_id; 127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}; 128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const struct afd { 130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int a_af; 131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int a_addrlen; 132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int a_socklen; 133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int a_off; 134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *a_addrany; 135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *a_loopback; 136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int a_scoped; 137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} afdl [] = { 138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall {PF_INET6, sizeof(struct in6_addr), 140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sizeof(struct sockaddr_in6), 141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall offsetof(struct sockaddr_in6, sin6_addr), 142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall in6_addrany, in6_loopback, 1}, 143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall {PF_INET, sizeof(struct in_addr), 145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sizeof(struct sockaddr_in), 146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall offsetof(struct sockaddr_in, sin_addr), 147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall in_addrany, in_loopback, 0}, 148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall {0, 0, 0, 0, NULL, NULL, 0}, 149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}; 150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct explore { 152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int e_af; 153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int e_socktype; 154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int e_protocol; 155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *e_protostr; 156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int e_wild; 157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define WILD_AF(ex) ((ex)->e_wild & 0x01) 158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) 159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) 160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}; 161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const struct explore explore[] = { 163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if 0 164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 }, 165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, 170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, 174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall { -1, 0, 0, NULL, 0 }, 175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}; 176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define PTON_MAX 16 179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define PTON_MAX 4 181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int str_isnumber __P((const char *)); 185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int explore_fqdn __P((const struct addrinfo *, const char *, 186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *, struct addrinfo **)); 187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int explore_null __P((const struct addrinfo *, const char *, 188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *, struct addrinfo **)); 189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int explore_numeric __P((const struct addrinfo *, const char *, 190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *, struct addrinfo **)); 191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int explore_numeric_scope __P((const struct addrinfo *, const char *, 192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *, struct addrinfo **)); 193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int get_name __P((const char *, const struct afd *, struct addrinfo **, 194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *, const struct addrinfo *, const char *)); 195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int get_canonname __P((const struct addrinfo *, 196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *, const char *)); 197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct addrinfo *get_ai __P((const struct addrinfo *, 198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *, const char *)); 199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int get_portmatch __P((const struct addrinfo *, const char *)); 200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int get_port __P((struct addrinfo *, const char *, int)); 201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const struct afd *find_afd __P((int)); 202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic char *ai_errlist[] = { 204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Success", 205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Address family for hostname not supported", /* EAI_ADDRFAMILY */ 206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Temporary failure in name resolution", /* EAI_AGAIN */ 207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Invalid value for ai_flags", /* EAI_BADFLAGS */ 208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Non-recoverable failure in name resolution", /* EAI_FAIL */ 209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "ai_family not supported", /* EAI_FAMILY */ 210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Memory allocation failure", /* EAI_MEMORY */ 211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "No address associated with hostname", /* EAI_NODATA */ 212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "hostname nor servname provided, or not known", /* EAI_NONAME */ 213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "servname not supported for ai_socktype", /* EAI_SERVICE */ 214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "ai_socktype not supported", /* EAI_SOCKTYPE */ 215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "System error returned in errno", /* EAI_SYSTEM */ 216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Invalid value for hints", /* EAI_BADHINTS */ 217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Resolved protocol is unknown", /* EAI_PROTOCOL */ 218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall "Unknown error", /* EAI_MAX */ 219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}; 220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* XXX macros that make external reference is BAD. */ 222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define GET_AI(ai, afd, addr) \ 224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldo { \ 225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* external reference: pai, error, and label free */ \ 226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (ai) = get_ai(pai, (afd), (addr)); \ 227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((ai) == NULL) { \ 228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_MEMORY; \ 229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; \ 230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } \ 231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} while (0) 232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define GET_PORT(ai, serv) \ 234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldo { \ 235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* external reference: error and label free */ \ 236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = get_port((ai), (serv), 0); \ 237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (error != 0) \ 238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; \ 239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} while (0) 240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define GET_CANONNAME(ai, str) \ 242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldo { \ 243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* external reference: pai, error and label free */ \ 244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = get_canonname(pai, (ai), (str)); \ 245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (error != 0) \ 246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; \ 247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} while (0) 248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define ERR(err) \ 250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldo { \ 251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* external reference: error, and label bad */ \ 252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = (err); \ 253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto bad; \ 254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} while (0) 255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define MATCH_FAMILY(x, y, w) \ 257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC))) 258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define MATCH(x, y, w) \ 259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ((x) == (y) || ((w) && ((x) == ANY || (y) == ANY))) 260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if defined(DEFINE_ADDITIONAL_IPV6_STUFF) 262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallchar * 263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgai_strerror(ecode) 264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int ecode; 265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ecode < 0 || ecode > EAI_MAX) 267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ecode = EAI_MAX; 268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return ai_errlist[ecode]; 269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallvoid 273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallfreeaddrinfo(ai) 274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *ai; 275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *next; 277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall do { 279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall next = ai->ai_next; 280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ai->ai_canonname) 281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(ai->ai_canonname); 282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* no need to free(ai->ai_addr) */ 283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(ai); 284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } while ((ai = next) != NULL); 285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstr_isnumber(p) 289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *p; 290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *q = (char *)p; 292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while (*q) { 293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (! isdigit(*q)) 294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return NO; 295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall q++; 296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return YES; 298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallgetaddrinfo(hostname, servname, hints, res) 302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *hostname, *servname; 303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *hints; 304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo **res; 305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo sentinel; 307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *cur; 308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int error = 0; 309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo ai; 310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo ai0; 311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *pai; 312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *afd; 313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct explore *ex; 314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef FAITH 316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall static int firsttime = 1; 317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (firsttime) { 319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* translator hack */ 320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *q = getenv("GAI"); 321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) 322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall translate = YES; 323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall firsttime = 0; 324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sentinel.ai_next = NULL; 328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = &sentinel; 329511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai = &ai; 330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_flags = 0; 331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_family = PF_UNSPEC; 332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_socktype = ANY; 333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_protocol = ANY; 334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_addrlen = 0; 335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_canonname = NULL; 336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_addr = NULL; 337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_next = NULL; 338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hostname == NULL && servname == NULL) 340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return EAI_NONAME; 341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hints) { 342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* error check for hints */ 343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hints->ai_addrlen || hints->ai_canonname || 344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hints->ai_addr || hints->ai_next) 345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ERR(EAI_BADHINTS); /* xxx */ 346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hints->ai_flags & ~AI_MASK) 347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ERR(EAI_BADFLAGS); 348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (hints->ai_family) { 349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case PF_UNSPEC: 350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case PF_INET: 351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case PF_INET6: 353511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ERR(EAI_FAMILY); 357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memcpy(pai, hints, sizeof(*pai)); 359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if both socktype/protocol are specified, check if they 362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * are meaningful combination. 363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { 365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (ex = explore; ex->e_af >= 0; ex++) { 366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_family != ex->e_af) 367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ex->e_socktype == ANY) 369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ex->e_protocol == ANY) 371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_socktype == ex->e_socktype 373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall && pai->ai_protocol != ex->e_protocol) { 374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ERR(EAI_BADHINTS); 375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * check for special cases. (1) numeric servname is disallowed if 382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * socktype/protocol are left unspecified. (2) servname is disallowed 383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * for raw and other inet{,6} sockets. 384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) 386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef PF_INET6 387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) 388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ) { 390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai0 = *pai; 391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_family == PF_UNSPEC) { 393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef PF_INET6 394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_family = PF_INET6; 395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_family = PF_INET; 397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = get_portmatch(pai, servname); 400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (error) 401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ERR(error); 402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *pai = ai0; 404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai0 = *pai; 407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NULL hostname, or numeric hostname */ 409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (ex = explore; ex->e_af >= 0; ex++) { 410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *pai = ai0; 411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) 413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) 415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 416511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) 417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_family == PF_UNSPEC) 420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_family = ex->e_af; 421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_socktype = ex->e_socktype; 423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 424511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_protocol = ex->e_protocol; 425511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hostname == NULL) 427511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = explore_null(pai, hostname, servname, &cur->ai_next); 428511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall else 429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next); 430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 431511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (error) 432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; 433511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while (cur && cur->ai_next) 435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = cur->ai_next; 436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX 440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If numreic representation of AF1 can be interpreted as FQDN 441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * representation of AF2, we need to think again about the code below. 442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (sentinel.ai_next) 444511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto good; 445511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_flags & AI_NUMERICHOST) 447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ERR(EAI_NONAME); 448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hostname == NULL) 449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ERR(EAI_NONAME); 450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * hostname as alphabetical name. 453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * we would like to prefer AF_INET6 than AF_INET, so we'll make a 454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * outer loop by AFs. 455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (afd = afdl; afd->a_af; afd++) { 457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *pai = ai0; 458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1)) 460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (ex = explore; ex->e_af >= 0; ex++) { 463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *pai = ai0; 464511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 465511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_family == PF_UNSPEC) 466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_family = afd->a_af; 467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 468511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) 469511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!MATCH(pai->ai_socktype, ex->e_socktype, 471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall WILD_SOCKTYPE(ex))) { 472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 473511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 474511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!MATCH(pai->ai_protocol, ex->e_protocol, 475511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall WILD_PROTOCOL(ex))) { 476511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 477511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 478511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 479511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_family == PF_UNSPEC) 480511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_family = ex->e_af; 481511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 482511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_socktype = ex->e_socktype; 483511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 484511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_protocol = ex->e_protocol; 485511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 486511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = explore_fqdn(pai, hostname, servname, 487511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall &cur->ai_next); 488511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 489511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while (cur && cur->ai_next) 490511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = cur->ai_next; 491511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 492511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 493511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 494511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* XXX */ 495511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (sentinel.ai_next) 496511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = 0; 497511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 498511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (error) 499511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; 500511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (error == 0) { 501511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (sentinel.ai_next) { 502511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall good: 503511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = sentinel.ai_next; 504511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return SUCCESS; 505511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 506511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_FAIL; 507511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 508511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free: 509511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bad: 510511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (sentinel.ai_next) 511511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freeaddrinfo(sentinel.ai_next); 512511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = NULL; 513511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return error; 514511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 515511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 516511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 517511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * FQDN hostname, DNS lookup 518511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 519511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 520511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallexplore_fqdn(pai, hostname, servname, res) 521511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *pai; 522511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *hostname; 523511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *servname; 524511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo **res; 525511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 526511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct hostent *hp; 527511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int h_error; 528511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int af; 529511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char **aplist = NULL, *apbuf = NULL; 530511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *ap; 531511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo sentinel, *cur; 532511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int i; 533511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef USE_GETIPNODEBY 534511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int naddrs; 535511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 536511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *afd; 537511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int error; 538511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 539511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = NULL; 540511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sentinel.ai_next = NULL; 541511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = &sentinel; 542511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 543511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 544511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Do not filter unsupported AFs here. We need to honor content of 545511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * databases (/etc/hosts, DNS and others). Otherwise we cannot 546511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * replace gethostbyname() by getaddrinfo(). 547511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 548511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 549511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 550511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if the servname does not match socktype/protocol, ignore it. 551511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 552511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (get_portmatch(pai, servname) != 0) 553511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 554511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 555511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall afd = find_afd(pai->ai_family); 556511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 557511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 558511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * post-RFC2553: should look at (pai->ai_flags & AI_ADDRCONFIG) 559511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * rather than hardcoding it. we may need to add AI_ADDRCONFIG 560511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * handling code by ourselves in case we don't have getipnodebyname(). 561511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 562511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef USE_GETIPNODEBY 563511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hp = getipnodebyname(hostname, pai->ai_family, AI_ADDRCONFIG, &h_error); 564511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 565511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_GETHOSTBYNAME2 566511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hp = gethostbyname2(hostname, pai->ai_family); 567511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 568511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_family != AF_INET) 569511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 570511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hp = gethostbyname(hostname); 571511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_H_ERRNO 572511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall h_error = h_errno; 573511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 574511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall h_error = EINVAL; 575511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 576511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /*HAVE_GETHOSTBYNAME2*/ 577511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /*USE_GETIPNODEBY*/ 578511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 579511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hp == NULL) { 580511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (h_error) { 581511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case HOST_NOT_FOUND: 582511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case NO_DATA: 583511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_NODATA; 584511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 585511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case TRY_AGAIN: 586511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_AGAIN; 587511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 588511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case NO_RECOVERY: 589511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case NETDB_INTERNAL: 590511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 591511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_FAIL; 592511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 593511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 594511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else if ((hp->h_name == NULL) || (hp->h_name[0] == 0) 595511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall || (hp->h_addr_list[0] == NULL)) { 596511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef USE_GETIPNODEBY 597511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freehostent(hp); 598511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 599511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hp = NULL; 600511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_FAIL; 601511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 602511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 603511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hp == NULL) 604511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; 605511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 606511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef USE_GETIPNODEBY 607511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall aplist = hp->h_addr_list; 608511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 609511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 610511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * hp will be overwritten if we use gethostbyname2(). 611511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * always deep copy for simplification. 612511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 613511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (naddrs = 0; hp->h_addr_list[naddrs] != NULL; naddrs++) 614511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ; 615511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall naddrs++; 616511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall aplist = (char **)malloc(sizeof(aplist[0]) * naddrs); 617511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall apbuf = (char *)malloc(hp->h_length * naddrs); 618511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (aplist == NULL || apbuf == NULL) { 619511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_MEMORY; 620511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; 621511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 622511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memset(aplist, 0, sizeof(aplist[0]) * naddrs); 623511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (i = 0; i < naddrs; i++) { 624511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hp->h_addr_list[i] == NULL) { 625511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall aplist[i] = NULL; 626511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 627511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 628511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memcpy(&apbuf[i * hp->h_length], hp->h_addr_list[i], 629511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hp->h_length); 630511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall aplist[i] = &apbuf[i * hp->h_length]; 631511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 632511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 633511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 634511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (i = 0; aplist[i] != NULL; i++) { 635511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall af = hp->h_addrtype; 636511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ap = aplist[i]; 637511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef AF_INET6 638511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (af == AF_INET6 639511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { 640511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall af = AF_INET; 641511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ap = ap + sizeof(struct in6_addr) 642511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall - sizeof(struct in_addr); 643511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 644511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 645511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 646511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (af != pai->ai_family) 647511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 648511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 649511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((pai->ai_flags & AI_CANONNAME) == 0) { 650511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_AI(cur->ai_next, afd, ap); 651511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_PORT(cur->ai_next, servname); 652511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 653511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 654511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if AI_CANONNAME and if reverse lookup 655511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * fail, return ai anyway to pacify 656511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * calling application. 657511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 658511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX getaddrinfo() is a name->address 659511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * translation function, and it looks 660511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * strange that we do addr->name 661511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * translation here. 662511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 663511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall get_name(ap, afd, &cur->ai_next, 664511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ap, pai, servname); 665511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 666511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 667511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while (cur && cur->ai_next) 668511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = cur->ai_next; 669511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 670511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 671511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = sentinel.ai_next; 672511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 673511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 674511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallfree: 675511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef USE_GETIPNODEBY 676511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hp) 677511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freehostent(hp); 678511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 679511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (aplist) 680511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(aplist); 681511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (apbuf) 682511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(apbuf); 683511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (sentinel.ai_next) 684511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freeaddrinfo(sentinel.ai_next); 685511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return error; 686511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 687511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 688511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 689511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * hostname == NULL. 690511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * passive socket -> anyaddr (0.0.0.0 or ::) 691511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * non-passive socket -> localhost (127.0.0.1 or ::1) 692511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 693511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 694511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallexplore_null(pai, hostname, servname, res) 695511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *pai; 696511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *hostname; 697511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *servname; 698511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo **res; 699511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 700511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int s; 701511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *afd; 702511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *cur; 703511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo sentinel; 704511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int error; 705511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 706511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = NULL; 707511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sentinel.ai_next = NULL; 708511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = &sentinel; 709511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 710511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 711511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * filter out AFs that are not supported by the kernel 712511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX errno? 713511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 714511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall s = socket(pai->ai_family, SOCK_DGRAM, 0); 715511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (s < 0) { 716511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (errno != EMFILE) 717511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 718511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 719511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall close(s); 720511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 721511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 722511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if the servname does not match socktype/protocol, ignore it. 723511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 724511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (get_portmatch(pai, servname) != 0) 725511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 726511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 727511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall afd = find_afd(pai->ai_family); 728511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 729511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_flags & AI_PASSIVE) { 730511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_AI(cur->ai_next, afd, afd->a_addrany); 731511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* xxx meaningless? 732511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * GET_CANONNAME(cur->ai_next, "anyaddr"); 733511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 734511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_PORT(cur->ai_next, servname); 735511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 736511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_AI(cur->ai_next, afd, afd->a_loopback); 737511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* xxx meaningless? 738511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * GET_CANONNAME(cur->ai_next, "localhost"); 739511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 740511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_PORT(cur->ai_next, servname); 741511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 742511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = cur->ai_next; 743511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 744511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = sentinel.ai_next; 745511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 746511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 747511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallfree: 748511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (sentinel.ai_next) 749511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freeaddrinfo(sentinel.ai_next); 750511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return error; 751511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 752511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 753511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 754511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * numeric hostname 755511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 756511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 757511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallexplore_numeric(pai, hostname, servname, res) 758511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *pai; 759511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *hostname; 760511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *servname; 761511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo **res; 762511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 763511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *afd; 764511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *cur; 765511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo sentinel; 766511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int error; 767511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char pton[PTON_MAX]; 768511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int flags; 769511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 770511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = NULL; 771511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sentinel.ai_next = NULL; 772511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = &sentinel; 773511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 774511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 775511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if the servname does not match socktype/protocol, ignore it. 776511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 777511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (get_portmatch(pai, servname) != 0) 778511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 779511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 780511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall afd = find_afd(pai->ai_family); 781511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall flags = pai->ai_flags; 782511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 783511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (inet_pton(afd->a_af, hostname, pton) == 1) { 784511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_int32_t v4a; 785511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 786511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_char pfx; 787511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 788511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 789511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (afd->a_af) { 790511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case AF_INET: 791511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall v4a = (u_int32_t)ntohl(((struct in_addr *)pton)->s_addr); 792511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) 793511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall flags &= ~AI_CANONNAME; 794511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall v4a >>= IN_CLASSA_NSHIFT; 795511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (v4a == 0 || v4a == IN_LOOPBACKNET) 796511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall flags &= ~AI_CANONNAME; 797511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 798511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 799511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case AF_INET6: 800511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pfx = ((struct in6_addr *)pton)->s6_addr[0]; 801511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pfx == 0 || pfx == 0xfe || pfx == 0xff) 802511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall flags &= ~AI_CANONNAME; 803511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 804511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 805511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 806511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 807511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pai->ai_family == afd->a_af || 808511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pai->ai_family == PF_UNSPEC /*?*/) { 809511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((flags & AI_CANONNAME) == 0) { 810511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_AI(cur->ai_next, afd, pton); 811511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_PORT(cur->ai_next, servname); 812511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 813511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 814511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if AI_CANONNAME and if reverse lookup 815511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * fail, return ai anyway to pacify 816511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * calling application. 817511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 818511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * XXX getaddrinfo() is a name->address 819511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * translation function, and it looks 820511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * strange that we do addr->name 821511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * translation here. 822511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 823511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall get_name(pton, afd, &cur->ai_next, 824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pton, pai, servname); 825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 826511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while (cur && cur->ai_next) 827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cur = cur->ai_next; 828511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 829511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ERR(EAI_FAMILY); /*xxx*/ 830511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 831511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 832511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = sentinel.ai_next; 833511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 834511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 835511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallfree: 836511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallbad: 837511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (sentinel.ai_next) 838511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freeaddrinfo(sentinel.ai_next); 839511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return error; 840511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 841511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 842511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 843511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * numeric hostname with scope 844511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 845511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 846511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallexplore_numeric_scope(pai, hostname, servname, res) 847511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *pai; 848511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *hostname; 849511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *servname; 850511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo **res; 851511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 852511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef SCOPE_DELIMITER 853511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return explore_numeric(pai, hostname, servname, res); 854511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 855511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *afd; 856511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *cur; 857511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int error; 858511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *cp, *hostname2 = NULL; 859511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int scope; 860511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct sockaddr_in6 *sin6; 861511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 862511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 863511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * if the servname does not match socktype/protocol, ignore it. 864511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 865511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (get_portmatch(pai, servname) != 0) 866511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 867511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 868511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall afd = find_afd(pai->ai_family); 869511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!afd->a_scoped) 870511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return explore_numeric(pai, hostname, servname, res); 871511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 872511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cp = strchr(hostname, SCOPE_DELIMITER); 873511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (cp == NULL) 874511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return explore_numeric(pai, hostname, servname, res); 875511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 876511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 877511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Handle special case of <scoped_address><delimiter><scope id> 878511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 879511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hostname2 = strdup(hostname); 880511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hostname2 == NULL) 881511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return EAI_MEMORY; 882511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* terminate at the delimiter */ 883511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hostname2[cp - hostname] = '\0'; 884511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 885511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cp++; 886511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (pai->ai_family) { 887511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 888511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case AF_INET6: 889511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall scope = if_nametoindex(cp); 890511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (scope == 0) { 891511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(hostname2); 892511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (EAI_NONAME); 893511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 894511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 895511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 896511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 897511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 898511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = explore_numeric(pai, hostname2, servname, res); 899511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (error == 0) { 900511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (cur = *res; cur; cur = cur->ai_next) { 901511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (cur->ai_family != AF_INET6) 902511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall continue; 903511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sin6 = (struct sockaddr_in6 *)cur->ai_addr; 904511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 905511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) 906511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sin6->sin6_scope_id = scope; 907511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 908511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 909511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 910511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(hostname2); 911511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 912511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return error; 913511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 914511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 915511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 916511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 917511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallget_name(addr, afd, res, numaddr, pai, servname) 918511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *addr; 919511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *afd; 920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo **res; 921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *numaddr; 922511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *pai; 923511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *servname; 924511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 925511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct hostent *hp = NULL; 926511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *cur = NULL; 927511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int error = 0; 928511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *ap = NULL, *cn = NULL; 929511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef USE_GETIPNODEBY 930511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int h_error; 931511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 932511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); 933511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 934511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); 935511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 936511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { 937511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef USE_GETIPNODEBY 938511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_AI(cur, afd, hp->h_addr_list[0]); 939511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_PORT(cur, servname); 940511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_CANONNAME(cur, hp->h_name); 941511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 942511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* hp will be damaged if we use gethostbyaddr() */ 943511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((ap = (char *)malloc(hp->h_length)) == NULL) { 944511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_MEMORY; 945511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; 946511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 947511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memcpy(ap, hp->h_addr_list[0], hp->h_length); 948511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((cn = strdup(hp->h_name)) == NULL) { 949511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error = EAI_MEMORY; 950511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall goto free; 951511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 952511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 953511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_AI(cur, afd, ap); 954511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_PORT(cur, servname); 955511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_CANONNAME(cur, cn); 956511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(ap); ap = NULL; 957511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(cn); cn = NULL; 958511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 959511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 960511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_AI(cur, afd, numaddr); 961511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall GET_PORT(cur, servname); 962511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 963511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 964511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef USE_GETIPNODEBY 965511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hp) 966511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freehostent(hp); 967511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 968511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = cur; 969511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return SUCCESS; 970511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free: 971511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (cur) 972511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freeaddrinfo(cur); 973511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ap) 974511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(ap); 975511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (cn) 976511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall free(cn); 977511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef USE_GETIPNODEBY 978511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (hp) 979511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall freehostent(hp); 980511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 981511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *res = NULL; 982511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return error; 983511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 984511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 985511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 986511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallget_canonname(pai, ai, str) 987511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *pai; 988511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *ai; 989511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *str; 990511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 991511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((pai->ai_flags & AI_CANONNAME) != 0) { 992511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai->ai_canonname = strdup(str); 993511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ai->ai_canonname == NULL) 994511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return EAI_MEMORY; 995511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 996511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 997511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 998511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 999511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic struct addrinfo * 1000511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallget_ai(pai, afd, addr) 1001511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *pai; 1002511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *afd; 1003511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *addr; 1004511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 1005511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *p; 1006511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *ai; 1007511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1008511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) 1009511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall + (afd->a_socklen)); 1010511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ai == NULL) 1011511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return NULL; 1012511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1013511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memcpy(ai, pai, sizeof(struct addrinfo)); 1014511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai->ai_addr = (struct sockaddr *)(ai + 1); 1015511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memset(ai->ai_addr, 0, afd->a_socklen); 1016511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SOCKADDR_SA_LEN 1017511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai->ai_addr->sa_len = afd->a_socklen; 1018511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 1019511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai->ai_addrlen = afd->a_socklen; 1020511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ai->ai_addr->sa_family = ai->ai_family = afd->a_af; 1021511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p = (char *)(ai->ai_addr); 1022511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memcpy(p + afd->a_off, addr, afd->a_addrlen); 1023511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return ai; 1024511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 1025511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1026511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 1027511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallget_portmatch(ai, servname) 1028511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct addrinfo *ai; 1029511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *servname; 1030511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 1031511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1032511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* get_port does not touch first argument. when matchonly == 1. */ 1033511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return get_port((struct addrinfo *)ai, servname, 1); 1034511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 1035511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1036511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int 1037511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallget_port(ai, servname, matchonly) 1038511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct addrinfo *ai; 1039511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *servname; 1040511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int matchonly; 1041511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 1042511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const char *proto; 1043511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct servent *sp; 1044511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int port; 1045511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int allownumeric; 1046511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1047511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (servname == NULL) 1048511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 1049511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (ai->ai_family) { 1050511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case AF_INET: 1051511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef AF_INET6 1052511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case AF_INET6: 1053511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 1054511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1055511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 1056511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 1057511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1058511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1059511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (ai->ai_socktype) { 1060511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case SOCK_RAW: 1061511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return EAI_SERVICE; 1062511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case SOCK_DGRAM: 1063511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case SOCK_STREAM: 1064511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall allownumeric = 1; 1065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case ANY: 1067511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall allownumeric = 0; 1068511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1069511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 1070511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return EAI_SOCKTYPE; 1071511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1072511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1073511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (str_isnumber(servname)) { 1074511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!allownumeric) 1075511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return EAI_SERVICE; 1076511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall port = htons(atoi(servname)); 1077511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (port < 0 || port > 65535) 1078511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return EAI_SERVICE; 1079511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 1080511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (ai->ai_socktype) { 1081511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case SOCK_DGRAM: 1082511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = "udp"; 1083511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1084511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case SOCK_STREAM: 1085511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = "tcp"; 1086511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1087511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 1088511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall proto = NULL; 1089511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1090511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1091511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1092511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((sp = getservbyname(servname, proto)) == NULL) 1093511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return EAI_SERVICE; 1094511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall port = sp->s_port; 1095511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1096511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1097511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (!matchonly) { 1098511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (ai->ai_family) { 1099511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case AF_INET: 1100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ((struct sockaddr_in *)ai->ai_addr)->sin_port = port; 1101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef INET6 1103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case AF_INET6: 1104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port; 1105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 1106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 1107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 1111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 1112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const struct afd * 1114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallfind_afd(af) 1115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int af; 1116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 1117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall const struct afd *afd; 1118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (af == PF_UNSPEC) 1120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return NULL; 1121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (afd = afdl; afd->a_af; afd++) { 1122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (afd->a_af == af) 1123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return afd; 1124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 1125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return NULL; 1126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 1127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 1129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /*__MING64__*/ 1130