• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 
16 #include "dhcp_result_store_manager.h"
17 #include "dhcp_common_utils.h"
18 #include "dhcp_errcode.h"
19 #include "dhcp_logger.h"
20 #include "securec.h"
21 
22 namespace OHOS {
23 namespace DHCP {
24 DEFINE_DHCPLOG_DHCP_LABEL("DhcpResultStoreManager");
25 constexpr int MAC_ADDR_SIZE = 17;
DhcpResultStoreManager()26 DhcpResultStoreManager::DhcpResultStoreManager()
27 {
28     DHCP_LOGI("DhcpResultStoreManager()");
29 }
30 
~DhcpResultStoreManager()31 DhcpResultStoreManager::~DhcpResultStoreManager()
32 {
33     DHCP_LOGI("~DhcpResultStoreManager()");
34 }
35 
GetInstance()36 DhcpResultStoreManager &DhcpResultStoreManager::GetInstance()
37 {
38     static DhcpResultStoreManager g_ipInstance;
39     return g_ipInstance;
40 }
41 
TrimString(std::string & str)42 static void TrimString(std::string &str)
43 {
44     int32_t i = 0;
45     int32_t j = static_cast<int32_t>(str.length()) - 1;
46     while (i < static_cast<int32_t>(str.length()) && (str[i] == ' ' || str[i] == '\n')) {
47         ++i;
48     }
49     while (j >= 0 && (str[j] == ' '|| str[j] == '\n')) {
50         --j;
51     }
52     str = ((i > j) ? "" : str.substr(i, j - i + 1));
53 }
54 
SetClassKeyValue(IpInfoCached & item,const std::string & key,const std::string & value)55 static int32_t SetClassKeyValue(IpInfoCached &item, const std::string &key, const std::string &value)
56 {
57     int32_t errorKeyValue = 0;
58     std::string valueTmp = value;
59     if (key == "bssid") {
60         item.bssid = value;
61     } else if (key == "ssid") {
62         item.ssid = value;
63     } else if (key == "absoluteLeasetime") {
64         item.absoluteLeasetime = static_cast<int64_t>(CheckDataLegal(valueTmp));
65     } else if (key == "strYiaddr") {
66         if (strcpy_s(item.ipResult.strYiaddr, sizeof(item.ipResult.strYiaddr), value.c_str()) != EOK) {
67             errorKeyValue++;
68         }
69     } else if (key == "strOptServerId") {
70         if (strcpy_s(item.ipResult.strOptServerId, sizeof(item.ipResult.strOptServerId), value.c_str()) != EOK) {
71             errorKeyValue++;
72         }
73     } else if (key == "strOptSubnet") {
74         if (strcpy_s(item.ipResult.strOptSubnet, sizeof(item.ipResult.strOptSubnet), value.c_str()) != EOK) {
75             errorKeyValue++;
76         }
77     } else if (key == "strOptDns1") {
78         if (strcpy_s(item.ipResult.strOptDns1, sizeof(item.ipResult.strOptDns1), value.c_str()) != EOK) {
79             errorKeyValue++;
80         }
81     } else if (key == "strOptDns2") {
82         if (strcpy_s(item.ipResult.strOptDns2, sizeof(item.ipResult.strOptDns2), value.c_str()) != EOK) {
83             errorKeyValue++;
84         }
85     } else if (key == "strOptRouter1") {
86         if (strcpy_s(item.ipResult.strOptRouter1, sizeof(item.ipResult.strOptRouter1), value.c_str()) != EOK) {
87             errorKeyValue++;
88         }
89     } else if (key == "strOptRouter2") {
90         if (strcpy_s(item.ipResult.strOptRouter2, sizeof(item.ipResult.strOptRouter2), value.c_str()) != EOK) {
91             errorKeyValue++;
92         }
93     } else if (key == "uOptLeasetime") {
94         item.ipResult.uOptLeasetime = static_cast<uint32_t>(CheckDataLegal(valueTmp));
95     } else {
96         errorKeyValue++;
97     }
98     return errorKeyValue;
99 }
100 
OutClassString(IpInfoCached & item)101 static std::string OutClassString(IpInfoCached &item)
102 {
103     std::string buffer = "";
104     buffer += "    <IpInfoCached>\n";
105     buffer += "    bssid=" + std::string(item.bssid) + "\n";
106     buffer += "    ssid=" + std::string(item.ssid) + "\n";
107     buffer += "    absoluteLeasetime=" + std::to_string(item.absoluteLeasetime) + "\n";
108     buffer += "    strYiaddr=" + std::string(item.ipResult.strYiaddr) + "\n";
109     buffer += "    strOptServerId=" + std::string(item.ipResult.strOptServerId) + "\n";
110     buffer += "    strOptSubnet=" + std::string(item.ipResult.strOptSubnet) + "\n";
111     buffer += "    strOptDns1=" + std::string(item.ipResult.strOptDns1) + "\n";
112     buffer += "    strOptDns2=" + std::string(item.ipResult.strOptDns2) + "\n";
113     buffer += "    strOptRouter1=" + std::string(item.ipResult.strOptRouter1) + "\n";
114     buffer += "    strOptRouter2=" + std::string(item.ipResult.strOptRouter2) + "\n";
115     buffer += "    uOptLeasetime=" + std::to_string(item.ipResult.uOptLeasetime) + "\n";
116     buffer += "    <IpInfoCached>\n";
117     return buffer;
118 }
119 
ClearClass(IpInfoCached & item)120 static void ClearClass(IpInfoCached &item)
121 {
122     item.bssid.clear();
123     item.absoluteLeasetime = 0;
124     item.ipResult.uOptLeasetime = 0;
125 }
126 
ReadNetworkSection(IpInfoCached & item,FILE * fp,char * line,size_t lineSize)127 static int32_t ReadNetworkSection(IpInfoCached &item, FILE *fp, char *line, size_t lineSize)
128 {
129     int32_t sectionError = 0;
130     while (fgets(line, lineSize, fp) != nullptr) {
131         std::string strLine = line;
132         TrimString(strLine);
133         if (strLine.empty()) {
134             continue;
135         }
136         if (strLine[0] == '<' && ((strLine.length() > 0) && (strLine[strLine.length() - 1] == '>'))) {
137             return sectionError;
138         }
139         std::string::size_type npos = strLine.find("=");
140         if (npos == std::string::npos) {
141             DHCP_LOGE("Invalid config line");
142             sectionError++;
143             continue;
144         }
145         std::string key = strLine.substr(0, npos);
146         std::string value = strLine.substr(npos + 1);
147         TrimString(key);
148         TrimString(value);
149         /* template function, needing specialization */
150         sectionError += SetClassKeyValue(item, key, value);
151     }
152     DHCP_LOGE("Section config not end correctly");
153     sectionError++;
154     return sectionError;
155 }
156 
ReadNetwork(IpInfoCached & item,FILE * fp,char * line,size_t lineSize)157 static int32_t ReadNetwork(IpInfoCached &item, FILE *fp, char *line, size_t lineSize)
158 {
159     int32_t networkError = 0;
160     while (fgets(line, lineSize, fp) != nullptr) {
161         std::string strLine = line;
162         TrimString(strLine);
163         if (strLine.empty()) {
164             continue;
165         }
166         if (strLine[0] == '<' && ((strLine.length() > 0) && (strLine[strLine.length() - 1] == '>'))) {
167             networkError += ReadNetworkSection(item, fp, line, lineSize);
168         } else if (strLine.compare("}") == 0) {
169             return networkError;
170         } else {
171             DHCP_LOGE("Invalid config line");
172             networkError++;
173         }
174     }
175     DHCP_LOGE("Network config not end correctly");
176     networkError++;
177     return networkError;
178 }
179 
180 
SaveIpInfoInLocalFile(const IpInfoCached ipResult)181 int32_t DhcpResultStoreManager::SaveIpInfoInLocalFile(const IpInfoCached ipResult)
182 {
183     std::unique_lock<std::mutex> lock(m_ipResultMutex);
184     for (auto it = m_allIpCached.begin(); it != m_allIpCached.end(); it++) {
185         if (ipResult.bssid == it->bssid) {
186             m_allIpCached.erase(it);
187             break;
188         }
189     }
190     m_allIpCached.push_back(ipResult);
191     return SaveConfig();
192 }
193 
RemoveCachedIp(const IpInfoCached & cacheInfo)194 int32_t DhcpResultStoreManager::RemoveCachedIp(const IpInfoCached &cacheInfo)
195 {
196     LoadAllIpCached(DHCP_CACHE_FILE);
197     DHCP_LOGE("RemoveCachedIp, m_allIpCached size is %{public}d", static_cast<int32_t>(m_allIpCached.size()));
198     if (cacheInfo.ssid.empty()) {
199         DHCP_LOGE("RemoveCachedIp, ssid is empty");
200         return DHCP_E_FAILED;
201     }
202     std::unique_lock<std::mutex> lock(m_ipResultMutex);
203     if (m_allIpCached.empty()) {
204         DHCP_LOGE("m_allIpCached is empty");
205         return DHCP_E_FAILED;
206     }
207     m_allIpCached.erase(std::remove_if(m_allIpCached.begin(), m_allIpCached.end(),
208         [cacheInfo](IpInfoCached x) { return x.ssid == cacheInfo.ssid; }), m_allIpCached.end());
209     return SaveConfig();
210 }
211 
AddCachedIp(const IpInfoCached & cacheInfo)212 int32_t DhcpResultStoreManager::AddCachedIp(const IpInfoCached &cacheInfo)
213 {
214     LoadAllIpCached(DHCP_CACHE_FILE);
215     DHCP_LOGE("AddCachedIp, m_allIpCached size is %{public}d", static_cast<int32_t>(m_allIpCached.size()));
216     std::unique_lock<std::mutex> lock(m_ipResultMutex);
217     if (m_allIpCached.empty()) {
218         DHCP_LOGE("m_allIpCached is empty");
219         return DHCP_E_FAILED;
220     }
221     if (cacheInfo.ssid.empty() || (cacheInfo.bssid.size() != MAC_ADDR_SIZE)) {
222         DHCP_LOGE("ssid or bssid is invalid");
223         return DHCP_E_FAILED;
224     }
225     for (auto it = m_allIpCached.begin(); it != m_allIpCached.end(); it++) {
226         if (cacheInfo.bssid == it->bssid) {
227             it->ssid = cacheInfo.ssid;
228             break;
229         }
230     }
231     return SaveConfig();
232 }
233 
GetCachedIp(const std::string targetBssid,IpInfoCached & outIpResult)234 int32_t DhcpResultStoreManager::GetCachedIp(const std::string targetBssid, IpInfoCached &outIpResult)
235 {
236     std::string fileName = DHCP_CACHE_FILE;
237     LoadAllIpCached(fileName);
238     std::unique_lock<std::mutex> lock(m_ipResultMutex);
239     for (auto it = m_allIpCached.begin(); it != m_allIpCached.end(); it++) {
240         if (targetBssid == it->bssid) {
241             outIpResult = static_cast<IpInfoCached>(*it);
242             return 0;
243         }
244     }
245     return -1;
246 }
247 
SetConfigFilePath(const std::string & fileName)248 void DhcpResultStoreManager::SetConfigFilePath(const std::string &fileName)
249 {
250     m_fileName = fileName;
251 }
252 
LoadAllIpCached(const std::string & fileName)253 int32_t DhcpResultStoreManager::LoadAllIpCached(const std::string &fileName)
254 {
255     std::unique_lock<std::mutex> lock(m_ipResultMutex);
256     SetConfigFilePath(fileName);
257     if (m_fileName.empty()) {
258         DHCP_LOGE("File name is empty.");
259         return -1;
260     }
261     char *realPaths = realpath(m_fileName.c_str(), nullptr);
262     if (realPaths == nullptr) {
263         DHCP_LOGE("realpath failed error");
264         return -1;
265     }
266     FILE *fp = fopen(realPaths, "r");
267     if (!fp) {
268         DHCP_LOGE("Loading config file: %{public}s, fopen() failed!", m_fileName.c_str());
269         free(realPaths);
270         return -1;
271     }
272     m_allIpCached.clear();
273     std::vector<IpInfoCached>().swap(m_allIpCached);
274     IpInfoCached item;
275     char line[1024];
276     int32_t configError;
277     while (fgets(line, sizeof(line), fp) != nullptr) {
278         std::string strLine = line;
279         TrimString(strLine);
280         if (strLine.empty()) {
281             continue;
282         }
283         if (strLine[0] == '[' && ((strLine.length() > 0) && (strLine[strLine.length() - 1] == '{'))) {
284             ClearClass(item); /* template function, needing specialization */
285             configError = ReadNetwork(item, fp, line, sizeof(line));
286             if (configError > 0) {
287                 DHCP_LOGE("Parse network failed.");
288                 continue;
289             }
290             m_allIpCached.push_back(item);
291         }
292     }
293 
294     (void)fclose(fp);
295     free(realPaths);
296     return 0;
297 }
298 
299 
SaveConfig()300 int32_t DhcpResultStoreManager::SaveConfig()
301 {
302     if (!IsValidPath(m_fileName)) {
303         DHCP_LOGE("invalid path:%{public}s", m_fileName.c_str());
304         return -1;
305     }
306 
307     FILE* fp = fopen(m_fileName.c_str(), "w");
308     if (!fp) {
309         DHCP_LOGE("Save config file: %{public}s, fopen() failed!", m_fileName.c_str());
310         return -1;
311     }
312     std::string content = "";
313     for (std::size_t i = 0; i < m_allIpCached.size(); ++i) {
314         IpInfoCached &item = m_allIpCached[i];
315         content += "[IpInfoCached_" + std::to_string(i + 1) + "] {\n";
316         content += OutClassString(item) + "\n";
317         content += "}\n";
318     }
319     uint32_t ret = fwrite(content.c_str(), 1, content.length(), fp);
320     if (ret != static_cast<uint32_t>(content.length())) {
321         DHCP_LOGE("Save config file: %{public}s, fwrite() failed!", m_fileName.c_str());
322     }
323     (void)fflush(fp);
324     (void)fsync(fileno(fp));
325     (void)fclose(fp);
326     m_allIpCached.clear(); /* clear values */
327     std::vector<IpInfoCached>().swap(m_allIpCached);
328     return 0;
329 }
330 
331 }  // namespace DHCP
332 }  // namespace OHOS