xref: /freebsd/crypto/krb5/src/include/fake-addrinfo.h (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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