]> granicus.if.org Git - libnl/commitdiff
define advanced attributes out
authorRich Fought <Rich.Fought@watchguard.com>
Sat, 13 Oct 2012 00:44:27 +0000 (17:44 -0700)
committerRich Fought <Rich.Fought@watchguard.com>
Sat, 13 Oct 2012 00:44:27 +0000 (17:44 -0700)
include/netlink/netfilter/exp.h
lib/netfilter/exp.c
lib/netfilter/exp_obj.c

index bb4c98e204dbf5a2f06610b91359a81cbb7d2a65..89a9d01687ede72ba60c5e7c0473163e8bfeb12e 100644 (file)
 #include <netlink/cache.h>
 #include <netlink/msg.h>
 
+#include <linux/version.h>
+
+#if CTA_EXPECT_MAX > CTA_EXPECT_HELP_NAME
+#define NLE_ZONE
+#elseif CTA_EXPECT_MAX > CTA_EXPECT_ZONE
+#define NLE_ZONE
+#define NLE_FLAGS
+#elseif (CTA_EXPECT_MAX > CTA_EXPECT_FLAGS)
+#define NLE_ZONE
+#define NLE_FLAGS
+#define NLE_NAT_FN_CLASS
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -29,7 +42,10 @@ enum nfnl_exp_tuples {
     NFNL_EXP_TUPLE_EXPECT,
     NFNL_EXP_TUPLE_MASTER,
     NFNL_EXP_TUPLE_MASK,
-    NFNL_EXP_TUPLE_NAT
+#ifdef NLE_NAT_FN_CLASS
+    NFNL_EXP_TUPLE_NAT,
+#endif
+    NFNL_EXP_TUPLE_MAX
 };
 
 extern struct nl_object_ops exp_obj_ops;
@@ -72,17 +88,22 @@ extern int  nfnl_exp_set_helper_name(struct nfnl_exp *, void *);
 extern int  nfnl_exp_test_helper_name(const struct nfnl_exp *);
 extern const char * nfnl_exp_get_helper_name(const struct nfnl_exp *);
 
+#ifdef NLE_ZONE
 extern void nfnl_exp_set_zone(struct nfnl_exp *, uint16_t);
 extern int  nfnl_exp_test_zone(const struct nfnl_exp *);
 extern uint16_t nfnl_exp_get_zone(const struct nfnl_exp *);
+#endif
 
-extern void nfnl_exp_set_class(struct nfnl_exp *, uint32_t);
-extern int  nfnl_exp_test_class(const struct nfnl_exp *);
-extern uint32_t nfnl_exp_get_class(const struct nfnl_exp *);
-
+#ifdef NLE_FLAGS
 extern void nfnl_exp_set_flags(struct nfnl_exp *, uint32_t);
 extern int  nfnl_exp_test_flags(const struct nfnl_exp *);
 extern uint32_t nfnl_exp_get_flags(const struct nfnl_exp *);
+#endif
+
+#ifdef NLE_NAT_FN_CLASS
+extern void nfnl_exp_set_class(struct nfnl_exp *, uint32_t);
+extern int  nfnl_exp_test_class(const struct nfnl_exp *);
+extern uint32_t nfnl_exp_get_class(const struct nfnl_exp *);
 
 extern int  nfnl_exp_set_fn(struct nfnl_exp *, void *);
 extern int  nfnl_exp_test_fn(const struct nfnl_exp *);
@@ -91,6 +112,7 @@ extern const char * nfnl_exp_get_fn(const struct nfnl_exp *);
 extern void nfnl_exp_set_nat_dir(struct nfnl_exp *, uint8_t);
 extern int  nfnl_exp_test_nat_dir(const struct nfnl_exp *);
 extern uint8_t nfnl_exp_get_nat_dir(const struct nfnl_exp *);
+#endif
 
 // The int argument specifies which nfnl_exp_dir (expect, master, mask or nat)
 // Expectation objects only use orig, not reply
