dev: mark paths likely/unlikely
[netsniff-ng.git] / staging / cli_sequence.c
blob0a55251efe4ee9ded74184dc176e1cbb43aac703
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2010 Herbert Haas
4 *
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.
8 *
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
12 * details.
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
20 #include "mz.h"
21 #include "cli.h"
22 #include "mops.h"
23 #include "llist.h"
25 // PURPOSE: Enter sequence configuration mode
26 // either a) create new or b) edit old or c) delete old sequence
27 //
28 // # sequence MY_SEQUENCE
29 // # sequence OLD_SEQUENCE delete
30 //
31 int conf_sequence (struct cli_def *cli, const char *command, char *argv[], int argc)
33 struct mz_ll *cur;
34 char str[512];
35 int ret=0;
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);
44 return CLI_OK;
47 switch (argc) {
48 case 1:
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]);
53 if (cur==NULL) {
54 cli_print(cli, "ERROR: Cannot allocate another sequence!\n");
55 return CLI_OK;
57 } // else ENTER EXISTING (cur already points to it)
58 cli_seq = cur;
59 cli_set_configmode(cli, MZ_MODE_SEQUENCE, "config-seq");
60 break;
62 case 2: // otherwise DELETE?
63 if (mz_strcmp(argv[1], "delete", 3)==0) {
64 ret = mops_delete_sequence(argv[0]);
65 switch (ret) {
66 case 1:
67 cli_print(cli, "Sequence '%s' does not exist\n", argv[0]);
68 break;
69 case 2:
70 cli_print(cli, "Sequence '%s' is currently active! Cannot delete it.\n", argv[0]);
71 break;
72 default:
73 cli_print(cli, "Sequence '%s' deleted.\n", argv[0]);
76 break;
77 default:
78 // nothing
79 break;
81 return CLI_OK;
85 // add packet to current sequence
86 int sequence_add (struct cli_def *cli, const char *command, char *argv[], int argc)
88 struct mops *mp;
89 int ret=0;
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");
95 return CLI_OK;
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");
105 return CLI_OK;
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");
114 return CLI_OK;
118 // add a delay
119 int sequence_delay (struct cli_def *cli, const char *command, char *argv[], int argc)
121 int ret=0, ret2=0;
122 struct timespec t;
123 char str[128];
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");
129 return CLI_OK;
132 switch (argc) {
133 case 1: // only one argument, but may contain an unit (such as '314sec')
134 ret = delay_parse(&t, argv[0], NULL);
135 break;
137 case 2: // user specified two arguments such as '100 msec'
138 ret = delay_parse(&t, argv[0], argv[1]);
139 break;
140 default:
141 cli_print(cli, "Too many arguments! Expected delay value and unit, such as '10 msec'\n");
142 return CLI_OK;
145 switch (ret) {
146 case 1:
147 cli_print(cli, "Invalid unit! Use one of {nsec, usec, msec, sec, min, hours}\n");
148 return CLI_OK;
149 break;
150 case 2:
151 cli_print(cli, "Value too large! Supported range is from 0 to 999999999\n");
152 return CLI_OK;
153 break;
157 ret2 = mops_add_delay_to_sequence (cli_seq, &t);
158 if (ret2==-1) {
159 cli_print(cli, "You must add a packet first.\n");
160 return CLI_OK;
162 if (ret2==-2) {
163 cli_print(cli, "Cannot add delay (array full).\n");
164 return CLI_OK;
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);
172 return CLI_OK;
176 // remove one packet
177 int sequence_remove (struct cli_def *cli, const char *command, char *argv[], int argc)
179 int ret=0;
180 int i=0;
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");
186 return CLI_OK;
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);
193 i=1;
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");
197 return CLI_OK;
199 ret = mops_delete_packet_from_pseq (cli_seq, (int) str2int(argv[0]));
201 switch (ret) {
202 case 0:
203 if (i) cli_print(cli, "Removed all entries.\n");
204 else cli_print(cli, "Removed one entry.\n");
205 break;
206 case 1:
207 cli_print(cli, "List empty or invalid packet index.\n");
208 break;
209 case 2:
210 cli_print(cli, "Packet index too large.\n");
211 break;
214 return CLI_OK;
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];
222 struct pseq *seq;
223 int i;
225 if (strcmp(argv[argc-1],"?")==0) {
226 cli_print(cli, "Shows all packets of the current sequence.\n");
227 return CLI_OK;
230 if (argc>0) {
231 cli_print(cli, "This command has currently no arguments!\n");
232 return CLI_OK;
235 seq = (struct pseq*) cli_seq->data;
237 if (seq->count==0) {
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) {
248 name[13]=0x00;
249 strcat(name, "...");
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);
260 return CLI_OK;