summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2010-10-26 00:24:30 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2010-10-26 00:26:14 +0200
commitb034a0686435b9f6f6f79d34924480ca2f3e68e9 (patch)
tree62be878c475aa7f012a56bbf2d24f3660b253cac /tools
parent09bbe2bde426efe3608cd72cdaf3d7414e434c3c (diff)
downloadconnman-b034a0686435b9f6f6f79d34924480ca2f3e68e9.tar.gz
connman-b034a0686435b9f6f6f79d34924480ca2f3e68e9.tar.bz2
connman-b034a0686435b9f6f6f79d34924480ca2f3e68e9.zip
iptables-test: Parse targets and matches options
The target and matches parsing routine allow for a proper xtable structure building. Those structures then allow for an easier rule building.
Diffstat (limited to 'tools')
-rw-r--r--tools/iptables-test.c129
1 files changed, 91 insertions, 38 deletions
diff --git a/tools/iptables-test.c b/tools/iptables-test.c
index c4796185..9df04345 100644
--- a/tools/iptables-test.c
+++ b/tools/iptables-test.c
@@ -313,24 +313,18 @@ err:
}
static struct ipt_entry *
-new_builtin_rule(char *target_name,
- char *match_name, int match_argc, char **match_argv)
+new_builtin_rule(char *target_name, struct xtables_match *xt_m)
{
struct ipt_entry *new_entry;
size_t match_size, target_size;
- struct xtables_match *xt_m;
+ struct xt_entry_match *entry_match;
struct xt_standard_target *target;
- xt_m = NULL;
- match_size = 0;
-
- if (match_name) {
- xt_m = xtables_find_match(match_name, XTF_TRY_LOAD, NULL);
- if (xt_m == NULL)
- return NULL;
- match_size = ALIGN(sizeof(struct xt_entry_match)) + xt_m->size;
- }
+ if (xt_m)
+ match_size = xt_m->m->u.match_size;
+ else
+ match_size = 0;
target_size = ALIGN(sizeof(struct xt_standard_target));
@@ -344,14 +338,8 @@ new_builtin_rule(char *target_name,
match_size;
if (xt_m) {
- struct xt_entry_match *entry_match;
-
entry_match = (struct xt_entry_match *)new_entry->elems;
- entry_match->u.match_size = match_size;
- strcpy(entry_match->u.user.name, xt_m->name);
- entry_match->u.user.revision = xt_m->revision;
- if (xt_m->init != NULL)
- xt_m->init(entry_match);
+ memcpy(entry_match, xt_m->m, match_size);
}
target = (struct xt_standard_target *)(new_entry->elems + match_size);
@@ -364,33 +352,29 @@ new_builtin_rule(char *target_name,
}
static struct ipt_entry *
-new_custom_rule(char *target_name, int target_argc, char **target_argv,
- char *match_name, int match_argc, char **match_argv)
+new_custom_rule(struct xtables_target *xt_t, struct xtables_match *xt_m)
{
return NULL;
}
static struct ipt_entry *
-new_rule(char *target_name, int target_argc, char **target_argv,
- char *match_name, int match_argc, char **match_argv)
+new_rule(char *target_name, struct xtables_target *xt_t,
+ char *match_name, struct xtables_match *xt_m)
{
struct ipt_entry *new_entry;
if (is_builtin_target(target_name))
- new_entry = new_builtin_rule(target_name,
- match_name, match_argc, match_argv);
+ new_entry = new_builtin_rule(target_name, xt_m);
else
- new_entry = new_custom_rule(target_name,
- target_argc, target_argv,
- match_name, match_argc, match_argv);
+ new_entry = new_custom_rule(xt_t, xt_m);
return new_entry;
}
static int
connman_iptables_add_rule(struct connman_iptables *table, char *chain_name,
- char *target_name, int target_argc, char **target_argv,
- char *match_name, int match_argc, char **match_argv)
+ char *target_name, struct xtables_target *xt_t,
+ char *match_name, struct xtables_match *xt_m)
{
GList *chain_tail;
struct ipt_entry *new_entry;
@@ -399,8 +383,8 @@ connman_iptables_add_rule(struct connman_iptables *table, char *chain_name,
if (chain_tail == NULL)
return -EINVAL;
- new_entry = new_rule(target_name, target_argc, target_argv,
- match_name, match_argc, match_argv);
+ new_entry = new_rule(target_name, xt_t,
+ match_name, xt_m);
if (new_entry == NULL)
return -EINVAL;
@@ -615,6 +599,8 @@ static void connman_iptables_cleanup(struct connman_iptables *table)
g_free(table->info);
g_free(table->blob_entries);
g_free(table);
+
+ xtables_free_opts(1);
}
static int connman_iptables_commit(struct connman_iptables *table)
@@ -696,21 +682,32 @@ static struct option connman_iptables_opts[] = {
{NULL},
};
+struct xtables_globals connman_iptables_globals = {
+ .option_offset = 0,
+ .opts = connman_iptables_opts,
+ .orig_opts = connman_iptables_opts,
+};
+
int main(int argc, char *argv[])
{
struct connman_iptables *table;
+ struct xtables_match *xt_m;
+ struct xtables_target *xt_t;
char *table_name, *chain, *new_chain, *match_name, *target_name;
int c;
+ size_t size;
gboolean dump;
- xtables_init();
- xtables_set_nfproto(NFPROTO_IPV4);
+ xtables_init_all(&connman_iptables_globals, NFPROTO_IPV4);
dump = FALSE;
table_name = chain = new_chain = match_name = target_name = NULL;
+ table = NULL;
+ xt_m = NULL;
+ xt_t = NULL;
while ((c = getopt_long(argc, argv,
- "-A:L::N:j:i:m:o:t:", connman_iptables_opts, NULL)) != -1) {
+ "-A:L::N:j:i:m:o:t:", connman_iptables_globals.opts, NULL)) != -1) {
switch (c) {
case 'A':
chain = optarg;
@@ -726,6 +723,28 @@ int main(int argc, char *argv[])
case 'j':
target_name = optarg;
+ xt_t = xtables_find_target(target_name, XTF_TRY_LOAD);
+
+ if (xt_t == NULL)
+ break;
+
+ size = ALIGN(sizeof(struct ipt_entry_target)) + xt_t->size;
+
+ xt_t->t = g_try_malloc0(size);
+ if (xt_t->t == NULL)
+ goto out;
+ xt_t->t->u.target_size = size;
+ strcpy(xt_t->t->u.user.name, target_name);
+ xt_t->t->u.user.revision = xt_t->revision;
+ if (xt_t->init != NULL)
+ xt_t->init(xt_t->t);
+ connman_iptables_globals.opts =
+ xtables_merge_options(connman_iptables_globals.opts,
+ xt_t->extra_opts,
+ &xt_t->option_offset);
+ if (connman_iptables_globals.opts == NULL)
+ goto out;
+
break;
case 'i':
@@ -733,6 +752,26 @@ int main(int argc, char *argv[])
case 'm':
match_name = optarg;
+
+ xt_m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, NULL);
+ size = ALIGN(sizeof(struct ipt_entry_match)) + xt_m->size;
+ xt_m->m = g_try_malloc0(size);
+ if (xt_m == NULL)
+ goto out;
+ xt_m->m->u.match_size = size;
+ strcpy(xt_m->m->u.user.name, xt_m->name);
+ xt_m->m->u.user.revision = xt_m->revision;
+ if (xt_m->init != NULL)
+ xt_m->init(xt_m->m);
+ if (xt_m != xt_m->next) {
+ connman_iptables_globals.opts =
+ xtables_merge_options(connman_iptables_globals.opts,
+ xt_m->extra_opts,
+ &xt_m->option_offset);
+ if (connman_iptables_globals.opts == NULL)
+ goto out;
+ }
+
break;
case 'o':
@@ -743,8 +782,15 @@ int main(int argc, char *argv[])
break;
default:
- printf("default %s\n", optarg);
+ if (xt_t == NULL || xt_t->parse == NULL ||
+ !xt_t->parse(c - xt_t->option_offset, argv, 0, &xt_t->tflags, NULL, &xt_t->t)) {
+ if (xt_m == NULL || xt_m->parse == NULL)
+ break;
+ xt_m->parse(c - xt_m->option_offset, argv, 0, &xt_m->mflags, NULL, &xt_m->m);
+ }
+
+ break;
}
}
@@ -779,8 +825,8 @@ int main(int argc, char *argv[])
printf("Adding %s to %s (match %s)\n", target_name, chain, match_name);
connman_iptables_add_rule(table, chain,
- target_name, 0, NULL,
- match_name, 0, NULL);
+ target_name, xt_t,
+ match_name, xt_m);
goto commit;
}
@@ -789,7 +835,14 @@ commit:
connman_iptables_commit(table);
+out:
connman_iptables_cleanup(table);
+ if (xt_t)
+ g_free(xt_t->t);
+
+ if (xt_m)
+ g_free(xt_m->m);
+
return 0;
}