manpages: do not include v4-only modules in ip6tables manpage
[jleu-iptables.git] / extensions / libipt_SAME.c
blob5cb0d3f4d095126f774b84353678fe27435d648c
1 /* Shared library add-on to iptables to add simple non load-balancing SNAT support. */
2 #include <stdio.h>
3 #include <netdb.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <getopt.h>
7 #include <xtables.h>
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)
14 printf(
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"
20 " --nodst\n"
21 " Don't use destination-ip in\n"
22 " source selection\n"
23 " --random\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' },
31 { .name = NULL }
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 */
39 mr->rangesize = 0;
40 mr->info = 0;
41 mr->ipnum = 0;
45 /* Parses range of IPs */
46 static void
47 parse_to(char *arg, struct nf_nat_range *range)
49 char *dash;
50 const struct in_addr *ip;
52 range->flags |= IP_NAT_RANGE_MAP_IPS;
53 dash = strchr(arg, '-');
55 if (dash)
56 *dash = '\0';
58 ip = xtables_numeric_to_ipaddr(arg);
59 if (!ip)
60 xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
61 arg);
62 range->min_ip = ip->s_addr;
64 if (dash) {
65 ip = xtables_numeric_to_ipaddr(dash+1);
66 if (!ip)
67 xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
68 dash+1);
70 range->max_ip = ip->s_addr;
71 if (dash)
72 if (range->min_ip > range->max_ip)
73 xtables_error(PARAMETER_PROBLEM, "Bad IP range \"%s-%s\"\n",
74 arg, dash+1);
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;
86 unsigned int count;
88 switch (c) {
89 case '1':
90 if (mr->rangesize == IPT_SAME_MAX_RANGE)
91 xtables_error(PARAMETER_PROBLEM,
92 "Too many ranges specified, maximum "
93 "is %i ranges.\n",
94 IPT_SAME_MAX_RANGE);
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;
104 mr->rangesize++;
105 *flags |= IPT_SAME_OPT_TO;
106 break;
108 case '2':
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;
115 break;
117 case '3':
118 *flags |= IPT_SAME_OPT_RANDOM;
119 for (count=0; count < mr->rangesize; count++)
120 mr->range[count].flags |= IP_NAT_RANGE_PROTO_RANDOM;
121 break;
123 default:
124 return 0;
127 return 1;
130 static void SAME_check(unsigned int flags)
132 if (!(flags & IPT_SAME_OPT_TO))
133 xtables_error(PARAMETER_PROBLEM,
134 "SAME needs --to");
137 static void SAME_print(const void *ip, const struct xt_entry_target *target,
138 int numeric)
140 unsigned int count;
141 const struct ipt_same_info *mr = (const void *)target->data;
142 int random_selection = 0;
144 printf("same:");
146 for (count = 0; count < mr->rangesize; count++) {
147 const struct nf_nat_range *r = &mr->range[count];
148 struct in_addr a;
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)
156 printf(" ");
157 else
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)
164 printf("nodst ");
166 if (random_selection)
167 printf("random ");
170 static void SAME_save(const void *ip, const struct xt_entry_target *target)
172 unsigned int count;
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];
178 struct in_addr a;
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)
185 printf(" ");
186 else
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)
193 printf("--nodst ");
195 if (random_selection)
196 printf("--random ");
199 static struct xtables_target same_tg_reg = {
200 .name = "SAME",
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)),
205 .help = SAME_help,
206 .init = SAME_init,
207 .parse = SAME_parse,
208 .final_check = SAME_check,
209 .print = SAME_print,
210 .save = SAME_save,
211 .extra_opts = SAME_opts,
214 void _init(void)
216 xtables_register_target(&same_tg_reg);