2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2010 Herbert Haas
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
25 // PURPOSE: Enter sequence configuration mode
26 // either a) create new or b) edit old or c) delete old sequence
28 // # sequence MY_SEQUENCE
29 // # sequence OLD_SEQUENCE delete
31 int conf_sequence (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
37 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
<1) || (argc
>2)) {
39 cli_print(cli
, "Configure a sequence of packets.\n");
40 cli_print(cli
, "ARGUMENTS: <sequence_name> [delete]\n");
42 cli_print(cli
, "Current list of packet sequences:\n");
43 while (mops_dump_sequence(str
)) cli_print(cli
, "%s\r", str
);
49 cur
= mz_ll_search_name (packet_sequences
, argv
[0]);
50 if (cur
==NULL
) { // create NEW sequence
51 cli_print(cli
, "Sequence does not exist; creating new sequence named '%s'\n", argv
[0]);
52 cur
= mops_create_sequence(argv
[0]);
54 cli_print(cli
, "ERROR: Cannot allocate another sequence!\n");
57 } // else ENTER EXISTING (cur already points to it)
59 cli_set_configmode(cli
, MZ_MODE_SEQUENCE
, "config-seq");
62 case 2: // otherwise DELETE?
63 if (mz_strcmp(argv
[1], "delete", 3)==0) {
64 ret
= mops_delete_sequence(argv
[0]);
67 cli_print(cli
, "Sequence '%s' does not exist\n", argv
[0]);
70 cli_print(cli
, "Sequence '%s' is currently active! Cannot delete it.\n", argv
[0]);
73 cli_print(cli
, "Sequence '%s' deleted.\n", argv
[0]);
85 // add packet to current sequence
86 int sequence_add (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
91 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) ) {
93 cli_print(cli
, "Add a packet to the current sequence.\n");
94 cli_print(cli
, "ARGUMENT: <packet name> OR <packet-identifier>\n");
98 // first assume argument is a name
99 mp
= mops_search_name (mp_head
, argv
[0]);
100 if (mp
==NULL
) { // but packet name does not exist
101 if (mz_strisnum(argv
[0])!=0) // arg is really a number?
102 mp
= mops_search_id (mp_head
, (int) str2int(argv
[0]));
103 if (mp
==NULL
) { // also packet ID not found
104 cli_print(cli
, "Packet does not exist!\n");
109 // packet found, so add to current sequence
110 ret
= mops_add_packet_to_sequence (cli_seq
, mp
);
111 if (ret
==1) cli_print(cli
, "Cannot add packet (unknown error, maybe report this)!\n");
112 if (ret
==-1) cli_print(cli
, "Cannot add packet: sequence already full!\n");
113 if (ret
==-2) cli_print(cli
, "Cannot add packet with infinite count!\n");
119 int sequence_delay (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
125 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
<1) || (argc
>2)) {
126 cli_print(cli
, "Add a delay to the current sequence.\n");
127 cli_print(cli
, "ARGUMENTS: <delay> [hour | min | sec | msec | usec | nsec]\n");
128 cli_print(cli
, "The default unit is milliseconds (i. e. when no unit is given).\n");
133 case 1: // only one argument, but may contain an unit (such as '314sec')
134 ret
= delay_parse(&t
, argv
[0], NULL
);
137 case 2: // user specified two arguments such as '100 msec'
138 ret
= delay_parse(&t
, argv
[0], argv
[1]);
141 cli_print(cli
, "Too many arguments! Expected delay value and unit, such as '10 msec'\n");
147 cli_print(cli
, "Invalid unit! Use one of {nsec, usec, msec, sec, min, hours}\n");
151 cli_print(cli
, "Value too large! Supported range is from 0 to 999999999\n");
157 ret2
= mops_add_delay_to_sequence (cli_seq
, &t
);
159 cli_print(cli
, "You must add a packet first.\n");
163 cli_print(cli
, "Cannot add delay (array full).\n");
167 sprintf(str
, "Delay set to %lu sec and %lu nsec",
168 ((struct pseq
*) cli_seq
->data
)->gap
[ret2
].tv_sec
,
169 ((struct pseq
*) cli_seq
->data
)->gap
[ret2
].tv_nsec
);
170 cli_print(cli
, "%s\n", str
);
177 int sequence_remove (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
182 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1)) {
183 cli_print(cli
, "Remove a packet (and any associated pause configuration) from the current sequence.\n");
184 cli_print(cli
, "ARGUMENT: <sequence-list-index> | last | all\n");
185 cli_print(cli
, "FYI: Use the 'show' command to see the current packet list with indexes.\n");
189 if (mz_strcmp(argv
[0], "last", 1)==0) {
190 ret
= mops_delete_packet_from_pseq (cli_seq
, -1);
191 } else if (mz_strcmp(argv
[0], "all", 1)==0) {
192 ret
= mops_delete_all_packets_from_pseq (cli_seq
);
194 } else { // index number given
195 if (mz_strisnum(argv
[0])==0) {
196 cli_print(cli
, "Invalid parameter. Please specify a packet index number or 'last'\n");
199 ret
= mops_delete_packet_from_pseq (cli_seq
, (int) str2int(argv
[0]));
203 if (i
) cli_print(cli
, "Removed all entries.\n");
204 else cli_print(cli
, "Removed one entry.\n");
207 cli_print(cli
, "List empty or invalid packet index.\n");
210 cli_print(cli
, "Packet index too large.\n");
218 // show packet list of that sequence
219 int sequence_show (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
221 char str
[512], name
[32], layers
[16], proto
[16];
225 if (strcmp(argv
[argc
-1],"?")==0) {
226 cli_print(cli
, "Shows all packets of the current sequence.\n");
231 cli_print(cli
, "This command has currently no arguments!\n");
235 seq
= (struct pseq
*) cli_seq
->data
;
238 cli_print(cli
, "Current sequence '%s' has no entries.\n", cli_seq
->name
);
240 else { // show all packets in this sequence
241 cli_print(cli
, "%i sequence(s) defined.\r", packet_sequences
->refcount
-1); // total info
242 snprintf(str
,512, "Current sequence '%s' has %i entries:", cli_seq
->name
, seq
->count
); // num entries here
243 cli_print(cli
, "%s\n", str
);
244 cli_print(cli
, "Nr PId PktName Layers Protocol Device");
245 for (i
=0; i
<seq
->count
; i
++) {
246 strncpy (name
, seq
->packet
[i
]->packet_name
, 13); // only show first 13 chars
247 if (strnlen(seq
->packet
[i
]->packet_name
, MAX_MOPS_PACKET_NAME_LEN
)>13) {
251 mops_get_proto_info(seq
->packet
[i
], layers
, proto
);
252 snprintf(str
,512, "%2i %4i %-16s %s %-8s %-6s", i
+1, seq
->packet
[i
]->id
, name
, layers
, proto
, seq
->packet
[i
]->device
);
253 cli_print(cli
, "%s\r", str
);
254 if ((seq
->gap
[i
].tv_sec
!=0) || (seq
->gap
[i
].tv_nsec
!=0)) { // gap also defined?
255 timespec2str(&seq
->gap
[i
], str
);
256 cli_print(cli
, " \\___ %s pause ___/\r", str
);