2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-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
27 int cmd_bpdu_id (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
29 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
32 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) )
34 mz_def16("0x0000", pd
->id
, str
);
35 cli_print(cli
, "Specify the BPDU identifier (0..65535)\r");
36 cli_print(cli
, "%s\n", str
);
41 if (mops_pdesc_2byte(&pd
->id
, argv
[0], 0, 0, 65535))
43 cli_print(cli
, "Specify a value between 0 and 65535\n");
50 int cmd_bpdu_version (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
52 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
54 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) )
56 cli_print(cli
, "Specify the BPDU version (0..255)\r");
61 if (mops_pdesc_1byte(&pd
->version
, argv
[0], 0, 0, 255))
63 cli_print(cli
, "Specify a value between 0 and 255\n");
72 int cmd_bpdu_type (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
74 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
76 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) ) {
77 cli_print(cli
, "Specify the BPDU type, either via keyword or number (0..255)\n");
78 cli_print(cli
, "Keywords:\n");
79 cli_print(cli
, " conf .... Configuration BPDU\r");
80 cli_print(cli
, " tcn ..... Topology Change BPDU\r");
85 if (mz_strcmp(argv
[0], "configuration", 1)==0) {
87 } else if (mz_strcmp(argv
[0], "tcn", 1)==0) {
89 } else if (mops_pdesc_1byte(&pd
->bpdu_type
, argv
[0], 0, 0, 255)) {
90 cli_print(cli
, "Specify a value between 0 and 255\n");
97 int cmd_bpdu_flags (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
99 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
103 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>8) )
105 cli_print(cli
, "Specify the BPDU flags by keyword.\r");
106 cli_print(cli
, "Note that not-mentioned flags will be set to zero!\n");
107 cli_print(cli
, "General keywords:\n");
108 cli_print(cli
, " ack .... Topology Change Acknowledgement\r");
109 cli_print(cli
, " tcn .... Topology Change Notification\r");
110 cli_print(cli
, "\r");
111 cli_print(cli
, "RSTP-specific keywords:\n");
112 cli_print(cli
, " agree .... Agreement\r");
113 cli_print(cli
, " prop .... Proposal\r");
114 cli_print(cli
, " fwd .... Forward State\r");
115 cli_print(cli
, " learn .... Learn State\r");
116 cli_print(cli
, "\r");
117 cli_print(cli
, " Port roles:\n");
118 cli_print(cli
, " unknown .... Unknown\r");
119 cli_print(cli
, " alt .... Alternate or Backup\r");
120 cli_print(cli
, " root .... Root\r");
121 cli_print(cli
, " desg .... Designated\r");
122 cli_print(cli
, "\n");
127 // tcnack agree fwd learn X X proposal TCN
128 // where XX is 00 unknown
129 // 01 alternate or backup
135 pd
->flags
= 0x00; // always reset to zero (= normal Configuration BPDU)
137 for (i
=0; i
<argc
; i
++)
139 if (mz_strcmp(argv
[i
], "ack", 2)==0) pd
->flags
|= 0x80;
141 if (mz_strcmp(argv
[i
], "tcn", 2)==0) pd
->flags
|= 0x01;
143 if (mz_strcmp(argv
[i
], "agree", 2)==0) pd
->flags
|= 0x40;
145 if (mz_strcmp(argv
[i
], "fwd", 2)==0) pd
->flags
|= 0x20;
147 if (mz_strcmp(argv
[i
], "learn", 2)==0) pd
->flags
|= 0x10;
149 if (mz_strcmp(argv
[i
], "proposal", 2)==0) pd
->flags
|= 0x02;
151 if (mz_strcmp(argv
[i
], "unknown", 2)==0) pd
->flags
&= 0xf3;
153 if (mz_strcmp(argv
[i
], "alt", 2)==0) { pd
->flags
&= 0xf7; pd
->flags
|= 0x04; }
155 if (mz_strcmp(argv
[i
], "root", 2)==0) { pd
->flags
&= 0xfb; pd
->flags
|= 0x08; }
157 if (mz_strcmp(argv
[i
], "desg", 2)==0) pd
->flags
|= 0x0c;
160 char2bits(pd
->flags
, str
);
161 cli_print(cli
, "Flags: %s\n", str
);
165 cli_print(cli
, "No flags configured (use '?')\n");
179 int cmd_bpdu_rid (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
182 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
186 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>2) )
188 cli_print(cli
, "Specify the BPDU root identifier, using the following format:\n");
189 cli_print(cli
, " <priority>[:ext-sys-id] [interface | MAC-Address]\n");
190 cli_print(cli
, " <priority> ....... priority (0-15)\r");
191 cli_print(cli
, " <ext-sys-id> ....... extended system-id (0-4095)\n");
192 cli_print(cli
, "Optionally the MAC address of the root bridge can be given, either directly as arbitrary\r");
193 cli_print(cli
, "address (format: XX:XX:XX:XX:XX:XX) or by referring to an existing interface.\n");
194 cli_print(cli
, "Per default the MAC address of the default interface is used and a priority of zero.\n");
195 cli_print(cli
, "\n");
200 cli_print(cli
, "Please specify at least the priority (use ?)\n");
204 mz_tok(argv
[0], ":", 2, p
, e
);
206 pri
= (int) str2int(p
);
208 esi
= (int) str2int(e
);
212 if (argc
==1) // no MAC given
214 r
= mops_create_bpdu_bid (clipkt
, pri
, esi
, NULL
, 1); // 1 means RID (0 means BID)
217 r
= mops_create_bpdu_bid (clipkt
, pri
, esi
, argv
[1], 1); // 1 means RID (0 means BID)
220 // Check return value
224 cli_print(cli
, "Priority must be within 0..15\n");
228 cli_print(cli
, "Extended System-ID must be within 0..4095\n");
232 cli_print(cli
, "Invalid MAC address or interface\n");
236 cli_print(cli
, "Invalid format - use ?\n");
245 bs2str(pd
->root_id
, p
, 8);
246 cli_print(cli
, "RID is now %s\n", p
);
257 int cmd_bpdu_pc (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
259 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
260 unsigned long long int i
;
262 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>1) )
264 cli_print(cli
, "Specify the BPDU root path cost (0..4294967295)\r");
265 cli_print(cli
, "\n");
271 cli_print(cli
, "Missing argument (use ?)\n");
275 i
= str2lint (argv
[0]);
278 cli_print(cli
, "Range exceeded (0..4294967295)\n");
281 pd
->root_pc
= (u_int32_t
) i
;
289 int cmd_bpdu_bid (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
292 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
296 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>2) )
298 cli_print(cli
, "Specify the BPDU bridge identifier, using the following format:\n");
299 cli_print(cli
, " <priority>[:ext-sys-id] [interface | MAC-Address]\n");
300 cli_print(cli
, " <priority> ....... priority (0-15)\r");
301 cli_print(cli
, " <ext-sys-id> ....... extended system-id (0-4095)\n");
302 cli_print(cli
, "Optionally the MAC address of the root bridge can be given, either directly as arbitrary\r");
303 cli_print(cli
, "address (format: XX:XX:XX:XX:XX:XX) or by referring to an existing interface.\n");
304 cli_print(cli
, "Per default the MAC address of the default interface is used and a priority of zero.\n");
305 cli_print(cli
, "\n");
312 cli_print(cli
, "Please specify at least the priority (use ?)\n");
316 mz_tok(argv
[0], ":", 2, p
, e
);
318 pri
= (int) str2int(p
);
320 esi
= (int) str2int(e
);
324 if (argc
==1) // no MAC given
326 r
= mops_create_bpdu_bid (clipkt
, pri
, esi
, NULL
, 0); // 0 means BID (1 means RID)
329 r
= mops_create_bpdu_bid (clipkt
, pri
, esi
, argv
[1], 0); // 0 means BID (1 means RID)
332 // Check return value
336 cli_print(cli
, "Priority must be within 0..15\n");
340 cli_print(cli
, "Extended System-ID must be within 0..4095\n");
344 cli_print(cli
, "Invalid MAC address or interface\n");
348 cli_print(cli
, "Invalid format - use ?\n");
357 bs2str(pd
->bridge_id
, p
, 8);
358 cli_print(cli
, "BID is now %s\n", p
);
368 int cmd_bpdu_pid (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
370 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
373 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>1) )
375 cli_print(cli
, "Specify the BPDU port identifier (0..65535)\r");
376 cli_print(cli
, "\n");
382 cli_print(cli
, "Missing argument (use ?)\n");
386 i
= (u_int32_t
) str2int (argv
[0]);
390 cli_print(cli
, "The port identifier must be within 0..65535\n");
394 pd
->port_id
= (u_int16_t
) i
;
403 // All timers are multiples of 1/256 sec. Thus times range from 0 to 255 seconds.
407 int cmd_bpdu_age (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
409 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
413 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>2) )
415 mz_def16("0", pd
->message_age
, str
);
417 cli_print(cli
, "Specify the message age:\n");
418 cli_print(cli
, " - either in seconds (0..256) e. g. '14 sec'\r");
419 cli_print(cli
, " - or as multiples of 1/256 seconds (0..65535)\n");
420 cli_print(cli
, "%s\n", str
);
421 cli_print(cli
, "\n");
427 cli_print(cli
, "Missing argument (use ?)\n");
431 i
= (u_int32_t
) str2int (argv
[0]);
433 if (argc
==1) // absolute
436 cli_print(cli
, "The age must be within 0..65535\n");
438 pd
->message_age
= (u_int16_t
) i
;
440 else if (mz_strcmp(argv
[1], "seconds", 1)==0) // in seconds
443 cli_print(cli
, "The age must be within 0..256 seconds\n");
447 i
= 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996
451 pd
->message_age
= (u_int16_t
) i
;
456 cli_print(cli
, "Invalid argument\n");
468 int cmd_bpdu_maxage (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
470 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
474 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>2) )
476 mz_def16("20 seconds", pd
->max_age
, str
);
478 cli_print(cli
, "Specify the maximum message age:\n");
479 cli_print(cli
, " - either in seconds (0..256) e. g. '20 sec'\r");
480 cli_print(cli
, " - or as multiples of 1/256 seconds (0..65535)\n");
481 cli_print(cli
, "%s\n", str
);
482 cli_print(cli
, "\n");
488 cli_print(cli
, "Missing argument (use ?)\n");
492 i
= (u_int32_t
) str2int (argv
[0]);
494 if (argc
==1) // absolute
497 cli_print(cli
, "The max age must be within 0..65535\n");
499 pd
->max_age
= (u_int16_t
) i
;
501 else if (mz_strcmp(argv
[1], "seconds", 1)==0) // in seconds
504 cli_print(cli
, "The max age must be within 0..256 seconds\n");
508 i
= 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996
512 pd
->max_age
= (u_int16_t
) i
;
517 cli_print(cli
, "Invalid argument\n");
527 int cmd_bpdu_hello (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
529 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
533 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>2) )
535 mz_def16("2 seconds", pd
->hello_time
, str
);
537 cli_print(cli
, "Specify the hello interval:\n");
538 cli_print(cli
, " - either in seconds (0..256) e. g. '2 sec'\r");
539 cli_print(cli
, " - or as multiples of 1/256 seconds (0..65535)\n");
540 cli_print(cli
, "%s\n", str
); cli_print(cli
, "\n");
546 cli_print(cli
, "Missing argument (use ?)\n");
551 i
= (u_int32_t
) str2int (argv
[0]);
553 if (argc
==1) // absolute
556 cli_print(cli
, "The hello interval must be within 0..65535\n");
558 pd
->hello_time
= (u_int16_t
) i
;
560 else if (mz_strcmp(argv
[1], "seconds", 1)==0) // in seconds
563 cli_print(cli
, "The hello interval must be within 0..256 seconds\n");
567 i
= 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996
571 pd
->hello_time
= (u_int16_t
) i
;
576 cli_print(cli
, "Invalid argument\n");
582 int cmd_bpdu_fwd (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
584 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
588 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>2) )
590 mz_def16("15 seconds", pd
->f_delay
, str
);
592 cli_print(cli
, "Specify the forward delay:\n");
593 cli_print(cli
, " - either in seconds (0..256) e. g. '15 sec'\r");
594 cli_print(cli
, " - or as multiples of 1/256 seconds (0..65535)\n");
595 cli_print(cli
, "%s\n", str
);
596 cli_print(cli
, "\n");
602 cli_print(cli
, "Missing argument (use ?)\n");
607 i
= (u_int32_t
) str2int (argv
[0]);
609 if (argc
==1) // absolute
612 cli_print(cli
, "The forward delay must be within 0..65535\n");
614 pd
->f_delay
= (u_int16_t
) i
;
616 else if (mz_strcmp(argv
[1], "seconds", 1)==0) // in seconds
619 cli_print(cli
, "The forward delay must be within 0..256 seconds\n");
623 i
= 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996
627 pd
->f_delay
= (u_int16_t
) i
;
632 cli_print(cli
, "Invalid argument\n");
640 int cmd_bpdu_mode (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
642 struct mops_ext_bpdu
* pd
= clipkt
->p_desc
;
644 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>1) )
646 cli_print(cli
, "Specify the BPDU mode using the keywords:\n");
647 cli_print(cli
, " stp ...... IEEE 802.1d (traditional CST)\r");
648 cli_print(cli
, " rstp ...... IEEE 802.1w (Rapid STP)\r");
649 cli_print(cli
, " mstp ...... IEEE 802.1s (Multiple STP)\r");
650 cli_print(cli
, " pvst ...... Cisco Per-VLAN STP\r");
651 cli_print(cli
, " rpvst ...... Cisco Per-VLAN RSTP\r");
652 cli_print(cli
, "\n");
658 cli_print(cli
, "Missing argument (use ?)\n");
663 if (mz_strcmp(argv
[0], "stp", 1)==0)
670 else if (mz_strcmp(argv
[0], "rstp", 2)==0)
676 else if (mz_strcmp(argv
[0], "mstp", 1)==0)
681 else if (mz_strcmp(argv
[0], "pvst", 1)==0)
688 else if (mz_strcmp(argv
[0], "rpvst", 2)==0)
697 // TODO: also change version to 2 if RSTP, 0 if legacy
706 int cmd_bpdu_vlan(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
710 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
>1) )
712 cli_print(cli
, "Specify the VLAN number for PVST+ messages (0..4095)\n");
713 cli_print(cli
, "\n");
719 cli_print(cli
, "Missing argument (use ?)\n");
723 i
= (u_int32_t
) str2int(argv
[0]);
727 cli_print(cli
, "VLAN number is definitely too large! (0..65535 at maximum)\n");
733 cli_print(cli
, "Warning: Invalid VLAN number (0..4095) - but let's try it...\n");
736 mops_create_bpdu_trailer(clipkt
, (u_int16_t
) i
);
743 int cmd_bpdu_end(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
746 sprintf(prompt
, "pkt-%i",clipkt
->id
);
747 cli_set_configmode(cli
, MZ_MODE_PACKET
, prompt
);