summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-05-23 11:52:20 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2009-05-23 11:52:20 +0200
commit20ed81b10714dfe78e31e9721e2d4f42b4beabb2 (patch)
treecc2482605cfff21244cb090f9d2e76bfb95514aa
parent975ae9979ec73e8acb2c215ee9a84fded2f4357a (diff)
api: add new callback interface while keeping backward compatibility
This patch adds nfct_callback_register2() and nfct_callback_unregister2() that allows to register a callback function with a new callback interface that includes the Netlink message. This fixes an early design error. This is not nice but it is the only way to resolve this problem without breaking backward (I don't like function versioning, it is messy). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/internal/object.h9
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack.h12
-rw-r--r--src/conntrack/api.c74
-rw-r--r--src/conntrack/callback.c2
4 files changed, 97 insertions, 0 deletions
diff --git a/include/internal/object.h b/include/internal/object.h
index fe1506c..378ba74 100644
--- a/include/internal/object.h
+++ b/include/internal/object.h
@@ -22,6 +22,15 @@ struct nfct_handle {
struct nf_conntrack *ct,
void *data);
+ /* This is the second version of the callback that includes
+ * the Netlink header. This is the result of an early design
+ * error, hiding Netlink details is evil. You end needing some
+ * internal information at some point like the Netlink PortID. */
+ int (*cb2)(const struct nlmsghdr *nlh,
+ enum nf_conntrack_msg_type type,
+ struct nf_conntrack *ct,
+ void *data);
+
int (*expect_cb)(enum nf_conntrack_msg_type type,
struct nf_expect *exp,
void *data);
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index 1e23b0b..ec85066 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -233,6 +233,18 @@ extern int nfct_callback_register(struct nfct_handle *h,
extern void nfct_callback_unregister(struct nfct_handle *h);
+/* register / unregister callback: extended version including netlink header */
+
+extern int nfct_callback_register2(struct nfct_handle *h,
+ enum nf_conntrack_msg_type type,
+ int (*cb)(const struct nlmsghdr *nlh,
+ enum nf_conntrack_msg_type type,
+ struct nf_conntrack *ct,
+ void *data),
+ void *data);
+
+extern void nfct_callback_unregister2(struct nfct_handle *h);
+
/* callback verdict */
enum {
NFCT_CB_FAILURE = -1, /* failure */
diff --git a/src/conntrack/api.c b/src/conntrack/api.c
index e69ea49..0639b5f 100644
--- a/src/conntrack/api.c
+++ b/src/conntrack/api.c
@@ -200,6 +200,80 @@ void nfct_callback_unregister(struct nfct_handle *h)
}
/**
+ * nf_callback_register2 - register a callback
+ * @h: library handler
+ * @cb: callback used to process conntrack received
+ * @data: data used by the callback, if any.
+ *
+ * This function register a callback to handle the conntrack received,
+ * in case of error -1 is returned and errno is set appropiately, otherwise
+ * 0 is returned.
+ *
+ * Note that the data parameter is optional, if you do not want to pass any
+ * data to your callback, then use NULL.
+ *
+ * NOTICE: The difference with nf_callback_register() is that this function
+ * uses the new callback interface that includes the Netlink header.
+ *
+ * WARNING: Don't mix nf_callback_register() and nf_callback_register2()
+ * calls, use only once at a time.
+ */
+int nfct_callback_register2(struct nfct_handle *h,
+ enum nf_conntrack_msg_type type,
+ int (*cb)(const struct nlmsghdr *nlh,
+ enum nf_conntrack_msg_type type,
+ struct nf_conntrack *ct,
+ void *data),
+ void *data)
+{
+ struct __data_container *container;
+
+ assert(h != NULL);
+
+ container = calloc(sizeof(struct __data_container), 1);
+ if (container == NULL)
+ return -1;
+
+ h->cb2 = cb;
+ container->h = h;
+ container->type = type;
+ container->data = data;
+
+ h->nfnl_cb.call = __callback;
+ h->nfnl_cb.data = container;
+ h->nfnl_cb.attr_count = CTA_MAX;
+
+ nfnl_callback_register(h->nfnlssh_ct,
+ IPCTNL_MSG_CT_NEW,
+ &h->nfnl_cb);
+
+ nfnl_callback_register(h->nfnlssh_ct,
+ IPCTNL_MSG_CT_DELETE,
+ &h->nfnl_cb);
+
+ return 0;
+}
+
+/**
+ * nfct_callback_unregister2 - unregister a callback
+ * @h: library handler
+ */
+void nfct_callback_unregister2(struct nfct_handle *h)
+{
+ assert(h != NULL);
+
+ nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
+ nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
+
+ h->cb2 = NULL;
+ free(h->nfnl_cb.data);
+
+ h->nfnl_cb.call = NULL;
+ h->nfnl_cb.data = NULL;
+ h->nfnl_cb.attr_count = 0;
+}
+
+/**
* nfct_set_attr - set the value of a certain conntrack attribute
* @ct: pointer to a valid conntrack
* @type: attribute type
diff --git a/src/conntrack/callback.c b/src/conntrack/callback.c
index 7faf13a..c83a564 100644
--- a/src/conntrack/callback.c
+++ b/src/conntrack/callback.c
@@ -31,6 +31,8 @@ int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data)
if (container->h->cb)
ret = container->h->cb(type, ct, container->data);
+ else if (container->h->cb2)
+ ret = container->h->cb2(nlh, type, ct, container->data);
switch(ret) {
case NFCT_CB_FAILURE: