1 /*
2 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
3 *
4 * Based on Svenning Soerensen's IPv4 NETMAP target. Development of IPv6 NAT
5 * funded by Astaro.
6 */
7
8 #include <stdio.h>
9 #include <netdb.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <getopt.h>
13 #include <xtables.h>
14 #include <libiptc/libip6tc.h>
15 #include <linux/netfilter/nf_nat.h>
16
17 #define MODULENAME "NETMAP"
18
19 enum {
20 O_TO = 0,
21 };
22
23 static const struct xt_option_entry NETMAP_opts[] = {
24 {.name = "to", .id = O_TO, .type = XTTYPE_HOSTMASK,
25 .flags = XTOPT_MAND},
26 XTOPT_TABLEEND,
27 };
28
NETMAP_help(void)29 static void NETMAP_help(void)
30 {
31 printf(MODULENAME" target options:\n"
32 " --%s address[/mask]\n"
33 " Network address to map to.\n\n",
34 NETMAP_opts[0].name);
35 }
36
NETMAP_parse(struct xt_option_call * cb)37 static void NETMAP_parse(struct xt_option_call *cb)
38 {
39 struct nf_nat_range *range = cb->data;
40 unsigned int i;
41
42 xtables_option_parse(cb);
43 range->flags |= NF_NAT_RANGE_MAP_IPS;
44 for (i = 0; i < 4; i++) {
45 range->min_addr.ip6[i] = cb->val.haddr.ip6[i] &
46 cb->val.hmask.ip6[i];
47 range->max_addr.ip6[i] = range->min_addr.ip6[i] |
48 ~cb->val.hmask.ip6[i];
49 }
50 }
51
NETMAP_print(const void * ip,const struct xt_entry_target * target,int numeric)52 static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
53 int numeric)
54 {
55 const struct nf_nat_range *r = (const void *)target->data;
56 struct in6_addr a;
57 unsigned int i;
58 int bits;
59
60 a = r->min_addr.in6;
61 printf("%s", xtables_ip6addr_to_numeric(&a));
62 for (i = 0; i < 4; i++)
63 a.s6_addr32[i] = ~(r->min_addr.ip6[i] ^ r->max_addr.ip6[i]);
64 bits = xtables_ip6mask_to_cidr(&a);
65 if (bits < 0)
66 printf("/%s", xtables_ip6addr_to_numeric(&a));
67 else
68 printf("/%d", bits);
69 }
70
NETMAP_save(const void * ip,const struct xt_entry_target * target)71 static void NETMAP_save(const void *ip, const struct xt_entry_target *target)
72 {
73 printf(" --%s ", NETMAP_opts[0].name);
74 NETMAP_print(ip, target, 0);
75 }
76
77 static struct xtables_target netmap_tg_reg = {
78 .name = MODULENAME,
79 .version = XTABLES_VERSION,
80 .family = NFPROTO_IPV6,
81 .size = XT_ALIGN(sizeof(struct nf_nat_range)),
82 .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
83 .help = NETMAP_help,
84 .x6_parse = NETMAP_parse,
85 .print = NETMAP_print,
86 .save = NETMAP_save,
87 .x6_options = NETMAP_opts,
88 };
89
_init(void)90 void _init(void)
91 {
92 xtables_register_target(&netmap_tg_reg);
93 }
94