IPv6 resolver API compability library codes from ZMailer by OH2MQK
git-svn-id: http://repo.ham.fi/svn/aprsc/trunk@10 3ce903b1-3385-4e86-93cd-f9a4a239f7ac
This commit is contained in:
parent
50a4855c92
commit
887fe9b150
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Libc fill-in for ZMailer using IPv6 API
|
||||
by Matti Aarnio <mea@nic.funet.fi> 1997, 2001
|
||||
|
||||
The original Craig Metz code is deeply Linux specific,
|
||||
this adaptation tries to be way more generic..
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#ifndef EAI_BADFLAGS
|
||||
# include "netdb6.h"
|
||||
#endif
|
||||
|
||||
#ifndef __STDC__
|
||||
# define const
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
|
||||
/*
|
||||
%%% copyright-cmetz-97
|
||||
This software is Copyright 1997 by Craig Metz, All Rights Reserved.
|
||||
The Inner Net License Version 2 applies to this software.
|
||||
You should have received a copy of the license with this software. If
|
||||
you didn't get a copy, you may request one from <license@inner.net>.
|
||||
|
||||
*/
|
||||
|
||||
const char *gai_strerror(errnum)
|
||||
int errnum;
|
||||
{
|
||||
static char buffer[24];
|
||||
switch(errnum) {
|
||||
case 0:
|
||||
return "no error";
|
||||
case EAI_BADFLAGS:
|
||||
return "invalid value for ai_flags";
|
||||
case EAI_NONAME:
|
||||
return "name or service is not known";
|
||||
case EAI_AGAIN:
|
||||
return "temporary failure in name resolution";
|
||||
case EAI_FAIL:
|
||||
return "non-recoverable failure in name resolution";
|
||||
case EAI_NODATA:
|
||||
return "no address associated with name";
|
||||
case EAI_FAMILY:
|
||||
return "ai_family not supported";
|
||||
case EAI_SOCKTYPE:
|
||||
return "ai_socktype not supported";
|
||||
case EAI_SERVICE:
|
||||
return "service not supported for ai_socktype";
|
||||
case EAI_ADDRFAMILY:
|
||||
return "address family for name not supported";
|
||||
case EAI_MEMORY:
|
||||
return "memory allocation failure";
|
||||
case EAI_SYSTEM:
|
||||
return "system error";
|
||||
default:
|
||||
sprintf(buffer,"gai_error_%02x", errnum);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* Generalized adaptation to ZMailer libc fill-in use by
|
||||
* Matti Aarnio <mea@nic.funet.fi> 2000
|
||||
*
|
||||
* The original version taken from glibc-2.1.92 on 1-Aug-2000
|
||||
*
|
||||
* This is SERIOUSLY LOBOTIMIZED to be usable in environments WITHOUT
|
||||
* threaded versions of getservbyname(), and friends, plus ridding
|
||||
* __alloca() calls as they are VERY GCC specific, which isn't a good
|
||||
* thing for ZMailer. (Also DE-ANSIfied to K&R style..)
|
||||
*
|
||||
* Original reason for having getaddrinfo() API in ZMailer was
|
||||
* to support IPv6 universe -- and that is still the reason. This
|
||||
* adaptation module is primarily for those systems which don't have
|
||||
* this IPv6 API, but there are also some systems (all those using
|
||||
* the original INNER NET code -- glibc 2.0/2.1/2.2(?) especially)
|
||||
* which have faulty error condition processing in them. Specifically
|
||||
* plain simple TIMEOUTS on queries are not handled properly!
|
||||
*
|
||||
* Now that Linuxes have caught up at libc level, we no longer have
|
||||
* a reason to support kernel things which don't exist at libc level.
|
||||
* (Running ZMailer on Linux with libc5 is not supported in sense of
|
||||
* supporting IPv6 at the kernel..)
|
||||
*
|
||||
*
|
||||
* THIS getnameinfo() FUNCTION IS NOT USED IN ZMAILER, BUT IS
|
||||
* SUPPLIED JUST TO COMPLETE THE API IN CASE IT WILL SOMETIME BECOME
|
||||
* USED...
|
||||
*
|
||||
*/
|
||||
|
||||
/* The Inner Net License, Version 2.00
|
||||
|
||||
The author(s) grant permission for redistribution and use in source and
|
||||
binary forms, with or without modification, of the software and documentation
|
||||
provided that the following conditions are met:
|
||||
|
||||
0. If you receive a version of the software that is specifically labelled
|
||||
as not being for redistribution (check the version message and/or README),
|
||||
you are not permitted to redistribute that version of the software in any
|
||||
way or form.
|
||||
1. All terms of the all other applicable copyrights and licenses must be
|
||||
followed.
|
||||
2. Redistributions of source code must retain the authors' copyright
|
||||
notice(s), this list of conditions, and the following disclaimer.
|
||||
3. Redistributions in binary form must reproduce the authors' copyright
|
||||
notice(s), this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
4. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement with the name(s) of the
|
||||
authors as specified in the copyright notice(s) substituted where
|
||||
indicated:
|
||||
|
||||
This product includes software developed by <name(s)>, The Inner
|
||||
Net, and other contributors.
|
||||
|
||||
5. Neither the name(s) of the author(s) 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 ITS AUTHORS 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 AUTHORS 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.
|
||||
|
||||
If these license terms cause you a real problem, contact the author. */
|
||||
|
||||
/* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
|
||||
|
||||
# include "ac-defs.h" /* autoconfig environment */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h> /* Sol 2.6 barfs without this.. */
|
||||
#include <resolv.h>
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
#include <sys/utsname.h>
|
||||
#include <netdb.h>
|
||||
#if !defined(EAI_AGAIN) || !defined(AI_NUMERICHOST)
|
||||
# include "netdb6.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef min
|
||||
# define min(x,y) (((x) > (y)) ? (y) : (x))
|
||||
#endif /* min */
|
||||
|
||||
#ifndef AF_LOCAL
|
||||
# ifdef AF_UNIX
|
||||
# define AF_LOCAL AF_UNIX
|
||||
# define PF_LOCAL PF_UNIX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static char * nrl_domainname __((void));
|
||||
static char *
|
||||
nrl_domainname ()
|
||||
{
|
||||
static char *domain;
|
||||
static int not_first;
|
||||
char hostnamebuf[MAXHOSTNAMELEN];
|
||||
|
||||
if (! not_first) {
|
||||
char *c;
|
||||
struct hostent *h;
|
||||
|
||||
not_first = 1;
|
||||
|
||||
h = gethostbyname ("localhost");
|
||||
|
||||
if (h && (c = strchr (h->h_name, '.')))
|
||||
domain = strdup (++c);
|
||||
else {
|
||||
/* The name contains no domain information. Use the name
|
||||
now to get more information. */
|
||||
gethostname (hostnamebuf, MAXHOSTNAMELEN);
|
||||
|
||||
c = strchr (hostnamebuf, '.');
|
||||
if (c)
|
||||
domain = strdup (++c);
|
||||
else {
|
||||
h = gethostbyname(hostnamebuf);
|
||||
|
||||
if (h && (c = strchr(h->h_name, '.')))
|
||||
domain = strdup (++c);
|
||||
else {
|
||||
struct in_addr in_addr;
|
||||
|
||||
in_addr.s_addr = htonl (0x7f000001);
|
||||
|
||||
|
||||
h = gethostbyaddr((const char *) &in_addr,
|
||||
sizeof (struct in_addr),
|
||||
AF_INET);
|
||||
|
||||
if (h && (c = strchr (h->h_name, '.')))
|
||||
domain = strdup (++c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
/* This is NASTY, GLIBC has changed the type after instroducing
|
||||
this function, Sol (2.)8 has 'int', of upcoming POSIX standard
|
||||
revision I don't know.. */
|
||||
|
||||
#ifndef GETNAMEINFOFLAGTYPE
|
||||
# if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
|
||||
# if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 2
|
||||
/* I am not sure that it was already 2.2(.0) that had
|
||||
this change, but 2.2.2 has it... */
|
||||
# define GETNAMEINFOFLAGTYPE unsigned int
|
||||
# else
|
||||
# define GETNAMEINFOFLAGTYPE int
|
||||
# endif
|
||||
# else
|
||||
# define GETNAMEINFOFLAGTYPE int
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
int
|
||||
getnameinfo __((const struct sockaddr *sa, size_t addrlen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen,
|
||||
GETNAMEINFOFLAGTYPE flags));
|
||||
|
||||
int
|
||||
getnameinfo (sa, addrlen, host, hostlen, serv, servlen, flags)
|
||||
const struct sockaddr *sa;
|
||||
size_t addrlen;
|
||||
char *host;
|
||||
size_t hostlen;
|
||||
char *serv;
|
||||
size_t servlen;
|
||||
GETNAMEINFOFLAGTYPE flags;
|
||||
{
|
||||
int serrno = errno;
|
||||
int ok = 0;
|
||||
|
||||
if (sa == NULL || addrlen < sizeof (sa->sa_family))
|
||||
return -1;
|
||||
|
||||
switch (sa->sa_family) {
|
||||
#ifdef AF_LOCAL
|
||||
case AF_LOCAL:
|
||||
if (addrlen < (size_t) (((struct sockaddr_un *) NULL)->sun_path))
|
||||
return -1;
|
||||
break;
|
||||
#endif
|
||||
case AF_INET:
|
||||
if (addrlen < sizeof (struct sockaddr_in))
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (host != NULL && hostlen > 0)
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
if (!(flags & NI_NUMERICHOST)) {
|
||||
struct hostent *h;
|
||||
|
||||
h = gethostbyaddr((void *) &(((struct sockaddr_in *)sa)->sin_addr),
|
||||
sizeof(struct in_addr), AF_INET);
|
||||
if (h) {
|
||||
if (flags & NI_NOFQDN) {
|
||||
char *c;
|
||||
if ((c = nrl_domainname ()) && (c = strstr(h->h_name, c))
|
||||
&& (c != h->h_name) && (*(--c) == '.')) {
|
||||
strncpy (host, h->h_name,
|
||||
min(hostlen, (size_t) (c - h->h_name)));
|
||||
host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0';
|
||||
ok = 1;
|
||||
} else {
|
||||
strncpy (host, h->h_name, hostlen);
|
||||
ok = 1;
|
||||
}
|
||||
} else {
|
||||
strncpy (host, h->h_name, hostlen);
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
if (flags & NI_NAMEREQD) {
|
||||
return -1;
|
||||
} else {
|
||||
const char *c;
|
||||
c = inet_ntop (AF_INET,
|
||||
(void *) &(((struct sockaddr_in *) sa)->sin_addr),
|
||||
host, hostlen);
|
||||
if (!c) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef AF_LOCAL
|
||||
case AF_LOCAL:
|
||||
if (!(flags & NI_NUMERICHOST)) {
|
||||
struct utsname utsname;
|
||||
|
||||
if (!uname (&utsname)) {
|
||||
strncpy (host, utsname.nodename, hostlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & NI_NAMEREQD) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy (host, "localhost", hostlen);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (serv && (servlen > 0))
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
if (!(flags & NI_NUMERICSERV)) {
|
||||
struct servent *s;
|
||||
s = getservbyport(((struct sockaddr_in *) sa)->sin_port,
|
||||
((flags & NI_DGRAM) ? "udp" : "tcp"));
|
||||
if (s) {
|
||||
strncpy (serv, s->s_name, servlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
char decbuf[30];
|
||||
sprintf(decbuf, "%d", ntohs (((struct sockaddr_in *) sa)->sin_port));
|
||||
strncpy(serv, decbuf, servlen);
|
||||
serv[servlen-1] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef AF_LOCAL
|
||||
case AF_LOCAL:
|
||||
strncpy (serv, ((struct sockaddr_un *) sa)->sun_path, servlen);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (host && (hostlen > 0))
|
||||
host[hostlen-1] = 0;
|
||||
if (serv && (servlen > 0))
|
||||
serv[servlen-1] = 0;
|
||||
errno = serrno;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id: inet_ntop.c,v 1.2 2006/10/23 21:36:28 mea Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "hostenv.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h> /* For AF_**** */
|
||||
#if 0
|
||||
#include <netinet/in.h> /* Actually not needed.. */
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
/* #include "portability.h" */
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) sprintf x
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4 __((const u_char *src, char *dst, size_t size));
|
||||
#if defined(AF_INET6) && defined(INET6)
|
||||
static const char *inet_ntop6 __((const u_char *src, char *dst, size_t size));
|
||||
#endif
|
||||
|
||||
/* char *
|
||||
* inet_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
|
||||
const char * inet_ntop __((int, const void *, char *, size_t));
|
||||
|
||||
const char *
|
||||
inet_ntop(af, src, dst, size)
|
||||
int af;
|
||||
const void *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
#if defined(AF_INET6) && defined(INET6)
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address, more or less like inet_ntoa()
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a u_char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(src, dst, size)
|
||||
const u_char *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
static const char fmt[] = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
|
||||
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
#if defined(AF_INET6) && defined(INET6)
|
||||
|
||||
#ifndef IN6ADDRSZ
|
||||
#define IN6ADDRSZ 16
|
||||
#endif
|
||||
#ifndef INT16SZ
|
||||
#define INT16SZ 2
|
||||
#endif
|
||||
|
||||
/* const char *
|
||||
* inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop6(src, dst, size)
|
||||
const u_char *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int words[IN6ADDRSZ / INT16SZ];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
best.len = cur.len = 0;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += SPRINTF((tp, "%x", words[i]));
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((tp - tmp) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id: inet_pton.c,v 1.1.1.1 1998/02/10 21:01:46 mea Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "hostenv.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h> /* For AF_**** */
|
||||
#if 0
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
/* #include "portability.h" */
|
||||
|
||||
#ifndef INADDRSZ
|
||||
#define INADDRSZ 4
|
||||
#endif
|
||||
#ifndef IN6ADDRSZ
|
||||
#define IN6ADDRSZ 16
|
||||
#endif
|
||||
#ifndef INT16SZ
|
||||
#define INT16SZ 2
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4 __((const char *src, u_char *dst));
|
||||
#if defined(AF_INET6) && defined(INET6)
|
||||
static int inet_pton6 __((const char *src, u_char *dst));
|
||||
#endif
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
|
||||
int inet_pton __((int, const char *, void *));
|
||||
|
||||
int
|
||||
inet_pton(af, src, dst)
|
||||
int af;
|
||||
const char *src;
|
||||
void *dst;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
#if defined(AF_INET6) && defined(INET6)
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(src, dst)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
u_char tmp[INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
u_int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (! saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
memcpy(dst, tmp, INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#if defined(AF_INET6) && defined(INET6)
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(src, dst)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
u_int val;
|
||||
|
||||
memset((tp = tmp), 0, IN6ADDRSZ);
|
||||
endp = tp + IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if (tp + INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
IPv6 API additions for the ZMailer at those machines
|
||||
without proper libraries and includes.
|
||||
By Matti Aarnio <mea@nic.funet.fi> 1997,2004
|
||||
*/
|
||||
|
||||
#ifndef __
|
||||
# ifdef __STDC__
|
||||
# define __(x) x
|
||||
# else
|
||||
# define __(x) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
#ifndef AI_PASSIVE
|
||||
|
||||
struct addrinfo {
|
||||
int ai_flags; /* AI_PASSIVE | AI_CANONNAME */
|
||||
int ai_family; /* PF_xxx */
|
||||
int ai_socktype; /* SOCK_xxx */
|
||||
int ai_protocol; /* 0, or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
size_t ai_addrlen; /* Length of ai_addr */
|
||||
char *ai_canonname; /* canonical name for hostname */
|
||||
struct sockaddr *ai_addr; /* binary address */
|
||||
struct addrinfo *ai_next; /* next structure in linked list */
|
||||
};
|
||||
|
||||
|
||||
extern int getaddrinfo __(( const char *node, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res ));
|
||||
extern void freeaddrinfo __(( struct addrinfo *res ));
|
||||
extern const char *gai_strerror __((int errcode));
|
||||
|
||||
#define AI_PASSIVE 1 /* Socket address is intended for `bind'. */
|
||||
#endif
|
||||
#ifndef AI_CANONNAME
|
||||
#define AI_CANONNAME 2 /* Request for canonical name. */
|
||||
#endif
|
||||
#ifndef AI_NUMERICHOST
|
||||
#define AI_NUMERICHOST 4 /* Don't use name resolution. */
|
||||
#endif
|
||||
|
||||
#ifndef EAI_ADDRFAMILY
|
||||
/* Error values for `getaddrinfo' function. */
|
||||
#define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */
|
||||
#define EAI_NONAME -2 /* NAME or SERVICE is unknown. */
|
||||
#define EAI_AGAIN -3 /* Temporary failure in name resolution. */
|
||||
#define EAI_FAIL -4 /* Non-recoverable failure in name res. */
|
||||
#define EAI_NODATA -5 /* No address associated with NAME. */
|
||||
#define EAI_FAMILY -6 /* `ai_family' not supported. */
|
||||
#define EAI_SOCKTYPE -7 /* `ai_socktype' not supported. */
|
||||
#define EAI_SERVICE -8 /* SERVICE not supported for `ai_socktype'. */
|
||||
#define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */
|
||||
#define EAI_MEMORY -10 /* Memory allocation failure. */
|
||||
#define EAI_SYSTEM -11 /* System error returned in `errno'. */
|
||||
#endif
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#define NI_MAXSERV 32
|
||||
|
||||
#define NI_NUMERICHOST 0x01
|
||||
#define NI_NUMERICSERV 0x02
|
||||
#define NI_NAMEREQD 0x04
|
||||
#define NI_NOFQDN 0x08
|
||||
#define NI_DGRAM 0x10
|
||||
#endif
|
||||
#endif /* ndef HAVE_GETADDRINFO */
|
||||
Loading…
Reference in New Issue