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
18 #include <limits.h> /* UINT_MAX */
19 #include <stdio.h> /* *printf */
20 #include <string.h> /* mem* */
24 #include <linux/netfilter_ipv4/ip_set_iphash.h>
28 #define OPT_CREATE_HASHSIZE 0x01U
29 #define OPT_CREATE_PROBES 0x02U
30 #define OPT_CREATE_RESIZE 0x04U
31 #define OPT_CREATE_NETMASK 0x08U
33 /* Initialize the create. */
35 iphash_create_init(void *data
)
37 struct ip_set_req_iphash_create
*mydata
= data
;
41 /* Default create parameters */
42 mydata
->hashsize
= IP_NF_SET_HASHSIZE
;
46 mydata
->netmask
= 0xFFFFFFFF;
49 /* Function which parses command options; returns true if it ate an option */
51 iphash_create_parse(int c
, char *argv
[] UNUSED
, void *data
, unsigned *flags
)
53 struct ip_set_req_iphash_create
*mydata
=
54 (struct ip_set_req_iphash_create
*) data
;
63 if (string_to_number(optarg
, 1, UINT_MAX
- 1, &mydata
->hashsize
))
64 exit_error(PARAMETER_PROBLEM
, "Invalid hashsize `%s' specified", optarg
);
66 *flags
|= OPT_CREATE_HASHSIZE
;
68 DP("--hashsize %u", mydata
->hashsize
);
74 if (string_to_number(optarg
, 1, 65535, &value
))
75 exit_error(PARAMETER_PROBLEM
, "Invalid probes `%s' specified", optarg
);
77 mydata
->probes
= value
;
78 *flags
|= OPT_CREATE_PROBES
;
80 DP("--probes %u", mydata
->probes
);
86 if (string_to_number(optarg
, 0, 65535, &value
))
87 exit_error(PARAMETER_PROBLEM
, "Invalid resize `%s' specified", optarg
);
89 mydata
->resize
= value
;
90 *flags
|= OPT_CREATE_RESIZE
;
92 DP("--resize %u", mydata
->resize
);
98 if (string_to_number(optarg
, 0, 32, &bits
))
99 exit_error(PARAMETER_PROBLEM
,
100 "Invalid netmask `%s' specified", optarg
);
103 mydata
->netmask
= 0xFFFFFFFF << (32 - bits
);
105 *flags
|= OPT_CREATE_NETMASK
;
107 DP("--netmask %x", mydata
->netmask
);
118 /* Final check; exit if not ok. */
120 iphash_create_final(void *data UNUSED
, unsigned int flags UNUSED
)
124 /* Create commandline options */
125 static const struct option create_opts
[] = {
126 {.name
= "hashsize", .has_arg
= required_argument
, .val
= '1'},
127 {.name
= "probes", .has_arg
= required_argument
, .val
= '2'},
128 {.name
= "resize", .has_arg
= required_argument
, .val
= '3'},
129 {.name
= "netmask", .has_arg
= required_argument
, .val
= '4'},
133 /* Add, del, test parser */
135 iphash_adt_parser(int cmd UNUSED
, const char *arg
, void *data
)
137 struct ip_set_req_iphash
*mydata
= data
;
139 parse_ip(arg
, &mydata
->ip
);
141 exit_error(PARAMETER_PROBLEM
,
142 "Zero valued IP address `%s' specified", arg
);
152 iphash_initheader(struct set
*set
, const void *data
)
154 const struct ip_set_req_iphash_create
*header
= data
;
155 struct ip_set_iphash
*map
= set
->settype
->header
;
157 memset(map
, 0, sizeof(struct ip_set_iphash
));
158 map
->hashsize
= header
->hashsize
;
159 map
->probes
= header
->probes
;
160 map
->resize
= header
->resize
;
161 map
->netmask
= header
->netmask
;
165 mask_to_bits(ip_set_ip_t mask
)
167 unsigned int bits
= 32;
168 ip_set_ip_t maskaddr
;
170 if (mask
== 0xFFFFFFFF)
173 maskaddr
= 0xFFFFFFFE;
174 while (--bits
> 0 && maskaddr
!= mask
)
181 iphash_printheader(struct set
*set
, unsigned options UNUSED
)
183 struct ip_set_iphash
*mysetdata
= set
->settype
->header
;
185 printf(" hashsize: %u", mysetdata
->hashsize
);
186 printf(" probes: %u", mysetdata
->probes
);
187 printf(" resize: %u", mysetdata
->resize
);
188 if (mysetdata
->netmask
== 0xFFFFFFFF)
191 printf(" netmask: %d\n", mask_to_bits(mysetdata
->netmask
));
195 iphash_printips(struct set
*set UNUSED
, void *data
, u_int32_t len
,
196 unsigned options
, char dont_align
)
201 while (offset
< len
) {
203 printf("%s\n", ip_tostring(*ip
, options
));
204 offset
+= IPSET_VALIGN(sizeof(ip_set_ip_t
), dont_align
);
209 iphash_saveheader(struct set
*set
, unsigned options UNUSED
)
211 struct ip_set_iphash
*mysetdata
= set
->settype
->header
;
213 printf("-N %s %s --hashsize %u --probes %u --resize %u",
214 set
->name
, set
->settype
->typename
,
215 mysetdata
->hashsize
, mysetdata
->probes
, mysetdata
->resize
);
216 if (mysetdata
->netmask
== 0xFFFFFFFF)
219 printf(" --netmask %d\n", mask_to_bits(mysetdata
->netmask
));
222 /* Print save for an IP */
224 iphash_saveips(struct set
*set UNUSED
, void *data
, u_int32_t len
,
225 unsigned options
, char dont_align
)
230 while (offset
< len
) {
232 printf("-A %s %s\n", set
->name
, ip_tostring(*ip
, options
));
233 offset
+= IPSET_VALIGN(sizeof(ip_set_ip_t
), dont_align
);
241 ("-N set iphash [--hashsize hashsize] [--probes probes ]\n"
242 " [--resize resize] [--netmask CIDR-netmask]\n"
248 static struct settype settype_iphash
= {
249 .typename
= SETTYPE_NAME
,
250 .protocol_version
= IP_SET_PROTOCOL_VERSION
,
253 .create_size
= sizeof(struct ip_set_req_iphash_create
),
254 .create_init
= iphash_create_init
,
255 .create_parse
= iphash_create_parse
,
256 .create_final
= iphash_create_final
,
257 .create_opts
= create_opts
,
260 .adt_size
= sizeof(struct ip_set_req_iphash
),
261 .adt_parser
= iphash_adt_parser
,
264 .header_size
= sizeof(struct ip_set_iphash
),
265 .initheader
= iphash_initheader
,
266 .printheader
= iphash_printheader
,
267 .printips
= iphash_printips
,
268 .printips_sorted
= iphash_printips
,
269 .saveheader
= iphash_saveheader
,
270 .saveips
= iphash_saveips
,
272 .usage
= iphash_usage
,
277 settype_register(&settype_iphash
);