missed
[iptables.git] / ipset / ipset_iptreemap.c
1 /* Copyright 2007 Sven Wegener <sven.wegener@stealer.net>
2  *
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 2 of the License, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15  * Place, Suite 330, Boston, MA 02111-1307 USA
16  */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <limits.h>
24
25 #include <linux/netfilter_ipv4/ip_set_iptreemap.h>
26
27 #include "ipset.h"
28
29 #define OPT_CREATE_GC 0x1
30
31 void
32 create_init(void *data)
33 {
34         struct ip_set_req_iptreemap_create *mydata = (struct ip_set_req_iptreemap_create *) data;
35
36         mydata->gc_interval = 0;
37 }
38
39 int
40 create_parse(int c, char *argv[], void *data, unsigned int *flags)
41 {
42         struct ip_set_req_iptreemap_create *mydata = (struct ip_set_req_iptreemap_create *) data;
43
44         switch (c) {
45                 case 'g':
46                         string_to_number(optarg, 0, UINT_MAX, &mydata->gc_interval);
47
48                         *flags |= OPT_CREATE_GC;
49                 break;
50                 default:
51                         return 0;
52                 break;
53         }
54
55         return 1;
56 }
57
58 void
59 create_final(void *data, unsigned int flags)
60 {
61 }
62
63 static struct option create_opts[] = {
64         {"gc", 1, 0, 'g'},
65         {0}
66 };
67
68 ip_set_ip_t
69 adt_parser(unsigned int cmd, const char *optarg, void *data)
70 {
71         struct ip_set_req_iptreemap *mydata = (struct ip_set_req_iptreemap *) data;
72         ip_set_ip_t mask;
73
74         char *saved = ipset_strdup(optarg);
75         char *ptr, *tmp = saved;
76
77         if (strchr(tmp, '/')) {
78                 parse_ipandmask(tmp, &mydata->start, &mask);
79                 mydata->end = mydata->start | ~mask;
80         } else {
81                 ptr = strsep(&tmp, ":");
82                 parse_ip(ptr, &mydata->start);
83
84                 if (tmp) {
85                         parse_ip(tmp, &mydata->end);
86                 } else {
87                         mydata->end = mydata->start;
88                 }
89         }
90
91         return 1;
92 }
93
94 void
95 initheader(struct set *set, const void *data)
96 {
97         struct ip_set_req_iptreemap_create *header = (struct ip_set_req_iptreemap_create *) data;
98         struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->settype->header;
99
100         map->gc_interval = header->gc_interval;
101 }
102
103 void
104 printheader(struct set *set, unsigned int options)
105 {
106         struct ip_set_iptreemap *mysetdata = (struct ip_set_iptreemap *) set->settype->header;
107
108         if (mysetdata->gc_interval)
109                 printf(" gc: %u", mysetdata->gc_interval);
110
111         printf("\n");
112 }
113
114 void
115 printips_sorted(struct set *set, void *data, size_t len, unsigned int options)
116 {
117         struct ip_set_req_iptreemap *req;
118         size_t offset = 0;
119
120         while (len >= offset + sizeof(struct ip_set_req_iptreemap)) {
121                 req = (struct ip_set_req_iptreemap *) (data + offset);
122
123                 printf("%s", ip_tostring(req->start, options));
124                 if (req->start != req->end)
125                         printf(":%s", ip_tostring(req->end, options));
126                 printf("\n");
127
128                 offset += sizeof(struct ip_set_req_iptreemap);
129         }
130 }
131
132 void
133 saveheader(struct set *set, unsigned int options)
134 {
135         struct ip_set_iptreemap *mysetdata = (struct ip_set_iptreemap *) set->settype->header;
136
137         printf("-N %s %s", set->name, set->settype->typename);
138
139         if (mysetdata->gc_interval)
140                 printf(" --gc %u", mysetdata->gc_interval);
141
142         printf("\n");
143 }
144
145 void
146 saveips(struct set *set, void *data, size_t len, unsigned int options)
147 {
148         struct ip_set_req_iptreemap *req;
149         size_t offset = 0;
150
151         while (len >= offset + sizeof(struct ip_set_req_iptreemap)) {
152                 req = (struct ip_set_req_iptreemap *) (data + offset);
153
154                 printf("-A %s %s", set->name, ip_tostring(req->start, options));
155
156                 if (req->start != req->end)
157                         printf(":%s", ip_tostring(req->end, options));
158
159                 printf("\n");
160
161                 offset += sizeof(struct ip_set_req_iptreemap);
162         }
163 }
164
165 void
166 usage(void)
167 {
168         printf(
169                 "-N set iptreemap --gc interval\n"
170                 "-A set IP\n"
171                 "-D set IP\n"
172                 "-T set IP\n"
173         );
174 }
175
176 static struct settype settype_iptreemap = {
177         .typename = SETTYPE_NAME,
178         .protocol_version = IP_SET_PROTOCOL_VERSION,
179
180         .create_size = sizeof(struct ip_set_req_iptreemap_create),
181         .create_init = &create_init,
182         .create_parse = &create_parse,
183         .create_final = &create_final,
184         .create_opts = create_opts,
185
186         .adt_size = sizeof(struct ip_set_req_iptreemap),
187         .adt_parser = &adt_parser,
188
189         .header_size = sizeof(struct ip_set_iptreemap),
190         .initheader = &initheader,
191         .printheader = &printheader,
192         .printips = &printips_sorted,
193         .printips_sorted = &printips_sorted,
194         .saveheader = &saveheader,
195         .saveips = &saveips,
196
197         .bindip_tostring = &binding_ip_tostring,
198         .bindip_parse = &parse_ip,
199
200         .usage = &usage,
201 };
202
203 void __attribute__ ((constructor)) my_init(void)
204 {
205         settype_register(&settype_iptreemap);
206 }