dev: mark paths likely/unlikely
[netsniff-ng.git] / staging / cli_tcp.c
blob16dc5a01a2cf4a509eb635e6a660271cc1f6ca1e
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-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"
26 // NOTE: The port numbers are maintained for both TCP and UDP.
27 // See cli_udp.c.
30 int cmd_tcp_seqnr (struct cli_def *cli, const char *command, char *argv[], int argc)
32 u_int32_t txs;
33 unsigned long long int tmp;
35 if ( (strcmp(argv[argc-1],"?")==0) || (argc>3) ) {
36 cli_print(cli, "Specify the TCP sequence number (0-4294967295)\n");
37 cli_print(cli, "You may specify up to three parameters:\n");
38 cli_print(cli, " <sqnr>\r");
39 cli_print(cli, " <sqnr_start> <sqnr_stop>\r");
40 cli_print(cli, " <sqnr_start> <sqnr_stop> <sqnr_delta>\n");
41 cli_print(cli, "If a range is specified without step size 'sqnr_delta' (2nd case)\r");
42 cli_print(cli, "then sqnr_delta is per default set to one.\r");
43 cli_print(cli, "\n");
44 return CLI_OK;
47 tmp = str2lint(argv[0]);
48 if (tmp<=0xffffffff)
49 clipkt->tcp_seq = (u_int32_t) tmp;
50 else {
51 cli_print(cli, "Argument 1 must not exceed 4294967295\n");
52 return CLI_OK;
54 clipkt->tcp_seq_delta = 0;
56 if (argc>1) {
57 tmp = str2lint(argv[1]);
58 if (tmp<=0xffffffff) {
59 clipkt->tcp_seq_start = clipkt->tcp_seq;
60 clipkt->tcp_seq_stop = (u_int32_t) tmp;
61 } else {
62 cli_print(cli, "Argument 2 must not exceed 4294967295\n");
63 return CLI_OK;
65 clipkt->tcp_seq_delta = 1;
68 if (argc>2) {
69 tmp = str2lint(argv[2]);
70 if (tmp<=0xffffffff) {
71 clipkt->tcp_seq_delta = (u_int32_t) tmp;
72 } else {
73 cli_print(cli, "Argument 3 must not exceed 4294967295\n");
74 return CLI_OK;
77 if (argv[2]==0) {
78 cli_print(cli, "Note that a zero step size disables the range feature\n");
79 return CLI_OK;
83 txs = mops_tcp_complexity_sqnr (clipkt);
84 cli_print(cli, "FYI: Packet runs through %lu sequence numbers\n", (long unsigned int) txs);
86 return CLI_OK;
93 int cmd_tcp_acknr (struct cli_def *cli, const char *command, char *argv[], int argc)
95 u_int32_t txs;
96 unsigned long long int tmp;
98 if ( (strcmp(argv[argc-1],"?")==0) || (argc>3) ) {
99 cli_print(cli, "Specify the TCP acknowledgement number (0-4294967295)\n");
100 cli_print(cli, "You may specify up to three parameters:\n");
101 cli_print(cli, " <acknr>\r");
102 cli_print(cli, " <acknr_start> <acknr_stop>\r");
103 cli_print(cli, " <acknr_start> <acknr_stop> <acknr_delta>\n");
104 cli_print(cli, "If a range is specified without step size 'acknr_delta' (2nd case)\r");
105 cli_print(cli, "then acknr_delta is per default set to one.\r");
106 cli_print(cli, "\n");
107 return CLI_OK;
110 tmp = str2lint(argv[0]);
111 if (tmp<=0xffffffff)
112 clipkt->tcp_ack = (u_int32_t) tmp;
113 else {
114 cli_print(cli, "Argument 1 must not exceed 4294967295\n");
115 return CLI_OK;
117 clipkt->tcp_ack_delta = 0;
119 if (argc>1) {
120 tmp = str2lint(argv[1]);
121 if (tmp<=0xffffffff) {
122 clipkt->tcp_ack_start = clipkt->tcp_ack;
123 clipkt->tcp_ack_stop = (u_int32_t) tmp;
124 } else {
125 cli_print(cli, "Argument 2 must not exceed 4294967295\n");
126 return CLI_OK;
128 clipkt->tcp_ack_delta = 1;
131 if (argc>2) {
132 tmp = str2lint(argv[2]);
133 if (tmp<=0xffffffff) {
134 clipkt->tcp_ack_delta = (u_int32_t) tmp;
135 } else {
136 cli_print(cli, "Argument 3 must not exceed 4294967295\n");
137 return CLI_OK;
140 if (argv[2]==0) {
141 cli_print(cli, "Note that a zero step size disables the range feature\n");
142 return CLI_OK;
146 txs = mops_tcp_complexity_acknr (clipkt);
147 cli_print(cli, "FYI: Packet runs through %lu acknowledge numbers\n", (long unsigned int) txs);
150 return CLI_OK;
158 int cmd_tcp_offset (struct cli_def *cli, const char *command, char *argv[], int argc)
160 unsigned int tmp;
162 if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) )
164 cli_print(cli, "Specify the TCP offset (=header length, 0..15) \r");
165 cli_print(cli, "\n");
166 return CLI_OK;
169 tmp = (unsigned int) str2int(argv[0]);
170 if (tmp<=15)
171 clipkt->tcp_offset = (u_int8_t) tmp;
172 else
174 cli_print(cli, "The TCP offset must not exceed 15\n");
177 return CLI_OK;
183 int cmd_tcp_res (struct cli_def *cli, const char *command, char *argv[], int argc)
185 int tmp;
187 if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) )
189 cli_print(cli, "Specify the TCP reserved field in binary format (4 bits)\n");
190 cli_print(cli, "\n");
191 return CLI_OK;
194 tmp = str2bin8 (argv[0]);
195 if ((tmp==-1)||(tmp>15))
197 cli_print(cli, "Invalid binary value! Allowed range: 0000 - 1111\n");
199 else
200 clipkt->tcp_res = (u_int8_t) tmp;
202 return CLI_OK;
206 int cmd_tcp_flags (struct cli_def *cli, const char *command, char *argv[], int argc)
208 int i, j=0;
209 char str[64];
211 if (strcmp(argv[argc-1],"?")==0)
213 cli_print(cli, "Configure a combination of TCP flags at once. All mentioned \r");
214 cli_print(cli, "flags are set, while not mentioned flags remain unset.\r");
215 cli_print(cli, "Flag keywords: cwr, ece, urg, ack, psh, rst, syn, fin.\r");
216 cli_print(cli, "NOTE: The flags command alone resets all flags to zero!\n");
217 cli_print(cli, "Example:\n");
218 cli_print(cli, " mz(config-pkt-1-tcp)# flags syn fin ack \n");
219 cli_print(cli, "\n");
220 mops_tcp_flags2str (clipkt, str);
221 cli_print(cli,"Current setting is: %s\n",str);
222 return CLI_OK;
225 if (argc>8)
227 cli_print(cli, "Up to 8 arguments are allowed using the keywords:\r");
228 cli_print(cli, "cwr, ece, urg, ack, psh, rst, syn, fin.\n");
229 return CLI_OK;
232 clipkt->tcp_ctrl_CWR = 0;
233 clipkt->tcp_ctrl_ECE = 0;
234 clipkt->tcp_ctrl_URG = 0;
235 clipkt->tcp_ctrl_ACK = 0;
236 clipkt->tcp_ctrl_PSH = 0;
237 clipkt->tcp_ctrl_RST = 0;
238 clipkt->tcp_ctrl_SYN = 0;
239 clipkt->tcp_ctrl_FIN = 0;
243 for (i=0; i<argc; i++) {
244 if (mz_strcmp(argv[i], "cwr", 1)==0) {
245 clipkt->tcp_ctrl_CWR = 1;
246 j=1;
249 if (mz_strcmp(argv[i], "ece", 1)==0) {
250 clipkt->tcp_ctrl_ECE = 1;
251 j=1;
254 if (mz_strcmp(argv[i], "urg", 1)==0) {
255 clipkt->tcp_ctrl_URG = 1;
256 j=1;
259 if (mz_strcmp(argv[i], "ack", 1)==0) {
260 clipkt->tcp_ctrl_ACK = 1;
261 j=1;
264 if (mz_strcmp(argv[i], "psh", 1)==0) {
265 clipkt->tcp_ctrl_PSH = 1;
266 j=1;
269 if (mz_strcmp(argv[i], "rst", 1)==0) {
270 clipkt->tcp_ctrl_RST = 1;
271 j=1;
274 if (mz_strcmp(argv[i], "syn", 1)==0) {
275 clipkt->tcp_ctrl_SYN = 1;
276 j=1;
279 if (mz_strcmp(argv[i], "fin", 1)==0) {
280 clipkt->tcp_ctrl_FIN = 1;
281 j=1;
284 if (!j) {
285 cli_print(cli, "Unknown keyword at position %i\n", i+1);
286 return CLI_OK;
288 else { // flag matched, continue
289 j=0;
293 mops_tcp_flags2str (clipkt, str);
294 cli_print(cli,"Current setting is: %s\n",str);
296 return CLI_OK;
301 int cmd_tcp_cwr (struct cli_def *cli, const char *command, char *argv[], int argc)
303 char str[64];
305 if (strcmp(argv[argc-1],"?")==0)
307 cli_print(cli, "Set or unset the TCP Congestion Window Reduced flag (CWR)\r");
308 mops_tcp_flags2str (clipkt, str);
309 cli_print(cli,"Current setting is: %s\n",str);
310 return CLI_OK;
313 if (argc!=1)
315 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
316 return CLI_OK;
320 if (mz_strcmp(argv[0], "set", 1)==0)
321 clipkt->tcp_ctrl_CWR = 1;
322 else if (mz_strcmp(argv[0], "unset", 1)==0)
323 clipkt->tcp_ctrl_CWR = 0;
324 else
325 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
327 mops_tcp_flags2str (clipkt, str);
328 cli_print(cli,"Current setting is: %s\n",str);
330 return CLI_OK;
335 int cmd_tcp_ece (struct cli_def *cli, const char *command, char *argv[], int argc)
337 char str[64];
339 if (strcmp(argv[argc-1],"?")==0) {
340 cli_print(cli, "Set or unset the TCP ECN-Echo flag (ECE)\r");
341 mops_tcp_flags2str (clipkt, str);
342 cli_print(cli,"Current setting is: %s\n",str);
343 return CLI_OK;
346 if (argc!=1) {
347 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
348 return CLI_OK;
351 if (mz_strcmp(argv[0], "set", 1)==0)
352 clipkt->tcp_ctrl_ECE = 1;
353 else if (mz_strcmp(argv[0], "unset", 1)==0)
354 clipkt->tcp_ctrl_ECE = 0;
355 else
356 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
358 mops_tcp_flags2str (clipkt, str);
359 cli_print(cli,"Current setting is: %s\n",str);
361 return CLI_OK;
366 int cmd_tcp_urg (struct cli_def *cli, const char *command, char *argv[], int argc)
368 char str[64];
370 if (strcmp(argv[argc-1],"?")==0) {
371 cli_print(cli, "Set or unset the TCP urgent flag (URG)\r");
372 mops_tcp_flags2str (clipkt, str);
373 cli_print(cli,"Current setting is: %s\n",str);
374 return CLI_OK;
377 if (argc!=1) {
378 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
379 return CLI_OK;
382 if (mz_strcmp(argv[0], "set", 1)==0)
383 clipkt->tcp_ctrl_URG = 1;
384 else if (mz_strcmp(argv[0], "unset", 1)==0)
385 clipkt->tcp_ctrl_URG = 0;
386 else
387 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
389 mops_tcp_flags2str (clipkt, str);
390 cli_print(cli,"Current setting is: %s\n",str);
392 return CLI_OK;
398 int cmd_tcp_ack (struct cli_def *cli, const char *command, char *argv[], int argc)
400 char str[64];
402 if (strcmp(argv[argc-1],"?")==0) {
403 cli_print(cli, "Set or unset the TCP acknowledgement flag (ACK)\r");
404 mops_tcp_flags2str (clipkt, str);
405 cli_print(cli,"Current setting is: %s\n",str);
406 return CLI_OK;
409 if (argc!=1) {
410 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
411 return CLI_OK;
415 if (mz_strcmp(argv[0], "set", 1)==0)
416 clipkt->tcp_ctrl_ACK = 1;
417 else if (mz_strcmp(argv[0], "unset", 1)==0)
418 clipkt->tcp_ctrl_ACK = 0;
419 else
420 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
422 mops_tcp_flags2str (clipkt, str);
423 cli_print(cli,"Current setting is: %s\n",str);
425 return CLI_OK;
430 int cmd_tcp_psh (struct cli_def *cli, const char *command, char *argv[], int argc)
432 char str[64];
434 if (strcmp(argv[argc-1],"?")==0) {
435 cli_print(cli, "Set or unset the TCP push flag (PSH)\r");
436 mops_tcp_flags2str (clipkt, str);
437 cli_print(cli,"Current setting is: %s\n",str);
438 return CLI_OK;
441 if (argc!=1) {
442 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
443 return CLI_OK;
446 if (mz_strcmp(argv[0], "set", 1)==0)
447 clipkt->tcp_ctrl_PSH = 1;
448 else if (mz_strcmp(argv[0], "unset", 1)==0)
449 clipkt->tcp_ctrl_PSH = 0;
450 else
451 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
453 mops_tcp_flags2str (clipkt, str);
454 cli_print(cli,"Current setting is: %s\n",str);
456 return CLI_OK;
461 int cmd_tcp_rst (struct cli_def *cli, const char *command, char *argv[], int argc)
463 char str[64];
465 if (strcmp(argv[argc-1],"?")==0) {
466 cli_print(cli, "Set or unset the TCP reset flag (RST)\r");
467 mops_tcp_flags2str (clipkt, str);
468 cli_print(cli,"Current setting is: %s\n",str);
469 return CLI_OK;
472 if (argc!=1) {
473 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
474 return CLI_OK;
477 if (mz_strcmp(argv[0], "set", 1)==0)
478 clipkt->tcp_ctrl_RST = 1;
479 else if (mz_strcmp(argv[0], "unset", 1)==0)
480 clipkt->tcp_ctrl_RST = 0;
481 else
482 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
484 mops_tcp_flags2str (clipkt, str);
485 cli_print(cli,"Current setting is: %s\n",str);
487 return CLI_OK;
492 int cmd_tcp_syn (struct cli_def *cli, const char *command, char *argv[], int argc)
494 char str[64];
496 if (strcmp(argv[argc-1],"?")==0) {
497 cli_print(cli, "Set or unset the TCP synchronisation flag (SYN)\r");
498 mops_tcp_flags2str (clipkt, str);
499 cli_print(cli,"Current setting is: %s\n",str);
500 return CLI_OK;
503 if (argc!=1) {
504 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
505 return CLI_OK;
508 if (mz_strcmp(argv[0], "set", 1)==0)
509 clipkt->tcp_ctrl_SYN = 1;
510 else if (mz_strcmp(argv[0], "unset", 1)==0)
511 clipkt->tcp_ctrl_SYN = 0;
512 else
513 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
515 mops_tcp_flags2str (clipkt, str);
516 cli_print(cli,"Current setting is: %s\n",str);
518 return CLI_OK;
523 int cmd_tcp_fin (struct cli_def *cli, const char *command, char *argv[], int argc)
525 char str[64];
527 if (strcmp(argv[argc-1],"?")==0) {
528 cli_print(cli, "Set or unset the TCP finalisation flag (FIN)\r");
529 mops_tcp_flags2str (clipkt, str);
530 cli_print(cli,"Current setting is: %s\n",str);
531 return CLI_OK;
534 if (argc!=1) {
535 cli_print(cli, "Use the 'set' or 'unset' keywords.\n");
536 return CLI_OK;
539 if (mz_strcmp(argv[0], "set", 1)==0)
540 clipkt->tcp_ctrl_FIN = 1;
541 else if (mz_strcmp(argv[0], "unset", 1)==0)
542 clipkt->tcp_ctrl_FIN = 0;
543 else
544 cli_print(cli, "Unknown keyword. Use the 'set' or 'unset' keywords.\n");
546 mops_tcp_flags2str (clipkt, str);
547 cli_print(cli,"Current setting is: %s\n",str);
549 return CLI_OK;
554 int cmd_tcp_window (struct cli_def *cli, const char *command, char *argv[], int argc)
556 unsigned long int tmp;
558 if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) )
560 cli_print(cli, "Specify the TCP window size (0..65535)\r");
561 cli_print(cli, "\n");
562 return CLI_OK;
565 tmp = (unsigned long int) str2int (argv[0]);
566 if (tmp<65535)
568 clipkt->tcp_win = (u_int16_t) tmp;
570 else
572 cli_print(cli, "The TCP window size must not exceed 65535\n");
575 return CLI_OK;
580 int cmd_tcp_sum (struct cli_def *cli, const char *command, char *argv[], int argc)
582 int sum;
584 if (strncmp(argv[argc-1], "?", 2)==0)
586 cli_print(cli, "Specify the TCP checksum in hexadecimal or use the keyword 'auto'.\r");
587 cli_print(cli, "By default, the checksum is computed automatically.\n");
588 return CLI_OK;
591 if (mz_strcmp(argv[0], "auto", 2)==0)
593 clipkt->tcp_sum_false=0;
594 return CLI_OK;
597 sum = (int) xstr2int(argv[0]);
599 if (sum>0xffff)
601 cli_print(cli, "The checksum must be within range 0..ffff\n");
602 return CLI_OK;
605 clipkt->tcp_sum = (u_int16_t) sum;
606 clipkt->tcp_sum_false=1;
608 return CLI_OK;
613 int cmd_tcp_urgptr(struct cli_def *cli, const char *command, char *argv[], int argc)
616 unsigned long int tmp;
618 if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) )
620 cli_print(cli, "Specify the TCP urgent pointer (0..65535)\r");
621 cli_print(cli, "\n");
622 return CLI_OK;
625 tmp = (unsigned long int) str2int (argv[0]);
626 if (tmp<65535)
628 clipkt->tcp_urg = (u_int16_t) tmp;
630 else
632 cli_print(cli, "The TCP urgent pointer must not exceed 65535\n");
635 return CLI_OK;
640 int cmd_tcp_options (struct cli_def *cli, const char *command, char *argv[], int argc)
642 int mss=0, sack=0, scale=0;
643 u_int32_t tsval=0, tsecr=0;
645 if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) ) {
646 cli_print(cli, "Specify TCP options\n");
647 cli_print(cli, "Option parameters:\n");
648 cli_print(cli, "[ mss <0..65535> ] [sack] [tsval <0..4294967295> [tsecr <0..4294967295>]] [nop] [scale <0..14>]\n");
649 cli_print(cli, "NOTE: Only a set of default options are supported in this version\r");
650 cli_print(cli, "(20 bytes, consisting of MSS=1452 bytes, SACK permitted, a Timestamp,\r");
651 cli_print(cli, "NOP, and Window Scale 5)\r");
652 cli_print(cli, "\n");
653 return CLI_OK;
656 if (clipkt->tcp_option_used) {
657 // turn off
658 clipkt->tcp_option_used = 0;
659 } else {
660 // turn on
661 mops_tcp_add_option (clipkt, mss, sack, scale, tsval, tsecr);
663 cli_print(cli, "NOTE: Only a set of default options are supported in this version\r");
664 cli_print(cli, "(20 bytes, consisting of MSS=1452 bytes, SACK permitted, a Timestamp,\r");
665 cli_print(cli, "NOP, and Window Scale 5)\n");
668 return CLI_OK;
673 int cmd_tcp_end(struct cli_def *cli, const char *command, char *argv[], int argc)
675 char prompt[16];
676 sprintf(prompt, "pkt-%i",clipkt->id);
677 cli_set_configmode(cli, MZ_MODE_PACKET, prompt);
678 return CLI_OK;