Imported Upstream version 1.26
[platform/upstream/connman.git] / tools / iptables-unit.c
index 49b05e0..7e427e2 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  Connection Manager
  *
- *  Copyright (C) 2013  BWM CarIT GmbH. All rights reserved.
+ *  Copyright (C) 2013-2014  BMW Car IT GmbH.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
 
 #include "../src/connman.h"
 
+static bool assert_rule(const char *table_name, const char *rule)
+{
+       char *cmd, *output, **lines;
+       GError **error = NULL;
+       int i;
+
+       cmd = g_strdup_printf(IPTABLES_SAVE " -t %s", table_name);
+       g_spawn_command_line_sync(cmd, &output, NULL, NULL, error);
+       g_free(cmd);
+
+       lines = g_strsplit(output, "\n", 0);
+       g_free(output);
+
+       for (i = 0; lines[i]; i++) {
+               DBG("lines[%02d]: %s\n", i, lines[i]);
+               if (g_strcmp0(lines[i], rule) == 0)
+                       break;
+       }
+       g_strfreev(lines);
+
+       if (!lines[i])
+               return false;
+
+       return true;
+}
+
+static void assert_rule_exists(const char *table_name, const char *rule)
+{
+       if (g_strcmp0(IPTABLES_SAVE, "") == 0) {
+               DBG("iptables-save is missing, no assertion possible");
+               return;
+       }
+
+       g_assert(assert_rule(table_name, rule));
+}
+
+static void assert_rule_not_exists(const char *table_name, const char *rule)
+{
+       if (g_strcmp0(IPTABLES_SAVE, "") == 0) {
+               DBG("iptables-save is missing, no assertion possible");
+               return;
+       }
+
+       g_assert(!assert_rule(table_name, rule));
+}
+
 static void test_iptables_chain0(void)
 {
        int err;
@@ -37,11 +83,15 @@ static void test_iptables_chain0(void)
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter", ":foo - [0:0]");
+
        err = __connman_iptables_delete_chain("filter", "foo");
        g_assert(err == 0);
 
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
+
+       assert_rule_not_exists("filter", ":foo - [0:0]");
 }
 
 static void test_iptables_chain1(void)
@@ -94,23 +144,33 @@ static void test_iptables_chain3(void)
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter", ":user-chain-0 - [0:0]");
+
        err = __connman_iptables_new_chain("filter", "user-chain-1");
        g_assert(err == 0);
 
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter", ":user-chain-0 - [0:0]");
+       assert_rule_exists("filter", ":user-chain-1 - [0:0]");
+
        err = __connman_iptables_delete_chain("filter", "user-chain-1");
        g_assert(err == 0);
 
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter", ":user-chain-0 - [0:0]");
+       assert_rule_not_exists("filter", ":user-chain-1 - [0:0]");
+
        err = __connman_iptables_delete_chain("filter", "user-chain-0");
        g_assert(err == 0);
 
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
+
+       assert_rule_not_exists("filter", ":user-chain-0 - [0:0]");
 }
 
 static void test_iptables_rule0(void)
@@ -126,14 +186,19 @@ static void test_iptables_rule0(void)
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter",
+                               "-A INPUT -m mark --mark 0x1 -j LOG");
+
        err = __connman_iptables_delete("filter", "INPUT",
                                        "-m mark --mark 1 -j LOG");
        g_assert(err == 0);
 
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
-}
 
+       assert_rule_not_exists("filter",
+                               "-A INPUT -m mark --mark 0x1 -j LOG");
+}
 
 static void test_iptables_rule1(void)
 {
@@ -147,11 +212,17 @@ static void test_iptables_rule1(void)
        err = __connman_iptables_commit("nat");
        g_assert(err == 0);
 
+       assert_rule_exists("nat",
+               "-A POSTROUTING -s 10.10.1.0/24 -o eth0 -j MASQUERADE");
+
        err = __connman_iptables_delete("nat", "POSTROUTING",
                                "-s 10.10.1.0/24 -o eth0 -j MASQUERADE");
 
        err = __connman_iptables_commit("nat");
        g_assert(err == 0);
+
+       assert_rule_not_exists("nat",
+               "-A POSTROUTING -s 10.10.1.0/24 -o eth0 -j MASQUERADE");
 }
 
 static void test_iptables_rule2(void)
