libipt_NETMAP.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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 <linux/netfilter/nf_nat.h>
  11. #define MODULENAME "NETMAP"
  12. enum {
  13. O_TO = 0,
  14. };
  15. static const struct xt_option_entry NETMAP_opts[] = {
  16. {.name = "to", .id = O_TO, .type = XTTYPE_HOSTMASK,
  17. .flags = XTOPT_MAND},
  18. XTOPT_TABLEEND,
  19. };
  20. static void NETMAP_help(void)
  21. {
  22. printf(MODULENAME" target options:\n"
  23. " --%s address[/mask]\n"
  24. " Network address to map to.\n\n",
  25. NETMAP_opts[0].name);
  26. }
  27. static int
  28. netmask2bits(uint32_t netmask)
  29. {
  30. uint32_t bm;
  31. int bits;
  32. netmask = ntohl(netmask);
  33. for (bits = 0, bm = 0x80000000; netmask & bm; netmask <<= 1)
  34. bits++;
  35. if (netmask)
  36. return -1; /* holes in netmask */
  37. return bits;
  38. }
  39. static void NETMAP_init(struct xt_entry_target *t)
  40. {
  41. struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data;
  42. /* Actually, it's 0, but it's ignored at the moment. */
  43. mr->rangesize = 1;
  44. }
  45. static void NETMAP_parse(struct xt_option_call *cb)
  46. {
  47. struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
  48. struct nf_nat_ipv4_range *range = &mr->range[0];
  49. xtables_option_parse(cb);
  50. range->flags |= NF_NAT_RANGE_MAP_IPS;
  51. range->min_ip = cb->val.haddr.ip & cb->val.hmask.ip;
  52. range->max_ip = range->min_ip | ~cb->val.hmask.ip;
  53. }
  54. static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
  55. int numeric)
  56. {
  57. const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
  58. const struct nf_nat_ipv4_range *r = &mr->range[0];
  59. struct in_addr a;
  60. int bits;
  61. a.s_addr = r->min_ip;
  62. printf("%s", xtables_ipaddr_to_numeric(&a));
  63. a.s_addr = ~(r->min_ip ^ r->max_ip);
  64. bits = netmask2bits(a.s_addr);
  65. if (bits < 0)
  66. printf("/%s", xtables_ipaddr_to_numeric(&a));
  67. else
  68. printf("/%d", bits);
  69. }
  70. static void NETMAP_save(const void *ip, const struct xt_entry_target *target)
  71. {
  72. printf(" --%s ", NETMAP_opts[0].name);
  73. NETMAP_print(ip, target, 0);
  74. }
  75. static struct xtables_target netmap_tg_reg = {
  76. .name = MODULENAME,
  77. .version = XTABLES_VERSION,
  78. .family = NFPROTO_IPV4,
  79. .size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
  80. .userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
  81. .help = NETMAP_help,
  82. .init = NETMAP_init,
  83. .x6_parse = NETMAP_parse,
  84. .print = NETMAP_print,
  85. .save = NETMAP_save,
  86. .x6_options = NETMAP_opts,
  87. };
  88. void _init(void)
  89. {
  90. xtables_register_target(&netmap_tg_reg);
  91. }