index 26eaf0cba6dc1c5c8508f895217f0e0704f0f136..cbe1b95a714a9a18251cc445bb4f95b9c974190a 100644 (file)
@@ -37,12 +37,16 @@ static struct nla_policy exp_policy[CTA_EXPECT_MAX+1] = {
        [CTA_EXPECT_TIMEOUT]    = { .type = NLA_U32 },
        [CTA_EXPECT_ID]             = { .type = NLA_U32 },
        [CTA_EXPECT_HELP_NAME]  = { .type = NLA_STRING },
-#if 0
-       [CTA_EXPECT_ZONE]       = { .type = NLA_U16 },    // In latest kernel header
-    [CTA_EXPECT_FLAGS]      = { .type = NLA_U32 },    // In latest kernel header
-       [CTA_EXPECT_CLASS]      = { .type = NLA_U32 },    // In libnetfilter_conntrack include/linux/linux_nfnetlink_conntrack.h
-    [CTA_EXPECT_NAT]        = { .type = NLA_NESTED }, // In libnetfilter_conntrack include/linux/linux_nfnetlink_conntrack.h
-    [CTA_EXPECT_FN]         = { .type = NLA_STRING }, // In libnetfilter_conntrack include/linux/linux_nfnetlink_conntrack.h
+#ifdef NLE_ZONE
+       [CTA_EXPECT_ZONE]       = { .type = NLA_U16 },    // Added in kernel 2.6.34
+#endif
+#ifdef NLE_FLAGS
+       [CTA_EXPECT_FLAGS]      = { .type = NLA_U32 },    // Added in kernel 2.6.37
+#endif
+#ifdef NLE_NAT_FN_CLASS
+       [CTA_EXPECT_CLASS]      = { .type = NLA_U32 },    // Added in kernel 3.5
+    [CTA_EXPECT_NAT]        = { .type = NLA_NESTED }, // Added in kernel 3.5
+    [CTA_EXPECT_FN]         = { .type = NLA_STRING }, // Added in kernel 3.5
 #endif
 };
 
@@ -59,10 +63,10 @@ static struct nla_policy exp_ip_policy[CTA_IP_MAX+1] = {
 };
 
 static struct nla_policy exp_proto_policy[CTA_PROTO_MAX+1] = {
-       [CTA_PROTO_NUM]         = { .type = NLA_U8 },
+       [CTA_PROTO_NUM]             = { .type = NLA_U8 },
        [CTA_PROTO_SRC_PORT]    = { .type = NLA_U16 },
        [CTA_PROTO_DST_PORT]    = { .type = NLA_U16 },
-       [CTA_PROTO_ICMP_ID]     = { .type = NLA_U16 },
+       [CTA_PROTO_ICMP_ID]         = { .type = NLA_U16 },
        [CTA_PROTO_ICMP_TYPE]   = { .type = NLA_U8 },
        [CTA_PROTO_ICMP_CODE]   = { .type = NLA_U8 },
        [CTA_PROTO_ICMPV6_ID]   = { .type = NLA_U16 },
@@ -70,6 +74,12 @@ static struct nla_policy exp_proto_policy[CTA_PROTO_MAX+1] = {
        [CTA_PROTO_ICMPV6_CODE] = { .type = NLA_U8 },
 };
 
+#ifdef NLE_NAT_FN_CLASS
+static struct nla_policy exp_nat_policy[CTA_EXPECT_NAT_MAX+1] = {
+    [CTA_EXPECT_NAT_DIR]     = { .type = NLA_U8 },
+    [CTA_EXPECT_NAT_TUPLE]   = { .type = NLA_NESTED },
+};
+#endif
 
 static int exp_parse_ip(struct nfnl_exp *exp, int tuple, struct nlattr *attr)
 {
@@ -182,6 +192,29 @@ static int exp_parse_tuple(struct nfnl_exp *exp, int tuple, struct nlattr *attr)
        return 0;
 }
 
+#ifdef NLE_NAT_FN_CLASS
+static int exp_parse_nat(struct nfnl_exp *exp, struct nlattr *attr)
+{
+    struct nlattr *tb[CTA_EXPECT_NAT_MAX+1];
+    int err;
+
+    err = nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr, exp_nat_policy);
+    if (err < 0)
+        return err;
+
+    if (tb[CTA_EXPECT_NAT_DIR])
+        nfnl_exp_set_nat_dir(exp, nla_get_u8(tb[CTA_EXPECT_NAT_DIR]));
+
+    if (tb[CTA_EXPECT_NAT_TUPLE]) {
+        err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_NAT, tb[CTA_EXPECT_NAT_TUPLE]);
+        if (err < 0)
+            return err;
+    }
+
+    return 0;
+}
+#endif
+
 int nfnlmsg_exp_group(struct nlmsghdr *nlh)
 {
        switch (nfnlmsg_subtype(nlh)) {
@@ -232,13 +265,41 @@ int nfnlmsg_exp_parse(struct nlmsghdr *nlh, struct nfnl_exp **result)
                        goto errout;
        }
 
+#ifdef NLE_NAT_FN_CLASS
+    if (tb[CTA_EXPECT_NAT])
+        err = exp_parse_nat(exp, tb[CTA_EXPECT_MASK]);
+        if (err < 0)
+            goto errout;
+
+    if (tb[CTA_EXPECT_CLASS])
+        nfnl_exp_set_class(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_CLASS])));
+
+    if (tb[CTA_EXPECT_FN])
+        nfnl_exp_set_fn(exp, nla_data(tb[CTA_EXPECT_FN]));
+
+#endif
+
+
        if (tb[CTA_EXPECT_TIMEOUT])
                nfnl_exp_set_timeout(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_TIMEOUT])));
