Home | History | Annotate | Download | only in expect
      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