1524518261009f3f81febfdd8398becc4a80cc941Rusty Russell#include <stdio.h>
20a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI#include <xtables.h>
30a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI#include <linux/netfilter/xt_esp.h>
4524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
5a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardtenum {
6a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	O_ESPSPI = 0,
7a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt};
8a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt
9181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void esp_help(void)
10524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
11524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	printf(
128b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"esp match options:\n"
13967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --espspi spi[:spi]\n"
148b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"				match spi (range)\n");
15524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
16524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
17a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardtstatic const struct xt_option_entry esp_opts[] = {
18a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	{.name = "espspi", .id = O_ESPSPI, .type = XTTYPE_UINT32RC,
19a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	 .flags = XTOPT_INVERT | XTOPT_PUT,
20a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	 XTOPT_POINTER(struct xt_esp, spis)},
21a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	XTOPT_TABLEEND,
22524518261009f3f81febfdd8398becc4a80cc941Rusty Russell};
23524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
24a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardtstatic void esp_parse(struct xt_option_call *cb)
25524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
26a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	struct xt_esp *espinfo = cb->data;
27524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
28a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	xtables_option_parse(cb);
296944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt	if (cb->nvals == 1)
306944f2c8190f1c4319aeac748470c71b0ba45025Jan Engelhardt		espinfo->spis[1] = espinfo->spis[0];
31a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	if (cb->invert)
32a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt		espinfo->invflags |= XT_ESP_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) {
420a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI		if (min == max)
4373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %s:%s%u", name, inv, min);
440a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI		else
4573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" %ss:%s%u:%u", name, inv, min, max);
46524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	}
47524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
48524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
49524518261009f3f81febfdd8398becc4a80cc941Rusty Russellstatic void
50181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtesp_print(const void *ip, const struct xt_entry_match *match, int numeric)
51524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
520a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI	const struct xt_esp *esp = (struct xt_esp *)match->data;
53524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
5473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" esp");
55524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	print_spis("spi", esp->spis[0], esp->spis[1],
560a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI		    esp->invflags & XT_ESP_INV_SPI);
570a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI	if (esp->invflags & ~XT_ESP_INV_MASK)
5873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" Unknown invflags: 0x%X",
590a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI		       esp->invflags & ~XT_ESP_INV_MASK);
60524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
61524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
62181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void esp_save(const void *ip, const struct xt_entry_match *match)
63524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
640a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI	const struct xt_esp *espinfo = (struct xt_esp *)match->data;
65524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
66f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte	if (!(espinfo->spis[0] == 0
67f0ac814a2137abe334bd0000d59e9be4721e1ddcHarald Welte	    && espinfo->spis[1] == 0xFFFFFFFF)) {
6873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%s --espspi ",
6973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			(espinfo->invflags & XT_ESP_INV_SPI) ? " !" : "");
70524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		if (espinfo->spis[0]
71524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		    != espinfo->spis[1])
7273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%u:%u",
73524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       espinfo->spis[0],
74524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       espinfo->spis[1]);
75524518261009f3f81febfdd8398becc4a80cc941Rusty Russell		else
7673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%u",
77524518261009f3f81febfdd8398becc4a80cc941Rusty Russell			       espinfo->spis[0]);
78524518261009f3f81febfdd8398becc4a80cc941Rusty Russell	}
79524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
80524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
81524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
82181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match esp_match = {
83c5e85736c207f211d82d2878a5781f512327dfceJan Engelhardt	.family		= NFPROTO_UNSPEC,
848caee8b9e34fed4562fcff553197c161fc9d9979Pablo Neira	.name 		= "esp",
858b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version 	= XTABLES_VERSION,
860a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI	.size		= XT_ALIGN(sizeof(struct xt_esp)),
870a04e8d695549788213f842cc99c724a564a88dfYasuyuki KOZAKAI	.userspacesize	= XT_ALIGN(sizeof(struct xt_esp)),
88181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.help		= esp_help,
89181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.print		= esp_print,
90181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.save		= esp_save,
91a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	.x6_parse	= esp_parse,
92a3876fa13ffe792e209cc1a8ac1214946c898eeaJan Engelhardt	.x6_options	= esp_opts,
93524518261009f3f81febfdd8398becc4a80cc941Rusty Russell};
94524518261009f3f81febfdd8398becc4a80cc941Rusty Russell
95524518261009f3f81febfdd8398becc4a80cc941Rusty Russellvoid
96524518261009f3f81febfdd8398becc4a80cc941Rusty Russell_init(void)
97524518261009f3f81febfdd8398becc4a80cc941Rusty Russell{
98181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	xtables_register_match(&esp_match);
99524518261009f3f81febfdd8398becc4a80cc941Rusty Russell}
100