@ -1,52 +1,39 @@
/* Copyright (c) 1996 by Internet Software Consortium.
/*
* Copyright ( c ) 2004 by Internet Systems Consortium , Inc . ( " ISC " )
* Copyright ( c ) 1996 - 1999 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 .
* THE SOFTWARE IS PROVIDED " AS IS " AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS . IN NO EVENT SHALL ISC 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 .
*/
# include "ares_setup.h"
# if defined(LIBC_SCCS) && !defined(lint)
static const char rcsid [ ] = " $Id: inet_ntop.c,v 1.5 2005/11/03 22:59:52 marka Exp $ " ;
# endif /* LIBC_SCCS and not lint */
# ifdef HAVE_SYS_SOCKET_H
# include <sys / socket.h>
# endif
# ifdef HAVE_NETINET_IN_H
# include <netinet / in.h>
# endif
# ifdef HAVE_ARPA_INET_H
# include <arpa / inet.h>
# endif
# ifdef HAVE_ARPA_NAMESER_H
# include <arpa / nameser.h>
# else
# include "nameser.h"
# endif
# ifdef HAVE_ARPA_NAMESER_COMPAT_H
# include <arpa / nameser_compat.h>
# endif
# include "port_before.h"
# include <sys/param.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <arpa/nameser.h>
# include <ctype.h>
# include <errno.h>
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include "ares.h"
# include "ares_ipv6.h"
# include "inet_ntop.h"
# ifndef HAVE_INET_NTOP
# include "port_after.h"
# ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf /**/ x)
@ -54,38 +41,36 @@
# define SPRINTF(x) ((size_t)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 unsigned char * src , char * dst , size_t size ) ;
static const char * inet_ntop6 ( const unsigned char * src , char * dst , size_t size ) ;
static const char * inet_ntop4 __P ( ( const u_ char * src , char * dst , size_t size ) ) ;
static const char * inet_ntop6 __P ( ( const u_ char * src , char * dst , size_t size ) ) ;
/* 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 ) .
* note :
* On Windows we store the error in the thread errno , not
* in the winsock error code . This is to avoid loosing the
* actual last winsock error . So use macro ERRNO to fetch the
* errno this funtion sets when returning NULL , not SOCKERRNO .
* author :
* Paul Vixie , 1996.
*/
const char *
ares_inet_ntop ( int af , const void * src , char * dst , size_t size )
inet_ntop ( af , src , dst , size )
int af ;
const void * src ;
char * dst ;
size_t size ;
{
switch ( af )
{
switch ( af ) {
case AF_INET :
return ( inet_ntop4 ( src , dst , size ) ) ;
case AF_INET6 :
return ( inet_ntop6 ( src , dst , size ) ) ;
default :
SET_ERRNO ( EAFNOSUPPORT ) ;
errno = EAFNOSUPPORT ;
return ( NULL ) ;
}
/* NOTREACHED */
@ -93,24 +78,26 @@ ares_inet_ntop(int af, const void *src, char *dst, size_t size)
/* const char *
* inet_ntop4 ( src , dst , size )
* format an IPv4 address , more or less like inet_ntoa ( )
* format an IPv4 address
* return :
* ` dst ' ( as a const )
* notes :
* ( 1 ) uses no statics
* ( 2 ) takes a unsigned char * not an in_addr as input
* ( 2 ) takes a u_ char* not an in_addr as input
* author :
* Paul Vixie , 1996.
*/
static const char *
inet_ntop4 ( const unsigned char * src , char * dst , size_t size )
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 )
{
SET_ERRNO ( ENOSPC ) ;
if ( SPRINTF ( ( tmp , fmt , src [ 0 ] , src [ 1 ] , src [ 2 ] , src [ 3 ] ) ) > = size ) {
errno = ENOSPC ;
return ( NULL ) ;
}
strcpy ( dst , tmp ) ;
@ -124,7 +111,10 @@ inet_ntop4(const unsigned char *src, char *dst, size_t size)
* Paul Vixie , 1996.
*/
static const char *
inet_ntop6 ( const unsigned char * src , char * dst , size_t size )
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
@ -133,13 +123,9 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
* 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 " ) ] ;
char * tp ;
struct {
long base ;
long len ;
} best , cur ;
unsigned long words [ NS_IN6ADDRSZ / NS_INT16SZ ] ;
char tmp [ sizeof " ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255 " ] , * tp ;
struct { int base , len ; } best , cur ;
u_int words [ NS_IN6ADDRSZ / NS_INT16SZ ] ;
int i ;
/*
@ -147,36 +133,28 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
* 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 ) ) ;
memset ( words , ' \0 ' , sizeof words ) ;
for ( i = 0 ; i < NS_IN6ADDRSZ ; i + + )
words [ i / 2 ] | = ( src [ i ] < < ( ( 1 - ( i % 2 ) ) < < 3 ) ) ;
best . base = - 1 ;
cur . base = - 1 ;
best . len = 0 ;
cur . base = - 1 ;
cur . len = 0 ;
for ( i = 0 ; i < ( NS_IN6ADDRSZ / NS_INT16SZ ) ; i + + )
{
if ( words [ i ] = = 0 )
{
for ( i = 0 ; i < ( NS_IN6ADDRSZ / NS_INT16SZ ) ; i + + ) {
if ( words [ i ] = = 0 ) {
if ( cur . base = = - 1 )
cur . base = i , cur . len = 1 ;
else
cur . len + + ;
}
else
{
if ( cur . base ! = - 1 )
{
} else {
if ( cur . base ! = - 1 ) {
if ( best . base = = - 1 | | cur . len > best . len )
best = cur ;
cur . base = - 1 ;
}
}
}
if ( cur . base ! = - 1 )
{
if ( cur . base ! = - 1 ) {
if ( best . base = = - 1 | | cur . len > best . len )
best = cur ;
}
@ -187,12 +165,10 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
* Format the result .
*/
tp = tmp ;
for ( i = 0 ; i < ( NS_IN6ADDRSZ / NS_INT16SZ ) ; i + + )
{
for ( i = 0 ; i < ( NS_IN6ADDRSZ / NS_INT16SZ ) ; i + + ) {
/* Are we inside the best run of 0x00's? */
if ( best . base ! = - 1 & & i > = best . base & &
i < ( best . base + best . len ) )
{
i < ( best . base + best . len ) ) {
if ( i = = best . base )
* tp + + = ' : ' ;
continue ;
@ -201,32 +177,31 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
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 ) ) )
if ( i = = 6 & & best . base = = 0 & & ( best . len = = 6 | |
( best . len = = 7 & & words [ 7 ] ! = 0x0001 ) | |
( 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 , " %l x " , words [ i ] ) ) ;
tp + = SPRINTF ( ( tp , " %x " , words [ i ] ) ) ;
}
/* Was it a trailing run of 0x00's? */
if ( best . base ! = - 1 & & ( best . base + best . len ) = = ( NS_IN6ADDRSZ / NS_INT16SZ ) )
if ( best . base ! = - 1 & & ( best . base + best . len ) = =
( NS_IN6ADDRSZ / NS_INT16SZ ) )
* tp + + = ' : ' ;
* tp + + = ' \0 ' ;
/*
* Check for overflow , copy , and we ' re done .
*/
if ( ( size_t ) ( tp - tmp ) > size )
{
SET_ERRNO ( ENOSPC ) ;
if ( ( size_t ) ( tp - tmp ) > size ) {
errno = ENOSPC ;
return ( NULL ) ;
}
strcpy ( dst , tmp ) ;
return ( dst ) ;
}
# endif
/*! \file */