1524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <stdio.h>
25d9678ad3eabc34ac40dfe055d7f6a8e44445a5aJan Engelhardt#include <xtables.h>
3524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <linux/netfilter_ipv4/ipt_ah.h>
4ddac6c5bc636003d664d25c08ea3fe176565096cJan Engelhardt
54d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardtenum {
64d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	O_AHSPI = 0,
74d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt};
84d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt
959d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void ah_help(void)
10524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
11524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	printf(
128b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"ah match options:\n"
13967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --ahspi spi[:spi]\n"
148b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"				match spi (range)\n");
15524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
16524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
174d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardtstatic const struct xt_option_entry ah_opts[] = {
184d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	{.name = "ahspi", .id = O_AHSPI, .type = XTTYPE_UINT32RC,
194d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	 .flags = XTOPT_INVERT | XTOPT_PUT,
204d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	 XTOPT_POINTER(struct ipt_ah, spis)},
214d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	XTOPT_TABLEEND,
22524518261009f3f81febfdd8398becc4a80cc941Rusty Russell};
23524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
244264de1f270a0fac44dde8ece6fde0a879aebc8eJan Engelhardtstatic void ah_init(struct xt_entry_match *m)
254264de1f270a0fac44dde8ece6fde0a879aebc8eJan Engelhardt{
264264de1f270a0fac44dde8ece6fde0a879aebc8eJan Engelhardt	struct ipt_ah *ahinfo = (void *)m->data;
274264de1f270a0fac44dde8ece6fde0a879aebc8eJan Engelhardt
284264de1f270a0fac44dde8ece6fde0a879aebc8eJan Engelhardt	ahinfo->spis[1] = ~0U;
294264de1f270a0fac44dde8ece6fde0a879aebc8eJan Engelhardt}
304264de1f270a0fac44dde8ece6fde0a879aebc8eJan Engelhardt
314d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardtstatic void ah_parse(struct xt_option_call *cb)
32524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
334d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	struct ipt_ah *ahinfo = cb->data;
34524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
354d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	xtables_option_parse(cb);
366944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt	if (cb->nvals == 1)
376944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		ahinfo->spis[1] = ahinfo->spis[0];
384d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	if (cb->invert)
394d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt		ahinfo->invflags |= IPT_AH_INV_SPI;
40524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
41524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
42524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void
437ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtprint_spis(const char *name, uint32_t min, uint32_t max,
44524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	    int invert)
45524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
46524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	const char *inv = invert ? "!" : "";
47524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
48524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	if (min != 0 || max != 0xFFFFFFFF || invert) {
49524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		printf("%s", name);
50524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		if (min == max) {
51524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf(":%s", inv);
52524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf("%u", min);
53524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		} else {
54524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf("s:%s", inv);
55524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf("%u",min);
56524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf(":");
57524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf("%u",max);
58524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		}
59524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	}
60524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
61524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
6259d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void ah_print(const void *ip, const struct xt_entry_match *match,
6359d164019340d110d302634e429320577f0db7beJan Engelhardt                     int numeric)
64524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
65524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	const struct ipt_ah *ah = (struct ipt_ah *)match->data;
66524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
6773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" ah ");
68524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	print_spis("spi", ah->spis[0], ah->spis[1],
69524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		    ah->invflags & IPT_AH_INV_SPI);
70524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	if (ah->invflags & ~IPT_AH_INV_MASK)
7173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" Unknown invflags: 0x%X",
72524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		       ah->invflags & ~IPT_AH_INV_MASK);
73524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
74524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
7559d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void ah_save(const void *ip, const struct xt_entry_match *match)
76524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
77524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	const struct ipt_ah *ahinfo = (struct ipt_ah *)match->data;
78524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
79f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte	if (!(ahinfo->spis[0] == 0
80f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte	    && ahinfo->spis[1] == 0xFFFFFFFF)) {
8173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%s --ahspi ",
8273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			(ahinfo->invflags & IPT_AH_INV_SPI) ? " !" : "");
83524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		if (ahinfo->spis[0]
84524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		    != ahinfo->spis[1])
8573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%u:%u",
86524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       ahinfo->spis[0],
87524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       ahinfo->spis[1]);
88524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		else
8973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%u",
90524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       ahinfo->spis[0]);
91524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	}
92524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
93524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
94524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
957a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayusostatic int ah_xlate(struct xt_xlate *xl,
967a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso		    const struct xt_xlate_mt_params *params)
97b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj{
987a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso	const struct ipt_ah *ahinfo = (struct ipt_ah *)params->match->data;
99b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj
100b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	if (!(ahinfo->spis[0] == 0 && ahinfo->spis[1] == 0xFFFFFFFF)) {
1016b60dc5be58a5781cacc4e6f238454d5e8421760Pablo Neira Ayuso		xt_xlate_add(xl, "ah spi%s ",
102b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj			   (ahinfo->invflags & IPT_AH_INV_SPI) ? " !=" : "");
103b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj		if (ahinfo->spis[0] != ahinfo->spis[1])
104f035be35c749d5c5cbb7ffdbcd1c548b91bd3033Pablo M. Bermudo Garay			xt_xlate_add(xl, "%u-%u", ahinfo->spis[0],
105b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj				   ahinfo->spis[1]);
106b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj		else
107f035be35c749d5c5cbb7ffdbcd1c548b91bd3033Pablo M. Bermudo Garay			xt_xlate_add(xl, "%u", ahinfo->spis[0]);
108b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	}
109b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj
110b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	return 1;
111b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj}
112b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj
1138b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardtstatic struct xtables_match ah_mt_reg = {
114b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	.name		= "ah",
115b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	.version	= XTABLES_VERSION,
11603d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt	.family		= NFPROTO_IPV4,
1178b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.size		= XT_ALIGN(sizeof(struct ipt_ah)),
118b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	.userspacesize	= XT_ALIGN(sizeof(struct ipt_ah)),
119b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	.help		= ah_help,
1204264de1f270a0fac44dde8ece6fde0a879aebc8eJan Engelhardt	.init		= ah_init,
121b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	.print		= ah_print,
122b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	.save		= ah_save,
1234d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	.x6_parse	= ah_parse,
1244d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	.x6_options	= ah_opts,
125b9a46ee40616582b4fca4aa395d52d048c7dbba8Shivani Bhardwaj	.xlate		= ah_xlate,
126524518261009f3f81febfdd8398becc4a80cc941Rusty Russell};
127524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
128524518261009f3f81febfdd8398becc4a80cc941Rusty Russellvoid
129524518261009f3f81febfdd8398becc4a80cc941Rusty Russell_init(void)
130524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
1318b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	xtables_register_match(&ah_mt_reg);
132524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
133