From 0cf75aaf19ffd08e7c63fee737423d01343f4cb9 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 26 Sep 2013 18:25:45 +0200
Subject: nfct: modularize extensions

Modularize timeout and helper extensions.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/nfct.h                | 25 +++++++++++--------------
 src/nfct-extensions/helper.c  | 31 +++++++++++++++++++++++--------
 src/nfct-extensions/timeout.c | 20 ++++++++++++++++++--
 src/nfct.c                    | 35 +++++++++++++++++++++++++++++------
 4 files changed, 81 insertions(+), 30 deletions(-)

diff --git a/include/nfct.h b/include/nfct.h
index 5548b03..ddf9038 100644
--- a/include/nfct.h
+++ b/include/nfct.h
@@ -1,6 +1,8 @@
 #ifndef _NFCT_H_
 #define _NFCT_H_
 
+#include "linux_list.h"
+
 enum {
 	NFCT_SUBSYS_NONE = 0,
 	NFCT_SUBSYS_TIMEOUT,
@@ -19,21 +21,16 @@ enum {
 	NFCT_CMD_DISABLE,
 };
 
+#define __init __attribute__((constructor))
+
 void nfct_perror(const char *msg);
 
-int nfct_cmd_timeout_parse_params(int argc, char *argv[]);
-int nfct_cmd_timeout_list(int argc, char *argv[]);
-int nfct_cmd_timeout_add(int argc, char *argv[]);
-int nfct_cmd_timeout_delete(int argc, char *argv[]);
-int nfct_cmd_timeout_get(int argc, char *argv[]);
-int nfct_cmd_timeout_flush(int argc, char *argv[]);
-
-int nfct_cmd_helper_parse_params(int argc, char *argv[]);
-int nfct_cmd_helper_list(int argc, char *argv[]);
-int nfct_cmd_helper_add(int argc, char *argv[]);
-int nfct_cmd_helper_delete(int argc, char *argv[]);
-int nfct_cmd_helper_get(int argc, char *argv[]);
-int nfct_cmd_helper_flush(int argc, char *argv[]);
-int nfct_cmd_helper_disable(int argc, char *argv[]);
+struct nfct_extension {
+	struct list_head	head;
+	int			type;
+	int (*parse_params)(int argc, char *argv[]);
+};
+
+void nfct_extension_register(struct nfct_extension *ext);
 
 #endif
diff --git a/src/nfct-extensions/helper.c b/src/nfct-extensions/helper.c
index f91fc41..98ccde2 100644
--- a/src/nfct-extensions/helper.c
+++ b/src/nfct-extensions/helper.c
@@ -37,8 +37,14 @@ nfct_cmd_helper_usage(char *argv[])
 			"[parameters...]\n", VERSION, argv[0]);
 }
 
-int
-nfct_cmd_helper_parse_params(int argc, char *argv[])
+static int nfct_cmd_helper_list(int argc, char *argv[]);
+static int nfct_cmd_helper_add(int argc, char *argv[]);
+static int nfct_cmd_helper_delete(int argc, char *argv[]);
+static int nfct_cmd_helper_get(int argc, char *argv[]);
+static int nfct_cmd_helper_flush(int argc, char *argv[]);
+static int nfct_cmd_helper_disable(int argc, char *argv[]);
+
+static int nfct_cmd_helper_parse_params(int argc, char *argv[])
 {
 	int cmd = NFCT_CMD_NONE, ret = 0;
 
@@ -115,7 +121,7 @@ err:
 	return MNL_CB_OK;
 }
 
-int nfct_cmd_helper_list(int argc, char *argv[])
+static int nfct_cmd_helper_list(int argc, char *argv[])
 {
 	struct mnl_socket *nl;
 	char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -165,7 +171,7 @@ int nfct_cmd_helper_list(int argc, char *argv[])
 	return 0;
 }
 
-int nfct_cmd_helper_add(int argc, char *argv[])
+static int nfct_cmd_helper_add(int argc, char *argv[])
 {
 	struct mnl_socket *nl;
 	char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -281,7 +287,7 @@ int nfct_cmd_helper_add(int argc, char *argv[])
 	return 0;
 }
 
-int nfct_cmd_helper_delete(int argc, char *argv[])
+static int nfct_cmd_helper_delete(int argc, char *argv[])
 {
 	struct mnl_socket *nl;
 	char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -375,7 +381,7 @@ int nfct_cmd_helper_delete(int argc, char *argv[])
 	return 0;
 }
 
-int nfct_cmd_helper_get(int argc, char *argv[])
+static int nfct_cmd_helper_get(int argc, char *argv[])
 {
 	struct mnl_socket *nl;
 	char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -468,7 +474,7 @@ int nfct_cmd_helper_get(int argc, char *argv[])
 	return 0;
 }
 
