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