libxt_TCPOPTSTRIP.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Shared library add-on to iptables to add TCPOPTSTRIP target support.
  3. * Copyright (c) 2007 Sven Schnelle <svens@bitebene.org>
  4. * Copyright © CC Computer Consultants GmbH, 2007
  5. * Jan Engelhardt <jengelh@computergmbh.de>
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <xtables.h>
  10. #include <netinet/tcp.h>
  11. #include <linux/netfilter/xt_TCPOPTSTRIP.h>
  12. #ifndef TCPOPT_MD5SIG
  13. # define TCPOPT_MD5SIG 19
  14. #endif
  15. enum {
  16. O_STRIP_OPTION = 0,
  17. };
  18. struct tcp_optionmap {
  19. const char *name, *desc;
  20. const unsigned int option;
  21. };
  22. static const struct xt_option_entry tcpoptstrip_tg_opts[] = {
  23. {.name = "strip-options", .id = O_STRIP_OPTION, .type = XTTYPE_STRING},
  24. XTOPT_TABLEEND,
  25. };
  26. static const struct tcp_optionmap tcp_optionmap[] = {
  27. {"wscale", "Window scale", TCPOPT_WINDOW},
  28. {"mss", "Maximum Segment Size", TCPOPT_MAXSEG},
  29. {"sack-permitted", "SACK permitted", TCPOPT_SACK_PERMITTED},
  30. {"sack", "Selective ACK", TCPOPT_SACK},
  31. {"timestamp", "Timestamp", TCPOPT_TIMESTAMP},
  32. {"md5", "MD5 signature", TCPOPT_MD5SIG},
  33. {NULL},
  34. };
  35. static void tcpoptstrip_tg_help(void)
  36. {
  37. const struct tcp_optionmap *w;
  38. printf(
  39. "TCPOPTSTRIP target options:\n"
  40. " --strip-options value strip specified TCP options denoted by value\n"
  41. " (separated by comma) from TCP header\n"
  42. " Instead of the numeric value, you can also use the following names:\n"
  43. );
  44. for (w = tcp_optionmap; w->name != NULL; ++w)
  45. printf(" %-14s strip \"%s\" option\n", w->name, w->desc);
  46. }
  47. static void
  48. parse_list(struct xt_tcpoptstrip_target_info *info, const char *arg)
  49. {
  50. unsigned int option;
  51. char *p;
  52. int i;
  53. while (true) {
  54. p = strchr(arg, ',');
  55. if (p != NULL)
  56. *p = '\0';
  57. option = 0;
  58. for (i = 0; tcp_optionmap[i].name != NULL; ++i)
  59. if (strcmp(tcp_optionmap[i].name, arg) == 0) {
  60. option = tcp_optionmap[i].option;
  61. break;
  62. }
  63. if (option == 0 &&
  64. !xtables_strtoui(arg, NULL, &option, 0, UINT8_MAX))
  65. xtables_error(PARAMETER_PROBLEM,
  66. "Bad TCP option value \"%s\"", arg);
  67. if (option < 2)
  68. xtables_error(PARAMETER_PROBLEM,
  69. "Option value may not be 0 or 1");
  70. if (tcpoptstrip_test_bit(info->strip_bmap, option))
  71. xtables_error(PARAMETER_PROBLEM,
  72. "Option \"%s\" already specified", arg);
  73. tcpoptstrip_set_bit(info->strip_bmap, option);
  74. if (p == NULL)
  75. break;
  76. arg = p + 1;
  77. }
  78. }
  79. static void tcpoptstrip_tg_parse(struct xt_option_call *cb)
  80. {
  81. struct xt_tcpoptstrip_target_info *info = cb->data;
  82. xtables_option_parse(cb);
  83. parse_list(info, cb->arg);
  84. }
  85. static void
  86. tcpoptstrip_print_list(const struct xt_tcpoptstrip_target_info *info,
  87. bool numeric)
  88. {
  89. unsigned int i, j;
  90. const char *name;
  91. bool first = true;
  92. for (i = 0; i < 256; ++i) {
  93. if (!tcpoptstrip_test_bit(info->strip_bmap, i))
  94. continue;
  95. if (!first)
  96. printf(",");
  97. first = false;
  98. name = NULL;
  99. if (!numeric)
  100. for (j = 0; tcp_optionmap[j].name != NULL; ++j)
  101. if (tcp_optionmap[j].option == i)
  102. name = tcp_optionmap[j].name;
  103. if (name != NULL)
  104. printf("%s", name);
  105. else
  106. printf("%u", i);
  107. }
  108. }
  109. static void
  110. tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target,
  111. int numeric)
  112. {
  113. const struct xt_tcpoptstrip_target_info *info =
  114. (const void *)target->data;
  115. printf(" TCPOPTSTRIP options ");
  116. tcpoptstrip_print_list(info, numeric);
  117. }
  118. static void
  119. tcpoptstrip_tg_save(const void *ip, const struct xt_entry_target *target)
  120. {
  121. const struct xt_tcpoptstrip_target_info *info =
  122. (const void *)target->data;
  123. printf(" --strip-options ");
  124. tcpoptstrip_print_list(info, true);
  125. }
  126. static struct xtables_target tcpoptstrip_tg_reg = {
  127. .version = XTABLES_VERSION,
  128. .name = "TCPOPTSTRIP",
  129. .family = NFPROTO_UNSPEC,
  130. .size = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
  131. .userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
  132. .help = tcpoptstrip_tg_help,
  133. .print = tcpoptstrip_tg_print,
  134. .save = tcpoptstrip_tg_save,
  135. .x6_parse = tcpoptstrip_tg_parse,
  136. .x6_options = tcpoptstrip_tg_opts,
  137. };
  138. void _init(void)
  139. {
  140. xtables_register_target(&tcpoptstrip_tg_reg);
  141. }