5 * Copyright (C) 2013-2014 BMW Car IT GmbH.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "../src/connman.h"
31 static bool assert_rule(const char *table_name, const char *rule)
33 char *cmd, *output, **lines;
34 GError **error = NULL;
38 cmd = g_strdup_printf(IPTABLES_SAVE " -t %s", table_name);
39 g_spawn_command_line_sync(cmd, &output, NULL, NULL, error);
42 lines = g_strsplit(output, "\n", 0);
47 for (i = 0; lines[i]; i++) {
48 DBG("lines[%02d]: %s\n", i, lines[i]);
49 if (g_strcmp0(lines[i], rule) == 0)
60 static void assert_rule_exists(const char *table_name, const char *rule)
62 if (g_strcmp0(IPTABLES_SAVE, "") == 0) {
63 DBG("iptables-save is missing, no assertion possible");
67 g_assert(assert_rule(table_name, rule));
70 static void assert_rule_not_exists(const char *table_name, const char *rule)
72 if (g_strcmp0(IPTABLES_SAVE, "") == 0) {
73 DBG("iptables-save is missing, no assertion possible");
77 g_assert(!assert_rule(table_name, rule));
80 static void test_iptables_chain0(void)
84 err = __connman_iptables_new_chain("filter", "foo");
87 err = __connman_iptables_commit("filter");
90 assert_rule_exists("filter", ":foo - [0:0]");
92 err = __connman_iptables_delete_chain("filter", "foo");
95 err = __connman_iptables_commit("filter");
98 assert_rule_not_exists("filter", ":foo - [0:0]");
101 static void test_iptables_chain1(void)
105 err = __connman_iptables_new_chain("filter", "foo");
108 err = __connman_iptables_commit("filter");
111 err = __connman_iptables_flush_chain("filter", "foo");
114 err = __connman_iptables_commit("filter");
117 err = __connman_iptables_delete_chain("filter", "foo");
120 err = __connman_iptables_commit("filter");
124 static void test_iptables_chain2(void)
128 err = __connman_iptables_change_policy("filter", "INPUT", "DROP");
131 err = __connman_iptables_commit("filter");
134 err = __connman_iptables_change_policy("filter", "INPUT", "ACCEPT");
137 err = __connman_iptables_commit("filter");
141 static void test_iptables_chain3(void)
145 err = __connman_iptables_new_chain("filter", "user-chain-0");
148 err = __connman_iptables_commit("filter");
151 assert_rule_exists("filter", ":user-chain-0 - [0:0]");
153 err = __connman_iptables_new_chain("filter", "user-chain-1");
156 err = __connman_iptables_commit("filter");
159 assert_rule_exists("filter", ":user-chain-0 - [0:0]");
160 assert_rule_exists("filter", ":user-chain-1 - [0:0]");
162 err = __connman_iptables_delete_chain("filter", "user-chain-1");
165 err = __connman_iptables_commit("filter");
168 assert_rule_exists("filter", ":user-chain-0 - [0:0]");
169 assert_rule_not_exists("filter", ":user-chain-1 - [0:0]");
171 err = __connman_iptables_delete_chain("filter", "user-chain-0");
174 err = __connman_iptables_commit("filter");
177 assert_rule_not_exists("filter", ":user-chain-0 - [0:0]");
180 static void test_iptables_rule0(void)
184 /* Test simple appending and removing a rule */
186 err = __connman_iptables_append("filter", "INPUT",
187 "-m mark --mark 1 -j LOG");
190 err = __connman_iptables_commit("filter");
193 assert_rule_exists("filter",
194 "-A INPUT -m mark --mark 0x1 -j LOG");
196 err = __connman_iptables_delete("filter", "INPUT",
197 "-m mark --mark 1 -j LOG");
200 err = __connman_iptables_commit("filter");
203 assert_rule_not_exists("filter",
204 "-A INPUT -m mark --mark 0x1 -j LOG");
207 static void test_iptables_rule1(void)
211 /* Test if we can do NAT stuff */
213 err = __connman_iptables_append("nat", "POSTROUTING",
214 "-s 10.10.1.0/24 -o eth0 -j MASQUERADE");
216 err = __connman_iptables_commit("nat");
219 assert_rule_exists("nat",
220 "-A POSTROUTING -s 10.10.1.0/24 -o eth0 -j MASQUERADE");
222 err = __connman_iptables_delete("nat", "POSTROUTING",
223 "-s 10.10.1.0/24 -o eth0 -j MASQUERADE");
225 err = __connman_iptables_commit("nat");
228 assert_rule_not_exists("nat",
229 "-A POSTROUTING -s 10.10.1.0/24 -o eth0 -j MASQUERADE");
232 static void test_iptables_rule2(void)
236 /* Test if the right rule is removed */
238 err = __connman_iptables_append("filter", "INPUT",
239 "-m mark --mark 1 -j LOG");
242 err = __connman_iptables_commit("filter");
245 assert_rule_exists("filter",
246 "-A INPUT -m mark --mark 0x1 -j LOG");
248 err = __connman_iptables_append("filter", "INPUT",
249 "-m mark --mark 2 -j LOG");
252 err = __connman_iptables_commit("filter");
255 assert_rule_exists("filter",
256 "-A INPUT -m mark --mark 0x1 -j LOG");
257 assert_rule_exists("filter",
258 "-A INPUT -m mark --mark 0x2 -j LOG");
260 err = __connman_iptables_delete("filter", "INPUT",
261 "-m mark --mark 2 -j LOG");
264 err = __connman_iptables_commit("filter");
267 assert_rule_exists("filter",
268 "-A INPUT -m mark --mark 0x1 -j LOG");
269 assert_rule_not_exists("filter",
270 "-A INPUT -m mark --mark 0x2 -j LOG");
272 err = __connman_iptables_delete("filter", "INPUT",
273 "-m mark --mark 1 -j LOG");
276 err = __connman_iptables_commit("filter");
279 assert_rule_not_exists("filter",
280 "-A INPUT -m mark --mark 0x1 -j LOG");
283 static void test_iptables_target0(void)
287 /* Test if 'fallthrough' targets work */
289 err = __connman_iptables_append("filter", "INPUT",
293 err = __connman_iptables_append("filter", "INPUT",
297 err = __connman_iptables_commit("filter");
300 assert_rule_exists("filter", "-A INPUT -m mark --mark 0x1");
301 assert_rule_exists("filter", "-A INPUT -m mark --mark 0x2");
303 err = __connman_iptables_delete("filter", "INPUT",
307 err = __connman_iptables_commit("filter");
310 err = __connman_iptables_delete("filter", "INPUT",
314 err = __connman_iptables_commit("filter");
317 assert_rule_not_exists("filter", "-A INPUT -m mark --mark 0x1");
318 assert_rule_not_exists("filter", "-A INPUT -m mark --mark 0x2");
321 struct connman_notifier *nat_notifier;
323 struct connman_service {
327 char *connman_service_get_interface(struct connman_service *service)
332 int connman_notifier_register(struct connman_notifier *notifier)
334 nat_notifier = notifier;
339 void connman_notifier_unregister(struct connman_notifier *notifier)
344 static void test_nat_basic0(void)
348 err = __connman_nat_enable("bridge", "192.168.2.1", 24);
351 /* test that table is empty */
352 err = __connman_iptables_append("nat", "POSTROUTING",
353 "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
356 err = __connman_iptables_commit("nat");
359 assert_rule_exists("nat",
360 "-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE");
362 err = __connman_iptables_delete("nat", "POSTROUTING",
363 "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
366 err = __connman_iptables_commit("nat");
369 assert_rule_not_exists("nat",
370 "-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE");
372 __connman_nat_disable("bridge");
375 static void test_nat_basic1(void)
377 struct connman_service *service;
380 service = g_try_new0(struct connman_service, 1);
383 nat_notifier->default_changed(service);
385 err = __connman_nat_enable("bridge", "192.168.2.1", 24);
388 /* test that table is not empty */
389 err = __connman_iptables_append("nat", "POSTROUTING",
390 "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
393 err = __connman_iptables_commit("nat");
396 __connman_nat_disable("bridge");
398 /* test that table is empty again */
399 err = __connman_iptables_delete("nat", "POSTROUTING",
400 "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
403 err = __connman_iptables_commit("nat");
409 static gchar *option_debug = NULL;
411 static bool parse_debug(const char *key, const char *value,
412 gpointer user_data, GError **error)
415 option_debug = g_strdup(value);
417 option_debug = g_strdup("*");
422 static GOptionEntry options[] = {
423 { "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG,
424 G_OPTION_ARG_CALLBACK, parse_debug,
425 "Specify debug options to enable", "DEBUG" },
429 int main(int argc, char *argv[])
431 GOptionContext *context;
432 GError *error = NULL;
435 g_test_init(&argc, &argv, NULL);
437 context = g_option_context_new(NULL);
438 g_option_context_add_main_entries(context, options, NULL);
440 if (!g_option_context_parse(context, &argc, &argv, &error)) {
442 g_printerr("%s\n", error->message);
445 g_printerr("An unknown error occurred\n");
449 g_option_context_free(context);
451 __connman_log_init(argv[0], option_debug, false, false,
452 "Unit Tests Connection Manager", VERSION);
454 __connman_iptables_init();
455 __connman_nat_init();
457 g_test_add_func("/iptables/chain0", test_iptables_chain0);
458 g_test_add_func("/iptables/chain1", test_iptables_chain1);
459 g_test_add_func("/iptables/chain2", test_iptables_chain2);
460 g_test_add_func("/iptables/chain3", test_iptables_chain3);
461 g_test_add_func("/iptables/rule0", test_iptables_rule0);
462 g_test_add_func("/iptables/rule1", test_iptables_rule1);
463 g_test_add_func("/iptables/rule2", test_iptables_rule2);
464 g_test_add_func("/iptables/target0", test_iptables_target0);
465 g_test_add_func("/nat/basic0", test_nat_basic0);
466 g_test_add_func("/nat/basic1", test_nat_basic1);
470 __connman_nat_cleanup();
471 __connman_iptables_cleanup();
473 g_free(option_debug);