blob: 26f81408fc45bbafd10e28d41a6b070b4c843be8 [file] [log] [blame]
Harald Welted32980d2002-03-25 08:38:26 +00001#include <stdio.h>
Jan Engelhardt5d9678a2008-11-20 10:15:35 +01002#include <xtables.h>
Harald Welted32980d2002-03-25 08:38:26 +00003#include <linux/netfilter_ipv6/ip6t_ah.h>
Jan Engelhardtddac6c52008-09-01 14:22:19 +02004
Jan Engelhardt4d6ede02011-02-16 01:59:18 +01005enum {
6 O_AHSPI = 0,
7 O_AHLEN,
8 O_AHRES,
9};
10
Jan Engelhardt997045f2007-10-04 16:29:21 +000011static void ah_help(void)
Harald Welted32980d2002-03-25 08:38:26 +000012{
13 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020014"ah match options:\n"
Jan Engelhardt96727922008-08-13 14:42:41 +020015"[!] --ahspi spi[:spi] match spi (range)\n"
16"[!] --ahlen length total length of this header\n"
Jan Engelhardt12a18d62011-02-18 01:45:05 +010017" --ahres check the reserved field too\n");
Harald Welted32980d2002-03-25 08:38:26 +000018}
19
Jan Engelhardt4d6ede02011-02-16 01:59:18 +010020#define s struct ip6t_ah
21static const struct xt_option_entry ah_opts[] = {
22 {.name = "ahspi", .id = O_AHSPI, .type = XTTYPE_UINT32RC,
23 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spis)},
24 {.name = "ahlen", .id = O_AHLEN, .type = XTTYPE_UINT32,
25 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdrlen)},
26 {.name = "ahres", .id = O_AHRES, .type = XTTYPE_NONE},
27 XTOPT_TABLEEND,
Harald Welted32980d2002-03-25 08:38:26 +000028};
Jan Engelhardt4d6ede02011-02-16 01:59:18 +010029#undef s
Harald Welted32980d2002-03-25 08:38:26 +000030
Jan Engelhardt4d6ede02011-02-16 01:59:18 +010031static void ah_parse(struct xt_option_call *cb)
Harald Welted32980d2002-03-25 08:38:26 +000032{
Jan Engelhardt4d6ede02011-02-16 01:59:18 +010033 struct ip6t_ah *ahinfo = cb->data;
Harald Welted32980d2002-03-25 08:38:26 +000034
Jan Engelhardt4d6ede02011-02-16 01:59:18 +010035 xtables_option_parse(cb);
36 switch (cb->entry->id) {
37 case O_AHSPI:
Jan Engelhardt6944f2c2011-05-24 23:50:29 +020038 if (cb->nvals == 1)
39 ahinfo->spis[1] = ahinfo->spis[0];
Jan Engelhardt4d6ede02011-02-16 01:59:18 +010040 if (cb->invert)
Harald Welted32980d2002-03-25 08:38:26 +000041 ahinfo->invflags |= IP6T_AH_INV_SPI;
Harald Welted32980d2002-03-25 08:38:26 +000042 break;
Jan Engelhardt4d6ede02011-02-16 01:59:18 +010043 case O_AHLEN:
44 if (cb->invert)
Harald Welted32980d2002-03-25 08:38:26 +000045 ahinfo->invflags |= IP6T_AH_INV_LEN;
Harald Welted32980d2002-03-25 08:38:26 +000046 break;
Jan Engelhardt4d6ede02011-02-16 01:59:18 +010047 case O_AHRES:
Harald Welted32980d2002-03-25 08:38:26 +000048 ahinfo->hdrres = 1;
Harald Welted32980d2002-03-25 08:38:26 +000049 break;
Harald Welted32980d2002-03-25 08:38:26 +000050 }
Harald Welted32980d2002-03-25 08:38:26 +000051}
52
Harald Welted32980d2002-03-25 08:38:26 +000053static void
Jan Engelhardt7ac40522011-01-07 12:34:04 +010054print_spis(const char *name, uint32_t min, uint32_t max,
Harald Welted32980d2002-03-25 08:38:26 +000055 int invert)
56{
57 const char *inv = invert ? "!" : "";
58
59 if (min != 0 || max != 0xFFFFFFFF || invert) {
Stephane Ouellette703575d2003-08-23 18:41:47 +000060 if (min == max)
Jan Engelhardt73866352010-12-18 02:04:59 +010061 printf("%s:%s%u", name, inv, min);
Stephane Ouellette703575d2003-08-23 18:41:47 +000062 else
Jan Engelhardt73866352010-12-18 02:04:59 +010063 printf("%ss:%s%u:%u", name, inv, min, max);
Harald Welted32980d2002-03-25 08:38:26 +000064 }
65}
66
67static void
Jan Engelhardt7ac40522011-01-07 12:34:04 +010068print_len(const char *name, uint32_t len, int invert)
Harald Welted32980d2002-03-25 08:38:26 +000069{
70 const char *inv = invert ? "!" : "";
71
Stephane Ouellette703575d2003-08-23 18:41:47 +000072 if (len != 0 || invert)
Jan Engelhardt73866352010-12-18 02:04:59 +010073 printf("%s:%s%u", name, inv, len);
Harald Welted32980d2002-03-25 08:38:26 +000074}
75
Jan Engelhardt997045f2007-10-04 16:29:21 +000076static void ah_print(const void *ip, const struct xt_entry_match *match,
77 int numeric)
Harald Welted32980d2002-03-25 08:38:26 +000078{
79 const struct ip6t_ah *ah = (struct ip6t_ah *)match->data;
80
Jan Engelhardt73866352010-12-18 02:04:59 +010081 printf(" ah ");
Harald Welted32980d2002-03-25 08:38:26 +000082 print_spis("spi", ah->spis[0], ah->spis[1],
83 ah->invflags & IP6T_AH_INV_SPI);
84 print_len("length", ah->hdrlen,
85 ah->invflags & IP6T_AH_INV_LEN);
Stephane Ouellette703575d2003-08-23 18:41:47 +000086
87 if (ah->hdrres)
Jan Engelhardt73866352010-12-18 02:04:59 +010088 printf(" reserved");
Stephane Ouellette703575d2003-08-23 18:41:47 +000089
Harald Welted32980d2002-03-25 08:38:26 +000090 if (ah->invflags & ~IP6T_AH_INV_MASK)
Jan Engelhardt73866352010-12-18 02:04:59 +010091 printf(" Unknown invflags: 0x%X",
Harald Welted32980d2002-03-25 08:38:26 +000092 ah->invflags & ~IP6T_AH_INV_MASK);
93}
94
Jan Engelhardt997045f2007-10-04 16:29:21 +000095static void ah_save(const void *ip, const struct xt_entry_match *match)
Harald Welted32980d2002-03-25 08:38:26 +000096{
97 const struct ip6t_ah *ahinfo = (struct ip6t_ah *)match->data;
98
99 if (!(ahinfo->spis[0] == 0
100 && ahinfo->spis[1] == 0xFFFFFFFF)) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100101 printf("%s --ahspi ",
102 (ahinfo->invflags & IP6T_AH_INV_SPI) ? " !" : "");
Harald Welted32980d2002-03-25 08:38:26 +0000103 if (ahinfo->spis[0]
104 != ahinfo->spis[1])
Jan Engelhardt73866352010-12-18 02:04:59 +0100105 printf("%u:%u",
Harald Welted32980d2002-03-25 08:38:26 +0000106 ahinfo->spis[0],
107 ahinfo->spis[1]);
108 else
Jan Engelhardt73866352010-12-18 02:04:59 +0100109 printf("%u",
Harald Welted32980d2002-03-25 08:38:26 +0000110 ahinfo->spis[0]);
111 }
112
András Kis-Szabód8a12a82002-04-24 09:36:30 +0000113 if (ahinfo->hdrlen != 0 || (ahinfo->invflags & IP6T_AH_INV_LEN) ) {
Jan Engelhardt73866352010-12-18 02:04:59 +0100114 printf("%s --ahlen %u",
115 (ahinfo->invflags & IP6T_AH_INV_LEN) ? " !" : "",
Harald Welted32980d2002-03-25 08:38:26 +0000116 ahinfo->hdrlen);
117 }
118
Stephane Ouellette703575d2003-08-23 18:41:47 +0000119 if (ahinfo->hdrres != 0 )
Jan Engelhardt73866352010-12-18 02:04:59 +0100120 printf(" --ahres");
Harald Welted32980d2002-03-25 08:38:26 +0000121}
122
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200123static struct xtables_match ah_mt6_reg = {
Stephane Ouellette703575d2003-08-23 18:41:47 +0000124 .name = "ah",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200125 .version = XTABLES_VERSION,
Jan Engelhardt03d99482008-11-18 12:27:54 +0100126 .family = NFPROTO_IPV6,
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200127 .size = XT_ALIGN(sizeof(struct ip6t_ah)),
128 .userspacesize = XT_ALIGN(sizeof(struct ip6t_ah)),
Jan Engelhardt997045f2007-10-04 16:29:21 +0000129 .help = ah_help,
Jan Engelhardt997045f2007-10-04 16:29:21 +0000130 .print = ah_print,
131 .save = ah_save,
Jan Engelhardt4d6ede02011-02-16 01:59:18 +0100132 .x6_parse = ah_parse,
133 .x6_options = ah_opts,
Harald Welted32980d2002-03-25 08:38:26 +0000134};
135
136void
137_init(void)
138{
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200139 xtables_register_match(&ah_mt6_reg);
Harald Welted32980d2002-03-25 08:38:26 +0000140}