1147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE#include <stdio.h>
236087d952be182a6163fc508c2168b9c3b9209c2Yasuyuki KOZAKAI#include <xtables.h>
336087d952be182a6163fc508c2168b9c3b9209c2Yasuyuki KOZAKAI#include <linux/netfilter/xt_length.h>
4147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE
5c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardtenum {
6c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	O_LENGTH = 0,
7c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt};
8c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt
9181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void length_help(void)
10147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE{
11147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE	printf(
128b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"length match options:\n"
13147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE"[!] --length length[:length]    Match packet length against value or range\n"
148b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"                                of values (inclusive)\n");
15147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE}
16147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE
17c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardtstatic const struct xt_option_entry length_opts[] = {
18c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	{.name = "length", .id = O_LENGTH, .type = XTTYPE_UINT16RC,
19c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	 .flags = XTOPT_MAND | XTOPT_INVERT},
20c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	XTOPT_TABLEEND,
21147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE};
22147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE
23c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardtstatic void length_parse(struct xt_option_call *cb)
24147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE{
25c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	struct xt_length_info *info = cb->data;
26147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE
27c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	xtables_option_parse(cb);
28c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	info->min = cb->val.u16_range[0];
296944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt	info->max = cb->val.u16_range[0];
306944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt	if (cb->nvals >= 2)
316944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		info->max = cb->val.u16_range[1];
32c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	if (cb->invert)
33c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt		info->invert = 1;
34147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE}
35147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE
36147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIEstatic void
37cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardtlength_print(const void *ip, const struct xt_entry_match *match, int numeric)
38147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE{
39cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt	const struct xt_length_info *info = (void *)match->data;
40cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt
4173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" length %s", info->invert ? "!" : "");
42cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt	if (info->min == info->max)
4373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%u", info->min);
44147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE	else
4573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%u:%u", info->min, info->max);
46147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE}
47147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE
48181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void length_save(const void *ip, const struct xt_entry_match *match)
49147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE{
50cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt	const struct xt_length_info *info = (void *)match->data;
51cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt
5273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf("%s --length ", info->invert ? " !" : "");
53cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt	if (info->min == info->max)
5473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%u", info->min);
55cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt	else
5673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%u:%u", info->min, info->max);
57147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE}
58147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE
597a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayusostatic int length_xlate(struct xt_xlate *xl,
607a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso			const struct xt_xlate_mt_params *params)
6195a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj{
627a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso	const struct xt_length_info *info = (void *)params->match->data;
6395a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj
646b60dc5be58a5781cacc4e6f238454d5e8421760Pablo Neira Ayuso	xt_xlate_add(xl, "meta length %s", info->invert ? "!= " : "");
6595a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj	if (info->min == info->max)
66f035be35c749d5c5cbb7ffdbcd1c548b91bd3033Pablo M. Bermudo Garay		xt_xlate_add(xl, "%u", info->min);
6795a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj	else
68f035be35c749d5c5cbb7ffdbcd1c548b91bd3033Pablo M. Bermudo Garay		xt_xlate_add(xl, "%u-%u", info->min, info->max);
6995a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj
7095a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj	return 1;
7195a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj}
7295a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj
7395a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj
74181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match length_match = {
7542979363f3958b4436c6d2503753c182c58e55eaJan Engelhardt	.family		= NFPROTO_UNSPEC,
7636087d952be182a6163fc508c2168b9c3b9209c2Yasuyuki KOZAKAI	.name		= "length",
778b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version	= XTABLES_VERSION,
7836087d952be182a6163fc508c2168b9c3b9209c2Yasuyuki KOZAKAI	.size		= XT_ALIGN(sizeof(struct xt_length_info)),
7936087d952be182a6163fc508c2168b9c3b9209c2Yasuyuki KOZAKAI	.userspacesize	= XT_ALIGN(sizeof(struct xt_length_info)),
80181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.help		= length_help,
81181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.print		= length_print,
82181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.save		= length_save,
83c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	.x6_parse	= length_parse,
84c15f9e3f6d8552cddfc858b115d996c7cf5b47e9Jan Engelhardt	.x6_options	= length_opts,
8595a7a9df945790f92237e4d2e91f3d372d6a2ad5Shivani Bhardwaj	.xlate		= length_xlate,
86147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE};
87147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE
88147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIEvoid _init(void)
89147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE{
90181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	xtables_register_match(&length_match);
91147a2be5ef19af6ef3842f496d1de2ae3e679eccFabrice MARIE}
92