1/* 2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org> 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 10#include "internal/internal.h" 11 12static void __build_timeout(struct nfnlhdr *req, 13 size_t size, 14 const struct nf_expect *exp) 15{ 16 nfnl_addattr32(&req->nlh, size, CTA_EXPECT_TIMEOUT,htonl(exp->timeout)); 17} 18 19static void __build_zone(struct nfnlhdr *req, size_t size, 20 const struct nf_expect *exp) 21{ 22 nfnl_addattr16(&req->nlh, size, CTA_EXPECT_ZONE, htons(exp->zone)); 23} 24 25static void __build_flags(struct nfnlhdr *req, 26 size_t size, const struct nf_expect *exp) 27{ 28 nfnl_addattr32(&req->nlh, size, CTA_EXPECT_FLAGS,htonl(exp->flags)); 29} 30 31static void __build_class(struct nfnlhdr *req, 32 size_t size, 33 const struct nf_expect *exp) 34{ 35 nfnl_addattr32(&req->nlh, size, CTA_EXPECT_CLASS, htonl(exp->class)); 36} 37 38static void __build_helper_name(struct nfnlhdr *req, size_t size, 39 const struct nf_expect *exp) 40{ 41 nfnl_addattr_l(&req->nlh, size, CTA_EXPECT_HELP_NAME, 42 exp->helper_name, strlen(exp->helper_name)+1); 43} 44 45static void __build_expectfn(struct nfnlhdr *req, 46 size_t size, const struct nf_expect *exp) 47{ 48 nfnl_addattr_l(&req->nlh, size, CTA_EXPECT_FN, 49 exp->expectfn, strlen(exp->expectfn)+1); 50} 51 52int __build_expect(struct nfnl_subsys_handle *ssh, 53 struct nfnlhdr *req, 54 size_t size, 55 uint16_t type, 56 uint16_t flags, 57 const struct nf_expect *exp) 58{ 59 uint8_t l3num; 60 61 if (test_bit(ATTR_ORIG_L3PROTO, exp->master.set)) 62 l3num = exp->master.orig.l3protonum; 63 else if (test_bit(ATTR_ORIG_L3PROTO, exp->expected.set)) 64 l3num = exp->expected.orig.l3protonum; 65 else 66 return -1; 67 68 memset(req, 0, size); 69 70 nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags); 71 72 if (test_bit(ATTR_EXP_EXPECTED, exp->set)) { 73 __build_tuple(req, size, &exp->expected.orig, CTA_EXPECT_TUPLE); 74 } 75 76 if (test_bit(ATTR_EXP_MASTER, exp->set)) { 77 __build_tuple(req, size, &exp->master.orig, CTA_EXPECT_MASTER); 78 } 79 80 if (test_bit(ATTR_EXP_MASK, exp->set)) { 81 __build_tuple(req, size, &exp->mask.orig, CTA_EXPECT_MASK); 82 } 83 84 if (test_bit(ATTR_EXP_NAT_TUPLE, exp->set) && 85 test_bit(ATTR_EXP_NAT_DIR, exp->set)) { 86 struct nfattr *nest; 87 88 nest = nfnl_nest(&req->nlh, size, CTA_EXPECT_NAT); 89 __build_tuple(req, size, &exp->nat.orig, CTA_EXPECT_NAT_TUPLE); 90 nfnl_addattr32(&req->nlh, size, CTA_EXPECT_NAT_DIR, 91 htonl(exp->nat_dir)); 92 nfnl_nest_end(&req->nlh, nest); 93 } 94 95 if (test_bit(ATTR_EXP_TIMEOUT, exp->set)) 96 __build_timeout(req, size, exp); 97 if (test_bit(ATTR_EXP_FLAGS, exp->set)) 98 __build_flags(req, size, exp); 99 if (test_bit(ATTR_EXP_ZONE, exp->set)) 100 __build_zone(req, size, exp); 101 if (test_bit(ATTR_EXP_CLASS, exp->set)) 102 __build_class(req, size, exp); 103 if (test_bit(ATTR_EXP_HELPER_NAME, exp->set)) 104 __build_helper_name(req, size, exp); 105 if (test_bit(ATTR_EXP_FN, exp->set)) 106 __build_expectfn(req, size, exp); 107 108 return 0; 109} 110