tcpedit_api.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  4. * Copyright (c) 2013-2018 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. #include <ctype.h>
  20. #include <sys/types.h>
  21. #include <stdlib.h>
  22. #include "config.h"
  23. #include "defines.h"
  24. #include "tcpedit.h"
  25. #include "portmap.h"
  26. #include "dlt_utils.h"
  27. /**
  28. * Set output DLT plugin by using it's DLT_<type>. Note that the user plugin
  29. * is DLT_USER0.
  30. */
  31. int
  32. tcpedit_set_encoder_dltplugin_byid(tcpedit_t *tcpedit, int dlt)
  33. {
  34. tcpeditdlt_plugin_t *plugin;
  35. tcpeditdlt_t *ctx;
  36. assert(tcpedit);
  37. ctx = tcpedit->dlt_ctx;
  38. assert(ctx);
  39. if (ctx->encoder) {
  40. tcpedit_seterr(tcpedit, "You have already selected a DLT encoder: %s", ctx->encoder->name);
  41. return TCPEDIT_ERROR;
  42. }
  43. plugin = tcpedit_dlt_getplugin(ctx, dlt);
  44. if (plugin == NULL) {
  45. tcpedit_seterr(tcpedit, "No output DLT plugin decoder with DLT type: 0x%04x", dlt);
  46. return TCPEDIT_ERROR;
  47. }
  48. ctx->encoder = plugin;
  49. /* init the encoder plugin if it's not the decoder plugin too */
  50. if (ctx->encoder->dlt != ctx->decoder->dlt) {
  51. if (ctx->encoder->plugin_init(ctx) != TCPEDIT_OK) {
  52. /* plugin should generate the error */
  53. return TCPEDIT_ERROR;
  54. }
  55. }
  56. return TCPEDIT_OK;
  57. }
  58. /**
  59. * same as tcpedit_set_encoder_plugin_byid() except we take the DLT_<name>
  60. * as a string to select it
  61. */
  62. int
  63. tcpedit_set_encoder_dltplugin_byname(tcpedit_t *tcpedit, const char *name)
  64. {
  65. tcpeditdlt_plugin_t *plugin;
  66. tcpeditdlt_t *ctx;
  67. assert(tcpedit);
  68. ctx = tcpedit->dlt_ctx;
  69. assert(ctx);
  70. if (ctx->encoder) {
  71. tcpedit_seterr(tcpedit, "You have already selected a DLT encoder: %s", ctx->encoder->name);
  72. return TCPEDIT_ERROR;
  73. }
  74. plugin = tcpedit_dlt_getplugin_byname(ctx, name);
  75. if (plugin == NULL) {
  76. tcpedit_seterr(tcpedit, "No output DLT plugin available for: %s", name);
  77. return TCPEDIT_ERROR;
  78. }
  79. ctx->encoder = plugin;
  80. /* init the encoder plugin if it's not the decoder plugin too */
  81. if (ctx->encoder->dlt != ctx->decoder->dlt) {
  82. if (ctx->encoder->plugin_init(ctx) != TCPEDIT_OK) {
  83. /* plugin should generate the error */
  84. return TCPEDIT_ERROR;
  85. }
  86. }
  87. return TCPEDIT_OK;
  88. }
  89. /**
  90. * Set whether we should edit broadcast & multicast IP addresses
  91. */
  92. int
  93. tcpedit_set_skip_broadcast(tcpedit_t *tcpedit, bool value)
  94. {
  95. assert(tcpedit);
  96. tcpedit->skip_broadcast = value;
  97. return TCPEDIT_OK;
  98. }
  99. /**
  100. * \brief force fixing L3 & L4 data by padding or truncating packets
  101. */
  102. int
  103. tcpedit_set_fixlen(tcpedit_t *tcpedit, tcpedit_fixlen value)
  104. {
  105. assert(tcpedit);
  106. tcpedit->fixlen = value;
  107. return TCPEDIT_OK;
  108. }
  109. /**
  110. * \brief should we always recalculate L3 & L4 checksums?
  111. */
  112. int
  113. tcpedit_set_fixcsum(tcpedit_t *tcpedit, bool value)
  114. {
  115. assert(tcpedit);
  116. tcpedit->fixcsum = value;
  117. return TCPEDIT_OK;
  118. }
  119. /**
  120. * \brief should we remove the EFCS from the frame?
  121. */
  122. int
  123. tcpedit_set_efcs(tcpedit_t *tcpedit, bool value)
  124. {
  125. assert(tcpedit);
  126. tcpedit->efcs = value;
  127. return TCPEDIT_OK;
  128. }
  129. /**
  130. * \brief set the IPv4 TTL mode
  131. */
  132. int
  133. tcpedit_set_ttl_mode(tcpedit_t *tcpedit, tcpedit_ttl_mode value)
  134. {
  135. assert(tcpedit);
  136. tcpedit->ttl_mode = value;
  137. return TCPEDIT_OK;
  138. }
  139. /**
  140. * \brief set the IPv4 ttl value
  141. */
  142. int
  143. tcpedit_set_ttl_value(tcpedit_t *tcpedit, uint8_t value)
  144. {
  145. assert(tcpedit);
  146. tcpedit->ttl_value = value;
  147. return TCPEDIT_OK;
  148. }
  149. /**
  150. * \brief set the IPv4 TOS/DiffServ/ECN byte value
  151. */
  152. int
  153. tcpedit_set_tos(tcpedit_t *tcpedit, uint8_t value)
  154. {
  155. assert(tcpedit);
  156. tcpedit->tos = value;
  157. return TCPEDIT_OK;
  158. }
  159. /**
  160. * \brief set the IPv6 Traffic Class byte value
  161. */
  162. int
  163. tcpedit_set_tclass(tcpedit_t *tcpedit, uint8_t value)
  164. {
  165. assert(tcpedit);
  166. tcpedit->tclass = value;
  167. return TCPEDIT_OK;
  168. }
  169. /**
  170. * \brief set the IPv6 Flow Label 20bit value
  171. */
  172. int
  173. tcpedit_set_flowlabel(tcpedit_t *tcpedit, uint32_t value)
  174. {
  175. assert(tcpedit);
  176. tcpedit->flowlabel = value;
  177. return TCPEDIT_OK;
  178. }
  179. /**
  180. * Set the IPv4 IP address randomization seed
  181. */
  182. int
  183. tcpedit_set_seed(tcpedit_t *tcpedit)
  184. {
  185. assert(tcpedit);
  186. tcpedit->rewrite_ip = true;
  187. tcpedit->seed = 1;
  188. tcpedit->seed = tcpr_random(&tcpedit->seed);
  189. return TCPEDIT_OK;
  190. }
  191. /**
  192. * Set the MTU of the frames
  193. */
  194. int
  195. tcpedit_set_mtu(tcpedit_t *tcpedit, int value)
  196. {
  197. assert(tcpedit);
  198. tcpedit->mtu = value;
  199. return TCPEDIT_OK;
  200. }
  201. /**
  202. * Enable truncating packets to the MTU length
  203. */
  204. int tcpedit_set_mtu_truncate(tcpedit_t *tcpedit, bool value)
  205. {
  206. assert(tcpedit);
  207. tcpedit->mtu_truncate = value;
  208. return TCPEDIT_OK;
  209. }
  210. /**
  211. * Set the maxpacket- currently not supported
  212. */
  213. int
  214. tcpedit_set_maxpacket(tcpedit_t *tcpedit, int value)
  215. {
  216. assert(tcpedit);
  217. tcpedit->maxpacket = value;
  218. return TCPEDIT_OK;
  219. }
  220. /**
  221. * \brief Set the server to client (primary) CIDR map (Pseudo NAT)
  222. *
  223. * Set the server to client (primary) CIDR map using the given string
  224. * which is in the format of:
  225. * <match cidr>:<target cidr>,...
  226. * 192.168.0.0/16:10.77.0.0/16,172.16.0.0/12:10.1.0.0/24
  227. */
  228. int
  229. tcpedit_set_cidrmap_s2c(tcpedit_t *tcpedit, char *value)
  230. {
  231. assert(tcpedit);
  232. tcpedit->rewrite_ip = true;
  233. if (! parse_cidr_map(&tcpedit->cidrmap1, value)) {
  234. tcpedit_seterr(tcpedit, "Unable to parse: %s", value);
  235. return TCPEDIT_ERROR;
  236. }
  237. return TCPEDIT_OK;
  238. }
  239. /**
  240. * \brief Set the client to server (secondary) CIDR map (Pseudo NAT)
  241. *
  242. * Set the client to server (secondary) CIDR map using the given string
  243. * which is in the format of:
  244. * <match cidr>:<target cidr>,...
  245. * 192.168.0.0/16:10.77.0.0/16,172.16.0.0/12:10.1.0.0/24
  246. */
  247. int
  248. tcpedit_set_cidrmap_c2s(tcpedit_t *tcpedit, char *value)
  249. {
  250. assert(tcpedit);
  251. tcpedit->rewrite_ip = true;
  252. if (! parse_cidr_map(&tcpedit->cidrmap2, value)) {
  253. tcpedit_seterr(tcpedit, "Unable to parse: %s", value);
  254. return TCPEDIT_ERROR;
  255. }
  256. return TCPEDIT_OK;
  257. }
  258. /**
  259. * Rewrite the Source IP of any packet
  260. */
  261. int
  262. tcpedit_set_srcip_map(tcpedit_t *tcpedit, char *value)
  263. {
  264. assert(tcpedit);
  265. tcpedit->rewrite_ip = true;
  266. if (! parse_cidr_map(&tcpedit->srcipmap, value)) {
  267. tcpedit_seterr(tcpedit, "Unable to parse source ip map: %s", value);
  268. return TCPEDIT_ERROR;
  269. }
  270. return TCPEDIT_OK;
  271. }
  272. /**
  273. * Rewrite the Destination IP of any packet
  274. */
  275. int
  276. tcpedit_set_dstip_map(tcpedit_t *tcpedit, char *value)
  277. {
  278. assert(tcpedit);
  279. tcpedit->rewrite_ip = true;
  280. if (! parse_cidr_map(&tcpedit->dstipmap, value)) {
  281. tcpedit_seterr(tcpedit, "Unable to parse destination ip map: %s", value);
  282. return TCPEDIT_ERROR;
  283. }
  284. return TCPEDIT_OK;
  285. }
  286. /**
  287. * Rewrite TCP/UDP ports using the following format:
  288. * <src>:<dst>,...
  289. */
  290. int
  291. tcpedit_set_port_map(tcpedit_t *tcpedit, char *value)
  292. {
  293. assert(tcpedit);
  294. if (! parse_portmap(&tcpedit->portmap, value)) {
  295. tcpedit_seterr(tcpedit,
  296. "Unable to parse portmap: %s", value);
  297. return TCPEDIT_ERROR;
  298. }
  299. return TCPEDIT_OK;
  300. }