1 /* Shared library add-on to ip6tables to add AH support. */
9 #include <linux/netfilter_ipv6/ip6t_ah.h>
11 static void ah_help(void)
15 "[!] --ahspi spi[:spi] match spi (range)\n"
16 "[!] --ahlen length total length of this header\n"
17 " --ahres check the reserved filed, too\n");
20 static const struct option ah_opts
[] = {
21 { .name
= "ahspi", .has_arg
= 1, .val
= '1' },
22 { .name
= "ahlen", .has_arg
= 1, .val
= '2' },
23 { .name
= "ahres", .has_arg
= 0, .val
= '3' },
28 parse_ah_spi(const char *spistr
, const char *typestr
)
30 unsigned long int spi
;
33 spi
= strtoul(spistr
, &ep
, 0);
36 xtables_error(PARAMETER_PROBLEM
,
37 "AH no valid digits in %s `%s'", typestr
, spistr
);
39 if ( spi
== ULONG_MAX
&& errno
== ERANGE
)
40 xtables_error(PARAMETER_PROBLEM
,
41 "%s `%s' specified too big: would overflow",
44 if ( *spistr
!= '\0' && *ep
!= '\0' )
45 xtables_error(PARAMETER_PROBLEM
,
46 "AH error parsing %s `%s'", typestr
, spistr
);
52 parse_ah_spis(const char *spistring
, u_int32_t
*spis
)
57 buffer
= strdup(spistring
);
58 if ((cp
= strchr(buffer
, ':')) == NULL
)
59 spis
[0] = spis
[1] = parse_ah_spi(buffer
, "spi");
64 spis
[0] = buffer
[0] ? parse_ah_spi(buffer
, "spi") : 0;
65 spis
[1] = cp
[0] ? parse_ah_spi(cp
, "spi") : 0xFFFFFFFF;
70 static void ah_init(struct xt_entry_match
*m
)
72 struct ip6t_ah
*ahinfo
= (struct ip6t_ah
*)m
->data
;
74 ahinfo
->spis
[1] = 0xFFFFFFFF;
79 static int ah_parse(int c
, char **argv
, int invert
, unsigned int *flags
,
80 const void *entry
, struct xt_entry_match
**match
)
82 struct ip6t_ah
*ahinfo
= (struct ip6t_ah
*)(*match
)->data
;
86 if (*flags
& IP6T_AH_SPI
)
87 xtables_error(PARAMETER_PROBLEM
,
88 "Only one `--ahspi' allowed");
89 xtables_check_inverse(optarg
, &invert
, &optind
, 0);
90 parse_ah_spis(argv
[optind
-1], ahinfo
->spis
);
92 ahinfo
->invflags
|= IP6T_AH_INV_SPI
;
93 *flags
|= IP6T_AH_SPI
;
96 if (*flags
& IP6T_AH_LEN
)
97 xtables_error(PARAMETER_PROBLEM
,
98 "Only one `--ahlen' allowed");
99 xtables_check_inverse(optarg
, &invert
, &optind
, 0);
100 ahinfo
->hdrlen
= parse_ah_spi(argv
[optind
-1], "length");
102 ahinfo
->invflags
|= IP6T_AH_INV_LEN
;
103 *flags
|= IP6T_AH_LEN
;
106 if (*flags
& IP6T_AH_RES
)
107 xtables_error(PARAMETER_PROBLEM
,
108 "Only one `--ahres' allowed");
110 *flags
|= IP6T_AH_RES
;
120 print_spis(const char *name
, u_int32_t min
, u_int32_t max
,
123 const char *inv
= invert
? "!" : "";
125 if (min
!= 0 || max
!= 0xFFFFFFFF || invert
) {
127 printf("%s:%s%u ", name
, inv
, min
);
129 printf("%ss:%s%u:%u ", name
, inv
, min
, max
);
134 print_len(const char *name
, u_int32_t len
, int invert
)
136 const char *inv
= invert
? "!" : "";
138 if (len
!= 0 || invert
)
139 printf("%s:%s%u ", name
, inv
, len
);
142 static void ah_print(const void *ip
, const struct xt_entry_match
*match
,
145 const struct ip6t_ah
*ah
= (struct ip6t_ah
*)match
->data
;
148 print_spis("spi", ah
->spis
[0], ah
->spis
[1],
149 ah
->invflags
& IP6T_AH_INV_SPI
);
150 print_len("length", ah
->hdrlen
,
151 ah
->invflags
& IP6T_AH_INV_LEN
);
156 if (ah
->invflags
& ~IP6T_AH_INV_MASK
)
157 printf("Unknown invflags: 0x%X ",
158 ah
->invflags
& ~IP6T_AH_INV_MASK
);
161 static void ah_save(const void *ip
, const struct xt_entry_match
*match
)
163 const struct ip6t_ah
*ahinfo
= (struct ip6t_ah
*)match
->data
;
165 if (!(ahinfo
->spis
[0] == 0
166 && ahinfo
->spis
[1] == 0xFFFFFFFF)) {
168 (ahinfo
->invflags
& IP6T_AH_INV_SPI
) ? "! " : "");
179 if (ahinfo
->hdrlen
!= 0 || (ahinfo
->invflags
& IP6T_AH_INV_LEN
) ) {
180 printf("%s--ahlen %u ",
181 (ahinfo
->invflags
& IP6T_AH_INV_LEN
) ? "! " : "",
185 if (ahinfo
->hdrres
!= 0 )
189 static struct xtables_match ah_mt6_reg
= {
191 .version
= XTABLES_VERSION
,
192 .family
= NFPROTO_IPV6
,
193 .size
= XT_ALIGN(sizeof(struct ip6t_ah
)),
194 .userspacesize
= XT_ALIGN(sizeof(struct ip6t_ah
)),
200 .extra_opts
= ah_opts
,
206 xtables_register_match(&ah_mt6_reg
);