Initialize smart traffic control iptables package
[platform/core/connectivity/stc-iptables.git] / src / stc-iptables-util.c
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License version 2 as
6  *  published by the Free Software Foundation.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program; if not, write to the Free Software
15  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16  */
17
18 #include <string.h>
19
20 #include "stc-iptables-util.h"
21 #include "helper-iptables.h"
22 #include "helper-ip6tables.h"
23
24 #define STC_IPTABLES_DBUS_ERROR_NAME "net.stc.iptables.Error.Failed"
25         
26 #define STC_IPTABLES_DBUS_REPLY(invocation, parameters) \
27                 g_dbus_method_invocation_return_value((invocation), parameters);
28         
29 #define STC_IPTABLES_DBUS_REPLY_ERROR(invocation, err_num) \
30                 g_dbus_method_invocation_return_dbus_error((invocation), \
31                                                            STC_IPTABLES_DBUS_ERROR_NAME, \
32                                                            stc_iptables_err_strs[-(err_num)])
33
34 static const gchar *stc_iptables_err_strs[] = {
35                 "ERROR_NONE",
36                 "FAIL",
37                 "DB_FAILED",
38                 "OUT_OF_MEMORY",
39                 "INVALID_PARAMETER",
40                 "NO_DATA",
41                 "UNINITIALIZED",
42                 "NOTIMPL"
43         };
44
45 void __stc_extract_rule(const char *key, GVariant *value,
46                                void *user_data)
47 {
48         iptables_rule_s *rule = (iptables_rule_s *)user_data;
49         if (rule == NULL)
50                 return;
51
52         if (!g_strcmp0(key, "chain")) {
53                 gsize len = 0;
54                 rule->chain = g_variant_dup_string(value, &len);
55                 STC_LOGD("chain: [%s]", rule->chain);
56
57         } else if (!g_strcmp0(key, "type")) {
58                 rule->type = g_variant_get_uint32(value);
59                 STC_LOGD("type: [%d]", rule->type);
60
61         } else if (!g_strcmp0(key, "ifname")) {
62                 gsize len = 0;
63                 rule->ifname = g_variant_dup_string(value, &len);
64                 STC_LOGD("ifname: [%s]", rule->ifname);
65
66         } else if (!g_strcmp0(key, "cgroup")) {
67                 rule->classid = g_variant_get_uint32(value);
68                 STC_LOGD("classid: [%d]", rule->classid);
69
70         } else if (!g_strcmp0(key, "nfacct")) {
71                 gsize len = 0;
72                 rule->nfacct_name = g_variant_dup_string(value, &len);
73                 STC_LOGD("nfacct_name: [%s]", rule->nfacct_name);
74
75         } else if (!g_strcmp0(key, "target")) {
76                 gsize len = 0;
77                 rule->target = g_variant_dup_string(value, &len);
78                 STC_LOGD("target: [%s]", rule->target);
79
80         } else {
81                 STC_LOGD("Unknown rule");
82         }
83 }
84
85 void __stc_extract_6_rule(const char *key, GVariant *value,
86                                void *user_data)
87 {
88         ip6tables_rule_s *rule = (ip6tables_rule_s *)user_data;
89         if (rule == NULL)
90                 return;
91
92         if (!g_strcmp0(key, "chain")) {
93                 gsize len = 0;
94                 rule->chain = g_variant_dup_string(value, &len);
95                 STC_LOGD("chain: [%s]", rule->chain);
96
97         } else if (!g_strcmp0(key, "type")) {
98                 rule->type = g_variant_get_uint32(value);
99                 STC_LOGD("type: [%d]", rule->type);
100
101         } else if (!g_strcmp0(key, "ifname")) {
102                 gsize len = 0;
103                 rule->ifname = g_variant_dup_string(value, &len);
104                 STC_LOGD("ifname: [%s]", rule->ifname);
105
106         } else if (!g_strcmp0(key, "cgroup")) {
107                 rule->classid = g_variant_get_uint32(value);
108                 STC_LOGD("classid: [%d]", rule->classid);
109
110         } else if (!g_strcmp0(key, "nfacct")) {
111                 gsize len = 0;
112                 rule->nfacct_name = g_variant_dup_string(value, &len);
113                 STC_LOGD("nfacct_name: [%s]", rule->nfacct_name);
114
115         } else if (!g_strcmp0(key, "target")) {
116                 gsize len = 0;
117                 rule->target = g_variant_dup_string(value, &len);
118                 STC_LOGD("target: [%s]", rule->target);
119
120         } else {
121                 STC_LOGD("Unknown rule");
122         }
123 }
124
125 gboolean handle_iptables_add_rule(StcRule *object,
126                                GDBusMethodInvocation *invocation,
127                                GVariant *rules,
128                                void *user_data)
129 {
130         __STC_LOG_FUNC_ENTER__;
131         stc_error_e ret = STC_ERROR_NONE;
132         GVariant *return_parameters = NULL;
133
134         if (rules != NULL) {
135                 GVariantIter *iter = NULL;
136                 GVariantIter *iter_row = NULL;
137
138                 g_variant_get(rules, "aa{sv}", &iter);
139
140                 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
141                         iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1);
142                         if (rule != NULL) {
143                                 memset(rule, 0, sizeof(iptables_rule_s));
144
145                                 stc_iptables_gdbus_dict_foreach(iter_row,
146                                                                __stc_extract_rule,
147                                                                rule);
148
149                                 ret = iptables_add_rule(rule);
150                                 if (ret != STC_ERROR_NONE) {
151                                         STC_LOGE("Failed add rule [%s:%d:%s:%d:%s:%s]", rule->chain,
152                                                 rule->type, rule->ifname, rule->classid,
153                                                 rule->nfacct_name, rule->target);
154                                 }
155
156                                 FREE(rule->chain);
157                                 FREE(rule->ifname);
158                                 FREE(rule->nfacct_name);
159                                 FREE(rule->target);
160                         }
161
162                         g_variant_iter_free(iter_row);
163                 }
164                 g_variant_iter_free(iter);
165         } else {
166                 STC_IPTABLES_DBUS_REPLY_ERROR(invocation,
167                         STC_ERROR_INVALID_PARAMETER);
168                 __STC_LOG_FUNC_EXIT__;
169                 return TRUE;
170         }
171
172         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
173
174         STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
175         STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
176
177         __STC_LOG_FUNC_EXIT__;
178         return TRUE;
179 }
180
181 gboolean handle_iptables_remove_rule(StcRule *object,
182                                GDBusMethodInvocation *invocation,
183                                GVariant *rules,
184                                void *user_data)
185 {
186         __STC_LOG_FUNC_ENTER__;
187         stc_error_e ret = STC_ERROR_NONE;
188         GVariant *return_parameters = NULL;
189
190         if (rules != NULL) {
191                 GVariantIter *iter = NULL;
192                 GVariantIter *iter_row = NULL;
193                 g_variant_get(rules, "aa{sv}", &iter);
194
195                 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
196                         iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1);
197                         if (rule != NULL) {
198                                 memset(rule, 0, sizeof(iptables_rule_s));
199
200                                 stc_iptables_gdbus_dict_foreach(iter_row,
201                                                                __stc_extract_rule,
202                                                                rule);
203
204                                 ret = iptables_remove_rule(rule);
205                                 if (ret != STC_ERROR_NONE) {
206                                         STC_LOGE("Failed remove rule [%s:%d:%s:%d:%s:%s]", rule->chain,
207                                                 rule->type, rule->ifname, rule->classid,
208                                                 rule->nfacct_name, rule->target);
209                                 }
210
211                                 FREE(rule->chain);
212                                 FREE(rule->ifname);
213                                 FREE(rule->nfacct_name);
214                                 FREE(rule->target);
215                         }
216
217                         g_variant_iter_free(iter_row);
218                 }
219                 g_variant_iter_free(iter);
220         } else {
221                 STC_IPTABLES_DBUS_REPLY_ERROR(invocation,
222                         STC_ERROR_INVALID_PARAMETER);
223                 __STC_LOG_FUNC_EXIT__;
224                 return TRUE;
225         }
226
227         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
228
229         STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
230         STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
231
232         __STC_LOG_FUNC_EXIT__;
233         return TRUE;
234 }
235
236 gboolean handle_iptables_add_chain(StcChain *object,
237                                GDBusMethodInvocation *invocation,
238                                const gchar *chain,
239                                void *user_data)
240 {
241         __STC_LOG_FUNC_ENTER__;
242         stc_error_e ret = STC_ERROR_NONE;
243         GVariant *return_parameters = NULL;
244
245         ret = iptables_add_chain(chain);
246         if (ret < STC_ERROR_NONE) {
247                 STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret);
248                 __STC_LOG_FUNC_EXIT__;
249                 return TRUE;
250         }
251
252         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
253
254         STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
255         STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
256
257         __STC_LOG_FUNC_EXIT__;
258         return TRUE;
259 }
260
261 gboolean handle_iptables_remove_chain(StcChain *object,
262                                GDBusMethodInvocation *invocation,
263                                const gchar *chain,
264                                void *user_data)
265 {
266         __STC_LOG_FUNC_ENTER__;
267         stc_error_e ret = STC_ERROR_NONE;
268         GVariant *return_parameters = NULL;
269
270         ret = iptables_remove_chain(chain);
271         if (ret < STC_ERROR_NONE) {
272                 STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret);
273                 __STC_LOG_FUNC_EXIT__;
274                 return TRUE;
275         }
276
277         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
278
279         STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
280         STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
281
282         __STC_LOG_FUNC_EXIT__;
283         return TRUE;
284 }
285
286 gboolean handle_ip6tables_add_rule(StcRule *object,
287                                GDBusMethodInvocation *invocation,
288                                GVariant *rules,
289                                void *user_data)
290 {
291         __STC_LOG_FUNC_ENTER__;
292         stc_error_e ret = STC_ERROR_NONE;
293         GVariant *return_parameters = NULL;
294
295         if (rules != NULL) {
296                 GVariantIter *iter = NULL;
297                 GVariantIter *iter_row = NULL;
298
299                 g_variant_get(rules, "aa{sv}", &iter);
300
301                 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
302                         ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1);
303                         if (rule != NULL) {
304                                 memset(rule, 0, sizeof(ip6tables_rule_s));
305
306                                 stc_iptables_gdbus_dict_foreach(iter_row,
307                                                                __stc_extract_6_rule,
308                                                                rule);
309
310                                 ret = ip6tables_add_rule(rule);
311                                 if (ret != STC_ERROR_NONE) {
312                                         STC_LOGE("Failed add rule [%s:%d:%s:%d:%s:%s]", rule->chain,
313                                                 rule->type, rule->ifname, rule->classid,
314                                                 rule->nfacct_name, rule->target);
315                                 }
316
317                                 FREE(rule->chain);
318                                 FREE(rule->ifname);
319                                 FREE(rule->nfacct_name);
320                                 FREE(rule->target);
321                         }
322
323                         g_variant_iter_free(iter_row);
324                 }
325                 g_variant_iter_free(iter);
326         } else {
327                 STC_IPTABLES_DBUS_REPLY_ERROR(invocation,
328                         STC_ERROR_INVALID_PARAMETER);
329                 __STC_LOG_FUNC_EXIT__;
330                 return TRUE;
331         }
332
333         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
334
335         STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
336         STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
337
338         __STC_LOG_FUNC_EXIT__;
339         return TRUE;
340 }
341
342 gboolean handle_ip6tables_remove_rule(StcRule *object,
343                                GDBusMethodInvocation *invocation,
344                                GVariant *rules,
345                                void *user_data)
346 {
347         __STC_LOG_FUNC_ENTER__;
348         stc_error_e ret = STC_ERROR_NONE;
349         GVariant *return_parameters = NULL;
350
351         if (rules != NULL) {
352                 GVariantIter *iter = NULL;
353                 GVariantIter *iter_row = NULL;
354                 g_variant_get(rules, "aa{sv}", &iter);
355
356                 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
357                         ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1);
358                         if (rule != NULL) {
359                                 memset(rule, 0, sizeof(ip6tables_rule_s));
360
361                                 stc_iptables_gdbus_dict_foreach(iter_row,
362                                                                __stc_extract_6_rule,
363                                                                rule);
364
365                                 ret = ip6tables_remove_rule(rule);
366                                 if (ret != STC_ERROR_NONE) {
367                                         STC_LOGE("Failed remove rule [%s:%d:%s:%d:%s:%s]", rule->chain,
368                                                 rule->type, rule->ifname, rule->classid,
369                                                 rule->nfacct_name, rule->target);
370                                 }
371
372                                 FREE(rule->chain);
373                                 FREE(rule->ifname);
374                                 FREE(rule->nfacct_name);
375                                 FREE(rule->target);
376                         }
377
378                         g_variant_iter_free(iter_row);
379                 }
380                 g_variant_iter_free(iter);
381         } else {
382                 STC_IPTABLES_DBUS_REPLY_ERROR(invocation,
383                         STC_ERROR_INVALID_PARAMETER);
384                 __STC_LOG_FUNC_EXIT__;
385                 return TRUE;
386         }
387
388         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
389
390         STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
391         STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
392
393         __STC_LOG_FUNC_EXIT__;
394         return TRUE;
395 }
396
397 gboolean handle_ip6tables_add_chain(StcChain *object,
398                                GDBusMethodInvocation *invocation,
399                                const gchar *chain,
400                                void *user_data)
401 {
402         __STC_LOG_FUNC_ENTER__;
403         stc_error_e ret = STC_ERROR_NONE;
404         GVariant *return_parameters = NULL;
405
406         ret = ip6tables_add_chain(chain);
407         if (ret < STC_ERROR_NONE) {
408                 STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret);
409                 __STC_LOG_FUNC_EXIT__;
410                 return TRUE;
411         }
412
413         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
414
415         STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
416         STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
417
418         __STC_LOG_FUNC_EXIT__;
419         return TRUE;
420 }
421
422 gboolean handle_ip6tables_remove_chain(StcChain *object,
423                                GDBusMethodInvocation *invocation,
424                                const gchar *chain,
425                                void *user_data)
426 {
427         __STC_LOG_FUNC_ENTER__;
428         stc_error_e ret = STC_ERROR_NONE;
429         GVariant *return_parameters = NULL;
430
431         ret = ip6tables_remove_chain(chain);
432         if (ret < STC_ERROR_NONE) {
433                 STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret);
434                 __STC_LOG_FUNC_EXIT__;
435                 return TRUE;
436         }
437
438         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
439
440         STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
441         STC_IPTABLES_DBUS_REPLY(invocation, return_parameters);
442
443         __STC_LOG_FUNC_EXIT__;
444         return TRUE;
445 }