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.
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 */
28 #include <linux/netfilter_ipv4/ip_set_macipmap.h>
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. */
42 macipmap_create_init(void *data UNUSED
)
48 /* Function which parses command options; returns true if it ate an option */
50 macipmap_create_parse(int c
, char *argv
[] UNUSED
, void *data
, unsigned *flags
)
52 struct ip_set_req_macipmap_create
*mydata
= data
;
58 parse_ip(optarg
, &mydata
->from
);
60 *flags
|= OPT_CREATE_FROM
;
62 DP("--from %x (%s)", mydata
->from
,
63 ip_tostring_numeric(mydata
->from
));
68 parse_ip(optarg
, &mydata
->to
);
70 *flags
|= OPT_CREATE_TO
;
72 DP("--to %x (%s)", mydata
->to
,
73 ip_tostring_numeric(mydata
->to
));
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
));
93 mydata
->flags
|= IPSET_MACIP_MATCHUNSET
;
95 *flags
|= OPT_CREATE_MATCHUNSET
;
108 /* Final check; exit if not ok. */
110 macipmap_create_final(void *data
, unsigned int flags
)
112 struct ip_set_req_macipmap_create
*mydata
= data
;
115 exit_error(PARAMETER_PROBLEM
,
116 "Need to specify --from and --to, or --network\n");
118 if (flags
& OPT_CREATE_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");
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",
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'},
156 parse_mac(const char *mac
, unsigned char *ethernet
)
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
++) {
167 number
= strtol(mac
+ i
* 3, &end
, 16);
169 if (end
== mac
+ i
* 3 + 2 && number
>= 0 && number
<= 255)
170 ethernet
[i
] = number
;
172 exit_error(PARAMETER_PROBLEM
,
173 "Bad mac address `%s'", mac
);
177 /* Add, del, test parser */
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
, ",");
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
);
198 parse_mac(tmp
, mydata
->ethernet
);
200 memset(mydata
->ethernet
, 0, ETH_ALEN
);
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
;
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");
237 print_mac(unsigned char macaddress
[ETH_ALEN
])
241 printf("%02X", macaddress
[0]);
242 for (i
= 1; i
< ETH_ALEN
; i
++)
243 printf(":%02X", macaddress
[i
]);
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
].
266 macipmap_printips_sorted(struct set
*set
, void *data
,
267 u_int32_t len
, unsigned options
,
270 struct ip_set_req_macipmap
*d
;
274 return __macipmap_printips_sorted(set
, data
, len
, options
);
276 while (offset
< len
) {
278 printf("%s,", ip_tostring(d
->ip
, options
));
279 print_mac(d
->ethernet
);
281 offset
+= IPSET_ALIGN(sizeof(struct ip_set_req_macipmap
));
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");
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
) {
311 set
->name
, ip_tostring(addr
, options
));
312 print_mac(table
[addr
- mysetdata
->first_ip
].
321 macipmap_saveips(struct set
*set
, void *data
,
322 u_int32_t len
, unsigned options
,
325 struct ip_set_req_macipmap
*d
;
329 return __macipmap_saveips(set
, data
, len
, options
);
331 while (offset
< len
) {
333 printf("-A %s %s,", set
->name
, ip_tostring(d
->ip
, options
));
334 print_mac(d
->ethernet
);
336 offset
+= IPSET_ALIGN(sizeof(struct ip_set_req_macipmap
));
344 ("-N set macipmap --from IP --to IP [--matchunset]\n"
345 "-N set macipmap --network IP/mask [--matchunset]\n"
348 "-T set IP[,MAC]\n");
351 static struct settype settype_macipmap
= {
352 .typename
= SETTYPE_NAME
,
353 .protocol_version
= IP_SET_PROTOCOL_VERSION
,
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
,
363 .adt_size
= sizeof(struct ip_set_req_macipmap
),
364 .adt_parser
= macipmap_adt_parser
,
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
);