1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2*7f2fe78bSCy Schubert /* 3*7f2fe78bSCy Schubert * Copyright (C) 2001,2002,2003,2004 by the Massachusetts Institute of Technology, 4*7f2fe78bSCy Schubert * Cambridge, MA, USA. All Rights Reserved. 5*7f2fe78bSCy Schubert * 6*7f2fe78bSCy Schubert * This software is being provided to you, the LICENSEE, by the 7*7f2fe78bSCy Schubert * Massachusetts Institute of Technology (M.I.T.) under the following 8*7f2fe78bSCy Schubert * license. By obtaining, using and/or copying this software, you agree 9*7f2fe78bSCy Schubert * that you have read, understood, and will comply with these terms and 10*7f2fe78bSCy Schubert * conditions: 11*7f2fe78bSCy Schubert * 12*7f2fe78bSCy Schubert * Export of this software from the United States of America may 13*7f2fe78bSCy Schubert * require a specific license from the United States Government. 14*7f2fe78bSCy Schubert * It is the responsibility of any person or organization contemplating 15*7f2fe78bSCy Schubert * export to obtain such a license before exporting. 16*7f2fe78bSCy Schubert * 17*7f2fe78bSCy Schubert * WITHIN THAT CONSTRAINT, permission to use, copy, modify and distribute 18*7f2fe78bSCy Schubert * this software and its documentation for any purpose and without fee or 19*7f2fe78bSCy Schubert * royalty is hereby granted, provided that you agree to comply with the 20*7f2fe78bSCy Schubert * following copyright notice and statements, including the disclaimer, and 21*7f2fe78bSCy Schubert * that the same appear on ALL copies of the software and documentation, 22*7f2fe78bSCy Schubert * including modifications that you make for internal use or for 23*7f2fe78bSCy Schubert * distribution: 24*7f2fe78bSCy Schubert * 25*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS 26*7f2fe78bSCy Schubert * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not 27*7f2fe78bSCy Schubert * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF 28*7f2fe78bSCy Schubert * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF 29*7f2fe78bSCy Schubert * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY 30*7f2fe78bSCy Schubert * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. 31*7f2fe78bSCy Schubert * 32*7f2fe78bSCy Schubert * The name of the Massachusetts Institute of Technology or M.I.T. may NOT 33*7f2fe78bSCy Schubert * be used in advertising or publicity pertaining to distribution of the 34*7f2fe78bSCy Schubert * software. Title to copyright in this software and any associated 35*7f2fe78bSCy Schubert * documentation shall at all times remain with M.I.T., and USER agrees to 36*7f2fe78bSCy Schubert * preserve same. 37*7f2fe78bSCy Schubert * 38*7f2fe78bSCy Schubert * Furthermore if you modify this software you must label 39*7f2fe78bSCy Schubert * your software as modified software and not distribute it in such a 40*7f2fe78bSCy Schubert * fashion that it might be confused with the original M.I.T. software. 41*7f2fe78bSCy Schubert */ 42*7f2fe78bSCy Schubert 43*7f2fe78bSCy Schubert /* Approach overview: 44*7f2fe78bSCy Schubert 45*7f2fe78bSCy Schubert If a system version is available but buggy, save handles to it (via 46*7f2fe78bSCy Schubert inline functions in a support library), redefine the names to refer 47*7f2fe78bSCy Schubert to library functions, and in those functions, call the system 48*7f2fe78bSCy Schubert versions and fix up the returned data. Use the native data 49*7f2fe78bSCy Schubert structures and flag values. 50*7f2fe78bSCy Schubert 51*7f2fe78bSCy Schubert If no system version exists, use gethostby* and fake it. Define 52*7f2fe78bSCy Schubert the data structures and flag values locally. 53*7f2fe78bSCy Schubert 54*7f2fe78bSCy Schubert 55*7f2fe78bSCy Schubert On macOS, getaddrinfo results aren't cached (though 56*7f2fe78bSCy Schubert gethostbyname results are), so we need to build a cache here. Now 57*7f2fe78bSCy Schubert things are getting really messy. Because the cache is in use, we 58*7f2fe78bSCy Schubert use getservbyname, and throw away thread safety. (Not that the 59*7f2fe78bSCy Schubert cache is thread safe, but when we get locking support, that'll be 60*7f2fe78bSCy Schubert dealt with.) This code needs tearing down and rebuilding, soon. 61*7f2fe78bSCy Schubert 62*7f2fe78bSCy Schubert 63*7f2fe78bSCy Schubert Note that recent Windows developers' code has an interesting hack: 64*7f2fe78bSCy Schubert When you include the right header files, with the right set of 65*7f2fe78bSCy Schubert macros indicating system versions, you'll get an inline function 66*7f2fe78bSCy Schubert that looks for getaddrinfo (or whatever) in the system library, and 67*7f2fe78bSCy Schubert calls it if it's there. If it's not there, it fakes it with 68*7f2fe78bSCy Schubert gethostby* calls. 69*7f2fe78bSCy Schubert 70*7f2fe78bSCy Schubert We're taking a simpler approach: A system provides these routines or 71*7f2fe78bSCy Schubert it does not. 72*7f2fe78bSCy Schubert 73*7f2fe78bSCy Schubert Someday, we may want to take into account different versions (say, 74*7f2fe78bSCy Schubert different revs of GNU libc) where some are broken in one way, and 75*7f2fe78bSCy Schubert some work or are broken in another way. Cross that bridge when we 76*7f2fe78bSCy Schubert come to it. */ 77*7f2fe78bSCy Schubert 78*7f2fe78bSCy Schubert /* To do, maybe: 79*7f2fe78bSCy Schubert 80*7f2fe78bSCy Schubert + For AIX 4.3.3, using the RFC 2133 definition: Implement 81*7f2fe78bSCy Schubert AI_NUMERICHOST. It's not defined in the header file. 82*7f2fe78bSCy Schubert 83*7f2fe78bSCy Schubert For certain (old?) versions of GNU libc, AI_NUMERICHOST is 84*7f2fe78bSCy Schubert defined but not implemented. 85*7f2fe78bSCy Schubert 86*7f2fe78bSCy Schubert + Use gethostbyname2, inet_aton and other IPv6 or thread-safe 87*7f2fe78bSCy Schubert functions if available. But, see 88*7f2fe78bSCy Schubert https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=135182 for one 89*7f2fe78bSCy Schubert gethostbyname2 problem on Linux. And besides, if a platform is 90*7f2fe78bSCy Schubert supporting IPv6 at all, they really should be doing getaddrinfo 91*7f2fe78bSCy Schubert by now. 92*7f2fe78bSCy Schubert 93*7f2fe78bSCy Schubert + inet_ntop, inet_pton 94*7f2fe78bSCy Schubert 95*7f2fe78bSCy Schubert + Conditionally export/import the function definitions, so a 96*7f2fe78bSCy Schubert library can have a single copy instead of multiple. 97*7f2fe78bSCy Schubert 98*7f2fe78bSCy Schubert + Upgrade host requirements to include working implementations of 99*7f2fe78bSCy Schubert these functions, and throw all this away. Pleeease? :-) */ 100*7f2fe78bSCy Schubert 101*7f2fe78bSCy Schubert #ifndef FAI_DEFINED 102*7f2fe78bSCy Schubert #define FAI_DEFINED 103*7f2fe78bSCy Schubert #include "port-sockets.h" 104*7f2fe78bSCy Schubert #include "socket-utils.h" 105*7f2fe78bSCy Schubert 106*7f2fe78bSCy Schubert #if !defined (HAVE_GETADDRINFO) 107*7f2fe78bSCy Schubert 108*7f2fe78bSCy Schubert #undef addrinfo 109*7f2fe78bSCy Schubert #define addrinfo my_fake_addrinfo 110*7f2fe78bSCy Schubert 111*7f2fe78bSCy Schubert struct addrinfo { 112*7f2fe78bSCy Schubert int ai_family; /* PF_foo */ 113*7f2fe78bSCy Schubert int ai_socktype; /* SOCK_foo */ 114*7f2fe78bSCy Schubert int ai_protocol; /* 0, IPPROTO_foo */ 115*7f2fe78bSCy Schubert int ai_flags; /* AI_PASSIVE etc */ 116*7f2fe78bSCy Schubert size_t ai_addrlen; /* real length of socket address */ 117*7f2fe78bSCy Schubert char *ai_canonname; /* canonical name of host */ 118*7f2fe78bSCy Schubert struct sockaddr *ai_addr; /* pointer to variable-size address */ 119*7f2fe78bSCy Schubert struct addrinfo *ai_next; /* next in linked list */ 120*7f2fe78bSCy Schubert }; 121*7f2fe78bSCy Schubert 122*7f2fe78bSCy Schubert #undef AI_PASSIVE 123*7f2fe78bSCy Schubert #define AI_PASSIVE 0x01 124*7f2fe78bSCy Schubert #undef AI_CANONNAME 125*7f2fe78bSCy Schubert #define AI_CANONNAME 0x02 126*7f2fe78bSCy Schubert #undef AI_NUMERICHOST 127*7f2fe78bSCy Schubert #define AI_NUMERICHOST 0x04 128*7f2fe78bSCy Schubert /* RFC 2553 says these are part of the interface for getipnodebyname, 129*7f2fe78bSCy Schubert not for getaddrinfo. RFC 3493 says they're part of the interface 130*7f2fe78bSCy Schubert for getaddrinfo, and getipnodeby* are deprecated. Our fake 131*7f2fe78bSCy Schubert getaddrinfo implementation here does IPv4 only anyways. */ 132*7f2fe78bSCy Schubert #undef AI_V4MAPPED 133*7f2fe78bSCy Schubert #define AI_V4MAPPED 0 134*7f2fe78bSCy Schubert #undef AI_ADDRCONFIG 135*7f2fe78bSCy Schubert #define AI_ADDRCONFIG 0 136*7f2fe78bSCy Schubert #undef AI_ALL 137*7f2fe78bSCy Schubert #define AI_ALL 0 138*7f2fe78bSCy Schubert #undef AI_DEFAULT 139*7f2fe78bSCy Schubert #define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) 140*7f2fe78bSCy Schubert 141*7f2fe78bSCy Schubert #ifndef NI_MAXHOST 142*7f2fe78bSCy Schubert #define NI_MAXHOST 1025 143*7f2fe78bSCy Schubert #endif 144*7f2fe78bSCy Schubert #ifndef NI_MAXSERV 145*7f2fe78bSCy Schubert #define NI_MAXSERV 32 146*7f2fe78bSCy Schubert #endif 147*7f2fe78bSCy Schubert 148*7f2fe78bSCy Schubert #undef NI_NUMERICHOST 149*7f2fe78bSCy Schubert #define NI_NUMERICHOST 0x01 150*7f2fe78bSCy Schubert #undef NI_NUMERICSERV 151*7f2fe78bSCy Schubert #define NI_NUMERICSERV 0x02 152*7f2fe78bSCy Schubert #undef NI_NAMEREQD 153*7f2fe78bSCy Schubert #define NI_NAMEREQD 0x04 154*7f2fe78bSCy Schubert #undef NI_DGRAM 155*7f2fe78bSCy Schubert #define NI_DGRAM 0x08 156*7f2fe78bSCy Schubert #undef NI_NOFQDN 157*7f2fe78bSCy Schubert #define NI_NOFQDN 0x10 158*7f2fe78bSCy Schubert 159*7f2fe78bSCy Schubert 160*7f2fe78bSCy Schubert #undef EAI_ADDRFAMILY 161*7f2fe78bSCy Schubert #define EAI_ADDRFAMILY 1 162*7f2fe78bSCy Schubert #undef EAI_AGAIN 163*7f2fe78bSCy Schubert #define EAI_AGAIN 2 164*7f2fe78bSCy Schubert #undef EAI_BADFLAGS 165*7f2fe78bSCy Schubert #define EAI_BADFLAGS 3 166*7f2fe78bSCy Schubert #undef EAI_FAIL 167*7f2fe78bSCy Schubert #define EAI_FAIL 4 168*7f2fe78bSCy Schubert #undef EAI_FAMILY 169*7f2fe78bSCy Schubert #define EAI_FAMILY 5 170*7f2fe78bSCy Schubert #undef EAI_MEMORY 171*7f2fe78bSCy Schubert #define EAI_MEMORY 6 172*7f2fe78bSCy Schubert #undef EAI_NODATA 173*7f2fe78bSCy Schubert #define EAI_NODATA 7 174*7f2fe78bSCy Schubert #undef EAI_NONAME 175*7f2fe78bSCy Schubert #define EAI_NONAME 8 176*7f2fe78bSCy Schubert #undef EAI_SERVICE 177*7f2fe78bSCy Schubert #define EAI_SERVICE 9 178*7f2fe78bSCy Schubert #undef EAI_SOCKTYPE 179*7f2fe78bSCy Schubert #define EAI_SOCKTYPE 10 180*7f2fe78bSCy Schubert #undef EAI_SYSTEM 181*7f2fe78bSCy Schubert #define EAI_SYSTEM 11 182*7f2fe78bSCy Schubert 183*7f2fe78bSCy Schubert #endif /* ! HAVE_GETADDRINFO */ 184*7f2fe78bSCy Schubert 185*7f2fe78bSCy Schubert /* Fudge things on older gai implementations. */ 186*7f2fe78bSCy Schubert /* AIX 4.3.3 is based on RFC 2133; no AI_NUMERICHOST. */ 187*7f2fe78bSCy Schubert #ifndef AI_NUMERICHOST 188*7f2fe78bSCy Schubert # define AI_NUMERICHOST 0 189*7f2fe78bSCy Schubert #endif 190*7f2fe78bSCy Schubert /* Partial RFC 2553 implementations may not have AI_ADDRCONFIG and 191*7f2fe78bSCy Schubert friends, which RFC 3493 says are now part of the getaddrinfo 192*7f2fe78bSCy Schubert interface, and we'll want to use. */ 193*7f2fe78bSCy Schubert #ifndef AI_ADDRCONFIG 194*7f2fe78bSCy Schubert # define AI_ADDRCONFIG 0 195*7f2fe78bSCy Schubert #endif 196*7f2fe78bSCy Schubert #ifndef AI_V4MAPPED 197*7f2fe78bSCy Schubert # define AI_V4MAPPED 0 198*7f2fe78bSCy Schubert #endif 199*7f2fe78bSCy Schubert #ifndef AI_ALL 200*7f2fe78bSCy Schubert # define AI_ALL 0 201*7f2fe78bSCy Schubert #endif 202*7f2fe78bSCy Schubert #ifndef AI_DEFAULT 203*7f2fe78bSCy Schubert # define AI_DEFAULT (AI_ADDRCONFIG|AI_V4MAPPED) 204*7f2fe78bSCy Schubert #endif 205*7f2fe78bSCy Schubert 206*7f2fe78bSCy Schubert #if defined(NEED_INSIXADDR_ANY) 207*7f2fe78bSCy Schubert /* If compiling with IPv6 support and C library does not define in6addr_any */ 208*7f2fe78bSCy Schubert extern const struct in6_addr krb5int_in6addr_any; 209*7f2fe78bSCy Schubert #undef in6addr_any 210*7f2fe78bSCy Schubert #define in6addr_any krb5int_in6addr_any 211*7f2fe78bSCy Schubert #endif 212*7f2fe78bSCy Schubert 213*7f2fe78bSCy Schubert /* Call out to stuff defined in libkrb5support. */ 214*7f2fe78bSCy Schubert extern int krb5int_getaddrinfo (const char *node, const char *service, 215*7f2fe78bSCy Schubert const struct addrinfo *hints, 216*7f2fe78bSCy Schubert struct addrinfo **aip); 217*7f2fe78bSCy Schubert extern void krb5int_freeaddrinfo (struct addrinfo *ai); 218*7f2fe78bSCy Schubert extern const char *krb5int_gai_strerror(int err); 219*7f2fe78bSCy Schubert extern int krb5int_getnameinfo (const struct sockaddr *sa, socklen_t salen, 220*7f2fe78bSCy Schubert char *hbuf, size_t hbuflen, 221*7f2fe78bSCy Schubert char *sbuf, size_t sbuflen, 222*7f2fe78bSCy Schubert int flags); 223*7f2fe78bSCy Schubert #ifndef IMPLEMENT_FAKE_GETADDRINFO 224*7f2fe78bSCy Schubert #undef getaddrinfo 225*7f2fe78bSCy Schubert #define getaddrinfo krb5int_getaddrinfo 226*7f2fe78bSCy Schubert #undef freeaddrinfo 227*7f2fe78bSCy Schubert #define freeaddrinfo krb5int_freeaddrinfo 228*7f2fe78bSCy Schubert #undef gai_strerror 229*7f2fe78bSCy Schubert #define gai_strerror krb5int_gai_strerror 230*7f2fe78bSCy Schubert #undef getnameinfo 231*7f2fe78bSCy Schubert #define getnameinfo krb5int_getnameinfo 232*7f2fe78bSCy Schubert #endif 233*7f2fe78bSCy Schubert 234*7f2fe78bSCy Schubert #endif /* FAI_DEFINED */ 235