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*, str* */
24 #include <linux/netfilter_ipv4/ip_set_nethash.h>
28 #define OPT_CREATE_HASHSIZE 0x01U
29 #define OPT_CREATE_PROBES 0x02U
30 #define OPT_CREATE_RESIZE 0x04U
32 /* Initialize the create. */
34 nethash_create_init(void *data
)
36 struct ip_set_req_nethash_create
*mydata
= data
;
40 /* Default create parameters */
41 mydata
->hashsize
= IP_NF_SET_HASHSIZE
;
46 /* Function which parses command options; returns true if it ate an option */
48 nethash_create_parse(int c
, char *argv
[] UNUSED
, void *data
, unsigned *flags
)
50 struct ip_set_req_nethash_create
*mydata
= data
;
58 if (string_to_number(optarg
, 1, UINT_MAX
- 1, &mydata
->hashsize
))
59 exit_error(PARAMETER_PROBLEM
, "Invalid hashsize `%s' specified", optarg
);
61 *flags
|= OPT_CREATE_HASHSIZE
;
63 DP("--hashsize %u", mydata
->hashsize
);
69 if (string_to_number(optarg
, 1, 65535, &value
))
70 exit_error(PARAMETER_PROBLEM
, "Invalid probes `%s' specified", optarg
);
72 mydata
->probes
= value
;
73 *flags
|= OPT_CREATE_PROBES
;
75 DP("--probes %u", mydata
->probes
);
81 if (string_to_number(optarg
, 0, 65535, &value
))
82 exit_error(PARAMETER_PROBLEM
, "Invalid resize `%s' specified", optarg
);
84 mydata
->resize
= value
;
85 *flags
|= OPT_CREATE_RESIZE
;
87 DP("--resize %u", mydata
->resize
);
98 /* Final check; exit if not ok. */
100 nethash_create_final(void *data UNUSED
, unsigned int flags UNUSED
)
104 /* Create commandline options */
105 static const struct option create_opts
[] = {
106 {.name
= "hashsize", .has_arg
= required_argument
, .val
= '1'},
107 {.name
= "probes", .has_arg
= required_argument
, .val
= '2'},
108 {.name
= "resize", .has_arg
= required_argument
, .val
= '3'},
112 /* Add, del, test parser */
114 nethash_adt_parser(int cmd
, const char *arg
, void *data
)
116 struct ip_set_req_nethash
*mydata
= data
;
117 char *saved
= ipset_strdup(arg
);
118 char *ptr
, *tmp
= saved
;
121 ptr
= strsep(&tmp
, "/");
127 exit_error(PARAMETER_PROBLEM
,
128 "Missing cidr from `%s'", arg
);
130 if (string_to_number(tmp
, 1, 31, &cidr
))
131 exit_error(PARAMETER_PROBLEM
,
132 "Out of range cidr `%s' specified", arg
);
135 parse_ip(ptr
, &mydata
->ip
);
138 exit_error(PARAMETER_PROBLEM
,
139 "Zero valued IP address `%s' specified", ptr
);
151 nethash_initheader(struct set
*set
, const void *data
)
153 const struct ip_set_req_nethash_create
*header
= data
;
154 struct ip_set_nethash
*map
= set
->settype
->header
;
156 memset(map
, 0, sizeof(struct ip_set_nethash
));
157 map
->hashsize
= header
->hashsize
;
158 map
->probes
= header
->probes
;
159 map
->resize
= header
->resize
;
163 nethash_printheader(struct set
*set
, unsigned options UNUSED
)
165 struct ip_set_nethash
*mysetdata
= set
->settype
->header
;
167 printf(" hashsize: %u", mysetdata
->hashsize
);
168 printf(" probes: %u", mysetdata
->probes
);
169 printf(" resize: %u\n", mysetdata
->resize
);
175 unpack_ip_tostring(ip_set_ip_t ip
, unsigned options UNUSED
)
181 for (i
= 3; i
>= 0; i
--)
182 if (((unsigned char *)&ip
)[i
] != 0) {
187 a
= ((unsigned char *)&ip
)[j
];
191 } else if (a
<= 192) {
194 } else if (a
<= 224) {
197 } else if (a
<= 240) {
200 } else if (a
<= 248) {
203 } else if (a
<= 252) {
206 } else if (a
<= 254) {
212 ((unsigned char *)&ip
)[j
] = a
;
215 sprintf(buf
, "%u.%u.%u.%u/%u",
216 ((unsigned char *)&ip
)[0],
217 ((unsigned char *)&ip
)[1],
218 ((unsigned char *)&ip
)[2],
219 ((unsigned char *)&ip
)[3],
222 DP("%s %s", ip_tostring(ntohl(ip
), 0), buf
);
227 nethash_printips(struct set
*set UNUSED
, void *data
, u_int32_t len
,
228 unsigned options
, char dont_align
)
233 while (offset
< len
) {
235 printf("%s\n", unpack_ip_tostring(*ip
, options
));
236 offset
+= IPSET_VALIGN(sizeof(ip_set_ip_t
), dont_align
);
241 nethash_saveheader(struct set
*set
, unsigned options UNUSED
)
243 struct ip_set_nethash
*mysetdata
= set
->settype
->header
;
245 printf("-N %s %s --hashsize %u --probes %u --resize %u\n",
246 set
->name
, set
->settype
->typename
,
247 mysetdata
->hashsize
, mysetdata
->probes
, mysetdata
->resize
);
250 /* Print save for an IP */
252 nethash_saveips(struct set
*set UNUSED
, void *data
, u_int32_t len
,
253 unsigned options
, char dont_align
)
258 while (offset
< len
) {
260 printf("-A %s %s\n", set
->name
,
261 unpack_ip_tostring(*ip
, options
));
262 offset
+= IPSET_VALIGN(sizeof(ip_set_ip_t
), dont_align
);
270 ("-N set nethash [--hashsize hashsize] [--probes probes ]\n"
271 " [--resize resize]\n"
277 static struct settype settype_nethash
= {
278 .typename
= SETTYPE_NAME
,
279 .protocol_version
= IP_SET_PROTOCOL_VERSION
,
282 .create_size
= sizeof(struct ip_set_req_nethash_create
),
283 .create_init
= nethash_create_init
,
284 .create_parse
= nethash_create_parse
,
285 .create_final
= nethash_create_final
,
286 .create_opts
= create_opts
,
289 .adt_size
= sizeof(struct ip_set_req_nethash
),
290 .adt_parser
= nethash_adt_parser
,
293 .header_size
= sizeof(struct ip_set_nethash
),
294 .initheader
= nethash_initheader
,
295 .printheader
= nethash_printheader
,
296 .printips
= nethash_printips
,
297 .printips_sorted
= nethash_printips
,
298 .saveheader
= nethash_saveheader
,
299 .saveips
= nethash_saveips
,
301 .usage
= nethash_usage
,
306 settype_register(&settype_nethash
);