Changeset 50367 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Feb 7, 2014 3:38:41 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/string/strformatrt.cpp
r48935 r50367 56 56 #include "internal/string.h" 57 57 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 */ 67 static 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 } 58 173 59 174 … … 395 510 { 396 511 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); 415 513 return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1); 416 514 } … … 454 552 case RTNETADDRTYPE_IPV6: 455 553 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 474 556 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, 492 559 u.pNetAddr->uPort); 493 560
Note:
See TracChangeset
for help on using the changeset viewer.