netresolv: Add support for AI_V4MAPPED in ai_flags in getaddrinfo
Ports over the following commits from FreeBSD: https://github.com/freebsd/freebsd-src/commit/b848a37d4eddb432629a799713cf6fb6f0fd8c3c https://github.com/freebsd/freebsd-src/commit/2cff354f1a56af10ad02164a9ee38c013ac80688 Fixes #14323. Change-Id: I40e6f0ee132eb2d17d8ec66ba0e28566e8695d18 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10358 Haiku-Format: Haiku-format Bot <[email protected]> Tested-by: Commit checker robot <[email protected]> Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
committed by
Jérôme Duval
parent
763cfd171b
commit
902921a554
@@ -83,9 +83,9 @@ const char *hstrerror(int);
|
|||||||
#define AI_ADDRCONFIG 0x00000400
|
#define AI_ADDRCONFIG 0x00000400
|
||||||
#define AI_V4MAPPED 0x00000800
|
#define AI_V4MAPPED 0x00000800
|
||||||
|
|
||||||
#define AI_MASK \
|
#define AI_MASK \
|
||||||
(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG)
|
(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG | AI_ALL \
|
||||||
|
| AI_V4MAPPED)
|
||||||
|
|
||||||
/* getnameinfo */
|
/* getnameinfo */
|
||||||
#if defined(_DEFAULT_SOURCE)
|
#if defined(_DEFAULT_SOURCE)
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
getservent.c
|
getservent.c
|
||||||
getservent_r.c
|
getservent_r.c
|
||||||
hesiod.c
|
hesiod.c
|
||||||
|
map_v4v6.c
|
||||||
nsdispatch.c
|
nsdispatch.c
|
||||||
nslexer.l
|
nslexer.l
|
||||||
nsparser.y
|
nsparser.y
|
||||||
|
|||||||
@@ -88,9 +88,10 @@ __RCSID("$NetBSD: getaddrinfo.c,v 1.119.2.1 2020/11/29 11:25:31 martin Exp $");
|
|||||||
|
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
|
|
||||||
#include <libutil.h>
|
#include "netdb_private.h"
|
||||||
#include "nsswitch.h"
|
#include "nsswitch.h"
|
||||||
#include "servent.h"
|
#include "servent.h"
|
||||||
|
#include <libutil.h>
|
||||||
|
|
||||||
#ifndef RUMP_ACTION
|
#ifndef RUMP_ACTION
|
||||||
#ifdef __weak_alias
|
#ifdef __weak_alias
|
||||||
@@ -136,17 +137,19 @@ static const struct afd {
|
|||||||
const char *a_addrany;
|
const char *a_addrany;
|
||||||
const char *a_loopback;
|
const char *a_loopback;
|
||||||
int a_scoped;
|
int a_scoped;
|
||||||
} afdl [] = {
|
} afdl[] = {
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
{PF_INET6, sizeof(struct in6_addr),
|
#define N_INET6 0
|
||||||
sizeof(struct sockaddr_in6),
|
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
|
||||||
offsetof(struct sockaddr_in6, sin6_addr),
|
offsetof(struct sockaddr_in6, sin6_addr), in6_addrany, in6_loopback, 1},
|
||||||
in6_addrany, in6_loopback, 1},
|
#define N_INET 1
|
||||||
|
#define N_LOCAL 2
|
||||||
|
#else
|
||||||
|
#define N_INET 0
|
||||||
|
#define N_LOCAL 1
|
||||||
#endif
|
#endif
|
||||||
{PF_INET, sizeof(struct in_addr),
|
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
|
||||||
sizeof(struct sockaddr_in),
|
offsetof(struct sockaddr_in, sin_addr), in_addrany, in_loopback, 0},
|
||||||
offsetof(struct sockaddr_in, sin_addr),
|
|
||||||
in_addrany, in_loopback, 0},
|
|
||||||
{0, 0, 0, 0, NULL, NULL, 0},
|
{0, 0, 0, 0, NULL, NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -522,6 +525,24 @@ getaddrinfo(const char *hostname, const char *servname,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC 3493: AI_ALL and AI_V4MAPPED are effective only against
|
||||||
|
* AF_INET6 query. They need to be ignored if specified in other
|
||||||
|
* occassions.
|
||||||
|
*/
|
||||||
|
switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
|
||||||
|
case AI_V4MAPPED:
|
||||||
|
case AI_ALL | AI_V4MAPPED:
|
||||||
|
#ifdef INET6
|
||||||
|
if (pai->ai_family != AF_INET6)
|
||||||
|
pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case AI_ALL:
|
||||||
|
pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && addrconfig(&mask) == -1)
|
if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && addrconfig(&mask) == -1)
|
||||||
ERR(EAI_FAIL);
|
ERR(EAI_FAIL);
|
||||||
|
|
||||||
@@ -925,6 +946,17 @@ set_source(struct ai_order *aio, struct policyhead *ph,
|
|||||||
if ((s = socket(ai.ai_family, ai.ai_socktype | SOCK_CLOEXEC,
|
if ((s = socket(ai.ai_family, ai.ai_socktype | SOCK_CLOEXEC,
|
||||||
ai.ai_protocol)) < 0)
|
ai.ai_protocol)) < 0)
|
||||||
return; /* give up */
|
return; /* give up */
|
||||||
|
|
||||||
|
#ifdef INET6
|
||||||
|
if (ai.ai_family == AF_INET6) {
|
||||||
|
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)ai.ai_addr;
|
||||||
|
int off = 0;
|
||||||
|
|
||||||
|
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
|
||||||
|
(void)setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&off, sizeof(off));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SOCK_CLOEXEC == 0
|
#if SOCK_CLOEXEC == 0
|
||||||
fcntl(s, F_SETFD, FD_CLOEXEC);
|
fcntl(s, F_SETFD, FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
@@ -1308,7 +1340,7 @@ explore_numeric(const struct addrinfo *pai, const char *hostname,
|
|||||||
struct servent_data *svd)
|
struct servent_data *svd)
|
||||||
{
|
{
|
||||||
const struct afd *afd;
|
const struct afd *afd;
|
||||||
struct addrinfo *cur;
|
struct addrinfo *cur, ai0;
|
||||||
struct addrinfo sentinel;
|
struct addrinfo sentinel;
|
||||||
int error;
|
int error;
|
||||||
char pton[PTON_MAX];
|
char pton[PTON_MAX];
|
||||||
@@ -1369,26 +1401,35 @@ explore_numeric(const struct addrinfo *pai, const char *hostname,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (inet_pton(afd->a_af, hostname, pton) == 1) {
|
if (inet_pton(afd->a_af, hostname, pton) != 1) {
|
||||||
if (pai->ai_family == afd->a_af ||
|
if (pai->ai_family != AF_INET6 || (pai->ai_flags & AI_V4MAPPED) != AI_V4MAPPED)
|
||||||
pai->ai_family == PF_UNSPEC /*?*/) {
|
return 0;
|
||||||
GET_AI(cur->ai_next, afd, pton);
|
if (inet_aton(hostname, (struct in_addr*)pton) != 1)
|
||||||
GET_PORT(cur->ai_next, servname, svd);
|
return 0;
|
||||||
if ((pai->ai_flags & AI_CANONNAME)) {
|
afd = &afdl[N_INET];
|
||||||
/*
|
ai0 = *pai;
|
||||||
* Set the numeric address itself as
|
ai0.ai_family = AF_INET;
|
||||||
* the canonical name, based on a
|
pai = &ai0;
|
||||||
* clarification in rfc2553bis-03.
|
|
||||||
*/
|
|
||||||
GET_CANONNAME(cur->ai_next, canonname);
|
|
||||||
}
|
|
||||||
while (cur->ai_next)
|
|
||||||
cur = cur->ai_next;
|
|
||||||
} else
|
|
||||||
ERR(EAI_FAMILY); /*xxx*/
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (pai->ai_family == afd->a_af || pai->ai_family == PF_UNSPEC /*?*/) {
|
||||||
|
GET_AI(cur->ai_next, afd, pton);
|
||||||
|
GET_PORT(cur->ai_next, servname, svd);
|
||||||
|
if (pai->ai_flags & AI_CANONNAME) {
|
||||||
|
/*
|
||||||
|
* Set the numeric address itself as
|
||||||
|
* the canonical name, based on a
|
||||||
|
* clarification in rfc2553bis-03.
|
||||||
|
*/
|
||||||
|
GET_CANONNAME(cur->ai_next, canonname);
|
||||||
|
}
|
||||||
|
while (cur->ai_next)
|
||||||
|
cur = cur->ai_next;
|
||||||
|
} else {
|
||||||
|
ERR(EAI_FAMILY); /*xxx*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
*res = sentinel.ai_next;
|
*res = sentinel.ai_next;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1503,6 +1544,7 @@ allocaddrinfo(socklen_t addrlen)
|
|||||||
return ai;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct addrinfo *
|
static struct addrinfo *
|
||||||
get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
|
get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
|
||||||
{
|
{
|
||||||
@@ -1510,10 +1552,22 @@ get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
|
|||||||
struct addrinfo *ai;
|
struct addrinfo *ai;
|
||||||
struct sockaddr *save;
|
struct sockaddr *save;
|
||||||
|
|
||||||
|
#ifdef INET6
|
||||||
|
struct in6_addr mapaddr;
|
||||||
|
#endif
|
||||||
|
|
||||||
_DIAGASSERT(pai != NULL);
|
_DIAGASSERT(pai != NULL);
|
||||||
_DIAGASSERT(afd != NULL);
|
_DIAGASSERT(afd != NULL);
|
||||||
_DIAGASSERT(addr != NULL);
|
_DIAGASSERT(addr != NULL);
|
||||||
|
|
||||||
|
#ifdef INET6
|
||||||
|
if (afd->a_af == AF_INET && (pai->ai_flags & AI_V4MAPPED) != 0) {
|
||||||
|
afd = &afdl[N_INET6];
|
||||||
|
_map_v4v6_address(addr, (char*)&mapaddr);
|
||||||
|
addr = (char*)&mapaddr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ai = allocaddrinfo((socklen_t)afd->a_socklen);
|
ai = allocaddrinfo((socklen_t)afd->a_socklen);
|
||||||
if (ai == NULL)
|
if (ai == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -2097,10 +2151,13 @@ _dns_query(struct res_target *q, const struct addrinfo *pai,
|
|||||||
cur = cur->ai_next;
|
cur = cur->ai_next;
|
||||||
}
|
}
|
||||||
if (q2) {
|
if (q2) {
|
||||||
ai = getanswer(res, buf2, q2->n, q2->name, q2->qtype, pai);
|
if (!ai || pai->ai_family != AF_UNSPEC
|
||||||
if (ai)
|
|| (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) != AI_V4MAPPED) {
|
||||||
cur->ai_next = ai;
|
ai = getanswer(res, buf2, q2->n, q2->name, q2->qtype, pai);
|
||||||
}
|
if (ai)
|
||||||
|
cur->ai_next = ai;
|
||||||
|
}
|
||||||
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
free(buf2);
|
free(buf2);
|
||||||
return sentinel.ai_next;
|
return sentinel.ai_next;
|
||||||
@@ -2245,7 +2302,7 @@ _dns_host_lookup(const char *name, const struct addrinfo *pai)
|
|||||||
static int
|
static int
|
||||||
_dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
_dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
||||||
{
|
{
|
||||||
struct addrinfo *ai = NULL;
|
struct addrinfo ai0, *ai = NULL;
|
||||||
const char *name, *servname;
|
const char *name, *servname;
|
||||||
const struct addrinfo *pai;
|
const struct addrinfo *pai;
|
||||||
|
|
||||||
@@ -2253,6 +2310,12 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
|||||||
pai = va_arg(ap, const struct addrinfo *);
|
pai = va_arg(ap, const struct addrinfo *);
|
||||||
servname = va_arg(ap, char *);
|
servname = va_arg(ap, char *);
|
||||||
|
|
||||||
|
if (pai->ai_family == AF_INET6 && (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) {
|
||||||
|
ai0 = *pai;
|
||||||
|
ai0.ai_family = AF_UNSPEC;
|
||||||
|
pai = &ai0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try doing SRV lookup on service first.
|
* Try doing SRV lookup on service first.
|
||||||
*/
|
*/
|
||||||
@@ -2370,6 +2433,10 @@ _gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
|
|||||||
found:
|
found:
|
||||||
hints = *pai;
|
hints = *pai;
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
|
||||||
|
if (pai->ai_family == AF_INET6 && (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED)
|
||||||
|
hints.ai_flags |= AI_V4MAPPED;
|
||||||
|
|
||||||
error = getaddrinfo(addr, NULL, &hints, &res0);
|
error = getaddrinfo(addr, NULL, &hints, &res0);
|
||||||
if (error)
|
if (error)
|
||||||
goto again;
|
goto again;
|
||||||
@@ -2387,6 +2454,20 @@ found:
|
|||||||
return res0;
|
return res0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct addrinfo*
|
||||||
|
_getht(FILE** hostf, const char* name, const struct addrinfo* pai, struct addrinfo* cur)
|
||||||
|
{
|
||||||
|
struct addrinfo* p;
|
||||||
|
|
||||||
|
while ((p = _gethtent(hostf, name, pai)) != NULL) {
|
||||||
|
cur->ai_next = p;
|
||||||
|
while (cur && cur->ai_next)
|
||||||
|
cur = cur->ai_next;
|
||||||
|
}
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
static int
|
static int
|
||||||
_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
||||||
@@ -2394,7 +2475,6 @@ _files_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
|||||||
const char *name;
|
const char *name;
|
||||||
const struct addrinfo *pai;
|
const struct addrinfo *pai;
|
||||||
struct addrinfo sentinel, *cur;
|
struct addrinfo sentinel, *cur;
|
||||||
struct addrinfo *p;
|
|
||||||
#ifndef _REENTRANT
|
#ifndef _REENTRANT
|
||||||
static
|
static
|
||||||
#endif
|
#endif
|
||||||
@@ -2407,10 +2487,18 @@ _files_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
|||||||
cur = &sentinel;
|
cur = &sentinel;
|
||||||
|
|
||||||
_sethtent(&hostf);
|
_sethtent(&hostf);
|
||||||
while ((p = _gethtent(&hostf, name, pai)) != NULL) {
|
if (pai->ai_family == AF_INET6 && (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) == AI_V4MAPPED) {
|
||||||
cur->ai_next = p;
|
struct addrinfo ai0 = *pai;
|
||||||
while (cur && cur->ai_next)
|
|
||||||
cur = cur->ai_next;
|
ai0.ai_flags &= ~AI_V4MAPPED;
|
||||||
|
cur = _getht(&hostf, name, &ai0, cur);
|
||||||
|
if (sentinel.ai_next == NULL) {
|
||||||
|
_sethtent(&hostf);
|
||||||
|
ai0.ai_flags |= AI_V4MAPPED;
|
||||||
|
cur = _getht(&hostf, name, &ai0, cur);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cur = _getht(&hostf, name, pai, cur);
|
||||||
}
|
}
|
||||||
_endhtent(&hostf);
|
_endhtent(&hostf);
|
||||||
|
|
||||||
@@ -2475,6 +2563,8 @@ nextline:
|
|||||||
|
|
||||||
hints = *pai;
|
hints = *pai;
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
if (pai->ai_family == AF_INET6 && (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED)
|
||||||
|
hints.ai_flags |= AI_V4MAPPED;
|
||||||
error = getaddrinfo(addr, NULL, &hints, &res0);
|
error = getaddrinfo(addr, NULL, &hints, &res0);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
for (res = res0; res; res = res->ai_next) {
|
for (res = res0; res; res = res->ai_next) {
|
||||||
@@ -2522,15 +2612,44 @@ _yp_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
|||||||
memset(&sentinel, 0, sizeof(sentinel));
|
memset(&sentinel, 0, sizeof(sentinel));
|
||||||
cur = &sentinel;
|
cur = &sentinel;
|
||||||
|
|
||||||
|
/* ipnodes.byname can hold both IPv4/v6 */
|
||||||
|
r = yp_match(ypdomain, "ipnodes.byname", name, (int)strlen(name), &ypbuf, &ypbuflen);
|
||||||
|
if (r == 0) {
|
||||||
|
ai = _yphostent(ypbuf, pai);
|
||||||
|
if (ai) {
|
||||||
|
cur->ai_next = ai;
|
||||||
|
while (cur && cur->ai_next)
|
||||||
|
cur = cur->ai_next;
|
||||||
|
}
|
||||||
|
free(ypbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ai != NULL) {
|
||||||
|
struct sockaddr_in6* sin6;
|
||||||
|
|
||||||
|
switch (ai->ai_family) {
|
||||||
|
case AF_INET:
|
||||||
|
goto done;
|
||||||
|
case AF_INET6:
|
||||||
|
sin6 = (struct sockaddr_in6*)ai->ai_addr;
|
||||||
|
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
|
||||||
|
goto done;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* hosts.byname is only for IPv4 (Solaris8) */
|
/* hosts.byname is only for IPv4 (Solaris8) */
|
||||||
if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
|
if (pai->ai_family == AF_UNSPEC || pai->ai_family == AF_INET
|
||||||
|
|| ((pai->ai_family == AF_INET6 && (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED)
|
||||||
|
&& (ai == NULL || (pai->ai_flags & AI_ALL) == AI_ALL))) {
|
||||||
r = yp_match(ypdomain, "hosts.byname", name,
|
r = yp_match(ypdomain, "hosts.byname", name,
|
||||||
(int)strlen(name), &ypbuf, &ypbuflen);
|
(int)strlen(name), &ypbuf, &ypbuflen);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
struct addrinfo ai4;
|
struct addrinfo ai4;
|
||||||
|
|
||||||
ai4 = *pai;
|
ai4 = *pai;
|
||||||
ai4.ai_family = AF_INET;
|
if (pai->ai_family == AF_UNSPEC)
|
||||||
|
ai4.ai_family = AF_INET;
|
||||||
ai = _yphostent(ypbuf, &ai4);
|
ai = _yphostent(ypbuf, &ai4);
|
||||||
if (ai) {
|
if (ai) {
|
||||||
cur->ai_next = ai;
|
cur->ai_next = ai;
|
||||||
@@ -2541,16 +2660,7 @@ _yp_getaddrinfo(void *rv, void *cb_data, va_list ap)
|
|||||||
free(ypbuf);
|
free(ypbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ipnodes.byname can hold both IPv4/v6 */
|
done:
|
||||||
r = yp_match(ypdomain, "ipnodes.byname", name,
|
|
||||||
(int)strlen(name), &ypbuf, &ypbuflen);
|
|
||||||
if (r == 0) {
|
|
||||||
ai = _yphostent(ypbuf, pai);
|
|
||||||
if (ai)
|
|
||||||
cur->ai_next = ai;
|
|
||||||
free(ypbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sentinel.ai_next == NULL) {
|
if (sentinel.ai_next == NULL) {
|
||||||
h_errno = HOST_NOT_FOUND;
|
h_errno = HOST_NOT_FOUND;
|
||||||
return NS_NOTFOUND;
|
return NS_NOTFOUND;
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*
|
||||||
|
* ++Copyright++ 1985, 1988, 1993
|
||||||
|
* -
|
||||||
|
* Copyright (c) 1985, 1988, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
* -
|
||||||
|
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies, and that
|
||||||
|
* the name of Digital Equipment Corporation not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the document or software without
|
||||||
|
* specific, written prior permission.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||||
|
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||||
|
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||||
|
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
* SOFTWARE.
|
||||||
|
* -
|
||||||
|
* --Copyright--
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <arpa/nameser.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "netdb_private.h"
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <resolv.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
int32_t al;
|
||||||
|
char ac;
|
||||||
|
} align;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_map_v4v6_address(const char* src, char* dst)
|
||||||
|
{
|
||||||
|
/* Our caller may update in place. */
|
||||||
|
memmove(&dst[12], src, NS_INADDRSZ);
|
||||||
|
/* Mark this ipv6 addr as a mapped ipv4. */
|
||||||
|
memset(&dst[10], 0xff, 2);
|
||||||
|
memset(&dst[0], 0, 10);
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (C) 2005 The FreeBSD Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
|
void _map_v4v6_address(const char*, char*);
|
||||||
Reference in New Issue
Block a user