3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include "mobileap_iptables.h"
24 #include "mobileap_softap.h"
26 #include "mobileap_common.h"
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"
41 int _iptables_create_chain(const char *table_name, const char *chain_name)
43 char cmd[MAX_BUF_SIZE] = { 0, };
45 snprintf(cmd, sizeof(cmd), "%s "CREATE_CHAIN_STR, IPTABLES, table_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;
53 return MOBILE_AP_ERROR_NONE;
56 int _iptables_flush_rules(const char *table_name, const char *chain_name)
58 char cmd[MAX_BUF_SIZE] = { 0, };
60 snprintf(cmd, sizeof(cmd), "%s "FLUSH_CMD_STR, IPTABLES, table_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;
68 return MOBILE_AP_ERROR_NONE;
71 int _iptables_delete_chain(const char *table_name, const char *chain_name)
73 char cmd[MAX_BUF_SIZE] = { 0, };
75 snprintf(cmd, sizeof(cmd), "%s "DELETE_CHAIN_STR, IPTABLES, table_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;
83 return MOBILE_AP_ERROR_NONE;
86 int _iptables_add_rule(iptables_rule_e rule_type, const char *table, const char *chain, ...)
88 if (table == NULL || chain == NULL) {
89 ERR("invalid parameters\n");
90 return MOBILE_AP_ERROR_INVALID_PARAM;
94 char cmd[MAX_BUF_SIZE] = { 0, };
98 case PKT_REDIRECTION_RULE: {
101 dst_chain = va_arg(ap, char *);
102 if (dst_chain == NULL) {
103 ERR("invalid parameters\n");
107 snprintf(cmd, sizeof(cmd), "%s "REDIRECTION_ADD_RULE_STR, IPTABLES,
108 table, chain, dst_chain);
112 case FORWARD_RULE_WITH_ACTION: {
113 char *in_iface = NULL;
114 char *out_iface = NULL;
117 in_iface = va_arg(ap, char *);
118 out_iface = va_arg(ap, char *);
119 action = va_arg(ap, char *);
121 if (in_iface == NULL || out_iface == NULL || action == NULL) {
122 ERR("invalid parameters\n");
126 snprintf(cmd, sizeof(cmd), "%s "FORWARD_RULE_WITH_ACTION_STR, IPTABLES,
127 table, chain, in_iface, out_iface, action);
131 case FORWARD_RULE_WITH_ACTION_AND_STATE: {
132 char *in_iface = NULL;
133 char *out_iface = NULL;
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 *);
142 if (in_iface == NULL || out_iface == NULL || action == NULL ||
144 ERR("invalid parameters\n");
148 snprintf(cmd, sizeof(cmd), "%s "FORWARD_RULE_WITH_ACTION_AND_STATE_STR,
149 IPTABLES, table, chain, in_iface, out_iface, state, action);
155 char *ip_iface = NULL;
158 char *final_ip = NULL;
159 unsigned short org_port = 0;
160 unsigned short final_port = 0;
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);
169 if (ip_iface == NULL || proto == NULL || org_ip == NULL ||
171 ERR("invalid parameters\n");
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);
182 char *ext_iface = NULL;
184 ext_iface = va_arg(ap, char *);
186 if (ext_iface == NULL) {
187 ERR("invalid parameters\n");
191 snprintf(cmd, sizeof(cmd), "%s "MASQUERADE_RULE_STR, IPTABLES,
192 table, chain, ext_iface);
196 case CLAMP_MSS_RULE: {
197 snprintf(cmd, sizeof(cmd), "%s "CLAMP_MSS_RULE_STR, IPTABLES,
205 action = va_arg(ap, char *);
207 if (action == NULL) {
208 ERR("invalid parameters\n");
212 snprintf(cmd, sizeof(cmd), "%s "DEFAULT_RULE_STR, IPTABLES,
213 table, chain, action);
218 ERR("case not supported\n");
222 if (_execute_command(cmd)) {
223 SERR("command [%s] failed\n", cmd);
228 return MOBILE_AP_ERROR_NONE;
232 return MOBILE_AP_ERROR_INVALID_PARAM;
235 int _iptables_delete_rule(iptables_rule_e rule_type, const char *table, const char *chain, ...)
238 char cmd[MAX_BUF_SIZE] = { 0, };
242 case PKT_REDIRECTION_RULE: {
243 char *dst_chain = NULL;
245 dst_chain = va_arg(ap, char *);
246 snprintf(cmd, sizeof(cmd), "%s "REDIRECTION_DEL_RULE_STR, IPTABLES,
247 table, chain, dst_chain);
251 ERR("case not supported\n");
255 if (_execute_command(cmd)) {
256 SERR("command [%s] failed\n", cmd);
257 return MOBILE_AP_ERROR_INTERNAL;
260 return MOBILE_AP_ERROR_NONE;
264 return MOBILE_AP_ERROR_INTERNAL;
267 int _get_data_usage(const char *src, const char *dest, unsigned long long *tx,
268 unsigned long long *rx)
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;
276 char cmd[MAX_BUF_SIZE] = {0, };
277 char buf[MAX_BUF_SIZE] = {0, };
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);
290 fp = fopen(DATA_USAGE_FILE, "r");
292 ERR("%s open failed\n", DATA_USAGE_FILE);
293 ERR("%s\n", strerror(errno));
294 return MOBILE_AP_ERROR_INTERNAL;
297 while (fgets(buf, sizeof(buf), fp) != NULL) {
302 unlink(DATA_USAGE_FILE);
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);
314 fp = fopen(DATA_USAGE_FILE, "r");
316 ERR("%s open failed\n", DATA_USAGE_FILE);
317 ERR("%s\n", strerror(errno));
318 return MOBILE_AP_ERROR_INTERNAL;
321 while (fgets(buf, sizeof(buf), fp) != NULL) {
326 unlink(DATA_USAGE_FILE);
328 return MOBILE_AP_ERROR_NONE;