18e745fdaSopenharmony_ci/*
28e745fdaSopenharmony_ci * Copyright (C) 2022-2023 Huawei Device Co., Ltd.
38e745fdaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48e745fdaSopenharmony_ci * you may not use this file except in compliance with the License.
58e745fdaSopenharmony_ci * You may obtain a copy of the License at
68e745fdaSopenharmony_ci *
78e745fdaSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88e745fdaSopenharmony_ci *
98e745fdaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108e745fdaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118e745fdaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128e745fdaSopenharmony_ci * See the License for the specific language governing permissions and
138e745fdaSopenharmony_ci * limitations under the License.
148e745fdaSopenharmony_ci */
158e745fdaSopenharmony_ci#include "ethernet_configuration.h"
168e745fdaSopenharmony_ci
178e745fdaSopenharmony_ci#include <arpa/inet.h>
188e745fdaSopenharmony_ci#include <cerrno>
198e745fdaSopenharmony_ci#include <cstdlib>
208e745fdaSopenharmony_ci#include <dirent.h>
218e745fdaSopenharmony_ci#include <fcntl.h>
228e745fdaSopenharmony_ci#include <fstream>
238e745fdaSopenharmony_ci#include <limits>
248e745fdaSopenharmony_ci#include <regex>
258e745fdaSopenharmony_ci#include <sstream>
268e745fdaSopenharmony_ci#include <sys/stat.h>
278e745fdaSopenharmony_ci#include <sys/types.h>
288e745fdaSopenharmony_ci#include <unistd.h>
298e745fdaSopenharmony_ci
308e745fdaSopenharmony_ci#include "net_manager_constants.h"
318e745fdaSopenharmony_ci#include "netmanager_base_common_utils.h"
328e745fdaSopenharmony_ci#include "netmgr_ext_log_wrapper.h"
338e745fdaSopenharmony_ci#include "route.h"
348e745fdaSopenharmony_ci#include "securec.h"
358e745fdaSopenharmony_ci
368e745fdaSopenharmony_cinamespace OHOS {
378e745fdaSopenharmony_cinamespace NetManagerStandard {
388e745fdaSopenharmony_cinamespace {
398e745fdaSopenharmony_ciconst std::string IFACE_MATCH = "eth\\d";
408e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_COMPONENT_FLAG = "config_ethernet_interfaces";
418e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_IFACE = "iface";
428e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_LANIFACE = "laniface";
438e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_CAPS = "caps";
448e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_IP = "ip";
458e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_GATEWAY = "gateway";
468e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_DNS = "dns";
478e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_NETMASK = "netmask";
488e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_ROUTE = "route";
498e745fdaSopenharmony_ciconst std::string CONFIG_KEY_ETH_ROUTE_MASK = "routemask";
508e745fdaSopenharmony_ciconstexpr int32_t MKDIR_ERR = -1;
518e745fdaSopenharmony_ciconstexpr int32_t USER_PATH_LEN = 25;
528e745fdaSopenharmony_ciconstexpr const char *FILE_OBLIQUE_LINE = "/";
538e745fdaSopenharmony_ciconstexpr const char *KEY_DEVICE = "DEVICE=";
548e745fdaSopenharmony_ciconstexpr const char *KEY_BOOTPROTO = "BOOTPROTO=";
558e745fdaSopenharmony_ciconstexpr const char *KEY_STATIC = "STATIC";
568e745fdaSopenharmony_ciconstexpr const char *KEY_DHCP = "DHCP";
578e745fdaSopenharmony_ciconstexpr const char *KEY_LAN_STATIC = "LAN_STATIC";
588e745fdaSopenharmony_ciconstexpr const char *KEY_LAN_DHCP = "LAN_DHCP";
598e745fdaSopenharmony_ciconstexpr const char *KEY_IPADDR = "IPADDR=";
608e745fdaSopenharmony_ciconstexpr const char *KEY_NETMASK = "NETMASK=";
618e745fdaSopenharmony_ciconstexpr const char *KEY_GATEWAY = "GATEWAY=";
628e745fdaSopenharmony_ciconstexpr const char *KEY_ROUTE = "ROUTE=";
638e745fdaSopenharmony_ciconstexpr const char *KEY_ROUTE_NETMASK = "ROUTE_NETMASK=";
648e745fdaSopenharmony_ciconstexpr const char *KEY_DNS = "DNS=";
658e745fdaSopenharmony_ciconstexpr const char *KEY_PROXY_HOST = "PROXY_HOST=";
668e745fdaSopenharmony_ciconstexpr const char *KEY_PROXY_PORT = "PROXY_PORT=";
678e745fdaSopenharmony_ciconstexpr const char *KEY_PROXY_EXCLUSIONS = "PROXY_EXCLUSIONS=";
688e745fdaSopenharmony_ciconstexpr const char *WRAP = "\n";
698e745fdaSopenharmony_ciconstexpr const char *DEFAULT_IPV4_ADDR = "0.0.0.0";
708e745fdaSopenharmony_ciconstexpr const char *DEFAULT_IPV6_ADDR = "::";
718e745fdaSopenharmony_ciconstexpr const char *DEFAULT_IPV6_MAX_ADDRESS = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
728e745fdaSopenharmony_ciconstexpr const char *EMPTY_NET_ADDR = "*";
738e745fdaSopenharmony_ciconstexpr const char *ADDR_SEPARATOR = ",";
748e745fdaSopenharmony_ciconstexpr const char *EXCLUSIONS_DELIMITER = ",";
758e745fdaSopenharmony_ci} // namespace
768e745fdaSopenharmony_ci
778e745fdaSopenharmony_ciEthernetConfiguration::EthernetConfiguration()
788e745fdaSopenharmony_ci{
798e745fdaSopenharmony_ci    CreateDir(USER_CONFIG_DIR);
808e745fdaSopenharmony_ci}
818e745fdaSopenharmony_ci
828e745fdaSopenharmony_cibool EthernetConfiguration::ReadEthernetInterfaces(std::map<std::string, std::set<NetCap>> &devCaps,
838e745fdaSopenharmony_ci                                                   std::map<std::string, sptr<InterfaceConfiguration>> &devCfgs,
848e745fdaSopenharmony_ci                                                   const cJSON* const json)
858e745fdaSopenharmony_ci{
868e745fdaSopenharmony_ci    for (int32_t i = 0; i < cJSON_GetArraySize(json); i++) {
878e745fdaSopenharmony_ci        cJSON *item = cJSON_GetArrayItem(json, i);
888e745fdaSopenharmony_ci        if (item == nullptr) {
898e745fdaSopenharmony_ci            continue;
908e745fdaSopenharmony_ci        }
918e745fdaSopenharmony_ci        std::string iface;
928e745fdaSopenharmony_ci        bool isLan = false;
938e745fdaSopenharmony_ci        cJSON *lanIface = cJSON_GetObjectItem(item, CONFIG_KEY_ETH_LANIFACE.c_str());
948e745fdaSopenharmony_ci        if (lanIface == nullptr) {
958e745fdaSopenharmony_ci            cJSON *ethIface = cJSON_GetObjectItem(item, CONFIG_KEY_ETH_IFACE.c_str());
968e745fdaSopenharmony_ci            iface = cJSON_GetStringValue(ethIface);
978e745fdaSopenharmony_ci            isLan = false;
988e745fdaSopenharmony_ci        } else {
998e745fdaSopenharmony_ci            iface = cJSON_GetStringValue(lanIface);
1008e745fdaSopenharmony_ci            isLan = true;
1018e745fdaSopenharmony_ci        }
1028e745fdaSopenharmony_ci        cJSON *capsObj = cJSON_GetObjectItem(item, CONFIG_KEY_ETH_CAPS.c_str());
1038e745fdaSopenharmony_ci        std::set<NetCap> caps;
1048e745fdaSopenharmony_ci        for (int32_t j = 0; j < cJSON_GetArraySize(capsObj); j++) {
1058e745fdaSopenharmony_ci            cJSON *capsItem = cJSON_GetArrayItem(capsObj, j);
1068e745fdaSopenharmony_ci            if (capsItem == nullptr) {
1078e745fdaSopenharmony_ci                continue;
1088e745fdaSopenharmony_ci            }
1098e745fdaSopenharmony_ci            const auto capsValue = capsItem->valueint;
1108e745fdaSopenharmony_ci            NETMGR_EXT_LOG_D("ReadConfigData capsValue : %{public}d", capsValue);
1118e745fdaSopenharmony_ci            caps.insert(NetCap(capsValue));
1128e745fdaSopenharmony_ci        }
1138e745fdaSopenharmony_ci        if (!caps.empty()) {
1148e745fdaSopenharmony_ci            devCaps[iface] = caps;
1158e745fdaSopenharmony_ci        }
1168e745fdaSopenharmony_ci        const auto &fit = devCfgs.find(iface);
1178e745fdaSopenharmony_ci        if (fit != devCfgs.end()) {
1188e745fdaSopenharmony_ci            NETMGR_EXT_LOG_E("The iface=%{public}s device have set!", fit->first.c_str());
1198e745fdaSopenharmony_ci            continue;
1208e745fdaSopenharmony_ci        }
1218e745fdaSopenharmony_ci        sptr<InterfaceConfiguration> config = ConvertJsonToConfiguration(item, isLan);
1228e745fdaSopenharmony_ci        if (config == nullptr) {
1238e745fdaSopenharmony_ci            NETMGR_EXT_LOG_E("config is nullptr");
1248e745fdaSopenharmony_ci            return false;
1258e745fdaSopenharmony_ci        }
1268e745fdaSopenharmony_ci        std::regex re(IFACE_MATCH);
1278e745fdaSopenharmony_ci        if (cJSON_GetObjectItem(item, CONFIG_KEY_ETH_IP.c_str()) && std::regex_search(iface, re)) {
1288e745fdaSopenharmony_ci            devCfgs[iface] = config;
1298e745fdaSopenharmony_ci        }
1308e745fdaSopenharmony_ci    }
1318e745fdaSopenharmony_ci    return true;
1328e745fdaSopenharmony_ci}
1338e745fdaSopenharmony_ci
1348e745fdaSopenharmony_cibool EthernetConfiguration::ReadSystemConfiguration(std::map<std::string, std::set<NetCap>> &devCaps,
1358e745fdaSopenharmony_ci                                                    std::map<std::string, sptr<InterfaceConfiguration>> &devCfgs)
1368e745fdaSopenharmony_ci{
1378e745fdaSopenharmony_ci    const auto &jsonStr = ReadJsonFile(NETWORK_CONFIG_PATH);
1388e745fdaSopenharmony_ci    if (jsonStr.length() == 0) {
1398e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("ReadConfigData config file is return empty!");
1408e745fdaSopenharmony_ci        return false;
1418e745fdaSopenharmony_ci    }
1428e745fdaSopenharmony_ci    cJSON *json = cJSON_Parse(jsonStr.c_str());
1438e745fdaSopenharmony_ci    if (json == nullptr) {
1448e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("json parse failed!");
1458e745fdaSopenharmony_ci        return false;
1468e745fdaSopenharmony_ci    }
1478e745fdaSopenharmony_ci    cJSON *jsonEth = cJSON_GetObjectItem(json, CONFIG_KEY_ETH_COMPONENT_FLAG.c_str());
1488e745fdaSopenharmony_ci    if (jsonEth == nullptr) {
1498e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("ReadConfigData not find config_ethernet_interfaces!");
1508e745fdaSopenharmony_ci        cJSON_Delete(json);
1518e745fdaSopenharmony_ci        return false;
1528e745fdaSopenharmony_ci    }
1538e745fdaSopenharmony_ci    ReadEthernetInterfaces(devCaps, devCfgs, jsonEth);
1548e745fdaSopenharmony_ci    cJSON_Delete(json);
1558e745fdaSopenharmony_ci    return true;
1568e745fdaSopenharmony_ci}
1578e745fdaSopenharmony_ci
1588e745fdaSopenharmony_cisptr<InterfaceConfiguration> EthernetConfiguration::ConvertJsonToConfiguration(const cJSON* const jsonData, bool isLan)
1598e745fdaSopenharmony_ci{
1608e745fdaSopenharmony_ci    sptr<InterfaceConfiguration> config = new (std::nothrow) InterfaceConfiguration();
1618e745fdaSopenharmony_ci    if (config == nullptr) {
1628e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("config is nullptr");
1638e745fdaSopenharmony_ci        return nullptr;
1648e745fdaSopenharmony_ci    }
1658e745fdaSopenharmony_ci
1668e745fdaSopenharmony_ci    if (isLan) {
1678e745fdaSopenharmony_ci        config->mode_ = LAN_STATIC;
1688e745fdaSopenharmony_ci    } else {
1698e745fdaSopenharmony_ci        config->mode_ = STATIC;
1708e745fdaSopenharmony_ci    }
1718e745fdaSopenharmony_ci    std::string ip = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_IP.c_str())->valuestring;
1728e745fdaSopenharmony_ci    std::string route = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_ROUTE.c_str())->valuestring;
1738e745fdaSopenharmony_ci    std::string gateway = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_GATEWAY.c_str())->valuestring;
1748e745fdaSopenharmony_ci    std::string netmask = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_NETMASK.c_str())->valuestring;
1758e745fdaSopenharmony_ci    std::string dns = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_DNS.c_str())->valuestring;
1768e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(ip, config->ipStatic_.ipAddrList_);
1778e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(route, config->ipStatic_.routeList_);
1788e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(gateway, config->ipStatic_.gatewayList_);
1798e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(netmask, config->ipStatic_.netMaskList_);
1808e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(dns, config->ipStatic_.dnsServers_);
1818e745fdaSopenharmony_ci    std::string routeMask = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_ROUTE_MASK.c_str())->valuestring;
1828e745fdaSopenharmony_ci    ParserIfaceIpAndRoute(config, routeMask);
1838e745fdaSopenharmony_ci    return config;
1848e745fdaSopenharmony_ci}
1858e745fdaSopenharmony_ci
1868e745fdaSopenharmony_cibool EthernetConfiguration::ReadUserConfiguration(std::map<std::string, sptr<InterfaceConfiguration>> &devCfgs)
1878e745fdaSopenharmony_ci{
1888e745fdaSopenharmony_ci    DIR *dir = nullptr;
1898e745fdaSopenharmony_ci    dirent *ptr = nullptr;
1908e745fdaSopenharmony_ci    if ((dir = opendir(USER_CONFIG_DIR)) == nullptr) {
1918e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("Read user configuration open dir error dir=[%{public}s]", USER_CONFIG_DIR);
1928e745fdaSopenharmony_ci        return false;
1938e745fdaSopenharmony_ci    }
1948e745fdaSopenharmony_ci    std::string iface;
1958e745fdaSopenharmony_ci    while ((ptr = readdir(dir)) != nullptr) {
1968e745fdaSopenharmony_ci        if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
1978e745fdaSopenharmony_ci            continue;
1988e745fdaSopenharmony_ci        }
1998e745fdaSopenharmony_ci        if (ptr->d_type == DT_REG) {
2008e745fdaSopenharmony_ci            std::string filePath = std::string(USER_CONFIG_DIR) + FILE_OBLIQUE_LINE + ptr->d_name;
2018e745fdaSopenharmony_ci            std::string fileContent;
2028e745fdaSopenharmony_ci            if (!ReadFile(filePath, fileContent)) {
2038e745fdaSopenharmony_ci                continue;
2048e745fdaSopenharmony_ci            }
2058e745fdaSopenharmony_ci            std::string().swap(iface);
2068e745fdaSopenharmony_ci            sptr<InterfaceConfiguration> cfg = new (std::nothrow) InterfaceConfiguration();
2078e745fdaSopenharmony_ci            if (cfg == nullptr) {
2088e745fdaSopenharmony_ci                NETMGR_EXT_LOG_E("cfg new failed for devname[%{public}s]", iface.c_str());
2098e745fdaSopenharmony_ci                continue;
2108e745fdaSopenharmony_ci            }
2118e745fdaSopenharmony_ci            ParserFileConfig(fileContent, iface, cfg);
2128e745fdaSopenharmony_ci            std::regex re(IFACE_MATCH);
2138e745fdaSopenharmony_ci            if (!iface.empty() && std::regex_search(iface, re)) {
2148e745fdaSopenharmony_ci                NETMGR_EXT_LOG_D("ReadFileList devname[%{public}s]", iface.c_str());
2158e745fdaSopenharmony_ci                devCfgs[iface] = cfg;
2168e745fdaSopenharmony_ci            }
2178e745fdaSopenharmony_ci        }
2188e745fdaSopenharmony_ci    }
2198e745fdaSopenharmony_ci    closedir(dir);
2208e745fdaSopenharmony_ci    return true;
2218e745fdaSopenharmony_ci}
2228e745fdaSopenharmony_ci
2238e745fdaSopenharmony_cibool EthernetConfiguration::WriteUserConfiguration(const std::string &iface, sptr<InterfaceConfiguration> &cfg)
2248e745fdaSopenharmony_ci{
2258e745fdaSopenharmony_ci    if (cfg == nullptr) {
2268e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("cfg is nullptr");
2278e745fdaSopenharmony_ci        return false;
2288e745fdaSopenharmony_ci    }
2298e745fdaSopenharmony_ci    if (!CreateDir(USER_CONFIG_DIR)) {
2308e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("create dir failed");
2318e745fdaSopenharmony_ci        return false;
2328e745fdaSopenharmony_ci    }
2338e745fdaSopenharmony_ci
2348e745fdaSopenharmony_ci    if (cfg->mode_ == STATIC || cfg->mode_ == LAN_STATIC) {
2358e745fdaSopenharmony_ci        ParserIfaceIpAndRoute(cfg, std::string());
2368e745fdaSopenharmony_ci    }
2378e745fdaSopenharmony_ci
2388e745fdaSopenharmony_ci    std::string fileContent;
2398e745fdaSopenharmony_ci    GenCfgContent(iface, cfg, fileContent);
2408e745fdaSopenharmony_ci
2418e745fdaSopenharmony_ci    std::string filePath = std::string(USER_CONFIG_DIR) + FILE_OBLIQUE_LINE + iface;
2428e745fdaSopenharmony_ci    return WriteFile(filePath, fileContent);
2438e745fdaSopenharmony_ci}
2448e745fdaSopenharmony_ci
2458e745fdaSopenharmony_cibool EthernetConfiguration::ClearAllUserConfiguration()
2468e745fdaSopenharmony_ci{
2478e745fdaSopenharmony_ci    return DelDir(USER_CONFIG_DIR);
2488e745fdaSopenharmony_ci}
2498e745fdaSopenharmony_ci
2508e745fdaSopenharmony_cibool EthernetConfiguration::ConvertToConfiguration(const EthernetDhcpCallback::DhcpResult &dhcpResult,
2518e745fdaSopenharmony_ci                                                   sptr<StaticConfiguration> &config)
2528e745fdaSopenharmony_ci{
2538e745fdaSopenharmony_ci    if (config == nullptr) {
2548e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("Error ConvertToIpConfiguration config is null");
2558e745fdaSopenharmony_ci        return false;
2568e745fdaSopenharmony_ci    }
2578e745fdaSopenharmony_ci    if (!IsValidDhcpResult(dhcpResult, config)) {
2588e745fdaSopenharmony_ci        return false;
2598e745fdaSopenharmony_ci    }
2608e745fdaSopenharmony_ci
2618e745fdaSopenharmony_ci    INetAddr ipAddr;
2628e745fdaSopenharmony_ci    ipAddr.address_ = dhcpResult.ipAddr;
2638e745fdaSopenharmony_ci    ipAddr.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(dhcpResult.ipAddr));
2648e745fdaSopenharmony_ci    ipAddr.prefixlen_ = (ipAddr.family_ == AF_INET6)
2658e745fdaSopenharmony_ci                            ? static_cast<uint8_t>(CommonUtils::Ipv6PrefixLen(dhcpResult.subNet))
2668e745fdaSopenharmony_ci                            : static_cast<uint8_t>(CommonUtils::Ipv4PrefixLen(dhcpResult.subNet));
2678e745fdaSopenharmony_ci    config->ipAddrList_.push_back(ipAddr);
2688e745fdaSopenharmony_ci
2698e745fdaSopenharmony_ci    INetAddr netMask;
2708e745fdaSopenharmony_ci    netMask.address_ = dhcpResult.subNet;
2718e745fdaSopenharmony_ci    config->netMaskList_.push_back(netMask);
2728e745fdaSopenharmony_ci
2738e745fdaSopenharmony_ci    INetAddr gateway;
2748e745fdaSopenharmony_ci    gateway.address_ = dhcpResult.gateWay;
2758e745fdaSopenharmony_ci    gateway.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(dhcpResult.gateWay));
2768e745fdaSopenharmony_ci    config->gatewayList_.push_back(gateway);
2778e745fdaSopenharmony_ci
2788e745fdaSopenharmony_ci    INetAddr route;
2798e745fdaSopenharmony_ci    if (dhcpResult.gateWay != dhcpResult.route1 && dhcpResult.route1 != EMPTY_NET_ADDR) {
2808e745fdaSopenharmony_ci        route.address_ = dhcpResult.route1;
2818e745fdaSopenharmony_ci        route.prefixlen_ = ipAddr.prefixlen_;
2828e745fdaSopenharmony_ci    } else if (dhcpResult.gateWay != dhcpResult.route2 && dhcpResult.route2 != EMPTY_NET_ADDR) {
2838e745fdaSopenharmony_ci        route.address_ = dhcpResult.route2;
2848e745fdaSopenharmony_ci        route.prefixlen_ = ipAddr.prefixlen_;
2858e745fdaSopenharmony_ci    } else {
2868e745fdaSopenharmony_ci        route.address_ = (ipAddr.family_ == AF_INET6) ? DEFAULT_IPV6_ADDR : DEFAULT_IPV4_ADDR;
2878e745fdaSopenharmony_ci        route.prefixlen_ = 0;
2888e745fdaSopenharmony_ci    }
2898e745fdaSopenharmony_ci    route.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(route.address_));
2908e745fdaSopenharmony_ci    config->routeList_.push_back(route);
2918e745fdaSopenharmony_ci
2928e745fdaSopenharmony_ci    INetAddr dnsNet1;
2938e745fdaSopenharmony_ci    dnsNet1.address_ = dhcpResult.dns1;
2948e745fdaSopenharmony_ci    INetAddr dnsNet2;
2958e745fdaSopenharmony_ci    dnsNet2.address_ = dhcpResult.dns2;
2968e745fdaSopenharmony_ci    config->dnsServers_.push_back(dnsNet1);
2978e745fdaSopenharmony_ci    config->dnsServers_.push_back(dnsNet2);
2988e745fdaSopenharmony_ci    return true;
2998e745fdaSopenharmony_ci}
3008e745fdaSopenharmony_ci
3018e745fdaSopenharmony_cistd::vector<INetAddr> EthernetConfiguration::GetGatewayFromMap(const std::unordered_map<std::string, INetAddr> &temp)
3028e745fdaSopenharmony_ci{
3038e745fdaSopenharmony_ci    std::vector<INetAddr> t;
3048e745fdaSopenharmony_ci    for (auto [k, v] : temp) {
3058e745fdaSopenharmony_ci        t.push_back(v);
3068e745fdaSopenharmony_ci    }
3078e745fdaSopenharmony_ci    return t;
3088e745fdaSopenharmony_ci}
3098e745fdaSopenharmony_ci
3108e745fdaSopenharmony_cistd::vector<INetAddr> EthernetConfiguration::GetGatewayFromRouteList(std::list<Route> &routeList)
3118e745fdaSopenharmony_ci{
3128e745fdaSopenharmony_ci    std::unordered_map<std::string, INetAddr> temp;
3138e745fdaSopenharmony_ci    for (const auto &route : routeList) {
3148e745fdaSopenharmony_ci        temp.emplace(route.gateway_.address_, route.gateway_);
3158e745fdaSopenharmony_ci    }
3168e745fdaSopenharmony_ci    auto temp2 = temp;
3178e745fdaSopenharmony_ci    temp.erase(DEFAULT_IPV4_ADDR);
3188e745fdaSopenharmony_ci    temp.erase(DEFAULT_IPV6_ADDR);
3198e745fdaSopenharmony_ci    if (temp.size() > 0) {
3208e745fdaSopenharmony_ci        return GetGatewayFromMap(temp);
3218e745fdaSopenharmony_ci    }
3228e745fdaSopenharmony_ci    return GetGatewayFromMap(temp2);
3238e745fdaSopenharmony_ci}
3248e745fdaSopenharmony_ci
3258e745fdaSopenharmony_cisptr<InterfaceConfiguration> EthernetConfiguration::MakeInterfaceConfiguration(
3268e745fdaSopenharmony_ci    const sptr<InterfaceConfiguration> &devCfg, const sptr<NetLinkInfo> &devLinkInfo)
3278e745fdaSopenharmony_ci{
3288e745fdaSopenharmony_ci    if (devCfg == nullptr || devLinkInfo == nullptr) {
3298e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("param is nullptr");
3308e745fdaSopenharmony_ci        return nullptr;
3318e745fdaSopenharmony_ci    }
3328e745fdaSopenharmony_ci    sptr<InterfaceConfiguration> cfg = new (std::nothrow) InterfaceConfiguration();
3338e745fdaSopenharmony_ci    if (cfg == nullptr) {
3348e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("cfg new failed");
3358e745fdaSopenharmony_ci        return nullptr;
3368e745fdaSopenharmony_ci    }
3378e745fdaSopenharmony_ci    cfg->mode_ = devCfg->mode_;
3388e745fdaSopenharmony_ci    for (const auto &ipAddr : devLinkInfo->netAddrList_) {
3398e745fdaSopenharmony_ci        cfg->ipStatic_.ipAddrList_.push_back(ipAddr);
3408e745fdaSopenharmony_ci        auto family = CommonUtils::GetAddrFamily(ipAddr.address_);
3418e745fdaSopenharmony_ci        INetAddr netMask;
3428e745fdaSopenharmony_ci        netMask.address_ =
3438e745fdaSopenharmony_ci            ipAddr.netMask_.empty()
3448e745fdaSopenharmony_ci                ? (((family == AF_INET6) ? CommonUtils::GetIpv6Prefix(DEFAULT_IPV6_MAX_ADDRESS, ipAddr.prefixlen_)
3458e745fdaSopenharmony_ci                                         : CommonUtils::GetMaskByLength(ipAddr.prefixlen_)))
3468e745fdaSopenharmony_ci                : ipAddr.netMask_;
3478e745fdaSopenharmony_ci        cfg->ipStatic_.netMaskList_.push_back(netMask);
3488e745fdaSopenharmony_ci    }
3498e745fdaSopenharmony_ci    for (const auto &route : devLinkInfo->routeList_) {
3508e745fdaSopenharmony_ci        cfg->ipStatic_.routeList_.push_back(route.destination_);
3518e745fdaSopenharmony_ci    }
3528e745fdaSopenharmony_ci    cfg->ipStatic_.gatewayList_ = GetGatewayFromRouteList(devLinkInfo->routeList_);
3538e745fdaSopenharmony_ci
3548e745fdaSopenharmony_ci    cfg->ipStatic_.domain_ = devLinkInfo->domain_;
3558e745fdaSopenharmony_ci    for (const auto &addr : devLinkInfo->dnsList_) {
3568e745fdaSopenharmony_ci        cfg->ipStatic_.dnsServers_.push_back(addr);
3578e745fdaSopenharmony_ci    }
3588e745fdaSopenharmony_ci    return cfg;
3598e745fdaSopenharmony_ci}
3608e745fdaSopenharmony_ci
3618e745fdaSopenharmony_cistd::string EthernetConfiguration::ReadJsonFile(const std::string &filePath)
3628e745fdaSopenharmony_ci{
3638e745fdaSopenharmony_ci    std::ifstream infile;
3648e745fdaSopenharmony_ci    std::string strLine;
3658e745fdaSopenharmony_ci    std::string strAll;
3668e745fdaSopenharmony_ci    infile.open(filePath);
3678e745fdaSopenharmony_ci    if (!infile.is_open()) {
3688e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("ReadJsonFile filePath failed");
3698e745fdaSopenharmony_ci        return strAll;
3708e745fdaSopenharmony_ci    }
3718e745fdaSopenharmony_ci    while (getline(infile, strLine)) {
3728e745fdaSopenharmony_ci        strAll.append(strLine);
3738e745fdaSopenharmony_ci    }
3748e745fdaSopenharmony_ci    infile.close();
3758e745fdaSopenharmony_ci    return strAll;
3768e745fdaSopenharmony_ci}
3778e745fdaSopenharmony_ci
3788e745fdaSopenharmony_cibool EthernetConfiguration::IsDirExist(const std::string &dirPath)
3798e745fdaSopenharmony_ci{
3808e745fdaSopenharmony_ci    struct stat status;
3818e745fdaSopenharmony_ci    if (dirPath.empty()) {
3828e745fdaSopenharmony_ci        return false;
3838e745fdaSopenharmony_ci    }
3848e745fdaSopenharmony_ci    return (stat(dirPath.c_str(), &status) == 0);
3858e745fdaSopenharmony_ci}
3868e745fdaSopenharmony_ci
3878e745fdaSopenharmony_cibool EthernetConfiguration::CreateDir(const std::string &dirPath)
3888e745fdaSopenharmony_ci{
3898e745fdaSopenharmony_ci    if (IsDirExist(dirPath)) {
3908e745fdaSopenharmony_ci        return true;
3918e745fdaSopenharmony_ci    }
3928e745fdaSopenharmony_ci    if (mkdir(dirPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == MKDIR_ERR) {
3938e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("mkdir failed %{public}d: %{public}s", errno, strerror(errno));
3948e745fdaSopenharmony_ci        return false;
3958e745fdaSopenharmony_ci    }
3968e745fdaSopenharmony_ci    return true;
3978e745fdaSopenharmony_ci}
3988e745fdaSopenharmony_ci
3998e745fdaSopenharmony_cibool EthernetConfiguration::DelDir(const std::string &dirPath)
4008e745fdaSopenharmony_ci{
4018e745fdaSopenharmony_ci    DIR *dir = nullptr;
4028e745fdaSopenharmony_ci    dirent *entry = nullptr;
4038e745fdaSopenharmony_ci    struct stat statbuf;
4048e745fdaSopenharmony_ci    if ((dir = opendir(dirPath.c_str())) == nullptr) {
4058e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("EthernetConfiguration DelDir open user dir failed!");
4068e745fdaSopenharmony_ci        return false;
4078e745fdaSopenharmony_ci    }
4088e745fdaSopenharmony_ci    while ((entry = readdir(dir)) != nullptr) {
4098e745fdaSopenharmony_ci        std::string filePath = dirPath + FILE_OBLIQUE_LINE + entry->d_name;
4108e745fdaSopenharmony_ci        lstat(filePath.c_str(), &statbuf);
4118e745fdaSopenharmony_ci        if (S_ISREG(statbuf.st_mode)) {
4128e745fdaSopenharmony_ci            remove(filePath.c_str());
4138e745fdaSopenharmony_ci        }
4148e745fdaSopenharmony_ci    }
4158e745fdaSopenharmony_ci    closedir(dir);
4168e745fdaSopenharmony_ci    sync();
4178e745fdaSopenharmony_ci    return rmdir(dirPath.c_str()) >= 0;
4188e745fdaSopenharmony_ci}
4198e745fdaSopenharmony_ci
4208e745fdaSopenharmony_cibool EthernetConfiguration::IsFileExist(const std::string &filePath, std::string &realPath)
4218e745fdaSopenharmony_ci{
4228e745fdaSopenharmony_ci    char tmpPath[PATH_MAX] = {0};
4238e745fdaSopenharmony_ci    if (!realpath(filePath.c_str(), tmpPath)) {
4248e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("file name is error");
4258e745fdaSopenharmony_ci        return false;
4268e745fdaSopenharmony_ci    }
4278e745fdaSopenharmony_ci    if (strncmp(tmpPath, USER_CONFIG_DIR, USER_PATH_LEN) != 0) {
4288e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("file path is error");
4298e745fdaSopenharmony_ci        return false;
4308e745fdaSopenharmony_ci    }
4318e745fdaSopenharmony_ci    realPath = tmpPath;
4328e745fdaSopenharmony_ci    return true;
4338e745fdaSopenharmony_ci}
4348e745fdaSopenharmony_ci
4358e745fdaSopenharmony_cibool EthernetConfiguration::ReadFile(const std::string &filePath, std::string &fileContent)
4368e745fdaSopenharmony_ci{
4378e745fdaSopenharmony_ci    std::unique_lock<std::mutex> lock(mutex_);
4388e745fdaSopenharmony_ci    if (filePath.empty()) {
4398e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("filePath empty.");
4408e745fdaSopenharmony_ci        return false;
4418e745fdaSopenharmony_ci    }
4428e745fdaSopenharmony_ci    std::string realPath;
4438e745fdaSopenharmony_ci    if (!IsFileExist(filePath, realPath)) {
4448e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("[%{public}s] not exist.", filePath.c_str());
4458e745fdaSopenharmony_ci        return false;
4468e745fdaSopenharmony_ci    }
4478e745fdaSopenharmony_ci    std::fstream file(realPath.c_str(), std::fstream::in);
4488e745fdaSopenharmony_ci    if (!file.is_open()) {
4498e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("EthernetConfiguration read file failed.err %{public}d %{public}s", errno, strerror(errno));
4508e745fdaSopenharmony_ci        return false;
4518e745fdaSopenharmony_ci    }
4528e745fdaSopenharmony_ci    std::stringstream buffer;
4538e745fdaSopenharmony_ci    buffer << file.rdbuf();
4548e745fdaSopenharmony_ci    fileContent = buffer.str();
4558e745fdaSopenharmony_ci    file.close();
4568e745fdaSopenharmony_ci    return true;
4578e745fdaSopenharmony_ci}
4588e745fdaSopenharmony_ci
4598e745fdaSopenharmony_cibool EthernetConfiguration::WriteFile(const std::string &filePath, const std::string &fileContent)
4608e745fdaSopenharmony_ci{
4618e745fdaSopenharmony_ci    std::fstream file(filePath.c_str(), std::fstream::out | std::fstream::trunc);
4628e745fdaSopenharmony_ci    if (!file.is_open()) {
4638e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("EthernetConfiguration write file=%{public}s fstream failed. err %{public}d %{public}s",
4648e745fdaSopenharmony_ci                         filePath.c_str(), errno, strerror(errno));
4658e745fdaSopenharmony_ci        return false;
4668e745fdaSopenharmony_ci    }
4678e745fdaSopenharmony_ci    file << fileContent.c_str();
4688e745fdaSopenharmony_ci    file.close();
4698e745fdaSopenharmony_ci    sync();
4708e745fdaSopenharmony_ci    return true;
4718e745fdaSopenharmony_ci}
4728e745fdaSopenharmony_ci
4738e745fdaSopenharmony_civoid EthernetConfiguration::ParserFileConfig(const std::string &fileContent, std::string &iface,
4748e745fdaSopenharmony_ci                                             sptr<InterfaceConfiguration> cfg)
4758e745fdaSopenharmony_ci{
4768e745fdaSopenharmony_ci    ParseDevice(fileContent, iface);
4778e745fdaSopenharmony_ci    ParseBootProto(fileContent, cfg);
4788e745fdaSopenharmony_ci    ParseStaticConfig(fileContent, cfg);
4798e745fdaSopenharmony_ci    ParserFileHttpProxy(fileContent, cfg);
4808e745fdaSopenharmony_ci}
4818e745fdaSopenharmony_ci
4828e745fdaSopenharmony_civoid EthernetConfiguration::ParseDevice(const std::string &fileContent, std::string &iface)
4838e745fdaSopenharmony_ci{
4848e745fdaSopenharmony_ci    std::string::size_type pos = fileContent.find(KEY_DEVICE);
4858e745fdaSopenharmony_ci    if (pos == std::string::npos) {
4868e745fdaSopenharmony_ci        return;
4878e745fdaSopenharmony_ci    }
4888e745fdaSopenharmony_ci    pos += strlen(KEY_DEVICE);
4898e745fdaSopenharmony_ci    const auto &device = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
4908e745fdaSopenharmony_ci    iface = device;
4918e745fdaSopenharmony_ci}
4928e745fdaSopenharmony_ci
4938e745fdaSopenharmony_civoid EthernetConfiguration::ParseBootProto(const std::string &fileContent, sptr<InterfaceConfiguration> cfg)
4948e745fdaSopenharmony_ci{
4958e745fdaSopenharmony_ci    std::string::size_type pos = fileContent.find(KEY_BOOTPROTO);
4968e745fdaSopenharmony_ci    if (pos == std::string::npos) {
4978e745fdaSopenharmony_ci        return;
4988e745fdaSopenharmony_ci    }
4998e745fdaSopenharmony_ci    pos += strlen(KEY_BOOTPROTO);
5008e745fdaSopenharmony_ci    const auto &bootProto = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
5018e745fdaSopenharmony_ci    if (bootProto == KEY_LAN_STATIC) {
5028e745fdaSopenharmony_ci        cfg->mode_ = LAN_STATIC;
5038e745fdaSopenharmony_ci    } else if (bootProto == KEY_LAN_DHCP) {
5048e745fdaSopenharmony_ci        cfg->mode_ = LAN_DHCP;
5058e745fdaSopenharmony_ci    } else if (bootProto == KEY_STATIC) {
5068e745fdaSopenharmony_ci        cfg->mode_ = STATIC;
5078e745fdaSopenharmony_ci    } else {
5088e745fdaSopenharmony_ci        cfg->mode_ = DHCP;
5098e745fdaSopenharmony_ci    }
5108e745fdaSopenharmony_ci}
5118e745fdaSopenharmony_ci
5128e745fdaSopenharmony_civoid EthernetConfiguration::ParseStaticConfig(const std::string &fileContent, sptr<InterfaceConfiguration> cfg)
5138e745fdaSopenharmony_ci{
5148e745fdaSopenharmony_ci    if (cfg->mode_ != STATIC && cfg->mode_ != LAN_STATIC) {
5158e745fdaSopenharmony_ci        return;
5168e745fdaSopenharmony_ci    }
5178e745fdaSopenharmony_ci    std::string ipAddresses, netMasks, gateways, routes, routeMasks, dnsServers;
5188e745fdaSopenharmony_ci    auto pos = fileContent.find(KEY_IPADDR);
5198e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5208e745fdaSopenharmony_ci        pos += strlen(KEY_IPADDR);
5218e745fdaSopenharmony_ci        ipAddresses = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
5228e745fdaSopenharmony_ci    }
5238e745fdaSopenharmony_ci
5248e745fdaSopenharmony_ci    pos = fileContent.find(KEY_NETMASK);
5258e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5268e745fdaSopenharmony_ci        pos += strlen(KEY_NETMASK);
5278e745fdaSopenharmony_ci        netMasks = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
5288e745fdaSopenharmony_ci    }
5298e745fdaSopenharmony_ci
5308e745fdaSopenharmony_ci    pos = fileContent.find(KEY_GATEWAY);
5318e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5328e745fdaSopenharmony_ci        pos += strlen(KEY_GATEWAY);
5338e745fdaSopenharmony_ci        gateways = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
5348e745fdaSopenharmony_ci    }
5358e745fdaSopenharmony_ci
5368e745fdaSopenharmony_ci    pos = fileContent.find(KEY_ROUTE);
5378e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5388e745fdaSopenharmony_ci        pos += strlen(KEY_ROUTE);
5398e745fdaSopenharmony_ci        routes = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
5408e745fdaSopenharmony_ci    }
5418e745fdaSopenharmony_ci
5428e745fdaSopenharmony_ci    pos = fileContent.find(KEY_ROUTE_NETMASK);
5438e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5448e745fdaSopenharmony_ci        pos += strlen(KEY_ROUTE_NETMASK);
5458e745fdaSopenharmony_ci        routeMasks = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
5468e745fdaSopenharmony_ci    }
5478e745fdaSopenharmony_ci
5488e745fdaSopenharmony_ci    pos = fileContent.find(KEY_DNS);
5498e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5508e745fdaSopenharmony_ci        pos += strlen(KEY_DNS);
5518e745fdaSopenharmony_ci        dnsServers = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
5528e745fdaSopenharmony_ci    }
5538e745fdaSopenharmony_ci
5548e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(ipAddresses, cfg->ipStatic_.ipAddrList_);
5558e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(routes, cfg->ipStatic_.routeList_);
5568e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(gateways, cfg->ipStatic_.gatewayList_);
5578e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(netMasks, cfg->ipStatic_.netMaskList_);
5588e745fdaSopenharmony_ci    StaticConfiguration::ExtractNetAddrBySeparator(dnsServers, cfg->ipStatic_.dnsServers_);
5598e745fdaSopenharmony_ci    ParserIfaceIpAndRoute(cfg, routeMasks);
5608e745fdaSopenharmony_ci}
5618e745fdaSopenharmony_ci
5628e745fdaSopenharmony_civoid EthernetConfiguration::ParserFileHttpProxy(const std::string &fileContent, const sptr<InterfaceConfiguration> &cfg)
5638e745fdaSopenharmony_ci{
5648e745fdaSopenharmony_ci    std::string::size_type pos = fileContent.find(KEY_PROXY_HOST);
5658e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5668e745fdaSopenharmony_ci        pos += strlen(KEY_PROXY_HOST);
5678e745fdaSopenharmony_ci        cfg->httpProxy_.SetHost(fileContent.substr(pos, fileContent.find(WRAP, pos) - pos));
5688e745fdaSopenharmony_ci    }
5698e745fdaSopenharmony_ci
5708e745fdaSopenharmony_ci    pos = fileContent.find(KEY_PROXY_PORT);
5718e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5728e745fdaSopenharmony_ci        pos += strlen(KEY_PROXY_PORT);
5738e745fdaSopenharmony_ci        uint32_t port = CommonUtils::StrToUint(fileContent.substr(pos, fileContent.find(WRAP, pos) - pos));
5748e745fdaSopenharmony_ci        cfg->httpProxy_.SetPort(static_cast<uint16_t>(port));
5758e745fdaSopenharmony_ci    }
5768e745fdaSopenharmony_ci
5778e745fdaSopenharmony_ci    pos = fileContent.find(KEY_PROXY_EXCLUSIONS);
5788e745fdaSopenharmony_ci    if (pos != std::string::npos) {
5798e745fdaSopenharmony_ci        pos += strlen(KEY_PROXY_EXCLUSIONS);
5808e745fdaSopenharmony_ci        auto exclusions = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
5818e745fdaSopenharmony_ci        std::list<std::string> exclusionList;
5828e745fdaSopenharmony_ci        for (const auto &exclusion : CommonUtils::Split(exclusions, EXCLUSIONS_DELIMITER)) {
5838e745fdaSopenharmony_ci            exclusionList.push_back(exclusion);
5848e745fdaSopenharmony_ci        }
5858e745fdaSopenharmony_ci        cfg->httpProxy_.SetExclusionList(exclusionList);
5868e745fdaSopenharmony_ci    }
5878e745fdaSopenharmony_ci}
5888e745fdaSopenharmony_ci
5898e745fdaSopenharmony_civoid EthernetConfiguration::ParserIfaceIpAndRoute(sptr<InterfaceConfiguration> &cfg, const std::string &rootNetMask)
5908e745fdaSopenharmony_ci{
5918e745fdaSopenharmony_ci    if (cfg == nullptr) {
5928e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("cfg is nullptr");
5938e745fdaSopenharmony_ci        return;
5948e745fdaSopenharmony_ci    }
5958e745fdaSopenharmony_ci
5968e745fdaSopenharmony_ci    std::for_each(cfg->ipStatic_.netMaskList_.begin(), cfg->ipStatic_.netMaskList_.end(), [&cfg](const auto &netMask) {
5978e745fdaSopenharmony_ci        auto maskFamily = CommonUtils::GetAddrFamily(netMask.address_);
5988e745fdaSopenharmony_ci        for (auto &ipAddr : cfg->ipStatic_.ipAddrList_) {
5998e745fdaSopenharmony_ci            if (maskFamily != CommonUtils::GetAddrFamily(ipAddr.address_)) {
6008e745fdaSopenharmony_ci                continue;
6018e745fdaSopenharmony_ci            }
6028e745fdaSopenharmony_ci            ipAddr.netMask_ = netMask.address_;
6038e745fdaSopenharmony_ci            ipAddr.prefixlen_ =
6048e745fdaSopenharmony_ci	    (maskFamily == AF_INET6) ? static_cast<uint32_t>(CommonUtils::Ipv6PrefixLen(netMask.address_))
6058e745fdaSopenharmony_ci                                     : static_cast<uint32_t>(CommonUtils::Ipv4PrefixLen(netMask.address_));
6068e745fdaSopenharmony_ci            break;
6078e745fdaSopenharmony_ci        }
6088e745fdaSopenharmony_ci    });
6098e745fdaSopenharmony_ci
6108e745fdaSopenharmony_ci    for (const auto &routeMask : CommonUtils::Split(rootNetMask, ADDR_SEPARATOR)) {
6118e745fdaSopenharmony_ci        auto maskFamily = CommonUtils::GetAddrFamily(routeMask);
6128e745fdaSopenharmony_ci        for (auto &route : cfg->ipStatic_.routeList_) {
6138e745fdaSopenharmony_ci            if (maskFamily != CommonUtils::GetAddrFamily(route.address_)) {
6148e745fdaSopenharmony_ci                continue;
6158e745fdaSopenharmony_ci            }
6168e745fdaSopenharmony_ci            route.prefixlen_ = (maskFamily == AF_INET6) ? static_cast<uint32_t>(CommonUtils::Ipv6PrefixLen(routeMask))
6178e745fdaSopenharmony_ci                                                        : static_cast<uint32_t>(CommonUtils::Ipv4PrefixLen(routeMask));
6188e745fdaSopenharmony_ci            break;
6198e745fdaSopenharmony_ci        }
6208e745fdaSopenharmony_ci    }
6218e745fdaSopenharmony_ci}
6228e745fdaSopenharmony_ci
6238e745fdaSopenharmony_cistd::string EthernetConfiguration::GetIfaceMode(IPSetMode mode)
6248e745fdaSopenharmony_ci{
6258e745fdaSopenharmony_ci    switch (mode) {
6268e745fdaSopenharmony_ci        case LAN_STATIC:
6278e745fdaSopenharmony_ci            return KEY_LAN_STATIC;
6288e745fdaSopenharmony_ci        case LAN_DHCP:
6298e745fdaSopenharmony_ci            return KEY_LAN_DHCP;
6308e745fdaSopenharmony_ci        case STATIC:
6318e745fdaSopenharmony_ci            return KEY_STATIC;
6328e745fdaSopenharmony_ci        default:
6338e745fdaSopenharmony_ci            return KEY_DHCP;
6348e745fdaSopenharmony_ci    }
6358e745fdaSopenharmony_ci}
6368e745fdaSopenharmony_ci
6378e745fdaSopenharmony_civoid EthernetConfiguration::GenCfgContent(const std::string &iface, sptr<InterfaceConfiguration> cfg,
6388e745fdaSopenharmony_ci                                          std::string &fileContent)
6398e745fdaSopenharmony_ci{
6408e745fdaSopenharmony_ci    if (cfg == nullptr) {
6418e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("cfg is nullptr");
6428e745fdaSopenharmony_ci        return;
6438e745fdaSopenharmony_ci    }
6448e745fdaSopenharmony_ci    std::string().swap(fileContent);
6458e745fdaSopenharmony_ci    fileContent = fileContent + KEY_DEVICE + iface + WRAP;
6468e745fdaSopenharmony_ci    std::string mode = GetIfaceMode(cfg->mode_);
6478e745fdaSopenharmony_ci    fileContent = fileContent + KEY_BOOTPROTO + mode + WRAP;
6488e745fdaSopenharmony_ci    if (cfg->mode_ == STATIC || cfg->mode_ == LAN_STATIC) {
6498e745fdaSopenharmony_ci        std::string ipAddresses = AccumulateNetAddress(cfg->ipStatic_.ipAddrList_);
6508e745fdaSopenharmony_ci        std::string netMasks = AccumulateNetAddress(cfg->ipStatic_.netMaskList_);
6518e745fdaSopenharmony_ci        std::string gateways = AccumulateNetAddress(cfg->ipStatic_.gatewayList_);
6528e745fdaSopenharmony_ci        std::string routes = AccumulateNetAddress(cfg->ipStatic_.routeList_);
6538e745fdaSopenharmony_ci        std::string routeMasks =
6548e745fdaSopenharmony_ci            std::accumulate(cfg->ipStatic_.routeList_.begin(), cfg->ipStatic_.routeList_.end(), std::string(),
6558e745fdaSopenharmony_ci                            [](const std::string &routeMask, const INetAddr &iter) {
6568e745fdaSopenharmony_ci                                auto family = CommonUtils::GetAddrFamily(iter.address_);
6578e745fdaSopenharmony_ci                                std::string mask = (family == AF_INET6) ? DEFAULT_IPV6_ADDR : DEFAULT_IPV4_ADDR;
6588e745fdaSopenharmony_ci                                return routeMask.empty() ? routeMask + mask : (routeMask + ADDR_SEPARATOR + mask);
6598e745fdaSopenharmony_ci                            });
6608e745fdaSopenharmony_ci        std::string dnsServers = AccumulateNetAddress(cfg->ipStatic_.dnsServers_);
6618e745fdaSopenharmony_ci
6628e745fdaSopenharmony_ci        fileContent = fileContent + KEY_IPADDR + ipAddresses + WRAP;
6638e745fdaSopenharmony_ci        fileContent = fileContent + KEY_NETMASK + netMasks + WRAP;
6648e745fdaSopenharmony_ci        fileContent = fileContent + KEY_GATEWAY + gateways + WRAP;
6658e745fdaSopenharmony_ci        fileContent = fileContent + KEY_ROUTE + routes + WRAP;
6668e745fdaSopenharmony_ci        fileContent = fileContent + KEY_ROUTE_NETMASK + routeMasks + WRAP;
6678e745fdaSopenharmony_ci        fileContent = fileContent + KEY_DNS + dnsServers + WRAP;
6688e745fdaSopenharmony_ci    }
6698e745fdaSopenharmony_ci    GenHttpProxyContent(cfg, fileContent);
6708e745fdaSopenharmony_ci}
6718e745fdaSopenharmony_ci
6728e745fdaSopenharmony_civoid EthernetConfiguration::GenHttpProxyContent(const sptr<InterfaceConfiguration> &cfg, std::string &fileContent)
6738e745fdaSopenharmony_ci{
6748e745fdaSopenharmony_ci    const auto &exclusionList = cfg->httpProxy_.GetExclusionList();
6758e745fdaSopenharmony_ci    std::string exclusions =
6768e745fdaSopenharmony_ci        std::accumulate(exclusionList.begin(), exclusionList.end(), std::string(),
6778e745fdaSopenharmony_ci                        [](const std::string &exclusion, const std::string &next) {
6788e745fdaSopenharmony_ci                            return exclusion.empty() ? exclusion + next : (exclusion + EXCLUSIONS_DELIMITER + next);
6798e745fdaSopenharmony_ci                        });
6808e745fdaSopenharmony_ci
6818e745fdaSopenharmony_ci    fileContent = fileContent + KEY_PROXY_HOST + cfg->httpProxy_.GetHost() + WRAP;
6828e745fdaSopenharmony_ci    fileContent = fileContent + KEY_PROXY_PORT + std::to_string(cfg->httpProxy_.GetPort()) + WRAP;
6838e745fdaSopenharmony_ci    fileContent = fileContent + KEY_PROXY_EXCLUSIONS + exclusions + WRAP;
6848e745fdaSopenharmony_ci}
6858e745fdaSopenharmony_ci
6868e745fdaSopenharmony_cistd::string EthernetConfiguration::AccumulateNetAddress(const std::vector<INetAddr> &netAddrList)
6878e745fdaSopenharmony_ci{
6888e745fdaSopenharmony_ci    return std::accumulate(netAddrList.begin(), netAddrList.end(), std::string(),
6898e745fdaSopenharmony_ci                           [](const std::string &addr, const INetAddr &iter) {
6908e745fdaSopenharmony_ci                               return addr.empty() ? (addr + iter.address_) : (addr + ADDR_SEPARATOR + iter.address_);
6918e745fdaSopenharmony_ci                           });
6928e745fdaSopenharmony_ci}
6938e745fdaSopenharmony_ci
6948e745fdaSopenharmony_cibool EthernetConfiguration::IsValidDhcpResult(const EthernetDhcpCallback::DhcpResult &dhcpResult,
6958e745fdaSopenharmony_ci                                              sptr<StaticConfiguration> &config)
6968e745fdaSopenharmony_ci{
6978e745fdaSopenharmony_ci    if (config == nullptr) {
6988e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("config is nullptr");
6998e745fdaSopenharmony_ci        return false;
7008e745fdaSopenharmony_ci    }
7018e745fdaSopenharmony_ci    if (dhcpResult.ipAddr.empty()) {
7028e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("DhcpResult ip addr is empty");
7038e745fdaSopenharmony_ci        return false;
7048e745fdaSopenharmony_ci    }
7058e745fdaSopenharmony_ci
7068e745fdaSopenharmony_ci    bool isSameIp = false;
7078e745fdaSopenharmony_ci    bool isSameGateway = false;
7088e745fdaSopenharmony_ci    if (std::any_of(config->ipAddrList_.begin(), config->ipAddrList_.end(), [&dhcpResult](const auto &ipAddr) {
7098e745fdaSopenharmony_ci        return dhcpResult.ipAddr == ipAddr.address_;
7108e745fdaSopenharmony_ci        })) {
7118e745fdaSopenharmony_ci        NETMGR_EXT_LOG_I("Same ip addr:%{public}s", CommonUtils::ToAnonymousIp(dhcpResult.ipAddr).c_str());
7128e745fdaSopenharmony_ci        isSameIp = true;
7138e745fdaSopenharmony_ci    }
7148e745fdaSopenharmony_ci
7158e745fdaSopenharmony_ci    if (std::any_of(config->gatewayList_.begin(), config->gatewayList_.end(), [&dhcpResult](const auto &gateway) {
7168e745fdaSopenharmony_ci        return dhcpResult.gateWay == gateway.address_;
7178e745fdaSopenharmony_ci        })) {
7188e745fdaSopenharmony_ci        NETMGR_EXT_LOG_I("Same gateway:%{public}s", CommonUtils::ToAnonymousIp(dhcpResult.gateWay).c_str());
7198e745fdaSopenharmony_ci        isSameGateway = true;
7208e745fdaSopenharmony_ci    }
7218e745fdaSopenharmony_ci    return !(isSameIp && isSameGateway);
7228e745fdaSopenharmony_ci}
7238e745fdaSopenharmony_ci} // namespace NetManagerStandard
7248e745fdaSopenharmony_ci} // namespace OHOS
725