1
0

xX.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  4. * Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  5. *
  6. * The Tcpreplay Suite of tools is free software: you can redistribute it
  7. * and/or modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation, either version 3 of the
  9. * License, or with the authors permission any later version.
  10. *
  11. * The Tcpreplay Suite is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /*
  20. * xX stands for "include or exclude" which is used with the
  21. * -x and -X flags
  22. *
  23. * Functions for use to process args for or check data against in
  24. * tcpreplay/do_packets and tcpprep.
  25. */
  26. #include "defines.h"
  27. #include "config.h"
  28. #include "common.h"
  29. #include <stdlib.h>
  30. /**
  31. * returns the include_exclude_mode on success placing the CIDR or LIST in mybuf
  32. * but on failure, returns xXError
  33. */
  34. int
  35. parse_xX_str(tcpr_xX_t *xX, char *str, tcpr_bpf_t *bpf)
  36. {
  37. int out;
  38. dbgx(1, "Parsing string: %s", str);
  39. dbgx(1, "Switching on: %c", str[0]);
  40. if (str[0] && str[1] == 0) {
  41. errx(-1, "Syntax error for option -%c", str[0]);
  42. }
  43. switch (str[0]) {
  44. case 'B': /* both ip's */
  45. str = str + 2;
  46. out = xXBoth;
  47. if (!parse_cidr(&(xX->cidr), str, ","))
  48. return xXError;
  49. break;
  50. case 'D': /* dst ip */
  51. str = str + 2;
  52. out = xXDest;
  53. if (!parse_cidr(&(xX->cidr), str, ","))
  54. return xXError;
  55. break;
  56. case 'E': /* either ip */
  57. str = str + 2;
  58. out = xXEither;
  59. if (!parse_cidr(&(xX->cidr), str, ","))
  60. return xXError;
  61. break;
  62. case 'F': /* bpf filter */
  63. str = str + 2;
  64. out = xXBPF;
  65. bpf->filter = safe_strdup(str);
  66. /*
  67. * note: it's temping to compile the BPF here, but we don't
  68. * yet know what the link type is for the file, so we have
  69. * to compile the BPF once we open the pcap file
  70. */
  71. break;
  72. case 'P': /* packet id */
  73. str = str + 2;
  74. out = xXPacket;
  75. if (!parse_list(&(xX->list), str))
  76. return xXError;
  77. break;
  78. case 'S': /* source ip */
  79. str = str + 2;
  80. out = xXSource;
  81. if (!parse_cidr(&(xX->cidr), str, ","))
  82. return xXError;
  83. break;
  84. default:
  85. errx(-1, "Invalid -%c option: %c", xX->mode, *str);
  86. }
  87. if (xX->mode == 'X') { /* run in exclude mode */
  88. out += xXExclude;
  89. if (bpf->filter != NULL)
  90. err(-1,
  91. "Using a BPF filter with -X doesn't work.\n"
  92. "Try using -xF:\"not <filter>\" instead");
  93. }
  94. xX->mode = out;
  95. return xX->mode;
  96. }
  97. /**
  98. * compare the source/destination IP address according to the mode
  99. * and return 1 if we should send the packet or 0 if not
  100. */
  101. int
  102. process_xX_by_cidr_ipv4(int mode, tcpr_cidr_t *cidr, ipv4_hdr_t *ip_hdr)
  103. {
  104. if (mode & xXExclude) {
  105. /* Exclude mode */
  106. switch (mode ^ xXExclude) {
  107. case xXSource:
  108. /* note: check_ip_cidr() returns TCPR_DIR_C2S for true, TCPR_DIR_S2C for false
  109. * and NOT true/false or 1/0, etc!
  110. */
  111. return check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ? DONT_SEND : SEND;
  112. case xXDest:
  113. return check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) ? DONT_SEND : SEND;
  114. case xXBoth:
  115. return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) && check_ip_cidr(cidr, ip_hdr->ip_src.s_addr))
  116. ? DONT_SEND
  117. : SEND;
  118. case xXEither:
  119. return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) || check_ip_cidr(cidr, ip_hdr->ip_src.s_addr))
  120. ? DONT_SEND
  121. : SEND;
  122. }
  123. } else {
  124. /* Include Mode */
  125. switch (mode) {
  126. case xXSource:
  127. return check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ? SEND : DONT_SEND;
  128. case xXDest:
  129. return check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) ? SEND : DONT_SEND;
  130. case xXBoth:
  131. return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) && check_ip_cidr(cidr, ip_hdr->ip_src.s_addr))
  132. ? SEND
  133. : DONT_SEND;
  134. case xXEither:
  135. return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) || check_ip_cidr(cidr, ip_hdr->ip_src.s_addr))
  136. ? SEND
  137. : DONT_SEND;
  138. default:
  139. assert(false);
  140. }
  141. }
  142. /* total failure */
  143. if (mode & xXExclude) {
  144. warn("Unable to determine action in CIDR filter mode. Default: Don't Send.");
  145. return DONT_SEND;
  146. } else {
  147. warn("Unable to determine action in CIDR filter mode. Default: Send.");
  148. return SEND;
  149. }
  150. }
  151. int
  152. process_xX_by_cidr_ipv6(int mode, tcpr_cidr_t *cidr, ipv6_hdr_t *ip6_hdr)
  153. {
  154. if (mode & xXExclude) {
  155. /* Exclude mode */
  156. switch (mode ^ xXExclude) {
  157. case xXSource:
  158. /* note: check_ip_cidr() returns TCPR_DIR_C2S for true, TCPR_DIR_S2C for false
  159. * and NOT true/false or 1/0, etc!
  160. */
  161. return check_ip6_cidr(cidr, &ip6_hdr->ip_src) ? DONT_SEND : SEND;
  162. case xXDest:
  163. return check_ip6_cidr(cidr, &ip6_hdr->ip_dst) ? DONT_SEND : SEND;
  164. case xXBoth:
  165. return (check_ip6_cidr(cidr, &ip6_hdr->ip_dst) && check_ip6_cidr(cidr, &ip6_hdr->ip_src)) ? DONT_SEND
  166. : SEND;
  167. case xXEither:
  168. return (check_ip6_cidr(cidr, &ip6_hdr->ip_dst) || check_ip6_cidr(cidr, &ip6_hdr->ip_src)) ? DONT_SEND
  169. : SEND;
  170. }
  171. } else {
  172. /* Include Mode */
  173. switch (mode) {
  174. case xXSource:
  175. return check_ip6_cidr(cidr, &ip6_hdr->ip_src) ? SEND : DONT_SEND;
  176. case xXDest:
  177. return check_ip6_cidr(cidr, &ip6_hdr->ip_dst) ? SEND : DONT_SEND;
  178. case xXBoth:
  179. return (check_ip6_cidr(cidr, &ip6_hdr->ip_dst) && check_ip6_cidr(cidr, &ip6_hdr->ip_src)) ? SEND
  180. : DONT_SEND;
  181. case xXEither:
  182. return (check_ip6_cidr(cidr, &ip6_hdr->ip_dst) || check_ip6_cidr(cidr, &ip6_hdr->ip_src)) ? SEND
  183. : DONT_SEND;
  184. default:
  185. assert(false);
  186. }
  187. }
  188. /* total failure */
  189. if (mode & xXExclude) {
  190. warn("Unable to determine action in CIDR filter mode. Default: Don't Send.");
  191. return DONT_SEND;
  192. } else {
  193. warn("Unable to determine action in CIDR filter mode. Default: Send.");
  194. return SEND;
  195. }
  196. }