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-05 13:22:19 +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-05 13:22:19 +0000
commit66a41c1c413e39ba39e41d72d18abb36a1491d46 (patch)
tree94299200681a8ba19517f25649b66d449cc5fc54
parent9cac907e38eca19e4aa00bf809141de8bf31faa8 (diff)
This patch includes the following updates for the userspace
libnfnetlink_conntrack library: a) change ctnl_open prototype: Now the subsystem is passed as parameter to select if we work working with given subsystem, say NFNL_CTNETLINK_CONNTRACK[_EXP]. b) added functions ctnl_[new|get|del]_expect c) minor change in ctnl_build_tuple that let us create tuples based on CTA_* and CTA_EXPECT_* attributes. (Pablo Neira)
-rw-r--r--include/libnfnetlink_conntrack/libnfnetlink_conntrack.h7
-rw-r--r--src/libnfnetlink_conntrack.c111
2 files changed, 109 insertions, 9 deletions
diff --git a/include/libnfnetlink_conntrack/libnfnetlink_conntrack.h b/include/libnfnetlink_conntrack/libnfnetlink_conntrack.h
index f5dfa8c..151dd30 100644
--- a/include/libnfnetlink_conntrack/libnfnetlink_conntrack.h
+++ b/include/libnfnetlink_conntrack/libnfnetlink_conntrack.h
@@ -99,7 +99,7 @@ struct ctnl_handle {
struct ctnl_msg_handler *handler[IPCTNL_MSG_MAX];
};
-extern int ctnl_open(struct ctnl_handle *, unsigned);
+extern int ctnl_open(struct ctnl_handle *, u_int8_t, unsigned);
extern int ctnl_close(struct ctnl_handle *);
extern int ctnl_unregister_handler(struct ctnl_handle *, int);
extern int ctnl_register_handler(struct ctnl_handle *,
@@ -113,6 +113,11 @@ extern int ctnl_list_conntrack_zero_counters(struct ctnl_handle *, int);
extern int ctnl_event_conntrack(struct ctnl_handle *, int);
extern int ctnl_flush_conntrack(struct ctnl_handle *);
+extern int ctnl_new_expect(struct ctnl_handle *, struct ctnl_tuple *,
+ struct ctnl_tuple *, struct ctnl_tuple *,
+ unsigned long);
+extern int ctnl_del_expect(struct ctnl_handle *,struct ctnl_tuple *);
+extern int ctnl_get_expect(struct ctnl_handle *, struct ctnl_tuple *);
extern int ctnl_list_expect(struct ctnl_handle *, int);
extern int ctnl_event_expect(struct ctnl_handle *, int);
extern int ctnl_flush_expect(struct ctnl_handle *);
diff --git a/src/libnfnetlink_conntrack.c b/src/libnfnetlink_conntrack.c
index 08f8a08..868cf96 100644
--- a/src/libnfnetlink_conntrack.c
+++ b/src/libnfnetlink_conntrack.c
@@ -60,7 +60,8 @@ static int list_conntrack_handler(struct sockaddr_nl *nladdr,
struct ctnl_msg_handler *hdlr = cth->handler[type];
int ret;
- if (NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK) {
+ if (NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK &&
+ NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK_EXP) {
ctnl_error("received message for wrong subsys, skipping\n");
nfnl_dump_packet(n, n->nlmsg_len, "list_conntrack_handler");
return 0;
@@ -91,13 +92,14 @@ static int list_conntrack_handler(struct sockaddr_nl *nladdr,
* cth: pointer to already allocated library handle
* subscriptions: netlink groups we are interested in
*/
-int ctnl_open(struct ctnl_handle *cth, unsigned subscriptions)
+int ctnl_open(struct ctnl_handle *cth, u_int8_t subsys_id,
+ unsigned subscriptions)
{
int err;
memset(cth, 0, sizeof(*cth));
- err = nfnl_open(&cth->nfnlh, NFNL_SUBSYS_CTNETLINK, subscriptions);
+ err = nfnl_open(&cth->nfnlh, subsys_id, subscriptions);
if (err < 0) {
return err;
}
@@ -249,9 +251,8 @@ static void ctnl_build_tuple_proto(struct nfnlhdr *req, int size,
}
static void ctnl_build_tuple(struct nfnlhdr *req, int size,
- struct ctnl_tuple *t, int dir)
+ struct ctnl_tuple *t, int type)
{
- enum ctattr_type type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
struct nfattr *nest;
nest = nfnl_nest(&req->nlh, size, type);
@@ -329,9 +330,9 @@ static void ctnl_build_conntrack(struct nfnlhdr *req, int size,
struct ctnl_conntrack *ct)
{
ctnl_build_tuple(req, size, &ct->tuple[CTNL_DIR_ORIGINAL],
- CTNL_DIR_ORIGINAL);
+ CTA_TUPLE_ORIG);
ctnl_build_tuple(req, size, &ct->tuple[CTNL_DIR_REPLY],
- CTNL_DIR_REPLY);
+ CTA_TUPLE_REPLY);
nfnl_addattr_l(&req->nlh, size, CTA_STATUS, &ct->status,
sizeof(unsigned int));
@@ -382,6 +383,7 @@ int ctnl_del_conntrack(struct ctnl_handle *cth,
{
struct nfnlhdr *req;
char buf[CTNL_BUFFSIZE];
+ int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
memset(&buf, 0, sizeof(buf));
req = (void *) &buf;
@@ -390,7 +392,7 @@ int ctnl_del_conntrack(struct ctnl_handle *cth,
0, AF_INET, 0, IPCTNL_MSG_CT_DELETE,
NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
- ctnl_build_tuple(req, sizeof(buf), tuple, dir);
+ ctnl_build_tuple(req, sizeof(buf), tuple, type);
if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0)
return -1;
@@ -470,3 +472,96 @@ int ctnl_flush_expect(struct ctnl_handle *cth)
return nfnl_listen(&cth->nfnlh, &list_conntrack_handler, cth);
}
+
+/**
+ * ctnl_new_expect - create a new expectation
+ *
+ * cth: libctnetlink handle
+ * master_tuple: tuple of the master original direction
+ * t: direction, original or reply.
+ * exp_tuple: tuple of to-be-created expectation
+ * mask: mask of to-be-created expectation
+ * timeout: timeout of new expectation
+ */
+int ctnl_new_expect(struct ctnl_handle *cth,
+ struct ctnl_tuple *master,
+ struct ctnl_tuple *tuple,
+ struct ctnl_tuple *mask,
+ unsigned long timeout)
+{
+ struct nfnlhdr *req;
+ char buf[CTNL_BUFFSIZE];
+
+ memset(&buf, 0, sizeof(buf));
+ req = (void *) &buf;
+
+ nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf,
+ 0, AF_INET, 0, IPCTNL_MSG_EXP_NEW,
+ NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK);
+
+ ctnl_build_tuple(req, sizeof(buf), master, CTA_EXPECT_MASTER);
+ ctnl_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_TUPLE);
+ ctnl_build_tuple(req, sizeof(buf), mask, CTA_EXPECT_MASK);
+
+ if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_TIMEOUT, &timeout,
+ sizeof(timeout)) < 0)
+ return -1;
+
+ if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0 ) {
+ ctnl_error("error while nfnl_send\n");
+ return -1;
+ }
+
+ return nfnl_listen(&cth->nfnlh, &list_conntrack_handler, cth);
+}
+
+/**
+ * ctnl_del_expect - delete an expectation from conntrack subsystem
+ *
+ * cth: libctnetlink handle
+ * t: tuple of to-be-deleted expectation
+ */
+int ctnl_del_expect(struct ctnl_handle *cth,
+ struct ctnl_tuple *tuple)
+{
+ struct nfnlhdr *req;
+ char buf[CTNL_BUFFSIZE];
+
+ memset(&buf, 0, sizeof(buf));
+ req = (void *) &buf;
+
+ nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf,
+ 0, AF_INET, 0, IPCTNL_MSG_EXP_DELETE,
+ NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
+
+ ctnl_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER);
+
+ if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0)
+ return -1;
+
+ return nfnl_listen(&cth->nfnlh, &list_conntrack_handler, cth);
+}
+
+int ctnl_get_expect(struct ctnl_handle *cth,
+ struct ctnl_tuple *tuple)
+{
+ struct nfnlhdr *req;
+ char buf[CTNL_BUFFSIZE];
+
+ memset(&buf, 0, sizeof(buf));
+ req = (void *) &buf;
+
+ nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf,
+ 0, AF_INET, 0, IPCTNL_MSG_EXP_GET,
+ NLM_F_REQUEST|NLM_F_ACK);
+
+ ctnl_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER);
+
+ if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0 ) {
+ ctnl_error("error while nfnl_send\n");
+ return -1;
+ }
+
+ return nfnl_listen(&cth->nfnlh, &list_conntrack_handler, cth);
+}
+