• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "ethernet_configuration.h"
16 
17 #include <arpa/inet.h>
18 #include <cerrno>
19 #include <cstdlib>
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <fstream>
23 #include <limits>
24 #include <regex>
25 #include <sstream>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 
30 #include "net_manager_constants.h"
31 #include "netmanager_base_common_utils.h"
32 #include "netmgr_ext_log_wrapper.h"
33 #include "route.h"
34 #include "securec.h"
35 
36 namespace OHOS {
37 namespace NetManagerStandard {
38 namespace {
39 const std::string IFACE_MATCH = "eth\\d";
40 const std::string CONFIG_KEY_ETH_COMPONENT_FLAG = "config_ethernet_interfaces";
41 const std::string CONFIG_KEY_ETH_IFACE = "iface";
42 const std::string CONFIG_KEY_ETH_LANIFACE = "laniface";
43 const std::string CONFIG_KEY_ETH_CAPS = "caps";
44 const std::string CONFIG_KEY_ETH_IP = "ip";
45 const std::string CONFIG_KEY_ETH_GATEWAY = "gateway";
46 const std::string CONFIG_KEY_ETH_DNS = "dns";
47 const std::string CONFIG_KEY_ETH_NETMASK = "netmask";
48 const std::string CONFIG_KEY_ETH_ROUTE = "route";
49 const std::string CONFIG_KEY_ETH_ROUTE_MASK = "routemask";
50 constexpr int32_t MKDIR_ERR = -1;
51 constexpr int32_t USER_PATH_LEN = 25;
52 constexpr const char *FILE_OBLIQUE_LINE = "/";
53 constexpr const char *KEY_DEVICE = "DEVICE=";
54 constexpr const char *KEY_BOOTPROTO = "BOOTPROTO=";
55 constexpr const char *KEY_STATIC = "STATIC";
56 constexpr const char *KEY_DHCP = "DHCP";
57 constexpr const char *KEY_LAN_STATIC = "LAN_STATIC";
58 constexpr const char *KEY_LAN_DHCP = "LAN_DHCP";
59 constexpr const char *KEY_IPADDR = "IPADDR=";
60 constexpr const char *KEY_NETMASK = "NETMASK=";
61 constexpr const char *KEY_GATEWAY = "GATEWAY=";
62 constexpr const char *KEY_ROUTE = "ROUTE=";
63 constexpr const char *KEY_ROUTE_NETMASK = "ROUTE_NETMASK=";
64 constexpr const char *KEY_DNS = "DNS=";
65 constexpr const char *KEY_PROXY_HOST = "PROXY_HOST=";
66 constexpr const char *KEY_PROXY_PORT = "PROXY_PORT=";
67 constexpr const char *KEY_PROXY_EXCLUSIONS = "PROXY_EXCLUSIONS=";
68 constexpr const char *WRAP = "\n";
69 constexpr const char *DEFAULT_IPV4_ADDR = "0.0.0.0";
70 constexpr const char *DEFAULT_IPV6_ADDR = "::";
71 constexpr const char *DEFAULT_IPV6_MAX_ADDRESS = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
72 constexpr const char *EMPTY_NET_ADDR = "*";
73 constexpr const char *ADDR_SEPARATOR = ",";
74 constexpr const char *EXCLUSIONS_DELIMITER = ",";
75 } // namespace
76 
EthernetConfiguration()77 EthernetConfiguration::EthernetConfiguration()
78 {
79     CreateDir(USER_CONFIG_DIR);
80 }
81 
ReadSystemConfiguration(std::map<std::string,std::set<NetCap>> & devCaps,std::map<std::string,sptr<InterfaceConfiguration>> & devCfgs)82 bool EthernetConfiguration::ReadSystemConfiguration(std::map<std::string, std::set<NetCap>> &devCaps,
83                                                     std::map<std::string, sptr<InterfaceConfiguration>> &devCfgs)
84 {
85     const auto &jsonStr = ReadJsonFile(NETWORK_CONFIG_PATH);
86     if (jsonStr.length() == 0) {
87         NETMGR_EXT_LOG_E("ReadConfigData config file is return empty!");
88         return false;
89     }
90     if (!nlohmann::json::accept(jsonStr)) {
91         NETMGR_EXT_LOG_E("Invalid JSON format!");
92         return false;
93     }
94     const auto &jsonCfg = nlohmann::json::parse(jsonStr);
95     if (jsonCfg.find(CONFIG_KEY_ETH_COMPONENT_FLAG) == jsonCfg.end()) {
96         NETMGR_EXT_LOG_E("ReadConfigData not find network_ethernet_component!");
97         return false;
98     }
99     const auto &arrIface = jsonCfg.at(CONFIG_KEY_ETH_COMPONENT_FLAG);
100     NETMGR_EXT_LOG_D("read ConfigData ethValue:%{public}s", arrIface.dump().c_str());
101     for (const auto &item : arrIface) {
102         bool isLan = item.contains(CONFIG_KEY_ETH_LANIFACE);
103         const auto &iface = isLan
104                            ? item[CONFIG_KEY_ETH_LANIFACE].get<std::string>()
105                            : item[CONFIG_KEY_ETH_IFACE].get<std::string>();
106         const auto &caps = item.at(CONFIG_KEY_ETH_CAPS).get<std::set<NetCap>>();
107         if (!caps.empty()) {
108             devCaps[iface] = caps;
109         }
110         const auto &fit = devCfgs.find(iface);
111         if (fit != devCfgs.end()) {
112             NETMGR_EXT_LOG_E("The iface=%{public}s device have set!", fit->first.c_str());
113             continue;
114         }
115         sptr<InterfaceConfiguration> config = ConvertJsonToConfiguration(item, isLan);
116         if (config == nullptr) {
117             NETMGR_EXT_LOG_E("config is nullptr");
118             return false;
119         }
120         std::regex re(IFACE_MATCH);
121         if (!item[CONFIG_KEY_ETH_IP].empty() && std::regex_search(iface, re)) {
122             devCfgs[iface] = config;
123         }
124     }
125     return true;
126 }
127 
ConvertJsonToConfiguration(const nlohmann::json & jsonData,bool isLan)128 sptr<InterfaceConfiguration> EthernetConfiguration::ConvertJsonToConfiguration(const nlohmann::json &jsonData,
129                                                                                bool isLan)
130 {
131     sptr<InterfaceConfiguration> config = new (std::nothrow) InterfaceConfiguration();
132     if (config == nullptr) {
133         NETMGR_EXT_LOG_E("config is nullptr");
134         return nullptr;
135     }
136 
137     if (isLan) {
138         config->mode_ = LAN_STATIC;
139     } else {
140         config->mode_ = STATIC;
141     }
142     StaticConfiguration::ExtractNetAddrBySeparator(jsonData[CONFIG_KEY_ETH_IP], config->ipStatic_.ipAddrList_);
143     StaticConfiguration::ExtractNetAddrBySeparator(jsonData[CONFIG_KEY_ETH_ROUTE], config->ipStatic_.routeList_);
144     StaticConfiguration::ExtractNetAddrBySeparator(jsonData[CONFIG_KEY_ETH_GATEWAY], config->ipStatic_.gatewayList_);
145     StaticConfiguration::ExtractNetAddrBySeparator(jsonData[CONFIG_KEY_ETH_NETMASK], config->ipStatic_.netMaskList_);
146     StaticConfiguration::ExtractNetAddrBySeparator(jsonData[CONFIG_KEY_ETH_DNS], config->ipStatic_.dnsServers_);
147 
148     ParserIfaceIpAndRoute(config, jsonData[CONFIG_KEY_ETH_ROUTE_MASK]);
149     return config;
150 }
151 
ReadUserConfiguration(std::map<std::string,sptr<InterfaceConfiguration>> & devCfgs)152 bool EthernetConfiguration::ReadUserConfiguration(std::map<std::string, sptr<InterfaceConfiguration>> &devCfgs)
153 {
154     DIR *dir = nullptr;
155     dirent *ptr = nullptr;
156     if ((dir = opendir(USER_CONFIG_DIR)) == nullptr) {
157         NETMGR_EXT_LOG_E("Read user configuration open dir error dir=[%{public}s]", USER_CONFIG_DIR);
158         return false;
159     }
160     std::string iface;
161     while ((ptr = readdir(dir)) != nullptr) {
162         if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
163             continue;
164         }
165         if (ptr->d_type == DT_REG) {
166             std::string filePath = std::string(USER_CONFIG_DIR) + FILE_OBLIQUE_LINE + ptr->d_name;
167             std::string fileContent;
168             if (!ReadFile(filePath, fileContent)) {
169                 continue;
170             }
171             std::string().swap(iface);
172             sptr<InterfaceConfiguration> cfg = new (std::nothrow) InterfaceConfiguration();
173             if (cfg == nullptr) {
174                 NETMGR_EXT_LOG_E("cfg new failed for devname[%{public}s]", iface.c_str());
175                 continue;
176             }
177             ParserFileConfig(fileContent, iface, cfg);
178             std::regex re(IFACE_MATCH);
179             if (!iface.empty() && std::regex_search(iface, re)) {
180                 NETMGR_EXT_LOG_D("ReadFileList devname[%{public}s]", iface.c_str());
181                 devCfgs[iface] = cfg;
182             }
183         }
184     }
185     closedir(dir);
186     return true;
187 }
188 
WriteUserConfiguration(const std::string & iface,sptr<InterfaceConfiguration> & cfg)189 bool EthernetConfiguration::WriteUserConfiguration(const std::string &iface, sptr<InterfaceConfiguration> &cfg)
190 {
191     if (cfg == nullptr) {
192         NETMGR_EXT_LOG_E("cfg is nullptr");
193         return false;
194     }
195     if (!CreateDir(USER_CONFIG_DIR)) {
196         NETMGR_EXT_LOG_E("create dir failed");
197         return false;
198     }
199 
200     if (cfg->mode_ == STATIC || cfg->mode_ == LAN_STATIC) {
201         ParserIfaceIpAndRoute(cfg, std::string());
202     }
203 
204     std::string fileContent;
205     GenCfgContent(iface, cfg, fileContent);
206 
207     std::string filePath = std::string(USER_CONFIG_DIR) + FILE_OBLIQUE_LINE + iface;
208     return WriteFile(filePath, fileContent);
209 }
210 
ClearAllUserConfiguration()211 bool EthernetConfiguration::ClearAllUserConfiguration()
212 {
213     return DelDir(USER_CONFIG_DIR);
214 }
215 
ConvertToConfiguration(const EthernetDhcpCallback::DhcpResult & dhcpResult,sptr<StaticConfiguration> & config)216 bool EthernetConfiguration::ConvertToConfiguration(const EthernetDhcpCallback::DhcpResult &dhcpResult,
217                                                    sptr<StaticConfiguration> &config)
218 {
219     if (config == nullptr) {
220         NETMGR_EXT_LOG_E("Error ConvertToIpConfiguration config is null");
221         return false;
222     }
223     if (!IsValidDhcpResult(dhcpResult, config)) {
224         return false;
225     }
226 
227     INetAddr ipAddr;
228     ipAddr.address_ = dhcpResult.ipAddr;
229     ipAddr.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(dhcpResult.ipAddr));
230     ipAddr.prefixlen_ = (ipAddr.family_ == AF_INET6)
231                             ? static_cast<uint8_t>(CommonUtils::Ipv6PrefixLen(dhcpResult.subNet))
232                             : static_cast<uint8_t>(CommonUtils::Ipv4PrefixLen(dhcpResult.subNet));
233     config->ipAddrList_.push_back(ipAddr);
234 
235     INetAddr netMask;
236     netMask.address_ = dhcpResult.subNet;
237     config->netMaskList_.push_back(netMask);
238 
239     INetAddr gateway;
240     gateway.address_ = dhcpResult.gateWay;
241     gateway.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(dhcpResult.gateWay));
242     config->gatewayList_.push_back(gateway);
243 
244     INetAddr route;
245     if (dhcpResult.gateWay != dhcpResult.route1 && dhcpResult.route1 != EMPTY_NET_ADDR) {
246         route.address_ = dhcpResult.route1;
247         route.prefixlen_ = ipAddr.prefixlen_;
248     } else if (dhcpResult.gateWay != dhcpResult.route2 && dhcpResult.route2 != EMPTY_NET_ADDR) {
249         route.address_ = dhcpResult.route2;
250         route.prefixlen_ = ipAddr.prefixlen_;
251     } else {
252         route.address_ = (ipAddr.family_ == AF_INET6) ? DEFAULT_IPV6_ADDR : DEFAULT_IPV4_ADDR;
253         route.prefixlen_ = 0;
254     }
255     route.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(route.address_));
256     config->routeList_.push_back(route);
257 
258     INetAddr dnsNet1;
259     dnsNet1.address_ = dhcpResult.dns1;
260     INetAddr dnsNet2;
261     dnsNet2.address_ = dhcpResult.dns2;
262     config->dnsServers_.push_back(dnsNet1);
263     config->dnsServers_.push_back(dnsNet2);
264     return true;
265 }
266 
GetGatewayFromMap(const std::unordered_map<std::string,INetAddr> & temp)267 std::vector<INetAddr> EthernetConfiguration::GetGatewayFromMap(const std::unordered_map<std::string, INetAddr> &temp)
268 {
269     std::vector<INetAddr> t;
270     for (auto [k, v] : temp) {
271         t.push_back(v);
272     }
273     return t;
274 }
275 
GetGatewayFromRouteList(std::list<Route> & routeList)276 std::vector<INetAddr> EthernetConfiguration::GetGatewayFromRouteList(std::list<Route> &routeList)
277 {
278     std::unordered_map<std::string, INetAddr> temp;
279     for (const auto &route : routeList) {
280         temp.emplace(route.gateway_.address_, route.gateway_);
281     }
282     auto temp2 = temp;
283     temp.erase(DEFAULT_IPV4_ADDR);
284     temp.erase(DEFAULT_IPV6_ADDR);
285     if (temp.size() > 0) {
286         return GetGatewayFromMap(temp);
287     }
288     return GetGatewayFromMap(temp2);
289 }
290 
MakeInterfaceConfiguration(const sptr<InterfaceConfiguration> & devCfg,const sptr<NetLinkInfo> & devLinkInfo)291 sptr<InterfaceConfiguration> EthernetConfiguration::MakeInterfaceConfiguration(
292     const sptr<InterfaceConfiguration> &devCfg, const sptr<NetLinkInfo> &devLinkInfo)
293 {
294     if (devCfg == nullptr || devLinkInfo == nullptr) {
295         NETMGR_EXT_LOG_E("param is nullptr");
296         return nullptr;
297     }
298     sptr<InterfaceConfiguration> cfg = new (std::nothrow) InterfaceConfiguration();
299     if (cfg == nullptr) {
300         NETMGR_EXT_LOG_E("cfg new failed");
301         return nullptr;
302     }
303     cfg->mode_ = devCfg->mode_;
304     for (const auto &ipAddr : devLinkInfo->netAddrList_) {
305         cfg->ipStatic_.ipAddrList_.push_back(ipAddr);
306         auto family = CommonUtils::GetAddrFamily(ipAddr.address_);
307         INetAddr netMask;
308         netMask.address_ =
309             ipAddr.netMask_.empty()
310                 ? (((family == AF_INET6) ? CommonUtils::GetIpv6Prefix(DEFAULT_IPV6_MAX_ADDRESS, ipAddr.prefixlen_)
311                                          : CommonUtils::GetMaskByLength(ipAddr.prefixlen_)))
312                 : ipAddr.netMask_;
313         cfg->ipStatic_.netMaskList_.push_back(netMask);
314     }
315     for (const auto &route : devLinkInfo->routeList_) {
316         cfg->ipStatic_.routeList_.push_back(route.destination_);
317     }
318     cfg->ipStatic_.gatewayList_ = GetGatewayFromRouteList(devLinkInfo->routeList_);
319 
320     cfg->ipStatic_.domain_ = devLinkInfo->domain_;
321     for (const auto &addr : devLinkInfo->dnsList_) {
322         cfg->ipStatic_.dnsServers_.push_back(addr);
323     }
324     return cfg;
325 }
326 
ReadJsonFile(const std::string & filePath)327 std::string EthernetConfiguration::ReadJsonFile(const std::string &filePath)
328 {
329     std::ifstream infile;
330     std::string strLine;
331     std::string strAll;
332     infile.open(filePath);
333     if (!infile.is_open()) {
334         NETMGR_EXT_LOG_E("ReadJsonFile filePath failed");
335         return strAll;
336     }
337     while (getline(infile, strLine)) {
338         strAll.append(strLine);
339     }
340     infile.close();
341     return strAll;
342 }
343 
IsDirExist(const std::string & dirPath)344 bool EthernetConfiguration::IsDirExist(const std::string &dirPath)
345 {
346     struct stat status;
347     if (dirPath.empty()) {
348         return false;
349     }
350     return (stat(dirPath.c_str(), &status) == 0);
351 }
352 
CreateDir(const std::string & dirPath)353 bool EthernetConfiguration::CreateDir(const std::string &dirPath)
354 {
355     if (IsDirExist(dirPath)) {
356         return true;
357     }
358     if (mkdir(dirPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == MKDIR_ERR) {
359         NETMGR_EXT_LOG_E("mkdir failed %{public}d: %{public}s", errno, strerror(errno));
360         return false;
361     }
362     return true;
363 }
364 
DelDir(const std::string & dirPath)365 bool EthernetConfiguration::DelDir(const std::string &dirPath)
366 {
367     DIR *dir = nullptr;
368     dirent *entry = nullptr;
369     struct stat statbuf;
370     if ((dir = opendir(dirPath.c_str())) == nullptr) {
371         NETMGR_EXT_LOG_E("EthernetConfiguration DelDir open user dir failed!");
372         return false;
373     }
374     while ((entry = readdir(dir)) != nullptr) {
375         std::string filePath = dirPath + FILE_OBLIQUE_LINE + entry->d_name;
376         lstat(filePath.c_str(), &statbuf);
377         if (S_ISREG(statbuf.st_mode)) {
378             remove(filePath.c_str());
379         }
380     }
381     closedir(dir);
382     sync();
383     return rmdir(dirPath.c_str()) >= 0;
384 }
385 
IsFileExist(const std::string & filePath,std::string & realPath)386 bool EthernetConfiguration::IsFileExist(const std::string &filePath, std::string &realPath)
387 {
388     char tmpPath[PATH_MAX] = {0};
389     if (!realpath(filePath.c_str(), tmpPath)) {
390         NETMGR_EXT_LOG_E("file name is error");
391         return false;
392     }
393     if (strncmp(tmpPath, USER_CONFIG_DIR, USER_PATH_LEN) != 0) {
394         NETMGR_EXT_LOG_E("file path is error");
395         return false;
396     }
397     realPath = tmpPath;
398     return true;
399 }
400 
ReadFile(const std::string & filePath,std::string & fileContent)401 bool EthernetConfiguration::ReadFile(const std::string &filePath, std::string &fileContent)
402 {
403     std::unique_lock<std::mutex> lock(mutex_);
404     if (filePath.empty()) {
405         NETMGR_EXT_LOG_E("filePath empty.");
406         return false;
407     }
408     std::string realPath;
409     if (!IsFileExist(filePath, realPath)) {
410         NETMGR_EXT_LOG_E("[%{public}s] not exist.", filePath.c_str());
411         return false;
412     }
413     std::fstream file(realPath.c_str(), std::fstream::in);
414     if (!file.is_open()) {
415         NETMGR_EXT_LOG_E("EthernetConfiguration read file failed.err %{public}d %{public}s", errno, strerror(errno));
416         return false;
417     }
418     std::stringstream buffer;
419     buffer << file.rdbuf();
420     fileContent = buffer.str();
421     file.close();
422     return true;
423 }
424 
WriteFile(const std::string & filePath,const std::string & fileContent)425 bool EthernetConfiguration::WriteFile(const std::string &filePath, const std::string &fileContent)
426 {
427     std::fstream file(filePath.c_str(), std::fstream::out | std::fstream::trunc);
428     if (!file.is_open()) {
429         NETMGR_EXT_LOG_E("EthernetConfiguration write file=%{public}s fstream failed. err %{public}d %{public}s",
430                          filePath.c_str(), errno, strerror(errno));
431         return false;
432     }
433     file << fileContent.c_str();
434     file.close();
435     sync();
436     return true;
437 }
438 
ParserFileConfig(const std::string & fileContent,std::string & iface,sptr<InterfaceConfiguration> cfg)439 void EthernetConfiguration::ParserFileConfig(const std::string &fileContent, std::string &iface,
440                                              sptr<InterfaceConfiguration> cfg)
441 {
442     ParseDevice(fileContent, iface);
443     ParseBootProto(fileContent, cfg);
444     ParseStaticConfig(fileContent, cfg);
445     ParserFileHttpProxy(fileContent, cfg);
446 }
447 
ParseDevice(const std::string & fileContent,std::string & iface)448 void EthernetConfiguration::ParseDevice(const std::string &fileContent, std::string &iface)
449 {
450     std::string::size_type pos = fileContent.find(KEY_DEVICE);
451     if (pos == std::string::npos) {
452         return;
453     }
454     pos += strlen(KEY_DEVICE);
455     const auto &device = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
456     iface = device;
457 }
458 
ParseBootProto(const std::string & fileContent,sptr<InterfaceConfiguration> cfg)459 void EthernetConfiguration::ParseBootProto(const std::string &fileContent, sptr<InterfaceConfiguration> cfg)
460 {
461     std::string::size_type pos = fileContent.find(KEY_BOOTPROTO);
462     if (pos == std::string::npos) {
463         return;
464     }
465     pos += strlen(KEY_BOOTPROTO);
466     const auto &bootProto = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
467     if (bootProto == KEY_LAN_STATIC) {
468         cfg->mode_ = LAN_STATIC;
469     } else if (bootProto == KEY_LAN_DHCP) {
470         cfg->mode_ = LAN_DHCP;
471     } else if (bootProto == KEY_STATIC) {
472         cfg->mode_ = STATIC;
473     } else {
474         cfg->mode_ = DHCP;
475     }
476 }
477 
ParseStaticConfig(const std::string & fileContent,sptr<InterfaceConfiguration> cfg)478 void EthernetConfiguration::ParseStaticConfig(const std::string &fileContent, sptr<InterfaceConfiguration> cfg)
479 {
480     if (cfg->mode_ != STATIC && cfg->mode_ != LAN_STATIC) {
481         return;
482     }
483     std::string ipAddresses, netMasks, gateways, routes, routeMasks, dnsServers;
484     auto pos = fileContent.find(KEY_IPADDR);
485     if (pos != std::string::npos) {
486         pos += strlen(KEY_IPADDR);
487         ipAddresses = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
488     }
489 
490     pos = fileContent.find(KEY_NETMASK);
491     if (pos != std::string::npos) {
492         pos += strlen(KEY_NETMASK);
493         netMasks = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
494     }
495 
496     pos = fileContent.find(KEY_GATEWAY);
497     if (pos != std::string::npos) {
498         pos += strlen(KEY_GATEWAY);
499         gateways = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
500     }
501 
502     pos = fileContent.find(KEY_ROUTE);
503     if (pos != std::string::npos) {
504         pos += strlen(KEY_ROUTE);
505         routes = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
506     }
507 
508     pos = fileContent.find(KEY_ROUTE_NETMASK);
509     if (pos != std::string::npos) {
510         pos += strlen(KEY_ROUTE_NETMASK);
511         routeMasks = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
512     }
513 
514     pos = fileContent.find(KEY_DNS);
515     if (pos != std::string::npos) {
516         pos += strlen(KEY_DNS);
517         dnsServers = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
518     }
519 
520     StaticConfiguration::ExtractNetAddrBySeparator(ipAddresses, cfg->ipStatic_.ipAddrList_);
521     StaticConfiguration::ExtractNetAddrBySeparator(routes, cfg->ipStatic_.routeList_);
522     StaticConfiguration::ExtractNetAddrBySeparator(gateways, cfg->ipStatic_.gatewayList_);
523     StaticConfiguration::ExtractNetAddrBySeparator(netMasks, cfg->ipStatic_.netMaskList_);
524     StaticConfiguration::ExtractNetAddrBySeparator(dnsServers, cfg->ipStatic_.dnsServers_);
525     ParserIfaceIpAndRoute(cfg, routeMasks);
526 }
527 
ParserFileHttpProxy(const std::string & fileContent,const sptr<InterfaceConfiguration> & cfg)528 void EthernetConfiguration::ParserFileHttpProxy(const std::string &fileContent, const sptr<InterfaceConfiguration> &cfg)
529 {
530     std::string::size_type pos = fileContent.find(KEY_PROXY_HOST);
531     if (pos != std::string::npos) {
532         pos += strlen(KEY_PROXY_HOST);
533         cfg->httpProxy_.SetHost(fileContent.substr(pos, fileContent.find(WRAP, pos) - pos));
534     }
535 
536     pos = fileContent.find(KEY_PROXY_PORT);
537     if (pos != std::string::npos) {
538         pos += strlen(KEY_PROXY_PORT);
539         uint32_t port = CommonUtils::StrToUint(fileContent.substr(pos, fileContent.find(WRAP, pos) - pos));
540         cfg->httpProxy_.SetPort(static_cast<uint16_t>(port));
541     }
542 
543     pos = fileContent.find(KEY_PROXY_EXCLUSIONS);
544     if (pos != std::string::npos) {
545         pos += strlen(KEY_PROXY_EXCLUSIONS);
546         auto exclusions = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
547         std::list<std::string> exclusionList;
548         for (const auto &exclusion : CommonUtils::Split(exclusions, EXCLUSIONS_DELIMITER)) {
549             exclusionList.push_back(exclusion);
550         }
551         cfg->httpProxy_.SetExclusionList(exclusionList);
552     }
553 }
554 
ParserIfaceIpAndRoute(sptr<InterfaceConfiguration> & cfg,const std::string & rootNetMask)555 void EthernetConfiguration::ParserIfaceIpAndRoute(sptr<InterfaceConfiguration> &cfg, const std::string &rootNetMask)
556 {
557     if (cfg == nullptr) {
558         NETMGR_EXT_LOG_E("cfg is nullptr");
559         return;
560     }
561 
562     std::for_each(cfg->ipStatic_.netMaskList_.begin(), cfg->ipStatic_.netMaskList_.end(), [&cfg](const auto &netMask) {
563         auto maskFamily = CommonUtils::GetAddrFamily(netMask.address_);
564         for (auto &ipAddr : cfg->ipStatic_.ipAddrList_) {
565             if (maskFamily != CommonUtils::GetAddrFamily(ipAddr.address_)) {
566                 continue;
567             }
568             ipAddr.netMask_ = netMask.address_;
569             ipAddr.prefixlen_ =
570 	    (maskFamily == AF_INET6) ? static_cast<uint32_t>(CommonUtils::Ipv6PrefixLen(netMask.address_))
571                                      : static_cast<uint32_t>(CommonUtils::Ipv4PrefixLen(netMask.address_));
572             break;
573         }
574     });
575 
576     for (const auto &routeMask : CommonUtils::Split(rootNetMask, ADDR_SEPARATOR)) {
577         auto maskFamily = CommonUtils::GetAddrFamily(routeMask);
578         for (auto &route : cfg->ipStatic_.routeList_) {
579             if (maskFamily != CommonUtils::GetAddrFamily(route.address_)) {
580                 continue;
581             }
582             route.prefixlen_ = (maskFamily == AF_INET6) ? static_cast<uint32_t>(CommonUtils::Ipv6PrefixLen(routeMask))
583                                                         : static_cast<uint32_t>(CommonUtils::Ipv4PrefixLen(routeMask));
584             break;
585         }
586     }
587 }
588 
GetIfaceMode(IPSetMode mode)589 std::string EthernetConfiguration::GetIfaceMode(IPSetMode mode)
590 {
591     switch (mode) {
592         case LAN_STATIC:
593             return KEY_LAN_STATIC;
594         case LAN_DHCP:
595             return KEY_LAN_DHCP;
596         case STATIC:
597             return KEY_STATIC;
598         default:
599             return KEY_DHCP;
600     }
601 }
602 
GenCfgContent(const std::string & iface,sptr<InterfaceConfiguration> cfg,std::string & fileContent)603 void EthernetConfiguration::GenCfgContent(const std::string &iface, sptr<InterfaceConfiguration> cfg,
604                                           std::string &fileContent)
605 {
606     if (cfg == nullptr) {
607         NETMGR_EXT_LOG_E("cfg is nullptr");
608         return;
609     }
610     std::string().swap(fileContent);
611     fileContent = fileContent + KEY_DEVICE + iface + WRAP;
612     std::string mode = GetIfaceMode(cfg->mode_);
613     fileContent = fileContent + KEY_BOOTPROTO + mode + WRAP;
614     if (cfg->mode_ == STATIC || cfg->mode_ == LAN_STATIC) {
615         std::string ipAddresses = AccumulateNetAddress(cfg->ipStatic_.ipAddrList_);
616         std::string netMasks = AccumulateNetAddress(cfg->ipStatic_.netMaskList_);
617         std::string gateways = AccumulateNetAddress(cfg->ipStatic_.gatewayList_);
618         std::string routes = AccumulateNetAddress(cfg->ipStatic_.routeList_);
619         std::string routeMasks =
620             std::accumulate(cfg->ipStatic_.routeList_.begin(), cfg->ipStatic_.routeList_.end(), std::string(),
621                             [](const std::string &routeMask, const INetAddr &iter) {
622                                 auto family = CommonUtils::GetAddrFamily(iter.address_);
623                                 std::string mask = (family == AF_INET6) ? DEFAULT_IPV6_ADDR : DEFAULT_IPV4_ADDR;
624                                 return routeMask.empty() ? routeMask + mask : (routeMask + ADDR_SEPARATOR + mask);
625                             });
626         std::string dnsServers = AccumulateNetAddress(cfg->ipStatic_.dnsServers_);
627 
628         fileContent = fileContent + KEY_IPADDR + ipAddresses + WRAP;
629         fileContent = fileContent + KEY_NETMASK + netMasks + WRAP;
630         fileContent = fileContent + KEY_GATEWAY + gateways + WRAP;
631         fileContent = fileContent + KEY_ROUTE + routes + WRAP;
632         fileContent = fileContent + KEY_ROUTE_NETMASK + routeMasks + WRAP;
633         fileContent = fileContent + KEY_DNS + dnsServers + WRAP;
634     }
635     GenHttpProxyContent(cfg, fileContent);
636 }
637 
GenHttpProxyContent(const sptr<InterfaceConfiguration> & cfg,std::string & fileContent)638 void EthernetConfiguration::GenHttpProxyContent(const sptr<InterfaceConfiguration> &cfg, std::string &fileContent)
639 {
640     const auto &exclusionList = cfg->httpProxy_.GetExclusionList();
641     std::string exclusions =
642         std::accumulate(exclusionList.begin(), exclusionList.end(), std::string(),
643                         [](const std::string &exclusion, const std::string &next) {
644                             return exclusion.empty() ? exclusion + next : (exclusion + EXCLUSIONS_DELIMITER + next);
645                         });
646 
647     fileContent = fileContent + KEY_PROXY_HOST + cfg->httpProxy_.GetHost() + WRAP;
648     fileContent = fileContent + KEY_PROXY_PORT + std::to_string(cfg->httpProxy_.GetPort()) + WRAP;
649     fileContent = fileContent + KEY_PROXY_EXCLUSIONS + exclusions + WRAP;
650 }
651 
AccumulateNetAddress(const std::vector<INetAddr> & netAddrList)652 std::string EthernetConfiguration::AccumulateNetAddress(const std::vector<INetAddr> &netAddrList)
653 {
654     return std::accumulate(netAddrList.begin(), netAddrList.end(), std::string(),
655                            [](const std::string &addr, const INetAddr &iter) {
656                                return addr.empty() ? (addr + iter.address_) : (addr + ADDR_SEPARATOR + iter.address_);
657                            });
658 }
659 
IsValidDhcpResult(const EthernetDhcpCallback::DhcpResult & dhcpResult,sptr<StaticConfiguration> & config)660 bool EthernetConfiguration::IsValidDhcpResult(const EthernetDhcpCallback::DhcpResult &dhcpResult,
661                                               sptr<StaticConfiguration> &config)
662 {
663     if (config == nullptr) {
664         NETMGR_EXT_LOG_E("config is nullptr");
665         return false;
666     }
667     if (dhcpResult.ipAddr.empty()) {
668         NETMGR_EXT_LOG_E("DhcpResult ip addr is empty");
669         return false;
670     }
671 
672     bool isSameIp = false;
673     bool isSameGateway = false;
674     if (std::any_of(config->ipAddrList_.begin(), config->ipAddrList_.end(), [&dhcpResult](const auto &ipAddr) {
675         return dhcpResult.ipAddr == ipAddr.address_;
676         })) {
677         NETMGR_EXT_LOG_I("Same ip addr:%{public}s", CommonUtils::ToAnonymousIp(dhcpResult.ipAddr).c_str());
678         isSameIp = true;
679     }
680 
681     if (std::any_of(config->gatewayList_.begin(), config->gatewayList_.end(), [&dhcpResult](const auto &gateway) {
682         return dhcpResult.gateWay == gateway.address_;
683         })) {
684         NETMGR_EXT_LOG_I("Same gateway:%{public}s", CommonUtils::ToAnonymousIp(dhcpResult.gateWay).c_str());
685         isSameGateway = true;
686     }
687     return !(isSameIp && isSameGateway);
688 }
689 } // namespace NetManagerStandard
690 } // namespace OHOS
691