/* $Id$ */ /* * Copyright (c) 2001-2010 Aaron Turner * Copyright (c) 2013-2017 Fred Klassen - AppNeta * * The Tcpreplay Suite of tools is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or with the authors permission any later version. * * The Tcpreplay Suite is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the Tcpreplay Suite. If not, see . */ #include #include #include #include "config.h" #include "defines.h" #include "tcpedit.h" #include "portmap.h" #include "dlt_utils.h" /** * Set output DLT plugin by using it's DLT_. Note that the user plugin * is DLT_USER0. */ int tcpedit_set_encoder_dltplugin_byid(tcpedit_t *tcpedit, int dlt) { tcpeditdlt_plugin_t *plugin; tcpeditdlt_t *ctx; assert(tcpedit); ctx = tcpedit->dlt_ctx; assert(ctx); if (ctx->encoder) { tcpedit_seterr(tcpedit, "You have already selected a DLT encoder: %s", ctx->encoder->name); return TCPEDIT_ERROR; } plugin = tcpedit_dlt_getplugin(ctx, dlt); if (plugin == NULL) { tcpedit_seterr(tcpedit, "No output DLT plugin decoder with DLT type: 0x%04x", dlt); return TCPEDIT_ERROR; } ctx->encoder = plugin; /* init the encoder plugin if it's not the decoder plugin too */ if (ctx->encoder->dlt != ctx->decoder->dlt) { if (ctx->encoder->plugin_init(ctx) != TCPEDIT_OK) { /* plugin should generate the error */ return TCPEDIT_ERROR; } } return TCPEDIT_OK; } /** * same as tcpedit_set_encoder_plugin_byid() except we take the DLT_ * as a string to select it */ int tcpedit_set_encoder_dltplugin_byname(tcpedit_t *tcpedit, const char *name) { tcpeditdlt_plugin_t *plugin; tcpeditdlt_t *ctx; assert(tcpedit); ctx = tcpedit->dlt_ctx; assert(ctx); if (ctx->encoder) { tcpedit_seterr(tcpedit, "You have already selected a DLT encoder: %s", ctx->encoder->name); return TCPEDIT_ERROR; } plugin = tcpedit_dlt_getplugin_byname(ctx, name); if (plugin == NULL) { tcpedit_seterr(tcpedit, "No output DLT plugin available for: %s", name); return TCPEDIT_ERROR; } ctx->encoder = plugin; /* init the encoder plugin if it's not the decoder plugin too */ if (ctx->encoder->dlt != ctx->decoder->dlt) { if (ctx->encoder->plugin_init(ctx) != TCPEDIT_OK) { /* plugin should generate the error */ return TCPEDIT_ERROR; } } return TCPEDIT_OK; } /** * Set whether we should edit broadcast & multicast IP addresses */ int tcpedit_set_skip_broadcast(tcpedit_t *tcpedit, bool value) { assert(tcpedit); tcpedit->skip_broadcast = value; return TCPEDIT_OK; } /** * \brief force fixing L3 & L4 data by padding or truncating packets */ int tcpedit_set_fixlen(tcpedit_t *tcpedit, tcpedit_fixlen value) { assert(tcpedit); tcpedit->fixlen = value; return TCPEDIT_OK; } /** * \brief should we always recalculate L3 & L4 checksums? */ int tcpedit_set_fixcsum(tcpedit_t *tcpedit, bool value) { assert(tcpedit); tcpedit->fixcsum = value; return TCPEDIT_OK; } /** * \brief should we remove the EFCS from the frame? */ int tcpedit_set_efcs(tcpedit_t *tcpedit, bool value) { assert(tcpedit); tcpedit->efcs = value; return TCPEDIT_OK; } /** * \brief set the IPv4 TTL mode */ int tcpedit_set_ttl_mode(tcpedit_t *tcpedit, tcpedit_ttl_mode value) { assert(tcpedit); tcpedit->ttl_mode = value; return TCPEDIT_OK; } /** * \brief set the IPv4 ttl value */ int tcpedit_set_ttl_value(tcpedit_t *tcpedit, uint8_t value) { assert(tcpedit); tcpedit->ttl_value = value; return TCPEDIT_OK; } /** * \brief set the IPv4 TOS/DiffServ/ECN byte value */ int tcpedit_set_tos(tcpedit_t *tcpedit, uint8_t value) { assert(tcpedit); tcpedit->tos = value; return TCPEDIT_OK; } /** * \brief set the IPv6 Traffic Class byte value */ int tcpedit_set_tclass(tcpedit_t *tcpedit, uint8_t value) { assert(tcpedit); tcpedit->tclass = value; return TCPEDIT_OK; } /** * \brief set the IPv6 Flow Label 20bit value */ int tcpedit_set_flowlabel(tcpedit_t *tcpedit, uint32_t value) { assert(tcpedit); tcpedit->flowlabel = value; return TCPEDIT_OK; } /** * Set the IPv4 IP address randomization seed */ int tcpedit_set_seed(tcpedit_t *tcpedit) { assert(tcpedit); tcpedit->rewrite_ip = true; tcpedit->seed = 1; tcpedit->seed = tcpr_random(&tcpedit->seed); return TCPEDIT_OK; } /** * Set the MTU of the frames */ int tcpedit_set_mtu(tcpedit_t *tcpedit, int value) { assert(tcpedit); tcpedit->mtu = value; return TCPEDIT_OK; } /** * Enable trucating packets to the MTU lenght */ int tcpedit_set_mtu_truncate(tcpedit_t *tcpedit, bool value) { assert(tcpedit); tcpedit->mtu_truncate = value; return TCPEDIT_OK; } /** * Set the maxpacket- currently not supported */ int tcpedit_set_maxpacket(tcpedit_t *tcpedit, int value) { assert(tcpedit); tcpedit->maxpacket = value; return TCPEDIT_OK; } /** * \brief Set the server to client (primary) CIDR map (Pseudo NAT) * * Set the server to client (primary) CIDR map using the given string * which is in the format of: * :,... * 192.168.0.0/16:10.77.0.0/16,172.16.0.0/12:10.1.0.0/24 */ int tcpedit_set_cidrmap_s2c(tcpedit_t *tcpedit, char *value) { assert(tcpedit); tcpedit->rewrite_ip = true; if (! parse_cidr_map(&tcpedit->cidrmap1, value)) { tcpedit_seterr(tcpedit, "Unable to parse: %s", value); return TCPEDIT_ERROR; } return TCPEDIT_OK; } /** * \brief Set the client to server (secondary) CIDR map (Pseudo NAT) * * Set the client to server (secondary) CIDR map using the given string * which is in the format of: * :,... * 192.168.0.0/16:10.77.0.0/16,172.16.0.0/12:10.1.0.0/24 */ int tcpedit_set_cidrmap_c2s(tcpedit_t *tcpedit, char *value) { assert(tcpedit); tcpedit->rewrite_ip = true; if (! parse_cidr_map(&tcpedit->cidrmap2, value)) { tcpedit_seterr(tcpedit, "Unable to parse: %s", value); return TCPEDIT_ERROR; } return TCPEDIT_OK; } /** * Rewrite the Source IP of any packet */ int tcpedit_set_srcip_map(tcpedit_t *tcpedit, char *value) { assert(tcpedit); tcpedit->rewrite_ip = true; if (! parse_cidr_map(&tcpedit->srcipmap, value)) { tcpedit_seterr(tcpedit, "Unable to parse source ip map: %s", value); return TCPEDIT_ERROR; } return TCPEDIT_OK; } /** * Rewrite the Destination IP of any packet */ int tcpedit_set_dstip_map(tcpedit_t *tcpedit, char *value) { assert(tcpedit); tcpedit->rewrite_ip = true; if (! parse_cidr_map(&tcpedit->dstipmap, value)) { tcpedit_seterr(tcpedit, "Unable to parse destination ip map: %s", value); return TCPEDIT_ERROR; } return TCPEDIT_OK; } /** * Rewrite TCP/UDP ports using the following format: * :,... */ int tcpedit_set_port_map(tcpedit_t *tcpedit, char *value) { assert(tcpedit); if (! parse_portmap(&tcpedit->portmap, value)) { tcpedit_seterr(tcpedit, "Unable to parse portmap: %s", value); return TCPEDIT_ERROR; } return TCPEDIT_OK; }