xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/myaddrinfo.h (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1*33881f77Schristos /*	$NetBSD: myaddrinfo.h,v 1.3 2020/03/18 19:05:21 christos Exp $	*/
241fbaed0Stron 
341fbaed0Stron #ifndef _MYADDRINFO_H_INCLUDED_
441fbaed0Stron #define _MYADDRINFO_H_INCLUDED_
541fbaed0Stron 
641fbaed0Stron /*++
741fbaed0Stron /* NAME
841fbaed0Stron /*	myaddrinfo 3h
941fbaed0Stron /* SUMMARY
1041fbaed0Stron /*	addrinfo encapsulation and emulation
1141fbaed0Stron /* SYNOPSIS
1241fbaed0Stron /*	#include <myaddrinfo.h>
1341fbaed0Stron /* DESCRIPTION
1441fbaed0Stron /* .nf
1541fbaed0Stron 
1641fbaed0Stron  /*
1741fbaed0Stron   * System library.
1841fbaed0Stron   */
1941fbaed0Stron #include <sys/types.h>
2041fbaed0Stron #include <sys/socket.h>
2141fbaed0Stron #include <netinet/in.h>
2241fbaed0Stron #include <netdb.h>
2341fbaed0Stron #include <string.h>
2441fbaed0Stron #include <errno.h>			/* MAI_STRERROR() */
2541fbaed0Stron #include <limits.h>			/* CHAR_BIT */
2641fbaed0Stron 
2741fbaed0Stron  /*
2841fbaed0Stron   * Backwards compatibility support for IPV4 systems without addrinfo API.
2941fbaed0Stron   */
3041fbaed0Stron #ifdef EMULATE_IPV4_ADDRINFO
3141fbaed0Stron 
3241fbaed0Stron  /*
3341fbaed0Stron   * Avoid clashes with global symbols, just in case some third-party library
3441fbaed0Stron   * provides its own addrinfo() implementation. This also allows us to test
3541fbaed0Stron   * the IPV4 emulation code on an IPV6 enabled system.
3641fbaed0Stron   */
3741fbaed0Stron #undef  freeaddrinfo
3841fbaed0Stron #define freeaddrinfo	mai_freeaddrinfo
3941fbaed0Stron #undef  gai_strerror
4041fbaed0Stron #define gai_strerror	mai_strerror
4141fbaed0Stron #undef  addrinfo
4241fbaed0Stron #define addrinfo	mai_addrinfo
4341fbaed0Stron #undef  sockaddr_storage
4441fbaed0Stron #define sockaddr_storage mai_sockaddr_storage
4541fbaed0Stron 
4641fbaed0Stron  /*
4741fbaed0Stron   * Modern systems define this in <netdb.h>.
4841fbaed0Stron   */
4941fbaed0Stron struct addrinfo {
5041fbaed0Stron     int     ai_flags;			/* AI_PASSIVE|CANONNAME|NUMERICHOST */
5141fbaed0Stron     int     ai_family;			/* PF_xxx */
5241fbaed0Stron     int     ai_socktype;		/* SOCK_xxx */
5341fbaed0Stron     int     ai_protocol;		/* 0 or IPPROTO_xxx */
5441fbaed0Stron     size_t  ai_addrlen;			/* length of ai_addr */
5541fbaed0Stron     char   *ai_canonname;		/* canonical name for nodename */
5641fbaed0Stron     struct sockaddr *ai_addr;		/* binary address */
5741fbaed0Stron     struct addrinfo *ai_next;		/* next structure in linked list */
5841fbaed0Stron };
5941fbaed0Stron 
6041fbaed0Stron  /*
6141fbaed0Stron   * Modern systems define this in <sys/socket.h>.
6241fbaed0Stron   */
6341fbaed0Stron struct sockaddr_storage {
6441fbaed0Stron     struct sockaddr_in dummy;		/* alignment!! */
6541fbaed0Stron };
6641fbaed0Stron 
6741fbaed0Stron  /*
6841fbaed0Stron   * Result codes. See gai_strerror() for text. Undefine already imported
6941fbaed0Stron   * definitions so that we can test the IPv4-only emulation on a modern
7041fbaed0Stron   * system without getting a ton of compiler warnings.
7141fbaed0Stron   */
7241fbaed0Stron #undef  EAI_ADDRFAMILY
7341fbaed0Stron #define EAI_ADDRFAMILY   1
7441fbaed0Stron #undef  EAI_AGAIN
7541fbaed0Stron #define EAI_AGAIN        2
7641fbaed0Stron #undef  EAI_BADFLAGS
7741fbaed0Stron #define EAI_BADFLAGS     3
7841fbaed0Stron #undef  EAI_FAIL
7941fbaed0Stron #define EAI_FAIL         4
8041fbaed0Stron #undef  EAI_FAMILY
8141fbaed0Stron #define EAI_FAMILY       5
8241fbaed0Stron #undef  EAI_MEMORY
8341fbaed0Stron #define EAI_MEMORY       6
8441fbaed0Stron #undef  EAI_NODATA
8541fbaed0Stron #define EAI_NODATA       7
8641fbaed0Stron #undef  EAI_NONAME
8741fbaed0Stron #define EAI_NONAME       8
8841fbaed0Stron #undef  EAI_SERVICE
8941fbaed0Stron #define EAI_SERVICE      9
9041fbaed0Stron #undef  EAI_SOCKTYPE
9141fbaed0Stron #define EAI_SOCKTYPE    10
9241fbaed0Stron #undef  EAI_SYSTEM
9341fbaed0Stron #define EAI_SYSTEM      11
9441fbaed0Stron #undef  EAI_BADHINTS
9541fbaed0Stron #define EAI_BADHINTS    12
9641fbaed0Stron #undef  EAI_PROTOCOL
9741fbaed0Stron #define EAI_PROTOCOL    13
9841fbaed0Stron #undef  EAI_RESNULL
9941fbaed0Stron #define EAI_RESNULL     14
10041fbaed0Stron #undef  EAI_MAX
10141fbaed0Stron #define EAI_MAX         15
10241fbaed0Stron 
10341fbaed0Stron extern void freeaddrinfo(struct addrinfo *);
10441fbaed0Stron extern char *gai_strerror(int);
10541fbaed0Stron 
10641fbaed0Stron #endif
10741fbaed0Stron 
10841fbaed0Stron  /*
10941fbaed0Stron   * Bounds grow in leaps. These macros attempt to keep non-library code free
11041fbaed0Stron   * from IPV6 #ifdef pollution. Avoid macro names that end in STRLEN because
11141fbaed0Stron   * they suggest that space for the null terminator is not included.
11241fbaed0Stron   */
11341fbaed0Stron #ifdef HAS_IPV6
11441fbaed0Stron # define MAI_HOSTADDR_STRSIZE	INET6_ADDRSTRLEN
11541fbaed0Stron #else
11641fbaed0Stron # ifndef INET_ADDRSTRLEN
11741fbaed0Stron #  define INET_ADDRSTRLEN	16
11841fbaed0Stron # endif
11941fbaed0Stron # define MAI_HOSTADDR_STRSIZE	INET_ADDRSTRLEN
12041fbaed0Stron #endif
12141fbaed0Stron 
12241fbaed0Stron #define MAI_HOSTNAME_STRSIZE	1025
12341fbaed0Stron #define MAI_SERVNAME_STRSIZE	32
12441fbaed0Stron #define MAI_SERVPORT_STRSIZE	sizeof("65535")
12541fbaed0Stron 
12641fbaed0Stron #define MAI_V4ADDR_BITS		32
12741fbaed0Stron #define MAI_V6ADDR_BITS		128
12841fbaed0Stron #define MAI_V4ADDR_BYTES	((MAI_V4ADDR_BITS + (CHAR_BIT - 1))/CHAR_BIT)
12941fbaed0Stron #define MAI_V6ADDR_BYTES	((MAI_V6ADDR_BITS + (CHAR_BIT - 1))/CHAR_BIT)
13041fbaed0Stron 
13141fbaed0Stron  /*
13241fbaed0Stron   * Routines and data structures to hide some of the complexity of the
13341fbaed0Stron   * addrinfo API. They still don't hide that we may get results for address
13441fbaed0Stron   * families that we aren't interested in.
13541fbaed0Stron   *
13641fbaed0Stron   * Note: the getnameinfo() and inet_ntop() system library functions use unsafe
13741fbaed0Stron   * APIs with separate pointer and length arguments. To avoid buffer overflow
13841fbaed0Stron   * problems with these functions, Postfix uses pointers to structures
13941fbaed0Stron   * internally. This way the compiler can enforce that callers provide
14041fbaed0Stron   * buffers with the appropriate length, instead of having to trust that
14141fbaed0Stron   * callers will never mess up some length calculation.
14241fbaed0Stron   */
14341fbaed0Stron typedef struct {
14441fbaed0Stron     char    buf[MAI_HOSTNAME_STRSIZE];
14541fbaed0Stron } MAI_HOSTNAME_STR;
14641fbaed0Stron 
14741fbaed0Stron typedef struct {
14841fbaed0Stron     char    buf[MAI_HOSTADDR_STRSIZE];
14941fbaed0Stron } MAI_HOSTADDR_STR;
15041fbaed0Stron 
15141fbaed0Stron typedef struct {
15241fbaed0Stron     char    buf[MAI_SERVNAME_STRSIZE];
15341fbaed0Stron } MAI_SERVNAME_STR;
15441fbaed0Stron 
15541fbaed0Stron typedef struct {
15641fbaed0Stron     char    buf[MAI_SERVPORT_STRSIZE];
15741fbaed0Stron } MAI_SERVPORT_STR;
15841fbaed0Stron 
159e262b48eSchristos extern int WARN_UNUSED_RESULT hostname_to_sockaddr_pf(const char *,
160e262b48eSchristos 			        int, const char *, int, struct addrinfo **);
161e262b48eSchristos extern int WARN_UNUSED_RESULT hostaddr_to_sockaddr(const char *,
162e262b48eSchristos 			             const char *, int, struct addrinfo **);
163e262b48eSchristos extern int WARN_UNUSED_RESULT sockaddr_to_hostaddr(const struct sockaddr *,
164e262b48eSchristos 	        SOCKADDR_SIZE, MAI_HOSTADDR_STR *, MAI_SERVPORT_STR *, int);
165e262b48eSchristos extern int WARN_UNUSED_RESULT sockaddr_to_hostname(const struct sockaddr *,
166e262b48eSchristos 	        SOCKADDR_SIZE, MAI_HOSTNAME_STR *, MAI_SERVNAME_STR *, int);
16741fbaed0Stron extern void myaddrinfo_control(int,...);
16841fbaed0Stron 
16941fbaed0Stron #define MAI_CTL_END	0		/* list terminator */
17041fbaed0Stron 
17141fbaed0Stron #define MAI_STRERROR(e) ((e) == EAI_SYSTEM ? strerror(errno) : gai_strerror(e))
17241fbaed0Stron 
173ff6d749dStron #define hostname_to_sockaddr(host, serv, sock, res) \
174ff6d749dStron 	hostname_to_sockaddr_pf((host), PF_UNSPEC, (serv), (sock), (res))
175ff6d749dStron 
17641fbaed0Stron  /*
17741fbaed0Stron   * Macros for the case where we really don't want to be bothered with things
17841fbaed0Stron   * that may fail.
17941fbaed0Stron   */
180ff6d749dStron #define HOSTNAME_TO_SOCKADDR_PF(host, pf, serv, sock, res) \
18141fbaed0Stron     do { \
18241fbaed0Stron 	int _aierr; \
183ff6d749dStron 	_aierr = hostname_to_sockaddr_pf((host), (pf), (serv), (sock), (res)); \
18441fbaed0Stron 	if (_aierr) \
185ff6d749dStron 	    msg_fatal("hostname_to_sockaddr_pf: %s", MAI_STRERROR(_aierr)); \
18641fbaed0Stron     } while (0)
18741fbaed0Stron 
188ff6d749dStron #define HOSTNAME_TO_SOCKADDR(host, serv, sock, res) \
189ff6d749dStron 	HOSTNAME_TO_SOCKADDR_PF((host), PF_UNSPEC, (serv), (sock), (res))
190ff6d749dStron 
19141fbaed0Stron #define HOSTADDR_TO_SOCKADDR(host, serv, sock, res) \
19241fbaed0Stron     do { \
19341fbaed0Stron 	int _aierr; \
19441fbaed0Stron 	_aierr = hostaddr_to_sockaddr((host), (serv), (sock), (res)); \
19541fbaed0Stron 	if (_aierr) \
19641fbaed0Stron 	    msg_fatal("hostaddr_to_sockaddr: %s", MAI_STRERROR(_aierr)); \
19741fbaed0Stron     } while (0)
19841fbaed0Stron 
19941fbaed0Stron #define SOCKADDR_TO_HOSTADDR(sa, salen, host, port, sock) \
20041fbaed0Stron     do { \
20141fbaed0Stron 	int _aierr; \
20241fbaed0Stron 	_aierr = sockaddr_to_hostaddr((sa), (salen), (host), (port), (sock)); \
20341fbaed0Stron 	if (_aierr) \
20441fbaed0Stron 	    msg_fatal("sockaddr_to_hostaddr: %s", MAI_STRERROR(_aierr)); \
20541fbaed0Stron     } while (0)
20641fbaed0Stron 
20741fbaed0Stron #define SOCKADDR_TO_HOSTNAME(sa, salen, host, service, sock) \
20841fbaed0Stron     do { \
20941fbaed0Stron 	int _aierr; \
21041fbaed0Stron 	_aierr = sockaddr_to_hostname((sa), (salen), (host), (service), (sock)); \
21141fbaed0Stron 	if (_aierr) \
21241fbaed0Stron 	    msg_fatal("sockaddr_to_hostname: %s", MAI_STRERROR(_aierr)); \
21341fbaed0Stron     } while (0)
21441fbaed0Stron 
21541fbaed0Stron /* LICENSE
21641fbaed0Stron /* .ad
21741fbaed0Stron /* .fi
21841fbaed0Stron /*	The Secure Mailer license must be distributed with this software.
21941fbaed0Stron /* AUTHOR(S)
22041fbaed0Stron /*	Wietse Venema
22141fbaed0Stron /*	IBM T.J. Watson Research
22241fbaed0Stron /*	P.O. Box 704
22341fbaed0Stron /*	Yorktown Heights, NY 10598, USA
224*33881f77Schristos /*
225*33881f77Schristos /*	Wietse Venema
226*33881f77Schristos /*	Google, Inc.
227*33881f77Schristos /*	111 8th Avenue
228*33881f77Schristos /*	New York, NY 10011, USA
22941fbaed0Stron /*--*/
23041fbaed0Stron 
23141fbaed0Stron #endif
232