libxt_NFQUEUE.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /* Shared library add-on to iptables for NFQ
  2. *
  3. * (C) 2005 by Harald Welte <laforge@netfilter.org>
  4. *
  5. * This program is distributed under the terms of GNU GPL v2, 1991
  6. *
  7. */
  8. #include <stdio.h>
  9. #include <xtables.h>
  10. #include <linux/netfilter/xt_NFQUEUE.h>
  11. enum {
  12. O_QUEUE_NUM = 0,
  13. O_QUEUE_BALANCE,
  14. O_QUEUE_BYPASS,
  15. F_QUEUE_NUM = 1 << O_QUEUE_NUM,
  16. F_QUEUE_BALANCE = 1 << O_QUEUE_BALANCE,
  17. };
  18. static void NFQUEUE_help(void)
  19. {
  20. printf(
  21. "NFQUEUE target options\n"
  22. " --queue-num value Send packet to QUEUE number <value>.\n"
  23. " Valid queue numbers are 0-65535\n"
  24. );
  25. }
  26. static void NFQUEUE_help_v1(void)
  27. {
  28. NFQUEUE_help();
  29. printf(
  30. " --queue-balance first:last Balance flows between queues <value> to <value>.\n");
  31. }
  32. static void NFQUEUE_help_v2(void)
  33. {
  34. NFQUEUE_help_v1();
  35. printf(
  36. " --queue-bypass Bypass Queueing if no queue instance exists.\n");
  37. }
  38. #define s struct xt_NFQ_info
  39. static const struct xt_option_entry NFQUEUE_opts[] = {
  40. {.name = "queue-num", .id = O_QUEUE_NUM, .type = XTTYPE_UINT16,
  41. .flags = XTOPT_PUT, XTOPT_POINTER(s, queuenum),
  42. .excl = F_QUEUE_BALANCE},
  43. {.name = "queue-balance", .id = O_QUEUE_BALANCE,
  44. .type = XTTYPE_UINT16RC, .excl = F_QUEUE_NUM},
  45. {.name = "queue-bypass", .id = O_QUEUE_BYPASS, .type = XTTYPE_NONE},
  46. XTOPT_TABLEEND,
  47. };
  48. #undef s
  49. static void NFQUEUE_parse(struct xt_option_call *cb)
  50. {
  51. xtables_option_parse(cb);
  52. if (cb->entry->id == O_QUEUE_BALANCE)
  53. xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
  54. "--queue-balance not supported (kernel too old?)");
  55. }
  56. static void NFQUEUE_parse_v1(struct xt_option_call *cb)
  57. {
  58. struct xt_NFQ_info_v1 *info = cb->data;
  59. const uint16_t *r = cb->val.u16_range;
  60. xtables_option_parse(cb);
  61. switch (cb->entry->id) {
  62. case O_QUEUE_BALANCE:
  63. if (cb->nvals != 2)
  64. xtables_error(PARAMETER_PROBLEM,
  65. "Bad range \"%s\"", cb->arg);
  66. if (r[0] >= r[1])
  67. xtables_error(PARAMETER_PROBLEM, "%u should be less than %u",
  68. r[0], r[1]);
  69. info->queuenum = r[0];
  70. info->queues_total = r[1] - r[0] + 1;
  71. break;
  72. }
  73. }
  74. static void NFQUEUE_parse_v2(struct xt_option_call *cb)
  75. {
  76. struct xt_NFQ_info_v2 *info = cb->data;
  77. NFQUEUE_parse_v1(cb);
  78. switch (cb->entry->id) {
  79. case O_QUEUE_BYPASS:
  80. info->bypass = 1;
  81. break;
  82. }
  83. }
  84. static void NFQUEUE_print(const void *ip,
  85. const struct xt_entry_target *target, int numeric)
  86. {
  87. const struct xt_NFQ_info *tinfo =
  88. (const struct xt_NFQ_info *)target->data;
  89. printf(" NFQUEUE num %u", tinfo->queuenum);
  90. }
  91. static void NFQUEUE_print_v1(const void *ip,
  92. const struct xt_entry_target *target, int numeric)
  93. {
  94. const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
  95. unsigned int last = tinfo->queues_total;
  96. if (last > 1) {
  97. last += tinfo->queuenum - 1;
  98. printf(" NFQUEUE balance %u:%u", tinfo->queuenum, last);
  99. } else {
  100. printf(" NFQUEUE num %u", tinfo->queuenum);
  101. }
  102. }
  103. static void NFQUEUE_print_v2(const void *ip,
  104. const struct xt_entry_target *target, int numeric)
  105. {
  106. const struct xt_NFQ_info_v2 *info = (void *) target->data;
  107. NFQUEUE_print_v1(ip, target, numeric);
  108. if (info->bypass)
  109. printf(" bypass");
  110. }
  111. static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target)
  112. {
  113. const struct xt_NFQ_info *tinfo =
  114. (const struct xt_NFQ_info *)target->data;
  115. printf(" --queue-num %u", tinfo->queuenum);
  116. }
  117. static void NFQUEUE_save_v1(const void *ip, const struct xt_entry_target *target)
  118. {
  119. const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
  120. unsigned int last = tinfo->queues_total;
  121. if (last > 1) {
  122. last += tinfo->queuenum - 1;
  123. printf(" --queue-balance %u:%u", tinfo->queuenum, last);
  124. } else {
  125. printf(" --queue-num %u", tinfo->queuenum);
  126. }
  127. }
  128. static void NFQUEUE_save_v2(const void *ip, const struct xt_entry_target *target)
  129. {
  130. const struct xt_NFQ_info_v2 *info = (void *) target->data;
  131. NFQUEUE_save_v1(ip, target);
  132. if (info->bypass)
  133. printf(" --queue-bypass");
  134. }
  135. static void NFQUEUE_init_v1(struct xt_entry_target *t)
  136. {
  137. struct xt_NFQ_info_v1 *tinfo = (void *)t->data;
  138. tinfo->queues_total = 1;
  139. }
  140. static struct xtables_target nfqueue_targets[] = {
  141. {
  142. .family = NFPROTO_UNSPEC,
  143. .name = "NFQUEUE",
  144. .version = XTABLES_VERSION,
  145. .size = XT_ALIGN(sizeof(struct xt_NFQ_info)),
  146. .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info)),
  147. .help = NFQUEUE_help,
  148. .print = NFQUEUE_print,
  149. .save = NFQUEUE_save,
  150. .x6_parse = NFQUEUE_parse,
  151. .x6_options = NFQUEUE_opts
  152. },{
  153. .family = NFPROTO_UNSPEC,
  154. .revision = 1,
  155. .name = "NFQUEUE",
  156. .version = XTABLES_VERSION,
  157. .size = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)),
  158. .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)),
  159. .help = NFQUEUE_help_v1,
  160. .init = NFQUEUE_init_v1,
  161. .print = NFQUEUE_print_v1,
  162. .save = NFQUEUE_save_v1,
  163. .x6_parse = NFQUEUE_parse_v1,
  164. .x6_options = NFQUEUE_opts,
  165. },{
  166. .family = NFPROTO_UNSPEC,
  167. .revision = 2,
  168. .name = "NFQUEUE",
  169. .version = XTABLES_VERSION,
  170. .size = XT_ALIGN(sizeof(struct xt_NFQ_info_v2)),
  171. .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v2)),
  172. .help = NFQUEUE_help_v2,
  173. .init = NFQUEUE_init_v1,
  174. .print = NFQUEUE_print_v2,
  175. .save = NFQUEUE_save_v2,
  176. .x6_parse = NFQUEUE_parse_v2,
  177. .x6_options = NFQUEUE_opts,
  178. }
  179. };
  180. void _init(void)
  181. {
  182. xtables_register_targets(nfqueue_targets, ARRAY_SIZE(nfqueue_targets));
  183. }