diff options
| author | Gaurav Sinha <gaurav.sinha@vyatta.com> | 2012-02-08 11:31:31 -0800 | 
|---|---|---|
| committer | Gaurav Sinha <gaurav.sinha@vyatta.com> | 2012-02-08 11:31:31 -0800 | 
| commit | 9f9a63cecdc6ac4f449d3eacda6c591f0de9fbf3 (patch) | |
| tree | 18e6fef8b6e8640db261b6448eb7f25411139474 | |
| parent | 66da74b336fe66472f9b5d16f730e0261c5ef4af (diff) | |
| parent | 167eb3e2028561ab2cc0f2b7b6ff9d24c56514f6 (diff) | |
| download | conntrack-tools-9f9a63cecdc6ac4f449d3eacda6c591f0de9fbf3.tar.gz conntrack-tools-9f9a63cecdc6ac4f449d3eacda6c591f0de9fbf3.zip  | |
Merge branch 'master' of git://git.netfilter.org/conntrack-tools into upstream
| -rw-r--r-- | include/network.h | 8 | ||||
| -rw-r--r-- | src/build.c | 37 | ||||
| -rw-r--r-- | src/parse.c | 88 | 
3 files changed, 130 insertions, 3 deletions
diff --git a/include/network.h b/include/network.h index ab95499..41c35af 100644 --- a/include/network.h +++ b/include/network.h @@ -239,6 +239,7 @@ enum nta_attr {  	NTA_ICMP_ID,		/* uint16_t */  	NTA_TCP_WSCALE_ORIG,	/* uint8_t */  	NTA_TCP_WSCALE_REPL,	/* uint8_t */ +	NTA_HELPER_NAME,	/* string (variable length) */  	NTA_MAX  }; @@ -269,6 +270,13 @@ enum nta_exp_attr {  	NTA_EXP_MASK_PORT,		/* struct nfct_attr_grp_port */  	NTA_EXP_TIMEOUT,		/* uint32_t */  	NTA_EXP_FLAGS,			/* uint32_t */ +	NTA_EXP_CLASS,			/* uint32_t */ +	NTA_EXP_NAT_IPV4,		/* struct nfct_attr_grp_ipv4 */ +	NTA_EXP_NAT_PORT,		/* struct nfct_attr_grp_port */ +	NTA_EXP_NAT_L4PROTO,		/* uint8_t */ +	NTA_EXP_NAT_DIR,		/* uint32_t */ +	NTA_EXP_HELPER_NAME,		/* string (variable length) */ +	NTA_EXP_FN,			/* string (variable length) */  	NTA_EXP_MAX  }; diff --git a/src/build.c b/src/build.c index 3193884..7d4ef12 100644 --- a/src/build.c +++ b/src/build.c @@ -65,6 +65,13 @@ ct_build_u32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b)  	addattr(n, b, &data, sizeof(uint32_t));  } +static inline void +ct_build_str(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) +{ +	const char *data = nfct_get_attr(ct, a); +	addattr(n, b, data, strlen(data)+1); +} +  static inline void   ct_build_group(const struct nf_conntrack *ct, int a, struct nethdr *n,   	      int b, int size) @@ -223,6 +230,9 @@ void ct2msg(const struct nf_conntrack *ct, struct nethdr *n)  	/* NAT sequence adjustment */  	if (nfct_attr_is_set_array(ct, nat_type, 6))  		ct_build_natseqadj(ct, n); + +	if (nfct_attr_is_set(ct, ATTR_HELPER_NAME)) +		ct_build_str(ct, ATTR_HELPER_NAME, n, NTA_HELPER_NAME);  }  static void @@ -270,6 +280,13 @@ exp_build_u32(const struct nf_expect *exp, int a, struct nethdr *n, int b)  	addattr(n, b, &data, sizeof(uint32_t));  } +static inline void +exp_build_str(const struct nf_expect *exp, int a, struct nethdr *n, int b) +{ +	const char *data = nfexp_get_attr(exp, a); +	addattr(n, b, data, strlen(data)+1); +} +  void exp2msg(const struct nf_expect *exp, struct nethdr *n)  {  	const struct nf_conntrack *ct = nfexp_get_attr(exp, ATTR_EXP_MASTER); @@ -322,4 +339,24 @@ void exp2msg(const struct nf_expect *exp, struct nethdr *n)  		exp_build_u32(exp, ATTR_EXP_TIMEOUT, n, NTA_EXP_TIMEOUT);  	exp_build_u32(exp, ATTR_EXP_FLAGS, n, NTA_EXP_FLAGS); +	if (nfexp_attr_is_set(exp, ATTR_EXP_CLASS)) +		exp_build_u32(exp, ATTR_EXP_CLASS, n, NTA_EXP_CLASS); + +	/* include NAT information, if any. */ +	ct = nfexp_get_attr(exp, ATTR_EXP_NAT_TUPLE); +	if (ct != NULL) { +		if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) { +			ct_build_group(ct, ATTR_GRP_ORIG_IPV4, n, +					NTA_EXP_NAT_IPV4, +					sizeof(struct nfct_attr_grp_ipv4)); +		} +		ct_build_u8(ct, ATTR_L4PROTO, n, NTA_EXP_NAT_L4PROTO); +		if (exp_l4proto_fcn[l4proto].build) +			exp_l4proto_fcn[l4proto].build(ct, n, NTA_EXP_NAT_PORT); + +		exp_build_u32(exp, ATTR_EXP_NAT_DIR, n, NTA_EXP_NAT_DIR); +	} +	exp_build_str(exp, ATTR_EXP_HELPER_NAME, n, NTA_EXP_HELPER_NAME); +	if (nfexp_attr_is_set(exp, ATTR_EXP_FN)) +		exp_build_str(exp, ATTR_EXP_FN, n, NTA_EXP_FN);  } diff --git a/src/parse.c b/src/parse.c index 81e9c6b..732bc44 100644 --- a/src/parse.c +++ b/src/parse.c @@ -28,6 +28,7 @@  static void ct_parse_u8(struct nf_conntrack *ct, int attr, void *data);  static void ct_parse_u16(struct nf_conntrack *ct, int attr, void *data);  static void ct_parse_u32(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_str(struct nf_conntrack *ct, int attr, void *data);  static void ct_parse_group(struct nf_conntrack *ct, int attr, void *data);  static void ct_parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data); @@ -35,6 +36,7 @@ struct ct_parser {  	void 	(*parse)(struct nf_conntrack *ct, int attr, void *data);  	int 	attr;  	int	size; +	int	max_size;  };  static struct ct_parser h[NTA_MAX] = { @@ -172,6 +174,11 @@ static struct ct_parser h[NTA_MAX] = {  		.attr	= ATTR_TCP_WSCALE_REPL,  		.size	= NTA_SIZE(sizeof(uint8_t)),  	}, +	[NTA_HELPER_NAME] = { +		.parse	= ct_parse_str, +		.attr	= ATTR_HELPER_NAME, +		.max_size = NFCT_HELPER_NAME_MAX, +	},  };  static void @@ -196,6 +203,12 @@ ct_parse_u32(struct nf_conntrack *ct, int attr, void *data)  }  static void +ct_parse_str(struct nf_conntrack *ct, int attr, void *data) +{ +	nfct_set_attr(ct, h[attr].attr, data); +} + +static void  ct_parse_group(struct nf_conntrack *ct, int attr, void *data)  {  	nfct_set_attr_grp(ct, h[attr].attr, data); @@ -236,7 +249,11 @@ int msg2ct(struct nf_conntrack *ct, struct nethdr *net, size_t remain)  			return -1;  		if (attr->nta_attr > NTA_MAX)  			return -1; -		if (attr->nta_len != h[attr->nta_attr].size) +		if (h[attr->nta_attr].size && +		    attr->nta_len != h[attr->nta_attr].size) +			return -1; +		if (h[attr->nta_attr].max_size && +		    attr->nta_len > h[attr->nta_attr].max_size)  			return -1;  		if (h[attr->nta_attr].parse == NULL) {  			attr = NTA_NEXT(attr, len); @@ -252,12 +269,14 @@ int msg2ct(struct nf_conntrack *ct, struct nethdr *net, size_t remain)  static void exp_parse_ct_group(void *ct, int attr, void *data);  static void exp_parse_ct_u8(void *ct, int attr, void *data);  static void exp_parse_u32(void *exp, int attr, void *data); +static void exp_parse_str(void *exp, int attr, void *data);  static struct exp_parser {  	void 	(*parse)(void *obj, int attr, void *data);  	int 	exp_attr;  	int 	ct_attr;  	int	size; +	int	max_size;  } exp_h[NTA_EXP_MAX] = {  	[NTA_EXP_MASTER_IPV4] = {  		.parse		= exp_parse_ct_group, @@ -341,6 +360,44 @@ static struct exp_parser {  		.exp_attr	= ATTR_EXP_FLAGS,  		.size		= NTA_SIZE(sizeof(uint32_t)),  	}, +	[NTA_EXP_CLASS] = { +		.parse		= exp_parse_u32, +		.exp_attr	= ATTR_EXP_CLASS, +		.size		= NTA_SIZE(sizeof(uint32_t)), +	}, +	[NTA_EXP_NAT_IPV4] = { +		.parse		= exp_parse_ct_group, +		.exp_attr	= ATTR_EXP_NAT_TUPLE, +		.ct_attr	= ATTR_GRP_ORIG_IPV4, +		.size		= NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)), +	}, +	[NTA_EXP_NAT_L4PROTO] = { +		.parse		= exp_parse_ct_u8, +		.exp_attr	= ATTR_EXP_NAT_TUPLE, +		.ct_attr	= ATTR_L4PROTO, +		.size		= NTA_SIZE(sizeof(uint8_t)), +	}, +	[NTA_EXP_NAT_PORT] = { +		.parse		= exp_parse_ct_group, +		.exp_attr	= ATTR_EXP_NAT_TUPLE, +		.ct_attr	= ATTR_GRP_ORIG_PORT, +		.size		= NTA_SIZE(sizeof(struct nfct_attr_grp_port)), +	}, +	[NTA_EXP_NAT_DIR] = { +		.parse		= exp_parse_u32, +		.exp_attr	= ATTR_EXP_NAT_DIR, +		.size		= NTA_SIZE(sizeof(uint32_t)), +	}, +	[NTA_EXP_HELPER_NAME] = { +		.parse		= exp_parse_str, +		.exp_attr	= ATTR_EXP_HELPER_NAME, +		.max_size	= NFCT_HELPER_NAME_MAX, +	}, +	[NTA_EXP_FN] = { +		.parse		= exp_parse_str, +		.exp_attr	= ATTR_EXP_FN, +		.max_size	= NFCT_HELPER_NAME_MAX, +	},  };  static void exp_parse_ct_group(void *ct, int attr, void *data) @@ -360,11 +417,16 @@ static void exp_parse_u32(void *exp, int attr, void *data)  	nfexp_set_attr_u32(exp, exp_h[attr].exp_attr, ntohl(*value));  } +static void exp_parse_str(void *exp, int attr, void *data) +{ +	nfexp_set_attr(exp, exp_h[attr].exp_attr, data); +} +  int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain)  {  	int len;  	struct netattr *attr; -	struct nf_conntrack *master, *expected, *mask; +	struct nf_conntrack *master, *expected, *mask, *nat;  	if (remain < net->len)  		return -1; @@ -384,13 +446,21 @@ int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain)  	if (mask == NULL)  		goto err_mask; +	nat = nfct_new(); +	if (nat == NULL) +		goto err_nat; +  	while (len > ssizeof(struct netattr)) {  		ATTR_NETWORK2HOST(attr);  		if (attr->nta_len > len)  			goto err;  		if (attr->nta_attr > NTA_MAX)  			goto err; -		if (attr->nta_len != exp_h[attr->nta_attr].size) +		if (exp_h[attr->nta_attr].size && +		    attr->nta_len != exp_h[attr->nta_attr].size) +			goto err; +		if (exp_h[attr->nta_attr].max_size && +		    attr->nta_len > exp_h[attr->nta_attr].max_size)  			goto err;  		if (exp_h[attr->nta_attr].parse == NULL) {  			attr = NTA_NEXT(attr, len); @@ -407,8 +477,17 @@ int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain)  			exp_h[attr->nta_attr].parse(mask, attr->nta_attr,  						    NTA_DATA(attr));  			break; +		case ATTR_EXP_NAT_TUPLE: +			exp_h[attr->nta_attr].parse(nat, attr->nta_attr, +						    NTA_DATA(attr)); +			nfexp_set_attr(exp, ATTR_EXP_NAT_TUPLE, nat); +			break;  		case ATTR_EXP_TIMEOUT:  		case ATTR_EXP_FLAGS: +		case ATTR_EXP_CLASS: +		case ATTR_EXP_HELPER_NAME: +		case ATTR_EXP_NAT_DIR: +		case ATTR_EXP_FN:  			exp_h[attr->nta_attr].parse(exp, attr->nta_attr,  						    NTA_DATA(attr));  			break; @@ -429,9 +508,12 @@ int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain)  	nfct_destroy(mask);  	nfct_destroy(expected);  	nfct_destroy(master); +	nfct_destroy(nat);  	return 0;  err: +	nfct_destroy(nat); +err_nat:  	nfct_destroy(mask);  err_mask:  	nfct_destroy(expected);  | 
