sm_gethost.c revision 90792
164562Sgshapiro/*
273188Sgshapiro *  Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
364562Sgshapiro *	All rights reserved.
464562Sgshapiro *
564562Sgshapiro * By using this file, you agree to the terms and conditions set
664562Sgshapiro * forth in the LICENSE file which can be found at the top level of
764562Sgshapiro * the sendmail distribution.
864562Sgshapiro *
964562Sgshapiro */
1064562Sgshapiro
1190792Sgshapiro#include <sm/gen.h>
1290792SgshapiroSM_RCSID("@(#)$Id: sm_gethost.c,v 8.26 2001/09/11 04:04:45 gshapiro Exp $")
1364562Sgshapiro
1464562Sgshapiro#include <sendmail.h>
1564562Sgshapiro#if NETINET || NETINET6
1664562Sgshapiro# include <arpa/inet.h>
1764562Sgshapiro#endif /* NETINET || NETINET6 */
1864562Sgshapiro
1990792Sgshapiro/*
2064562Sgshapiro**  MI_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
2164562Sgshapiro**
2264562Sgshapiro**	Some operating systems have wierd problems with the gethostbyXXX
2364562Sgshapiro**	routines.  For example, Solaris versions at least through 2.3
2464562Sgshapiro**	don't properly deliver a canonical h_name field.  This tries to
2564562Sgshapiro**	work around these problems.
2664562Sgshapiro**
2764562Sgshapiro**	Support IPv6 as well as IPv4.
2864562Sgshapiro*/
2964562Sgshapiro
3077349Sgshapiro#if NETINET6 && NEEDSGETIPNODE
3164562Sgshapiro
3280785Sgshapiro# ifndef AI_ADDRCONFIG
3380785Sgshapiro#  define AI_ADDRCONFIG	0	/* dummy */
3480785Sgshapiro# endif /* ! AI_ADDRCONFIG */
3564562Sgshapiro# ifndef AI_ALL
3664562Sgshapiro#  define AI_ALL	0	/* dummy */
3764562Sgshapiro# endif /* ! AI_ALL */
3880785Sgshapiro# ifndef AI_DEFAULT
3980785Sgshapiro#  define AI_DEFAULT	0	/* dummy */
4080785Sgshapiro# endif /* ! AI_DEFAULT */
4164562Sgshapiro
4264562Sgshapirostatic struct hostent *
4366494Sgshapirogetipnodebyname(name, family, flags, err)
4464562Sgshapiro	char *name;
4564562Sgshapiro	int family;
4664562Sgshapiro	int flags;
4764562Sgshapiro	int *err;
4864562Sgshapiro{
4990792Sgshapiro	bool resv6 = true;
5064562Sgshapiro	struct hostent *h;
5164562Sgshapiro
5264562Sgshapiro	if (family == AF_INET6)
5364562Sgshapiro	{
5464562Sgshapiro		/* From RFC2133, section 6.1 */
5564562Sgshapiro		resv6 = bitset(RES_USE_INET6, _res.options);
5664562Sgshapiro		_res.options |= RES_USE_INET6;
5764562Sgshapiro	}
5873188Sgshapiro	SM_SET_H_ERRNO(0);
5964562Sgshapiro	h = gethostbyname(name);
6064562Sgshapiro	if (family == AF_INET6 && !resv6)
6164562Sgshapiro		_res.options &= ~RES_USE_INET6;
6290792Sgshapiro	*err = h_errno;
6364562Sgshapiro	return h;
6464562Sgshapiro}
6571345Sgshapiro
6671345Sgshapirovoid
6771345Sgshapirofreehostent(h)
6871345Sgshapiro	struct hostent *h;
6971345Sgshapiro{
7071345Sgshapiro	/*
7171345Sgshapiro	**  Stub routine -- if they don't have getipnodeby*(),
7271345Sgshapiro	**  they probably don't have the free routine either.
7371345Sgshapiro	*/
7471345Sgshapiro
7571345Sgshapiro	return;
7671345Sgshapiro}
7777349Sgshapiro#endif /* NEEDSGETIPNODE && NETINET6 */
7864562Sgshapiro
7964562Sgshapirostruct hostent *
8064562Sgshapiromi_gethostbyname(name, family)
8164562Sgshapiro	char *name;
8264562Sgshapiro	int family;
8364562Sgshapiro{
8464562Sgshapiro	struct hostent *h = NULL;
8564562Sgshapiro#if (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4))
8664562Sgshapiro# if SOLARIS == 20300 || SOLARIS == 203
8764562Sgshapiro	static struct hostent hp;
8864562Sgshapiro	static char buf[1000];
8964562Sgshapiro	extern struct hostent *_switch_gethostbyname_r();
9064562Sgshapiro
9164562Sgshapiro	h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
9264562Sgshapiro# else /* SOLARIS == 20300 || SOLARIS == 203 */
9364562Sgshapiro	extern struct hostent *__switch_gethostbyname();
9464562Sgshapiro
9564562Sgshapiro	h = __switch_gethostbyname(name);
9664562Sgshapiro# endif /* SOLARIS == 20300 || SOLARIS == 203 */
9764562Sgshapiro#else /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
9864562Sgshapiro# if NETINET6
9980785Sgshapiro	int flags = AI_DEFAULT|AI_ALL;
10064562Sgshapiro	int err;
10164562Sgshapiro# endif /* NETINET6 */
10264562Sgshapiro
10364562Sgshapiro# if NETINET6
10480785Sgshapiro#  if ADDRCONFIG_IS_BROKEN
10580785Sgshapiro	flags &= ~AI_ADDRCONFIG;
10680785Sgshapiro#  endif /* ADDRCONFIG_IS_BROKEN */
10780785Sgshapiro	h = getipnodebyname(name, family, flags, &err);
10873188Sgshapiro	SM_SET_H_ERRNO(err);
10964562Sgshapiro# else /* NETINET6 */
11064562Sgshapiro	h = gethostbyname(name);
11164562Sgshapiro# endif /* NETINET6 */
11264562Sgshapiro
11364562Sgshapiro#endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */
11464562Sgshapiro	return h;
11564562Sgshapiro}
11690792Sgshapiro
11790792Sgshapiro#if NETINET6
11890792Sgshapiro/*
11990792Sgshapiro**  MI_INET_PTON -- convert printed form to network address.
12090792Sgshapiro**
12190792Sgshapiro**	Wrapper for inet_pton() which handles IPv6: labels.
12290792Sgshapiro**
12390792Sgshapiro**	Parameters:
12490792Sgshapiro**		family -- address family
12590792Sgshapiro**		src -- string
12690792Sgshapiro**		dst -- destination address structure
12790792Sgshapiro**
12890792Sgshapiro**	Returns:
12990792Sgshapiro**		1 if the address was valid
13090792Sgshapiro**		0 if the address wasn't parseable
13190792Sgshapiro**		-1 if error
13290792Sgshapiro*/
13390792Sgshapiro
13490792Sgshapiroint
13590792Sgshapiromi_inet_pton(family, src, dst)
13690792Sgshapiro	int family;
13790792Sgshapiro	const char *src;
13890792Sgshapiro	void *dst;
13990792Sgshapiro{
14090792Sgshapiro	if (family == AF_INET6 &&
14190792Sgshapiro	    strncasecmp(src, "IPv6:", 5) == 0)
14290792Sgshapiro		src += 5;
14390792Sgshapiro	return inet_pton(family, src, dst);
14490792Sgshapiro}
14590792Sgshapiro#endif /* NETINET6 */
146