00001
00002
00003
00004
00005
00006
00007
00008 #include "internal/internal.h"
00009
00010 static void __build_timeout(struct nfnlhdr *req,
00011 size_t size,
00012 const struct nf_expect *exp)
00013 {
00014 nfnl_addattr32(&req->nlh, size, CTA_EXPECT_TIMEOUT,htonl(exp->timeout));
00015 }
00016
00017 static void __build_zone(struct nfnlhdr *req, size_t size,
00018 const struct nf_expect *exp)
00019 {
00020 nfnl_addattr16(&req->nlh, size, CTA_EXPECT_ZONE, htons(exp->zone));
00021 }
00022
00023 static void __build_flags(struct nfnlhdr *req,
00024 size_t size, const struct nf_expect *exp)
00025 {
00026 nfnl_addattr32(&req->nlh, size, CTA_EXPECT_FLAGS,htonl(exp->flags));
00027 }
00028
00029 int __build_expect(struct nfnl_subsys_handle *ssh,
00030 struct nfnlhdr *req,
00031 size_t size,
00032 u_int16_t type,
00033 u_int16_t flags,
00034 const struct nf_expect *exp)
00035 {
00036 u_int8_t l3num;
00037
00038 if (test_bit(ATTR_ORIG_L3PROTO, exp->master.set))
00039 l3num = exp->master.tuple[__DIR_ORIG].l3protonum;
00040 else if (test_bit(ATTR_ORIG_L3PROTO, exp->expected.set))
00041 l3num = exp->expected.tuple[__DIR_ORIG].l3protonum;
00042 else
00043 return -1;
00044
00045 memset(req, 0, size);
00046
00047 nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags);
00048
00049 if (test_bit(ATTR_EXP_EXPECTED, exp->set)) {
00050 __build_tuple(req,
00051 size,
00052 &exp->expected.tuple[__DIR_ORIG],
00053 CTA_EXPECT_TUPLE);
00054 }
00055
00056 if (test_bit(ATTR_EXP_MASTER, exp->set)) {
00057 __build_tuple(req,
00058 size,
00059 &exp->master.tuple[__DIR_ORIG],
00060 CTA_EXPECT_MASTER);
00061 }
00062
00063 if (test_bit(ATTR_EXP_MASK, exp->set)) {
00064 __build_tuple(req,
00065 size,
00066 &exp->mask.tuple[__DIR_ORIG],
00067 CTA_EXPECT_MASK);
00068 }
00069
00070 if (test_bit(ATTR_EXP_TIMEOUT, exp->set))
00071 __build_timeout(req, size, exp);
00072 if (test_bit(ATTR_EXP_FLAGS, exp->set))
00073 __build_flags(req, size, exp);
00074 if (test_bit(ATTR_EXP_ZONE, exp->set))
00075 __build_zone(req, size, exp);
00076
00077 return 0;
00078 }