Fix to compilation problem with new headers from 2.6.18 kernel.
[iptables.git] / ipset / ipset_portmap.c
1 /* Copyright 2004 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
2  *
3  * This program is free software; you can redistribute it and/or modify   
4  * it under the terms of the GNU General Public License as published by   
5  * the Free Software Foundation; either version 2 of the License, or      
6  * (at your option) any later version.                                    
7  *                                                                         
8  * This program is distributed in the hope that it will be useful,        
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of         
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
11  * GNU General Public License for more details.                           
12  *                                                                         
13  * You should have received a copy of the GNU General Public License      
14  * along with this program; if not, write to the Free Software            
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */
17
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24 #ifndef __always_inline
25 #define __always_inline inline
26 #endif
27 #include <asm/bitops.h>
28
29 #include <linux/netfilter_ipv4/ip_set_portmap.h>
30 #include "ipset.h"
31
32
33 #define BUFLEN 30;
34
35 #define OPT_CREATE_FROM    0x01U
36 #define OPT_CREATE_TO      0x02U
37
38 #define OPT_ADDDEL_PORT      0x01U
39
40 /* Initialize the create. */
41 void create_init(void *data)
42 {
43         DP("create INIT");
44         /* Nothing */
45 }
46
47 /* Function which parses command options; returns true if it ate an option */
48 int create_parse(int c, char *argv[], void *data, unsigned *flags)
49 {
50         struct ip_set_req_portmap_create *mydata =
51             (struct ip_set_req_portmap_create *) data;
52
53         DP("create_parse");
54
55         switch (c) {
56         case '1':
57                 parse_port(optarg, &mydata->from);
58
59                 *flags |= OPT_CREATE_FROM;
60
61                 DP("--from %x (%s)", mydata->from,
62                    port_tostring(mydata->from, 0));
63
64                 break;
65
66         case '2':
67                 parse_port(optarg, &mydata->to);
68
69                 *flags |= OPT_CREATE_TO;
70
71                 DP("--to %x (%s)", mydata->to,
72                    port_tostring(mydata->to, 0));
73
74                 break;
75
76         default:
77                 return 0;
78         }
79
80         return 1;
81 }
82
83 /* Final check; exit if not ok. */
84 void create_final(void *data, unsigned int flags)
85 {
86         struct ip_set_req_portmap_create *mydata =
87             (struct ip_set_req_portmap_create *) data;
88
89         if (flags == 0) {
90                 exit_error(PARAMETER_PROBLEM,
91                            "Need to specify --from and --to\n");
92         } else {
93                 /* --from --to */
94                 if ((flags & OPT_CREATE_FROM) == 0
95                     || (flags & OPT_CREATE_TO) == 0)
96                         exit_error(PARAMETER_PROBLEM,
97                                    "Need to specify both --from and --to\n");
98         }
99
100         DP("from : %x to: %x  diff: %d", mydata->from, mydata->to,
101            mydata->to - mydata->from);
102
103         if (mydata->from > mydata->to)
104                 exit_error(PARAMETER_PROBLEM,
105                            "From can't be lower than to.\n");
106
107         if (mydata->to - mydata->from > MAX_RANGE)
108                 exit_error(PARAMETER_PROBLEM,
109                            "Range too large. Max is %d ports in range\n",
110                            MAX_RANGE+1);
111 }
112
113 /* Create commandline options */
114 static struct option create_opts[] = {
115         {"from", 1, 0, '1'},
116         {"to", 1, 0, '2'},
117         {0}
118 };
119
120 /* Add, del, test parser */
121 ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data)
122 {
123         struct ip_set_req_portmap *mydata =
124             (struct ip_set_req_portmap *) data;
125
126         parse_port(optarg, &mydata->port);
127         DP("%s", port_tostring(mydata->port, 0));
128
129         return 1;       
130 }
131
132 /*
133  * Print and save
134  */
135
136 void initheader(struct set *set, const void *data)
137 {
138         struct ip_set_req_portmap_create *header =
139             (struct ip_set_req_portmap_create *) data;
140         struct ip_set_portmap *map =
141                 (struct ip_set_portmap *) set->settype->header;
142
143         memset(map, 0, sizeof(struct ip_set_portmap));
144         map->first_port = header->from;
145         map->last_port = header->to;
146 }
147
148 void printheader(struct set *set, unsigned options)
149 {
150         struct ip_set_portmap *mysetdata =
151             (struct ip_set_portmap *) set->settype->header;
152
153         printf(" from: %s", port_tostring(mysetdata->first_port, options));
154         printf(" to: %s\n", port_tostring(mysetdata->last_port, options));
155 }
156
157 void printports_sorted(struct set *set, void *data, size_t len, unsigned options)
158 {
159         struct ip_set_portmap *mysetdata =
160             (struct ip_set_portmap *) set->settype->header;
161         u_int32_t addr = mysetdata->first_port;
162
163         DP("%u -- %u", mysetdata->first_port, mysetdata->last_port);
164         while (addr <= mysetdata->last_port) {
165                 if (test_bit(addr - mysetdata->first_port, data))
166                         printf("%s\n", port_tostring(addr, options));
167                 addr++;
168         }
169 }
170
171 char * binding_port_tostring(struct set *set, ip_set_ip_t ip, unsigned options)
172 {
173         return port_tostring(ip, options);
174 }
175
176 void saveheader(struct set *set, unsigned options)
177 {
178         struct ip_set_portmap *mysetdata =
179             (struct ip_set_portmap *) set->settype->header;
180
181         printf("-N %s %s --from %s", 
182                set->name,
183                set->settype->typename,
184                port_tostring(mysetdata->first_port, options));
185         printf(" --to %s\n", 
186                port_tostring(mysetdata->last_port, options));
187 }
188
189 void saveports(struct set *set, void *data, size_t len, unsigned options)
190 {
191         struct ip_set_portmap *mysetdata =
192             (struct ip_set_portmap *) set->settype->header;
193         u_int32_t addr = mysetdata->first_port;
194
195         while (addr <= mysetdata->last_port) {
196                 if (test_bit(addr - mysetdata->first_port, data))
197                         printf("-A %s %s\n",
198                                set->name,
199                                port_tostring(addr, options));
200                 addr++;
201         }
202 }
203
204 void usage(void)
205 {
206         printf
207             ("-N set portmap --from PORT --to PORT\n"
208              "-A set PORT\n"
209              "-D set PORT\n"
210              "-T set PORT\n");
211 }
212
213 static struct settype settype_portmap = {
214         .typename = SETTYPE_NAME,
215         .protocol_version = IP_SET_PROTOCOL_VERSION,
216
217         /* Create */
218         .create_size = sizeof(struct ip_set_req_portmap_create),
219         .create_init = &create_init,
220         .create_parse = &create_parse,
221         .create_final = &create_final,
222         .create_opts = create_opts,
223
224         /* Add/del/test */
225         .adt_size = sizeof(struct ip_set_req_portmap),
226         .adt_parser = &adt_parser,
227
228         /* Printing */
229         .header_size = sizeof(struct ip_set_portmap),
230         .initheader = &initheader,
231         .printheader = &printheader,
232         .printips = &printports_sorted, /* We only have sorted version */
233         .printips_sorted = &printports_sorted,
234         .saveheader = &saveheader,
235         .saveips = &saveports,
236         
237         /* Bindings */
238         .bindip_tostring = &binding_port_tostring,
239         .bindip_parse = &parse_port,
240
241         .usage = &usage,
242 };
243
244 void _init(void)
245 {
246         settype_register(&settype_portmap);
247
248 }