From: Daniel Wagner <[email protected]>
This helpers allow to add a bunch of iptables rules together into
a set and then apply them in a 'atomic' way. Unfortunatly, it is
not garanteed to be completely automic but way better then having
several places trying to get this right.
---
Makefile.am | 2 +-
src/connman.h | 11 ++++
src/iptctx.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 203 insertions(+), 1 deletion(-)
create mode 100644 src/iptctx.c
diff --git a/Makefile.am b/Makefile.am
index cd69b56..e9aa95a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -97,7 +97,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources)
$(gweb_sources) \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \
src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \
- src/inotify.c
+ src/inotify.c src/iptctx.c
src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
@XTABLES_LIBS@ @GNUTLS_LIBS@ -lresolv -ldl -lrt
diff --git a/src/connman.h b/src/connman.h
index 6c3c22c..df24f1e 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -790,6 +790,17 @@ int __connman_stats_get(struct connman_service *service,
connman_bool_t roaming,
struct connman_stats_data *data);
+struct iptables_context;
+
+struct iptables_context *__connman_iptctx_create(void);
+void __connman_iptctx_destroy(struct iptables_context *ctx);
+int __connman_iptctx_add_rule(struct iptables_context *ctx,
+ const char *table,
+ const char *chain,
+ const char *rule_fmt, ...);
+int __connman_iptctx_enable(struct iptables_context *ctx);
+int __connman_iptctx_disable(struct iptables_context *ctx);
+
int __connman_iptables_new_chain(const char *table_name,
const char *chain);
int __connman_iptables_delete_chain(const char *table_name,
diff --git a/src/iptctx.c b/src/iptctx.c
new file mode 100644
index 0000000..903deb7
--- /dev/null
+++ b/src/iptctx.c
@@ -0,0 +1,191 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2013 BMW Car IT GmbH. All rights reserved.
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+
+#include "connman.h"
+
+struct xt_rule {
+ char *table;
+ char *chain;
+ char *rule_spec;
+};
+
+struct iptables_context {
+ GList *rules;
+};
+
+static void cleanup_xt_rule(gpointer user_data)
+{
+ struct xt_rule *rule = user_data;
+
+ g_free(rule->rule_spec);
+ g_free(rule->chain);
+ g_free(rule->table);
+ g_free(rule);
+}
+
+struct iptables_context *__connman_iptctx_create(void)
+{
+ struct iptables_context *ctx;
+
+ ctx = g_try_new0(struct iptables_context, 1);
+ if (ctx == NULL)
+ return NULL;
+
+ return ctx;
+}
+
+void __connman_iptctx_destroy(struct iptables_context *ctx)
+{
+ g_list_free_full(ctx->rules, cleanup_xt_rule);
+ g_free(ctx);
+}
+
+int __connman_iptctx_add_rule(struct iptables_context *ctx,
+ const char *table,
+ const char *chain,
+ const char *rule_fmt, ...)
+{
+ va_list args;
+ char *rule_spec;
+ struct xt_rule *rule;
+
+ va_start(args, rule_fmt);
+
+ rule_spec = g_strdup_vprintf(rule_fmt, args);
+
+ va_end(args);
+
+ if (rule_spec == NULL)
+ return -ENOMEM;
+
+ rule = g_try_new0(struct xt_rule, 1);
+ if (rule == NULL) {
+ g_free(rule_spec);
+ return -ENOMEM;
+ }
+
+ rule->table = g_strdup(table);
+ rule->chain = g_strdup(chain);
+ rule->rule_spec = rule_spec;
+
+ ctx->rules = g_list_append(ctx->rules, rule);
+
+ return 0;
+}
+
+int __connman_iptctx_enable(struct iptables_context *ctx)
+{
+ struct xt_rule *rule;
+ GList *list;
+ int err, err1;
+
+ for (list = g_list_first(ctx->rules); list != NULL;
+ list = g_list_next(list)) {
+ rule = list->data;
+
+ DBG("%s %s %s", rule->table, rule->chain, rule->rule_spec);
+
+ err = __connman_iptables_managed_append(rule->table,
+ rule->chain,
+ rule->rule_spec);
+ if (err < 0)
+ goto err;
+
+ err = __connman_iptables_commit(rule->table);
+ if (err < 0)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ connman_warn("Failed to install iptables rules: %s", strerror(-err));
+
+ for (list = g_list_previous(list); list != NULL;
+ list = g_list_previous(list)) {
+ rule = list->data;
+
+ err1 = __connman_iptables_managed_delete(rule->table,
+ rule->chain,
+ rule->rule_spec);
+ if (err1 < 0) {
+ /* Now what shall we do? */
+ connman_error("Cannot remove previously installed "
+ "iptables rules: %s", strerror(-err1));
+ }
+
+
+ err1 = __connman_iptables_commit(rule->table);
+ if (err1 < 0) {
+ /* Now what shall we do? */
+ connman_error("Cannot remove previously installed "
+ "iptables rules: %s", strerror(-err1));
+ }
+ }
+
+ return err;
+}
+
+int __connman_iptctx_disable(struct iptables_context *ctx)
+{
+ struct xt_rule *rule;
+ GList *list;
+ int err = 0;
+
+ for (list = g_list_last(ctx->rules); list != NULL;
+ list = g_list_previous(list)) {
+ rule = list->data;
+
+ DBG("%s %s %s", rule->table, rule->chain, rule->rule_spec);
+
+ err = __connman_iptables_managed_delete(rule->table,
+ rule->chain,
+ rule->rule_spec);
+ if (err < 0) {
+ /* Now what shall we do? */
+ connman_error("Cannot remove previously installed "
+ "iptables rules: %s", strerror(-err));
+ break;
+ }
+
+
+ err = __connman_iptables_commit(rule->table);
+ if (err < 0) {
+ /* Now what shall we do? */
+ connman_error("Cannot remove previously installed "
+ "iptables rules: %s", strerror(-err));
+ break;
+ }
+ }
+
+ return err;
+}
--
1.8.1.3.566.gaa39828
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman