New routers supported
[tomato.git] / release / src / router / ipset / ipset_macipmap.c
blobfb97caef9405bb5a8ca0ca47931336d71a946d3d
1 /* Copyright 2000, 2001, 2002 Joakim Axelsson (gozem@linux.nu)
2 * Patrick Schaaf (bof@bof.de)
3 * Martin Josefsson (gandalf@wlug.westbo.se)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdio.h> /* *printf */
22 #include <stdlib.h> /* mem* */
23 #include <string.h> /* str* */
24 #include <net/ethernet.h> /* ETH_ALEN */
26 #include "ipset.h"
28 #include <linux/netfilter_ipv4/ip_set_macipmap.h>
30 #define BUFLEN 30;
32 #define OPT_CREATE_FROM 0x01U
33 #define OPT_CREATE_TO 0x02U
34 #define OPT_CREATE_NETWORK 0x04U
35 #define OPT_CREATE_MATCHUNSET 0x08U
37 #define OPT_ADDDEL_IP 0x01U
38 #define OPT_ADDDEL_MAC 0x02U
40 /* Initialize the create. */
41 static void
42 macipmap_create_init(void *data UNUSED)
44 DP("create INIT");
45 /* Nothing */
48 /* Function which parses command options; returns true if it ate an option */
49 static int
50 macipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
52 struct ip_set_req_macipmap_create *mydata = data;
54 DP("create_parse");
56 switch (c) {
57 case '1':
58 parse_ip(optarg, &mydata->from);
60 *flags |= OPT_CREATE_FROM;
62 DP("--from %x (%s)", mydata->from,
63 ip_tostring_numeric(mydata->from));
65 break;
67 case '2':
68 parse_ip(optarg, &mydata->to);
70 *flags |= OPT_CREATE_TO;
72 DP("--to %x (%s)", mydata->to,
73 ip_tostring_numeric(mydata->to));
75 break;
77 case '3':
78 parse_ipandmask(optarg, &mydata->from, &mydata->to);
80 /* Make to the last of from + mask */
81 mydata->to = mydata->from | (~mydata->to);
83 *flags |= OPT_CREATE_NETWORK;
85 DP("--network from %x (%s)",
86 mydata->from, ip_tostring_numeric(mydata->from));
87 DP("--network to %x (%s)",
88 mydata->to, ip_tostring_numeric(mydata->to));
90 break;
92 case '4':
93 mydata->flags |= IPSET_MACIP_MATCHUNSET;
95 *flags |= OPT_CREATE_MATCHUNSET;
97 DP("--matchunset");
99 break;
101 default:
102 return 0;
105 return 1;
108 /* Final check; exit if not ok. */
109 static void
110 macipmap_create_final(void *data, unsigned int flags)
112 struct ip_set_req_macipmap_create *mydata = data;
114 if (flags == 0)
115 exit_error(PARAMETER_PROBLEM,
116 "Need to specify --from and --to, or --network\n");
118 if (flags & OPT_CREATE_NETWORK) {
119 /* --network */
120 if ((flags & OPT_CREATE_FROM) || (flags & OPT_CREATE_TO))
121 exit_error(PARAMETER_PROBLEM,
122 "Can't specify --from or --to with --network\n");
123 } else {
124 /* --from --to */
125 if ((flags & OPT_CREATE_FROM) == 0
126 || (flags & OPT_CREATE_TO) == 0)
127 exit_error(PARAMETER_PROBLEM,
128 "Need to specify both --from and --to\n");
132 DP("from : %x to: %x diff: %d match unset: %d", mydata->from,
133 mydata->to, mydata->to - mydata->from,
134 flags & OPT_CREATE_MATCHUNSET);
136 if (mydata->from > mydata->to)
137 exit_error(PARAMETER_PROBLEM,
138 "From can't be lower than to.\n");
140 if (mydata->to - mydata->from > MAX_RANGE)
141 exit_error(PARAMETER_PROBLEM,
142 "Range too large. Max is %d IPs in range\n",
143 MAX_RANGE+1);
146 /* Create commandline options */
147 static const struct option create_opts[] = {
148 {.name = "from", .has_arg = required_argument, .val = '1'},
149 {.name = "to", .has_arg = required_argument, .val = '2'},
150 {.name = "network", .has_arg = required_argument, .val = '3'},
151 {.name = "matchunset", .has_arg = no_argument, .val = '4'},
152 {NULL},
155 static void
156 parse_mac(const char *mac, unsigned char *ethernet)
158 unsigned int i = 0;
160 if (strlen(mac) != ETH_ALEN * 3 - 1)
161 exit_error(PARAMETER_PROBLEM, "Bad mac address `%s'", mac);
163 for (i = 0; i < ETH_ALEN; i++) {
164 long number;
165 char *end;
167 number = strtol(mac + i * 3, &end, 16);
169 if (end == mac + i * 3 + 2 && number >= 0 && number <= 255)
170 ethernet[i] = number;
171 else
172 exit_error(PARAMETER_PROBLEM,
173 "Bad mac address `%s'", mac);
177 /* Add, del, test parser */
178 static ip_set_ip_t
179 macipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
181 struct ip_set_req_macipmap *mydata = data;
182 char *saved = ipset_strdup(arg);
183 char *ptr, *tmp = saved;
185 DP("macipmap: %p %p", arg, data);
187 ptr = strsep(&tmp, ",");
188 if (!tmp) {
189 tmp = saved;
190 ptr = strsep(&tmp, ":%");
191 if (tmp && ++warn_once == 1)
192 fprintf(stderr, "Warning: please use ',' separator token between ip,mac.\n"
193 "Next release won't support old separator tokens.\n");
195 parse_ip(ptr, &mydata->ip);
197 if (tmp)
198 parse_mac(tmp, mydata->ethernet);
199 else
200 memset(mydata->ethernet, 0, ETH_ALEN);
202 free(saved);
204 return 1;
208 * Print and save
211 static void
212 macipmap_initheader(struct set *set, const void *data)
214 const struct ip_set_req_macipmap_create *header = data;
215 struct ip_set_macipmap *map = set->settype->header;
217 memset(map, 0, sizeof(struct ip_set_macipmap));
218 map->first_ip = header->from;
219 map->last_ip = header->to;
220 map->flags = header->flags;
223 static void
224 macipmap_printheader(struct set *set, unsigned options)
226 struct ip_set_macipmap *mysetdata = set->settype->header;
228 printf(" from: %s", ip_tostring(mysetdata->first_ip, options));
229 printf(" to: %s", ip_tostring(mysetdata->last_ip, options));
231 if (mysetdata->flags & IPSET_MACIP_MATCHUNSET)
232 printf(" matchunset");
233 printf("\n");
236 static void
237 print_mac(unsigned char macaddress[ETH_ALEN])
239 unsigned int i;
241 printf("%02X", macaddress[0]);
242 for (i = 1; i < ETH_ALEN; i++)
243 printf(":%02X", macaddress[i]);
246 static inline void
247 __macipmap_printips_sorted(struct set *set, void *data,
248 u_int32_t len UNUSED, unsigned options)
250 struct ip_set_macipmap *mysetdata = set->settype->header;
251 struct ip_set_macip *table = data;
252 u_int32_t addr = mysetdata->first_ip;
254 while (addr <= mysetdata->last_ip) {
255 if (table[addr - mysetdata->first_ip].match) {
256 printf("%s,", ip_tostring(addr, options));
257 print_mac(table[addr - mysetdata->first_ip].
258 ethernet);
259 printf("\n");
261 addr++;
265 static void
266 macipmap_printips_sorted(struct set *set, void *data,
267 u_int32_t len, unsigned options,
268 char dont_align)
270 struct ip_set_req_macipmap *d;
271 size_t offset = 0;
273 if (dont_align)
274 return __macipmap_printips_sorted(set, data, len, options);
276 while (offset < len) {
277 d = data + offset;
278 printf("%s,", ip_tostring(d->ip, options));
279 print_mac(d->ethernet);
280 printf("\n");
281 offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
285 static void
286 macipmap_saveheader(struct set *set, unsigned options)
288 struct ip_set_macipmap *mysetdata = set->settype->header;
290 printf("-N %s %s --from %s",
291 set->name, set->settype->typename,
292 ip_tostring(mysetdata->first_ip, options));
293 printf(" --to %s", ip_tostring(mysetdata->last_ip, options));
295 if (mysetdata->flags & IPSET_MACIP_MATCHUNSET)
296 printf(" --matchunset");
297 printf("\n");
300 static inline void
301 __macipmap_saveips(struct set *set, void *data,
302 u_int32_t len UNUSED, unsigned options)
304 struct ip_set_macipmap *mysetdata = set->settype->header;
305 struct ip_set_macip *table = data;
306 u_int32_t addr = mysetdata->first_ip;
308 while (addr <= mysetdata->last_ip) {
309 if (table[addr - mysetdata->first_ip].match) {
310 printf("-A %s %s,",
311 set->name, ip_tostring(addr, options));
312 print_mac(table[addr - mysetdata->first_ip].
313 ethernet);
314 printf("\n");
316 addr++;
320 static void
321 macipmap_saveips(struct set *set, void *data,
322 u_int32_t len, unsigned options,
323 char dont_align)
325 struct ip_set_req_macipmap *d;
326 size_t offset = 0;
328 if (dont_align)
329 return __macipmap_saveips(set, data, len, options);
331 while (offset < len) {
332 d = data + offset;
333 printf("-A %s %s,", set->name, ip_tostring(d->ip, options));
334 print_mac(d->ethernet);
335 printf("\n");
336 offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
340 static void
341 macipmap_usage(void)
343 printf
344 ("-N set macipmap --from IP --to IP [--matchunset]\n"
345 "-N set macipmap --network IP/mask [--matchunset]\n"
346 "-A set IP[,MAC]\n"
347 "-D set IP[,MAC]\n"
348 "-T set IP[,MAC]\n");
351 static struct settype settype_macipmap = {
352 .typename = SETTYPE_NAME,
353 .protocol_version = IP_SET_PROTOCOL_VERSION,
355 /* Create */
356 .create_size = sizeof(struct ip_set_req_macipmap_create),
357 .create_init = macipmap_create_init,
358 .create_parse = macipmap_create_parse,
359 .create_final = macipmap_create_final,
360 .create_opts = create_opts,
362 /* Add/del/test */
363 .adt_size = sizeof(struct ip_set_req_macipmap),
364 .adt_parser = macipmap_adt_parser,
366 /* Printing */
367 .header_size = sizeof(struct ip_set_macipmap),
368 .initheader = macipmap_initheader,
369 .printheader = macipmap_printheader,
370 .printips = macipmap_printips_sorted,
371 .printips_sorted = macipmap_printips_sorted,
372 .saveheader = macipmap_saveheader,
373 .saveips = macipmap_saveips,
375 .usage = macipmap_usage,
378 CONSTRUCTOR(macipmap)
380 settype_register(&settype_macipmap);