/*
* Connection Manager
*
- * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2013 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 <stdlib.h>
+#include <getopt.h>
#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/errno.h>
-#include <libiptc/libiptc.h>
-#include <libiptc/libip6tc.h>
-#include <xtables.h>
-
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter/xt_quota.h>
-
-static void print_match(const struct ipt_entry *e)
-{
- struct xt_entry_match *match;
- struct xtables_match *xt_match;
-
- match = (struct xt_entry_match *)e->elems;
- if (match == NULL)
- return;
-
- xt_match = xtables_find_match(match->u.user.name, XTF_TRY_LOAD, NULL);
- if (xt_match == NULL)
- return;
-
- printf("\tMATCH:%s\n", xt_match->m->u.user.name);
-}
-
-static void print_target(const struct ipt_entry *e)
-{
- struct xt_entry_target *target;
- struct xtables_target *xt_target;
-
- target = (void *)e + e->target_offset;
- if (target == NULL)
- return;
-
- xt_target = xtables_find_target(target->u.user.name, XTF_TRY_LOAD);
- if (xt_target == NULL)
- return;
-
- printf("\tTARGET: %s\n", xt_target->t->u.user.name);
-}
+#include <stdlib.h>
+#include <errno.h>
+#include <glib.h>
-static void print_rule(const struct ipt_entry *e, const char *chain)
-{
- /* print chain name */
- printf("CHAIN %s:\n", chain);
+#include "../src/connman.h"
- print_match(e);
- print_target(e);
-}
+enum iptables_command {
+ IPTABLES_COMMAND_APPEND,
+ IPTABLES_COMMAND_INSERT,
+ IPTABLES_COMMAND_DELETE,
+ IPTABLES_COMMAND_POLICY,
+ IPTABLES_COMMAND_CHAIN_INSERT,
+ IPTABLES_COMMAND_CHAIN_DELETE,
+ IPTABLES_COMMAND_CHAIN_FLUSH,
+ IPTABLES_COMMAND_DUMP,
+ IPTABLES_COMMAND_UNKNOWN,
+};
-static void print_tables(struct iptc_handle *h)
+int main(int argc, char *argv[])
{
- const char *chain;
- const struct ipt_entry *rule;
-
- chain = iptc_first_chain(h);
-
- while(chain) {
- rule = iptc_first_rule(chain, h);
- while (rule) {
- print_rule(rule, chain);
-
- rule = iptc_next_rule(rule, h);
+ enum iptables_command cmd = IPTABLES_COMMAND_UNKNOWN;
+ char *table = NULL, *chain = NULL, *rule = NULL, *tmp;
+ int err, c, i;
+
+ opterr = 0;
+
+ while ((c = getopt_long(argc, argv,
+ "-A:I:D:P:N:X:F:Lt:", NULL, NULL)) != -1) {
+ switch (c) {
+ case 'A':
+ chain = optarg;
+ cmd = IPTABLES_COMMAND_APPEND;
+ break;
+ case 'I':
+ chain = optarg;
+ cmd = IPTABLES_COMMAND_INSERT;
+ break;
+ case 'D':
+ chain = optarg;
+ cmd = IPTABLES_COMMAND_DELETE;
+ break;
+ case 'P':
+ chain = optarg;
+ /* The policy will be stored in rule. */
+ cmd = IPTABLES_COMMAND_POLICY;
+ break;
+ case 'N':
+ chain = optarg;
+ cmd = IPTABLES_COMMAND_CHAIN_INSERT;
+ break;
+ case 'X':
+ chain = optarg;
+ cmd = IPTABLES_COMMAND_CHAIN_DELETE;
+ break;
+ case 'F':
+ chain = optarg;
+ cmd = IPTABLES_COMMAND_CHAIN_FLUSH;
+ break;
+ case 'L':
+ cmd = IPTABLES_COMMAND_DUMP;
+ break;
+ case 't':
+ table = optarg;
+ break;
+ default:
+ goto out;
}
-
- chain = iptc_next_chain(h);
- }
-}
-
-static struct ipt_entry *build_quota_drop_entry(void)
-{
- struct ipt_entry *e;
- size_t match_size, target_size;
- struct xtables_target *t;
- struct xtables_match *m;
- struct xtables_rule_match *matches = NULL;
-
- m = xtables_find_match("quota", XTF_LOAD_MUST_SUCCEED, &matches);
- if (m == NULL)
- return NULL;
-
- match_size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;
-
- m->m = xtables_calloc(1, match_size);
- if (m->m == NULL)
- return NULL;
- m->m->u.match_size = match_size;
- strcpy(m->m->u.user.name, m->name);
- xtables_set_revision(m->m->u.user.name, m->revision);
- if (m->init != NULL)
- m->init(m->m);
-
- t = xtables_find_target("DROP", XTF_TRY_LOAD);
- if (t == NULL) {
- free(m->m);
- return NULL;
}
- target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + t->size;
-
- t->t = xtables_calloc(1, target_size);
- t->t->u.target_size = target_size;
- strcpy(t->t->u.user.name, "DROP");
- xtables_set_revision(t->t->u.user.name, t->revision);
- if (t->init != NULL)
- t->init(t->t);
-
- e = calloc(1, sizeof(struct ipt_entry) + match_size + target_size);
- if (e == NULL) {
- free(m->m);
- free(t->t);
+out:
+ if (!table)
+ table = "filter";
+
+ for (i = optind - 1; i < argc; i++) {
+ if (rule) {
+ tmp = rule;
+ rule = g_strdup_printf("%s %s", rule, argv[i]);
+ g_free(tmp);
+ } else
+ rule = g_strdup(argv[i]);
}
- e->target_offset = sizeof(struct ipt_entry) + match_size;
- e->next_offset = sizeof(struct ipt_entry) + match_size + target_size;
-
- memcpy(e->elems, m->m, match_size);
- memcpy(e->elems + match_size, t->t, target_size);
-
- return e;
-}
-
-static int add_rule(const ipt_chainlabel chain, struct ipt_entry *e,
- struct iptc_handle *h)
-{
- if (!iptc_create_chain(chain, h)) {
- printf("Chain creation error (%s)\n", iptc_strerror(errno));
- return -1;
+ __connman_iptables_init();
+
+ switch (cmd) {
+ case IPTABLES_COMMAND_APPEND:
+ err = __connman_iptables_append(table, chain, rule);
+ break;
+ case IPTABLES_COMMAND_INSERT:
+ err = __connman_iptables_insert(table, chain, rule);
+ break;
+ case IPTABLES_COMMAND_DELETE:
+ err = __connman_iptables_delete(table, chain, rule);
+ break;
+ case IPTABLES_COMMAND_POLICY:
+ err = __connman_iptables_change_policy(table, chain, rule);
+ break;
+ case IPTABLES_COMMAND_CHAIN_INSERT:
+ err = __connman_iptables_new_chain(table, chain);
+ break;
+ case IPTABLES_COMMAND_CHAIN_DELETE:
+ err = __connman_iptables_delete_chain(table, chain);
+ break;
+ case IPTABLES_COMMAND_CHAIN_FLUSH:
+ err = __connman_iptables_flush_chain(table, chain);
+ break;
+ case IPTABLES_COMMAND_DUMP:
+ __connman_log_init(argv[0], "*", false, false,
+ "iptables-test", "1");
+ err = __connman_iptables_dump(table);
+ break;
+ case IPTABLES_COMMAND_UNKNOWN:
+ printf("Missing command\n");
+ printf("usage: iptables-test [-t table] {-A|-I|-D} chain rule\n");
+ printf(" iptables-test [-t table] {-N|-X|-F} chain\n");
+ printf(" iptables-test [-t table] -L\n");
+ printf(" iptables-test [-t table] -P chain target\n");
+ exit(-EINVAL);
}
- if (!iptc_insert_entry(chain, e, 0, h)) {
- printf("Entry insertion error (%s)\n", iptc_strerror(errno));
- return -1;
+ if (err < 0) {
+ printf("Error: %s\n", strerror(-err));
+ exit(err);
}
- if (!iptc_commit(h)) {
- printf("Commit error (%s)\n", iptc_strerror(errno));
- return -1;
+ err = __connman_iptables_commit(table);
+ if (err < 0) {
+ printf("Failed to commit changes: %s\n", strerror(-err));
+ exit(err);
}
- return 0;
-}
-
-static void remove_rule(const ipt_chainlabel chain, struct iptc_handle *h)
-{
- iptc_flush_entries(chain, h);
- iptc_delete_chain(chain, h);
- iptc_commit(h);
-}
-
-
-int main(int argc, char *argv[])
-{
- struct iptc_handle *h;
- struct ipt_entry *e;
-
- if (argc < 2) {
- printf("Usage: iptables-test [chain-name]\n");
- return -1;
- }
-
- h = iptc_init("filter");
- if (!h) {
- printf("libiptc initialization error (%s)\n",
- iptc_strerror(errno));
- exit(errno);
- }
-
- xtables_init();
- xtables_set_nfproto(NFPROTO_IPV4);
-
- e = build_quota_drop_entry();
- if (e == NULL)
- return -1;
-
- add_rule(argv[1], e, h);
-
- print_tables(h);
+ g_free(rule);
- remove_rule(argv[1], h);
+ __connman_iptables_cleanup();
return 0;
}