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.
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
24 #include <sys/socket.h>
25 #include <sys/types.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
28 #ifndef __always_inline
29 #define __always_inline inline
31 #include <asm/bitops.h>
32 #include <asm/types.h>
34 #include <linux/netfilter_ipv4/ip_set_nethash.h>
35 #include <linux/netfilter_ipv4/ip_set_jhash.h>
41 #define OPT_CREATE_HASHSIZE 0x01U
42 #define OPT_CREATE_PROBES 0x02U
43 #define OPT_CREATE_RESIZE 0x04U
45 /* Initialize the create. */
46 void create_init(void *data)
48 struct ip_set_req_nethash_create *mydata =
49 (struct ip_set_req_nethash_create *) data;
53 /* Default create parameters */
54 mydata->hashsize = 1024;
59 /* Function which parses command options; returns true if it ate an option */
60 int create_parse(int c, char *argv[], void *data, unsigned *flags)
62 struct ip_set_req_nethash_create *mydata =
63 (struct ip_set_req_nethash_create *) data;
71 if (string_to_number(optarg, 1, UINT_MAX - 1, &mydata->hashsize))
72 exit_error(PARAMETER_PROBLEM, "Invalid hashsize `%s' specified", optarg);
74 *flags |= OPT_CREATE_HASHSIZE;
76 DP("--hashsize %u", mydata->hashsize);
82 if (string_to_number(optarg, 1, 65535, &value))
83 exit_error(PARAMETER_PROBLEM, "Invalid probes `%s' specified", optarg);
85 mydata->probes = value;
86 *flags |= OPT_CREATE_PROBES;
88 DP("--probes %u", mydata->probes);
94 if (string_to_number(optarg, 0, 65535, &value))
95 exit_error(PARAMETER_PROBLEM, "Invalid resize `%s' specified", optarg);
97 mydata->resize = value;
98 *flags |= OPT_CREATE_RESIZE;
100 DP("--resize %u", mydata->resize);
111 /* Final check; exit if not ok. */
112 void create_final(void *data, unsigned int flags)
115 struct ip_set_req_nethash_create *mydata =
116 (struct ip_set_req_nethash_create *) data;
118 DP("hashsize %u probes %u resize %u",
119 mydata->hashsize, mydata->probes, mydata->resize);
123 /* Create commandline options */
124 static struct option create_opts[] = {
125 {"hashsize", 1, 0, '1'},
126 {"probes", 1, 0, '2'},
127 {"resize", 1, 0, '3'},
131 /* Add, del, test parser */
132 ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data)
134 struct ip_set_req_nethash *mydata =
135 (struct ip_set_req_nethash *) data;
136 char *saved = ipset_strdup(optarg);
137 char *ptr, *tmp = saved;
140 ptr = strsep(&tmp, "/");
146 exit_error(PARAMETER_PROBLEM,
147 "Missing cidr from `%s'", optarg);
149 if (string_to_number(tmp, 1, 31, &cidr))
150 exit_error(PARAMETER_PROBLEM,
151 "Out of range cidr `%s' specified", optarg);
154 parse_ip(ptr, &mydata->ip);
156 exit_error(PARAMETER_PROBLEM,
157 "Zero valued IP address `%s' specified", ptr);
167 void initheader(struct set *set, const void *data)
169 struct ip_set_req_nethash_create *header =
170 (struct ip_set_req_nethash_create *) data;
171 struct ip_set_nethash *map =
172 (struct ip_set_nethash *) set->settype->header;
174 memset(map, 0, sizeof(struct ip_set_nethash));
175 map->hashsize = header->hashsize;
176 map->probes = header->probes;
177 map->resize = header->resize;
181 mask_to_bits(ip_set_ip_t mask)
183 unsigned int bits = 32;
184 ip_set_ip_t maskaddr;
186 if (mask == 0xFFFFFFFF)
189 maskaddr = 0xFFFFFFFE;
190 while (--bits >= 0 && maskaddr != mask)
196 void printheader(struct set *set, unsigned options)
198 struct ip_set_nethash *mysetdata =
199 (struct ip_set_nethash *) set->settype->header;
201 printf(" hashsize: %u", mysetdata->hashsize);
202 printf(" probes: %u", mysetdata->probes);
203 printf(" resize: %u\n", mysetdata->resize);
208 static char * unpack_ip_tostring(ip_set_ip_t ip, unsigned options)
214 for (i = 3; i >= 0; i--)
215 if (((unsigned char *)&ip)[i] != 0) {
220 a = ((unsigned char *)&ip)[j];
224 } else if (a <= 192) {
227 } else if (a <= 224) {
230 } else if (a <= 240) {
233 } else if (a <= 248) {
236 } else if (a <= 252) {
239 } else if (a <= 254) {
245 ((unsigned char *)&ip)[j] = a;
248 sprintf(buf, "%u.%u.%u.%u/%u",
249 ((unsigned char *)&ip)[0],
250 ((unsigned char *)&ip)[1],
251 ((unsigned char *)&ip)[2],
252 ((unsigned char *)&ip)[3],
255 DP("%s %s", ip_tostring(ntohl(ip), options), buf);
259 void printips(struct set *set, void *data, size_t len, unsigned options)
264 while (offset < len) {
267 printf("%s\n", unpack_ip_tostring(*ip, options));
268 offset += sizeof(ip_set_ip_t);
272 void saveheader(struct set *set, unsigned options)
274 struct ip_set_nethash *mysetdata =
275 (struct ip_set_nethash *) set->settype->header;
277 printf("-N %s %s --hashsize %u --probes %u --resize %u\n",
278 set->name, set->settype->typename,
279 mysetdata->hashsize, mysetdata->probes, mysetdata->resize);
282 /* Print save for an IP */
283 void saveips(struct set *set, void *data, size_t len, unsigned options)
288 while (offset < len) {
291 printf("-A %s %s\n", set->name,
292 unpack_ip_tostring(*ip, options));
293 offset += sizeof(ip_set_ip_t);
297 static char * net_tostring(struct set *set, ip_set_ip_t ip, unsigned options)
299 return unpack_ip_tostring(ip, options);
302 static void parse_net(const char *str, ip_set_ip_t *ip)
304 char *saved = strdup(str);
305 char *ptr, *tmp = saved;
308 ptr = strsep(&tmp, "/");
311 exit_error(PARAMETER_PROBLEM,
312 "Missing cidr from `%s'", str);
314 if (string_to_number(tmp, 1, 31, &cidr))
315 exit_error(PARAMETER_PROBLEM,
316 "Out of range cidr `%s' specified", str);
321 *ip = pack(*ip, cidr);
327 ("-N set nethash [--hashsize hashsize] [--probes probes ]\n"
328 " [--resize resize]\n"
334 static struct settype settype_nethash = {
335 .typename = SETTYPE_NAME,
336 .protocol_version = IP_SET_PROTOCOL_VERSION,
339 .create_size = sizeof(struct ip_set_req_nethash_create),
340 .create_init = &create_init,
341 .create_parse = &create_parse,
342 .create_final = &create_final,
343 .create_opts = create_opts,
346 .adt_size = sizeof(struct ip_set_req_nethash),
347 .adt_parser = &adt_parser,
350 .header_size = sizeof(struct ip_set_nethash),
351 .initheader = &initheader,
352 .printheader = &printheader,
353 .printips = &printips, /* We only have the unsorted version */
354 .printips_sorted = &printips,
355 .saveheader = &saveheader,
359 .bindip_tostring = &net_tostring,
360 .bindip_parse = &parse_net,
367 settype_register(&settype_nethash);