1 /* 2 * (C) 2005-2012 by Pablo Neira Ayuso <pablo (at) 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 * This code has been sponsored by Vyatta Inc. <http://www.vyatta.com> 10 */ 11 12 #include "internal/internal.h" 13 #include <libmnl/libmnl.h> 14 15 static int nlmsg_parse_expection_attr_cb(const struct nlattr *attr, void *data) 16 { 17 const struct nlattr **tb = data; 18 int type = mnl_attr_get_type(attr); 19 20 /* skip unsupported attribute in user-space */ 21 if (mnl_attr_type_valid(attr, CTA_EXPECT_MAX) < 0) 22 return MNL_CB_OK; 23 24 switch(type) { 25 case CTA_EXPECT_MASTER: 26 case CTA_EXPECT_TUPLE: 27 case CTA_EXPECT_MASK: 28 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) 29 return MNL_CB_ERROR; 30 break; 31 case CTA_EXPECT_TIMEOUT: 32 case CTA_EXPECT_FLAGS: 33 case CTA_EXPECT_ID: 34 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) 35 return MNL_CB_ERROR; 36 break; 37 case CTA_EXPECT_HELP_NAME: 38 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) 39 return MNL_CB_ERROR; 40 break; 41 case CTA_EXPECT_ZONE: 42 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) 43 return MNL_CB_ERROR; 44 break; 45 } 46 tb[type] = attr; 47 return MNL_CB_OK; 48 } 49 50 int nfexp_nlmsg_parse(const struct nlmsghdr *nlh, struct nf_expect *exp) 51 { 52 struct nlattr *tb[CTA_EXPECT_MAX+1] = {}; 53 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh); 54 55 mnl_attr_parse(nlh, sizeof(struct nfgenmsg), 56 nlmsg_parse_expection_attr_cb, tb); 57 58 if (tb[CTA_EXPECT_MASTER]) { 59 exp->expected.orig.l3protonum = nfg->nfgen_family; 60 set_bit(ATTR_ORIG_L3PROTO, exp->expected.set); 61 62 nfct_parse_tuple(tb[CTA_EXPECT_MASTER], &exp->master.orig, 63 __DIR_ORIG, exp->master.set); 64 set_bit(ATTR_EXP_MASTER, exp->set); 65 } 66 if (tb[CTA_EXPECT_TUPLE]) { 67 exp->mask.orig.l3protonum = nfg->nfgen_family; 68 set_bit(ATTR_ORIG_L3PROTO, exp->mask.set); 69 70 nfct_parse_tuple(tb[CTA_EXPECT_TUPLE], &exp->expected.orig, 71 __DIR_ORIG, exp->expected.set); 72 set_bit(ATTR_EXP_EXPECTED, exp->set); 73 } 74 if (tb[CTA_EXPECT_MASK]) { 75 exp->master.orig.l3protonum = nfg->nfgen_family; 76 set_bit(ATTR_ORIG_L3PROTO, exp->master.set); 77 78 nfct_parse_tuple(tb[CTA_EXPECT_MASK], &exp->mask.orig, 79 __DIR_ORIG, exp->mask.set); 80 set_bit(ATTR_EXP_MASK, exp->set); 81 } 82 if (tb[CTA_EXPECT_TIMEOUT]) { 83 exp->timeout = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_TIMEOUT])); 84 set_bit(ATTR_EXP_TIMEOUT, exp->set); 85 } 86 87 if (tb[CTA_EXPECT_ZONE]) { 88 exp->zone = ntohs(mnl_attr_get_u16(tb[CTA_EXPECT_ZONE])); 89 set_bit(ATTR_EXP_ZONE, exp->set); 90 } 91 92 if (tb[CTA_EXPECT_FLAGS]) { 93 exp->flags = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_FLAGS])); 94 set_bit(ATTR_EXP_FLAGS, exp->set); 95 } 96 97 if (tb[CTA_EXPECT_HELP_NAME]) { 98 strncpy(exp->helper_name, 99 mnl_attr_get_str(tb[CTA_EXPECT_HELP_NAME]), 100 NFCT_HELPER_NAME_MAX); 101 set_bit(ATTR_EXP_HELPER_NAME, exp->set); 102 } 103 return 0; 104 } 105