@@ -167,6 +238,9 @@ static void test_iptables_rule2(void)
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter",
+                               "-A INPUT -m mark --mark 0x1 -j LOG");
+
        err = __connman_iptables_append("filter", "INPUT",
                                        "-m mark --mark 2 -j LOG");
        g_assert(err == 0);
@@ -174,6 +248,11 @@ static void test_iptables_rule2(void)
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter",
+                               "-A INPUT -m mark --mark 0x1 -j LOG");
+       assert_rule_exists("filter",
+                               "-A INPUT -m mark --mark 0x2 -j LOG");
+
        err = __connman_iptables_delete("filter", "INPUT",
                                        "-m mark --mark 2 -j LOG");
        g_assert(err == 0);
@@ -181,12 +260,20 @@ static void test_iptables_rule2(void)
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter",
+                               "-A INPUT -m mark --mark 0x1 -j LOG");
+       assert_rule_not_exists("filter",
+                               "-A INPUT -m mark --mark 0x2 -j LOG");
+
        err = __connman_iptables_delete("filter", "INPUT",
                                        "-m mark --mark 1 -j LOG");
        g_assert(err == 0);
 
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
+
+       assert_rule_not_exists("filter",
+                               "-A INPUT -m mark --mark 0x1 -j LOG");
 }
 
 static void test_iptables_target0(void)
@@ -206,6 +293,9 @@ static void test_iptables_target0(void)
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
 
+       assert_rule_exists("filter", "-A INPUT -m mark --mark 0x1");
+       assert_rule_exists("filter", "-A INPUT -m mark --mark 0x2");
+
        err = __connman_iptables_delete("filter", "INPUT",
                                        "-m mark --mark 1");
        g_assert(err == 0);
@@ -219,6 +309,9 @@ static void test_iptables_target0(void)
 
        err = __connman_iptables_commit("filter");
        g_assert(err == 0);
+
+       assert_rule_not_exists("filter", "-A INPUT -m mark --mark 0x1");
+       assert_rule_not_exists("filter", "-A INPUT -m mark --mark 0x2");
 }
 
 struct connman_notifier *nat_notifier;
@@ -259,6 +352,19 @@ static void test_nat_basic0(void)
        err = __connman_iptables_commit("nat");
        g_assert(err == 0);
 
+       assert_rule_exists("nat",
+               "-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE");
+
+       err = __connman_iptables_delete("nat", "POSTROUTING",
+                                       "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
+       g_assert(err == 0);
+
+       err = __connman_iptables_commit("nat");
+       g_assert(err == 0);
+
+       assert_rule_not_exists("nat",
+               "-A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE");
+
        __connman_nat_disable("bridge");
 }
 
@@ -296,9 +402,88 @@ static void test_nat_basic1(void)
        g_free(service);
 }
 
