10Sstevel@tonic-gate /*
2781Sgtb  * Copyright (C) 2001,2002,2003,2004 by the Massachusetts Institute of Technology,
30Sstevel@tonic-gate  * Cambridge, MA, USA.  All Rights Reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This software is being provided to you, the LICENSEE, by the
60Sstevel@tonic-gate  * Massachusetts Institute of Technology (M.I.T.) under the following
70Sstevel@tonic-gate  * license.  By obtaining, using and/or copying this software, you agree
80Sstevel@tonic-gate  * that you have read, understood, and will comply with these terms and
90Sstevel@tonic-gate  * conditions:
100Sstevel@tonic-gate  *
110Sstevel@tonic-gate  * Export of this software from the United States of America may
120Sstevel@tonic-gate  * require a specific license from the United States Government.
130Sstevel@tonic-gate  * It is the responsibility of any person or organization contemplating
140Sstevel@tonic-gate  * export to obtain such a license before exporting.
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify and distribute
170Sstevel@tonic-gate  * this software and its documentation for any purpose and without fee or
180Sstevel@tonic-gate  * royalty is hereby granted, provided that you agree to comply with the
190Sstevel@tonic-gate  * following copyright notice and statements, including the disclaimer, and
200Sstevel@tonic-gate  * that the same appear on ALL copies of the software and documentation,
210Sstevel@tonic-gate  * including modifications that you make for internal use or for
220Sstevel@tonic-gate  * distribution:
230Sstevel@tonic-gate  *
240Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS
250Sstevel@tonic-gate  * OR WARRANTIES, EXPRESS OR IMPLIED.  By way of example, but not
260Sstevel@tonic-gate  * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF
270Sstevel@tonic-gate  * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
280Sstevel@tonic-gate  * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
290Sstevel@tonic-gate  * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  * The name of the Massachusetts Institute of Technology or M.I.T. may NOT
320Sstevel@tonic-gate  * be used in advertising or publicity pertaining to distribution of the
330Sstevel@tonic-gate  * software.  Title to copyright in this software and any associated
340Sstevel@tonic-gate  * documentation shall at all times remain with M.I.T., and USER agrees to
350Sstevel@tonic-gate  * preserve same.
360Sstevel@tonic-gate  *
370Sstevel@tonic-gate  * Furthermore if you modify this software you must label
380Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
390Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /* Approach overview:
430Sstevel@tonic-gate 
44781Sgtb    If a system version is available but buggy, save handles to it (via
45*7934SMark.Phalan@Sun.COM    inline functions in a support library), redefine the names to refer
46*7934SMark.Phalan@Sun.COM    to library functions, and in those functions, call the system
47*7934SMark.Phalan@Sun.COM    versions and fix up the returned data.  Use the native data
48*7934SMark.Phalan@Sun.COM    structures and flag values.
490Sstevel@tonic-gate 
500Sstevel@tonic-gate    If no system version exists, use gethostby* and fake it.  Define
510Sstevel@tonic-gate    the data structures and flag values locally.
520Sstevel@tonic-gate 
530Sstevel@tonic-gate 
54781Sgtb    On Mac OS X, getaddrinfo results aren't cached (though
55781Sgtb    gethostbyname results are), so we need to build a cache here.  Now
56781Sgtb    things are getting really messy.  Because the cache is in use, we
57781Sgtb    use getservbyname, and throw away thread safety.  (Not that the
58781Sgtb    cache is thread safe, but when we get locking support, that'll be
59781Sgtb    dealt with.)  This code needs tearing down and rebuilding, soon.
60781Sgtb 
61781Sgtb 
620Sstevel@tonic-gate    Note that recent Windows developers' code has an interesting hack:
630Sstevel@tonic-gate    When you include the right header files, with the right set of
640Sstevel@tonic-gate    macros indicating system versions, you'll get an inline function
650Sstevel@tonic-gate    that looks for getaddrinfo (or whatever) in the system library, and
660Sstevel@tonic-gate    calls it if it's there.  If it's not there, it fakes it with
670Sstevel@tonic-gate    gethostby* calls.
680Sstevel@tonic-gate 
690Sstevel@tonic-gate    We're taking a simpler approach: A system provides these routines or
700Sstevel@tonic-gate    it does not.
710Sstevel@tonic-gate 
720Sstevel@tonic-gate    Someday, we may want to take into account different versions (say,
730Sstevel@tonic-gate    different revs of GNU libc) where some are broken in one way, and
740Sstevel@tonic-gate    some work or are broken in another way.  Cross that bridge when we
750Sstevel@tonic-gate    come to it.  */
760Sstevel@tonic-gate 
770Sstevel@tonic-gate /* To do, maybe:
780Sstevel@tonic-gate 
790Sstevel@tonic-gate    + For AIX 4.3.3, using the RFC 2133 definition: Implement
800Sstevel@tonic-gate      AI_NUMERICHOST.  It's not defined in the header file.
810Sstevel@tonic-gate 
820Sstevel@tonic-gate      For certain (old?) versions of GNU libc, AI_NUMERICHOST is
830Sstevel@tonic-gate      defined but not implemented.
840Sstevel@tonic-gate 
850Sstevel@tonic-gate    + Use gethostbyname2, inet_aton and other IPv6 or thread-safe
860Sstevel@tonic-gate      functions if available.  But, see
870Sstevel@tonic-gate      http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=135182 for one
880Sstevel@tonic-gate      gethostbyname2 problem on Linux.  And besides, if a platform is
890Sstevel@tonic-gate      supporting IPv6 at all, they really should be doing getaddrinfo
900Sstevel@tonic-gate      by now.
910Sstevel@tonic-gate 
920Sstevel@tonic-gate    + inet_ntop, inet_pton
930Sstevel@tonic-gate 
94781Sgtb    + Conditionally export/import the function definitions, so a
95781Sgtb      library can have a single copy instead of multiple.
96781Sgtb 
970Sstevel@tonic-gate    + Upgrade host requirements to include working implementations of
980Sstevel@tonic-gate      these functions, and throw all this away.  Pleeease?  :-)  */
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate #ifndef FAI_DEFINED
1010Sstevel@tonic-gate #define FAI_DEFINED
1020Sstevel@tonic-gate #include "port-sockets.h"
1030Sstevel@tonic-gate #include "socket-utils.h"
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate #if !defined (HAVE_GETADDRINFO)
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate #undef  addrinfo
1080Sstevel@tonic-gate #define addrinfo	my_fake_addrinfo
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate struct addrinfo {
1110Sstevel@tonic-gate     int ai_family;		/* PF_foo */
1120Sstevel@tonic-gate     int ai_socktype;		/* SOCK_foo */
1130Sstevel@tonic-gate     int ai_protocol;		/* 0, IPPROTO_foo */
1140Sstevel@tonic-gate     int ai_flags;		/* AI_PASSIVE etc */
1150Sstevel@tonic-gate     size_t ai_addrlen;		/* real length of socket address */
1160Sstevel@tonic-gate     char *ai_canonname;		/* canonical name of host */
1170Sstevel@tonic-gate     struct sockaddr *ai_addr;	/* pointer to variable-size address */
1180Sstevel@tonic-gate     struct addrinfo *ai_next;	/* next in linked list */
1190Sstevel@tonic-gate };
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate #undef	AI_PASSIVE
1220Sstevel@tonic-gate #define	AI_PASSIVE	0x01
1230Sstevel@tonic-gate #undef	AI_CANONNAME
1240Sstevel@tonic-gate #define	AI_CANONNAME	0x02
1250Sstevel@tonic-gate #undef	AI_NUMERICHOST
1260Sstevel@tonic-gate #define	AI_NUMERICHOST	0x04
127781Sgtb /* RFC 2553 says these are part of the interface for getipnodebyname,
128781Sgtb    not for getaddrinfo.  RFC 3493 says they're part of the interface
129781Sgtb    for getaddrinfo, and getipnodeby* are deprecated.  Our fake
130781Sgtb    getaddrinfo implementation here does IPv4 only anyways.  */
1310Sstevel@tonic-gate #undef	AI_V4MAPPED
132781Sgtb #define	AI_V4MAPPED	0
1330Sstevel@tonic-gate #undef	AI_ADDRCONFIG
134781Sgtb #define	AI_ADDRCONFIG	0
1350Sstevel@tonic-gate #undef	AI_ALL
136781Sgtb #define	AI_ALL		0
1370Sstevel@tonic-gate #undef	AI_DEFAULT
138781Sgtb #define	AI_DEFAULT	(AI_V4MAPPED|AI_ADDRCONFIG)
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate #ifndef NI_MAXHOST
1410Sstevel@tonic-gate #define NI_MAXHOST 1025
1420Sstevel@tonic-gate #endif
1430Sstevel@tonic-gate #ifndef NI_MAXSERV
1440Sstevel@tonic-gate #define NI_MAXSERV 32
1450Sstevel@tonic-gate #endif
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate #undef	NI_NUMERICHOST
1480Sstevel@tonic-gate #define NI_NUMERICHOST	0x01
1490Sstevel@tonic-gate #undef	NI_NUMERICSERV
1500Sstevel@tonic-gate #define NI_NUMERICSERV	0x02
1510Sstevel@tonic-gate #undef	NI_NAMEREQD
1520Sstevel@tonic-gate #define NI_NAMEREQD	0x04
1530Sstevel@tonic-gate #undef	NI_DGRAM
1540Sstevel@tonic-gate #define NI_DGRAM	0x08
1550Sstevel@tonic-gate #undef	NI_NOFQDN
1560Sstevel@tonic-gate #define NI_NOFQDN	0x10
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate #undef  EAI_ADDRFAMILY
1600Sstevel@tonic-gate #define EAI_ADDRFAMILY	1
1610Sstevel@tonic-gate #undef  EAI_AGAIN
1620Sstevel@tonic-gate #define EAI_AGAIN	2
1630Sstevel@tonic-gate #undef  EAI_BADFLAGS
1640Sstevel@tonic-gate #define EAI_BADFLAGS	3
1650Sstevel@tonic-gate #undef  EAI_FAIL
1660Sstevel@tonic-gate #define EAI_FAIL	4
1670Sstevel@tonic-gate #undef  EAI_FAMILY
1680Sstevel@tonic-gate #define EAI_FAMILY	5
1690Sstevel@tonic-gate #undef  EAI_MEMORY
1700Sstevel@tonic-gate #define EAI_MEMORY	6
1710Sstevel@tonic-gate #undef  EAI_NODATA
1720Sstevel@tonic-gate #define EAI_NODATA	7
1730Sstevel@tonic-gate #undef  EAI_NONAME
1740Sstevel@tonic-gate #define EAI_NONAME	8
1750Sstevel@tonic-gate #undef  EAI_SERVICE
1760Sstevel@tonic-gate #define EAI_SERVICE	9
1770Sstevel@tonic-gate #undef  EAI_SOCKTYPE
1780Sstevel@tonic-gate #define EAI_SOCKTYPE	10
1790Sstevel@tonic-gate #undef  EAI_SYSTEM
1800Sstevel@tonic-gate #define EAI_SYSTEM	11
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate #endif /* ! HAVE_GETADDRINFO */
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate /* Fudge things on older gai implementations.  */
1850Sstevel@tonic-gate /* AIX 4.3.3 is based on RFC 2133; no AI_NUMERICHOST.  */
1860Sstevel@tonic-gate #ifndef AI_NUMERICHOST
1870Sstevel@tonic-gate # define AI_NUMERICHOST 0
1880Sstevel@tonic-gate #endif
189781Sgtb /* Partial RFC 2553 implementations may not have AI_ADDRCONFIG and
190781Sgtb    friends, which RFC 3493 says are now part of the getaddrinfo
191781Sgtb    interface, and we'll want to use.  */
192781Sgtb #ifndef AI_ADDRCONFIG
193781Sgtb # define AI_ADDRCONFIG 0
194781Sgtb #endif
195781Sgtb #ifndef AI_V4MAPPED
196781Sgtb # define AI_V4MAPPED 0
197781Sgtb #endif
198781Sgtb #ifndef AI_ALL
199781Sgtb # define AI_ALL 0
200781Sgtb #endif
201781Sgtb #ifndef AI_DEFAULT
202781Sgtb # define AI_DEFAULT (AI_ADDRCONFIG|AI_V4MAPPED)
2030Sstevel@tonic-gate #endif
2040Sstevel@tonic-gate 
205*7934SMark.Phalan@Sun.COM #if defined(KRB5_USE_INET6) && defined(NEED_INSIXADDR_ANY)
206*7934SMark.Phalan@Sun.COM /* If compiling with IPv6 support and C library does not define in6addr_any */
207*7934SMark.Phalan@Sun.COM extern const struct in6_addr krb5int_in6addr_any;
208*7934SMark.Phalan@Sun.COM #undef in6addr_any
209*7934SMark.Phalan@Sun.COM #define in6addr_any krb5int_in6addr_any
2100Sstevel@tonic-gate #endif
2110Sstevel@tonic-gate 
212*7934SMark.Phalan@Sun.COM /* Call out to stuff defined in libkrb5support.  */
213*7934SMark.Phalan@Sun.COM extern int krb5int_getaddrinfo (const char *node, const char *service,
214*7934SMark.Phalan@Sun.COM 				const struct addrinfo *hints,
215*7934SMark.Phalan@Sun.COM 				struct addrinfo **aip);
216*7934SMark.Phalan@Sun.COM extern void krb5int_freeaddrinfo (struct addrinfo *ai);
217*7934SMark.Phalan@Sun.COM extern const char *krb5int_gai_strerror(int err);
218*7934SMark.Phalan@Sun.COM extern int krb5int_getnameinfo (const struct sockaddr *sa, socklen_t salen,
219*7934SMark.Phalan@Sun.COM 				char *hbuf, size_t hbuflen,
220*7934SMark.Phalan@Sun.COM 				char *sbuf, size_t sbuflen,
221*7934SMark.Phalan@Sun.COM 				int flags);
222*7934SMark.Phalan@Sun.COM #ifndef IMPLEMENT_FAKE_GETADDRINFO
223*7934SMark.Phalan@Sun.COM #undef	getaddrinfo
224*7934SMark.Phalan@Sun.COM #define getaddrinfo krb5int_getaddrinfo
225*7934SMark.Phalan@Sun.COM #undef  freeaddrinfo
226*7934SMark.Phalan@Sun.COM #define freeaddrinfo krb5int_freeaddrinfo
227*7934SMark.Phalan@Sun.COM #undef  gai_strerror
228*7934SMark.Phalan@Sun.COM #define gai_strerror krb5int_gai_strerror
229*7934SMark.Phalan@Sun.COM #undef  getnameinfo
230*7934SMark.Phalan@Sun.COM #define getnameinfo krb5int_getnameinfo
2310Sstevel@tonic-gate #endif
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate #endif /* FAI_DEFINED */
234