-int nfct_cmd_helper_flush(int argc, char *argv[])
+static int nfct_cmd_helper_flush(int argc, char *argv[])
 {
 	struct mnl_socket *nl;
 	char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -519,7 +525,7 @@ int nfct_cmd_helper_flush(int argc, char *argv[])
 	return 0;
 }
 
-int nfct_cmd_helper_disable(int argc, char *argv[])
+static int nfct_cmd_helper_disable(int argc, char *argv[])
 {
 	struct mnl_socket *nl;
 	char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -613,3 +619,12 @@ int nfct_cmd_helper_disable(int argc, char *argv[])
 	return 0;
 }
 
+static struct nfct_extension helper = {
+	.type		= NFCT_SUBSYS_HELPER,
+	.parse_params	= nfct_cmd_helper_parse_params,
+};
+
+static void __init helper_init(void)
+{
+	nfct_extension_register(&helper);
+}
diff --git a/src/nfct-extensions/timeout.c b/src/nfct-extensions/timeout.c
index 5b32023..dde489a 100644
--- a/src/nfct-extensions/timeout.c
+++ b/src/nfct-extensions/timeout.c
@@ -35,7 +35,13 @@ nfct_cmd_timeout_usage(char *argv[])
 			"[parameters...]\n", VERSION, argv[0]);
 }
 
-int nfct_cmd_timeout_parse_params(int argc, char *argv[])
+static int nfct_cmd_timeout_list(int argc, char *argv[]);
+static int nfct_cmd_timeout_add(int argc, char *argv[]);
+static int nfct_cmd_timeout_delete(int argc, char *argv[]);
+static int nfct_cmd_timeout_get(int argc, char *argv[]);
+static int nfct_cmd_timeout_flush(int argc, char *argv[]);
+
+static int nfct_cmd_timeout_parse_params(int argc, char *argv[])
 {
 	int cmd = NFCT_CMD_NONE, ret;
 
@@ -105,7 +111,7 @@ err:
 	return MNL_CB_OK;
 }
 
-int nfct_cmd_timeout_list(int argc, char *argv[])
+static int nfct_cmd_timeout_list(int argc, char *argv[])
 {
 	struct mnl_socket *nl;
 	char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -484,3 +490,13 @@ int nfct_cmd_timeout_flush(int argc, char *argv[])
 
 	return 0;
 }
+
+static struct nfct_extension timeout = {
+	.type		= NFCT_SUBSYS_TIMEOUT,
+	.parse_params	= nfct_cmd_timeout_parse_params,
+};
+
+static void __init timeout_init(void)
+{
+	nfct_extension_register(&timeout);
+}
diff --git a/src/nfct.c b/src/nfct.c
index b5c9654..4795570 100644
--- a/src/nfct.c
+++ b/src/nfct.c
@@ -25,6 +25,7 @@
 #include <linux/netfilter/nfnetlink_cttimeout.h>
 #include <libnetfilter_cttimeout/libnetfilter_cttimeout.h>
 
+#include "linux_list.h"
 #include "nfct.h"
 
 static int nfct_cmd_version(int argc, char *argv[]);
@@ -46,9 +47,28 @@ void nfct_perror(const char *msg)
 	}
 }
 
+static LIST_HEAD(nfct_extension_list);
+
+void nfct_extension_register(struct nfct_extension *ext)
+{
+	list_add(&ext->head, &nfct_extension_list);
+}
+
+static struct nfct_extension *nfct_extension_lookup(int type)
+{
+	struct nfct_extension *ext;
+
+	list_for_each_entry(ext, &nfct_extension_list, head) {
+		if (ext->type == type)
+			return ext;
+	}
+	return NULL;
+}
+
 int main(int argc, char *argv[])
 {
 	int subsys = NFCT_SUBSYS_NONE, ret = 0;
+	struct nfct_extension *ext;
 
 	if (argc < 2) {
 		usage(argv);
@@ -70,18 +90,21 @@ int main(int argc, char *argv[])
 	}
 
 	switch(subsys) {
-	case NFCT_SUBSYS_TIMEOUT:
-		ret = nfct_cmd_timeout_parse_params(argc, argv);
-		break;
-	case NFCT_SUBSYS_HELPER:
-		ret = nfct_cmd_helper_parse_params(argc, argv);
-		break;
 	case NFCT_SUBSYS_VERSION:
 		ret = nfct_cmd_version(argc, argv);
 		break;
 	case NFCT_SUBSYS_HELP:
 		ret = nfct_cmd_help(argc, argv);
 		break;
+	default:
+		ext = nfct_extension_lookup(subsys);
+		if (ext == NULL) {
+			fprintf(stderr, "nfct v%s: subsystem %s not supported\n",
+				VERSION, argv[1]);
+			return EXIT_FAILURE;
+		}
+		ret = ext->parse_params(argc, argv);
+		break;
 	}
 	return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
-- 
cgit v1.2.3