summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-01-04 17:16:39 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2012-01-04 17:16:39 +0100
commit8e63e483240687ee4c4325073d84926e39416bc9 (patch)
tree54848f691373638fc54c84c5f87938e18977f6b1
parent849342adcb7099d23b39192a4369908bb0259eee (diff)
expect: add nfexp_cmp
This patch adds nfexp_cmp that allows you to compare two expectation objects. This includes the extension of test_api for this new function. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/internal/prototypes.h2
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack.h4
-rw-r--r--qa/test_api.c22
-rw-r--r--src/conntrack/compare.c10
-rw-r--r--src/expect/Makefile.am1
-rw-r--r--src/expect/api.c34
-rw-r--r--src/expect/compare.c59
7 files changed, 126 insertions, 6 deletions
diff --git a/include/internal/prototypes.h b/include/internal/prototypes.h
index 5f1418f..7ca8d35 100644
--- a/include/internal/prototypes.h
+++ b/include/internal/prototypes.h
@@ -21,6 +21,7 @@ int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data);
int __setobjopt(struct nf_conntrack *ct, unsigned int option);
int __getobjopt(const struct nf_conntrack *ct, unsigned int option);
int __compare(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags);
+int __cmp_orig(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags);
void __copy_fast(struct nf_conntrack *ct1, const struct nf_conntrack *ct);
int __setup_netlink_socket_filter(int fd, struct nfct_filter *filter);
@@ -32,6 +33,7 @@ int __build_expect(struct nfnl_subsys_handle *ssh, struct nfnlhdr *req, size_t s
int __parse_expect_message_type(const struct nlmsghdr *nlh);
void __parse_expect(const struct nlmsghdr *nlh, struct nfattr *cda[], struct nf_expect *exp);
int __expect_callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data);
+int __cmp_expect(const struct nf_expect *exp1, const struct nf_expect *exp2, unsigned int flags);
int __snprintf_expect(char *buf, unsigned int len, const struct nf_expect *exp, unsigned int type, unsigned int msg_output, unsigned int flags);
int __snprintf_expect_default(char *buf, unsigned int len, const struct nf_expect *exp, unsigned int msg_type, unsigned int flags);
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index 89d07ad..2e1c22c 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -599,6 +599,10 @@ extern int nfexp_snprintf(char *buf,
const unsigned int out_type,
const unsigned int out_flags);
+/* compare */
+extern int nfexp_cmp(const struct nf_expect *exp1,
+ const struct nf_expect *exp2,
+ unsigned int flags);
extern int nfexp_send(struct nfct_handle *h,
const enum nf_conntrack_query qt,
diff --git a/qa/test_api.c b/qa/test_api.c
index 1efaf2f..74f02d0 100644
--- a/qa/test_api.c
+++ b/qa/test_api.c
@@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
#include <sys/wait.h>
#include <errno.h>
@@ -33,7 +34,7 @@ int main(void)
{
int ret, i;
struct nf_conntrack *ct, *tmp;
- struct nf_expect *exp;
+ struct nf_expect *exp, *tmp_exp;
char data[32];
const char *val;
int status;
@@ -135,6 +136,11 @@ int main(void)
perror("nfexp_new");
return 0;
}
+ tmp_exp = nfexp_new();
+ if (!tmp_exp) {
+ perror("nfexp_new");
+ return 0;
+ }
printf("== test expect set API ==\n");
ret = fork();
@@ -180,8 +186,22 @@ int main(void)
eval_sigterm(status);
}
+ /* XXX: missing nfexp_copy API. */
+ memcpy(tmp_exp, exp, nfexp_maxsize());
+
+ printf("== test expect cmp API ==\n");
+ ret = fork();
+ if (ret == 0) {
+ nfexp_cmp(tmp_exp, exp, 0);
+ exit(0);
+ } else {
+ wait(&status);
+ eval_sigterm(status);
+ }
+
nfct_destroy(ct);
nfct_destroy(tmp);
nfexp_destroy(exp);
+ nfexp_destroy(tmp_exp);
return EXIT_SUCCESS;
}
diff --git a/src/conntrack/compare.c b/src/conntrack/compare.c
index f94f1b9..830195f 100644
--- a/src/conntrack/compare.c
+++ b/src/conntrack/compare.c
@@ -144,9 +144,9 @@ cmp_orig_ipv6_dst(const struct nf_conntrack *ct1,
sizeof(struct in6_addr)) == 0);
}
-static int cmp_orig(const struct nf_conntrack *ct1,
- const struct nf_conntrack *ct2,
- unsigned int flags)
+int __cmp_orig(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2,
+ unsigned int flags)
{
if (!__cmp(ATTR_ORIG_L3PROTO, ct1, ct2, flags, cmp_orig_l3proto))
return 0;
@@ -399,10 +399,10 @@ int __compare(const struct nf_conntrack *ct1,
{
if ((flags & ~(NFCT_CMP_MASK|NFCT_CMP_STRICT)) == NFCT_CMP_ALL)
return cmp_meta(ct1, ct2, flags) &&
- cmp_orig(ct1, ct2, flags) &&
+ __cmp_orig(ct1, ct2, flags) &&
cmp_repl(ct1, ct2, flags);
- if (flags & NFCT_CMP_ORIG && !cmp_orig(ct1, ct2, flags))
+ if (flags & NFCT_CMP_ORIG && !__cmp_orig(ct1, ct2, flags))
return 0;
if (flags & NFCT_CMP_REPL && !cmp_repl(ct1, ct2, flags))
diff --git a/src/expect/Makefile.am b/src/expect/Makefile.am
index 8adf740..977a359 100644
--- a/src/expect/Makefile.am
+++ b/src/expect/Makefile.am
@@ -3,6 +3,7 @@ include $(top_srcdir)/Make_global.am
noinst_LTLIBRARIES = libnfexpect.la
libnfexpect_la_SOURCES = api.c \
+ compare.c \
getter.c setter.c \
parse.c build.c \
snprintf.c \
diff --git a/src/expect/api.c b/src/expect/api.c
index cf45091..4da44a0 100644
--- a/src/expect/api.c
+++ b/src/expect/api.c
@@ -99,6 +99,40 @@ struct nf_expect *nfexp_clone(const struct nf_expect *exp)
}
/**
+ * nfexp_cmp - compare two expectation objects
+ * \param exp1 pointer to a valid expectation object
+ * \param exp2 pointer to a valid expectation object
+ * \param flags flags
+ *
+ * This function only compare attribute set in both objects, by default
+ * the comparison is not strict, ie. if a certain attribute is not set in one
+ * of the objects, then such attribute is not used in the comparison.
+ * If you want more strict comparisons, you can use the appropriate flags
+ * to modify this behaviour (see NFCT_CMP_STRICT and NFCT_CMP_MASK).
+ *
+ * The available flags are:
+ * - NFCT_CMP_STRICT: the compared objects must have the same attributes
+ * and the same values, otherwise it returns that the objects are
+ * different.
+ * - NFCT_CMP_MASK: the first object is used as mask, this means that
+ * if an attribute is present in exp1 but not in exp2, this function
+ * returns that the objects are different.
+ *
+ * Other existing flags that are used by nfct_cmp() are ignored.
+ *
+ * If both conntrack object are equal, this function returns 1, otherwise
+ * 0 is returned.
+ */
+int nfexp_cmp(const struct nf_expect *exp1, const struct nf_expect *exp2,
+ unsigned int flags)
+{
+ assert(exp1 != NULL);
+ assert(exp2 != NULL);
+
+ return __cmp_expect(exp1, exp2, flags);
+}
+
+/**
* @}
*/
diff --git a/src/expect/compare.c b/src/expect/compare.c
new file mode 100644
index 0000000..65ec9c2
--- /dev/null
+++ b/src/expect/compare.c
@@ -0,0 +1,59 @@
+/*
+ * (C) 2005-2012 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2012 by Vyatta Inc. <http://www.vyatta.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "internal/internal.h"
+
+static int exp_cmp(int attr,
+ const struct nf_expect *exp1,
+ const struct nf_expect *exp2,
+ unsigned int flags,
+ int (*cmp)(const struct nf_expect *exp1,
+ const struct nf_expect *exp2,
+ unsigned int flags))
+{
+ if (test_bit(attr, exp1->set) && test_bit(attr, exp2->set)) {
+ return cmp(exp1, exp2, flags);
+ } else if (flags & NFCT_CMP_MASK &&
+ test_bit(attr, exp1->set)) {
+ return 0;
+ } else if (flags & NFCT_CMP_STRICT) {
+ return 0;
+ }
+ return 1;
+}
+
+static int
+cmp_exp_flags(const struct nf_expect *exp1, const struct nf_expect *exp,
+ unsigned int flags)
+{
+ return (exp->flags == exp->flags);
+}
+
+int __cmp_expect(const struct nf_expect *exp1,
+ const struct nf_expect *exp2,
+ unsigned int flags)
+{
+ if (!__cmp_orig((struct nf_conntrack *)&exp1->master,
+ (struct nf_conntrack *)&exp2->master, flags)) {
+ return 0;
+ }
+ if (!__cmp_orig((struct nf_conntrack *)&exp1->expected,
+ (struct nf_conntrack *)&exp2->expected, flags)) {
+ return 0;
+ }
+ if (!__cmp_orig((struct nf_conntrack *)&exp1->mask,
+ (struct nf_conntrack *)&exp2->mask, flags)) {
+ return 0;
+ }
+ if (!exp_cmp(ATTR_EXP_FLAGS, exp1, exp2, flags, cmp_exp_flags))
+ return 0;
+
+ return 1;
+}