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 #include <cstdio>
16 #include <cstring>
17 #include <iostream>
18 #include <sstream>
19 #include <string>
20 #include "errorcode_convertor.h"
21 #include "iptables_wrapper.h"
22 #include "netmanager_base_common_utils.h"
23 #include "netnative_log_wrapper.h"
24 #include "net_manager_constants.h"
25 #include "wearable_distributed_net_manager.h"
26
27 namespace OHOS {
28 namespace nmd {
29 using namespace NetManagerStandard;
30 const int32_t MAX_CMD_LENGTH = 256;
31 const int32_t MAX_PORT_ID = 65535;
32
33 const std::string TCP_IPTABLES = "tcpiptables";
34 const std::string TCP_OUTPUT = "tcpoutput";
35 const std::string UDP_IPTABLES = "udpiptables";
36 const std::string UDP_OUTPUT = "udpoutput";
37 const std::string IPTABLES_DELETE_CMDS = "iptablesdeletecmds";
38
GetTcpIptables()39 std::vector<std::string> WearableDistributedNet::GetTcpIptables()
40 {
41 return tcpIptables_;
42 }
43
GetOutputAddTcp()44 std::string WearableDistributedNet::GetOutputAddTcp()
45 {
46 return tcpOutput_;
47 }
48
GetUdpIptables()49 std::vector<std::string> WearableDistributedNet::GetUdpIptables()
50 {
51 return udpIptables_;
52 }
53
GetUdpoutput()54 std::string WearableDistributedNet::GetUdpoutput()
55 {
56 return udpOutput_;
57 }
58
GetIptablesDeleteCmds()59 std::vector<std::string> WearableDistributedNet::GetIptablesDeleteCmds()
60 {
61 return iptablesDeleteCmds_;
62 }
63
ReadSystemIptablesConfiguration()64 bool WearableDistributedNet::ReadSystemIptablesConfiguration()
65 {
66 const auto &jsonStr = ReadJsonFile();
67 if (jsonStr.length() == 0) {
68 NETNATIVE_LOGE("ReadConfigData config file is return empty");
69 return false;
70 }
71 cJSON *json = cJSON_Parse(jsonStr.c_str());
72 if (json == nullptr) {
73 NETNATIVE_LOGE("Json parse failed");
74 return false;
75 }
76 bool result = ReadIptablesInterfaces(*json);
77 if (result == false) {
78 NETNATIVE_LOGE("Failed to read iptables interfaces");
79 cJSON_Delete(json);
80 return false;
81 }
82 cJSON_Delete(json);
83 return true;
84 }
85
ReadJsonFile()86 std::string WearableDistributedNet::ReadJsonFile()
87 {
88 std::ifstream infile;
89 std::string lineConfigInfo;
90 std::string allConfigInfo;
91 if (configPath_.empty()) {
92 NETNATIVE_LOGE("Config file path is empty");
93 return "";
94 }
95 infile.open(configPath_, std::ios::in);
96 if (!infile.is_open()) {
97 NETNATIVE_LOGE("ReadJsonFile filePath failed");
98 return allConfigInfo;
99 }
100 while (getline(infile, lineConfigInfo)) {
101 allConfigInfo.append(lineConfigInfo);
102 }
103 infile.close();
104 return allConfigInfo;
105 }
106
ParseTcpIptables(const cJSON &json)107 bool WearableDistributedNet::ParseTcpIptables(const cJSON &json)
108 {
109 cJSON *tcpIptablesObj = cJSON_GetObjectItemCaseSensitive(&json, TCP_IPTABLES.c_str());
110 for (int32_t i = 0; i < cJSON_GetArraySize(tcpIptablesObj); i++) {
111 cJSON *tcpIptablesItem = cJSON_GetArrayItem(tcpIptablesObj, i);
112 if (tcpIptablesItem == nullptr) {
113 NETNATIVE_LOGE("Invalid item in TCP iptables array");
114 return false;
115 }
116 const auto tcpIptablesValue = tcpIptablesItem->valuestring;
117 tcpIptables_.push_back(std::string(tcpIptablesValue));
118 }
119 return true;
120 }
121
ParseTcpOutputRule(const cJSON &json)122 bool WearableDistributedNet::ParseTcpOutputRule(const cJSON &json)
123 {
124 cJSON *tcpOutputJsonItem = cJSON_GetObjectItemCaseSensitive(&json, TCP_OUTPUT.c_str());
125 if (tcpOutputJsonItem == nullptr) {
126 NETNATIVE_LOGE("Failed to find tcpOutputJsonItem information");
127 return false;
128 }
129 tcpOutput_ = cJSON_GetStringValue(tcpOutputJsonItem);
130 return true;
131 }
132
ParseUdpIptables(const cJSON &json)133 bool WearableDistributedNet::ParseUdpIptables(const cJSON &json)
134 {
135 cJSON *udpIptablesObj = cJSON_GetObjectItemCaseSensitive(&json, UDP_IPTABLES.c_str());
136 for (int32_t i = 0; i < cJSON_GetArraySize(udpIptablesObj); i++) {
137 cJSON *udpIptablesItem = cJSON_GetArrayItem(udpIptablesObj, i);
138 if (udpIptablesItem == nullptr) {
139 NETNATIVE_LOGE("Invalid item in UDP iptables array");
140 return false;
141 }
142 const auto udpIptablesValue = udpIptablesItem->valuestring;
143 udpIptables_.push_back(std::string(udpIptablesValue));
144 }
145 return true;
146 }
147
ParseUdpOutputRule(const cJSON &json)148 bool WearableDistributedNet::ParseUdpOutputRule(const cJSON &json)
149 {
150 cJSON *udpOutputItem = cJSON_GetObjectItemCaseSensitive(&json, UDP_OUTPUT.c_str());
151 if (udpOutputItem == nullptr) {
152 NETNATIVE_LOGE("Failed to find udpOutputItem information");
153 return false;
154 }
155 udpOutput_ = cJSON_GetStringValue(udpOutputItem);
156 return true;
157 }
158
ParseIptablesDeleteCmds(const cJSON &json)159 bool WearableDistributedNet::ParseIptablesDeleteCmds(const cJSON &json)
160 {
161 cJSON *iptablesDeleteCmdsObj = cJSON_GetObjectItemCaseSensitive(&json, IPTABLES_DELETE_CMDS.c_str());
162 for (int32_t i = 0; i < cJSON_GetArraySize(iptablesDeleteCmdsObj); i++) {
163 cJSON *iptablesDeleteCmdsItem = cJSON_GetArrayItem(iptablesDeleteCmdsObj, i);
164 if (iptablesDeleteCmdsItem == nullptr) {
165 NETNATIVE_LOGE("Invalid item in iptables delete commands array");
166 return false;
167 }
168 const auto iptablesDeleteCmdsValue = iptablesDeleteCmdsItem->valuestring;
169 iptablesDeleteCmds_.push_back(std::string(iptablesDeleteCmdsValue));
170 }
171 return true;
172 }
173
ReadIptablesInterfaces(const cJSON &json)174 bool WearableDistributedNet::ReadIptablesInterfaces(const cJSON &json)
175 {
176 if (!ParseTcpIptables(json)) {
177 NETNATIVE_LOGE("ParseTcpIptables failed");
178 return false;
179 }
180 if (!ParseTcpOutputRule(json)) {
181 NETNATIVE_LOGE("ParseTcpOutputRule failed");
182 return false;
183 }
184 if (!ParseUdpIptables(json)) {
185 NETNATIVE_LOGE("ParseUdpIptables failed");
186 return false;
187 }
188 if (!ParseUdpOutputRule(json)) {
189 NETNATIVE_LOGE("ParseUdpOutputRule failed");
190 return false;
191 }
192 if (!ParseIptablesDeleteCmds(json)) {
193 NETNATIVE_LOGE("ParseIptablesDeleteCmds failed");
194 return false;
195 }
196 return true;
197 }
198
SetTcpPort(const int32_t tcpPortId)199 void WearableDistributedNet::SetTcpPort(const int32_t tcpPortId)
200 {
201 tcpPort_ = tcpPortId;
202 }
203
GetTcpPort()204 int32_t WearableDistributedNet::GetTcpPort()
205 {
206 return tcpPort_;
207 }
208
RunCommandResult(const std::string &cmd)209 int32_t RunCommandResult(const std::string &cmd)
210 {
211 std::string response =
212 IptablesWrapper::GetInstance()->RunCommandForRes(OHOS::nmd::IpType::IPTYPE_IPV4, cmd);
213 return response.empty() ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
214 }
215
ExecuteIptablesCommands(const std::vector<std::string> &commands)216 int32_t WearableDistributedNet::ExecuteIptablesCommands(const std::vector<std::string> &commands)
217 {
218 for (const auto &command : commands) {
219 if (command.length() > MAX_CMD_LENGTH) {
220 NETNATIVE_LOGE("Invalid command found at index");
221 return NETMANAGER_ERROR;
222 }
223 if (RunCommandResult(command) != NETMANAGER_SUCCESS) {
224 return NETMANAGER_ERROR;
225 }
226 }
227 return NETMANAGER_SUCCESS;
228 }
229
EnableWearableDistributedNetForward(const int32_t tcpPortId, const int32_t udpPortId)230 int32_t WearableDistributedNet::EnableWearableDistributedNetForward(const int32_t tcpPortId, const int32_t udpPortId)
231 {
232 if (!ReadSystemIptablesConfiguration()) {
233 NETNATIVE_LOGE("Failed to read system iptables configuration");
234 return NETMANAGER_ERR_READ_DATA_FAIL;
235 }
236 if (tcpPortId <= 0 || tcpPortId > MAX_PORT_ID) {
237 NETNATIVE_LOGE("Invalid TCP port ID");
238 return NETMANAGER_WEARABLE_DISTRIBUTED_NET_ERR_INVALID_TCP_PORT_ID;
239 }
240 if (udpPortId <= 0 || udpPortId > MAX_PORT_ID) {
241 NETNATIVE_LOGE("Invalid UDP port ID");
242 return NETMANAGER_WEARABLE_DISTRIBUTED_NET_ERR_INVALID_UDP_PORT_ID;
243 }
244 SetTcpPort(tcpPortId);
245 int32_t ret = EstablishTcpIpRules();
246 if (ret != NETMANAGER_SUCCESS) {
247 NETNATIVE_LOGE("Failed to establish TCP IP rules for network distribution");
248 return ret;
249 }
250 ret = EstablishUdpIpRules(udpPortId);
251 if (ret != NETMANAGER_SUCCESS) {
252 NETNATIVE_LOGE("Failed to establish UDP IP rules for network distribution");
253 return ret;
254 }
255
256 return NETMANAGER_SUCCESS;
257 }
258
GenerateRule(const std::string &inputRules, const int32_t portId)259 std::string WearableDistributedNet::GenerateRule(const std::string &inputRules, const int32_t portId)
260 {
261 if (inputRules.empty()) {
262 NETNATIVE_LOGE("Input rules are null");
263 return "";
264 }
265 if (inputRules.length() > MAX_CMD_LENGTH) {
266 NETNATIVE_LOGE("Input rules are invalid");
267 return "";
268 }
269 char res[MAX_CMD_LENGTH] = {0};
270 if (sprintf_s(res, MAX_CMD_LENGTH, inputRules.c_str(), portId) == -1) {
271 return "";
272 }
273 return std::string(res);
274 }
275
ApplyRule(const RULES_TYPE type, const int32_t portId)276 int32_t WearableDistributedNet::ApplyRule(const RULES_TYPE type, const int32_t portId)
277 {
278 if (portId <= 0 || portId > MAX_PORT_ID) {
279 return NETMANAGER_WEARABLE_DISTRIBUTED_NET_ERR_INVALID_PORT_ID;
280 }
281 std::string resultRules;
282 switch (type) {
283 case TCP_ADD_RULE:
284 resultRules = GenerateRule(TCP_ADD16, portId);
285 break;
286 case UDP_ADD_RULE:
287 resultRules = GenerateRule(UDP_ADD16, portId);
288 break;
289 case INPUT_ADD_RULE:
290 resultRules = GenerateRule(INPUT_ADD, portId);
291 break;
292 case INPUT_DEL_RULE:
293 resultRules = GenerateRule(INPUT_DEL, portId);
294 break;
295 default:
296 NETNATIVE_LOGE("Invalid rule type");
297 break;
298 }
299 if (resultRules.empty()) {
300 NETNATIVE_LOGE("Failed to generate rule");
301 return NETMANAGER_ERR_INVALID_PARAMETER;
302 }
303 return RunCommandResult(resultRules);
304 }
305
EstablishTcpIpRules()306 int32_t WearableDistributedNet::EstablishTcpIpRules()
307 {
308 NETNATIVE_LOGI("Establishing TCP IP rules for network distribution");
309 if (ExecuteIptablesCommands(GetTcpIptables()) != NETMANAGER_SUCCESS) {
310 NETNATIVE_LOGE("Failed to execute TCP iptables commands");
311 return NETMANAGER_ERROR;
312 }
313 if (ApplyRule(TCP_ADD_RULE, GetTcpPort()) != NETMANAGER_SUCCESS) {
314 NETNATIVE_LOGE("Failed to apply TCP add rule");
315 return NETMANAGER_ERROR;
316 }
317 return RunCommandResult(GetOutputAddTcp());
318 }
319
EstablishUdpIpRules(const int32_t udpPortId)320 int32_t WearableDistributedNet::EstablishUdpIpRules(const int32_t udpPortId)
321 {
322 NETNATIVE_LOGI("Establishing UDP IP rules for network distribution");
323 if (ExecuteIptablesCommands(GetUdpIptables()) != NETMANAGER_SUCCESS) {
324 NETNATIVE_LOGE("Failed to execute UDP iptables commands");
325 return NETMANAGER_ERROR;
326 }
327 if (ApplyRule(UDP_ADD_RULE, udpPortId) != NETMANAGER_SUCCESS) {
328 NETNATIVE_LOGE("Failed to apply UDP add rule");
329 return NETMANAGER_ERROR;
330 }
331 return RunCommandResult(GetUdpoutput());
332 }
333
DisableWearableDistributedNetForward()334 int32_t WearableDistributedNet::DisableWearableDistributedNetForward()
335 {
336 NETNATIVE_LOGI("Disabling wearable distributed net forward");
337 if (ExecuteIptablesCommands(GetIptablesDeleteCmds()) != NETMANAGER_SUCCESS) {
338 NETNATIVE_LOGE("Failed to execute iptables delete commands");
339 return NETMANAGER_ERROR;
340 }
341 if (ApplyRule(INPUT_DEL_RULE, GetTcpPort()) != NETMANAGER_SUCCESS) {
342 NETNATIVE_LOGE("Failed to apply input delete rule");
343 return NETMANAGER_ERROR;
344 }
345 return NETMANAGER_SUCCESS;
346 }
347 } // namespace nmd
348 } // namespace OHOS