original files of m241
This commit is contained in:
@@ -0,0 +1,443 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcom_inet_ntop.c,v $ $Revision: 1.9.70.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipcom/src/ipcom_inet_ntop.c,v $
|
||||
* $Author: jren $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipcom_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include "ipcom_clib.h"
|
||||
#include "ipcom_sock.h"
|
||||
#include "ipcom_sock6.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Number of 16-bit parts in an IPv6 address
|
||||
*/
|
||||
#define IN6_16BIT_PART_CNT (sizeof (struct Ip_in6_addr) / sizeof (Ip_u16))
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* ntopAfInetFmt - convert IPv4 address to string
|
||||
*
|
||||
* This routine convert a binary representation of an IPv4 address to a string
|
||||
*
|
||||
* RETURNS: pointer to the string, or IP_NULL if the buffer is too small
|
||||
*
|
||||
* ERRNO: N/A
|
||||
*/
|
||||
|
||||
IP_STATIC const char * ntopAfInetFmt
|
||||
(
|
||||
const void * addrPtr, /**< binary representation of Internet address */
|
||||
char * str, /**< storage for the string representation */
|
||||
Ip_size_t strLen, /**< the length of 'str' buffer */
|
||||
const char * fmt /**< address format */
|
||||
)
|
||||
{
|
||||
const unsigned char * inAddr = (const unsigned char *)addrPtr;
|
||||
|
||||
if (strLen <= (Ip_size_t)ipcom_snprintf (str, strLen, fmt,
|
||||
inAddr[0], inAddr[1], inAddr[2], inAddr[3]))
|
||||
{
|
||||
/*
|
||||
* The string buffer is not large enough
|
||||
*/
|
||||
str = IP_NULL;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* appendFmt - append a string generated from a format specifier
|
||||
*
|
||||
* This routine try to append a string using a format specifier as template
|
||||
*
|
||||
* RETURNS: a pointer to the first available character in the string, or IP_NULL
|
||||
* if the current string could not fit into the string buffer
|
||||
*
|
||||
* ERRNO: N/A
|
||||
*/
|
||||
|
||||
IP_STATIC char * appendFmt
|
||||
(
|
||||
char * str,
|
||||
Ip_size_t * strLen,
|
||||
const char * fmt,
|
||||
unsigned val
|
||||
)
|
||||
{
|
||||
if (str != IP_NULL)
|
||||
{
|
||||
Ip_size_t charsRequired = (Ip_size_t)ipcom_snprintf (str, *strLen, fmt, val);
|
||||
|
||||
if (*strLen > charsRequired)
|
||||
{
|
||||
*strLen -= charsRequired;
|
||||
str += charsRequired;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = IP_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* inet6ZeroRangeGet - get the longest range of zeros in an IPv6 address
|
||||
*
|
||||
* This routine get the index and length of the longest range of 16-bit zero
|
||||
* fields in an IPv6 address, only ranges of length two or longer may be
|
||||
* returned according to RFC5952.
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*
|
||||
* ERRNO: N/A
|
||||
*/
|
||||
|
||||
IP_STATIC void inet6ZeroRangeGet
|
||||
(
|
||||
const Ip_u16 * in6,
|
||||
unsigned * zeroIdxPtr,
|
||||
unsigned * zeroLenPtr
|
||||
)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned zIdx = IN6_16BIT_PART_CNT;
|
||||
unsigned zLen = 0;
|
||||
Ip_bool inZero = IP_FALSE;
|
||||
|
||||
*zeroIdxPtr = zIdx;
|
||||
*zeroLenPtr = zLen;
|
||||
|
||||
for (idx = 0; idx < IN6_16BIT_PART_CNT; idx++)
|
||||
{
|
||||
if (inZero)
|
||||
{
|
||||
if (in6[idx] == 0)
|
||||
{
|
||||
zLen++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* According to chapter 4.2.3 in RFC5952, the first zero-range
|
||||
* must be selected if there are two ranges of the same
|
||||
* size. A zero-range field must only be replaced with a
|
||||
* double-colon if there is at least two consecutive zero
|
||||
* fields.
|
||||
*/
|
||||
if (zLen > 1 && zLen > *zeroLenPtr)
|
||||
{
|
||||
*zeroIdxPtr = zIdx;
|
||||
*zeroLenPtr = zLen;
|
||||
}
|
||||
|
||||
inZero = IP_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in6[idx] == 0)
|
||||
{
|
||||
inZero = IP_TRUE;
|
||||
zIdx = idx;
|
||||
zLen = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (zLen > 1 && zLen > *zeroLenPtr)
|
||||
{
|
||||
/*
|
||||
* This case may happen when the zero-range is at the end of the
|
||||
* IPv6-address.
|
||||
*/
|
||||
*zeroIdxPtr = zIdx;
|
||||
*zeroLenPtr = zLen;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* hexFmt - return the format string for a hex16 value
|
||||
*
|
||||
* This routine return the format string to use for a hex16 value at a specific
|
||||
* index into an IPv6 address.
|
||||
*
|
||||
* RETURNS: a string format specifier
|
||||
*
|
||||
* ERRNO: N/A
|
||||
*/
|
||||
|
||||
IP_STATIC const char * hexFmt
|
||||
(
|
||||
unsigned idx,
|
||||
unsigned cnt
|
||||
)
|
||||
{
|
||||
const char * fmt = "%x:";
|
||||
|
||||
if (1 + idx == cnt)
|
||||
{
|
||||
fmt = "%x";
|
||||
}
|
||||
|
||||
return fmt;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* ntopAfInet6Pure - create a string representation of an IPv6 address
|
||||
*
|
||||
* This routine try to create a string representation of the binary format of
|
||||
* an IPv6 address.
|
||||
*
|
||||
* RETURNS: a string representation of the IPv6 address, or IP_NULL if the string
|
||||
* buffer is not large enough
|
||||
*
|
||||
* ERRNO: N/A
|
||||
*/
|
||||
|
||||
IP_STATIC const char * ntopAfInet6Pure
|
||||
(
|
||||
const void * addrPtr, /**< binary representation of Internet address */
|
||||
char * str, /**< storage for the string representation */
|
||||
Ip_size_t strLen /**< the length of 'str' buffer */
|
||||
)
|
||||
{
|
||||
const Ip_u16 * addr16Be = (const Ip_u16 *)addrPtr;
|
||||
unsigned zeroIdx;
|
||||
unsigned zeroLen;
|
||||
unsigned idx;
|
||||
const char * repr = str;
|
||||
|
||||
inet6ZeroRangeGet (addr16Be, &zeroIdx, &zeroLen);
|
||||
|
||||
for (idx = 0; idx < zeroIdx; idx++)
|
||||
{
|
||||
str = appendFmt (str,
|
||||
&strLen,
|
||||
hexFmt (idx, zeroIdx),
|
||||
ip_ntohs (addr16Be[idx]));
|
||||
}
|
||||
|
||||
if (zeroIdx < IN6_16BIT_PART_CNT)
|
||||
{
|
||||
str = appendFmt (str, &strLen, "::", 0);
|
||||
}
|
||||
|
||||
for (idx = zeroIdx + zeroLen; idx < IN6_16BIT_PART_CNT; idx++)
|
||||
{
|
||||
str = appendFmt (str,
|
||||
&strLen,
|
||||
hexFmt (idx, IN6_16BIT_PART_CNT),
|
||||
ip_htons (addr16Be[idx]));
|
||||
}
|
||||
|
||||
if (str == IP_NULL)
|
||||
{
|
||||
repr = IP_NULL;
|
||||
}
|
||||
|
||||
return repr;
|
||||
}
|
||||
|
||||
#ifdef IPCOM_USE_INET6
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* ntopAfInet - convert IPv6 address to string
|
||||
*
|
||||
* This routine convert a binary representation of an IPv6 address to a string
|
||||
*
|
||||
* RETURNS: pointer to the string, or IP_NULL if the buffer is too small
|
||||
*
|
||||
* ERRNO: N/A
|
||||
*/
|
||||
|
||||
IP_STATIC const char * ntopAfInet6
|
||||
(
|
||||
const void * addrPtr, /**< binary representation of Internet address */
|
||||
char * str, /**< storage for the string representation */
|
||||
Ip_size_t strLen /**< the length of 'str' buffer */
|
||||
)
|
||||
{
|
||||
struct Ip_in6_addr in6;
|
||||
const Ip_u16 * addr16Be = (const Ip_u16 *)&in6;
|
||||
const char * repr = IP_NULL;
|
||||
|
||||
(void)ipcom_memcpy (&in6, addrPtr, sizeof in6);
|
||||
if (IP_IN6_IS_ADDR_V4COMPAT (&in6))
|
||||
{
|
||||
/*
|
||||
* IPv4-compatible-IPv6 addresses has the format '::x.y.z.w' where the
|
||||
* dotted quad is the last 4 octets of the IPv6 address.
|
||||
*/
|
||||
repr = ntopAfInetFmt (addr16Be + 6, str, strLen, "::%u.%u.%u.%u");
|
||||
}
|
||||
else if (IP_IN6_IS_ADDR_V4MAPPED (&in6))
|
||||
{
|
||||
/*
|
||||
* IPv4-mapped-IPv6 addresses has the format '::ffff:x.y.z.w' where
|
||||
* the dotted quad is the last 4 octets of the IPv6 address.
|
||||
*
|
||||
* RFC5952 chapter 4.3 state that lowercase letters must be used when
|
||||
* representing hexadecimal numbers.
|
||||
*/
|
||||
repr = ntopAfInetFmt (addr16Be + 6, str, strLen, "::ffff:%u.%u.%u.%u");
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* IPv6 address without embedded IPv4
|
||||
*/
|
||||
repr = ntopAfInet6Pure (&in6, str, strLen);
|
||||
}
|
||||
|
||||
return repr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcom_inet_ntop
|
||||
*===========================================================================
|
||||
* Description: Converts the network address into a character string.
|
||||
* Parameters: family - The address family for the address to convert.
|
||||
* strptr - A pointer to the buffer that will receive the
|
||||
* string representation of the address.
|
||||
* len - The length of the strptr buffer.
|
||||
* Returns: The strptr value if the call was successful or IP_NULL
|
||||
* if failed (get error code from ipcom_errno).
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC IP_CONST char *
|
||||
ipcom_inet_ntop(int family, IP_CONST void *addrptr, char *strptr, Ip_size_t len)
|
||||
{
|
||||
const char * repr = IP_NULL;
|
||||
Ip_bool afNoSupp = IP_FALSE;
|
||||
|
||||
if (addrptr == IP_NULL || strptr == IP_NULL)
|
||||
return IP_NULL;
|
||||
|
||||
switch (family)
|
||||
{
|
||||
#ifdef IPCOM_USE_INET
|
||||
case IP_AF_INET:
|
||||
repr = ntopAfInetFmt (addrptr, strptr, len, "%u.%u.%u.%u");
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPCOM_USE_INET6
|
||||
case IP_AF_INET6:
|
||||
repr = ntopAfInet6 (addrptr, strptr, len);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
afNoSupp = IP_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (repr == IP_NULL)
|
||||
{
|
||||
if (afNoSupp)
|
||||
{
|
||||
(void)ipcom_errno_set (IP_ERRNO_EAFNOSUPPORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)ipcom_errno_set (IP_ERRNO_ENOSPC);
|
||||
}
|
||||
}
|
||||
|
||||
return repr;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user