No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / myaddrinfo.h
blobc257b472a3b1c8e91d7a2d270aa919763b8f23fa
1 /* $NetBSD$ */
3 #ifndef _MYADDRINFO_H_INCLUDED_
4 #define _MYADDRINFO_H_INCLUDED_
6 /*++
7 /* NAME
8 /* myaddrinfo 3h
9 /* SUMMARY
10 /* addrinfo encapsulation and emulation
11 /* SYNOPSIS
12 /* #include <myaddrinfo.h>
13 /* DESCRIPTION
14 /* .nf
17 * System library.
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <netdb.h>
23 #include <string.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.
37 #undef freeaddrinfo
38 #define freeaddrinfo mai_freeaddrinfo
39 #undef gai_strerror
40 #define gai_strerror mai_strerror
41 #undef addrinfo
42 #define addrinfo mai_addrinfo
43 #undef sockaddr_storage
44 #define sockaddr_storage mai_sockaddr_storage
47 * Modern systems define this in <netdb.h>.
49 struct addrinfo {
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.
72 #undef EAI_ADDRFAMILY
73 #define EAI_ADDRFAMILY 1
74 #undef EAI_AGAIN
75 #define EAI_AGAIN 2
76 #undef EAI_BADFLAGS
77 #define EAI_BADFLAGS 3
78 #undef EAI_FAIL
79 #define EAI_FAIL 4
80 #undef EAI_FAMILY
81 #define EAI_FAMILY 5
82 #undef EAI_MEMORY
83 #define EAI_MEMORY 6
84 #undef EAI_NODATA
85 #define EAI_NODATA 7
86 #undef EAI_NONAME
87 #define EAI_NONAME 8
88 #undef EAI_SERVICE
89 #define EAI_SERVICE 9
90 #undef EAI_SOCKTYPE
91 #define EAI_SOCKTYPE 10
92 #undef EAI_SYSTEM
93 #define EAI_SYSTEM 11
94 #undef EAI_BADHINTS
95 #define EAI_BADHINTS 12
96 #undef EAI_PROTOCOL
97 #define EAI_PROTOCOL 13
98 #undef EAI_RESNULL
99 #define EAI_RESNULL 14
100 #undef EAI_MAX
101 #define EAI_MAX 15
103 extern void freeaddrinfo(struct addrinfo *);
104 extern char *gai_strerror(int);
106 #endif
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.
113 #ifdef HAS_IPV6
114 # define MAI_HOSTADDR_STRSIZE INET6_ADDRSTRLEN
115 #else
116 # ifndef INET_ADDRSTRLEN
117 # define INET_ADDRSTRLEN 16
118 # endif
119 # define MAI_HOSTADDR_STRSIZE INET_ADDRSTRLEN
120 #endif
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.
143 typedef struct {
144 char buf[MAI_HOSTNAME_STRSIZE];
145 } MAI_HOSTNAME_STR;
147 typedef struct {
148 char buf[MAI_HOSTADDR_STRSIZE];
149 } MAI_HOSTADDR_STR;
151 typedef struct {
152 char buf[MAI_SERVNAME_STRSIZE];
153 } MAI_SERVNAME_STR;
155 typedef struct {
156 char buf[MAI_SERVPORT_STRSIZE];
157 } MAI_SERVPORT_STR;
159 extern int hostname_to_sockaddr(const char *, const char *, int,
160 struct addrinfo **);
161 extern int hostaddr_to_sockaddr(const char *, const char *, int,
162 struct addrinfo **);
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
175 * that may fail.
177 #define HOSTNAME_TO_SOCKADDR(host, serv, sock, res) \
178 do { \
179 int _aierr; \
180 _aierr = hostname_to_sockaddr((host), (serv), (sock), (res)); \
181 if (_aierr) \
182 msg_fatal("hostname_to_sockaddr: %s", MAI_STRERROR(_aierr)); \
183 } while (0)
185 #define HOSTADDR_TO_SOCKADDR(host, serv, sock, res) \
186 do { \
187 int _aierr; \
188 _aierr = hostaddr_to_sockaddr((host), (serv), (sock), (res)); \
189 if (_aierr) \
190 msg_fatal("hostaddr_to_sockaddr: %s", MAI_STRERROR(_aierr)); \
191 } while (0)
193 #define SOCKADDR_TO_HOSTADDR(sa, salen, host, port, sock) \
194 do { \
195 int _aierr; \
196 _aierr = sockaddr_to_hostaddr((sa), (salen), (host), (port), (sock)); \
197 if (_aierr) \
198 msg_fatal("sockaddr_to_hostaddr: %s", MAI_STRERROR(_aierr)); \
199 } while (0)
201 #define SOCKADDR_TO_HOSTNAME(sa, salen, host, service, sock) \
202 do { \
203 int _aierr; \
204 _aierr = sockaddr_to_hostname((sa), (salen), (host), (service), (sock)); \
205 if (_aierr) \
206 msg_fatal("sockaddr_to_hostname: %s", MAI_STRERROR(_aierr)); \
207 } while (0)
209 /* LICENSE
210 /* .ad
211 /* .fi
212 /* The Secure Mailer license must be distributed with this software.
213 /* AUTHOR(S)
214 /* Wietse Venema
215 /* IBM T.J. Watson Research
216 /* P.O. Box 704
217 /* Yorktown Heights, NY 10598, USA
218 /*--*/
220 #endif