VirtualBox

Changeset 50367 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Feb 7, 2014 3:38:41 PM (11 years ago)
Author:
vboxsync
Message:

Make %RTnaipv6 and %RTnaddr format IPv6 addresses according to RFC 5952.

Embedded IPv4 format is used for IPv4-compatible (except :: and ::1),
IPv4-mapped and RFC 2765 IPv4-translated addresses.

Square bracket [addr6]:port notation is used for %RTnaddr with port.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/string/strformatrt.cpp

    r48935 r50367  
    5656#include "internal/string.h"
    5757
     58
     59/**
     60 * Helper function to format IPv6 address according to RFC 5952.
     61 *
     62 * @returns The number of bytes formatted.
     63 * @param   pfnOutput       Pointer to output function.
     64 * @param   pvArgOutput     Argument for the output function.
     65 * @param   pIpv6Addr       IPv6 address
     66 */
     67static size_t rtstrFormatIPv6(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PCRTNETADDRIPV6 pIpv6Addr)
     68{
     69    size_t cch = 0; /* result */
     70
     71    bool fEmbeddedIpv4;
     72    size_t cwHexPart;
     73    size_t cwZeroRun, cwLongestZeroRun;
     74    size_t iZeroStart, iLongestZeroStart;
     75    size_t idx;
     76
     77    Assert(pIpv6Addr != NULL);
     78
     79    /*
     80     * Check for embedded IPv4 address.
     81     *
     82     * IPv4-compatible - ::11.22.33.44 (obsolete)
     83     * IPv4-mapped     - ::ffff:11.22.33.44
     84     * IPv4-translated - ::ffff:0:11.22.33.44 (RFC 2765)
     85     */
     86    fEmbeddedIpv4 = false;
     87    cwHexPart = RT_ELEMENTS(pIpv6Addr->au16);
     88    if (pIpv6Addr->au64[0] == 0
     89        && (   (pIpv6Addr->au32[2] == 0
     90                && (   pIpv6Addr->au32[3] != 0
     91                    && pIpv6Addr->au32[3] != RT_H2BE_U32_C(1)))
     92            || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0x0000ffff)
     93            || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0xffff0000)))
     94    {
     95        fEmbeddedIpv4 = true;
     96        cwHexPart -= 2;
     97    }
     98
     99    cwZeroRun = cwLongestZeroRun = 0;
     100    iZeroStart = iLongestZeroStart = -1;
     101    for (idx = 0; idx <= cwHexPart; ++idx)
     102    {
     103        if (idx < cwHexPart && pIpv6Addr->au16[idx] == 0)
     104        {
     105            if (cwZeroRun == 0)
     106            {
     107                cwZeroRun = 1;
     108                iZeroStart = idx;
     109            }
     110            else
     111                ++cwZeroRun;
     112        }
     113        else
     114        {
     115            if (cwZeroRun != 0)
     116            {
     117                if (cwZeroRun > 1 && cwZeroRun > cwLongestZeroRun)
     118                {
     119                    cwLongestZeroRun = cwZeroRun;
     120                    iLongestZeroStart = iZeroStart;
     121                }
     122                cwZeroRun = 0;
     123                iZeroStart = -1;
     124            }
     125        }
     126    }
     127
     128    if (cwLongestZeroRun == 0)
     129    {
     130        for (idx = 0; idx < cwHexPart; ++idx)
     131            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
     132                               "%s%x",
     133                               idx == 0 ? "" : ":",
     134                               RT_BE2H_U16(pIpv6Addr->au16[idx]));
     135
     136        if (fEmbeddedIpv4)
     137            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
     138    }
     139    else
     140    {
     141        const size_t iLongestZeroEnd = iLongestZeroStart + cwLongestZeroRun;
     142
     143        if (iLongestZeroStart == 0)
     144            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
     145        else
     146            for (idx = 0; idx < iLongestZeroStart; ++idx)
     147                cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
     148                                   "%x:", RT_BE2H_U16(pIpv6Addr->au16[idx]));
     149
     150        if (iLongestZeroEnd == cwHexPart)
     151            cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
     152        else
     153        {
     154            for (idx = iLongestZeroEnd; idx < cwHexPart; ++idx)
     155                cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
     156                                   ":%x", RT_BE2H_U16(pIpv6Addr->au16[idx]));
     157
     158            if (fEmbeddedIpv4)
     159                cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
     160        }
     161    }
     162
     163    if (fEmbeddedIpv4)
     164        cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
     165                           "%u.%u.%u.%u",
     166                           pIpv6Addr->au8[12],
     167                           pIpv6Addr->au8[13],
     168                           pIpv6Addr->au8[14],
     169                           pIpv6Addr->au8[15]);
     170
     171    return cch;
     172}
    58173
    59174
     
    395510                    {
    396511                        if (VALID_PTR(u.pIpv6Addr))
    397                             return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
    398                                                "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
    399                                                u.pIpv6Addr->au8[0],
    400                                                u.pIpv6Addr->au8[1],
    401                                                u.pIpv6Addr->au8[2],
    402                                                u.pIpv6Addr->au8[3],
    403                                                u.pIpv6Addr->au8[4],
    404                                                u.pIpv6Addr->au8[5],
    405                                                u.pIpv6Addr->au8[6],
    406                                                u.pIpv6Addr->au8[7],
    407                                                u.pIpv6Addr->au8[8],
    408                                                u.pIpv6Addr->au8[9],
    409                                                u.pIpv6Addr->au8[10],
    410                                                u.pIpv6Addr->au8[11],
    411                                                u.pIpv6Addr->au8[12],
    412                                                u.pIpv6Addr->au8[13],
    413                                                u.pIpv6Addr->au8[14],
    414                                                u.pIpv6Addr->au8[15]);
     512                            return rtstrFormatIPv6(pfnOutput, pvArgOutput, u.pIpv6Addr);
    415513                        return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
    416514                    }
     
    454552                                case RTNETADDRTYPE_IPV6:
    455553                                    if (u.pNetAddr->uPort == RTNETADDR_PORT_NA)
    456                                         return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
    457                                                            "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
    458                                                            u.pNetAddr->uAddr.IPv6.au8[0],
    459                                                            u.pNetAddr->uAddr.IPv6.au8[1],
    460                                                            u.pNetAddr->uAddr.IPv6.au8[2],
    461                                                            u.pNetAddr->uAddr.IPv6.au8[3],
    462                                                            u.pNetAddr->uAddr.IPv6.au8[4],
    463                                                            u.pNetAddr->uAddr.IPv6.au8[5],
    464                                                            u.pNetAddr->uAddr.IPv6.au8[6],
    465                                                            u.pNetAddr->uAddr.IPv6.au8[7],
    466                                                            u.pNetAddr->uAddr.IPv6.au8[8],
    467                                                            u.pNetAddr->uAddr.IPv6.au8[9],
    468                                                            u.pNetAddr->uAddr.IPv6.au8[10],
    469                                                            u.pNetAddr->uAddr.IPv6.au8[11],
    470                                                            u.pNetAddr->uAddr.IPv6.au8[12],
    471                                                            u.pNetAddr->uAddr.IPv6.au8[13],
    472                                                            u.pNetAddr->uAddr.IPv6.au8[14],
    473                                                            u.pNetAddr->uAddr.IPv6.au8[15]);
     554                                        return rtstrFormatIPv6(pfnOutput, pvArgOutput, &u.pNetAddr->uAddr.IPv6);
     555
    474556                                    return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
    475                                                        "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x %u",
    476                                                        u.pNetAddr->uAddr.IPv6.au8[0],
    477                                                        u.pNetAddr->uAddr.IPv6.au8[1],
    478                                                        u.pNetAddr->uAddr.IPv6.au8[2],
    479                                                        u.pNetAddr->uAddr.IPv6.au8[3],
    480                                                        u.pNetAddr->uAddr.IPv6.au8[4],
    481                                                        u.pNetAddr->uAddr.IPv6.au8[5],
    482                                                        u.pNetAddr->uAddr.IPv6.au8[6],
    483                                                        u.pNetAddr->uAddr.IPv6.au8[7],
    484                                                        u.pNetAddr->uAddr.IPv6.au8[8],
    485                                                        u.pNetAddr->uAddr.IPv6.au8[9],
    486                                                        u.pNetAddr->uAddr.IPv6.au8[10],
    487                                                        u.pNetAddr->uAddr.IPv6.au8[11],
    488                                                        u.pNetAddr->uAddr.IPv6.au8[12],
    489                                                        u.pNetAddr->uAddr.IPv6.au8[13],
    490                                                        u.pNetAddr->uAddr.IPv6.au8[14],
    491                                                        u.pNetAddr->uAddr.IPv6.au8[15],
     557                                                       "[%RTnaipv6]:%u",
     558                                                       &u.pNetAddr->uAddr.IPv6,
    492559                                                       u.pNetAddr->uPort);
    493560
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette