/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This is the DNS backend for IPv6 addresses.
* getbyname() is a local routine, but getbyaddr() actually shares the
* same codes as the one in gethostent.c.
*/
#include <malloc.h>
#include <stddef.h>
#include <string.h>
#include "dns_common.h"
/*
* If the DNS name service switch routines are used in a binary that depends
* on an older libresolv (libresolv.so.1, say), then having nss_dns.so.1 or
* libnss_dns.a depend on a newer libresolv (libresolv.so.2) will cause
* relocation problems. In particular, copy relocation of the _res structure
* (which changes in size from libresolv.so.1 to libresolv.so.2) could
* cause corruption, and result in a number of strange problems, including
* core dumps. Hence, we check if a libresolv is already loaded.
*/
#pragma weak res_endhostent
extern struct hostent *_gethostbyname(int *, const char *);
extern struct hostent *_nss_dns_gethostbyname2(int *, const char *);
typedef union {
long al;
char ac;
} align;
static void
{
int ret;
ret = endhostent();
if (ret == 0)
*errp = NSS_SUCCESS;
else
*errp = NSS_UNAVAIL;
}
#ifdef RNDUP
#endif
#ifdef PTROFF
#endif
#define PTROFF(p, o) (((o) == 0) ? 0 : (void *)((char *)(p) + (o)))
/*
* Make a copy of h->h_name.
*/
static char *
char *name;
int len;
if (outerr)
else
if (h == 0 || h->h_name == 0) {
*errp = 0;
return (0);
}
*errp = 1;
return (0);
}
*errp = 0;
return (name);
}
/*
* Copy the h->h_addr_list[] array to a new array, and append the
* moreAddrs[] list. If h->h_addr_list[] contains IPv4 addresses,
* convert them to v4 mapped IPv6 addresses.
*
* Note: The pointers to the addresses in the moreAddrs[] array are copied,
* but not the IP addresses themselves.
*/
static struct in6_addr **
if (outerr)
else
if (h == 0 || h->h_addr_list == 0) {
*errp = 0;
return (0);
}
/* Should we map v4 to IPv6 ? */
(h->h_addrtype == AF_INET);
/* If mapping, make sure we allocate enough memory for addresses */
if (moreAddrs != 0) {
moreAddrCount++);
}
*errp = 1;
return (0);
}
sizeof (addrList));
for (i = 0; i < addrCount; i++) {
if (domap) {
/* LINTED: E_BAD_PTR_CAST_ALIGN */
} else {
addrlen);
}
}
for (j = 0; j < moreAddrCount; j++, i++) {
}
/* Last pointer should be NULL */
addrArray[i] = 0;
*errp = 0;
return (addrArray);
}
/*
* Create a new alias array that is is a copy of h->h_aliases[] plus
* the aliases in mergeAliases[] which aren't duplicates of any alias
* in h->h_aliases[].
*
* Note 1: Only the string pointers (NOT the strings) in the mergeAliases[]
* array are copied.
*
* Note 2: The duplicate aliases in mergeAliases[] are replaced by NULL
* pointers.
*/
static char **
int stringSize = 0;
if (outerr)
else
if (h == 0 || h->h_aliases == 0) {
*errp = 0;
return (0);
}
}
if (mergeAliases != 0) {
/* Skip duplicates */
for (j = 0; j < aliasCount; j++) {
h->h_aliases[j]) == 0) {
countThis = 0;
break;
}
}
if (countThis)
realMac++;
else
mergeAliases[mergeAliasCount] = 0;
}
}
stringSize)) == 0) {
*errp = 1;
return (0);
}
for (i = 0; i < aliasCount; i++) {
aliasArray[i] = aliasList;
}
for (j = 0; j < mergeAliasCount; j++) {
if (mergeAliases[j] != 0) {
aliasArray[i++] = mergeAliases[j];
}
}
aliasArray[i] = 0;
*errp = 0;
return (aliasArray);
}
/*ARGSUSED*/
static nss_status_t
void *a;
{
char *v6Name = 0;
int v6_h_errno;
int old_retry;
/* Now get the AAAA records */
/*
* pointer in "he" is part of a static pthread key in libresolv
* It should be treated as read only.
* So clone a copy first.
*/
if (converr) {
}
if (converr) {
if (v6Name != 0)
}
if (converr) {
if (v6Name != 0)
if (v6Addrs != 0)
}
gotv6 = 1;
}
/*
* The conditions to search "A" records:
* 1. af is AF_INET
* 2. if af is AF_INET6
* then flags are either
* 1) (AI_ALL | AI_V4MAPPED) or
* 2) AI_V4MAPPED and he == NULL
* (No V6 addresses found or no search for V6 at all)
*/
/* Get the A records, and store the information */
else
/* Merge the results */
if (converr) {
if (v6Name != 0)
if (v6Addrs != 0)
if (v6Aliases != 0)
}
if (converr) {
if (v6Name != 0)
if (v6Addrs != 0)
if (v6Aliases != 0)
if (mergeAddrs != 0)
}
/* reset h_length, h_addrtype */
} else if (gotv6) {
}
/*
* if asked to return data in string,
* convert the hostent structure into
* string data
*/
if (ret == NSS_STR_PARSE_SUCCESS)
} else {
if (ret == NSS_STR_PARSE_SUCCESS)
}
if (ret != NSS_STR_PARSE_SUCCESS) {
if (ret == NSS_STR_PARSE_ERANGE) {
}
}
}
if (v6Name != 0)
if (v6Addrs != 0)
if (v6Aliases != 0)
if (mergeAddrs != 0)
if (mergeAliases != 0)
}
static nss_status_t
void *a;
{
/* uses the same getbyaddr from IPv4 */
return (__nss_dns_getbyaddr(be, a));
}
/*ARGSUSED*/
static nss_status_t
void *args;
{
return (NSS_UNAVAIL);
}
/*ARGSUSED*/
static nss_status_t
void *dummy;
{
/* XXXX not implemented at this point */
return (NSS_UNAVAIL);
}
/*ARGSUSED*/
static nss_status_t
void *dummy;
{
/* XXXX not implemented at this point */
return (NSS_UNAVAIL);
}
/*ARGSUSED*/
static nss_status_t
void *dummy;
{
if (be != 0) {
/* === Should change to invoke ops[ENDENT] ? */
(void) sigfillset(&newmask);
(void) mutex_lock(&one_lane);
}
_endhostent(&errp);
if (mt_disabled) {
(void) mutex_unlock(&one_lane);
} else {
(void) (*disable_mt)();
}
}
return (NSS_SUCCESS); /* In case anyone is dumb enough to check */
}
};
/*ARGSUSED*/
{
return (_nss_dns_constr(ipnodes_ops,
sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0])));
}
/*
* optional NSS2 packed backend gethostsbyipnode with ttl
* entry point.
*
* Returns:
* NSS_SUCCESS - successful
* NSS_NOTFOUND - successful but nothing found
* NSS_ERROR - fallback to NSS backend lookup mode
* If successful, buffer will be filled with valid data
*
*/
/*ARGSUSED*/
{
}