123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- /* $Id$ */
- /*
- * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- * Copyright (c) 2013-2024 Fred Klassen <tcpreplay at appneta dot com> - 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 <http://www.gnu.org/licenses/>.
- */
- #include "parse_args.h"
- #include "config.h"
- #include "portmap.h"
- #include "tcpedit.h"
- #include "tcpedit_stub.h"
- #include <stdlib.h>
- #include <string.h>
- /**
- * returns 0 for success w/o errors
- * returns 1 for success w/ warnings
- * returns -1 for error
- */
- int
- tcpedit_post_args(tcpedit_t *tcpedit)
- {
- int rcode;
- int i;
- uint32_t seed = 1, rand_num;
- assert(tcpedit);
- /* --pnat */
- if (HAVE_OPT(PNAT)) {
- int ct = STACKCT_OPT(PNAT);
- char **list = (char **)STACKLST_OPT(PNAT);
- int first = 1;
- tcpedit->rewrite_ip = true;
- do {
- char *p = *list++;
- if (first) {
- if (!parse_cidr_map(&tcpedit->cidrmap1, p)) {
- tcpedit_seterr(tcpedit, "Unable to parse first --pnat=%s", p);
- return -1;
- }
- } else {
- if (!parse_cidr_map(&tcpedit->cidrmap2, p)) {
- tcpedit_seterr(tcpedit, "Unable to parse second --pnat=%s", p);
- return -1;
- }
- }
- first = 0;
- } while (--ct > 0);
- }
- /* --srcipmap */
- if (HAVE_OPT(SRCIPMAP)) {
- tcpedit->rewrite_ip = true;
- if (!parse_cidr_map(&tcpedit->srcipmap, OPT_ARG(SRCIPMAP))) {
- tcpedit_seterr(tcpedit, "Unable to parse --srcipmap=%s", OPT_ARG(SRCIPMAP));
- return -1;
- }
- }
- /* --dstipmap */
- if (HAVE_OPT(DSTIPMAP)) {
- tcpedit->rewrite_ip = true;
- if (!parse_cidr_map(&tcpedit->dstipmap, OPT_ARG(DSTIPMAP))) {
- tcpedit_seterr(tcpedit, "Unable to parse --dstipmap=%s", OPT_ARG(DSTIPMAP));
- return -1;
- }
- }
- /*
- * If we have one and only one -N, then use the same map data
- * for both interfaces/files
- */
- if ((tcpedit->cidrmap1 != NULL) && (tcpedit->cidrmap2 == NULL))
- tcpedit->cidrmap2 = tcpedit->cidrmap1;
- /* --fixcsum */
- if (HAVE_OPT(FIXCSUM))
- tcpedit->fixcsum = true;
- /* --fixhdrlen */
- if (HAVE_OPT(FIXHDRLEN))
- tcpedit->fixhdrlen = true;
- /* --efcs */
- if (HAVE_OPT(EFCS))
- tcpedit->efcs = true;
- /* --ttl */
- if (HAVE_OPT(TTL)) {
- long ttl;
- if (strchr(OPT_ARG(TTL), '+')) {
- tcpedit->ttl_mode = TCPEDIT_TTL_MODE_ADD;
- } else if (strchr(OPT_ARG(TTL), '-')) {
- tcpedit->ttl_mode = TCPEDIT_TTL_MODE_SUB;
- } else {
- tcpedit->ttl_mode = TCPEDIT_TTL_MODE_SET;
- }
- ttl = strtol(OPT_ARG(TTL), (char **)NULL, 10);
- if (ttl < 0)
- ttl *= -1; /* convert to positive value */
- if (ttl > 255) {
- tcpedit_seterr(tcpedit, "Invalid --ttl value (must be 0-255): %ld", ttl);
- return -1;
- }
- tcpedit->ttl_value = (u_int8_t)ttl;
- }
- /* --tos */
- if (HAVE_OPT(TOS))
- tcpedit->tos = OPT_VALUE_TOS;
- /* --tclass */
- if (HAVE_OPT(TCLASS))
- tcpedit->tclass = OPT_VALUE_TCLASS;
- /* --flowlabel */
- if (HAVE_OPT(FLOWLABEL))
- tcpedit->flowlabel = OPT_VALUE_FLOWLABEL;
- /* --mtu */
- if (HAVE_OPT(MTU))
- tcpedit->mtu = OPT_VALUE_MTU;
- /* --mtu-trunc */
- if (HAVE_OPT(MTU_TRUNC))
- tcpedit->mtu_truncate = true;
- /* --skipbroadcast */
- if (HAVE_OPT(SKIPBROADCAST))
- tcpedit->skip_broadcast = true;
- /* --fixlen */
- if (HAVE_OPT(FIXLEN)) {
- if (strcmp(OPT_ARG(FIXLEN), "pad") == 0) {
- tcpedit->fixlen = TCPEDIT_FIXLEN_PAD;
- } else if (strcmp(OPT_ARG(FIXLEN), "trunc") == 0) {
- tcpedit->fixlen = TCPEDIT_FIXLEN_TRUNC;
- } else if (strcmp(OPT_ARG(FIXLEN), "del") == 0) {
- tcpedit->fixlen = TCPEDIT_FIXLEN_DEL;
- } else {
- tcpedit_seterr(tcpedit, "Invalid --fixlen=%s", OPT_ARG(FIXLEN));
- return -1;
- }
- }
- /* --rewrite-sequence */
- if (HAVE_OPT(TCP_SEQUENCE)) {
- tcpedit->tcp_sequence_enable = 1;
- seed = OPT_VALUE_TCP_SEQUENCE;
- for (i = 0; i < 5; ++i)
- rand_num = tcpr_random(&seed);
- tcpedit->tcp_sequence_adjust = rand_num;
- }
- /* TCP/UDP port rewriting */
- if (HAVE_OPT(PORTMAP)) {
- int ct = STACKCT_OPT(PORTMAP);
- char **list = (char **)STACKLST_OPT(PORTMAP);
- int first = 1;
- tcpedit_portmap_t *portmap_head, *portmap;
- do {
- char *p = *list++;
- if (first) {
- if (!parse_portmap(&tcpedit->portmap, p)) {
- tcpedit_seterr(tcpedit, "Unable to parse --portmap=%s", p);
- return -1;
- }
- } else {
- if (!parse_portmap(&portmap, p)) {
- tcpedit_seterr(tcpedit, "Unable to parse --portmap=%s", p);
- return -1;
- }
- /* append to end of tcpedit->portmap linked list */
- portmap_head = tcpedit->portmap;
- while (portmap_head->next != NULL)
- portmap_head = portmap_head->next;
- portmap_head->next = portmap;
- }
- first = 0;
- } while (--ct > 0);
- }
- /*
- * IP address rewriting processing. Update seed by making
- * 5 calls to tcpr_random() as our mixer for randomizing. This should
- * work better since most people aren't going to write out values
- * close to 32bit integers.
- */
- if (HAVE_OPT(SEED)) {
- tcpedit->rewrite_ip = true;
- seed = OPT_VALUE_SEED;
- } else if (HAVE_OPT(FUZZ_SEED)) {
- /* --fuzz-seed */
- seed = OPT_VALUE_FUZZ_SEED;
- tcpedit->fuzz_factor = OPT_VALUE_FUZZ_FACTOR;
- }
- for (i = 0; i < 5; ++i)
- rand_num = tcpr_random(&seed);
- srandom(rand_num);
- if (HAVE_OPT(SEED)) {
- tcpedit->rewrite_ip = true;
- tcpedit->seed = seed;
- }
- if (HAVE_OPT(FUZZ_SEED)) {
- /* --fuzz-seed */
- tcpedit->fuzz_seed = seed;
- }
- if (HAVE_OPT(ENDPOINTS)) {
- tcpedit->rewrite_ip = true;
- if (!parse_endpoints(&tcpedit->cidrmap1, &tcpedit->cidrmap2, OPT_ARG(ENDPOINTS))) {
- tcpedit_seterr(tcpedit, "Unable to parse --endpoints=%s", OPT_ARG(ENDPOINTS));
- return -1;
- }
- }
- /* parse the tcpedit dlt args */
- rcode = tcpedit_dlt_post_args(tcpedit);
- if (rcode < 0) {
- errx(-1, "Unable to parse args: %s", tcpedit_geterr(tcpedit));
- } else if (rcode == 1) {
- warnx("%s", tcpedit_geterr(tcpedit));
- }
- return 0;
- }
|