diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2013-05-13 13:53:27 +0200 |
---|---|---|
committer | Daniel Borkmann <dborkman@redhat.com> | 2013-05-13 15:10:16 +0200 |
commit | d0009856814c13d13770db5aadd7b2fabf947776 (patch) | |
tree | 6d18a94439f27f3c2685f05c57435116673f40cc /staging/cli_sequence.c | |
parent | 2b100f7515dbd01032967c2d1b81d2f8d63bf9b5 (diff) |
staging: add mausezahn staging directory
After some back and forth, we decided that it is easier to maintain
mausezahn in a staging directory until it is fully reworked and
cleaned up to be ready to be fully integrated. This way, it is better
than having it in a separate branch, and we can also accept patches
from outside more easily. Also, while at it, fix up some function
mismatches with libcli.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'staging/cli_sequence.c')
-rw-r--r-- | staging/cli_sequence.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/staging/cli_sequence.c b/staging/cli_sequence.c new file mode 100644 index 0000000..0a55251 --- /dev/null +++ b/staging/cli_sequence.c @@ -0,0 +1,263 @@ +/* + * Mausezahn - A fast versatile traffic generator + * Copyright (C) 2010 Herbert Haas + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + * + * This program 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 + * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html + * +*/ + + +#include "mz.h" +#include "cli.h" +#include "mops.h" +#include "llist.h" + +// PURPOSE: Enter sequence configuration mode +// either a) create new or b) edit old or c) delete old sequence +// +// # sequence MY_SEQUENCE +// # sequence OLD_SEQUENCE delete +// +int conf_sequence (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mz_ll *cur; + char str[512]; + int ret=0; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc<1) || (argc>2)) { + + cli_print(cli, "Configure a sequence of packets.\n"); + cli_print(cli, "ARGUMENTS: <sequence_name> [delete]\n"); + + cli_print(cli, "Current list of packet sequences:\n"); + while (mops_dump_sequence(str)) cli_print(cli, "%s\r", str); + return CLI_OK; + } + + switch (argc) { + case 1: + cur = mz_ll_search_name (packet_sequences, argv[0]); + if (cur==NULL) { // create NEW sequence + cli_print(cli, "Sequence does not exist; creating new sequence named '%s'\n", argv[0]); + cur = mops_create_sequence(argv[0]); + if (cur==NULL) { + cli_print(cli, "ERROR: Cannot allocate another sequence!\n"); + return CLI_OK; + } + } // else ENTER EXISTING (cur already points to it) + cli_seq = cur; + cli_set_configmode(cli, MZ_MODE_SEQUENCE, "config-seq"); + break; + + case 2: // otherwise DELETE? + if (mz_strcmp(argv[1], "delete", 3)==0) { + ret = mops_delete_sequence(argv[0]); + switch (ret) { + case 1: + cli_print(cli, "Sequence '%s' does not exist\n", argv[0]); + break; + case 2: + cli_print(cli, "Sequence '%s' is currently active! Cannot delete it.\n", argv[0]); + break; + default: + cli_print(cli, "Sequence '%s' deleted.\n", argv[0]); + } + } + break; + default: + // nothing + break; + } + return CLI_OK; +} + + +// add packet to current sequence +int sequence_add (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops *mp; + int ret=0; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1) ) { + + cli_print(cli, "Add a packet to the current sequence.\n"); + cli_print(cli, "ARGUMENT: <packet name> OR <packet-identifier>\n"); + return CLI_OK; + } + + // first assume argument is a name + mp = mops_search_name (mp_head, argv[0]); + if (mp==NULL) { // but packet name does not exist + if (mz_strisnum(argv[0])!=0) // arg is really a number? + mp = mops_search_id (mp_head, (int) str2int(argv[0])); + if (mp==NULL) { // also packet ID not found + cli_print(cli, "Packet does not exist!\n"); + return CLI_OK; + } + } + + // packet found, so add to current sequence + ret = mops_add_packet_to_sequence (cli_seq, mp); + if (ret==1) cli_print(cli, "Cannot add packet (unknown error, maybe report this)!\n"); + if (ret==-1) cli_print(cli, "Cannot add packet: sequence already full!\n"); + if (ret==-2) cli_print(cli, "Cannot add packet with infinite count!\n"); + return CLI_OK; +} + + +// add a delay +int sequence_delay (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + int ret=0, ret2=0; + struct timespec t; + char str[128]; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc<1) || (argc>2)) { + cli_print(cli, "Add a delay to the current sequence.\n"); + cli_print(cli, "ARGUMENTS: <delay> [hour | min | sec | msec | usec | nsec]\n"); + cli_print(cli, "The default unit is milliseconds (i. e. when no unit is given).\n"); + return CLI_OK; + } + + switch (argc) { + case 1: // only one argument, but may contain an unit (such as '314sec') + ret = delay_parse(&t, argv[0], NULL); + break; + + case 2: // user specified two arguments such as '100 msec' + ret = delay_parse(&t, argv[0], argv[1]); + break; + default: + cli_print(cli, "Too many arguments! Expected delay value and unit, such as '10 msec'\n"); + return CLI_OK; + } + + switch (ret) { + case 1: + cli_print(cli, "Invalid unit! Use one of {nsec, usec, msec, sec, min, hours}\n"); + return CLI_OK; + break; + case 2: + cli_print(cli, "Value too large! Supported range is from 0 to 999999999\n"); + return CLI_OK; + break; + } + + + ret2 = mops_add_delay_to_sequence (cli_seq, &t); + if (ret2==-1) { + cli_print(cli, "You must add a packet first.\n"); + return CLI_OK; + } + if (ret2==-2) { + cli_print(cli, "Cannot add delay (array full).\n"); + return CLI_OK; + } + + sprintf(str, "Delay set to %lu sec and %lu nsec", + ((struct pseq*) cli_seq->data)->gap[ret2].tv_sec, + ((struct pseq*) cli_seq->data)->gap[ret2].tv_nsec); + cli_print(cli, "%s\n", str); + + return CLI_OK; +} + + +// remove one packet +int sequence_remove (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + int ret=0; + int i=0; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Remove a packet (and any associated pause configuration) from the current sequence.\n"); + cli_print(cli, "ARGUMENT: <sequence-list-index> | last | all\n"); + cli_print(cli, "FYI: Use the 'show' command to see the current packet list with indexes.\n"); + return CLI_OK; + } + + if (mz_strcmp(argv[0], "last", 1)==0) { + ret = mops_delete_packet_from_pseq (cli_seq, -1); + } else if (mz_strcmp(argv[0], "all", 1)==0) { + ret = mops_delete_all_packets_from_pseq (cli_seq); + i=1; + } else { // index number given + if (mz_strisnum(argv[0])==0) { + cli_print(cli, "Invalid parameter. Please specify a packet index number or 'last'\n"); + return CLI_OK; + } + ret = mops_delete_packet_from_pseq (cli_seq, (int) str2int(argv[0])); + } + switch (ret) { + case 0: + if (i) cli_print(cli, "Removed all entries.\n"); + else cli_print(cli, "Removed one entry.\n"); + break; + case 1: + cli_print(cli, "List empty or invalid packet index.\n"); + break; + case 2: + cli_print(cli, "Packet index too large.\n"); + break; + + } + return CLI_OK; +} + + +// show packet list of that sequence +int sequence_show (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + char str[512], name[32], layers[16], proto[16]; + struct pseq *seq; + int i; + + if (strcmp(argv[argc-1],"?")==0) { + cli_print(cli, "Shows all packets of the current sequence.\n"); + return CLI_OK; + } + + if (argc>0) { + cli_print(cli, "This command has currently no arguments!\n"); + return CLI_OK; + } + + seq = (struct pseq*) cli_seq->data; + + if (seq->count==0) { + cli_print(cli, "Current sequence '%s' has no entries.\n", cli_seq->name); + } + else { // show all packets in this sequence + cli_print(cli, "%i sequence(s) defined.\r", packet_sequences->refcount-1); // total info + snprintf(str,512, "Current sequence '%s' has %i entries:", cli_seq->name, seq->count); // num entries here + cli_print(cli, "%s\n", str); + cli_print(cli, "Nr PId PktName Layers Protocol Device"); + for (i=0; i<seq->count; i++) { + strncpy (name, seq->packet[i]->packet_name, 13); // only show first 13 chars + if (strnlen(seq->packet[i]->packet_name, MAX_MOPS_PACKET_NAME_LEN)>13) { + name[13]=0x00; + strcat(name, "..."); + } + mops_get_proto_info(seq->packet[i], layers, proto); + snprintf(str,512, "%2i %4i %-16s %s %-8s %-6s", i+1, seq->packet[i]->id, name, layers, proto, seq->packet[i]->device); + cli_print(cli, "%s\r", str); + if ((seq->gap[i].tv_sec !=0) || (seq->gap[i].tv_nsec !=0)) { // gap also defined? + timespec2str(&seq->gap[i], str); + cli_print(cli, " \\___ %s pause ___/\r", str); + } + } + } + return CLI_OK; +} + + |