1 /* Shared library add-on to iptables to add simple non load-balancing SNAT support. */
8 #include <net/netfilter/nf_nat.h>
9 /* For 64bit kernel / 32bit userspace */
10 #include <linux/netfilter_ipv4/ipt_SAME.h>
12 static void SAME_help(void)
15 "SAME target options:\n"
16 " --to <ipaddr>-<ipaddr>\n"
17 " Addresses to map source to.\n"
18 " May be specified more than\n"
19 " once for multiple ranges.\n"
21 " Don't use destination-ip in\n"
24 " Randomize source port\n");
27 static const struct option SAME_opts
[] = {
28 { "to", 1, NULL
, '1' },
29 { "nodst", 0, NULL
, '2'},
30 { "random", 0, NULL
, '3' },
34 static void SAME_init(struct xt_entry_target
*t
)
36 struct ipt_same_info
*mr
= (struct ipt_same_info
*)t
->data
;
38 /* Set default to 0 */
45 /* Parses range of IPs */
47 parse_to(char *arg
, struct nf_nat_range
*range
)
50 const struct in_addr
*ip
;
52 range
->flags
|= IP_NAT_RANGE_MAP_IPS
;
53 dash
= strchr(arg
, '-');
58 ip
= xtables_numeric_to_ipaddr(arg
);
60 xtables_error(PARAMETER_PROBLEM
, "Bad IP address \"%s\"\n",
62 range
->min_ip
= ip
->s_addr
;
65 ip
= xtables_numeric_to_ipaddr(dash
+1);
67 xtables_error(PARAMETER_PROBLEM
, "Bad IP address \"%s\"\n",
70 range
->max_ip
= ip
->s_addr
;
72 if (range
->min_ip
> range
->max_ip
)
73 xtables_error(PARAMETER_PROBLEM
, "Bad IP range \"%s-%s\"\n",
77 #define IPT_SAME_OPT_TO 0x01
78 #define IPT_SAME_OPT_NODST 0x02
79 #define IPT_SAME_OPT_RANDOM 0x04
81 static int SAME_parse(int c
, char **argv
, int invert
, unsigned int *flags
,
82 const void *entry
, struct xt_entry_target
**target
)
84 struct ipt_same_info
*mr
85 = (struct ipt_same_info
*)(*target
)->data
;
90 if (mr
->rangesize
== IPT_SAME_MAX_RANGE
)
91 xtables_error(PARAMETER_PROBLEM
,
92 "Too many ranges specified, maximum "
95 if (xtables_check_inverse(optarg
, &invert
, NULL
, 0))
96 xtables_error(PARAMETER_PROBLEM
,
97 "Unexpected `!' after --to");
99 parse_to(optarg
, &mr
->range
[mr
->rangesize
]);
100 /* WTF do we need this for? */
101 if (*flags
& IPT_SAME_OPT_RANDOM
)
102 mr
->range
[mr
->rangesize
].flags
103 |= IP_NAT_RANGE_PROTO_RANDOM
;
105 *flags
|= IPT_SAME_OPT_TO
;
109 if (*flags
& IPT_SAME_OPT_NODST
)
110 xtables_error(PARAMETER_PROBLEM
,
111 "Can't specify --nodst twice");
113 mr
->info
|= IPT_SAME_NODST
;
114 *flags
|= IPT_SAME_OPT_NODST
;
118 *flags
|= IPT_SAME_OPT_RANDOM
;
119 for (count
=0; count
< mr
->rangesize
; count
++)
120 mr
->range
[count
].flags
|= IP_NAT_RANGE_PROTO_RANDOM
;
130 static void SAME_check(unsigned int flags
)
132 if (!(flags
& IPT_SAME_OPT_TO
))
133 xtables_error(PARAMETER_PROBLEM
,
137 static void SAME_print(const void *ip
, const struct xt_entry_target
*target
,
141 const struct ipt_same_info
*mr
= (const void *)target
->data
;
142 int random_selection
= 0;
146 for (count
= 0; count
< mr
->rangesize
; count
++) {
147 const struct nf_nat_range
*r
= &mr
->range
[count
];
150 a
.s_addr
= r
->min_ip
;
152 printf("%s", xtables_ipaddr_to_numeric(&a
));
153 a
.s_addr
= r
->max_ip
;
155 if (r
->min_ip
== r
->max_ip
)
158 printf("-%s ", xtables_ipaddr_to_numeric(&a
));
159 if (r
->flags
& IP_NAT_RANGE_PROTO_RANDOM
)
160 random_selection
= 1;
163 if (mr
->info
& IPT_SAME_NODST
)
166 if (random_selection
)
170 static void SAME_save(const void *ip
, const struct xt_entry_target
*target
)
173 const struct ipt_same_info
*mr
= (const void *)target
->data
;
174 int random_selection
= 0;
176 for (count
= 0; count
< mr
->rangesize
; count
++) {
177 const struct nf_nat_range
*r
= &mr
->range
[count
];
180 a
.s_addr
= r
->min_ip
;
181 printf("--to %s", xtables_ipaddr_to_numeric(&a
));
182 a
.s_addr
= r
->max_ip
;
184 if (r
->min_ip
== r
->max_ip
)
187 printf("-%s ", xtables_ipaddr_to_numeric(&a
));
188 if (r
->flags
& IP_NAT_RANGE_PROTO_RANDOM
)
189 random_selection
= 1;
192 if (mr
->info
& IPT_SAME_NODST
)
195 if (random_selection
)
199 static struct xtables_target same_tg_reg
= {
201 .version
= XTABLES_VERSION
,
202 .family
= NFPROTO_IPV4
,
203 .size
= XT_ALIGN(sizeof(struct ipt_same_info
)),
204 .userspacesize
= XT_ALIGN(sizeof(struct ipt_same_info
)),
208 .final_check
= SAME_check
,
211 .extra_opts
= SAME_opts
,
216 xtables_register_target(&same_tg_reg
);