123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- /* Shared library add-on to iptables to add static NAT support.
- Author: Svenning Soerensen <svenning@post5.tele.dk>
- */
- #include <stdio.h>
- #include <netdb.h>
- #include <string.h>
- #include <stdlib.h>
- #include <getopt.h>
- #include <xtables.h>
- #include <linux/netfilter/nf_nat.h>
- #define MODULENAME "NETMAP"
- enum {
- O_TO = 0,
- };
- static const struct xt_option_entry NETMAP_opts[] = {
- {.name = "to", .id = O_TO, .type = XTTYPE_HOSTMASK,
- .flags = XTOPT_MAND},
- XTOPT_TABLEEND,
- };
- static void NETMAP_help(void)
- {
- printf(MODULENAME" target options:\n"
- " --%s address[/mask]\n"
- " Network address to map to.\n\n",
- NETMAP_opts[0].name);
- }
- static int
- netmask2bits(uint32_t netmask)
- {
- uint32_t bm;
- int bits;
- netmask = ntohl(netmask);
- for (bits = 0, bm = 0x80000000; netmask & bm; netmask <<= 1)
- bits++;
- if (netmask)
- return -1; /* holes in netmask */
- return bits;
- }
- static void NETMAP_init(struct xt_entry_target *t)
- {
- struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data;
- /* Actually, it's 0, but it's ignored at the moment. */
- mr->rangesize = 1;
- }
- static void NETMAP_parse(struct xt_option_call *cb)
- {
- struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
- struct nf_nat_ipv4_range *range = &mr->range[0];
- xtables_option_parse(cb);
- range->flags |= NF_NAT_RANGE_MAP_IPS;
- range->min_ip = cb->val.haddr.ip & cb->val.hmask.ip;
- range->max_ip = range->min_ip | ~cb->val.hmask.ip;
- }
- static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
- {
- const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
- const struct nf_nat_ipv4_range *r = &mr->range[0];
- struct in_addr a;
- int bits;
- a.s_addr = r->min_ip;
- printf("%s", xtables_ipaddr_to_numeric(&a));
- a.s_addr = ~(r->min_ip ^ r->max_ip);
- bits = netmask2bits(a.s_addr);
- if (bits < 0)
- printf("/%s", xtables_ipaddr_to_numeric(&a));
- else
- printf("/%d", bits);
- }
- static void NETMAP_save(const void *ip, const struct xt_entry_target *target)
- {
- printf(" --%s ", NETMAP_opts[0].name);
- NETMAP_print(ip, target, 0);
- }
- static struct xtables_target netmap_tg_reg = {
- .name = MODULENAME,
- .version = XTABLES_VERSION,
- .family = NFPROTO_IPV4,
- .size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
- .userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
- .help = NETMAP_help,
- .init = NETMAP_init,
- .x6_parse = NETMAP_parse,
- .print = NETMAP_print,
- .save = NETMAP_save,
- .x6_options = NETMAP_opts,
- };
- void _init(void)
- {
- xtables_register_target(&netmap_tg_reg);
- }
|