+
        if (tb[CTA_EXPECT_ID])
                nfnl_exp_set_id(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_ID])));
-    if (tb[CTA_EXPECT_HELP_NAME])
+
+       if (tb[CTA_EXPECT_HELP_NAME])
         nfnl_exp_set_helper_name(exp, nla_data(tb[CTA_EXPECT_HELP_NAME]));
 
+#ifdef NLE_ZONE
+    if (tb[CTA_EXPECT_ZONE])
+        nfnl_exp_set_zone(exp, ntohs(nla_get_u16(tb[CTA_EXPECT_ZONE])));
+#endif
+
+#ifdef NLE_FLAGS
+    if (tb[CTA_EXPECT_FLAGS])
+        nfnl_exp_set_flags(exp, ntohl(nla_get_u32(tb[CTA_EXPECT_FLAGS])));
+#endif
+
+
        *result = exp;
        return 0;
 
@@ -364,6 +425,30 @@ nla_put_failure:
        return -NLE_MSGSIZE;
 }
 
+#ifdef NLE_NAT_FN_CLASS
+static int nfnl_exp_build_nat(struct nl_msg *msg, const struct nfnl_exp *exp)
+{
+    struct nlattr *nat;
+    int err;
+
+    nat = nla_nest_start(msg, CTA_EXPECT_NAT);
+
+    if (nfnl_exp_test_nat_dir(exp)) {
+        NLA_PUT_U8(msg, CTA_EXPECT_NAT_DIR,
+                nfnl_exp_get_nat_dir(exp));
+    }
+
+    if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_NAT_TUPLE)) < 0)
+        goto nla_put_failure;
+
+    nla_nest_end(msg, nat);
+    return 0;
+
+nla_put_failure:
+    return -NLE_MSGSIZE;
+}
+#endif
+
 static int nfnl_exp_build_message(const struct nfnl_exp *exp, int cmd, int flags,
                                 struct nl_msg **result)
 {
@@ -384,7 +469,20 @@ static int nfnl_exp_build_message(const struct nfnl_exp *exp, int cmd, int flags
     if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_MASK)) < 0)
         goto err_out;
 
-    // FIXME timeout and helper name
+#ifdef NLE_NAT_FN_CLASS
+    if (nfnl_exp_test_src(exp, NFNL_EXP_TUPLE_NAT)) {
+        if ((err = nfnl_exp_build_nat(msg, exp)) < 0)
+            goto err_out;
+    }
+
+    if (nfnl_exp_test_class(exp))
+        NLA_PUT_U32(msg, CTA_EXPECT_CLASS, htonl(nfnl_exp_get_class(exp)));
+
+    if (nfnl_exp_test_fn(exp))
+        NLA_PUT_STRING(msg, CTA_EXPECT_FN, nfnl_exp_get_fn(exp));
+
+#endif
+
     if (nfnl_exp_test_id(exp))
         NLA_PUT_U32(msg, CTA_EXPECT_ID, htonl(nfnl_exp_get_id(exp)));
 