+static void test_firewall_basic0(void)
+{
+       struct firewall_context *ctx;
+       int err;
+
+       ctx = __connman_firewall_create();
+       g_assert(ctx);
+
+       err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
+                                       "-m mark --mark 999 -j LOG");
+       g_assert(err == 0);
+
+       err = __connman_firewall_enable(ctx);
+       g_assert(err == 0);
+
+       assert_rule_exists("filter", ":connman-INPUT - [0:0]");
+       assert_rule_exists("filter", "-A INPUT -j connman-INPUT");
+       assert_rule_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j LOG");
+
+       err = __connman_firewall_disable(ctx);
+       g_assert(err == 0);
+
+       assert_rule_not_exists("filter", ":connman-INPUT - [0:0]");
+       assert_rule_not_exists("filter", "-A INPUT -j connman-INPUT");
+       assert_rule_not_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j LOG");
+
+       __connman_firewall_destroy(ctx);
+}
+
+static void test_firewall_basic1(void)
+{
+       struct firewall_context *ctx;
+       int err;
+
+       ctx = __connman_firewall_create();
+       g_assert(ctx);
+
+       err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
+                                       "-m mark --mark 999 -j LOG");
+       g_assert(err == 0);
+
+       err = __connman_firewall_add_rule(ctx, "filter", "OUTPUT",
+                                       "-m mark --mark 999 -j LOG");
+       g_assert(err == 0);
+
+       err = __connman_firewall_enable(ctx);
+       g_assert(err == 0);
+
+       err = __connman_firewall_disable(ctx);
+       g_assert(err == 0);
+
+       __connman_firewall_destroy(ctx);
+}
+
+static void test_firewall_basic2(void)
+{
+       struct firewall_context *ctx;
+       int err;
+
+       ctx = __connman_firewall_create();
+       g_assert(ctx);
+
+       err = __connman_firewall_add_rule(ctx, "mangle", "INPUT",
+                                       "-j CONNMARK --restore-mark");
+       g_assert(err == 0);
+
+       err = __connman_firewall_add_rule(ctx, "mangle", "POSTROUTING",
+                                       "-j CONNMARK --save-mark");
+       g_assert(err == 0);
+
+       err = __connman_firewall_enable(ctx);
+       g_assert(err == 0);
+
+       err = __connman_firewall_disable(ctx);
+       g_assert(err == 0);
+
+       __connman_firewall_destroy(ctx);
+}
+
 static gchar *option_debug = NULL;
 
-static gboolean parse_debug(const char *key, const char *value,
+static bool parse_debug(const char *key, const char *value,
                                        gpointer user_data, GError **error)
 {
        if (value)
@@ -306,7 +491,7 @@ static gboolean parse_debug(const char *key, const char *value,
        else
                option_debug = g_strdup("*");
 
-       return TRUE;
+       return true;
 }
 
 static GOptionEntry options[] = {
@@ -327,8 +512,8 @@ int main(int argc, char *argv[])
        context = g_option_context_new(NULL);
        g_option_context_add_main_entries(context, options, NULL);
 
-       if (g_option_context_parse(context, &argc, &argv, &error) == FALSE) {
-               if (error != NULL) {
+       if (!g_option_context_parse(context, &argc, &argv, &error)) {
+               if (error) {
                        g_printerr("%s\n", error->message);
                        g_error_free(error);
                } else
@@ -338,10 +523,11 @@ int main(int argc, char *argv[])
 
        g_option_context_free(context);
 
-       __connman_log_init(argv[0], option_debug, FALSE, FALSE,
+       __connman_log_init(argv[0], option_debug, false, false,
                        "Unit Tests Connection Manager", VERSION);
 
        __connman_iptables_init();
+       __connman_firewall_init();
        __connman_nat_init();
 
        g_test_add_func("/iptables/chain0", test_iptables_chain0);
@@ -354,10 +540,14 @@ int main(int argc, char *argv[])
        g_test_add_func("/iptables/target0", test_iptables_target0);
        g_test_add_func("/nat/basic0", test_nat_basic0);
        g_test_add_func("/nat/basic1", test_nat_basic1);
+       g_test_add_func("/firewall/basic0", test_firewall_basic0);
+       g_test_add_func("/firewall/basic1", test_firewall_basic1);
+       g_test_add_func("/firewall/basic2", test_firewall_basic2);
 
        err = g_test_run();
 
        __connman_nat_cleanup();
+       __connman_firewall_cleanup();
        __connman_iptables_cleanup();
 
        g_free(option_debug);