Sapan says vnet_tun is obsolete.
[iptables.git] / extensions / libxt_esp.c
1 /* Shared library add-on to iptables to add ESP support. */
2 #include <stdio.h>
3 #include <netdb.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <getopt.h>
7 #include <errno.h>
8 #include <xtables.h>
9 #include <linux/netfilter/xt_esp.h>
10
11 /* Function which prints out usage message. */
12 static void esp_help(void)
13 {
14         printf(
15 "esp match options:\n"
16 " --espspi [!] spi[:spi]\n"
17 "                               match spi (range)\n");
18 }
19
20 static const struct option esp_opts[] = {
21         { "espspi", 1, NULL, '1' },
22         { .name = NULL }
23 };
24
25 static u_int32_t
26 parse_esp_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 ) {
34                 exit_error(PARAMETER_PROBLEM,
35                            "ESP no valid digits in spi `%s'", spistr);
36         }
37         if ( spi == ULONG_MAX  && errno == ERANGE ) {
38                 exit_error(PARAMETER_PROBLEM,
39                            "spi `%s' specified too big: would overflow", spistr);
40         }       
41         if ( *spistr != '\0'  && *ep != '\0' ) {
42                 exit_error(PARAMETER_PROBLEM,
43                            "ESP error parsing spi `%s'", spistr);
44         }
45         return (u_int32_t) spi;
46 }
47
48 static void
49 parse_esp_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_esp_spi(buffer);
57         else {
58                 *cp = '\0';
59                 cp++;
60
61                 spis[0] = buffer[0] ? parse_esp_spi(buffer) : 0;
62                 spis[1] = cp[0] ? parse_esp_spi(cp) : 0xFFFFFFFF;
63                 if (spis[0] > spis[1])
64                         exit_error(PARAMETER_PROBLEM,
65                                    "Invalid ESP spi range: %s", spistring);
66         }
67         free(buffer);
68 }
69
70 /* Initialize the match. */
71 static void esp_init(struct xt_entry_match *m)
72 {
73         struct xt_esp *espinfo = (struct xt_esp *)m->data;
74
75         espinfo->spis[1] = 0xFFFFFFFF;
76 }
77
78 #define ESP_SPI 0x01
79
80 /* Function which parses command options; returns true if it
81    ate an option */
82 static int
83 esp_parse(int c, char **argv, int invert, unsigned int *flags,
84           const void *entry, struct xt_entry_match **match)
85 {
86         struct xt_esp *espinfo = (struct xt_esp *)(*match)->data;
87
88         switch (c) {
89         case '1':
90                 if (*flags & ESP_SPI)
91                         exit_error(PARAMETER_PROBLEM,
92                                    "Only one `--espspi' allowed");
93                 check_inverse(optarg, &invert, &optind, 0);
94                 parse_esp_spis(argv[optind-1], espinfo->spis);
95                 if (invert)
96                         espinfo->invflags |= XT_ESP_INV_SPI;
97                 *flags |= ESP_SPI;
98                 break;
99         default:
100                 return 0;
101         }
102
103         return 1;
104 }
105
106 static void
107 print_spis(const char *name, u_int32_t min, u_int32_t max,
108             int invert)
109 {
110         const char *inv = invert ? "!" : "";
111
112         if (min != 0 || max != 0xFFFFFFFF || invert) {
113                 if (min == max)
114                         printf("%s:%s%u ", name, inv, min);
115                 else
116                         printf("%ss:%s%u:%u ", name, inv, min, max);
117         }
118 }
119
120 /* Prints out the union ipt_matchinfo. */
121 static void
122 esp_print(const void *ip, const struct xt_entry_match *match, int numeric)
123 {
124         const struct xt_esp *esp = (struct xt_esp *)match->data;
125
126         printf("esp ");
127         print_spis("spi", esp->spis[0], esp->spis[1],
128                     esp->invflags & XT_ESP_INV_SPI);
129         if (esp->invflags & ~XT_ESP_INV_MASK)
130                 printf("Unknown invflags: 0x%X ",
131                        esp->invflags & ~XT_ESP_INV_MASK);
132 }
133
134 /* Saves the union ipt_matchinfo in parsable form to stdout. */
135 static void esp_save(const void *ip, const struct xt_entry_match *match)
136 {
137         const struct xt_esp *espinfo = (struct xt_esp *)match->data;
138
139         if (!(espinfo->spis[0] == 0
140             && espinfo->spis[1] == 0xFFFFFFFF)) {
141                 printf("--espspi %s", 
142                         (espinfo->invflags & XT_ESP_INV_SPI) ? "! " : "");
143                 if (espinfo->spis[0]
144                     != espinfo->spis[1])
145                         printf("%u:%u ",
146                                espinfo->spis[0],
147                                espinfo->spis[1]);
148                 else
149                         printf("%u ",
150                                espinfo->spis[0]);
151         }
152
153 }
154
155 static struct xtables_match esp_match = {
156         .family         = AF_INET,
157         .name           = "esp",
158         .version        = XTABLES_VERSION,
159         .size           = XT_ALIGN(sizeof(struct xt_esp)),
160         .userspacesize  = XT_ALIGN(sizeof(struct xt_esp)),
161         .help           = esp_help,
162         .init           = esp_init,
163         .parse          = esp_parse,
164         .print          = esp_print,
165         .save           = esp_save,
166         .extra_opts     = esp_opts,
167 };
168
169 static struct xtables_match esp_match6 = {
170         .family         = AF_INET6,
171         .name           = "esp",
172         .version        = XTABLES_VERSION,
173         .size           = XT_ALIGN(sizeof(struct xt_esp)),
174         .userspacesize  = XT_ALIGN(sizeof(struct xt_esp)),
175         .help           = esp_help,
176         .init           = esp_init,
177         .parse          = esp_parse,
178         .print          = esp_print,
179         .save           = esp_save,
180         .extra_opts     = esp_opts,
181 };
182
183 void
184 _init(void)
185 {
186         xtables_register_match(&esp_match);
187         xtables_register_match(&esp_match6);
188 }