blob: 58ed6d157e596e3fdfb94a595a140a31cd22d41f [file] [log] [blame]
Rusty Russell52451822000-08-27 07:47:46 +00001/* Shared library add-on to iptables to add AH support. */
Jan Engelhardt32b8e612010-07-23 21:16:14 +02002#include <stdbool.h>
Rusty Russell52451822000-08-27 07:47:46 +00003#include <stdio.h>
4#include <netdb.h>
5#include <string.h>
6#include <stdlib.h>
7#include <getopt.h>
8#include <errno.h>
Jan Engelhardt5d9678a2008-11-20 10:15:35 +01009#include <xtables.h>
Rusty Russell52451822000-08-27 07:47:46 +000010#include <linux/netfilter_ipv4/ipt_ah.h>
Jan Engelhardtddac6c52008-09-01 14:22:19 +020011
Jan Engelhardt59d16402007-10-04 16:28:39 +000012static void ah_help(void)
Rusty Russell52451822000-08-27 07:47:46 +000013{
14 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020015"ah match options:\n"
Jan Engelhardt96727922008-08-13 14:42:41 +020016"[!] --ahspi spi[:spi]\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020017" match spi (range)\n");
Rusty Russell52451822000-08-27 07:47:46 +000018}
19
Jan Engelhardt59d16402007-10-04 16:28:39 +000020static const struct option ah_opts[] = {
Jan Engelhardt32b8e612010-07-23 21:16:14 +020021 {.name = "ahspi", .has_arg = true, .val = '1'},
22 XT_GETOPT_TABLEEND,
Rusty Russell52451822000-08-27 07:47:46 +000023};
24
25static u_int32_t
26parse_ah_spi(const char *spistr)
27{
28 unsigned long int spi;
29 char* ep;
30
31 spi = strtoul(spistr,&ep,0) ;
32
33 if ( spistr == ep ) {
Jan Engelhardt1829ed42009-02-21 03:29:44 +010034 xtables_error(PARAMETER_PROBLEM,
Rusty Russell52451822000-08-27 07:47:46 +000035 "AH no valid digits in spi `%s'", spistr);
36 }
37 if ( spi == ULONG_MAX && errno == ERANGE ) {
Jan Engelhardt1829ed42009-02-21 03:29:44 +010038 xtables_error(PARAMETER_PROBLEM,
Rusty Russell52451822000-08-27 07:47:46 +000039 "spi `%s' specified too big: would overflow", spistr);
40 }
41 if ( *spistr != '\0' && *ep != '\0' ) {
Jan Engelhardt1829ed42009-02-21 03:29:44 +010042 xtables_error(PARAMETER_PROBLEM,
Rusty Russell52451822000-08-27 07:47:46 +000043 "AH error parsing spi `%s'", spistr);
44 }
Jan Engelhardt213e1852009-01-27 17:24:34 +010045 return spi;
Rusty Russell52451822000-08-27 07:47:46 +000046}
47
48static void
49parse_ah_spis(const char *spistring, u_int32_t *spis)
50{
51 char *buffer;
52 char *cp;
53
54 buffer = strdup(spistring);
55 if ((cp = strchr(buffer, ':')) == NULL)
56 spis[0] = spis[1] = parse_ah_spi(buffer);
57 else {
58 *cp = '\0';
59 cp++;
60
61 spis[0] = buffer[0] ? parse_ah_spi(buffer) : 0;
62 spis[1] = cp[0] ? parse_ah_spi(cp) : 0xFFFFFFFF;
63 }
64 free(buffer);
65}
66
Jan Engelhardt59d16402007-10-04 16:28:39 +000067static void ah_init(struct xt_entry_match *m)
Rusty Russell52451822000-08-27 07:47:46 +000068{
69 struct ipt_ah *ahinfo = (struct ipt_ah *)m->data;
70
71 ahinfo->spis[1] = 0xFFFFFFFF;
72}
73
74#define AH_SPI 0x01
75
Jan Engelhardt59d16402007-10-04 16:28:39 +000076static int ah_parse(int c, char **argv, int invert, unsigned int *flags,
77 const void *entry, struct xt_entry_match **match)
Rusty Russell52451822000-08-27 07:47:46 +000078{
79 struct ipt_ah *ahinfo = (struct ipt_ah *)(*match)->data;
80
81 switch (c) {
82 case '1':
83 if (*flags & AH_SPI)
Jan Engelhardt1829ed42009-02-21 03:29:44 +010084 xtables_error(PARAMETER_PROBLEM,
Harald Weltef0ac8142002-03-26 12:50:28 +000085 "Only one `--ahspi' allowed");
Jan Engelhardtbf971282009-11-03 19:55:11 +010086 xtables_check_inverse(optarg, &invert, &optind, 0, argv);
Jan Engelhardtbbe83862009-10-24 00:45:33 +020087 parse_ah_spis(optarg, ahinfo->spis);
Rusty Russell52451822000-08-27 07:47:46 +000088 if (invert)
89 ahinfo->invflags |= IPT_AH_INV_SPI;
90 *flags |= AH_SPI;
91 break;
92 default:
93 return 0;
94 }
95
96 return 1;
97}
98
Rusty Russell52451822000-08-27 07:47:46 +000099static void
100print_spis(const char *name, u_int32_t min, u_int32_t max,
101 int invert)
102{
103 const char *inv = invert ? "!" : "";
104
105 if (min != 0 || max != 0xFFFFFFFF || invert) {
106 printf("%s", name);
107 if (min == max) {
108 printf(":%s", inv);
109 printf("%u", min);
110 } else {
111 printf("s:%s", inv);
112 printf("%u",min);
113 printf(":");
114 printf("%u",max);
115 }
116 printf(" ");
117 }
118}
119
Jan Engelhardt59d16402007-10-04 16:28:39 +0000120static void ah_print(const void *ip, const struct xt_entry_match *match,
121 int numeric)
Rusty Russell52451822000-08-27 07:47:46 +0000122{
123 const struct ipt_ah *ah = (struct ipt_ah *)match->data;
124
125 printf("ah ");
126 print_spis("spi", ah->spis[0], ah->spis[1],
127 ah->invflags & IPT_AH_INV_SPI);
128 if (ah->invflags & ~IPT_AH_INV_MASK)
129 printf("Unknown invflags: 0x%X ",
130 ah->invflags & ~IPT_AH_INV_MASK);
131}
132
Jan Engelhardt59d16402007-10-04 16:28:39 +0000133static void ah_save(const void *ip, const struct xt_entry_match *match)
Rusty Russell52451822000-08-27 07:47:46 +0000134{
135 const struct ipt_ah *ahinfo = (struct ipt_ah *)match->data;
136
Harald Weltef0ac8142002-03-26 12:50:28 +0000137 if (!(ahinfo->spis[0] == 0
138 && ahinfo->spis[1] == 0xFFFFFFFF)) {
Jan Engelhardtcea9f712008-12-09 15:06:20 +0100139 printf("%s--ahspi ",
Harald Weltef0ac8142002-03-26 12:50:28 +0000140 (ahinfo->invflags & IPT_AH_INV_SPI) ? "! " : "");
Rusty Russell52451822000-08-27 07:47:46 +0000141 if (ahinfo->spis[0]
142 != ahinfo->spis[1])
Harald Weltef0ac8142002-03-26 12:50:28 +0000143 printf("%u:%u ",
Rusty Russell52451822000-08-27 07:47:46 +0000144 ahinfo->spis[0],
145 ahinfo->spis[1]);
146 else
Harald Weltef0ac8142002-03-26 12:50:28 +0000147 printf("%u ",
Rusty Russell52451822000-08-27 07:47:46 +0000148 ahinfo->spis[0]);
149 }
150
151}
152
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200153static struct xtables_match ah_mt_reg = {
Pablo Neira8caee8b2004-12-28 13:11:59 +0000154 .name = "ah",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200155 .version = XTABLES_VERSION,
Jan Engelhardt03d99482008-11-18 12:27:54 +0100156 .family = NFPROTO_IPV4,
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200157 .size = XT_ALIGN(sizeof(struct ipt_ah)),
158 .userspacesize = XT_ALIGN(sizeof(struct ipt_ah)),
Jan Engelhardt59d16402007-10-04 16:28:39 +0000159 .help = ah_help,
160 .init = ah_init,
161 .parse = ah_parse,
162 .print = ah_print,
163 .save = ah_save,
164 .extra_opts = ah_opts,
Rusty Russell52451822000-08-27 07:47:46 +0000165};
166
167void
168_init(void)
169{
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200170 xtables_register_match(&ah_mt_reg);
Rusty Russell52451822000-08-27 07:47:46 +0000171}