2N/A/*
2N/A * Copyright (C) 2001,2002,2003,2004 by the Massachusetts Institute of Technology,
2N/A * Cambridge, MA, USA. All Rights Reserved.
2N/A *
2N/A * This software is being provided to you, the LICENSEE, by the
2N/A * Massachusetts Institute of Technology (M.I.T.) under the following
2N/A * license. By obtaining, using and/or copying this software, you agree
2N/A * that you have read, understood, and will comply with these terms and
2N/A * conditions:
2N/A *
2N/A * Export of this software from the United States of America may
2N/A * require a specific license from the United States Government.
2N/A * It is the responsibility of any person or organization contemplating
2N/A * export to obtain such a license before exporting.
2N/A *
2N/A * WITHIN THAT CONSTRAINT, permission to use, copy, modify and distribute
2N/A * this software and its documentation for any purpose and without fee or
2N/A * royalty is hereby granted, provided that you agree to comply with the
2N/A * following copyright notice and statements, including the disclaimer, and
2N/A * that the same appear on ALL copies of the software and documentation,
2N/A * including modifications that you make for internal use or for
2N/A * distribution:
2N/A *
2N/A * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS
2N/A * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not
2N/A * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF
2N/A * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
2N/A * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
2N/A * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
2N/A *
2N/A * The name of the Massachusetts Institute of Technology or M.I.T. may NOT
2N/A * be used in advertising or publicity pertaining to distribution of the
2N/A * software. Title to copyright in this software and any associated
2N/A * documentation shall at all times remain with M.I.T., and USER agrees to
2N/A * preserve same.
2N/A *
2N/A * Furthermore if you modify this software you must label
2N/A * your software as modified software and not distribute it in such a
2N/A * fashion that it might be confused with the original M.I.T. software.
2N/A */
2N/A
2N/A/* Approach overview:
2N/A
2N/A If a system version is available but buggy, save handles to it (via
2N/A inline functions in a support library), redefine the names to refer
2N/A to library functions, and in those functions, call the system
2N/A versions and fix up the returned data. Use the native data
2N/A structures and flag values.
2N/A
2N/A If no system version exists, use gethostby* and fake it. Define
2N/A the data structures and flag values locally.
2N/A
2N/A
2N/A On Mac OS X, getaddrinfo results aren't cached (though
2N/A gethostbyname results are), so we need to build a cache here. Now
2N/A things are getting really messy. Because the cache is in use, we
2N/A use getservbyname, and throw away thread safety. (Not that the
2N/A cache is thread safe, but when we get locking support, that'll be
2N/A dealt with.) This code needs tearing down and rebuilding, soon.
2N/A
2N/A
2N/A Note that recent Windows developers' code has an interesting hack:
2N/A When you include the right header files, with the right set of
2N/A macros indicating system versions, you'll get an inline function
2N/A that looks for getaddrinfo (or whatever) in the system library, and
2N/A calls it if it's there. If it's not there, it fakes it with
2N/A gethostby* calls.
2N/A
2N/A We're taking a simpler approach: A system provides these routines or
2N/A it does not.
2N/A
2N/A Someday, we may want to take into account different versions (say,
2N/A different revs of GNU libc) where some are broken in one way, and
2N/A some work or are broken in another way. Cross that bridge when we
2N/A come to it. */
2N/A
2N/A/* To do, maybe:
2N/A
2N/A + For AIX 4.3.3, using the RFC 2133 definition: Implement
2N/A AI_NUMERICHOST. It's not defined in the header file.
2N/A
2N/A For certain (old?) versions of GNU libc, AI_NUMERICHOST is
2N/A defined but not implemented.
2N/A
2N/A + Use gethostbyname2, inet_aton and other IPv6 or thread-safe
2N/A functions if available. But, see
2N/A http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=135182 for one
2N/A gethostbyname2 problem on Linux. And besides, if a platform is
2N/A supporting IPv6 at all, they really should be doing getaddrinfo
2N/A by now.
2N/A
2N/A + inet_ntop, inet_pton
2N/A
2N/A + Conditionally export/import the function definitions, so a
2N/A library can have a single copy instead of multiple.
2N/A
2N/A + Upgrade host requirements to include working implementations of
2N/A these functions, and throw all this away. Pleeease? :-) */
2N/A
2N/A#ifndef FAI_DEFINED
2N/A#define FAI_DEFINED
2N/A#include "port-sockets.h"
2N/A#include "socket-utils.h"
2N/A
2N/A#if !defined (HAVE_GETADDRINFO)
2N/A
2N/A#undef addrinfo
2N/A#define addrinfo my_fake_addrinfo
2N/A
2N/Astruct addrinfo {
2N/A int ai_family; /* PF_foo */
2N/A int ai_socktype; /* SOCK_foo */
2N/A int ai_protocol; /* 0, IPPROTO_foo */
2N/A int ai_flags; /* AI_PASSIVE etc */
2N/A size_t ai_addrlen; /* real length of socket address */
2N/A char *ai_canonname; /* canonical name of host */
2N/A struct sockaddr *ai_addr; /* pointer to variable-size address */
2N/A struct addrinfo *ai_next; /* next in linked list */
2N/A};
2N/A
2N/A#undef AI_PASSIVE
2N/A#define AI_PASSIVE 0x01
2N/A#undef AI_CANONNAME
2N/A#define AI_CANONNAME 0x02
2N/A#undef AI_NUMERICHOST
2N/A#define AI_NUMERICHOST 0x04
2N/A/* RFC 2553 says these are part of the interface for getipnodebyname,
2N/A not for getaddrinfo. RFC 3493 says they're part of the interface
2N/A for getaddrinfo, and getipnodeby* are deprecated. Our fake
2N/A getaddrinfo implementation here does IPv4 only anyways. */
2N/A#undef AI_V4MAPPED
2N/A#define AI_V4MAPPED 0
2N/A#undef AI_ADDRCONFIG
2N/A#define AI_ADDRCONFIG 0
2N/A#undef AI_ALL
2N/A#define AI_ALL 0
2N/A#undef AI_DEFAULT
2N/A#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG)
2N/A
2N/A#ifndef NI_MAXHOST
2N/A#define NI_MAXHOST 1025
2N/A#endif
2N/A#ifndef NI_MAXSERV
2N/A#define NI_MAXSERV 32
2N/A#endif
2N/A
2N/A#undef NI_NUMERICHOST
2N/A#define NI_NUMERICHOST 0x01
2N/A#undef NI_NUMERICSERV
2N/A#define NI_NUMERICSERV 0x02
2N/A#undef NI_NAMEREQD
2N/A#define NI_NAMEREQD 0x04
2N/A#undef NI_DGRAM
2N/A#define NI_DGRAM 0x08
2N/A#undef NI_NOFQDN
2N/A#define NI_NOFQDN 0x10
2N/A
2N/A
2N/A#undef EAI_ADDRFAMILY
2N/A#define EAI_ADDRFAMILY 1
2N/A#undef EAI_AGAIN
2N/A#define EAI_AGAIN 2
2N/A#undef EAI_BADFLAGS
2N/A#define EAI_BADFLAGS 3
2N/A#undef EAI_FAIL
2N/A#define EAI_FAIL 4
2N/A#undef EAI_FAMILY
2N/A#define EAI_FAMILY 5
2N/A#undef EAI_MEMORY
2N/A#define EAI_MEMORY 6
2N/A#undef EAI_NODATA
2N/A#define EAI_NODATA 7
2N/A#undef EAI_NONAME
2N/A#define EAI_NONAME 8
2N/A#undef EAI_SERVICE
2N/A#define EAI_SERVICE 9
2N/A#undef EAI_SOCKTYPE
2N/A#define EAI_SOCKTYPE 10
2N/A#undef EAI_SYSTEM
2N/A#define EAI_SYSTEM 11
2N/A
2N/A#endif /* ! HAVE_GETADDRINFO */
2N/A
2N/A/* Fudge things on older gai implementations. */
2N/A/* AIX 4.3.3 is based on RFC 2133; no AI_NUMERICHOST. */
2N/A#ifndef AI_NUMERICHOST
2N/A# define AI_NUMERICHOST 0
2N/A#endif
2N/A/* Partial RFC 2553 implementations may not have AI_ADDRCONFIG and
2N/A friends, which RFC 3493 says are now part of the getaddrinfo
2N/A interface, and we'll want to use. */
2N/A#ifndef AI_ADDRCONFIG
2N/A# define AI_ADDRCONFIG 0
2N/A#endif
2N/A#ifndef AI_V4MAPPED
2N/A# define AI_V4MAPPED 0
2N/A#endif
2N/A#ifndef AI_ALL
2N/A# define AI_ALL 0
2N/A#endif
2N/A#ifndef AI_DEFAULT
2N/A# define AI_DEFAULT (AI_ADDRCONFIG|AI_V4MAPPED)
2N/A#endif
2N/A
2N/A#if defined(KRB5_USE_INET6) && defined(NEED_INSIXADDR_ANY)
2N/A/* If compiling with IPv6 support and C library does not define in6addr_any */
2N/Aextern const struct in6_addr krb5int_in6addr_any;
2N/A#undef in6addr_any
2N/A#define in6addr_any krb5int_in6addr_any
2N/A#endif
2N/A
2N/A/* Call out to stuff defined in libkrb5support. */
2N/Aextern int krb5int_getaddrinfo (const char *node, const char *service,
2N/A const struct addrinfo *hints,
2N/A struct addrinfo **aip);
2N/Aextern void krb5int_freeaddrinfo (struct addrinfo *ai);
2N/Aextern const char *krb5int_gai_strerror(int err);
2N/Aextern int krb5int_getnameinfo (const struct sockaddr *sa, socklen_t salen,
2N/A char *hbuf, size_t hbuflen,
2N/A char *sbuf, size_t sbuflen,
2N/A int flags);
2N/A#ifndef IMPLEMENT_FAKE_GETADDRINFO
2N/A#undef getaddrinfo
2N/A#define getaddrinfo krb5int_getaddrinfo
2N/A#undef freeaddrinfo
2N/A#define freeaddrinfo krb5int_freeaddrinfo
2N/A#undef gai_strerror
2N/A#define gai_strerror krb5int_gai_strerror
2N/A#undef getnameinfo
2N/A#define getnameinfo krb5int_getnameinfo
2N/A#endif
2N/A
2N/A#endif /* FAI_DEFINED */