blob: 5c4471a955af3b4fae6c0ab132b7a674fcd43dcd [file] [log] [blame]
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +00001/* Shared library add-on to iptables to add static NAT support.
2 Author: Svenning Soerensen <svenning@post5.tele.dk>
3*/
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +00004#include <stdio.h>
5#include <netdb.h>
6#include <string.h>
7#include <stdlib.h>
8#include <getopt.h>
Jan Engelhardt5d9678a2008-11-20 10:15:35 +01009#include <xtables.h>
Jan Engelhardt978e27e2009-02-21 04:42:32 +010010#include <net/netfilter/nf_nat.h>
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000011
12#define MODULENAME "NETMAP"
13
Jan Engelhardtef7d2e82011-05-08 21:12:46 +020014enum {
15 O_TO = 0,
16};
17
18static const struct xt_option_entry NETMAP_opts[] = {
19 {.name = "to", .id = O_TO, .type = XTTYPE_HOSTMASK,
20 .flags = XTOPT_MAND},
21 XTOPT_TABLEEND,
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000022};
23
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000024static void NETMAP_help(void)
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000025{
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020026 printf(MODULENAME" target options:\n"
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000027 " --%s address[/mask]\n"
28 " Network address to map to.\n\n",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020029 NETMAP_opts[0].name);
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000030}
31
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000032static int
Jan Engelhardt7ac40522011-01-07 12:34:04 +010033netmask2bits(uint32_t netmask)
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000034{
Jan Engelhardt7ac40522011-01-07 12:34:04 +010035 uint32_t bm;
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000036 int bits;
37
38 netmask = ntohl(netmask);
39 for (bits = 0, bm = 0x80000000; netmask & bm; netmask <<= 1)
40 bits++;
41 if (netmask)
42 return -1; /* holes in netmask */
43 return bits;
44}
45
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000046static void NETMAP_init(struct xt_entry_target *t)
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000047{
Jan Engelhardt978e27e2009-02-21 04:42:32 +010048 struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)t->data;
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000049
50 /* Actually, it's 0, but it's ignored at the moment. */
51 mr->rangesize = 1;
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000052}
53
Jan Engelhardtef7d2e82011-05-08 21:12:46 +020054static void NETMAP_parse(struct xt_option_call *cb)
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000055{
Jan Engelhardtef7d2e82011-05-08 21:12:46 +020056 struct nf_nat_multi_range *mr = cb->data;
57 struct nf_nat_range *range = &mr->range[0];
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000058
Jan Engelhardtef7d2e82011-05-08 21:12:46 +020059 xtables_option_parse(cb);
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000060 range->flags |= IP_NAT_RANGE_MAP_IPS;
Jan Engelhardtef7d2e82011-05-08 21:12:46 +020061 range->min_ip = cb->val.haddr.ip & cb->val.hmask.ip;
62 range->max_ip = range->min_ip | ~cb->val.hmask.ip;
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000063}
64
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000065static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
66 int numeric)
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000067{
Jan Engelhardt69f564e2009-05-26 13:14:06 +020068 const struct nf_nat_multi_range *mr = (const void *)target->data;
69 const struct nf_nat_range *r = &mr->range[0];
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000070 struct in_addr a;
71 int bits;
72
73 a.s_addr = r->min_ip;
Jan Engelhardte44ea7f2009-01-30 03:55:09 +010074 printf("%s", xtables_ipaddr_to_numeric(&a));
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000075 a.s_addr = ~(r->min_ip ^ r->max_ip);
76 bits = netmask2bits(a.s_addr);
77 if (bits < 0)
Jan Engelhardte44ea7f2009-01-30 03:55:09 +010078 printf("/%s", xtables_ipaddr_to_numeric(&a));
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000079 else
80 printf("/%d", bits);
81}
82
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000083static void NETMAP_save(const void *ip, const struct xt_entry_target *target)
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000084{
Jan Engelhardt73866352010-12-18 02:04:59 +010085 printf(" --%s ", NETMAP_opts[0].name);
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000086 NETMAP_print(ip, target, 0);
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +000087}
88
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020089static struct xtables_target netmap_tg_reg = {
Pablo Neira8caee8b2004-12-28 13:11:59 +000090 .name = MODULENAME,
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020091 .version = XTABLES_VERSION,
Jan Engelhardt03d99482008-11-18 12:27:54 +010092 .family = NFPROTO_IPV4,
Jan Engelhardt978e27e2009-02-21 04:42:32 +010093 .size = XT_ALIGN(sizeof(struct nf_nat_multi_range)),
94 .userspacesize = XT_ALIGN(sizeof(struct nf_nat_multi_range)),
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000095 .help = NETMAP_help,
96 .init = NETMAP_init,
Jan Engelhardtef7d2e82011-05-08 21:12:46 +020097 .x6_parse = NETMAP_parse,
Jan Engelhardt1d5b63d2007-10-04 16:29:00 +000098 .print = NETMAP_print,
99 .save = NETMAP_save,
Jan Engelhardtef7d2e82011-05-08 21:12:46 +0200100 .x6_options = NETMAP_opts,
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +0000101};
102
103void _init(void)
104{
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200105 xtables_register_target(&netmap_tg_reg);
Svenning Soerensenb2f9cb72001-05-03 01:15:09 +0000106}