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 
ReadEthernetInterfaces(std::map<std::string,std::set<NetCap>> & devCaps,std::map<std::string,sptr<InterfaceConfiguration>> & devCfgs,const cJSON * const json)82 bool EthernetConfiguration::ReadEthernetInterfaces(std::map<std::string, std::set<NetCap>> &devCaps,
83                                                    std::map<std::string, sptr<InterfaceConfiguration>> &devCfgs,
84                                                    const cJSON* const json)
85 {
86     for (int32_t i = 0; i < cJSON_GetArraySize(json); i++) {
87         cJSON *item = cJSON_GetArrayItem(json, i);
88         if (item == nullptr) {
89             continue;
90         }
91         std::string iface;
92         bool isLan = false;
93         cJSON *lanIface = cJSON_GetObjectItem(item, CONFIG_KEY_ETH_LANIFACE.c_str());
94         if (lanIface == nullptr) {
95             cJSON *ethIface = cJSON_GetObjectItem(item, CONFIG_KEY_ETH_IFACE.c_str());
96             iface = cJSON_GetStringValue(ethIface);
97             isLan = false;
98         } else {
99             iface = cJSON_GetStringValue(lanIface);
100             isLan = true;
101         }
102         cJSON *capsObj = cJSON_GetObjectItem(item, CONFIG_KEY_ETH_CAPS.c_str());
103         std::set<NetCap> caps;
104         for (int32_t j = 0; j < cJSON_GetArraySize(capsObj); j++) {
105             cJSON *capsItem = cJSON_GetArrayItem(capsObj, j);
106             if (capsItem == nullptr) {
107                 continue;
108             }
109             const auto capsValue = capsItem->valueint;
110             NETMGR_EXT_LOG_D("ReadConfigData capsValue : %{public}d", capsValue);
111             caps.insert(NetCap(capsValue));
112         }
113         if (!caps.empty()) {
114             devCaps[iface] = caps;
115         }
116         const auto &fit = devCfgs.find(iface);
117         if (fit != devCfgs.end()) {
118             NETMGR_EXT_LOG_E("The iface=%{public}s device have set!", fit->first.c_str());
119             continue;
120         }
121         sptr<InterfaceConfiguration> config = ConvertJsonToConfiguration(item, isLan);
122         if (config == nullptr) {
123             NETMGR_EXT_LOG_E("config is nullptr");
124             return false;
125         }
126         std::regex re(IFACE_MATCH);
127         if (cJSON_GetObjectItem(item, CONFIG_KEY_ETH_IP.c_str()) && std::regex_search(iface, re)) {
128             devCfgs[iface] = config;
129         }
130     }
131     return true;
132 }
133 
ReadSystemConfiguration(std::map<std::string,std::set<NetCap>> & devCaps,std::map<std::string,sptr<InterfaceConfiguration>> & devCfgs)134 bool EthernetConfiguration::ReadSystemConfiguration(std::map<std::string, std::set<NetCap>> &devCaps,
135                                                     std::map<std::string, sptr<InterfaceConfiguration>> &devCfgs)
136 {
137     const auto &jsonStr = ReadJsonFile(NETWORK_CONFIG_PATH);
138     if (jsonStr.length() == 0) {
139         NETMGR_EXT_LOG_E("ReadConfigData config file is return empty!");
140         return false;
141     }
142     cJSON *json = cJSON_Parse(jsonStr.c_str());
143     if (json == nullptr) {
144         NETMGR_EXT_LOG_E("json parse failed!");
145         return false;
146     }
147     cJSON *jsonEth = cJSON_GetObjectItem(json, CONFIG_KEY_ETH_COMPONENT_FLAG.c_str());
148     if (jsonEth == nullptr) {
149         NETMGR_EXT_LOG_E("ReadConfigData not find config_ethernet_interfaces!");
150         cJSON_Delete(json);
151         return false;
152     }
153     ReadEthernetInterfaces(devCaps, devCfgs, jsonEth);
154     cJSON_Delete(json);
155     return true;
156 }
157 
ConvertJsonToConfiguration(const cJSON * const jsonData,bool isLan)158 sptr<InterfaceConfiguration> EthernetConfiguration::ConvertJsonToConfiguration(const cJSON* const jsonData, bool isLan)
159 {
160     sptr<InterfaceConfiguration> config = new (std::nothrow) InterfaceConfiguration();
161     if (config == nullptr) {
162         NETMGR_EXT_LOG_E("config is nullptr");
163         return nullptr;
164     }
165 
166     if (isLan) {
167         config->mode_ = LAN_STATIC;
168     } else {
169         config->mode_ = STATIC;
170     }
171     std::string ip = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_IP.c_str())->valuestring;
172     std::string route = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_ROUTE.c_str())->valuestring;
173     std::string gateway = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_GATEWAY.c_str())->valuestring;
174     std::string netmask = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_NETMASK.c_str())->valuestring;
175     std::string dns = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_DNS.c_str())->valuestring;
176     StaticConfiguration::ExtractNetAddrBySeparator(ip, config->ipStatic_.ipAddrList_);
177     StaticConfiguration::ExtractNetAddrBySeparator(route, config->ipStatic_.routeList_);
178     StaticConfiguration::ExtractNetAddrBySeparator(gateway, config->ipStatic_.gatewayList_);
179     StaticConfiguration::ExtractNetAddrBySeparator(netmask, config->ipStatic_.netMaskList_);
180     StaticConfiguration::ExtractNetAddrBySeparator(dns, config->ipStatic_.dnsServers_);
181     std::string routeMask = cJSON_GetObjectItem(jsonData, CONFIG_KEY_ETH_ROUTE_MASK.c_str())->valuestring;
182     ParserIfaceIpAndRoute(config, routeMask);
183     return config;
184 }
185 
ReadUserConfiguration(std::map<std::string,sptr<InterfaceConfiguration>> & devCfgs)186 bool EthernetConfiguration::ReadUserConfiguration(std::map<std::string, sptr<InterfaceConfiguration>> &devCfgs)
187 {
188     DIR *dir = nullptr;
189     dirent *ptr = nullptr;
190     if ((dir = opendir(USER_CONFIG_DIR)) == nullptr) {
191         NETMGR_EXT_LOG_E("Read user configuration open dir error dir=[%{public}s]", USER_CONFIG_DIR);
192         return false;
193     }
194     std::string iface;
195     while ((ptr = readdir(dir)) != nullptr) {
196         if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
197             continue;
198         }
199         if (ptr->d_type == DT_REG) {
200             std::string filePath = std::string(USER_CONFIG_DIR) + FILE_OBLIQUE_LINE + ptr->d_name;
201             std::string fileContent;
202             if (!ReadFile(filePath, fileContent)) {
203                 continue;
204             }
205             std::string().swap(iface);
206             sptr<InterfaceConfiguration> cfg = new (std::nothrow) InterfaceConfiguration();
207             if (cfg == nullptr) {
208                 NETMGR_EXT_LOG_E("cfg new failed for devname[%{public}s]", iface.c_str());
209                 continue;
210             }
211             ParserFileConfig(fileContent, iface, cfg);
212             std::regex re(IFACE_MATCH);
213             if (!iface.empty() && std::regex_search(iface, re)) {
214                 NETMGR_EXT_LOG_D("ReadFileList devname[%{public}s]", iface.c_str());
215                 devCfgs[iface] = cfg;
216             }
217         }
218     }
219     closedir(dir);
220     return true;
221 }
222 
WriteUserConfiguration(const std::string & iface,sptr<InterfaceConfiguration> & cfg)223 bool EthernetConfiguration::WriteUserConfiguration(const std::string &iface, sptr<InterfaceConfiguration> &cfg)
224 {
225     if (cfg == nullptr) {
226         NETMGR_EXT_LOG_E("cfg is nullptr");
227         return false;
228     }
229     if (!CreateDir(USER_CONFIG_DIR)) {
230         NETMGR_EXT_LOG_E("create dir failed");
231         return false;
232     }
233 
234     if (cfg->mode_ == STATIC || cfg->mode_ == LAN_STATIC) {
235         ParserIfaceIpAndRoute(cfg, std::string());
236     }
237 
238     std::string fileContent;
239     GenCfgContent(iface, cfg, fileContent);
240 
241     std::string filePath = std::string(USER_CONFIG_DIR) + FILE_OBLIQUE_LINE + iface;
242     return WriteFile(filePath, fileContent);
243 }
244 
ClearAllUserConfiguration()245 bool EthernetConfiguration::ClearAllUserConfiguration()
246 {
247     return DelDir(USER_CONFIG_DIR);
248 }
249 
ConvertToConfiguration(const EthernetDhcpCallback::DhcpResult & dhcpResult,sptr<StaticConfiguration> & config)250 bool EthernetConfiguration::ConvertToConfiguration(const EthernetDhcpCallback::DhcpResult &dhcpResult,
251                                                    sptr<StaticConfiguration> &config)
252 {
253     if (config == nullptr) {
254         NETMGR_EXT_LOG_E("Error ConvertToIpConfiguration config is null");
255         return false;
256     }
257     if (!IsValidDhcpResult(dhcpResult, config)) {
258         return false;
259     }
260 
261     INetAddr ipAddr;
262     ipAddr.address_ = dhcpResult.ipAddr;
263     ipAddr.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(dhcpResult.ipAddr));
264     ipAddr.prefixlen_ = (ipAddr.family_ == AF_INET6)
265                             ? static_cast<uint8_t>(CommonUtils::Ipv6PrefixLen(dhcpResult.subNet))
266                             : static_cast<uint8_t>(CommonUtils::Ipv4PrefixLen(dhcpResult.subNet));
267     config->ipAddrList_.push_back(ipAddr);
268 
269     INetAddr netMask;
270     netMask.address_ = dhcpResult.subNet;
271     config->netMaskList_.push_back(netMask);
272 
273     INetAddr gateway;
274     gateway.address_ = dhcpResult.gateWay;
275     gateway.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(dhcpResult.gateWay));
276     config->gatewayList_.push_back(gateway);
277 
278     INetAddr route;
279     if (dhcpResult.gateWay != dhcpResult.route1 && dhcpResult.route1 != EMPTY_NET_ADDR) {
280         route.address_ = dhcpResult.route1;
281         route.prefixlen_ = ipAddr.prefixlen_;
282     } else if (dhcpResult.gateWay != dhcpResult.route2 && dhcpResult.route2 != EMPTY_NET_ADDR) {
283         route.address_ = dhcpResult.route2;
284         route.prefixlen_ = ipAddr.prefixlen_;
285     } else {
286         route.address_ = (ipAddr.family_ == AF_INET6) ? DEFAULT_IPV6_ADDR : DEFAULT_IPV4_ADDR;
287         route.prefixlen_ = 0;
288     }
289     route.family_ = static_cast<uint8_t>(CommonUtils::GetAddrFamily(route.address_));
290     config->routeList_.push_back(route);
291 
292     INetAddr dnsNet1;
293     dnsNet1.address_ = dhcpResult.dns1;
294     INetAddr dnsNet2;
295     dnsNet2.address_ = dhcpResult.dns2;
296     config->dnsServers_.push_back(dnsNet1);
297     config->dnsServers_.push_back(dnsNet2);
298     return true;
299 }
300 
GetGatewayFromMap(const std::unordered_map<std::string,INetAddr> & temp)301 std::vector<INetAddr> EthernetConfiguration::GetGatewayFromMap(const std::unordered_map<std::string, INetAddr> &temp)
302 {
303     std::vector<INetAddr> t;
304     for (auto [k, v] : temp) {
305         t.push_back(v);
306     }
307     return t;
308 }
309 
GetGatewayFromRouteList(std::list<Route> & routeList)310 std::vector<INetAddr> EthernetConfiguration::GetGatewayFromRouteList(std::list<Route> &routeList)
311 {
312     std::unordered_map<std::string, INetAddr> temp;
313     for (const auto &route : routeList) {
314         temp.emplace(route.gateway_.address_, route.gateway_);
315     }
316     auto temp2 = temp;
317     temp.erase(DEFAULT_IPV4_ADDR);
318     temp.erase(DEFAULT_IPV6_ADDR);
319     if (temp.size() > 0) {
320         return GetGatewayFromMap(temp);
321     }
322     return GetGatewayFromMap(temp2);
323 }
324 
MakeInterfaceConfiguration(const sptr<InterfaceConfiguration> & devCfg,const sptr<NetLinkInfo> & devLinkInfo)325 sptr<InterfaceConfiguration> EthernetConfiguration::MakeInterfaceConfiguration(
326     const sptr<InterfaceConfiguration> &devCfg, const sptr<NetLinkInfo> &devLinkInfo)
327 {
328     if (devCfg == nullptr || devLinkInfo == nullptr) {
329         NETMGR_EXT_LOG_E("param is nullptr");
330         return nullptr;
331     }
332     sptr<InterfaceConfiguration> cfg = new (std::nothrow) InterfaceConfiguration();
333     if (cfg == nullptr) {
334         NETMGR_EXT_LOG_E("cfg new failed");
335         return nullptr;
336     }
337     cfg->mode_ = devCfg->mode_;
338     for (const auto &ipAddr : devLinkInfo->netAddrList_) {
339         cfg->ipStatic_.ipAddrList_.push_back(ipAddr);
340         auto family = CommonUtils::GetAddrFamily(ipAddr.address_);
341         INetAddr netMask;
342         netMask.address_ =
343             ipAddr.netMask_.empty()
344                 ? (((family == AF_INET6) ? CommonUtils::GetIpv6Prefix(DEFAULT_IPV6_MAX_ADDRESS, ipAddr.prefixlen_)
345                                          : CommonUtils::GetMaskByLength(ipAddr.prefixlen_)))
346                 : ipAddr.netMask_;
347         cfg->ipStatic_.netMaskList_.push_back(netMask);
348     }
349     for (const auto &route : devLinkInfo->routeList_) {
350         cfg->ipStatic_.routeList_.push_back(route.destination_);
351     }
352     cfg->ipStatic_.gatewayList_ = GetGatewayFromRouteList(devLinkInfo->routeList_);
353 
354     cfg->ipStatic_.domain_ = devLinkInfo->domain_;
355     for (const auto &addr : devLinkInfo->dnsList_) {
356         cfg->ipStatic_.dnsServers_.push_back(addr);
357     }
358     return cfg;
359 }
360 
ReadJsonFile(const std::string & filePath)361 std::string EthernetConfiguration::ReadJsonFile(const std::string &filePath)
362 {
363     std::ifstream infile;
364     std::string strLine;
365     std::string strAll;
366     infile.open(filePath);
367     if (!infile.is_open()) {
368         NETMGR_EXT_LOG_E("ReadJsonFile filePath failed");
369         return strAll;
370     }
371     while (getline(infile, strLine)) {
372         strAll.append(strLine);
373     }
374     infile.close();
375     return strAll;
376 }
377 
IsDirExist(const std::string & dirPath)378 bool EthernetConfiguration::IsDirExist(const std::string &dirPath)
379 {
380     struct stat status;
381     if (dirPath.empty()) {
382         return false;
383     }
384     return (stat(dirPath.c_str(), &status) == 0);
385 }
386 
CreateDir(const std::string & dirPath)387 bool EthernetConfiguration::CreateDir(const std::string &dirPath)
388 {
389     if (IsDirExist(dirPath)) {
390         return true;
391     }
392     if (mkdir(dirPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == MKDIR_ERR) {
393         NETMGR_EXT_LOG_E("mkdir failed %{public}d: %{public}s", errno, strerror(errno));
394         return false;
395     }
396     return true;
397 }
398 
DelDir(const std::string & dirPath)399 bool EthernetConfiguration::DelDir(const std::string &dirPath)
400 {
401     DIR *dir = nullptr;
402     dirent *entry = nullptr;
403     struct stat statbuf;
404     if ((dir = opendir(dirPath.c_str())) == nullptr) {
405         NETMGR_EXT_LOG_E("EthernetConfiguration DelDir open user dir failed!");
406         return false;
407     }
408     while ((entry = readdir(dir)) != nullptr) {
409         std::string filePath = dirPath + FILE_OBLIQUE_LINE + entry->d_name;
410         lstat(filePath.c_str(), &statbuf);
411         if (S_ISREG(statbuf.st_mode)) {
412             remove(filePath.c_str());
413         }
414     }
415     closedir(dir);
416     sync();
417     return rmdir(dirPath.c_str()) >= 0;
418 }
419 
IsFileExist(const std::string & filePath,std::string & realPath)420 bool EthernetConfiguration::IsFileExist(const std::string &filePath, std::string &realPath)
421 {
422     char tmpPath[PATH_MAX] = {0};
423     if (!realpath(filePath.c_str(), tmpPath)) {
424         NETMGR_EXT_LOG_E("file name is error");
425         return false;
426     }
427     if (strncmp(tmpPath, USER_CONFIG_DIR, USER_PATH_LEN) != 0) {
428         NETMGR_EXT_LOG_E("file path is error");
429         return false;
430     }
431     realPath = tmpPath;
432     return true;
433 }
434 
ReadFile(const std::string & filePath,std::string & fileContent)435 bool EthernetConfiguration::ReadFile(const std::string &filePath, std::string &fileContent)
436 {
437     std::unique_lock<std::mutex> lock(mutex_);
438     if (filePath.empty()) {
439         NETMGR_EXT_LOG_E("filePath empty.");
440         return false;
441     }
442     std::string realPath;
443     if (!IsFileExist(filePath, realPath)) {
444         NETMGR_EXT_LOG_E("[%{public}s] not exist.", filePath.c_str());
445         return false;
446     }
447     std::fstream file(realPath.c_str(), std::fstream::in);
448     if (!file.is_open()) {
449         NETMGR_EXT_LOG_E("EthernetConfiguration read file failed.err %{public}d %{public}s", errno, strerror(errno));
450         return false;
451     }
452     std::stringstream buffer;
453     buffer << file.rdbuf();
454     fileContent = buffer.str();
455     file.close();
456     return true;
457 }
458 
WriteFile(const std::string & filePath,const std::string & fileContent)459 bool EthernetConfiguration::WriteFile(const std::string &filePath, const std::string &fileContent)
460 {
461     std::fstream file(filePath.c_str(), std::fstream::out | std::fstream::trunc);
462     if (!file.is_open()) {
463         NETMGR_EXT_LOG_E("EthernetConfiguration write file=%{public}s fstream failed. err %{public}d %{public}s",
464                          filePath.c_str(), errno, strerror(errno));
465         return false;
466     }
467     file << fileContent.c_str();
468     file.close();
469     sync();
470     return true;
471 }
472 
ParserFileConfig(const std::string & fileContent,std::string & iface,sptr<InterfaceConfiguration> cfg)473 void EthernetConfiguration::ParserFileConfig(const std::string &fileContent, std::string &iface,
474                                              sptr<InterfaceConfiguration> cfg)
475 {
476     ParseDevice(fileContent, iface);
477     ParseBootProto(fileContent, cfg);
478     ParseStaticConfig(fileContent, cfg);
479     ParserFileHttpProxy(fileContent, cfg);
480 }
481 
ParseDevice(const std::string & fileContent,std::string & iface)482 void EthernetConfiguration::ParseDevice(const std::string &fileContent, std::string &iface)
483 {
484     std::string::size_type pos = fileContent.find(KEY_DEVICE);
485     if (pos == std::string::npos) {
486         return;
487     }
488     pos += strlen(KEY_DEVICE);
489     const auto &device = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
490     iface = device;
491 }
492 
ParseBootProto(const std::string & fileContent,sptr<InterfaceConfiguration> cfg)493 void EthernetConfiguration::ParseBootProto(const std::string &fileContent, sptr<InterfaceConfiguration> cfg)
494 {
495     std::string::size_type pos = fileContent.find(KEY_BOOTPROTO);
496     if (pos == std::string::npos) {
497         return;
498     }
499     pos += strlen(KEY_BOOTPROTO);
500     const auto &bootProto = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
501     if (bootProto == KEY_LAN_STATIC) {
502         cfg->mode_ = LAN_STATIC;
503     } else if (bootProto == KEY_LAN_DHCP) {
504         cfg->mode_ = LAN_DHCP;
505     } else if (bootProto == KEY_STATIC) {
506         cfg->mode_ = STATIC;
507     } else {
508         cfg->mode_ = DHCP;
509     }
510 }
511 
ParseStaticConfig(const std::string & fileContent,sptr<InterfaceConfiguration> cfg)512 void EthernetConfiguration::ParseStaticConfig(const std::string &fileContent, sptr<InterfaceConfiguration> cfg)
513 {
514     if (cfg->mode_ != STATIC && cfg->mode_ != LAN_STATIC) {
515         return;
516     }
517     std::string ipAddresses, netMasks, gateways, routes, routeMasks, dnsServers;
518     auto pos = fileContent.find(KEY_IPADDR);
519     if (pos != std::string::npos) {
520         pos += strlen(KEY_IPADDR);
521         ipAddresses = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
522     }
523 
524     pos = fileContent.find(KEY_NETMASK);
525     if (pos != std::string::npos) {
526         pos += strlen(KEY_NETMASK);
527         netMasks = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
528     }
529 
530     pos = fileContent.find(KEY_GATEWAY);
531     if (pos != std::string::npos) {
532         pos += strlen(KEY_GATEWAY);
533         gateways = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
534     }
535 
536     pos = fileContent.find(KEY_ROUTE);
537     if (pos != std::string::npos) {
538         pos += strlen(KEY_ROUTE);
539         routes = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
540     }
541 
542     pos = fileContent.find(KEY_ROUTE_NETMASK);
543     if (pos != std::string::npos) {
544         pos += strlen(KEY_ROUTE_NETMASK);
545         routeMasks = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
546     }
547 
548     pos = fileContent.find(KEY_DNS);
549     if (pos != std::string::npos) {
550         pos += strlen(KEY_DNS);
551         dnsServers = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
552     }
553 
554     StaticConfiguration::ExtractNetAddrBySeparator(ipAddresses, cfg->ipStatic_.ipAddrList_);
555     StaticConfiguration::ExtractNetAddrBySeparator(routes, cfg->ipStatic_.routeList_);
556     StaticConfiguration::ExtractNetAddrBySeparator(gateways, cfg->ipStatic_.gatewayList_);
557     StaticConfiguration::ExtractNetAddrBySeparator(netMasks, cfg->ipStatic_.netMaskList_);
558     StaticConfiguration::ExtractNetAddrBySeparator(dnsServers, cfg->ipStatic_.dnsServers_);
559     ParserIfaceIpAndRoute(cfg, routeMasks);
560 }
561 
ParserFileHttpProxy(const std::string & fileContent,const sptr<InterfaceConfiguration> & cfg)562 void EthernetConfiguration::ParserFileHttpProxy(const std::string &fileContent, const sptr<InterfaceConfiguration> &cfg)
563 {
564     std::string::size_type pos = fileContent.find(KEY_PROXY_HOST);
565     if (pos != std::string::npos) {
566         pos += strlen(KEY_PROXY_HOST);
567         cfg->httpProxy_.SetHost(fileContent.substr(pos, fileContent.find(WRAP, pos) - pos));
568     }
569 
570     pos = fileContent.find(KEY_PROXY_PORT);
571     if (pos != std::string::npos) {
572         pos += strlen(KEY_PROXY_PORT);
573         uint32_t port = CommonUtils::StrToUint(fileContent.substr(pos, fileContent.find(WRAP, pos) - pos));
574         cfg->httpProxy_.SetPort(static_cast<uint16_t>(port));
575     }
576 
577     pos = fileContent.find(KEY_PROXY_EXCLUSIONS);
578     if (pos != std::string::npos) {
579         pos += strlen(KEY_PROXY_EXCLUSIONS);
580         auto exclusions = fileContent.substr(pos, fileContent.find(WRAP, pos) - pos);
581         std::list<std::string> exclusionList;
582         for (const auto &exclusion : CommonUtils::Split(exclusions, EXCLUSIONS_DELIMITER)) {
583             exclusionList.push_back(exclusion);
584         }
585         cfg->httpProxy_.SetExclusionList(exclusionList);
586     }
587 }
588 
ParserIfaceIpAndRoute(sptr<InterfaceConfiguration> & cfg,const std::string & rootNetMask)589 void EthernetConfiguration::ParserIfaceIpAndRoute(sptr<InterfaceConfiguration> &cfg, const std::string &rootNetMask)
590 {
591     if (cfg == nullptr) {
592         NETMGR_EXT_LOG_E("cfg is nullptr");
593         return;
594     }
595 
596     std::for_each(cfg->ipStatic_.netMaskList_.begin(), cfg->ipStatic_.netMaskList_.end(), [&cfg](const auto &netMask) {
597         auto maskFamily = CommonUtils::GetAddrFamily(netMask.address_);
598         for (auto &ipAddr : cfg->ipStatic_.ipAddrList_) {
599             if (maskFamily != CommonUtils::GetAddrFamily(ipAddr.address_)) {
600                 continue;
601             }
602             ipAddr.netMask_ = netMask.address_;
603             ipAddr.prefixlen_ =
604 	    (maskFamily == AF_INET6) ? static_cast<uint32_t>(CommonUtils::Ipv6PrefixLen(netMask.address_))
605                                      : static_cast<uint32_t>(CommonUtils::Ipv4PrefixLen(netMask.address_));
606             break;
607         }
608     });
609 
610     for (const auto &routeMask : CommonUtils::Split(rootNetMask, ADDR_SEPARATOR)) {
611         auto maskFamily = CommonUtils::GetAddrFamily(routeMask);
612         for (auto &route : cfg->ipStatic_.routeList_) {
613             if (maskFamily != CommonUtils::GetAddrFamily(route.address_)) {
614                 continue;
615             }
616             route.prefixlen_ = (maskFamily == AF_INET6) ? static_cast<uint32_t>(CommonUtils::Ipv6PrefixLen(routeMask))
617                                                         : static_cast<uint32_t>(CommonUtils::Ipv4PrefixLen(routeMask));
618             break;
619         }
620     }
621 }
622 
GetIfaceMode(IPSetMode mode)623 std::string EthernetConfiguration::GetIfaceMode(IPSetMode mode)
624 {
625     switch (mode) {
626         case LAN_STATIC:
627             return KEY_LAN_STATIC;
628         case LAN_DHCP:
629             return KEY_LAN_DHCP;
630         case STATIC:
631             return KEY_STATIC;
632         default:
633             return KEY_DHCP;
634     }
635 }
636 
GenCfgContent(const std::string & iface,sptr<InterfaceConfiguration> cfg,std::string & fileContent)637 void EthernetConfiguration::GenCfgContent(const std::string &iface, sptr<InterfaceConfiguration> cfg,
638                                           std::string &fileContent)
639 {
640     if (cfg == nullptr) {
641         NETMGR_EXT_LOG_E("cfg is nullptr");
642         return;
643     }
644     std::string().swap(fileContent);
645     fileContent = fileContent + KEY_DEVICE + iface + WRAP;
646     std::string mode = GetIfaceMode(cfg->mode_);
647     fileContent = fileContent + KEY_BOOTPROTO + mode + WRAP;
648     if (cfg->mode_ == STATIC || cfg->mode_ == LAN_STATIC) {
649         std::string ipAddresses = AccumulateNetAddress(cfg->ipStatic_.ipAddrList_);
650         std::string netMasks = AccumulateNetAddress(cfg->ipStatic_.netMaskList_);
651         std::string gateways = AccumulateNetAddress(cfg->ipStatic_.gatewayList_);
652         std::string routes = AccumulateNetAddress(cfg->ipStatic_.routeList_);
653         std::string routeMasks =
654             std::accumulate(cfg->ipStatic_.routeList_.begin(), cfg->ipStatic_.routeList_.end(), std::string(),
655                             [](const std::string &routeMask, const INetAddr &iter) {
656                                 auto family = CommonUtils::GetAddrFamily(iter.address_);
657                                 std::string mask = (family == AF_INET6) ? DEFAULT_IPV6_ADDR : DEFAULT_IPV4_ADDR;
658                                 return routeMask.empty() ? routeMask + mask : (routeMask + ADDR_SEPARATOR + mask);
659                             });
660         std::string dnsServers = AccumulateNetAddress(cfg->ipStatic_.dnsServers_);
661 
662         fileContent = fileContent + KEY_IPADDR + ipAddresses + WRAP;
663         fileContent = fileContent + KEY_NETMASK + netMasks + WRAP;
664         fileContent = fileContent + KEY_GATEWAY + gateways + WRAP;
665         fileContent = fileContent + KEY_ROUTE + routes + WRAP;
666         fileContent = fileContent + KEY_ROUTE_NETMASK + routeMasks + WRAP;
667         fileContent = fileContent + KEY_DNS + dnsServers + WRAP;
668     }
669     GenHttpProxyContent(cfg, fileContent);
670 }
671 
GenHttpProxyContent(const sptr<InterfaceConfiguration> & cfg,std::string & fileContent)672 void EthernetConfiguration::GenHttpProxyContent(const sptr<InterfaceConfiguration> &cfg, std::string &fileContent)
673 {
674     const auto &exclusionList = cfg->httpProxy_.GetExclusionList();
675     std::string exclusions =
676         std::accumulate(exclusionList.begin(), exclusionList.end(), std::string(),
677                         [](const std::string &exclusion, const std::string &next) {
678                             return exclusion.empty() ? exclusion + next : (exclusion + EXCLUSIONS_DELIMITER + next);
679                         });
680 
681     fileContent = fileContent + KEY_PROXY_HOST + cfg->httpProxy_.GetHost() + WRAP;
682     fileContent = fileContent + KEY_PROXY_PORT + std::to_string(cfg->httpProxy_.GetPort()) + WRAP;
683     fileContent = fileContent + KEY_PROXY_EXCLUSIONS + exclusions + WRAP;
684 }
685 
AccumulateNetAddress(const std::vector<INetAddr> & netAddrList)686 std::string EthernetConfiguration::AccumulateNetAddress(const std::vector<INetAddr> &netAddrList)
687 {
688     return std::accumulate(netAddrList.begin(), netAddrList.end(), std::string(),
689                            [](const std::string &addr, const INetAddr &iter) {
690                                return addr.empty() ? (addr + iter.address_) : (addr + ADDR_SEPARATOR + iter.address_);
691                            });
692 }
693 
IsValidDhcpResult(const EthernetDhcpCallback::DhcpResult & dhcpResult,sptr<StaticConfiguration> & config)694 bool EthernetConfiguration::IsValidDhcpResult(const EthernetDhcpCallback::DhcpResult &dhcpResult,
695                                               sptr<StaticConfiguration> &config)
696 {
697     if (config == nullptr) {
698         NETMGR_EXT_LOG_E("config is nullptr");
699         return false;
700     }
701     if (dhcpResult.ipAddr.empty()) {
702         NETMGR_EXT_LOG_E("DhcpResult ip addr is empty");
703         return false;
704     }
705 
706     bool isSameIp = false;
707     bool isSameGateway = false;
708     if (std::any_of(config->ipAddrList_.begin(), config->ipAddrList_.end(), [&dhcpResult](const auto &ipAddr) {
709         return dhcpResult.ipAddr == ipAddr.address_;
710         })) {
711         NETMGR_EXT_LOG_I("Same ip addr:%{public}s", CommonUtils::ToAnonymousIp(dhcpResult.ipAddr).c_str());
712         isSameIp = true;
713     }
714 
715     if (std::any_of(config->gatewayList_.begin(), config->gatewayList_.end(), [&dhcpResult](const auto &gateway) {
716         return dhcpResult.gateWay == gateway.address_;
717         })) {
718         NETMGR_EXT_LOG_I("Same gateway:%{public}s", CommonUtils::ToAnonymousIp(dhcpResult.gateWay).c_str());
719         isSameGateway = true;
720     }
721     return !(isSameIp && isSameGateway);
722 }
723 } // namespace NetManagerStandard
724 } // namespace OHOS
725