New routers supported
[tomato.git] / release / src / router / ipset / ipset_setlist.c
blobde16c442ec8e17fe800f3ba5e1188ab7a846fe64
1 /* Copyright 2008 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
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
25 #include <linux/netfilter_ipv4/ip_set_setlist.h>
26 #include "ipset.h"
28 /* Initialize the create. */
29 static void
30 setlist_create_init(void *data)
32 struct ip_set_req_setlist_create *mydata = data;
34 mydata->size = 8;
37 /* Function which parses command options; returns true if it ate an option */
38 static int
39 setlist_create_parse(int c, char *argv[] UNUSED, void *data,
40 unsigned *flags UNUSED)
42 struct ip_set_req_setlist_create *mydata = data;
43 unsigned int size;
45 switch (c) {
46 case '1':
47 if (string_to_number(optarg, 1, 255, &size))
48 exit_error(PARAMETER_PROBLEM,
49 "Invalid size '%s specified: must be "
50 "between 1-255", optarg);
51 mydata->size = size;
52 break;
53 default:
54 return 0;
56 return 1;
59 /* Final check; exit if not ok. */
60 static void
61 setlist_create_final(void *data UNUSED, unsigned int flags UNUSED)
65 /* Create commandline options */
66 static const struct option create_opts[] = {
67 {.name = "size", .has_arg = required_argument, .val = '1'},
68 {NULL},
71 static void
72 check_setname(const char *name)
74 if (strlen(name) > IP_SET_MAXNAMELEN - 1)
75 exit_error(PARAMETER_PROBLEM,
76 "Setname %s is longer than %d characters.",
77 name, IP_SET_MAXNAMELEN - 1);
80 /* Add, del, test parser */
81 static ip_set_ip_t
82 setlist_adt_parser(int cmd UNUSED, const char *arg, void *data)
84 struct ip_set_req_setlist *mydata = data;
85 char *saved = ipset_strdup(arg);
86 char *ptr, *tmp = saved;
88 DP("setlist: %p %p", arg, data);
90 ptr = strsep(&tmp, ",");
91 check_setname(ptr);
92 strcpy(mydata->name, ptr);
94 if (!tmp) {
95 mydata->before = 0;
96 mydata->ref[0] = '\0';
97 return 1;
100 ptr = strsep(&tmp, ",");
102 if (tmp == NULL || !(strcmp(ptr, "before") == 0 || strcmp(ptr, "after") == 0))
103 exit_error(PARAMETER_PROBLEM,
104 "Syntax error, you must specify elements as setname,[before|after],setname");
106 check_setname(tmp);
107 strcpy(mydata->ref, tmp);
108 mydata->before = !strcmp(ptr, "before");
110 free(saved);
112 return 1;
116 * Print and save
119 static void
120 setlist_initheader(struct set *set, const void *data)
122 const struct ip_set_req_setlist_create *header = data;
123 struct ip_set_setlist *map = set->settype->header;
125 memset(map, 0, sizeof(struct ip_set_setlist));
126 map->size = header->size;
129 static void
130 setlist_printheader(struct set *set, unsigned options UNUSED)
132 struct ip_set_setlist *mysetdata = set->settype->header;
134 printf(" size: %u\n", mysetdata->size);
137 static void
138 setlist_printips_sorted(struct set *set, void *data,
139 u_int32_t len UNUSED, unsigned options UNUSED,
140 char dont_align)
142 struct ip_set_setlist *mysetdata = set->settype->header;
143 int i, asize;
144 ip_set_id_t *id;
145 struct set *elem;
147 asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
148 for (i = 0; i < mysetdata->size; i++ ) {
149 DP("Try %u", i);
150 id = (ip_set_id_t *)(data + i * asize);
151 DP("Try %u, check", i);
152 if (*id == IP_SET_INVALID_ID)
153 return;
154 elem = set_find_byid(*id);
155 printf("%s\n", elem->name);
159 static void
160 setlist_saveheader(struct set *set, unsigned options UNUSED)
162 struct ip_set_setlist *mysetdata = set->settype->header;
164 printf("-N %s %s --size %u\n",
165 set->name, set->settype->typename,
166 mysetdata->size);
169 static void
170 setlist_saveips(struct set *set, void *data,
171 u_int32_t len UNUSED, unsigned options UNUSED, char dont_align)
173 struct ip_set_setlist *mysetdata = set->settype->header;
174 int i, asize;
175 ip_set_id_t *id;
176 struct set *elem;
178 asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
179 for (i = 0; i < mysetdata->size; i++ ) {
180 id = (ip_set_id_t *)(data + i * asize);
181 if (*id == IP_SET_INVALID_ID)
182 return;
183 elem = set_find_byid(*id);
184 printf("-A %s %s\n", set->name, elem->name);
188 static void
189 setlist_usage(void)
191 printf
192 ("-N set setlist --size size\n"
193 "-A set setname[,before|after,setname]\n"
194 "-D set setname\n"
195 "-T set setname\n");
198 static struct settype settype_setlist = {
199 .typename = SETTYPE_NAME,
200 .protocol_version = IP_SET_PROTOCOL_VERSION,
202 /* Create */
203 .create_size = sizeof(struct ip_set_req_setlist_create),
204 .create_init = setlist_create_init,
205 .create_parse = setlist_create_parse,
206 .create_final = setlist_create_final,
207 .create_opts = create_opts,
209 /* Add/del/test */
210 .adt_size = sizeof(struct ip_set_req_setlist),
211 .adt_parser = setlist_adt_parser,
213 /* Printing */
214 .header_size = sizeof(struct ip_set_setlist),
215 .initheader = setlist_initheader,
216 .printheader = setlist_printheader,
217 .printips = setlist_printips_sorted,
218 .printips_sorted = setlist_printips_sorted,
219 .saveheader = setlist_saveheader,
220 .saveips = setlist_saveips,
222 .usage = setlist_usage,
225 CONSTRUCTOR(setlist)
227 settype_register(&settype_setlist);