@@ -394,6 +492,16 @@ static int nfnl_exp_build_message(const struct nfnl_exp *exp, int cmd, int flags
     if (nfnl_exp_test_helper_name(exp))
         NLA_PUT_STRING(msg, CTA_EXPECT_HELP_NAME, nfnl_exp_get_helper_name(exp));
 
+#ifdef NLE_ZONE
+    if (nfnl_exp_test_zone(exp))
+        NLA_PUT_U16(msg, CTA_EXPECT_ZONE, htons(nfnl_exp_get_zone(exp)));
+#endif
+
+#ifdef NLE_FLAGS
+    if (nfnl_exp_test_flags(exp))
+        NLA_PUT_U32(msg, CTA_EXPECT_FLAGS, htonl(nfnl_exp_get_flags(exp)));
+#endif
+
        *result = msg;
        return 0;
 
index 69ba324c7711691bd06df0950fe2a2d6c029166c..daf4b098a80c55efdfdd1576dab70ccef32d16ae 100644 (file)
 #define EXP_ATTR_ID                       (1UL << 2) // 32-bit
 #define EXP_ATTR_HELPER_NAME          (1UL << 3) // string (16 bytes max)
 #define EXP_ATTR_ZONE                 (1UL << 4) // 16-bit
-#define EXP_ATTR_CLASS                (1UL << 5) // 32-bit ???
-#define EXP_ATTR_FLAGS                (1UL << 6) // 32-bit
+#define EXP_ATTR_FLAGS                (1UL << 5) // 32-bit
+#define EXP_ATTR_CLASS                (1UL << 6) // 32-bit ???
 #define EXP_ATTR_FN                   (1UL << 7) // String ???
-
 // Tuples
 #define EXP_ATTR_EXPECT_IP_SRC        (1UL << 8)
 #define EXP_ATTR_EXPECT_IP_DST        (1UL << 9)
@@ -188,7 +187,7 @@ static void exp_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p)
        int i = 0;
     char buf[64];
 
-       for (i = NFNL_EXP_TUPLE_EXPECT; i <= NFNL_EXP_TUPLE_NAT; i++) {
+       for (i = NFNL_EXP_TUPLE_EXPECT; i < NFNL_EXP_TUPLE_MAX; i++) {
         tuple_src = NULL;
         tuple_dst = NULL;
         tuple_sport = 0;
@@ -216,8 +215,10 @@ static void exp_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p)
         dump_icmp(p, exp, 0);
     }
 
+#ifdef NLE_NAT_FN_CLASS
     if (nfnl_exp_test_nat_dir(exp))
         nl_dump(p, "nat dir %s ", exp->exp_nat_dir);
+#endif
 
 }
 
@@ -254,18 +255,22 @@ static void exp_dump_details(struct nl_object *a, struct nl_dump_params *p)
     if (nfnl_exp_test_helper_name(exp))
         nl_dump(p, "helper %s ", exp->exp_helper_name);
 
+#ifdef NLE_NAT_FN_CLASS
     if (nfnl_exp_test_fn(exp))
         nl_dump(p, "fn %s ", exp->exp_fn);
 
-    if (nfnl_exp_test_zone(exp))
-        nl_dump(p, "zone %u ", nfnl_exp_get_zone(exp));
-
     if (nfnl_exp_test_class(exp))
         nl_dump(p, "class %u ", nfnl_exp_get_class(exp));
+#endif
 
-       if (nfnl_exp_test_flags(exp))
-               nl_dump(p, "<");
+#ifdef NLE_ZONE
+    if (nfnl_exp_test_zone(exp))
+        nl_dump(p, "zone %u ", nfnl_exp_get_zone(exp));
+#endif
 
+#ifdef NLE_FLAGS
+    if (nfnl_exp_test_flags(exp))
+               nl_dump(p, "<");
 #define PRINT_FLAG(str) \
        { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); }
 
@@ -279,40 +284,10 @@ static void exp_dump_details(struct nl_object *a, struct nl_dump_params *p)
 
        if (nfnl_exp_test_flags(exp))
                nl_dump(p, ">");
-       nl_dump(p, "\n");
-}
+#endif
 
-/*
-static void ct_dump_stats(struct nl_object *a, struct nl_dump_params *p)
-{
-       struct nfnl_ct *ct = (struct nfnl_ct *) a;
-       double res;
-       char *unit;
-       uint64_t packets;
-       const char * const names[] = {"rx", "tx"};
-       int i;
-
-       ct_dump_details(a, p);
-
-       if (!nfnl_ct_test_bytes(ct, 0) ||
-           !nfnl_ct_test_packets(ct, 0) ||
-           !nfnl_ct_test_bytes(ct, 1) ||
-           !nfnl_ct_test_packets(ct, 1))
-           {
-               nl_dump_line(p, "    Statistics are not available.\n");
-               nl_dump_line(p, "    Please set sysctl net.netfilter.nf_conntrack_acct=1\n");
-               nl_dump_line(p, "    (Require kernel 2.6.27)\n");
-               return;
-           }
-
-       nl_dump_line(p, "        # packets      volume\n");
-       for (i=0; i<=1; i++) {
-               res = nl_cancel_down_bytes(nfnl_ct_get_bytes(ct, i), &unit);
-               packets = nfnl_ct_get_packets(ct, i);
-               nl_dump_line(p, "    %s %10" PRIu64  " %7.2f %s\n", names[i], packets, res, unit);
-       }
+       nl_dump(p, "\n");
 }
-*/
 
 static int exp_cmp_l4proto_ports (union nfnl_exp_protodata *a, union nfnl_exp_protodata *b) {
     // Must return 0 for match, 1 for mismatch
@@ -637,6 +612,7 @@ uint8_t nfnl_exp_get_nat_dir(const struct nfnl_exp *exp)
     return exp->exp_nat_dir;
 }
 
