1 /* 2 * Copyright (c) 2011 Patrick McHardy <kaber (at) 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 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 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 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 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 90 void _init(void) 91 { 92 xtables_register_target(&netmap_tg_reg); 93 } 94