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 19enum { 20 O_TO = 0, 21}; 22 23static 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 29static 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 37static 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 52static 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 71static void NETMAP_print(const void *ip, const struct xt_entry_target *target, 72 int numeric) 73{ 74 printf(" to:"); 75 __NETMAP_print(ip, target, numeric); 76} 77 78static void NETMAP_save(const void *ip, const struct xt_entry_target *target) 79{ 80 printf(" --%s ", NETMAP_opts[0].name); 81 __NETMAP_print(ip, target, 0); 82} 83 84static struct xtables_target netmap_tg_reg = { 85 .name = MODULENAME, 86 .version = XTABLES_VERSION, 87 .family = NFPROTO_IPV6, 88 .size = XT_ALIGN(sizeof(struct nf_nat_range)), 89 .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)), 90 .help = NETMAP_help, 91 .x6_parse = NETMAP_parse, 92 .print = NETMAP_print, 93 .save = NETMAP_save, 94 .x6_options = NETMAP_opts, 95}; 96 97void _init(void) 98{ 99 xtables_register_target(&netmap_tg_reg); 100} 101