1 /* Shared library add-on to iptables to add static NAT support. 2 Author: Svenning Soerensen <svenning (at) post5.tele.dk> 3 */ 4 #include <stdio.h> 5 #include <netdb.h> 6 #include <string.h> 7 #include <stdlib.h> 8 #include <getopt.h> 9 #include <xtables.h> 10 #include <net/netfilter/nf_nat.h> 11 12 #define MODULENAME "NETMAP" 13 14 enum { 15 O_TO = 0, 16 }; 17 18 static const struct xt_option_entry NETMAP_opts[] = { 19 {.name = "to", .id = O_TO, .type = XTTYPE_HOSTMASK, 20 .flags = XTOPT_MAND}, 21 XTOPT_TABLEEND, 22 }; 23 24 static void NETMAP_help(void) 25 { 26 printf(MODULENAME" target options:\n" 27 " --%s address[/mask]\n" 28 " Network address to map to.\n\n", 29 NETMAP_opts[0].name); 30 } 31 32 static int 33 netmask2bits(uint32_t netmask) 34 { 35 uint32_t bm; 36 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 46 static void NETMAP_init(struct xt_entry_target *t) 47 { 48 struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)t->data; 49 50 /* Actually, it's 0, but it's ignored at the moment. */ 51 mr->rangesize = 1; 52 } 53 54 static void NETMAP_parse(struct xt_option_call *cb) 55 { 56 struct nf_nat_multi_range *mr = cb->data; 57 struct nf_nat_range *range = &mr->range[0]; 58 59 xtables_option_parse(cb); 60 range->flags |= IP_NAT_RANGE_MAP_IPS; 61 range->min_ip = cb->val.haddr.ip & cb->val.hmask.ip; 62 range->max_ip = range->min_ip | ~cb->val.hmask.ip; 63 } 64 65 static void NETMAP_print(const void *ip, const struct xt_entry_target *target, 66 int numeric) 67 { 68 const struct nf_nat_multi_range *mr = (const void *)target->data; 69 const struct nf_nat_range *r = &mr->range[0]; 70 struct in_addr a; 71 int bits; 72 73 a.s_addr = r->min_ip; 74 printf("%s", xtables_ipaddr_to_numeric(&a)); 75 a.s_addr = ~(r->min_ip ^ r->max_ip); 76 bits = netmask2bits(a.s_addr); 77 if (bits < 0) 78 printf("/%s", xtables_ipaddr_to_numeric(&a)); 79 else 80 printf("/%d", bits); 81 } 82 83 static void NETMAP_save(const void *ip, const struct xt_entry_target *target) 84 { 85 printf(" --%s ", NETMAP_opts[0].name); 86 NETMAP_print(ip, target, 0); 87 } 88 89 static struct xtables_target netmap_tg_reg = { 90 .name = MODULENAME, 91 .version = XTABLES_VERSION, 92 .family = NFPROTO_IPV4, 93 .size = XT_ALIGN(sizeof(struct nf_nat_multi_range)), 94 .userspacesize = XT_ALIGN(sizeof(struct nf_nat_multi_range)), 95 .help = NETMAP_help, 96 .init = NETMAP_init, 97 .x6_parse = NETMAP_parse, 98 .print = NETMAP_print, 99 .save = NETMAP_save, 100 .x6_options = NETMAP_opts, 101 }; 102 103 void _init(void) 104 { 105 xtables_register_target(&netmap_tg_reg); 106 } 107