Sapan says vnet_tun is obsolete.
[iptables.git] / extensions / libipt_ah.c
1 /* Shared library add-on to iptables to add AH 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 <iptables.h>
9 #include <linux/netfilter_ipv4/ipt_ah.h>
10                                         
11 /* Function which prints out usage message. */
12 static void ah_help(void)
13 {
14         printf(
15 "ah match options:\n"
16 " --ahspi [!] spi[:spi]\n"
17 "                               match spi (range)\n");
18 }
19
20 static const struct option ah_opts[] = {
21         { "ahspi", 1, NULL, '1' },
22         { .name = NULL }
23 };
24
25 static u_int32_t
26 parse_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 ) {
34                 exit_error(PARAMETER_PROBLEM,
35                            "AH 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                            "AH error parsing spi `%s'", spistr);
44         }
45         return (u_int32_t) spi;
46 }
47
48 static void
49 parse_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
67 /* Initialize the match. */
68 static void ah_init(struct xt_entry_match *m)
69 {
70         struct ipt_ah *ahinfo = (struct ipt_ah *)m->data;
71
72         ahinfo->spis[1] = 0xFFFFFFFF;
73 }
74
75 #define AH_SPI 0x01
76
77 /* Function which parses command options; returns true if it
78    ate an option */
79 static int ah_parse(int c, char **argv, int invert, unsigned int *flags,
80                     const void *entry, struct xt_entry_match **match)
81 {
82         struct ipt_ah *ahinfo = (struct ipt_ah *)(*match)->data;
83
84         switch (c) {
85         case '1':
86                 if (*flags & AH_SPI)
87                         exit_error(PARAMETER_PROBLEM,
88                                    "Only one `--ahspi' allowed");
89                 check_inverse(optarg, &invert, &optind, 0);
90                 parse_ah_spis(argv[optind-1], ahinfo->spis);
91                 if (invert)
92                         ahinfo->invflags |= IPT_AH_INV_SPI;
93                 *flags |= AH_SPI;
94                 break;
95         default:
96                 return 0;
97         }
98
99         return 1;
100 }
101
102 static void
103 print_spis(const char *name, u_int32_t min, u_int32_t max,
104             int invert)
105 {
106         const char *inv = invert ? "!" : "";
107
108         if (min != 0 || max != 0xFFFFFFFF || invert) {
109                 printf("%s", name);
110                 if (min == max) {
111                         printf(":%s", inv);
112                         printf("%u", min);
113                 } else {
114                         printf("s:%s", inv);
115                         printf("%u",min);
116                         printf(":");
117                         printf("%u",max);
118                 }
119                 printf(" ");
120         }
121 }
122
123 /* Prints out the union ipt_matchinfo. */
124 static void ah_print(const void *ip, const struct xt_entry_match *match,
125                      int numeric)
126 {
127         const struct ipt_ah *ah = (struct ipt_ah *)match->data;
128
129         printf("ah ");
130         print_spis("spi", ah->spis[0], ah->spis[1],
131                     ah->invflags & IPT_AH_INV_SPI);
132         if (ah->invflags & ~IPT_AH_INV_MASK)
133                 printf("Unknown invflags: 0x%X ",
134                        ah->invflags & ~IPT_AH_INV_MASK);
135 }
136
137 /* Saves the union ipt_matchinfo in parsable form to stdout. */
138 static void ah_save(const void *ip, const struct xt_entry_match *match)
139 {
140         const struct ipt_ah *ahinfo = (struct ipt_ah *)match->data;
141
142         if (!(ahinfo->spis[0] == 0
143             && ahinfo->spis[1] == 0xFFFFFFFF)) {
144                 printf("--ahspi %s", 
145                         (ahinfo->invflags & IPT_AH_INV_SPI) ? "! " : "");
146                 if (ahinfo->spis[0]
147                     != ahinfo->spis[1])
148                         printf("%u:%u ",
149                                ahinfo->spis[0],
150                                ahinfo->spis[1]);
151                 else
152                         printf("%u ",
153                                ahinfo->spis[0]);
154         }
155
156 }
157
158 static struct xtables_match ah_mt_reg = {
159         .name           = "ah",
160         .version        = XTABLES_VERSION,
161         .family         = PF_INET,
162         .size           = XT_ALIGN(sizeof(struct ipt_ah)),
163         .userspacesize  = XT_ALIGN(sizeof(struct ipt_ah)),
164         .help           = ah_help,
165         .init           = ah_init,
166         .parse          = ah_parse,
167         .print          = ah_print,
168         .save           = ah_save,
169         .extra_opts     = ah_opts,
170 };
171
172 void
173 _init(void)
174 {
175         xtables_register_match(&ah_mt_reg);
176 }