5 * Copyright (C) 2013 BWM CarIT GmbH. All rights reserved.
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
28 #include "../src/connman.h"
30 static bool assert_rule(const char *table_name, const char *rule)
32 char *cmd, *output, **lines;
33 GError **error = NULL;
36 cmd = g_strdup_printf(IPTABLES_SAVE " -t %s", table_name);
37 g_spawn_command_line_sync(cmd, &output, NULL, NULL, error);
40 lines = g_strsplit(output, "\n", 0);
43 for (i = 0; lines[i]; i++) {
44 DBG("lines[%02d]: %s\n", i, lines[i]);
45 if (g_strcmp0(lines[i], rule) == 0)
56 static void assert_rule_exists(const char *table_name, const char *rule)
58 if (g_strcmp0(IPTABLES_SAVE, "") == 0) {
59 DBG("iptables-save is missing, no assertion possible");
63 g_assert(assert_rule(table_name, rule));
66 static void assert_rule_not_exists(const char *table_name, const char *rule)
68 if (g_strcmp0(IPTABLES_SAVE, "") == 0) {
69 DBG("iptables-save is missing, no assertion possible");
73 g_assert(!assert_rule(table_name, rule));
76 static void test_iptables_chain0(void)
80 err = __connman_iptables_new_chain("filter", "foo");
83 err = __connman_iptables_commit("filter");
86 assert_rule_exists("filter", ":foo - [0:0]");
88 err = __connman_iptables_delete_chain("filter", "foo");
91 err = __connman_iptables_commit("filter");
94 assert_rule_not_exists("filter", ":foo - [0:0]");
97 static void test_iptables_chain1(void)
101 err = __connman_iptables_new_chain("filter", "foo");
104 err = __connman_iptables_commit("filter");
107 err = __connman_iptables_flush_chain("filter", "foo");
110 err = __connman_iptables_commit("filter");
113 err = __connman_iptables_delete_chain("filter", "foo");
116 err = __connman_iptables_commit("filter");
120 static void test_iptables_chain2(void)
124 err = __connman_iptables_change_policy("filter", "INPUT", "DROP");
127 err = __connman_iptables_commit("filter");
130 err = __connman_iptables_change_policy("filter", "INPUT", "ACCEPT");
133 err = __connman_iptables_commit("filter");
137 static void test_iptables_chain3(void)
141 err = __connman_iptables_new_chain("filter", "user-chain-0");
144 err = __connman_iptables_commit("filter");
147 assert_rule_exists("filter", ":user-chain-0 - [0:0]");
149 err = __connman_iptables_new_chain("filter", "user-chain-1");
152 err = __connman_iptables_commit("filter");
155 assert_rule_exists("filter", ":user-chain-0 - [0:0]");
156 assert_rule_exists("filter", ":user-chain-1 - [0:0]");
158 err = __connman_iptables_delete_chain("filter", "user-chain-1");
161 err = __connman_iptables_commit("filter");
164 assert_rule_exists("filter", ":user-chain-0 - [0:0]");
165 assert_rule_not_exists("filter", ":user-chain-1 - [0:0]");
167 err = __connman_iptables_delete_chain("filter", "user-chain-0");
170 err = __connman_iptables_commit("filter");
173 assert_rule_not_exists("filter", ":user-chain-0 - [0:0]");
176 static void test_iptables_rule0(void)
180 /* Test simple appending and removing a rule */
182 err = __connman_iptables_append("filter", "INPUT",
183 "-m mark --mark 1 -j LOG");
186 err = __connman_iptables_commit("filter");
189 assert_rule_exists("filter",
190 "-A INPUT -m mark --mark 0x1 -j LOG");
192 err = __connman_iptables_delete("filter", "INPUT",
193 "-m mark --mark 1 -j LOG");
196 err = __connman_iptables_commit("filter");
199 assert_rule_not_exists("filter",
200 "-A INPUT -m mark --mark 0x1 -j LOG");
203 static void test_iptables_rule1(void)
207 /* Test if we can do NAT stuff */
209 err = __connman_iptables_append("nat", "POSTROUTING",
210 "-s 10.10.1.0/24 -o eth0 -j MASQUERADE");
212 err = __connman_iptables_commit("nat");
215 assert_rule_exists("nat",
216 "-A POSTROUTING -s 10.10.1.0/24 -o eth0 -j MASQUERADE");
218 err = __connman_iptables_delete("nat", "POSTROUTING",
219 "-s 10.10.1.0/24 -o eth0 -j MASQUERADE");
221 err = __connman_iptables_commit("nat");
224 assert_rule_not_exists("nat",
225 "-A POSTROUTING -s 10.10.1.0/24 -o eth0 -j MASQUERADE");
228 static void test_iptables_rule2(void)
232 /* Test if the right rule is removed */
234 err = __connman_iptables_append("filter", "INPUT",
235 "-m mark --mark 1 -j LOG");
238 err = __connman_iptables_commit("filter");
241 assert_rule_exists("filter",
242 "-A INPUT -m mark --mark 0x1 -j LOG");
244 err = __connman_iptables_append("filter", "INPUT",
245 "-m mark --mark 2 -j LOG");
248 err = __connman_iptables_commit("filter");
251 assert_rule_exists("filter",
252 "-A INPUT -m mark --mark 0x1 -j LOG");
253 assert_rule_exists("filter",
254 "-A INPUT -m mark --mark 0x2 -j LOG");
256 err = __connman_iptables_delete("filter", "INPUT",
257 "-m mark --mark 2 -j LOG");
260 err = __connman_iptables_commit("filter");
263 assert_rule_exists("filter",
264 "-A INPUT -m mark --mark 0x1 -j LOG");
265 assert_rule_not_exists("filter",
266 "-A INPUT -m mark --mark 0x2 -j LOG");
268 err = __connman_iptables_delete("filter", "INPUT",
269 "-m mark --mark 1 -j LOG");
272 err = __connman_iptables_commit("filter");
275 assert_rule_not_exists("filter",
276 "-A INPUT -m mark --mark 0x1 -j LOG");
279 static void test_iptables_target0(void)
283 /* Test if 'fallthrough' targets work */
285 err = __connman_iptables_append("filter", "INPUT",
289 err = __connman_iptables_append("filter", "INPUT",
293 err = __connman_iptables_commit("filter");
296 assert_rule_exists("filter", "-A INPUT -m mark --mark 0x1");
297 assert_rule_exists("filter", "-A INPUT -m mark --mark 0x2");
299 err = __connman_iptables_delete("filter", "INPUT",
303 err = __connman_iptables_commit("filter");
306 err = __connman_iptables_delete("filter", "INPUT",
310 err = __connman_iptables_commit("filter");
313 assert_rule_not_exists("filter", "-A INPUT -m mark --mark 0x1");
314 assert_rule_not_exists("filter", "-A INPUT -m mark --mark 0x2");
317 struct connman_notifier *nat_notifier;
319 struct connman_service {
323 char *connman_service_get_interface(struct connman_service *service)
328 int connman_notifier_register(struct connman_notifier *notifier)
330 nat_notifier = notifier;
335 void connman_notifier_unregister(struct connman_notifier *notifier)
340 static void test_nat_basic0(void)
344 err = __connman_nat_enable("bridge", "192.168.2.1", 24);
347 /* test that table is empty */
348 err = __connman_iptables_append("nat", "POSTROUTING",
349 "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
352 err = __connman_iptables_commit("nat");
355 assert_rule_exists("nat",
356 "-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE");
358 err = __connman_iptables_delete("nat", "POSTROUTING",
359 "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
362 err = __connman_iptables_commit("nat");
365 assert_rule_not_exists("nat",
366 "-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE");
368 __connman_nat_disable("bridge");
371 static void test_nat_basic1(void)
373 struct connman_service *service;
376 service = g_try_new0(struct connman_service, 1);
379 nat_notifier->default_changed(service);
381 err = __connman_nat_enable("bridge", "192.168.2.1", 24);
384 /* test that table is not empty */
385 err = __connman_iptables_append("nat", "POSTROUTING",
386 "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
389 err = __connman_iptables_commit("nat");
392 __connman_nat_disable("bridge");
394 /* test that table is empty again */
395 err = __connman_iptables_delete("nat", "POSTROUTING",
396 "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
399 err = __connman_iptables_commit("nat");
405 static void test_firewall_basic0(void)
407 struct firewall_context *ctx;
410 ctx = __connman_firewall_create();
413 err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
414 "-m mark --mark 999 -j LOG");
417 err = __connman_firewall_enable(ctx);
420 assert_rule_exists("filter", ":connman-INPUT - [0:0]");
421 assert_rule_exists("filter", "-A INPUT -j connman-INPUT");
422 assert_rule_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j LOG");
424 err = __connman_firewall_disable(ctx);
427 assert_rule_not_exists("filter", ":connman-INPUT - [0:0]");
428 assert_rule_not_exists("filter", "-A INPUT -j connman-INPUT");
429 assert_rule_not_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j LOG");
431 __connman_firewall_destroy(ctx);
434 static void test_firewall_basic1(void)
436 struct firewall_context *ctx;
439 ctx = __connman_firewall_create();
442 err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
443 "-m mark --mark 999 -j LOG");
446 err = __connman_firewall_add_rule(ctx, "filter", "OUTPUT",
447 "-m mark --mark 999 -j LOG");
450 err = __connman_firewall_enable(ctx);
453 err = __connman_firewall_disable(ctx);
456 __connman_firewall_destroy(ctx);
459 static void test_firewall_basic2(void)
461 struct firewall_context *ctx;
464 ctx = __connman_firewall_create();
467 err = __connman_firewall_add_rule(ctx, "mangle", "INPUT",
468 "-j CONNMARK --restore-mark");
471 err = __connman_firewall_add_rule(ctx, "mangle", "POSTROUTING",
472 "-j CONNMARK --save-mark");
475 err = __connman_firewall_enable(ctx);
478 err = __connman_firewall_disable(ctx);
481 __connman_firewall_destroy(ctx);
484 static gchar *option_debug = NULL;
486 static bool parse_debug(const char *key, const char *value,
487 gpointer user_data, GError **error)
490 option_debug = g_strdup(value);
492 option_debug = g_strdup("*");
497 static GOptionEntry options[] = {
498 { "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG,
499 G_OPTION_ARG_CALLBACK, parse_debug,
500 "Specify debug options to enable", "DEBUG" },
504 int main(int argc, char *argv[])
506 GOptionContext *context;
507 GError *error = NULL;
510 g_test_init(&argc, &argv, NULL);
512 context = g_option_context_new(NULL);
513 g_option_context_add_main_entries(context, options, NULL);
515 if (!g_option_context_parse(context, &argc, &argv, &error)) {
517 g_printerr("%s\n", error->message);
520 g_printerr("An unknown error occurred\n");
524 g_option_context_free(context);
526 __connman_log_init(argv[0], option_debug, false, false,
527 "Unit Tests Connection Manager", VERSION);
529 __connman_iptables_init();
530 __connman_firewall_init();
531 __connman_nat_init();
533 g_test_add_func("/iptables/chain0", test_iptables_chain0);
534 g_test_add_func("/iptables/chain1", test_iptables_chain1);
535 g_test_add_func("/iptables/chain2", test_iptables_chain2);
536 g_test_add_func("/iptables/chain3", test_iptables_chain3);
537 g_test_add_func("/iptables/rule0", test_iptables_rule0);
538 g_test_add_func("/iptables/rule1", test_iptables_rule1);
539 g_test_add_func("/iptables/rule2", test_iptables_rule2);
540 g_test_add_func("/iptables/target0", test_iptables_target0);
541 g_test_add_func("/nat/basic0", test_nat_basic0);
542 g_test_add_func("/nat/basic1", test_nat_basic1);
543 g_test_add_func("/firewall/basic0", test_firewall_basic0);
544 g_test_add_func("/firewall/basic1", test_firewall_basic1);
545 g_test_add_func("/firewall/basic2", test_firewall_basic2);
549 __connman_nat_cleanup();
550 __connman_firewall_cleanup();
551 __connman_iptables_cleanup();
553 g_free(option_debug);