summaryrefslogtreecommitdiff
path: root/staging/cli_bpdu.c
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-05-13 13:53:27 +0200
committerDaniel Borkmann <dborkman@redhat.com>2013-05-13 15:10:16 +0200
commitd0009856814c13d13770db5aadd7b2fabf947776 (patch)
tree6d18a94439f27f3c2685f05c57435116673f40cc /staging/cli_bpdu.c
parent2b100f7515dbd01032967c2d1b81d2f8d63bf9b5 (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_bpdu.c')
-rw-r--r--staging/cli_bpdu.c750
1 files changed, 750 insertions, 0 deletions
diff --git a/staging/cli_bpdu.c b/staging/cli_bpdu.c
new file mode 100644
index 0000000..8cc2a69
--- /dev/null
+++ b/staging/cli_bpdu.c
@@ -0,0 +1,750 @@
+/*
+ * Mausezahn - A fast versatile traffic generator
+ * Copyright (C) 2008-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"
+
+
+
+int cmd_bpdu_id (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ char str[256];
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1) )
+ {
+ mz_def16("0x0000", pd->id, str);
+ cli_print(cli, "Specify the BPDU identifier (0..65535)\r");
+ cli_print(cli, "%s\n", str);
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (mops_pdesc_2byte(&pd->id, argv[0], 0, 0, 65535))
+ {
+ cli_print(cli, "Specify a value between 0 and 65535\n");
+ }
+
+ return CLI_OK;
+}
+
+
+int cmd_bpdu_version (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1) )
+ {
+ cli_print(cli, "Specify the BPDU version (0..255)\r");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (mops_pdesc_1byte(&pd->version, argv[0], 0, 0, 255))
+ {
+ cli_print(cli, "Specify a value between 0 and 255\n");
+ }
+
+
+ return CLI_OK;
+}
+
+
+
+int cmd_bpdu_type (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1) ) {
+ cli_print(cli, "Specify the BPDU type, either via keyword or number (0..255)\n");
+ cli_print(cli, "Keywords:\n");
+ cli_print(cli, " conf .... Configuration BPDU\r");
+ cli_print(cli, " tcn ..... Topology Change BPDU\r");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (mz_strcmp(argv[0], "configuration", 1)==0) {
+ pd->bpdu_type = 0x00;
+ } else if (mz_strcmp(argv[0], "tcn", 1)==0) {
+ pd->bpdu_type = 0x80;
+ } else if (mops_pdesc_1byte(&pd->bpdu_type, argv[0], 0, 0, 255)) {
+ cli_print(cli, "Specify a value between 0 and 255\n");
+ }
+
+ return CLI_OK;
+}
+
+
+int cmd_bpdu_flags (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ int i;
+ char str[16];
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>8) )
+ {
+ cli_print(cli, "Specify the BPDU flags by keyword.\r");
+ cli_print(cli, "Note that not-mentioned flags will be set to zero!\n");
+ cli_print(cli, "General keywords:\n");
+ cli_print(cli, " ack .... Topology Change Acknowledgement\r");
+ cli_print(cli, " tcn .... Topology Change Notification\r");
+ cli_print(cli, "\r");
+ cli_print(cli, "RSTP-specific keywords:\n");
+ cli_print(cli, " agree .... Agreement\r");
+ cli_print(cli, " prop .... Proposal\r");
+ cli_print(cli, " fwd .... Forward State\r");
+ cli_print(cli, " learn .... Learn State\r");
+ cli_print(cli, "\r");
+ cli_print(cli, " Port roles:\n");
+ cli_print(cli, " unknown .... Unknown\r");
+ cli_print(cli, " alt .... Alternate or Backup\r");
+ cli_print(cli, " root .... Root\r");
+ cli_print(cli, " desg .... Designated\r");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ // 7 6 5 4 3 2 1 0
+ // tcnack agree fwd learn X X proposal TCN
+ // where XX is 00 unknown
+ // 01 alternate or backup
+ // 10 root
+ // 11 designated
+
+ if (argc)
+ {
+ pd->flags = 0x00; // always reset to zero (= normal Configuration BPDU)
+
+ for (i=0; i<argc; i++)
+ {
+ if (mz_strcmp(argv[i], "ack", 2)==0) pd->flags |= 0x80;
+ else
+ if (mz_strcmp(argv[i], "tcn", 2)==0) pd->flags |= 0x01;
+ else
+ if (mz_strcmp(argv[i], "agree", 2)==0) pd->flags |= 0x40;
+ else
+ if (mz_strcmp(argv[i], "fwd", 2)==0) pd->flags |= 0x20;
+ else
+ if (mz_strcmp(argv[i], "learn", 2)==0) pd->flags |= 0x10;
+ else
+ if (mz_strcmp(argv[i], "proposal", 2)==0) pd->flags |= 0x02;
+ else
+ if (mz_strcmp(argv[i], "unknown", 2)==0) pd->flags &= 0xf3;
+ else
+ if (mz_strcmp(argv[i], "alt", 2)==0) { pd->flags &= 0xf7; pd->flags |= 0x04; }
+ else
+ if (mz_strcmp(argv[i], "root", 2)==0) { pd->flags &= 0xfb; pd->flags |= 0x08; }
+ else
+ if (mz_strcmp(argv[i], "desg", 2)==0) pd->flags |= 0x0c;
+ }
+ // Feedback
+ char2bits(pd->flags, str);
+ cli_print(cli, "Flags: %s\n", str);
+ }
+ else
+ {
+ cli_print(cli, "No flags configured (use '?')\n");
+ }
+
+ return CLI_OK;
+}
+
+
+
+
+
+
+
+
+
+int cmd_bpdu_rid (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ char p[64], e[64];
+ int pri, esi, r;
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) )
+ {
+ cli_print(cli, "Specify the BPDU root identifier, using the following format:\n");
+ cli_print(cli, " <priority>[:ext-sys-id] [interface | MAC-Address]\n");
+ cli_print(cli, " <priority> ....... priority (0-15)\r");
+ cli_print(cli, " <ext-sys-id> ....... extended system-id (0-4095)\n");
+ cli_print(cli, "Optionally the MAC address of the root bridge can be given, either directly as arbitrary\r");
+ cli_print(cli, "address (format: XX:XX:XX:XX:XX:XX) or by referring to an existing interface.\n");
+ cli_print(cli, "Per default the MAC address of the default interface is used and a priority of zero.\n");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0) {
+ cli_print(cli, "Please specify at least the priority (use ?)\n");
+ return CLI_OK;
+ }
+
+ mz_tok(argv[0], ":", 2, p, e);
+
+ pri = (int) str2int(p);
+ if (e!=NULL)
+ esi = (int) str2int(e);
+ else
+ esi = 0;
+
+ if (argc==1) // no MAC given
+ {
+ r = mops_create_bpdu_bid (clipkt, pri, esi, NULL, 1); // 1 means RID (0 means BID)
+ }
+ else
+ r = mops_create_bpdu_bid (clipkt, pri, esi, argv[1], 1); // 1 means RID (0 means BID)
+
+
+ // Check return value
+ switch (r)
+ {
+ case 1:
+ cli_print(cli, "Priority must be within 0..15\n");
+ return CLI_OK;
+ break;
+ case 2:
+ cli_print(cli, "Extended System-ID must be within 0..4095\n");
+ return CLI_OK;
+ break;
+ case 3:
+ cli_print(cli, "Invalid MAC address or interface\n");
+ return CLI_OK;
+ break;
+ case 4:
+ cli_print(cli, "Invalid format - use ?\n");
+ return CLI_OK;
+ break;
+ }
+
+
+
+ //---------
+ // Verify:
+ bs2str(pd->root_id, p, 8);
+ cli_print(cli, "RID is now %s\n", p);
+ // -------
+ //
+ return CLI_OK;
+}
+
+
+
+
+
+
+int cmd_bpdu_pc (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ unsigned long long int i;
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) )
+ {
+ cli_print(cli, "Specify the BPDU root path cost (0..4294967295)\r");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0)
+ {
+ cli_print(cli, "Missing argument (use ?)\n");
+ return CLI_OK;
+ }
+
+ i = str2lint (argv[0]);
+ if (i>0xffffffff)
+ {
+ cli_print(cli, "Range exceeded (0..4294967295)\n");
+ }
+ else
+ pd->root_pc = (u_int32_t) i;
+
+ return CLI_OK;
+}
+
+
+
+
+int cmd_bpdu_bid (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ char p[64], e[64];
+ int pri, esi, r;
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) )
+ {
+ cli_print(cli, "Specify the BPDU bridge identifier, using the following format:\n");
+ cli_print(cli, " <priority>[:ext-sys-id] [interface | MAC-Address]\n");
+ cli_print(cli, " <priority> ....... priority (0-15)\r");
+ cli_print(cli, " <ext-sys-id> ....... extended system-id (0-4095)\n");
+ cli_print(cli, "Optionally the MAC address of the root bridge can be given, either directly as arbitrary\r");
+ cli_print(cli, "address (format: XX:XX:XX:XX:XX:XX) or by referring to an existing interface.\n");
+ cli_print(cli, "Per default the MAC address of the default interface is used and a priority of zero.\n");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+
+ if (argc==0)
+ {
+ cli_print(cli, "Please specify at least the priority (use ?)\n");
+ return CLI_OK;
+ }
+
+ mz_tok(argv[0], ":", 2, p, e);
+
+ pri = (int) str2int(p);
+ if (e!=NULL)
+ esi = (int) str2int(e);
+ else
+ esi = 0;
+
+ if (argc==1) // no MAC given
+ {
+ r = mops_create_bpdu_bid (clipkt, pri, esi, NULL, 0); // 0 means BID (1 means RID)
+ }
+ else
+ r = mops_create_bpdu_bid (clipkt, pri, esi, argv[1], 0); // 0 means BID (1 means RID)
+
+
+ // Check return value
+ switch (r)
+ {
+ case 1:
+ cli_print(cli, "Priority must be within 0..15\n");
+ return CLI_OK;
+ break;
+ case 2:
+ cli_print(cli, "Extended System-ID must be within 0..4095\n");
+ return CLI_OK;
+ break;
+ case 3:
+ cli_print(cli, "Invalid MAC address or interface\n");
+ return CLI_OK;
+ break;
+ case 4:
+ cli_print(cli, "Invalid format - use ?\n");
+ return CLI_OK;
+ break;
+ }
+
+
+
+ //---------
+ // Verify:
+ bs2str(pd->bridge_id, p, 8);
+ cli_print(cli, "BID is now %s\n", p);
+ // -------
+ //
+ return CLI_OK;
+}
+
+
+
+
+
+int cmd_bpdu_pid (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ u_int32_t i;
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) )
+ {
+ cli_print(cli, "Specify the BPDU port identifier (0..65535)\r");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0)
+ {
+ cli_print(cli, "Missing argument (use ?)\n");
+ return CLI_OK;
+ }
+
+ i = (u_int32_t) str2int (argv[0]);
+
+ if (i>0xffff)
+ {
+ cli_print(cli, "The port identifier must be within 0..65535\n");
+ return CLI_OK;
+ }
+
+ pd->port_id = (u_int16_t) i;
+
+ return CLI_OK;
+}
+
+//
+//
+// NOTE:
+//
+// All timers are multiples of 1/256 sec. Thus times range from 0 to 255 seconds.
+//
+//
+
+int cmd_bpdu_age (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ u_int32_t i;
+ char str[256];
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) )
+ {
+ mz_def16("0", pd->message_age, str);
+
+ cli_print(cli, "Specify the message age:\n");
+ cli_print(cli, " - either in seconds (0..256) e. g. '14 sec'\r");
+ cli_print(cli, " - or as multiples of 1/256 seconds (0..65535)\n");
+ cli_print(cli, "%s\n", str);
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0)
+ {
+ cli_print(cli, "Missing argument (use ?)\n");
+ return CLI_OK;
+ }
+
+ i = (u_int32_t) str2int (argv[0]);
+
+ if (argc==1) // absolute
+ {
+ if (i>0xffff)
+ cli_print(cli, "The age must be within 0..65535\n");
+ else
+ pd->message_age = (u_int16_t) i;
+ }
+ else if (mz_strcmp(argv[1], "seconds", 1)==0) // in seconds
+ {
+ if (i>256)
+ cli_print(cli, "The age must be within 0..256 seconds\n");
+ else
+ {
+ if (i==256)
+ i = 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996
+ else
+ i = i * 256;
+
+ pd->message_age = (u_int16_t) i;
+ }
+
+ }
+ else
+ cli_print(cli, "Invalid argument\n");
+
+ return CLI_OK;
+
+}
+
+
+
+
+
+
+
+int cmd_bpdu_maxage (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ u_int32_t i;
+ char str[256];
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) )
+ {
+ mz_def16("20 seconds", pd->max_age, str);
+
+ cli_print(cli, "Specify the maximum message age:\n");
+ cli_print(cli, " - either in seconds (0..256) e. g. '20 sec'\r");
+ cli_print(cli, " - or as multiples of 1/256 seconds (0..65535)\n");
+ cli_print(cli, "%s\n", str);
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0)
+ {
+ cli_print(cli, "Missing argument (use ?)\n");
+ return CLI_OK;
+ }
+
+ i = (u_int32_t) str2int (argv[0]);
+
+ if (argc==1) // absolute
+ {
+ if (i>0xffff)
+ cli_print(cli, "The max age must be within 0..65535\n");
+ else
+ pd->max_age = (u_int16_t) i;
+ }
+ else if (mz_strcmp(argv[1], "seconds", 1)==0) // in seconds
+ {
+ if (i>256)
+ cli_print(cli, "The max age must be within 0..256 seconds\n");
+ else
+ {
+ if (i==256)
+ i = 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996
+ else
+ i = i * 256;
+
+ pd->max_age = (u_int16_t) i;
+ }
+
+ }
+ else
+ cli_print(cli, "Invalid argument\n");
+
+ return CLI_OK;
+
+}
+
+
+
+
+
+int cmd_bpdu_hello (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ u_int32_t i;
+ char str[256];
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) )
+ {
+ mz_def16("2 seconds", pd->hello_time, str);
+
+ cli_print(cli, "Specify the hello interval:\n");
+ cli_print(cli, " - either in seconds (0..256) e. g. '2 sec'\r");
+ cli_print(cli, " - or as multiples of 1/256 seconds (0..65535)\n");
+ cli_print(cli, "%s\n", str); cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0)
+ {
+ cli_print(cli, "Missing argument (use ?)\n");
+ return CLI_OK;
+ }
+
+
+ i = (u_int32_t) str2int (argv[0]);
+
+ if (argc==1) // absolute
+ {
+ if (i>0xffff)
+ cli_print(cli, "The hello interval must be within 0..65535\n");
+ else
+ pd->hello_time = (u_int16_t) i;
+ }
+ else if (mz_strcmp(argv[1], "seconds", 1)==0) // in seconds
+ {
+ if (i>256)
+ cli_print(cli, "The hello interval must be within 0..256 seconds\n");
+ else
+ {
+ if (i==256)
+ i = 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996
+ else
+ i = i * 256;
+
+ pd->hello_time = (u_int16_t) i;
+ }
+
+ }
+ else
+ cli_print(cli, "Invalid argument\n");
+
+ return CLI_OK;
+
+}
+
+int cmd_bpdu_fwd (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+ u_int32_t i;
+ char str[256];
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) )
+ {
+ mz_def16("15 seconds", pd->f_delay, str);
+
+ cli_print(cli, "Specify the forward delay:\n");
+ cli_print(cli, " - either in seconds (0..256) e. g. '15 sec'\r");
+ cli_print(cli, " - or as multiples of 1/256 seconds (0..65535)\n");
+ cli_print(cli, "%s\n", str);
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0)
+ {
+ cli_print(cli, "Missing argument (use ?)\n");
+ return CLI_OK;
+ }
+
+
+ i = (u_int32_t) str2int (argv[0]);
+
+ if (argc==1) // absolute
+ {
+ if (i>0xffff)
+ cli_print(cli, "The forward delay must be within 0..65535\n");
+ else
+ pd->f_delay = (u_int16_t) i;
+ }
+ else if (mz_strcmp(argv[1], "seconds", 1)==0) // in seconds
+ {
+ if (i>256)
+ cli_print(cli, "The forward delay must be within 0..256 seconds\n");
+ else
+ {
+ if (i==256)
+ i = 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996
+ else
+ i = i * 256;
+
+ pd->f_delay = (u_int16_t) i;
+ }
+
+ }
+ else
+ cli_print(cli, "Invalid argument\n");
+
+ return CLI_OK;
+
+}
+
+
+
+int cmd_bpdu_mode (struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ struct mops_ext_bpdu * pd = clipkt->p_desc;
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) )
+ {
+ cli_print(cli, "Specify the BPDU mode using the keywords:\n");
+ cli_print(cli, " stp ...... IEEE 802.1d (traditional CST)\r");
+ cli_print(cli, " rstp ...... IEEE 802.1w (Rapid STP)\r");
+ cli_print(cli, " mstp ...... IEEE 802.1s (Multiple STP)\r");
+ cli_print(cli, " pvst ...... Cisco Per-VLAN STP\r");
+ cli_print(cli, " rpvst ...... Cisco Per-VLAN RSTP\r");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0)
+ {
+ cli_print(cli, "Missing argument (use ?)\n");
+ return CLI_OK;
+ }
+
+
+ if (mz_strcmp(argv[0], "stp", 1)==0)
+ {
+ pd->version=0;
+ pd->rstp=0;
+ pd->pvst=0;
+ pd->mstp=0;
+ }
+ else if (mz_strcmp(argv[0], "rstp", 2)==0)
+ {
+ pd->version=2;
+ pd->rstp=1;
+ pd->mstp=0;
+ }
+ else if (mz_strcmp(argv[0], "mstp", 1)==0)
+ {
+ pd->version=3;
+ pd->mstp=1;
+ }
+ else if (mz_strcmp(argv[0], "pvst", 1)==0)
+ {
+ pd->version=0;
+ pd->pvst=1;
+ pd->rstp=0;
+ pd->mstp=0;
+ }
+ else if (mz_strcmp(argv[0], "rpvst", 2)==0)
+ {
+ pd->version=2;
+ pd->rstp=1;
+ pd->pvst=1;
+ pd->mstp=0;
+ }
+
+
+ // TODO: also change version to 2 if RSTP, 0 if legacy
+
+
+ return CLI_OK;
+}
+
+
+
+
+int cmd_bpdu_vlan(struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ u_int32_t i;
+
+ if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) )
+ {
+ cli_print(cli, "Specify the VLAN number for PVST+ messages (0..4095)\n");
+ cli_print(cli, "\n");
+ return CLI_OK;
+ }
+
+ if (argc==0)
+ {
+ cli_print(cli, "Missing argument (use ?)\n");
+ return CLI_OK;
+ }
+
+ i = (u_int32_t) str2int(argv[0]);
+
+ if (i>65535)
+ {
+ cli_print(cli, "VLAN number is definitely too large! (0..65535 at maximum)\n");
+ return CLI_OK;
+ }
+
+ if (i>4095)
+ {
+ cli_print(cli, "Warning: Invalid VLAN number (0..4095) - but let's try it...\n");
+ }
+
+ mops_create_bpdu_trailer(clipkt, (u_int16_t) i);
+
+ return CLI_OK;
+}
+
+
+
+int cmd_bpdu_end(struct cli_def *cli, const char *command, char *argv[], int argc)
+{
+ char prompt[16];
+ sprintf(prompt, "pkt-%i",clipkt->id);
+ cli_set_configmode(cli, MZ_MODE_PACKET, prompt);
+ return CLI_OK;
+}
+