1 /* Shared library add-on to iptables to add static NAT support.
2 Author: Svenning Soerensen <svenning@post5.tele.dk>
11 #include <net/netfilter/nf_nat.h>
13 #define MODULENAME "NETMAP"
15 static const struct option NETMAP_opts
[] = {
16 { "to", 1, NULL
, '1' },
20 static void NETMAP_help(void)
22 printf(MODULENAME
" target options:\n"
23 " --%s address[/mask]\n"
24 " Network address to map to.\n\n",
29 bits2netmask(int bits
)
31 u_int32_t netmask
, bm
;
33 if (bits
>= 32 || bits
< 0)
35 for (netmask
= 0, bm
= 0x80000000; bits
; bits
--, bm
>>= 1)
37 return htonl(netmask
);
41 netmask2bits(u_int32_t netmask
)
46 netmask
= ntohl(netmask
);
47 for (bits
= 0, bm
= 0x80000000; netmask
& bm
; netmask
<<= 1)
50 return -1; /* holes in netmask */
54 static void NETMAP_init(struct xt_entry_target
*t
)
56 struct nf_nat_multi_range
*mr
= (struct nf_nat_multi_range
*)t
->data
;
58 /* Actually, it's 0, but it's ignored at the moment. */
63 /* Parses network address */
65 parse_to(char *arg
, struct nf_nat_range
*range
)
68 const struct in_addr
*ip
;
72 range
->flags
|= IP_NAT_RANGE_MAP_IPS
;
73 slash
= strchr(arg
, '/');
77 ip
= xtables_numeric_to_ipaddr(arg
);
79 xtables_error(PARAMETER_PROBLEM
, "Bad IP address \"%s\"\n",
81 range
->min_ip
= ip
->s_addr
;
83 if (strchr(slash
+1, '.')) {
84 ip
= xtables_numeric_to_ipmask(slash
+1);
86 xtables_error(PARAMETER_PROBLEM
, "Bad netmask \"%s\"\n",
91 if (!xtables_strtoui(slash
+1, NULL
, &bits
, 0, 32))
92 xtables_error(PARAMETER_PROBLEM
, "Bad netmask \"%s\"\n",
94 netmask
= bits2netmask(bits
);
96 /* Don't allow /0 (/1 is probably insane, too) */
98 xtables_error(PARAMETER_PROBLEM
, "Netmask needed\n");
103 if (range
->min_ip
& ~netmask
) {
106 xtables_error(PARAMETER_PROBLEM
, "Bad network address \"%s\"\n",
109 range
->max_ip
= range
->min_ip
| ~netmask
;
112 static int NETMAP_parse(int c
, char **argv
, int invert
, unsigned int *flags
,
113 const void *entry
, struct xt_entry_target
**target
)
115 struct nf_nat_multi_range
*mr
116 = (struct nf_nat_multi_range
*)(*target
)->data
;
120 if (xtables_check_inverse(optarg
, &invert
, NULL
, 0))
121 xtables_error(PARAMETER_PROBLEM
,
122 "Unexpected `!' after --%s", NETMAP_opts
[0].name
);
124 parse_to(optarg
, &mr
->range
[0]);
133 static void NETMAP_check(unsigned int flags
)
136 xtables_error(PARAMETER_PROBLEM
,
137 MODULENAME
" needs --%s", NETMAP_opts
[0].name
);
140 static void NETMAP_print(const void *ip
, const struct xt_entry_target
*target
,
143 const struct nf_nat_multi_range
*mr
= (const void *)target
->data
;
144 const struct nf_nat_range
*r
= &mr
->range
[0];
148 a
.s_addr
= r
->min_ip
;
149 printf("%s", xtables_ipaddr_to_numeric(&a
));
150 a
.s_addr
= ~(r
->min_ip
^ r
->max_ip
);
151 bits
= netmask2bits(a
.s_addr
);
153 printf("/%s", xtables_ipaddr_to_numeric(&a
));
158 static void NETMAP_save(const void *ip
, const struct xt_entry_target
*target
)
160 printf("--%s ", NETMAP_opts
[0].name
);
161 NETMAP_print(ip
, target
, 0);
164 static struct xtables_target netmap_tg_reg
= {
166 .version
= XTABLES_VERSION
,
167 .family
= NFPROTO_IPV4
,
168 .size
= XT_ALIGN(sizeof(struct nf_nat_multi_range
)),
169 .userspacesize
= XT_ALIGN(sizeof(struct nf_nat_multi_range
)),
172 .parse
= NETMAP_parse
,
173 .final_check
= NETMAP_check
,
174 .print
= NETMAP_print
,
176 .extra_opts
= NETMAP_opts
,
181 xtables_register_target(&netmap_tg_reg
);