+#ifdef NLE_NAT_FN_CLASS
 #define EXP_GET_TUPLE(e, t) \
     (t == NFNL_EXP_TUPLE_MASTER) ? \
         &(e->exp_master) : \
@@ -644,6 +620,13 @@ uint8_t nfnl_exp_get_nat_dir(const struct nfnl_exp *exp)
         &(e->exp_mask) : \
     (t == NFNL_EXP_TUPLE_NAT) ? \
         &(e->exp_nat) : &(exp->exp_expect)
+#else
+#define EXP_GET_TUPLE(e, t) \
+    (t == NFNL_EXP_TUPLE_MASTER) ? \
+        &(e->exp_master) : \
+    (t == NFNL_EXP_TUPLE_MASK) ? \
+        &(e->exp_mask) : &(exp->exp_expect)
+#endif
 
 static int exp_get_src_attr(int tuple)
 {
@@ -656,9 +639,11 @@ static int exp_get_src_attr(int tuple)
         case NFNL_EXP_TUPLE_MASK:
             attr = EXP_ATTR_MASK_IP_SRC;
             break;
+#ifdef NLE_NAT_FN_CLASS
         case NFNL_EXP_TUPLE_NAT:
             attr = EXP_ATTR_NAT_IP_SRC;
             break;
+#endif
         case NFNL_EXP_TUPLE_EXPECT:
         default :
             attr = EXP_ATTR_EXPECT_IP_SRC;
@@ -679,9 +664,11 @@ static int exp_get_dst_attr(int tuple)
         case NFNL_EXP_TUPLE_MASK:
             attr = EXP_ATTR_MASK_IP_DST;
             break;
+#ifdef NLE_NAT_FN_CLASS
         case NFNL_EXP_TUPLE_NAT:
             attr = EXP_ATTR_NAT_IP_DST;
             break;
+#endif
         case NFNL_EXP_TUPLE_EXPECT:
         default :
             attr = EXP_ATTR_EXPECT_IP_DST;
@@ -765,9 +752,11 @@ static int exp_get_l4protonum_attr(int tuple)
         case NFNL_EXP_TUPLE_MASK:
             attr = EXP_ATTR_MASK_L4PROTO_NUM;
             break;
+#ifdef NLE_NAT_FN_CLASS
         case NFNL_EXP_TUPLE_NAT:
             attr = EXP_ATTR_NAT_L4PROTO_NUM;
             break;
+#endif
         case NFNL_EXP_TUPLE_EXPECT:
         default :
             attr = EXP_ATTR_EXPECT_L4PROTO_NUM;
@@ -807,9 +796,11 @@ static int exp_get_l4ports_attr(int tuple)
         case NFNL_EXP_TUPLE_MASK:
             attr = EXP_ATTR_MASK_L4PROTO_PORTS;
             break;
+#ifdef NLE_NAT_FN_CLASS
         case NFNL_EXP_TUPLE_NAT:
             attr = EXP_ATTR_NAT_L4PROTO_PORTS;
             break;
+#endif
         case NFNL_EXP_TUPLE_EXPECT:
         default :
             attr = EXP_ATTR_EXPECT_L4PROTO_PORTS;
@@ -858,9 +849,11 @@ static int exp_get_l4icmp_attr(int tuple)
         case NFNL_EXP_TUPLE_MASK:
             attr = EXP_ATTR_MASK_L4PROTO_ICMP;
             break;
+#ifdef NLE_NAT_FN_CLASS
         case NFNL_EXP_TUPLE_NAT:
             attr = EXP_ATTR_NAT_L4PROTO_ICMP;
             break;
+#endif
         case NFNL_EXP_TUPLE_EXPECT:
         default :
             attr = EXP_ATTR_EXPECT_L4PROTO_ICMP;