Matter SDK Coverage Report
Current view: top level - inet - IPAddress-StringFuncts.cpp (source / functions) Coverage Total Hit
Test: SHA:f1767a8b0a3778fdf31b1d979afbdf544892fd94 Lines: 67.2 % 58 39
Test Date: 2026-06-03 07:35:21 Functions: 83.3 % 6 5

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *    Copyright (c) 2013-2017 Nest Labs, Inc.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *      This file implements the human-readable string formatting and
      22              :  *      parsing methods from class <tt>Inet::IPAddress</tt>.
      23              :  *
      24              :  */
      25              : 
      26              : #include <algorithm>
      27              : #include <limits>
      28              : #include <stdint.h>
      29              : #include <stdio.h>
      30              : #include <string.h>
      31              : 
      32              : #include <inet/IPAddress.h>
      33              : #include <inet/InetInterface.h>
      34              : #include <lib/support/CodeUtils.h>
      35              : #include <lib/support/StringBuilder.h>
      36              : 
      37              : #if CHIP_SYSTEM_CONFIG_USE_POSIX_SOCKETS
      38              : #include <arpa/inet.h>
      39              : #endif
      40              : 
      41              : namespace chip {
      42              : namespace Inet {
      43              : 
      44              : // Normalize a string to lowercase per RFC 5952 (canonical IPv6 text form).
      45              : // ip6addr_ntoa_r and otIp6AddressToString output uppercase, which is
      46              : // non-canonical.
      47            2 : static void NormalizeIp6ToLower(char * str)
      48              : {
      49           52 :     for (char * p = str; *p != '\0'; ++p)
      50              :     {
      51           50 :         if (*p >= 'A' && *p <= 'F')
      52              :         {
      53            0 :             *p = static_cast<char>(*p + ('a' - 'A'));
      54              :         }
      55              :     }
      56            2 : }
      57              : 
      58        15497 : char * IPAddress::ToString(char * buf, uint32_t bufSize) const
      59              : {
      60              : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
      61              : #if INET_CONFIG_ENABLE_IPV4
      62              :     if (IsIPv4())
      63              :     {
      64              :         ip4_addr_t ip4_addr = ToIPv4();
      65              :         ip4addr_ntoa_r(&ip4_addr, buf, (int) bufSize);
      66              :     }
      67              :     else
      68              : #endif // INET_CONFIG_ENABLE_IPV4
      69              :     {
      70              :         ip6_addr_t ip6_addr = ToIPv6();
      71              :         ip6addr_ntoa_r(&ip6_addr, buf, (int) bufSize);
      72              :         // Normalize to lowercase per RFC 5952 (canonical IPv6 text form).
      73              :         NormalizeIp6ToLower(buf);
      74              :     }
      75              : #elif CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
      76              :     // socklen_t is sometimes signed, sometimes not, so the only safe way to do
      77              :     // this is to promote everything to an unsigned type that's known to be big
      78              :     // enough for everything, then cast back to uint32_t after taking the min.
      79        15497 :     bufSize = static_cast<uint32_t>(
      80        15497 :         std::min(static_cast<uintmax_t>(std::numeric_limits<socklen_t>::max()), static_cast<uintmax_t>(bufSize)));
      81              : #if INET_CONFIG_ENABLE_IPV4
      82        15497 :     if (IsIPv4())
      83              :     {
      84          137 :         const void * addr = &Addr[3];
      85          137 :         const char * s    = inet_ntop(AF_INET, addr, buf, static_cast<socklen_t>(bufSize));
      86              :         // This cast is safe because |s| points into |buf| which is not const.
      87          137 :         buf = const_cast<char *>(s);
      88              :     }
      89              :     else
      90              : #endif // INET_CONFIG_ENABLE_IPV4
      91              :     {
      92        15360 :         const void * addr = &Addr[0];
      93        15360 :         const char * s    = inet_ntop(AF_INET6, addr, buf, static_cast<socklen_t>(bufSize));
      94              :         // This cast is safe because |s| points into |buf| which is not const.
      95        15360 :         buf = const_cast<char *>(s);
      96              :     }
      97              : #elif CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
      98              :     otIp6Address addr = ToIPv6();
      99              :     otIp6AddressToString(&addr, buf, static_cast<uint16_t>(bufSize));
     100              :     // Normalize to lowercase per RFC 5952 (canonical IPv6 text form).
     101              :     NormalizeIp6ToLower(buf);
     102              : #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
     103              : 
     104        15497 :     return buf;
     105              : }
     106              : 
     107            5 : char * IPAddress::ToString(char * buf, uint32_t bufSize, const Inet::InterfaceId & interfaceId) const
     108              : {
     109            5 :     if (IsIPv6LinkLocal() && interfaceId.IsPresent())
     110              :     {
     111              :         char ipStr[IPAddress::kMaxStringLength];
     112            2 :         if (ToString(ipStr, sizeof(ipStr)) == nullptr)
     113              :         {
     114            0 :             return nullptr;
     115              :         }
     116              : 
     117              :         // Normalize to lowercase per RFC 5952 (canonical IPv6 text form).
     118            2 :         NormalizeIp6ToLower(ipStr);
     119              : 
     120            2 :         StringBuilderBase builder(buf, bufSize);
     121            2 :         builder.Add(ipStr);
     122              : 
     123              :         char ifName[Inet::InterfaceId::kMaxIfNameLength];
     124            4 :         if (interfaceId.GetInterfaceName(ifName, sizeof(ifName)) == CHIP_NO_ERROR)
     125              :         {
     126            2 :             builder.Add("%").Add(ifName);
     127              :         }
     128              : 
     129            2 :         return builder.Fit() ? buf : nullptr;
     130              :     }
     131              : 
     132            3 :     return ToString(buf, bufSize);
     133              : }
     134              : 
     135         1813 : bool IPAddress::FromString(const char * str, IPAddress & output)
     136              : {
     137              : #if INET_CONFIG_ENABLE_IPV4
     138         1813 :     if (strchr(str, ':') == nullptr)
     139              :     {
     140              : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     141              :         ip4_addr_t ipv4Addr;
     142              :         if (!ip4addr_aton(str, &ipv4Addr))
     143              :             return false;
     144              : #elif CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
     145              :         struct in_addr ipv4Addr;
     146          409 :         if (inet_pton(AF_INET, str, &ipv4Addr) < 1)
     147            0 :             return false;
     148              : #endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
     149          409 :         output = IPAddress(ipv4Addr);
     150              :     }
     151              :     else
     152              : #endif // INET_CONFIG_ENABLE_IPV4
     153              :     {
     154              : #if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     155              :         ip6_addr_t ipv6Addr;
     156              :         if (!ip6addr_aton(str, &ipv6Addr))
     157              :             return false;
     158              : #elif CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
     159              :         struct in6_addr ipv6Addr;
     160         1404 :         if (inet_pton(AF_INET6, str, &ipv6Addr) < 1)
     161            0 :             return false;
     162              : #elif CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     163              :         otIp6Address ipv6Addr;
     164              :         if (OT_ERROR_NONE != otIp6AddressFromString(str, &ipv6Addr))
     165              :             return false;
     166              : #endif
     167         1404 :         output = IPAddress(ipv6Addr);
     168              :     }
     169              : 
     170         1813 :     return true;
     171              : }
     172              : 
     173           55 : bool IPAddress::FromString(const char * str, size_t strLen, IPAddress & output)
     174              : {
     175           55 :     bool res = false;
     176              : 
     177           55 :     if (strLen < INET6_ADDRSTRLEN)
     178              :     {
     179              :         char hostNameBuf[INET6_ADDRSTRLEN];
     180           55 :         memcpy(hostNameBuf, str, strLen);
     181           55 :         hostNameBuf[strLen] = 0;
     182           55 :         res                 = IPAddress::FromString(hostNameBuf, output);
     183              :     }
     184              : 
     185           55 :     return res;
     186              : }
     187              : 
     188            0 : bool IPAddress::FromString(const char * str, IPAddress & addrOutput, class InterfaceId & ifaceOutput)
     189              : {
     190            0 :     char * addrStr       = const_cast<char *>(str);
     191            0 :     char * addrPart      = nullptr;
     192            0 :     char * scopePart     = nullptr;
     193            0 :     char * strtokContext = nullptr;
     194              : 
     195            0 :     addrPart = strtok_r(addrStr, "%", &strtokContext);
     196            0 :     if (addrPart != nullptr)
     197              :     {
     198            0 :         scopePart = strtok_r(nullptr, "%", &strtokContext);
     199              :     }
     200              : 
     201            0 :     if (addrPart == nullptr || scopePart == nullptr)
     202              :     {
     203            0 :         ifaceOutput = Inet::InterfaceId();
     204            0 :         return Inet::IPAddress::FromString(addrStr, addrOutput);
     205              :     }
     206              : 
     207            0 :     CHIP_ERROR err = Inet::InterfaceId::InterfaceNameToId(scopePart, ifaceOutput);
     208            0 :     if (err != CHIP_NO_ERROR)
     209              :     {
     210            0 :         return false;
     211              :     }
     212            0 :     return Inet::IPAddress::FromString(addrPart, addrOutput);
     213              : }
     214              : 
     215              : } // namespace Inet
     216              : } // namespace chip
        

Generated by: LCOV version 2.0-1