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
244d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardtstatic void ah_parse(struct xt_option_call *cb)
25524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
264d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	struct ipt_ah *ahinfo = cb->data;
27524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
284d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	xtables_option_parse(cb);
296944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt	if (cb->nvals == 1)
306944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		ahinfo->spis[1] = ahinfo->spis[0];
314d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	if (cb->invert)
324d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt		ahinfo->invflags |= IPT_AH_INV_SPI;
33524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
34524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
35524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void
367ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtprint_spis(const char *name, uint32_t min, uint32_t max,
37524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	    int invert)
38524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
39524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	const char *inv = invert ? "!" : "";
40524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
41524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	if (min != 0 || max != 0xFFFFFFFF || invert) {
42524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		printf("%s", name);
43524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		if (min == max) {
44524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf(":%s", inv);
45524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf("%u", min);
46524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		} else {
47524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf("s:%s", inv);
48524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf("%u",min);
49524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf(":");
50524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			printf("%u",max);
51524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		}
52524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	}
53524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
54524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
5559d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void ah_print(const void *ip, const struct xt_entry_match *match,
5659d164019340d110d302634e429320577f0db7beJan Engelhardt                     int numeric)
57524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
58524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	const struct ipt_ah *ah = (struct ipt_ah *)match->data;
59524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
6073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" ah ");
61524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	print_spis("spi", ah->spis[0], ah->spis[1],
62524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		    ah->invflags & IPT_AH_INV_SPI);
63524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	if (ah->invflags & ~IPT_AH_INV_MASK)
6473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" Unknown invflags: 0x%X",
65524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		       ah->invflags & ~IPT_AH_INV_MASK);
66524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
67524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
6859d164019340d110d302634e429320577f0db7beJan Engelhardtstatic void ah_save(const void *ip, const struct xt_entry_match *match)
69524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
70524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	const struct ipt_ah *ahinfo = (struct ipt_ah *)match->data;
71524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
72f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte	if (!(ahinfo->spis[0] == 0
73f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte	    && ahinfo->spis[1] == 0xFFFFFFFF)) {
7473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%s --ahspi ",
7573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			(ahinfo->invflags & IPT_AH_INV_SPI) ? " !" : "");
76524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		if (ahinfo->spis[0]
77524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		    != ahinfo->spis[1])
7873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%u:%u",
79524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       ahinfo->spis[0],
80524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       ahinfo->spis[1]);
81524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		else
8273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%u",
83524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       ahinfo->spis[0]);
84524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	}
85524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
86524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
87524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
888b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardtstatic struct xtables_match ah_mt_reg = {
898caee8b9e34fed4562fcff553197c161fc9d9979Pablo Neira	.name 		= "ah",
908b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version 	= XTABLES_VERSION,
9103d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt	.family		= NFPROTO_IPV4,
928b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.size		= XT_ALIGN(sizeof(struct ipt_ah)),
938b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.userspacesize 	= XT_ALIGN(sizeof(struct ipt_ah)),
9459d164019340d110d302634e429320577f0db7beJan Engelhardt	.help 		= ah_help,
9559d164019340d110d302634e429320577f0db7beJan Engelhardt	.print 		= ah_print,
9659d164019340d110d302634e429320577f0db7beJan Engelhardt	.save 		= ah_save,
974d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	.x6_parse	= ah_parse,
984d6ede0b324e5e9dcbb1d7cc2a7aebed9e56821aJan Engelhardt	.x6_options	= ah_opts,
99524518261009f3f81febfdd8398becc4a80cc941Rusty Russell};
100524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
101524518261009f3f81febfdd8398becc4a80cc941Rusty Russellvoid
102524518261009f3f81febfdd8398becc4a80cc941Rusty Russell_init(void)
103524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
1048b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	xtables_register_match(&ah_mt_reg);
105524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
106