1/* Shared library add-on to iptables to add static NAT support. 2 Author: Svenning Soerensen <svenning@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 14enum { 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, 22}; 23 24static 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 32static int 33netmask2bits(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 46static 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 54static 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 65static 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 83static 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 89static 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 103void _init(void) 104{ 105 xtables_register_target(&netmap_tg_reg); 106} 107