Free before return
[platform/core/connectivity/stc-manager.git] / src / stc-pcap.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "stc-db.h"
18 #include "stc-pcap.h"
19 #include "stc-manager-plugin-pcap.h"
20
21 #define PCAP_DBUS_ERROR_NAME "net.stc.pcap.Error.Failed"
22
23 #define STC_PCAP_DBUS_REPLY_ERROR(invocation, err_num) \
24         g_dbus_method_invocation_return_dbus_error((invocation), \
25                                                    PCAP_DBUS_ERROR_NAME, \
26                                                    stc_err_strs[-(err_num)])
27
28 static const gchar *stc_err_strs[] = {
29         "ERROR_NONE",
30         "FAIL",
31         "DB_FAILED",
32         "OUT_OF_MEMORY",
33         "INVALID_PARAMETER",
34         "NO_DATA",
35         "ALREADY_DATA",
36         "UNINITIALIZED",
37         "PERMISSION_DENIED",
38         "NOTIMPL"
39 };
40
41 gboolean __validate_pcap(stc_pcap_s *pcap)
42 {
43         __STC_LOG_FUNC_ENTER__;
44
45         if (pcap == NULL) {
46                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
47                 return FALSE; //LCOV_EXCL_LINE
48         }
49
50         if (pcap->ifname == NULL ||
51                 pcap->ifname[0] == '\0') {
52                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
53                 return FALSE; //LCOV_EXCL_LINE
54         }
55
56         __STC_LOG_FUNC_EXIT__;
57         return TRUE;
58 }
59
60 static void __stc_extract_pcap(const char *key, GVariant *value,
61                                            void *user_data)
62 {
63         stc_pcap_s *pcap = (stc_pcap_s *) user_data;
64         if (pcap == NULL) {
65                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
66                 return; //LCOV_EXCL_LINE
67         }
68
69         if (!g_strcmp0(key, STC_PCAP_IFNAME)) {
70                 gsize str_length;
71                 const gchar *str = g_variant_get_string(value, &str_length);
72                 pcap->ifname = g_strdup(str);
73                 STC_LOGD("ifname: [%s]", pcap->ifname);
74
75         } else if (!g_strcmp0(key, STC_PCAP_NFLOG_GROUP)) {
76                 pcap->nflog_group = g_variant_get_uint32(value);
77                 STC_LOGD("nflog group: [%d]", pcap->nflog_group);
78
79         } else {
80                 STC_LOGD("Unknown select rule"); //LCOV_EXCL_LINE
81         }
82 }
83
84 gboolean handle_pcap_start(StcPcap *object,
85                                 GDBusMethodInvocation *invocation,
86                                 GVariant *parameters,
87                                 void *user_data)
88 {
89         __STC_LOG_FUNC_ENTER__;
90         GVariantIter *iter = NULL;
91         stc_pcap_s pcap;
92         int ret = STC_ERROR_NONE;
93
94         stc_set_keep_alive(TRUE);
95
96         memset(&pcap, 0, sizeof(stc_pcap_s));
97
98         g_variant_get(parameters, "a{sv}", &iter);
99         if (iter != NULL) {
100                 stc_manager_gdbus_dict_foreach(iter,
101                                                __stc_extract_pcap,
102                                                &pcap);
103                 g_variant_iter_free(iter);
104         }
105
106         if (__validate_pcap(&pcap) == FALSE) {
107                 STC_PCAP_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
108                                                  STC_ERROR_INVALID_PARAMETER);
109                 g_free(pcap.ifname);
110                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
111                 return TRUE;
112         }
113
114         ret = stc_plugin_pcap_register_loop(pcap.ifname, pcap.nflog_group);
115         if (ret != STC_ERROR_NONE) {
116                 STC_PCAP_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
117                 g_free(pcap.ifname);
118                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
119                 return TRUE;
120         }
121
122         STC_DBUS_REPLY_ERROR_NONE(invocation);
123         g_free(pcap.ifname);
124         __STC_LOG_FUNC_EXIT__;
125         return TRUE;
126 }
127
128 gboolean handle_pcap_stop(StcPcap *object,
129                                 GDBusMethodInvocation *invocation,
130                                 GVariant *parameters,
131                                 void *user_data)
132 {
133         __STC_LOG_FUNC_ENTER__;
134         GVariantIter *iter = NULL;
135         stc_pcap_s pcap;
136         int ret = STC_ERROR_NONE;
137
138         stc_set_keep_alive(TRUE);
139
140         memset(&pcap, 0, sizeof(stc_pcap_s));
141
142         g_variant_get(parameters, "a{sv}", &iter);
143         if (iter != NULL) {
144                 stc_manager_gdbus_dict_foreach(iter,
145                                                __stc_extract_pcap,
146                                                &pcap);
147                 g_variant_iter_free(iter);
148         }
149
150         if (__validate_pcap(&pcap) == FALSE) {
151                 STC_PCAP_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
152                                                  STC_ERROR_INVALID_PARAMETER);
153                 g_free(pcap.ifname);
154                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
155                 return TRUE;
156         }
157
158         ret = stc_plugin_pcap_unregister_loop(pcap.ifname, pcap.nflog_group);
159         if (ret != STC_ERROR_NONE) {
160                 STC_PCAP_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
161                 g_free(pcap.ifname);
162                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
163                 return TRUE;
164         }
165
166         STC_DBUS_REPLY_ERROR_NONE(invocation);
167         g_free(pcap.ifname);
168         __STC_LOG_FUNC_EXIT__;
169         return TRUE;
170 }
171
172 gboolean handle_pcap_get_all(StcPcap *object,
173                                 GDBusMethodInvocation *invocation,
174                                 void *user_data)
175 {
176         __STC_LOG_FUNC_ENTER__;
177         GVariantBuilder *builder = NULL;
178         GVariant *return_parameters = NULL;
179
180         stc_set_keep_alive(TRUE);
181
182         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
183
184         stc_plugin_pcap_get_all_loop(builder);
185
186         return_parameters = g_variant_new("(aa{sv})", builder);
187         g_variant_builder_unref(builder);
188
189         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
190         STC_DBUS_REPLY(invocation, return_parameters);
191         __STC_LOG_FUNC_EXIT__;
192         return TRUE;
193 }
194
195 gboolean handle_pcap_find_all_devs(StcPcap *object,
196                                 GDBusMethodInvocation *invocation,
197                                 void *user_data)
198 {
199         __STC_LOG_FUNC_ENTER__;
200         GVariantBuilder *builder = NULL;
201         GVariant *return_parameters = NULL;
202
203         stc_set_keep_alive(TRUE);
204
205         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
206
207         stc_plugin_pcap_find_all_devs(builder);
208
209         return_parameters = g_variant_new("(aa{sv})", builder);
210         g_variant_builder_unref(builder);
211
212         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
213         STC_DBUS_REPLY(invocation, return_parameters);
214         __STC_LOG_FUNC_EXIT__;
215         return TRUE;
216 }