[netfilter-cvslog] r6410 - in trunk: libnetfilter_conntrack
libnetfilter_conntrack/include/libnetfilter_conntrack
libnetfilter_conntrack/src libnetfilter_log
libnetfilter_log/include/libnetfilter_log
libnetfilter_log/src libnetfilter_queue
libnetfilter_queue/include/libnetfilter_queue
libnetfilter_queue/src libnfnetlink
libnfnetlink/include/libnfnetlink libnfnetlink/src
laforge at netfilter.org
laforge at netfilter.org
Sat Jan 14 20:04:55 CET 2006
Author: laforge at netfilter.org
Date: 2006-01-14 20:04:51 +0100 (Sat, 14 Jan 2006)
New Revision: 6410
Modified:
trunk/libnetfilter_conntrack/Make_global.am
trunk/libnetfilter_conntrack/configure.in
trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c
trunk/libnetfilter_log/configure.in
trunk/libnetfilter_log/include/libnetfilter_log/libnetfilter_log.h
trunk/libnetfilter_log/src/Makefile.am
trunk/libnetfilter_log/src/libnetfilter_log.c
trunk/libnetfilter_queue/configure.in
trunk/libnetfilter_queue/include/libnetfilter_queue/libnetfilter_queue.h
trunk/libnetfilter_queue/src/Makefile.am
trunk/libnetfilter_queue/src/libnetfilter_queue.c
trunk/libnfnetlink/configure.in
trunk/libnfnetlink/include/libnfnetlink/libnfnetlink.h
trunk/libnfnetlink/src/Makefile.am
trunk/libnfnetlink/src/libnfnetlink.c
Log:
Introduce various API changes throughout the library stack
1) make libnfnetlink dynamically allocate it's handles
2) apply that change throughout libnetfilter_*
3) add {nfq,nflog,nfct}_open_nfnl() functions that open
the specific subsystem on top of an existing nfnl_handle,
which is required for upcoming libnetfilter_conntrack_helper
The changes break ABI and API compatibility of libnfnetlink, but don't
break ABI or API compatibility of the libnetfilter_* libraries.
Modified: trunk/libnetfilter_conntrack/Make_global.am
===================================================================
--- trunk/libnetfilter_conntrack/Make_global.am 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_conntrack/Make_global.am 2006-01-14 19:04:51 UTC (rev 6410)
@@ -1,6 +1,6 @@
# This is _NOT_ the library release version, it's an API version.
# Please read Chapter 6 "Library interface versions" of the libtool
# documentation before making any modification
-LIBVERSION=1:0:0
+LIBVERSION=2:0:1
INCLUDES=$(all_includes) -I$(top_srcdir)/include
Modified: trunk/libnetfilter_conntrack/configure.in
===================================================================
--- trunk/libnetfilter_conntrack/configure.in 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_conntrack/configure.in 2006-01-14 19:04:51 UTC (rev 6410)
@@ -4,7 +4,7 @@
AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.30)
+AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.31)
AC_PROG_CC
AM_PROG_LIBTOOL
Modified: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h 2006-01-14 19:04:51 UTC (rev 6410)
@@ -105,6 +105,7 @@
struct nfct_tuple mask;
u_int32_t timeout;
u_int32_t id;
+ u_int16_t expectfn_queue_id;
};
struct nfct_conntrack_compare {
@@ -225,6 +226,9 @@
* [Open|close] a conntrack handler
*/
extern struct nfct_handle *nfct_open(u_int8_t, unsigned);
+extern struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
+ u_int8_t subsys_id,
+ unsigned int subscriptions);
extern int nfct_close(struct nfct_handle *cth);
extern int nfct_fd(struct nfct_handle *cth);
Modified: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h 2006-01-14 19:04:51 UTC (rev 6410)
@@ -120,6 +120,7 @@
CTA_EXPECT_TIMEOUT,
CTA_EXPECT_ID,
CTA_EXPECT_HELP_NAME,
+ CTA_EXPECT_QUEUENR,
__CTA_EXPECT_MAX
};
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
@@ -131,6 +132,4 @@
};
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
-#define CTA_HELP_MAXNAMESIZE 32
-
#endif /* _IPCONNTRACK_NETLINK_H */
Modified: trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c
===================================================================
--- trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c 2006-01-14 19:04:51 UTC (rev 6410)
@@ -29,7 +29,9 @@
/* Harald says: "better for encapsulation" ;) */
struct nfct_handle {
- struct nfnl_handle nfnlh;
+ struct nfnl_handle *nfnlh;
+ struct nfnl_subsys_handle *nfnlssh_ct;
+ struct nfnl_subsys_handle *nfnlssh_exp;
nfct_callback callback; /* user callback */
void *callback_data; /* user data for callback */
nfct_handler handler; /* netlink handler */
@@ -75,44 +77,81 @@
return ret;
}
-struct nfct_handle *nfct_open(u_int8_t subsys_id, unsigned subscriptions)
+struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
+ u_int8_t subsys_id,
+ unsigned int subscriptions)
{
- int err;
- u_int8_t cb_count;
struct nfct_handle *cth;
- switch(subsys_id) {
- case NFNL_SUBSYS_CTNETLINK:
- cb_count = IPCTNL_MSG_MAX;
- break;
- case NFNL_SUBSYS_CTNETLINK_EXP:
- cb_count = IPCTNL_MSG_EXP_MAX;
- break;
- default:
- return NULL;
- break;
- }
- cth = (struct nfct_handle *)
- malloc(sizeof(struct nfct_handle));
+ cth = (struct nfct_handle *) malloc(sizeof(struct nfct_handle));
if (!cth)
return NULL;
memset(cth, 0, sizeof(*cth));
+ cth->nfnlh = nfnlh;
- err = nfnl_open(&cth->nfnlh, subsys_id, cb_count, subscriptions);
- if (err < 0) {
- free(cth);
- return NULL;
+ if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK) {
+ cth->nfnlssh_ct = nfnl_subsys_open(cth->nfnlh,
+ NFNL_SUBSYS_CTNETLINK,
+ IPCTNL_MSG_MAX,
+ subscriptions);
+ if (!cth->nfnlssh_ct)
+ goto out_free;
}
+ if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK_EXP) {
+ cth->nfnlssh_exp = nfnl_subsys_open(cth->nfnlh,
+ NFNL_SUBSYS_CTNETLINK_EXP,
+ IPCTNL_MSG_EXP_MAX,
+ subscriptions);
+ if (!cth->nfnlssh_exp)
+ goto out_free;
+ }
+
return cth;
+
+out_free:
+ if (cth->nfnlssh_exp) {
+ nfnl_subsys_close(cth->nfnlssh_exp);
+ cth->nfnlssh_exp = NULL;
+ }
+ if (cth->nfnlssh_ct) {
+ nfnl_subsys_close(cth->nfnlssh_ct);
+ cth->nfnlssh_ct = NULL;
+ }
+ free(cth);
+ return NULL;
}
+struct nfct_handle *nfct_open(u_int8_t subsys_id, unsigned subscriptions)
+{
+ struct nfnl_handle *nfnlh = nfnl_open();
+ struct nfct_handle *nfcth;
+
+ if (!nfnlh)
+ return NULL;
+
+ nfcth = nfct_open_nfnl(nfnlh, subsys_id, subscriptions);
+ if (!nfcth)
+ nfnl_close(nfnlh);
+
+ return nfcth;
+}
+
int nfct_close(struct nfct_handle *cth)
{
int err;
- err = nfnl_close(&cth->nfnlh);
+ if (cth->nfnlssh_exp) {
+ nfnl_subsys_close(cth->nfnlssh_exp);
+ cth->nfnlssh_exp = NULL;
+ }
+ if (cth->nfnlssh_ct) {
+ nfnl_subsys_close(cth->nfnlssh_ct);
+ cth->nfnlssh_ct = NULL;
+ }
+
+ err = nfnl_close(cth->nfnlh);
free(cth);
return err;
@@ -120,7 +159,7 @@
int nfct_fd(struct nfct_handle *cth)
{
- return nfnl_fd(&cth->nfnlh);
+ return nfnl_fd(cth->nfnlh);
}
void nfct_register_callback(struct nfct_handle *cth, nfct_callback callback,
@@ -889,7 +928,8 @@
memset(buf, 0, sizeof(buf));
- nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 0, IPCTNL_MSG_CT_NEW,
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0, l3num, 0,
+ IPCTNL_MSG_CT_NEW,
NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL);
nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_ORIGINAL],
@@ -911,7 +951,7 @@
if (ct->nat.min_ip != 0)
nfct_build_nat(req, sizeof(buf), ct);
- return nfnl_talk(&cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
}
int nfct_update_conntrack(struct nfct_handle *cth, struct nfct_conntrack *ct)
@@ -928,8 +968,8 @@
req = (void *) &buf;
memset(&buf, 0, sizeof(buf));
- nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 0, IPCTNL_MSG_CT_NEW,
- NLM_F_REQUEST|NLM_F_ACK);
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0, l3num, 0,
+ IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_ACK);
nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_ORIGINAL],
CTA_TUPLE_ORIG);
@@ -954,11 +994,11 @@
nfct_build_protoinfo(req, sizeof(buf), ct);
- err = nfnl_send(&cth->nfnlh, &req->nlh);
+ err = nfnl_send(cth->nfnlh, &req->nlh);
if (err < 0)
return err;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
int nfct_delete_conntrack(struct nfct_handle *cth, struct nfct_tuple *tuple,
@@ -972,7 +1012,7 @@
req = (void *) &buf;
memset(&buf, 0, sizeof(buf));
- nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0,
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0,
l3num, 0, IPCTNL_MSG_CT_DELETE,
NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
@@ -984,7 +1024,7 @@
sizeof(u_int32_t));
}
- return nfnl_talk(&cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
}
int nfct_get_conntrack(struct nfct_handle *cth, struct nfct_tuple *tuple,
@@ -1001,7 +1041,7 @@
memset(&buf, 0, sizeof(buf));
req = (void *) &buf;
- nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0,
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0,
l3num, 0, IPCTNL_MSG_CT_GET,
NLM_F_REQUEST|NLM_F_ACK);
@@ -1013,11 +1053,11 @@
sizeof(u_int32_t));
}
- err = nfnl_send(&cth->nfnlh, &req->nlh);
+ err = nfnl_send(cth->nfnlh, &req->nlh);
if (err < 0)
return err;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
static int __nfct_dump_conntrack_table(struct nfct_handle *cth, int zero,
@@ -1034,14 +1074,14 @@
else
msg = IPCTNL_MSG_CT_GET;
- nfnl_fill_hdr(&cth->nfnlh, &req.nlh, 0, family, 0,
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req.nlh, 0, family, 0,
msg, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP);
- err = nfnl_send(&cth->nfnlh, &req.nlh);
+ err = nfnl_send(cth->nfnlh, &req.nlh);
if (err < 0)
return err;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
int nfct_dump_conntrack_table(struct nfct_handle *cth, int family)
@@ -1064,7 +1104,7 @@
return -EPERM;
cth->handler = nfct_conntrack_netlink_handler;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
void nfct_register_proto(struct nfct_proto *h)
@@ -1095,14 +1135,14 @@
memset(&req, 0, sizeof(req));
cth->handler = nfct_expect_netlink_handler;
- nfnl_fill_hdr(&cth->nfnlh, &req.nlh, 0, family, 0,
+ nfnl_fill_hdr(cth->nfnlssh_exp, &req.nlh, 0, family, 0,
IPCTNL_MSG_EXP_GET, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST);
- err = nfnl_send(&cth->nfnlh, &req.nlh);
+ err = nfnl_send(cth->nfnlh, &req.nlh);
if (err < 0)
return err;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
int nfct_flush_conntrack_table(struct nfct_handle *cth, int family)
@@ -1111,11 +1151,11 @@
memset(&req, 0, sizeof(req));
- nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &req,
+ nfnl_fill_hdr(cth->nfnlssh_ct, (struct nlmsghdr *) &req,
0, family, 0, IPCTNL_MSG_CT_DELETE,
NLM_F_REQUEST|NLM_F_ACK);
- return nfnl_talk(&cth->nfnlh, &req.nlh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(cth->nfnlh, &req.nlh, 0, 0, NULL, NULL, NULL);
}
int nfct_get_expectation(struct nfct_handle *cth, struct nfct_tuple *tuple,
@@ -1129,7 +1169,8 @@
memset(&buf, 0, sizeof(buf));
req = (void *) &buf;
- nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 0, IPCTNL_MSG_EXP_GET,
+ nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num, 0,
+ IPCTNL_MSG_EXP_GET,
NLM_F_REQUEST|NLM_F_ACK);
cth->handler = nfct_expect_netlink_handler;
@@ -1139,11 +1180,11 @@
nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_ID, &id,
sizeof(u_int32_t));
- err = nfnl_send(&cth->nfnlh, &req->nlh);
+ err = nfnl_send(cth->nfnlh, &req->nlh);
if (err < 0)
return err;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
struct nfct_expect *
@@ -1161,7 +1202,7 @@
exp->master = *master;
exp->tuple = *tuple;
exp->mask = *mask;
- exp->timeout = htonl(timeout);
+ exp->timeout = timeout;
if (id != NFCT_ANY_ID)
exp->id = htonl(id);
@@ -1180,27 +1221,36 @@
char buf[NFCT_BUFSIZE];
req = (void *) &buf;
u_int8_t l3num = exp->tuple.l3protonum;
+ u_int32_t timeout;
+ u_int16_t queuenr;
memset(&buf, 0, sizeof(buf));
- nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 0, IPCTNL_MSG_EXP_NEW,
+ nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num, 0,
+ IPCTNL_MSG_EXP_NEW,
NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK);
nfct_build_tuple(req, sizeof(buf), &exp->master, CTA_EXPECT_MASTER);
nfct_build_tuple(req, sizeof(buf), &exp->tuple, CTA_EXPECT_TUPLE);
nfct_build_tuple(req, sizeof(buf), &exp->mask, CTA_EXPECT_MASK);
+ timeout = htonl(exp->timeout);
nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_TIMEOUT,
- &exp->timeout, sizeof(u_int32_t));
+ &timeout, sizeof(u_int32_t));
- err = nfnl_send(&cth->nfnlh, &req->nlh);
+ queuenr = htons(exp->expectfn_queue_id);
+ if (queuenr)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_QUEUENR,
+ &queuenr, sizeof(u_int16_t));
+
+ err = nfnl_send(cth->nfnlh, &req->nlh);
if (err < 0)
return err;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
-int nfct_delete_expectation(struct nfct_handle *cth,struct nfct_tuple *tuple,
+int nfct_delete_expectation(struct nfct_handle *cth, struct nfct_tuple *tuple,
u_int32_t id)
{
int err;
@@ -1211,7 +1261,7 @@
memset(&buf, 0, sizeof(buf));
req = (void *) &buf;
- nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num,
+ nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num,
0, IPCTNL_MSG_EXP_DELETE,
NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
@@ -1221,11 +1271,11 @@
nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_ID, &id,
sizeof(u_int32_t));
- err = nfnl_send(&cth->nfnlh, &req->nlh);
+ err = nfnl_send(cth->nfnlh, &req->nlh);
if (err < 0)
return err;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
int nfct_event_expectation(struct nfct_handle *cth)
@@ -1237,7 +1287,7 @@
return -EPERM;
cth->handler = nfct_expect_netlink_handler;
- return nfnl_listen(&cth->nfnlh, &callback_handler, cth);
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
}
int nfct_flush_expectation_table(struct nfct_handle *cth, int family)
@@ -1246,9 +1296,9 @@
memset(&req, 0, sizeof(req));
- nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &req,
+ nfnl_fill_hdr(cth->nfnlssh_exp, (struct nlmsghdr *) &req,
0, family, 0, IPCTNL_MSG_EXP_DELETE,
NLM_F_REQUEST|NLM_F_ACK);
- return nfnl_talk(&cth->nfnlh, &req.nlh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(cth->nfnlh, &req.nlh, 0, 0, NULL, NULL, NULL);
}
Modified: trunk/libnetfilter_log/configure.in
===================================================================
--- trunk/libnetfilter_log/configure.in 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_log/configure.in 2006-01-14 19:04:51 UTC (rev 6410)
@@ -4,7 +4,7 @@
AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(libnetfilter_log, 0.0.12)
+AM_INIT_AUTOMAKE(libnetfilter_log, 0.0.13)
AC_PROG_CC
AM_PROG_LIBTOOL
Modified: trunk/libnetfilter_log/include/libnetfilter_log/libnetfilter_log.h
===================================================================
--- trunk/libnetfilter_log/include/libnetfilter_log/libnetfilter_log.h 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_log/include/libnetfilter_log/libnetfilter_log.h 2006-01-14 19:04:51 UTC (rev 6410)
@@ -25,6 +25,7 @@
extern struct nflog_handle *nflog_open(void);
+extern struct nflog_handle *nflog_open_nfnl(struct nfnl_handle *nfnlh);
extern int nflog_close(struct nflog_handle *h);
extern int nflog_bind_pf(struct nflog_handle *h, u_int16_t pf);
Modified: trunk/libnetfilter_log/src/Makefile.am
===================================================================
--- trunk/libnetfilter_log/src/Makefile.am 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_log/src/Makefile.am 2006-01-14 19:04:51 UTC (rev 6410)
@@ -1,6 +1,6 @@
# This is _NOT_ the library release version, it's an API version.
# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
-LIBVERSION=1:0:0
+LIBVERSION=2:0:1
INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS=-fPIC -Wall
Modified: trunk/libnetfilter_log/src/libnetfilter_log.c
===================================================================
--- trunk/libnetfilter_log/src/libnetfilter_log.c 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_log/src/libnetfilter_log.c 2006-01-14 19:04:51 UTC (rev 6410)
@@ -33,7 +33,8 @@
struct nflog_handle
{
- struct nfnl_handle nfnlh;
+ struct nfnl_handle *nfnlh;
+ struct nfnl_subsys_handle *nfnlssh;
struct nflog_g_handle *gh_list;
};
@@ -94,7 +95,7 @@
static int __nflog_rcv_cmd(struct nlmsghdr *nlh, struct nfattr *nfa[],
void *data)
{
- struct nflog_handle *h = data;
+ /* struct nflog_handle *h = data; */
/* FIXME: implement this */
return 0;
@@ -110,13 +111,13 @@
struct nfulnl_msg_config_cmd cmd;
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
- nfnl_fill_hdr(&h->nfnlh, nmh, 0, pf, queuenum,
+ nfnl_fill_hdr(h->nfnlssh, nmh, 0, pf, queuenum,
NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
cmd.command = command;
nfnl_addattr_l(nmh, sizeof(buf), NFULA_CFG_CMD, &cmd, sizeof(cmd));
- return nfnl_talk(&h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
}
static int __nflog_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
@@ -152,7 +153,7 @@
struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h)
{
- return &h->nfnlh;
+ return h->nfnlh;
}
int nflog_fd(struct nflog_handle *h)
@@ -160,7 +161,7 @@
return nfnl_fd(nflog_nfnlh(h));
}
-struct nflog_handle *nflog_open(void)
+struct nflog_handle *nflog_open_nfnl(struct nfnl_handle *nfnlh)
{
struct nflog_handle *h;
int err;
@@ -170,21 +171,23 @@
return NULL;
memset(h, 0, sizeof(*h));
+ h->nfnlh = nfnlh;
- err = nfnl_open(&h->nfnlh, NFNL_SUBSYS_ULOG, NFULNL_MSG_MAX, 0);
- if (err < 0) {
- nflog_errno = err;
+ h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG,
+ NFULNL_MSG_MAX, 0);
+ if (!h->nfnlssh) {
+ /* FIXME: nflog_errno */
goto out_free;
}
cmd_cb.data = h;
- err = nfnl_callback_register(&h->nfnlh, NFULNL_MSG_CONFIG, &cmd_cb);
+ err = nfnl_callback_register(h->nfnlssh, NFULNL_MSG_CONFIG, &cmd_cb);
if (err < 0) {
nflog_errno = err;
goto out_close;
}
pkt_cb.data = h;
- err = nfnl_callback_register(&h->nfnlh, NFULNL_MSG_PACKET, &pkt_cb);
+ err = nfnl_callback_register(h->nfnlssh, NFULNL_MSG_PACKET, &pkt_cb);
if (err < 0) {
nflog_errno = err;
goto out_close;
@@ -192,12 +195,30 @@
return h;
out_close:
- nfnl_close(&h->nfnlh);
+ nfnl_close(h->nfnlh);
out_free:
free(h);
return NULL;
}
+struct nflog_handle *nflog_open(void)
+{
+ struct nfnl_handle *nfnlh;
+ struct nflog_handle *lh;
+
+ nfnlh = nfnl_open();
+ if (!nfnlh) {
+ /* FIXME: nflog_errno */
+ return NULL;
+ }
+
+ lh = nflog_open_nfnl(nfnlh);
+ if (!lh)
+ nfnl_close(nfnlh);
+
+ return lh;
+}
+
int nflog_callback_register(struct nflog_g_handle *gh, nflog_callback *cb,
void *data)
{
@@ -209,12 +230,12 @@
int nflog_handle_packet(struct nflog_handle *h, char *buf, int len)
{
- return nfnl_handle_packet(&h->nfnlh, buf, len);
+ return nfnl_handle_packet(h->nfnlh, buf, len);
}
int nflog_close(struct nflog_handle *h)
{
- return nfnl_close(&h->nfnlh);
+ return nfnl_close(h->nfnlh);
}
/* bind nf_queue from a specific protocol family */
@@ -275,7 +296,7 @@
struct nfulnl_msg_config_mode params;
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
- nfnl_fill_hdr(&gh->h->nfnlh, nmh, 0, AF_UNSPEC, gh->id,
+ nfnl_fill_hdr(gh->h->nfnlssh, nmh, 0, AF_UNSPEC, gh->id,
NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
params.copy_range = htonl(range); /* copy_range is short */
@@ -283,7 +304,7 @@
nfnl_addattr_l(nmh, sizeof(buf), NFULA_CFG_MODE, ¶ms,
sizeof(params));
- return nfnl_talk(&gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
}
int nflog_set_timeout(struct nflog_g_handle *gh, u_int32_t timeout)
@@ -291,12 +312,12 @@
char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(u_int32_t))];
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
- nfnl_fill_hdr(&gh->h->nfnlh, nmh, 0, AF_UNSPEC, gh->id,
+ nfnl_fill_hdr(gh->h->nfnlssh, nmh, 0, AF_UNSPEC, gh->id,
NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
nfnl_addattr32(nmh, sizeof(buf), NFULA_CFG_TIMEOUT, htonl(timeout));
- return nfnl_talk(&gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
}
int nflog_set_qthresh(struct nflog_g_handle *gh, u_int32_t qthresh)
@@ -304,12 +325,12 @@
char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(u_int32_t))];
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
- nfnl_fill_hdr(&gh->h->nfnlh, nmh, 0, AF_UNSPEC, gh->id,
+ nfnl_fill_hdr(gh->h->nfnlssh, nmh, 0, AF_UNSPEC, gh->id,
NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
nfnl_addattr32(nmh, sizeof(buf), NFULA_CFG_QTHRESH, htonl(qthresh));
- return nfnl_talk(&gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
}
int nflog_set_nlbufsiz(struct nflog_g_handle *gh, u_int32_t nlbufsiz)
@@ -318,16 +339,16 @@
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
int status;
- nfnl_fill_hdr(&gh->h->nfnlh, nmh, 0, AF_UNSPEC, gh->id,
+ nfnl_fill_hdr(gh->h->nfnlssh, nmh, 0, AF_UNSPEC, gh->id,
NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
nfnl_addattr32(nmh, sizeof(buf), NFULA_CFG_NLBUFSIZ, htonl(nlbufsiz));
- status = nfnl_talk(&gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
+ status = nfnl_talk(gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
/* we try to have space for at least 10 messages in the socket buffer */
if (status >= 0)
- nfnl_rcvbufsiz(&gh->h->nfnlh, 10*nlbufsiz);
+ nfnl_rcvbufsiz(gh->h->nfnlh, 10*nlbufsiz);
return status;
}
Modified: trunk/libnetfilter_queue/configure.in
===================================================================
--- trunk/libnetfilter_queue/configure.in 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_queue/configure.in 2006-01-14 19:04:51 UTC (rev 6410)
@@ -3,7 +3,7 @@
AC_INIT
AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(libnetfilter_queue, 0.0.11)
+AM_INIT_AUTOMAKE(libnetfilter_queue, 0.0.12)
AC_PROG_CC
AC_EXEEXT
Modified: trunk/libnetfilter_queue/include/libnetfilter_queue/libnetfilter_queue.h
===================================================================
--- trunk/libnetfilter_queue/include/libnetfilter_queue/libnetfilter_queue.h 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_queue/include/libnetfilter_queue/libnetfilter_queue.h 2006-01-14 19:04:51 UTC (rev 6410)
@@ -32,6 +32,7 @@
extern struct nfq_handle *nfq_open(void);
+extern struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh);
extern int nfq_close(struct nfq_handle *h);
extern int nfq_bind_pf(struct nfq_handle *h, u_int16_t pf);
Modified: trunk/libnetfilter_queue/src/Makefile.am
===================================================================
--- trunk/libnetfilter_queue/src/Makefile.am 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_queue/src/Makefile.am 2006-01-14 19:04:51 UTC (rev 6410)
@@ -1,6 +1,6 @@
# This is _NOT_ the library release version, it's an API version.
# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
-LIBVERSION=1:0:0
+LIBVERSION=2:0:1
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I${KERNELDIR}
AM_CFLAGS=-fPIC -Wall
Modified: trunk/libnetfilter_queue/src/libnetfilter_queue.c
===================================================================
--- trunk/libnetfilter_queue/src/libnetfilter_queue.c 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnetfilter_queue/src/libnetfilter_queue.c 2006-01-14 19:04:51 UTC (rev 6410)
@@ -31,7 +31,8 @@
struct nfq_handle
{
- struct nfnl_handle nfnlh;
+ struct nfnl_handle *nfnlh;
+ struct nfnl_subsys_handle *nfnlssh;
struct nfq_q_handle *qh_list;
};
@@ -98,14 +99,14 @@
struct nfqnl_msg_config_cmd cmd;
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
- nfnl_fill_hdr(&h->nfnlh, nmh, 0, AF_UNSPEC, queuenum,
+ nfnl_fill_hdr(h->nfnlssh, nmh, 0, AF_UNSPEC, queuenum,
NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
cmd.command = command;
cmd.pf = htons(pf);
nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_CMD, &cmd, sizeof(cmd));
- return nfnl_talk(&h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
}
static int __nfq_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
@@ -137,7 +138,7 @@
struct nfnl_handle *nfq_nfnlh(struct nfq_handle *h)
{
- return &h->nfnlh;
+ return h->nfnlh;
}
int nfq_fd(struct nfq_handle *h)
@@ -147,6 +148,21 @@
struct nfq_handle *nfq_open(void)
{
+ struct nfnl_handle *nfnlh = nfnl_open();
+ struct nfq_handle *qh;
+
+ if (!nfnlh)
+ return NULL;
+
+ qh = nfq_open_nfnl(nfnlh);
+ if (!qh)
+ nfnl_close(nfnlh);
+
+ return qh;
+}
+
+struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh)
+{
struct nfq_handle *h;
int err;
@@ -156,14 +172,15 @@
memset(h, 0, sizeof(*h));
- err = nfnl_open(&h->nfnlh, NFNL_SUBSYS_QUEUE, NFQNL_MSG_MAX, 0);
- if (err < 0) {
- nfq_errno = err;
+ h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_QUEUE,
+ NFQNL_MSG_MAX, 0);
+ if (!h->nfnlssh) {
+ /* FIXME: nfq_errno */
goto out_free;
}
pkt_cb.data = h;
- err = nfnl_callback_register(&h->nfnlh, NFQNL_MSG_PACKET, &pkt_cb);
+ err = nfnl_callback_register(h->nfnlssh, NFQNL_MSG_PACKET, &pkt_cb);
if (err < 0) {
nfq_errno = err;
goto out_close;
@@ -171,7 +188,7 @@
return h;
out_close:
- nfnl_close(&h->nfnlh);
+ nfnl_subsys_close(h->nfnlssh);
out_free:
free(h);
return NULL;
@@ -179,7 +196,10 @@
int nfq_close(struct nfq_handle *h)
{
- int ret = nfnl_close(&h->nfnlh);
+ int ret;
+
+ nfnl_subsys_close(h->nfnlssh);
+ ret = nfnl_close(h->nfnlh);
if (ret == 0)
free(h);
return ret;
@@ -242,7 +262,7 @@
int nfq_handle_packet(struct nfq_handle *h, char *buf, int len)
{
- return nfnl_handle_packet(&h->nfnlh, buf, len);
+ return nfnl_handle_packet(h->nfnlh, buf, len);
}
int nfq_set_mode(struct nfq_q_handle *qh,
@@ -253,7 +273,7 @@
struct nfqnl_msg_config_params params;
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
- nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id,
+ nfnl_fill_hdr(qh->h->nfnlssh, nmh, 0, AF_UNSPEC, qh->id,
NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
params.copy_range = htonl(range);
@@ -261,7 +281,7 @@
nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_PARAMS, ¶ms,
sizeof(params));
- return nfnl_talk(&qh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
+ return nfnl_talk(qh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
}
static int __set_verdict(struct nfq_q_handle *qh, u_int32_t id,
@@ -282,7 +302,7 @@
vh.verdict = htonl(verdict);
vh.id = htonl(id);
- nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id,
+ nfnl_fill_hdr(qh->h->nfnlssh, nmh, 0, AF_UNSPEC, qh->id,
NFQNL_MSG_VERDICT, NLM_F_REQUEST);
/* add verdict header */
@@ -303,7 +323,7 @@
nvecs += 2;
}
- return nfnl_sendiov(&qh->h->nfnlh, iov, nvecs, 0);
+ return nfnl_sendiov(qh->h->nfnlh, iov, nvecs, 0);
}
int nfq_set_verdict(struct nfq_q_handle *qh, u_int32_t id,
Modified: trunk/libnfnetlink/configure.in
===================================================================
--- trunk/libnfnetlink/configure.in 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnfnetlink/configure.in 2006-01-14 19:04:51 UTC (rev 6410)
@@ -4,7 +4,7 @@
AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(libnfnetlink, 0.0.14)
+AM_INIT_AUTOMAKE(libnfnetlink, 0.0.16)
AC_PROG_CC
AC_EXEEXT
Modified: trunk/libnfnetlink/include/libnfnetlink/libnfnetlink.h
===================================================================
--- trunk/libnfnetlink/include/libnfnetlink/libnfnetlink.h 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnfnetlink/include/libnfnetlink/libnfnetlink.h 2006-01-14 19:04:51 UTC (rev 6410)
@@ -43,25 +43,20 @@
u_int16_t attr_count;
};
-struct nfnl_handle {
- int fd;
- struct sockaddr_nl local;
- struct sockaddr_nl peer;
- u_int8_t subsys_id;
- u_int32_t seq;
- u_int32_t dump;
- struct nlmsghdr *last_nlhdr;
+struct nfnl_handle;
+struct nfnl_subsys_handle;
- u_int8_t cb_count;
- struct nfnl_callback *cb; /* array of callbacks */
-};
-
extern int nfnl_fd(struct nfnl_handle *h);
/* get a new library handle */
-extern int nfnl_open(struct nfnl_handle *, u_int8_t, u_int8_t, unsigned int);
+extern struct nfnl_handle *nfnl_open(void);
extern int nfnl_close(struct nfnl_handle *);
+extern struct nfnl_subsys_handle *nfnl_subsys_open(struct nfnl_handle *,
+ u_int8_t, u_int8_t,
+ unsigned int);
+extern void nfnl_subsys_close(struct nfnl_subsys_handle *);
+
/* sending of data */
extern int nfnl_send(struct nfnl_handle *, struct nlmsghdr *);
extern int nfnl_sendmsg(const struct nfnl_handle *, const struct msghdr *msg,
@@ -69,7 +64,7 @@
extern int nfnl_sendiov(const struct nfnl_handle *nfnlh,
const struct iovec *iov, unsigned int num,
unsigned int flags);
-extern void nfnl_fill_hdr(struct nfnl_handle *, struct nlmsghdr *,
+extern void nfnl_fill_hdr(struct nfnl_subsys_handle *, struct nlmsghdr *,
unsigned int, u_int8_t, u_int16_t, u_int16_t,
u_int16_t);
extern int nfnl_talk(struct nfnl_handle *, struct nlmsghdr *, pid_t,
@@ -84,9 +79,9 @@
/* receiving */
extern ssize_t nfnl_recv(const struct nfnl_handle *h, unsigned char *buf, size_t len);
-extern int nfnl_callback_register(struct nfnl_handle *,
+extern int nfnl_callback_register(struct nfnl_subsys_handle *,
u_int8_t type, struct nfnl_callback *cb);
-extern int nfnl_callback_unregister(struct nfnl_handle *, u_int8_t type);
+extern int nfnl_callback_unregister(struct nfnl_subsys_handle *, u_int8_t type);
extern int nfnl_handle_packet(struct nfnl_handle *, char *buf, int len);
/* parsing */
Modified: trunk/libnfnetlink/src/Makefile.am
===================================================================
--- trunk/libnfnetlink/src/Makefile.am 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnfnetlink/src/Makefile.am 2006-01-14 19:04:51 UTC (rev 6410)
@@ -1,12 +1,13 @@
-#AUTOMAKE_OPTIONS = no-dependencies foreign
+# This is _NOT_ the library release version, it's an API version.
+# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
+LIBVERSION=1:0:0
-#EXTRA_DIST = $(man_MANS) acinclude.m4
-
INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS=-fPIC -Wall
LIBS=
lib_LTLIBRARIES = libnfnetlink.la
-libnfnetlink_la_LDFLAGS = -Wc,-nostartfiles
+libnfnetlink_la_LDFLAGS = -Wc,-nostartfiles \
+ -version-info $(LIBVERSION)
libnfnetlink_la_SOURCES = libnfnetlink.c
Modified: trunk/libnfnetlink/src/libnfnetlink.c
===================================================================
--- trunk/libnfnetlink/src/libnfnetlink.c 2006-01-13 20:54:52 UTC (rev 6409)
+++ trunk/libnfnetlink/src/libnfnetlink.c 2006-01-14 19:04:51 UTC (rev 6410)
@@ -1,8 +1,9 @@
/* libnfnetlink.c: generic library for communication with netfilter
*
- * (C) 2001 by Jay Schulist <jschlst at samba.org>
- * (C) 2002-2005 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2002-2006 by Harald Welte <laforge at gnumonks.org>
*
+ * Based on some original ideas from Jay Schulist <jschlst at samba.org>
+ *
* Development of this code funded by Astaro AG (http://www.astaro.com)
*
* this software may be used and distributed according to the terms
@@ -12,6 +13,9 @@
* Define structure nfnlhdr
* Added __be64_to_cpu function
* Use NFA_TYPE macro to get the attribute type
+ *
+ * 2006-01-14 Harald Welte <laforge at netfilter.org>:
+ * introduce nfnl_subsys_handle
*/
#include <stdlib.h>
@@ -36,6 +40,26 @@
#define nfnl_debug_dump_packet(a, b, ...)
#endif
+struct nfnl_subsys_handle {
+ struct nfnl_handle *nfnlh;
+ u_int32_t subscriptions;
+ u_int8_t subsys_id;
+ u_int8_t cb_count;
+ struct nfnl_callback *cb; /* array of callbacks */
+};
+
+#define NFNL_MAX_SUBSYS 16 /* enough for now */
+struct nfnl_handle {
+ int fd;
+ struct sockaddr_nl local;
+ struct sockaddr_nl peer;
+ u_int32_t subscriptions;
+ u_int32_t seq;
+ u_int32_t dump;
+ struct nlmsghdr *last_nlhdr;
+ struct nfnl_subsys_handle subsys[NFNL_MAX_SUBSYS+1];
+};
+
void nfnl_dump_packet(struct nlmsghdr *nlh, int received_len, char *desc)
{
void *nlmsg_data = NLMSG_DATA(nlh);
@@ -65,66 +89,134 @@
return h->fd;
}
+static int recalc_rebind_subscriptions(struct nfnl_handle *nfnlh)
+{
+ int i;
+ u_int32_t new_subscriptions = 0;
+
+ for (i = 0; i < NFNL_MAX_SUBSYS; i++)
+ new_subscriptions |= nfnlh->subsys[i].subscriptions;
+
+ if (nfnlh->subscriptions != new_subscriptions) {
+ int err;
+
+ nfnlh->local.nl_groups = new_subscriptions;
+ err = bind(nfnlh->fd, (struct sockaddr *)&nfnlh->local,
+ sizeof(nfnlh->local));
+ if (err < 0) {
+ nfnl_error("bind(netlink): %s", strerror(errno));
+ return err;
+ }
+ nfnlh->subscriptions = new_subscriptions;
+ }
+
+ return 0;
+}
+
/**
* nfnl_open - open a netlink socket
*
* nfnlh: libnfnetlink handle to be allocated by user
- * subsys_id: which nfnetlink subsystem we are interested in
- * cb_count: number of callbacks that are used maximum.
- * subscriptions: netlink groups we want to be subscribed to
*
*/
-int nfnl_open(struct nfnl_handle *nfnlh, u_int8_t subsys_id,
- u_int8_t cb_count, u_int32_t subscriptions)
+struct nfnl_handle *nfnl_open(void)
{
+ struct nfnl_handle *nfnlh;
+ unsigned int addr_len;
int err;
- unsigned int addr_len;
- struct nfnl_callback *cb;
- cb = malloc(sizeof(*cb) * cb_count);
- if (!cb)
- return -ENOMEM;
-
+ nfnlh = malloc(sizeof(*nfnlh));
+ if (!nfnlh)
+ return NULL;
+
memset(nfnlh, 0, sizeof(*nfnlh));
nfnlh->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
if (nfnlh->fd < 0) {
nfnl_error("socket(netlink): %s", strerror(errno));
- return nfnlh->fd;
+ goto err_free;
}
nfnlh->local.nl_family = AF_NETLINK;
- nfnlh->local.nl_groups = subscriptions;
-
nfnlh->peer.nl_family = AF_NETLINK;
- err = bind(nfnlh->fd, (struct sockaddr *)&nfnlh->local,
- sizeof(nfnlh->local));
- if (err < 0) {
- nfnl_error("bind(netlink): %s", strerror(errno));
- return err;
- }
-
addr_len = sizeof(nfnlh->local);
err = getsockname(nfnlh->fd, (struct sockaddr *)&nfnlh->local,
&addr_len);
if (addr_len != sizeof(nfnlh->local)) {
nfnl_error("Bad address length (%u != %zd)", addr_len,
sizeof(nfnlh->local));
- return -1;
+ goto err_close;
}
if (nfnlh->local.nl_family != AF_NETLINK) {
nfnl_error("Bad address family %d", nfnlh->local.nl_family);
- return -1;
+ goto err_close;
}
nfnlh->seq = time(NULL);
- nfnlh->subsys_id = subsys_id;
- nfnlh->cb_count = cb_count;
- nfnlh->cb = cb;
- return 0;
+ return nfnlh;
+
+err_close:
+ close(nfnlh->fd);
+err_free:
+ free(nfnlh);
+ return NULL;
}
/**
+ * nfnl_subsys_open - open a netlink subsystem
+ *
+ * nfnlh: libnfnetlink handle
+ * subsys_id: which nfnetlink subsystem we are interested in
+ * cb_count: number of callbacks that are used maximum.
+ * subscriptions: netlink groups we want to be subscribed to
+ */
+struct nfnl_subsys_handle *
+nfnl_subsys_open(struct nfnl_handle *nfnlh, u_int8_t subsys_id,
+ u_int8_t cb_count, u_int32_t subscriptions)
+{
+ struct nfnl_subsys_handle *ssh;
+
+ if (subsys_id > NFNL_MAX_SUBSYS) {
+
+ return NULL;
+ }
+
+ ssh = &nfnlh->subsys[subsys_id];
+ if (ssh->cb) {
+
+ return NULL;
+ }
+
+ ssh->cb = malloc(sizeof(*(ssh->cb)) * cb_count);
+ if (!ssh->cb) {
+
+ return NULL;
+ }
+
+ ssh->nfnlh = nfnlh;
+ ssh->cb_count = cb_count;
+ ssh->subscriptions = subscriptions;
+
+ if (recalc_rebind_subscriptions(nfnlh) < 0) {
+ free(ssh->cb);
+ ssh->cb = NULL;
+ return NULL;
+ }
+
+ return ssh;
+}
+
+void nfnl_subsys_close(struct nfnl_subsys_handle *ssh)
+{
+ ssh->subscriptions = 0;
+ ssh->cb_count = 0;
+ if (ssh->cb) {
+ free(ssh->cb);
+ ssh->cb = NULL;
+ }
+}
+
+/**
* nfnl_close - close netlink socket
*
* nfnlh: libnfnetlink handle
@@ -132,8 +224,18 @@
*/
int nfnl_close(struct nfnl_handle *nfnlh)
{
- free(nfnlh->cb);
- return close(nfnlh->fd);
+ int i, ret;
+
+ for (i = 0; i < NFNL_MAX_SUBSYS; i++)
+ nfnl_subsys_close(&nfnlh->subsys[i]);
+
+ ret = close(nfnlh->fd);
+ if (ret < 0)
+ return ret;
+
+ free(nfnlh);
+
+ return 0;
}
/**
@@ -187,7 +289,7 @@
* the size of struct nlmsghdr + struct nfgenmsg
*
*/
-void nfnl_fill_hdr(struct nfnl_handle *nfnlh,
+void nfnl_fill_hdr(struct nfnl_subsys_handle *ssh,
struct nlmsghdr *nlh, unsigned int len,
u_int8_t family,
u_int16_t res_id,
@@ -198,10 +300,10 @@
((void *)nlh + sizeof(*nlh));
nlh->nlmsg_len = NLMSG_LENGTH(len+sizeof(*nfg));
- nlh->nlmsg_type = (nfnlh->subsys_id<<8)|msg_type;
+ nlh->nlmsg_type = (ssh->subsys_id<<8)|msg_type;
nlh->nlmsg_flags = msg_flags;
nlh->nlmsg_pid = 0;
- nlh->nlmsg_seq = ++nfnlh->seq;
+ nlh->nlmsg_seq = ++ssh->nfnlh->seq;
nfg->nfgen_family = family;
nfg->version = NFNETLINK_V0;
@@ -693,23 +795,23 @@
return nlh;
}
-int nfnl_callback_register(struct nfnl_handle *h,
+int nfnl_callback_register(struct nfnl_subsys_handle *ssh,
u_int8_t type, struct nfnl_callback *cb)
{
- if (type >= h->cb_count)
+ if (type >= ssh->cb_count)
return -EINVAL;
- memcpy(&h->cb[type], cb, sizeof(*cb));
+ memcpy(&ssh->cb[type], cb, sizeof(*cb));
return 0;
}
-int nfnl_callback_unregister(struct nfnl_handle *h, u_int8_t type)
+int nfnl_callback_unregister(struct nfnl_subsys_handle *ssh, u_int8_t type)
{
- if (type >= h->cb_count)
+ if (type >= ssh->cb_count)
return -EINVAL;
- h->cb[type].call = NULL;
+ ssh->cb[type].call = NULL;
return 0;
}
@@ -720,12 +822,20 @@
{
int min_len;
u_int8_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
- struct nfnl_callback *cb = &h->cb[type];
+ u_int8_t subsys_id = NFNL_SUBSYS_ID(nlh->nlmsg_type);
+ const struct nfnl_subsys_handle *ssh;
+ struct nfnl_callback *cb;
+ if (subsys_id > NFNL_MAX_SUBSYS)
+ return -EINVAL;
+
+ ssh = &h->subsys[subsys_id];
+ cb = &ssh->cb[type];
+
#if 1
/* checks need to be enabled as soon as this is called from
* somebody else than __nfnl_handle_msg */
- if (type >= h->cb_count)
+ if (type >= ssh->cb_count)
return -EINVAL;
min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg));
@@ -755,26 +865,30 @@
static int __nfnl_handle_msg(struct nfnl_handle *h, struct nlmsghdr *nlh,
int len)
{
+ struct nfnl_subsys_handle *ssh;
u_int8_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
+ u_int8_t subsys_id = NFNL_SUBSYS_ID(nlh->nlmsg_type);
int err = 0;
- if (NFNL_SUBSYS_ID(nlh->nlmsg_type) != h->subsys_id)
+ if (subsys_id > NFNL_MAX_SUBSYS)
return -1;
+ ssh = &h->subsys[subsys_id];
+
if (nlh->nlmsg_len < NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg))))
return -1;
- if (type >= h->cb_count)
+ if (type >= ssh->cb_count)
return -1;
- if (h->cb[type].attr_count) {
- struct nfattr *nfa[h->cb[type].attr_count];
+ if (ssh->cb[type].attr_count) {
+ struct nfattr *nfa[ssh->cb[type].attr_count];
err = nfnl_check_attributes(h, nlh, nfa);
if (err < 0)
return err;
- if (h->cb[type].call)
- return h->cb[type].call(nlh, nfa, h->cb[type].data);
+ if (ssh->cb[type].call)
+ return ssh->cb[type].call(nlh, nfa, ssh->cb[type].data);
}
return 0;
}
More information about the netfilter-cvslog
mailing list