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
19 #include <stdio.h> /* *printf */
20 #include <string.h> /* mem* */
24 #include <linux/netfilter_ipv4/ip_set_portmap.h>
28 #define OPT_CREATE_FROM 0x01U
29 #define OPT_CREATE_TO 0x02U
31 #define OPT_ADDDEL_PORT 0x01U
33 /* Initialize the create. */
35 portmap_create_init(void *data UNUSED
)
41 /* Function which parses command options; returns true if it ate an option */
43 portmap_create_parse(int c
, char *argv
[] UNUSED
, void *data
, unsigned *flags
)
45 struct ip_set_req_portmap_create
*mydata
= data
;
51 parse_port(optarg
, &mydata
->from
);
53 *flags
|= OPT_CREATE_FROM
;
55 DP("--from %x (%s)", mydata
->from
,
56 port_tostring(mydata
->from
, 0));
61 parse_port(optarg
, &mydata
->to
);
63 *flags
|= OPT_CREATE_TO
;
65 DP("--to %x (%s)", mydata
->to
,
66 port_tostring(mydata
->to
, 0));
77 /* Final check; exit if not ok. */
79 portmap_create_final(void *data
, unsigned int flags
)
81 struct ip_set_req_portmap_create
*mydata
= data
;
84 exit_error(PARAMETER_PROBLEM
,
85 "Need to specify --from and --to\n");
88 if ((flags
& OPT_CREATE_FROM
) == 0
89 || (flags
& OPT_CREATE_TO
) == 0)
90 exit_error(PARAMETER_PROBLEM
,
91 "Need to specify both --from and --to\n");
94 DP("from : %x to: %x diff: %d", mydata
->from
, mydata
->to
,
95 mydata
->to
- mydata
->from
);
97 if (mydata
->from
> mydata
->to
)
98 exit_error(PARAMETER_PROBLEM
,
99 "From can't be lower than to.\n");
101 if (mydata
->to
- mydata
->from
> MAX_RANGE
)
102 exit_error(PARAMETER_PROBLEM
,
103 "Range too large. Max is %d ports in range\n",
107 /* Create commandline options */
108 static const struct option create_opts
[] = {
109 {.name
= "from", .has_arg
= required_argument
, .val
= '1'},
110 {.name
= "to", .has_arg
= required_argument
, .val
= '2'},
114 /* Add, del, test parser */
116 portmap_adt_parser(int cmd UNUSED
, const char *arg
, void *data
)
118 struct ip_set_req_portmap
*mydata
= data
;
120 parse_port(arg
, &mydata
->ip
);
121 DP("%s", port_tostring(mydata
->ip
, 0));
131 portmap_initheader(struct set
*set
, const void *data
)
133 const struct ip_set_req_portmap_create
*header
= data
;
134 struct ip_set_portmap
*map
= set
->settype
->header
;
136 memset(map
, 0, sizeof(struct ip_set_portmap
));
137 map
->first_ip
= header
->from
;
138 map
->last_ip
= header
->to
;
142 portmap_printheader(struct set
*set
, unsigned options
)
144 struct ip_set_portmap
*mysetdata
= set
->settype
->header
;
146 printf(" from: %s", port_tostring(mysetdata
->first_ip
, options
));
147 printf(" to: %s\n", port_tostring(mysetdata
->last_ip
, options
));
151 __portmap_printips_sorted(struct set
*set
, void *data
,
152 u_int32_t len UNUSED
, unsigned options
)
154 struct ip_set_portmap
*mysetdata
= set
->settype
->header
;
155 ip_set_ip_t addr
= mysetdata
->first_ip
;
157 DP("%u -- %u", mysetdata
->first_ip
, mysetdata
->last_ip
);
158 while (addr
<= mysetdata
->last_ip
) {
159 if (test_bit(addr
- mysetdata
->first_ip
, data
))
160 printf("%s\n", port_tostring(addr
, options
));
166 portmap_printips_sorted(struct set
*set
, void *data
,
167 u_int32_t len
, unsigned options
,
174 return __portmap_printips_sorted(set
, data
, len
, options
);
176 while (offset
< len
) {
178 printf("%s\n", port_tostring(*ip
, options
));
179 offset
+= IPSET_ALIGN(sizeof(ip_set_ip_t
));
184 portmap_saveheader(struct set
*set
, unsigned options
)
186 struct ip_set_portmap
*mysetdata
= set
->settype
->header
;
188 printf("-N %s %s --from %s",
190 set
->settype
->typename
,
191 port_tostring(mysetdata
->first_ip
, options
));
193 port_tostring(mysetdata
->last_ip
, options
));
197 __portmap_saveips(struct set
*set
, void *data
,
198 u_int32_t len UNUSED
, unsigned options
)
200 struct ip_set_portmap
*mysetdata
= set
->settype
->header
;
201 ip_set_ip_t addr
= mysetdata
->first_ip
;
203 while (addr
<= mysetdata
->last_ip
) {
204 DP("addr: %lu, last_ip %lu", (long unsigned)addr
, (long unsigned)mysetdata
->last_ip
);
205 if (test_bit(addr
- mysetdata
->first_ip
, data
))
208 port_tostring(addr
, options
));
214 portmap_saveips(struct set
*set
, void *data
,
215 u_int32_t len
, unsigned options
,
222 return __portmap_saveips(set
, data
, len
, options
);
224 while (offset
< len
) {
226 printf("-A %s %s\n", set
->name
, port_tostring(*ip
, options
));
227 offset
+= IPSET_ALIGN(sizeof(ip_set_ip_t
));
235 ("-N set portmap --from PORT --to PORT\n"
241 static struct settype settype_portmap
= {
242 .typename
= SETTYPE_NAME
,
243 .protocol_version
= IP_SET_PROTOCOL_VERSION
,
246 .create_size
= sizeof(struct ip_set_req_portmap_create
),
247 .create_init
= portmap_create_init
,
248 .create_parse
= portmap_create_parse
,
249 .create_final
= portmap_create_final
,
250 .create_opts
= create_opts
,
253 .adt_size
= sizeof(struct ip_set_req_portmap
),
254 .adt_parser
= portmap_adt_parser
,
257 .header_size
= sizeof(struct ip_set_portmap
),
258 .initheader
= portmap_initheader
,
259 .printheader
= portmap_printheader
,
260 .printips
= portmap_printips_sorted
,
261 .printips_sorted
= portmap_printips_sorted
,
262 .saveheader
= portmap_saveheader
,
263 .saveips
= portmap_saveips
,
265 .usage
= portmap_usage
,
270 settype_register(&settype_portmap
);