3 #ifndef _MYADDRINFO_H_INCLUDED_
4 #define _MYADDRINFO_H_INCLUDED_
10 /* addrinfo encapsulation and emulation
12 /* #include <myaddrinfo.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
24 #include <errno.h> /* MAI_STRERROR() */
25 #include <limits.h> /* CHAR_BIT */
28 * Backwards compatibility support for IPV4 systems without addrinfo API.
30 #ifdef EMULATE_IPV4_ADDRINFO
33 * Avoid clashes with global symbols, just in case some third-party library
34 * provides its own addrinfo() implementation. This also allows us to test
35 * the IPV4 emulation code on an IPV6 enabled system.
38 #define freeaddrinfo mai_freeaddrinfo
40 #define gai_strerror mai_strerror
42 #define addrinfo mai_addrinfo
43 #undef sockaddr_storage
44 #define sockaddr_storage mai_sockaddr_storage
47 * Modern systems define this in <netdb.h>.
50 int ai_flags
; /* AI_PASSIVE|CANONNAME|NUMERICHOST */
51 int ai_family
; /* PF_xxx */
52 int ai_socktype
; /* SOCK_xxx */
53 int ai_protocol
; /* 0 or IPPROTO_xxx */
54 size_t ai_addrlen
; /* length of ai_addr */
55 char *ai_canonname
; /* canonical name for nodename */
56 struct sockaddr
*ai_addr
; /* binary address */
57 struct addrinfo
*ai_next
; /* next structure in linked list */
61 * Modern systems define this in <sys/socket.h>.
63 struct sockaddr_storage
{
64 struct sockaddr_in dummy
; /* alignment!! */
68 * Result codes. See gai_strerror() for text. Undefine already imported
69 * definitions so that we can test the IPv4-only emulation on a modern
70 * system without getting a ton of compiler warnings.
73 #define EAI_ADDRFAMILY 1
77 #define EAI_BADFLAGS 3
91 #define EAI_SOCKTYPE 10
95 #define EAI_BADHINTS 12
97 #define EAI_PROTOCOL 13
99 #define EAI_RESNULL 14
103 extern void freeaddrinfo(struct addrinfo
*);
104 extern char *gai_strerror(int);
109 * Bounds grow in leaps. These macros attempt to keep non-library code free
110 * from IPV6 #ifdef pollution. Avoid macro names that end in STRLEN because
111 * they suggest that space for the null terminator is not included.
114 # define MAI_HOSTADDR_STRSIZE INET6_ADDRSTRLEN
116 # ifndef INET_ADDRSTRLEN
117 # define INET_ADDRSTRLEN 16
119 # define MAI_HOSTADDR_STRSIZE INET_ADDRSTRLEN
122 #define MAI_HOSTNAME_STRSIZE 1025
123 #define MAI_SERVNAME_STRSIZE 32
124 #define MAI_SERVPORT_STRSIZE sizeof("65535")
126 #define MAI_V4ADDR_BITS 32
127 #define MAI_V6ADDR_BITS 128
128 #define MAI_V4ADDR_BYTES ((MAI_V4ADDR_BITS + (CHAR_BIT - 1))/CHAR_BIT)
129 #define MAI_V6ADDR_BYTES ((MAI_V6ADDR_BITS + (CHAR_BIT - 1))/CHAR_BIT)
132 * Routines and data structures to hide some of the complexity of the
133 * addrinfo API. They still don't hide that we may get results for address
134 * families that we aren't interested in.
136 * Note: the getnameinfo() and inet_ntop() system library functions use unsafe
137 * APIs with separate pointer and length arguments. To avoid buffer overflow
138 * problems with these functions, Postfix uses pointers to structures
139 * internally. This way the compiler can enforce that callers provide
140 * buffers with the appropriate length, instead of having to trust that
141 * callers will never mess up some length calculation.
144 char buf
[MAI_HOSTNAME_STRSIZE
];
148 char buf
[MAI_HOSTADDR_STRSIZE
];
152 char buf
[MAI_SERVNAME_STRSIZE
];
156 char buf
[MAI_SERVPORT_STRSIZE
];
159 extern int hostname_to_sockaddr(const char *, const char *, int,
161 extern int hostaddr_to_sockaddr(const char *, const char *, int,
163 extern int sockaddr_to_hostaddr(const struct sockaddr
*, SOCKADDR_SIZE
,
164 MAI_HOSTADDR_STR
*, MAI_SERVPORT_STR
*, int);
165 extern int sockaddr_to_hostname(const struct sockaddr
*, SOCKADDR_SIZE
,
166 MAI_HOSTNAME_STR
*, MAI_SERVNAME_STR
*, int);
167 extern void myaddrinfo_control(int,...);
169 #define MAI_CTL_END 0 /* list terminator */
171 #define MAI_STRERROR(e) ((e) == EAI_SYSTEM ? strerror(errno) : gai_strerror(e))
174 * Macros for the case where we really don't want to be bothered with things
177 #define HOSTNAME_TO_SOCKADDR(host, serv, sock, res) \
180 _aierr = hostname_to_sockaddr((host), (serv), (sock), (res)); \
182 msg_fatal("hostname_to_sockaddr: %s", MAI_STRERROR(_aierr)); \
185 #define HOSTADDR_TO_SOCKADDR(host, serv, sock, res) \
188 _aierr = hostaddr_to_sockaddr((host), (serv), (sock), (res)); \
190 msg_fatal("hostaddr_to_sockaddr: %s", MAI_STRERROR(_aierr)); \
193 #define SOCKADDR_TO_HOSTADDR(sa, salen, host, port, sock) \
196 _aierr = sockaddr_to_hostaddr((sa), (salen), (host), (port), (sock)); \
198 msg_fatal("sockaddr_to_hostaddr: %s", MAI_STRERROR(_aierr)); \
201 #define SOCKADDR_TO_HOSTNAME(sa, salen, host, service, sock) \
204 _aierr = sockaddr_to_hostname((sa), (salen), (host), (service), (sock)); \
206 msg_fatal("sockaddr_to_hostname: %s", MAI_STRERROR(_aierr)); \
212 /* The Secure Mailer license must be distributed with this software.
215 /* IBM T.J. Watson Research
217 /* Yorktown Heights, NY 10598, USA