summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org>2005-08-06 22:19:45 +0000
committer/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org>2005-08-06 22:19:45 +0000
commit47e498be59b170a0b3ea8bb783ab78f396510f38 (patch)
tree6b18982c43cb18ba157947840b6d49b4357adef5
parente741e28ee8a89bd7637a972339486dabb500438b (diff)
- don't export internals of handle data structure to users
- dynamically allocate handler at callee. - add more convenient callback_register() / handle_packet() api - add internal linked list of group handles and lookup/management functions - merge changes into compatibility library
-rw-r--r--_log/include/libnfnetlink_log/libnfnetlink_log.h33
-rw-r--r--_log/src/libipulog_compat.c20
-rw-r--r--_log/src/libnfnetlink_log.c175
3 files changed, 186 insertions, 42 deletions
diff --git a/_log/include/libnfnetlink_log/libnfnetlink_log.h b/_log/include/libnfnetlink_log/libnfnetlink_log.h
index 10345fd..4815bf3 100644
--- a/_log/include/libnfnetlink_log/libnfnetlink_log.h
+++ b/_log/include/libnfnetlink_log/libnfnetlink_log.h
@@ -13,36 +13,33 @@
#include <linux/netfilter/nfnetlink_log.h>
#include <libnfnetlink/libnfnetlink.h>
+struct nfulnl_handle;
+struct nfulnl_g_handle;
-struct nfulnl_handle
-{
- struct nfnl_handle nfnlh;
-};
+extern struct nfnl_handle *nfulnl_nfnlh(struct nfulnl_handle *h);
-struct nfulnl_g_handle
-{
- struct nfulnl_handle *h;
- u_int16_t id;
-};
+typedef nfulnl_callback(struct nfulnl_g_handle *gh, struct nfgenmsg *nfmsg,
+ struct nfattr *nfa[], void *data);
-struct ctnl_msg_handler {
- int type;
- int (*handler)(struct sockaddr_nl *, struct nlmsghdr *, void *arg);
-};
-extern int nfulnl_open(struct nfulnl_handle *h);
+extern struct nfulnl_handle *nfulnl_open(void);
extern int nfulnl_close(struct nfulnl_handle *h);
extern int nfulnl_bind_pf(struct nfulnl_handle *h, u_int16_t pf);
extern int nfulnl_unbind_pf(struct nfulnl_handle *h, u_int16_t pf);
-extern int nfulnl_bind_group(struct nfulnl_handle *h,
- struct nfulnl_g_handle *qh, u_int16_t num);
-extern int nfulnl_unbind_group(struct nfulnl_g_handle *qh);
+extern struct nfulnl_g_handle *nfulnl_bind_group(struct nfulnl_handle *h,
+ u_int16_t num);
+extern int nfulnl_unbind_group(struct nfulnl_g_handle *gh);
-extern int nfulnl_set_mode(struct nfulnl_g_handle *qh,
+extern int nfulnl_set_mode(struct nfulnl_g_handle *gh,
u_int8_t mode, unsigned int len);
extern int nfulnl_set_timeout(struct nfulnl_g_handle *gh, u_int32_t timeout);
extern int nfulnl_set_qthresh(struct nfulnl_g_handle *gh, u_int32_t qthresh);
extern int nfulnl_set_nlbufsiz(struct nfulnl_g_handle *gh, u_int32_t nlbufsiz);
+
+extern int nfulnl_callback_register(struct nfulnl_g_handle *gh,
+ nfulnl_callback *cb, void *data);
+extern int nfulnl_handle_packet(struct nfulnl_handle *h, char *buf, int len);
+
#endif /* __LIBNFNETLINK_LOG_H */
diff --git a/_log/src/libipulog_compat.c b/_log/src/libipulog_compat.c
index b6fc82e..d981e94 100644
--- a/_log/src/libipulog_compat.c
+++ b/_log/src/libipulog_compat.c
@@ -14,8 +14,8 @@
struct ipulog_handle
{
- struct nfulnl_handle nfulh;
- struct nfulnl_g_handle nful_gh;
+ struct nfulnl_handle *nfulh;
+ struct nfulnl_g_handle *nful_gh;
struct nlmsghdr *last_nlh;
#if 0
int fd;
@@ -94,13 +94,15 @@ struct ipulog_handle *ipulog_create_handle(u_int32_t gmask,
return NULL;
}
memset(h, 0, sizeof(*h));
- if (nfulnl_open(&h->nfulh) < 0)
+ h->nfulh = nfulnl_open();
+ if (!h->nfulh)
goto out_free;
- if (nfulnl_bind_pf(&h->nfulh, AF_INET) < 0)
+ if (nfulnl_bind_pf(h->nfulh, AF_INET) < 0)
goto out_free;
- if (nfulnl_bind_group(&h->nfulh, &h->nful_gh, group) < 0)
+ h->nful_gh = nfulnl_bind_group(h->nfulh, group);
+ if (!h->nful_gh)
goto out_free;
return h;
@@ -113,8 +115,8 @@ out_free:
void ipulog_destroy_handle(struct ipulog_handle *h)
{
- nfulnl_unbind_group(&h->nful_gh);
- nfulnl_close(&h->nfulh);
+ nfulnl_unbind_group(h->nful_gh);
+ nfulnl_close(h->nfulh);
free(h);
}
@@ -127,10 +129,10 @@ ulog_packet_msg_t *ipulog_get_packet(struct ipulog_handle *h,
struct nfulnl_msg_packet_hdr *hdr;
if (!h->last_nlh)
- nlh = nfnl_get_msg_first(&h->nfulh.nfnlh, buf, len);
+ nlh = nfnl_get_msg_first(nfulnl_nfnlh(h->nfulh), buf, len);
else {
next_msg:
- nlh = nfnl_get_msg_next(&h->nfulh.nfnlh, buf, len);
+ nlh = nfnl_get_msg_next(nfulnl_nfnlh(h->nfulh), buf, len);
}
h->last_nlh = nlh;
diff --git a/_log/src/libnfnetlink_log.c b/_log/src/libnfnetlink_log.c
index d0bd124..e497850 100644
--- a/_log/src/libnfnetlink_log.c
+++ b/_log/src/libnfnetlink_log.c
@@ -28,31 +28,74 @@
#include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_log.h>
+#include <libnfnetlink/libnfnetlink.h>
#include <libnfnetlink_log/libnfnetlink_log.h>
#define HEADER_LEN (NLMSG_LENGTH(sizeof(struct nlmsghdr)) \
+NLMSG_LENGTH(sizeof(struct nfgenmsg)))
+struct nfulnl_handle
+{
+ struct nfnl_handle nfnlh;
+ struct nfulnl_g_handle *gh_list;
+};
+
+struct nfulnl_g_handle
+{
+ struct nfulnl_g_handle *next;
+ struct nfulnl_handle *h;
+ u_int16_t id;
+
+ nfulnl_callback *cb;
+ void *data;
+};
+
+static int nfulnl_errno;
+
/***********************************************************************
* low level stuff
***********************************************************************/
-int nfulnl_open(struct nfulnl_handle *h)
+static void del_gh(struct nfulnl_g_handle *gh)
{
- int err;
+ struct nfulnl_g_handle *cur_gh, *prev_gh = NULL;
+
+ for (cur_gh = gh->h->gh_list; cur_gh; cur_gh = cur_gh->next) {
+ if (cur_gh == gh) {
+ if (prev_gh)
+ prev_gh->next = gh->next;
+ else
+ gh->h->gh_list = gh->next;
+ return;
+ }
+ prev_gh = cur_gh;
+ }
+}
- memset(h, 0, sizeof(*h));
+static void add_gh(struct nfulnl_g_handle *gh)
+{
+ gh->next = gh->h->gh_list;
+ gh->h->gh_list = gh;
+}
- err = nfnl_open(&h->nfnlh, NFNL_SUBSYS_ULOG, 0);
- if (err < 0)
- return err;
+static struct nfulnl_g_handle *find_gh(struct nfulnl_handle *h, u_int16_t group)
+{
+ struct nfulnl_g_handle *gh;
- return 0;
+ for (gh = h->gh_list; gh; gh = gh->next) {
+ if (gh->id == group)
+ return gh;
+ }
+ return NULL;
}
-int nfulnl_close(struct nfulnl_handle *h)
+static int __nfulnl_rcv_cmd(struct nlmsghdr *nlh, struct nfattr *nfa[],
+ void *data)
{
- return nfnl_close(&h->nfnlh);
+ struct nfulnl_handle *h = data;
+
+ /* FIXME: implement this */
+ return 0;
}
/* build a NFULNL_MSG_CONFIG message */
@@ -73,6 +116,89 @@ __build_send_cfg_msg(struct nfulnl_handle *h, u_int8_t command,
return nfnl_send(&h->nfnlh, nmh);
}
+static int __nfulnl_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
+ void *data)
+{
+ struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+ struct nfulnl_handle *h = data;
+ u_int16_t group = ntohl(nfmsg->res_id);
+ struct nfulnl_g_handle *gh = find_gh(h, group);
+
+ if (!gh)
+ return -EEXIST;
+
+ return gh->cb(gh, nfmsg, nfa, gh->data);
+}
+
+struct nfnl_callback cmd_cb = {
+ .call = &__nfulnl_rcv_cmd,
+ .attr_count = NFULA_CFG_MAX,
+};
+
+struct nfnl_callback pkt_cb = {
+ .call = &__nfulnl_rcv_pkt,
+ .attr_count = NFULA_MAX,
+};
+
+struct nfnl_handle *nfulnl_nfnlh(struct nfulnl_handle *h)
+{
+ return &h->nfnlh;
+}
+
+struct nfulnl_handle *nfulnl_open(void)
+{
+ struct nfulnl_handle *h;
+ int err;
+
+ h = malloc(sizeof(*h));
+ if (!h)
+ return NULL;
+
+ memset(h, 0, sizeof(*h));
+
+ err = nfnl_open(&h->nfnlh, NFNL_SUBSYS_ULOG, NFULNL_MSG_MAX, 0);
+ if (err < 0) {
+ nfulnl_errno = err;
+ return NULL;
+ }
+
+ cmd_cb.data = h;
+ err = nfnl_callback_register(&h->nfnlh, NFULNL_MSG_CONFIG, &cmd_cb);
+ if (err < 0) {
+ nfnl_close(&h->nfnlh);
+ nfulnl_errno = err;
+ return NULL;
+ }
+ pkt_cb.data = h;
+ err = nfnl_callback_register(&h->nfnlh, NFULNL_MSG_PACKET, &pkt_cb);
+ if (err < 0) {
+ nfnl_close(&h->nfnlh);
+ nfulnl_errno = err;
+ return NULL;
+ }
+
+ return h;
+}
+
+int nfulnl_callback_register(struct nfulnl_g_handle *gh, nfulnl_callback *cb,
+ void *data)
+{
+ gh->data = data;
+ gh->cb = cb;
+
+ return 0;
+}
+
+int nfulnl_handle_packet(struct nfulnl_handle *h, char *buf, int len)
+{
+ return nfnl_handle_packet(&h->nfnlh, buf, len);
+}
+
+int nfulnl_close(struct nfulnl_handle *h)
+{
+ return nfnl_close(&h->nfnlh);
+}
+
/* bind nf_queue from a specific protocol family */
int nfulnl_bind_pf(struct nfulnl_handle *h, u_int16_t pf)
{
@@ -86,21 +212,39 @@ int nfulnl_unbind_pf(struct nfulnl_handle *h, u_int16_t pf)
}
/* bind this socket to a specific queue number */
-int nfulnl_bind_group(struct nfulnl_handle *h,
- struct nfulnl_g_handle *gh, u_int16_t num)
+struct nfulnl_g_handle *
+nfulnl_bind_group(struct nfulnl_handle *h, u_int16_t num)
{
+ struct nfulnl_g_handle *gh;
+
+ if (find_gh(h, num))
+ return NULL;
+
+ gh = malloc(sizeof(*gh));
+ if (!gh)
+ return NULL;
+
+ memset(gh, 0, sizeof(*gh));
gh->h = h;
gh->id = num;
- return __build_send_cfg_msg(h, NFULNL_CFG_CMD_BIND, num, 0);
+ if (__build_send_cfg_msg(h, NFULNL_CFG_CMD_BIND, num, 0) < 0) {
+ free(gh);
+ return NULL;
+ }
+
+ add_gh(gh);
+ return gh;
}
/* unbind this socket from a specific queue number */
int nfulnl_unbind_group(struct nfulnl_g_handle *gh)
{
int ret = __build_send_cfg_msg(gh->h, NFULNL_CFG_CMD_UNBIND, gh->id, 0);
- if (ret == 0)
- gh->h = NULL;
+ if (ret == 0) {
+ del_gh(gh);
+ free(gh);
+ }
return ret;
}
@@ -166,5 +310,6 @@ int nfulnl_set_nlbufsiz(struct nfulnl_g_handle *gh, u_int32_t nlbufsiz)
/* we try to have space for at least 10 messages in the socket buffer */
if (status >= 0)
nfnl_rcvbufsiz(&gh->h->nfnlh, 10*nlbufsiz);
-}
+ return status;
+}