switch4g: completely re-writen
[tomato.git] / release / src / router / ipset / ipset_portmap.c
bloba1065ae6759301549f44cab75caf7ac76c6a4049
1 /* Copyright 2004 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
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.
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
19 #include <stdio.h> /* *printf */
20 #include <string.h> /* mem* */
22 #include "ipset.h"
24 #include <linux/netfilter_ipv4/ip_set_portmap.h>
26 #define BUFLEN 30;
28 #define OPT_CREATE_FROM 0x01U
29 #define OPT_CREATE_TO 0x02U
31 #define OPT_ADDDEL_PORT 0x01U
33 /* Initialize the create. */
34 static void
35 portmap_create_init(void *data UNUSED)
37 DP("create INIT");
38 /* Nothing */
41 /* Function which parses command options; returns true if it ate an option */
42 static int
43 portmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
45 struct ip_set_req_portmap_create *mydata = data;
47 DP("create_parse");
49 switch (c) {
50 case '1':
51 parse_port(optarg, &mydata->from);
53 *flags |= OPT_CREATE_FROM;
55 DP("--from %x (%s)", mydata->from,
56 port_tostring(mydata->from, 0));
58 break;
60 case '2':
61 parse_port(optarg, &mydata->to);
63 *flags |= OPT_CREATE_TO;
65 DP("--to %x (%s)", mydata->to,
66 port_tostring(mydata->to, 0));
68 break;
70 default:
71 return 0;
74 return 1;
77 /* Final check; exit if not ok. */
78 static void
79 portmap_create_final(void *data, unsigned int flags)
81 struct ip_set_req_portmap_create *mydata = data;
83 if (flags == 0) {
84 exit_error(PARAMETER_PROBLEM,
85 "Need to specify --from and --to\n");
86 } else {
87 /* --from --to */
88 if ((flags & OPT_CREATE_FROM) == 0
89 || (flags & OPT_CREATE_TO) == 0)
90 exit_error(PARAMETER_PROBLEM,
91 "Need to specify both --from and --to\n");
94 DP("from : %x to: %x diff: %d", mydata->from, mydata->to,
95 mydata->to - mydata->from);
97 if (mydata->from > mydata->to)
98 exit_error(PARAMETER_PROBLEM,
99 "From can't be lower than to.\n");
101 if (mydata->to - mydata->from > MAX_RANGE)
102 exit_error(PARAMETER_PROBLEM,
103 "Range too large. Max is %d ports in range\n",
104 MAX_RANGE+1);
107 /* Create commandline options */
108 static const struct option create_opts[] = {
109 {.name = "from", .has_arg = required_argument, .val = '1'},
110 {.name = "to", .has_arg = required_argument, .val = '2'},
111 {NULL},
114 /* Add, del, test parser */
115 static ip_set_ip_t
116 portmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
118 struct ip_set_req_portmap *mydata = data;
120 parse_port(arg, &mydata->ip);
121 DP("%s", port_tostring(mydata->ip, 0));
123 return 1;
127 * Print and save
130 static void
131 portmap_initheader(struct set *set, const void *data)
133 const struct ip_set_req_portmap_create *header = data;
134 struct ip_set_portmap *map = set->settype->header;
136 memset(map, 0, sizeof(struct ip_set_portmap));
137 map->first_ip = header->from;
138 map->last_ip = header->to;
141 static void
142 portmap_printheader(struct set *set, unsigned options)
144 struct ip_set_portmap *mysetdata = set->settype->header;
146 printf(" from: %s", port_tostring(mysetdata->first_ip, options));
147 printf(" to: %s\n", port_tostring(mysetdata->last_ip, options));
150 static inline void
151 __portmap_printips_sorted(struct set *set, void *data,
152 u_int32_t len UNUSED, unsigned options)
154 struct ip_set_portmap *mysetdata = set->settype->header;
155 ip_set_ip_t addr = mysetdata->first_ip;
157 DP("%u -- %u", mysetdata->first_ip, mysetdata->last_ip);
158 while (addr <= mysetdata->last_ip) {
159 if (test_bit(addr - mysetdata->first_ip, data))
160 printf("%s\n", port_tostring(addr, options));
161 addr++;
165 static void
166 portmap_printips_sorted(struct set *set, void *data,
167 u_int32_t len, unsigned options,
168 char dont_align)
170 ip_set_ip_t *ip;
171 size_t offset = 0;
173 if (dont_align)
174 return __portmap_printips_sorted(set, data, len, options);
176 while (offset < len) {
177 ip = data + offset;
178 printf("%s\n", port_tostring(*ip, options));
179 offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
183 static void
184 portmap_saveheader(struct set *set, unsigned options)
186 struct ip_set_portmap *mysetdata = set->settype->header;
188 printf("-N %s %s --from %s",
189 set->name,
190 set->settype->typename,
191 port_tostring(mysetdata->first_ip, options));
192 printf(" --to %s\n",
193 port_tostring(mysetdata->last_ip, options));
196 static inline void
197 __portmap_saveips(struct set *set, void *data,
198 u_int32_t len UNUSED, unsigned options)
200 struct ip_set_portmap *mysetdata = set->settype->header;
201 ip_set_ip_t addr = mysetdata->first_ip;
203 while (addr <= mysetdata->last_ip) {
204 DP("addr: %lu, last_ip %lu", (long unsigned)addr, (long unsigned)mysetdata->last_ip);
205 if (test_bit(addr - mysetdata->first_ip, data))
206 printf("-A %s %s\n",
207 set->name,
208 port_tostring(addr, options));
209 addr++;
213 static void
214 portmap_saveips(struct set *set, void *data,
215 u_int32_t len, unsigned options,
216 char dont_align)
218 ip_set_ip_t *ip;
219 size_t offset = 0;
221 if (dont_align)
222 return __portmap_saveips(set, data, len, options);
224 while (offset < len) {
225 ip = data + offset;
226 printf("-A %s %s\n", set->name, port_tostring(*ip, options));
227 offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
231 static void
232 portmap_usage(void)
234 printf
235 ("-N set portmap --from PORT --to PORT\n"
236 "-A set PORT\n"
237 "-D set PORT\n"
238 "-T set PORT\n");
241 static struct settype settype_portmap = {
242 .typename = SETTYPE_NAME,
243 .protocol_version = IP_SET_PROTOCOL_VERSION,
245 /* Create */
246 .create_size = sizeof(struct ip_set_req_portmap_create),
247 .create_init = portmap_create_init,
248 .create_parse = portmap_create_parse,
249 .create_final = portmap_create_final,
250 .create_opts = create_opts,
252 /* Add/del/test */
253 .adt_size = sizeof(struct ip_set_req_portmap),
254 .adt_parser = portmap_adt_parser,
256 /* Printing */
257 .header_size = sizeof(struct ip_set_portmap),
258 .initheader = portmap_initheader,
259 .printheader = portmap_printheader,
260 .printips = portmap_printips_sorted,
261 .printips_sorted = portmap_printips_sorted,
262 .saveheader = portmap_saveheader,
263 .saveips = portmap_saveips,
265 .usage = portmap_usage,
268 CONSTRUCTOR(portmap)
270 settype_register(&settype_portmap);