tizen 2.3.1 release
[framework/connectivity/mobileap-agent.git] / src / mobileap_iptables.c
1 /*
2  * mobileap-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <unistd.h>
23 #include "mobileap_iptables.h"
24 #include "mobileap_softap.h"
25 #include "mobileap.h"
26 #include "mobileap_common.h"
27
28 #define CREATE_CHAIN_STR                "-t %s -N %s"  /* table_name, chain_name */
29 #define REDIRECTION_ADD_RULE_STR        "-t %s -A %s -j %s"
30 #define REDIRECTION_DEL_RULE_STR        "-t %s -D %s -j %s"
31 #define FLUSH_CMD_STR           "-t %s -F %s"
32 #define DELETE_CHAIN_STR        "-t %s -X %s"
33 #define FORWARD_RULE_WITH_ACTION_STR            "-t %s -A %s -i %s -o %s -j %s"
34 #define FORWARD_RULE_WITH_ACTION_AND_STATE_STR  "-t %s -A %s -i %s -o %s -m state --state %s -j %s"
35 #define MASQUERADE_RULE_STR             "-t %s -A %s -o %s -j MASQUERADE"
36 #define PORT_FORWARD_RULE_STR   "-t %s -A %s -i %s -p %s -d %s --dport %d -j DNAT --to %s:%d"
37 #define CLAMP_MSS_RULE_STR      "-t %s -A %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu"
38 #define DEFAULT_RULE_STR        "-t %s -A %s -j %s"
39
40
41 int _iptables_create_chain(const char *table_name, const char *chain_name)
42 {
43         char cmd[MAX_BUF_SIZE] = { 0, };
44
45         snprintf(cmd, sizeof(cmd), "%s "CREATE_CHAIN_STR, IPTABLES, table_name,
46                 chain_name);
47         SDBG("command [%s]\n", cmd);
48         if (_execute_command(cmd)) {
49                 SERR("command [%s] failed\n", cmd);
50                 return MOBILE_AP_ERROR_INTERNAL;
51         }
52
53         return MOBILE_AP_ERROR_NONE;
54 }
55
56 int _iptables_flush_rules(const char *table_name, const char *chain_name)
57 {
58         char cmd[MAX_BUF_SIZE] = { 0, };
59
60         snprintf(cmd, sizeof(cmd), "%s "FLUSH_CMD_STR, IPTABLES, table_name,
61                 chain_name);
62         SDBG("command [%s]\n", cmd);
63         if (_execute_command(cmd)) {
64                 SERR("command [%s] failed\n", cmd);
65                 return MOBILE_AP_ERROR_INTERNAL;
66         }
67
68         return MOBILE_AP_ERROR_NONE;
69 }
70
71 int _iptables_delete_chain(const char *table_name, const char *chain_name)
72 {
73         char cmd[MAX_BUF_SIZE] = { 0, };
74
75         snprintf(cmd, sizeof(cmd), "%s "DELETE_CHAIN_STR, IPTABLES, table_name,
76                 chain_name);
77         SDBG("command [%s]\n", cmd);
78         if (_execute_command(cmd)) {
79                 SERR("command [%s] failed\n", cmd);
80                 return MOBILE_AP_ERROR_INTERNAL;
81         }
82
83         return MOBILE_AP_ERROR_NONE;
84 }
85
86 int _iptables_add_rule(iptables_rule_e rule_type, const char *table, const char *chain, ...)
87 {
88         if (table == NULL || chain == NULL) {
89                 ERR("invalid parameters\n");
90                 return MOBILE_AP_ERROR_INVALID_PARAM;
91         }
92
93         va_list ap;
94         char cmd[MAX_BUF_SIZE] = { 0, };
95
96         va_start(ap, chain);
97         switch (rule_type) {
98         case PKT_REDIRECTION_RULE: {
99                 char *dst_chain;
100
101                 dst_chain = va_arg(ap, char *);
102                 if (dst_chain == NULL) {
103                         ERR("invalid parameters\n");
104                         goto ERROR_EXIT;
105                 }
106
107                 snprintf(cmd, sizeof(cmd), "%s "REDIRECTION_ADD_RULE_STR, IPTABLES,
108                                 table, chain, dst_chain);
109                 break;
110         }
111
112         case FORWARD_RULE_WITH_ACTION: {
113                 char *in_iface = NULL;
114                 char *out_iface = NULL;
115                 char *action = NULL;
116
117                 in_iface = va_arg(ap, char *);
118                 out_iface = va_arg(ap, char *);
119                 action = va_arg(ap, char *);
120
121                 if (in_iface == NULL || out_iface == NULL || action == NULL) {
122                         ERR("invalid parameters\n");
123                         goto ERROR_EXIT;
124                 }
125
126                 snprintf(cmd, sizeof(cmd), "%s "FORWARD_RULE_WITH_ACTION_STR, IPTABLES,
127                         table, chain, in_iface, out_iface, action);
128                 break;
129         }
130
131         case FORWARD_RULE_WITH_ACTION_AND_STATE: {
132                 char *in_iface = NULL;
133                 char *out_iface = NULL;
134                 char *action = NULL;
135                 char *state = NULL;
136
137                 in_iface = va_arg(ap, char *);
138                 out_iface = va_arg(ap, char *);
139                 action = va_arg(ap, char *);
140                 state = va_arg(ap, char *);
141
142                 if (in_iface == NULL || out_iface == NULL || action == NULL ||
143                                 state == NULL) {
144                         ERR("invalid parameters\n");
145                         goto ERROR_EXIT;
146                 }
147
148                 snprintf(cmd, sizeof(cmd), "%s "FORWARD_RULE_WITH_ACTION_AND_STATE_STR,
149                         IPTABLES, table, chain, in_iface, out_iface, state, action);
150
151                 break;
152         }
153
154         case PORT_FW_RULE: {
155                 char *ip_iface = NULL;
156                 char *proto = NULL;
157                 char *org_ip = NULL;
158                 char *final_ip = NULL;
159                 unsigned short org_port = 0;
160                 unsigned short final_port = 0;
161
162                 ip_iface = va_arg(ap, char *);
163                 proto = va_arg(ap, char *);
164                 org_ip = va_arg(ap, char *);
165                 final_ip = va_arg(ap, char *);
166                 org_port = va_arg(ap, int);
167                 final_port = va_arg(ap, int);
168
169                 if (ip_iface == NULL || proto == NULL || org_ip == NULL ||
170                                 final_ip == NULL) {
171                         ERR("invalid parameters\n");
172                         goto ERROR_EXIT;
173                 }
174
175                 snprintf(cmd, sizeof(cmd), "%s "PORT_FORWARD_RULE_STR,
176                         IPTABLES, table, chain, ip_iface, proto,
177                         org_ip, org_port, final_ip, final_port);
178                 break;
179         }
180
181         case MASQ_RULE: {
182                 char *ext_iface = NULL;
183
184                 ext_iface = va_arg(ap, char *);
185
186                 if (ext_iface == NULL) {
187                         ERR("invalid parameters\n");
188                         goto ERROR_EXIT;
189                 }
190
191                 snprintf(cmd, sizeof(cmd), "%s "MASQUERADE_RULE_STR, IPTABLES,
192                                 table, chain, ext_iface);
193                 break;
194         }
195
196         case CLAMP_MSS_RULE: {
197                 snprintf(cmd, sizeof(cmd), "%s "CLAMP_MSS_RULE_STR, IPTABLES,
198                         table, chain);
199                 break;
200         }
201
202         case DEFAULT_RULE: {
203                 char *action;
204
205                 action = va_arg(ap, char *);
206
207                 if (action == NULL) {
208                         ERR("invalid parameters\n");
209                         goto ERROR_EXIT;
210                 }
211
212                 snprintf(cmd, sizeof(cmd), "%s "DEFAULT_RULE_STR, IPTABLES,
213                         table, chain, action);
214                 break;
215         }
216
217         default:
218                 ERR("case not supported\n");
219                 goto ERROR_EXIT;
220         }
221
222         if (_execute_command(cmd)) {
223                 SERR("command [%s] failed\n", cmd);
224                 goto ERROR_EXIT;
225         }
226
227         va_end(ap);
228         return MOBILE_AP_ERROR_NONE;
229
230 ERROR_EXIT:
231         va_end(ap);
232         return MOBILE_AP_ERROR_INVALID_PARAM;
233 }
234
235 int _iptables_delete_rule(iptables_rule_e rule_type, const char *table, const char *chain, ...)
236 {
237         va_list ap;
238         char cmd[MAX_BUF_SIZE] = { 0, };
239
240         va_start(ap, chain);
241         switch (rule_type) {
242         case PKT_REDIRECTION_RULE: {
243                 char *dst_chain = NULL;
244
245                 dst_chain = va_arg(ap, char *);
246                 snprintf(cmd, sizeof(cmd), "%s "REDIRECTION_DEL_RULE_STR, IPTABLES,
247                         table, chain, dst_chain);
248                 break;
249         }
250         default:
251                 ERR("case not supported\n");
252                 goto ERROR_EXIT;
253         }
254
255         if (_execute_command(cmd)) {
256                 SERR("command [%s] failed\n", cmd);
257                 return MOBILE_AP_ERROR_INTERNAL;
258         }
259         va_end(ap);
260         return MOBILE_AP_ERROR_NONE;
261
262 ERROR_EXIT:
263         va_end(ap);
264         return MOBILE_AP_ERROR_INTERNAL;
265 }
266
267 int _get_data_usage(const char *src, const char *dest, unsigned long long *tx,
268                 unsigned long long *rx)
269 {
270         if (src == NULL || src[0] == '\0' || dest == NULL || dest[0] == '\0' ||
271                         tx == NULL || rx == NULL) {
272                 ERR("Invalid parameter\n");
273                 return MOBILE_AP_ERROR_INVALID_PARAM;
274         }
275
276         char cmd[MAX_BUF_SIZE] = {0, };
277         char buf[MAX_BUF_SIZE] = {0, };
278         FILE *fp = NULL;
279
280         /* Tx : Src. -> Dest. */
281         snprintf(cmd, sizeof(cmd),
282                 "%s -t %s -L %s -vx | %s -v DROP | %s \"%s[ ]*%s\" | %s '{ print $2 }' > %s",
283                 IPTABLES, TABLE_FILTER, TETH_FILTER_FW, GREP, GREP, src, dest, AWK, DATA_USAGE_FILE);
284         if (system(cmd) < 0) {
285                 ERR("cmd %s is failed\n", cmd);
286         }
287
288         *tx = 0;
289
290         fp = fopen(DATA_USAGE_FILE, "r");
291         if (fp == NULL) {
292                 ERR("%s open failed\n", DATA_USAGE_FILE);
293                 ERR("%s\n", strerror(errno));
294                 return MOBILE_AP_ERROR_INTERNAL;
295         }
296
297         while (fgets(buf, sizeof(buf), fp) != NULL) {
298                 *tx += atoll(buf);
299         }
300
301         fclose(fp);
302         unlink(DATA_USAGE_FILE);
303
304         /* Rx : Dest. -> Src. */
305         snprintf(cmd, sizeof(cmd),
306                 "%s -t %s -L %s -vx | %s -v DROP | %s \"%s[ ]*%s\" | %s '{ print $2 }' > %s",
307                 IPTABLES, TABLE_FILTER, TETH_FILTER_FW, GREP, GREP, dest, src, AWK, DATA_USAGE_FILE);
308         if (system(cmd) < 0) {
309                 ERR("cmd %s is failed\n", cmd);
310         }
311
312         *rx = 0;
313
314         fp = fopen(DATA_USAGE_FILE, "r");
315         if (fp == NULL) {
316                 ERR("%s open failed\n", DATA_USAGE_FILE);
317                 ERR("%s\n", strerror(errno));
318                 return MOBILE_AP_ERROR_INTERNAL;
319         }
320
321         while (fgets(buf, sizeof(buf), fp) != NULL) {
322                 *rx += atoll(buf);
323         }
324
325         fclose(fp);
326         unlink(DATA_USAGE_FILE);
327
328         return MOBILE_AP_ERROR_NONE;
329 }