stp_cli.c
上传用户:allwinjm
上传日期:2021-08-29
资源大小:99k
文件大小:22k
源码类别:

Internet/IE编程

开发平台:

Unix_Linux

  1. /************************************************************************ 
  2.  * RSTP library - Rapid Spanning Tree (802.1t, 802.1w) 
  3.  * Copyright (C) 2001-2003 Optical Access 
  4.  * Author: Alex Rozin 
  5.  * 
  6.  * This file is part of RSTP library. 
  7.  * 
  8.  * RSTP library is free software; you can redistribute it and/or modify it 
  9.  * under the terms of the GNU Lesser General Public License as published by the 
  10.  * Free Software Foundation; version 2.1 
  11.  * 
  12.  * RSTP library is distributed in the hope that it will be useful, but 
  13.  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser 
  15.  * General Public License for more details. 
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public License 
  18.  * along with RSTP library; see the file COPYING.  If not, write to the Free 
  19.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
  20.  * 02111-1307, USA. 
  21.  **********************************************************************/
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <sys/types.h>
  27. #include <netinet/in.h>
  28. #include <arpa/inet.h>
  29. #include <unistd.h>
  30. #include "cli.h"
  31. #include "stp_cli.h"
  32. #include "bitmap.h"
  33. #include "uid_stp.h"
  34. #include "stp_in.h"
  35. #include "stp_to.h"
  36. int I_am_a_stupid_hub = 0;
  37. static void
  38. print_bridge_id (UID_BRIDGE_ID_T *bridge_id, unsigned char cr)
  39. {
  40.   printf("%04lX-%02x%02x%02x%02x%02x%02x",
  41.                   (unsigned long) bridge_id->prio,
  42.                   (unsigned char) bridge_id->addr[0],
  43.                   (unsigned char) bridge_id->addr[1],
  44.                   (unsigned char) bridge_id->addr[2],
  45.                   (unsigned char) bridge_id->addr[3],
  46.                   (unsigned char) bridge_id->addr[4],
  47.                   (unsigned char) bridge_id->addr[5]);
  48.   if (cr)
  49.         printf("n");
  50. }
  51. static char *
  52. stp_state2str (RSTP_PORT_STATE stp_port_state, int detail)
  53. {
  54.   if (detail) {
  55.     switch (stp_port_state) {
  56.       case UID_PORT_DISABLED:   return "Disabled";
  57.       case UID_PORT_DISCARDING: return "Discarding";
  58.       case UID_PORT_LEARNING:   return "Learning";
  59.       case UID_PORT_FORWARDING: return "Forwarding";
  60.       case UID_PORT_NON_STP:    return "NoStp";
  61.       default:                  return "Unknown";
  62.     }
  63.   }
  64.   switch (stp_port_state) {
  65.     case UID_PORT_DISABLED:     return "Dis";
  66.     case UID_PORT_DISCARDING:   return "Blk";
  67.     case UID_PORT_LEARNING:     return "Lrn";
  68.     case UID_PORT_FORWARDING:   return "Fwd";
  69.     case UID_PORT_NON_STP:      return "Non";
  70.     default:                    return "Unk";
  71.   }
  72. }
  73. static void CLI_out_port_id (int port, unsigned char cr)
  74. {
  75.   printf ("%s", STP_OUT_get_port_name (port));
  76.   if (cr)
  77.         printf("n");
  78. }
  79. static int cli_enable (int argc, char** argv)
  80. {
  81.   UID_STP_CFG_T uid_cfg;
  82.   int rc;
  83.   uid_cfg.field_mask = BR_CFG_STATE;
  84.   uid_cfg.stp_enabled = STP_ENABLED;
  85.   rc = STP_IN_stpm_set_cfg (0, NULL, &uid_cfg);
  86.   if (rc) {
  87.     printf ("can't enable: %sn", STP_IN_get_error_explanation (rc));
  88.   } else
  89.     I_am_a_stupid_hub = 0;
  90.   return 0;
  91. }
  92. static int cli_disable (int argc, char** argv)
  93. {
  94.   UID_STP_CFG_T uid_cfg;
  95.   int rc;
  96.   uid_cfg.field_mask = BR_CFG_STATE;
  97.   uid_cfg.stp_enabled = STP_DISABLED;
  98.   rc = STP_IN_stpm_set_cfg (0, NULL, &uid_cfg);
  99.   if (rc) {
  100.     printf ("can't disable: %sn", STP_IN_get_error_explanation (rc));
  101.   } else
  102.     I_am_a_stupid_hub = 1;
  103.   return 0;
  104. }
  105. static int cli_br_get_cfg (int argc, char** argv)
  106. {
  107.   UID_STP_STATE_T uid_state;
  108.   UID_STP_CFG_T   uid_cfg;
  109.   int             rc;
  110.   rc = STP_IN_stpm_get_state (0, &uid_state);
  111.   if (rc) {
  112.     printf ("can't get rstp bridge state: %sn", STP_IN_get_error_explanation (rc));
  113.     return 0;
  114.   }
  115.   rc = STP_IN_stpm_get_cfg (0, &uid_cfg);
  116.   if (rc) {
  117.     printf ("can't get rstp bridge configuration: %sn", STP_IN_get_error_explanation (rc));
  118.     return 0;
  119.   }
  120. #if 0
  121.   printf("Interface:       %-7s (tag:%d)    State: ",
  122.     uid_state.vlan_name, (int) uid_state.vlan_id);
  123. #else
  124.   printf("Bridge:          %-7s               State:",
  125.          uid_state.vlan_name);
  126. #endif
  127.   switch (uid_state.stp_enabled) {
  128.     case STP_ENABLED:  printf("enabledn"); break;
  129.     case STP_DISABLED: printf("disabledn");break;
  130.     default:           printf("unknownn"); return 0;
  131.   }
  132.   printf("BridgeId:        "); print_bridge_id (&uid_state.bridge_id, 0);
  133.   printf("     Bridge Proirity: %lu (0x%lX)n",
  134.     (unsigned long) uid_state.bridge_id.prio, (unsigned long) uid_state.bridge_id.prio);
  135.   if (uid_cfg.force_version < 2)
  136.     printf("Force Version:   stpn");
  137.   printf("Designated Root: "); print_bridge_id (&uid_state.designated_root, 1);
  138.   if (uid_state.root_port) {
  139.     printf("Root Port:       %04lx (", (unsigned long) uid_state.root_port);
  140.         CLI_out_port_id (uid_state.root_port & 0xfff, False);
  141.     printf("), Root Cost:     %-lun", (unsigned long) uid_state.root_path_cost);
  142.   } else {
  143.     printf("Root Port:       nonen");
  144.   }
  145.   if (uid_state.Topo_Change)
  146.     printf ("Topology Change Count: %lun", uid_state.Topo_Change_Count);
  147.   else
  148.     printf ("Time Since Topology Change: %lun", uid_state.timeSince_Topo_Change);
  149.   printf ("Max Age:         %2d   Bridge Max Age:       %-2dn",
  150.     (int) uid_state.max_age, (int) uid_cfg.max_age);
  151.   printf ("Hello Time:      %2d   Bridge Hello Time:    %-2dn",
  152.     (int) uid_state.hello_time, (int) uid_cfg.hello_time);
  153.   printf ("Forward Delay:   %2d   Bridge Forward Delay: %-2dn",
  154.     (int) uid_state.forward_delay, (int) uid_cfg.forward_delay);
  155.   printf ("Hold Time:       %2dn", (int) uid_cfg.hold_time);
  156.   return 0;
  157. }
  158. static void
  159. show_rstp_port (BITMAP_T* ports_bitmap, int detail)
  160. {
  161.   UID_STP_STATE_T      uid_state;
  162.   UID_STP_PORT_STATE_T uid_port;
  163.   UID_STP_PORT_CFG_T   uid_cfg;
  164.   int                  port_index;
  165.   int         rc;
  166.   
  167.   rc = STP_IN_stpm_get_state (0, &uid_state);
  168.   if (rc) {
  169.     printf ("can't get rstp bridge state: %sn", STP_IN_get_error_explanation (rc));
  170.   } else if (! detail) {
  171.     printf (" BridgeId: "); print_bridge_id (&uid_state.bridge_id, 0);
  172.     printf ("  RootId: "); print_bridge_id (&uid_state.designated_root, 1);
  173.   }
  174.   for (port_index = 0; port_index <= NUMBER_OF_PORTS; port_index++) {
  175.     if (! BitmapGetBit(ports_bitmap, port_index - 1)) continue;
  176.     uid_port.port_no = port_index;
  177.     rc = STP_IN_port_get_state (0, &uid_port);
  178.     if (rc) {
  179.       printf ("can't get rstp port state: %sn", STP_IN_get_error_explanation (rc));
  180.       continue;
  181.     }
  182.     memset (&uid_cfg, 0, sizeof (UID_STP_PORT_CFG_T));
  183.     rc = STP_IN_port_get_cfg (0, uid_port.port_no, &uid_cfg);
  184.     if (rc) {
  185.       printf ("can't get rstp port config: %sn", STP_IN_get_error_explanation (rc));
  186.       continue;
  187.     }
  188.     if (detail) {
  189.       printf("Stp Port "); CLI_out_port_id (port_index, False);
  190. #if 0
  191.       printf(": PortId: %04lx in vlan '%s' with tag %d:n",
  192.         (unsigned long) uid_port.port_id, uid_state.vlan_name, (int) uid_state.vlan_id);
  193. #else
  194.       printf(": PortId: %04lx in Bridge '%s':n",
  195.         (unsigned long) uid_port.port_id, uid_state.vlan_name);
  196. #endif
  197.       printf ("Priority:          %-dn", (int) (uid_port.port_id >> 8));
  198.       printf ("State:             %-16s", stp_state2str (uid_port.state, 1));
  199.       printf ("       Uptime: %-9lun", uid_port.uptime);
  200.       printf ("PortPathCost:      admin: ");
  201.       if (ADMIN_PORT_PATH_COST_AUTO == uid_cfg.admin_port_path_cost)
  202.         printf ("%-9s", "Auto");
  203.       else
  204.         printf ("%-9lu", uid_cfg.admin_port_path_cost);
  205.       printf ("       oper: %-9lun", uid_port.oper_port_path_cost);
  206.       printf ("Point2Point:       admin: ");
  207.       switch (uid_cfg.admin_point2point) {
  208.         case P2P_FORCE_TRUE:
  209.           printf ("%-9s", "ForceYes");
  210.           break;
  211.         case P2P_FORCE_FALSE:
  212.           printf ("%-9s", "ForceNo");
  213.           break;
  214.         case P2P_AUTO:
  215.           printf ("%-9s", "Auto");
  216.           break;
  217.       }
  218.       printf ("       oper: %-9sn", uid_port.oper_point2point ? "Yes" : "No");
  219.       printf ("Edge:              admin: %-9s       oper: %-9sn",
  220.               uid_cfg.admin_edge ? "Y" : "N",
  221.               uid_port.oper_edge ? "Y" : "N");
  222.       printf ("Partner:                                  oper: %-9sn",
  223.               uid_port.oper_stp_neigb ? "Slow" : "Rapid");
  224.         
  225.       if (' ' != uid_port.role) {
  226.         if ('-' != uid_port.role) {
  227.           printf("PathCost:          %-lun", (unsigned long) (uid_port.path_cost));
  228.           printf("Designated Root:   "); print_bridge_id (&uid_port.designated_root, 1);
  229.           printf("Designated Cost:   %-ldn", (unsigned long) uid_port.designated_cost);
  230.           printf("Designated Bridge: "); print_bridge_id (&uid_port.designated_bridge, 1);
  231.           printf("Designated Port:   %-4lxnr", (unsigned long) uid_port.designated_port);
  232.         }
  233.         printf("Role:              ");
  234.         switch (uid_port.role) {
  235.           case 'A': printf("Alternaten"); break;
  236.           case 'B': printf("Backupn"); break;
  237.           case 'R': printf("Rootn"); break;
  238.           case 'D': printf("Designatedn"); break;
  239.           case '-': printf("NonStpn"); break;
  240.           default:  printf("Unknown(%c)n", uid_port.role); break;
  241.         }
  242.         if ('R' == uid_port.role || 'D' == uid_port.role) {
  243.           /* printf("Tc:                %c  ", uid_port.tc ? 'Y' : 'n'); */
  244.           printf("TcAck:             %c  ",
  245.                uid_port.top_change_ack ?  'Y' : 'N');
  246.           printf("TcWhile:       %3dn", (int) uid_port.tcWhile);
  247.         }
  248.       }
  249.       if (UID_PORT_DISABLED == uid_port.state || '-' == uid_port.role) {
  250. #if 0
  251.         printf("helloWhen:       %3d  ", (int) uid_port.helloWhen);
  252.         printf("lnkWhile:      %3dn", (int) uid_port.lnkWhile);
  253.         printf("fdWhile:         %3dn", (int) uid_port.fdWhile);
  254. #endif
  255.       } else if ('-' != uid_port.role) {
  256.         printf("fdWhile:         %3d  ", (int) uid_port.fdWhile);
  257.         printf("rcvdInfoWhile: %3dn", (int) uid_port.rcvdInfoWhile);
  258.         printf("rbWhile:         %3d  ", (int) uid_port.rbWhile);
  259.         printf("rrWhile:       %3dn", (int) uid_port.rrWhile);
  260. #if 0
  261.         printf("mdelayWhile:     %3d  ", (int) uid_port.mdelayWhile);
  262.         printf("lnkWhile:      %3dn", (int) uid_port.lnkWhile);
  263.         printf("helloWhen:       %3d  ", (int) uid_port.helloWhen);
  264.         printf("txCount:       %3dn", (int) uid_port.txCount);
  265. #endif
  266.       }
  267.       printf("RSTP BPDU rx:      %lun", (unsigned long) uid_port.rx_rstp_bpdu_cnt);
  268.       printf("CONFIG BPDU rx:    %lun", (unsigned long) uid_port.rx_cfg_bpdu_cnt);
  269.       printf("TCN BPDU rx:       %lun", (unsigned long) uid_port.rx_tcn_bpdu_cnt);
  270.     } else {
  271.       printf("%c%c%c  ",
  272.         (uid_port.oper_point2point) ? ' ' : '*',
  273.         (uid_port.oper_edge) ?        'E' : ' ',
  274.         (uid_port.oper_stp_neigb) ?   's' : ' ');
  275.       CLI_out_port_id (port_index, False);
  276.       printf(" %04lx %3s ", (unsigned long) uid_port.port_id,
  277.                stp_state2str (uid_port.state, 0));
  278.       printf (" ");
  279.       print_bridge_id (&uid_port.designated_root, 0);
  280.       printf(" ");
  281.       print_bridge_id (&uid_port.designated_bridge, 0);
  282.       printf(" %4lx %c", (unsigned long) uid_port.designated_port,  uid_port.role);
  283.       printf ("n");
  284.     }
  285.   }
  286. }
  287. static int cli_pr_get_cfg (int argc, char** argv)
  288. {
  289.   BITMAP_T        ports_bitmap;
  290.   int             port_index;
  291.   char        detail;
  292.   if ('a' == argv[1][0]) {
  293.     BitmapSetAllBits(&ports_bitmap);
  294.     detail = 0;
  295.   } else {
  296.     port_index = strtoul(argv[1], 0, 10);
  297.     BitmapClear(&ports_bitmap);
  298.     BitmapSetBit(&ports_bitmap, port_index - 1);
  299.     detail = 1;
  300.   }
  301.   show_rstp_port (&ports_bitmap, detail);
  302.   return 0;
  303. }
  304. static void
  305. set_bridge_cfg_value (unsigned long value, unsigned long val_mask)
  306. {
  307.   UID_STP_CFG_T uid_cfg;
  308.   char*         val_name;
  309.   int           rc;
  310.   uid_cfg.field_mask = val_mask;
  311.   switch (val_mask) {
  312.     case BR_CFG_STATE:
  313.       uid_cfg.stp_enabled = value;
  314.       val_name = "state";
  315.       break;
  316.     case BR_CFG_PRIO:
  317.       uid_cfg.bridge_priority = value;
  318.       val_name = "priority";
  319.       break;
  320.     case BR_CFG_AGE:
  321.       uid_cfg.max_age = value;
  322.       val_name = "max_age";
  323.       break;
  324.     case BR_CFG_HELLO:
  325.       uid_cfg.hello_time = value;
  326.       val_name = "hello_time";
  327.       break;
  328.     case BR_CFG_DELAY:
  329.       uid_cfg.forward_delay = value;
  330.       val_name = "forward_delay";
  331.       break;
  332.     case BR_CFG_FORCE_VER:
  333.       uid_cfg.force_version = value;
  334.       val_name = "force_version";
  335.       break;
  336.     case BR_CFG_AGE_MODE:
  337.     case BR_CFG_AGE_TIME:
  338.     default: printf ("Invalid value mask 0X%lxn", val_mask);  return;
  339.       break;
  340.   }
  341.   rc = STP_IN_stpm_set_cfg (0, NULL, &uid_cfg);
  342.   if (0 != rc) {
  343.     printf ("Can't change rstp bridge %s:%s", val_name, STP_IN_get_error_explanation (rc));
  344.   } else {
  345.     printf ("Changed rstp bridge %sn", val_name);
  346.   }
  347. }
  348. static int cli_br_prio (int argc, char** argv)
  349. {
  350.   long      br_prio = 32768L;
  351.   if (strlen (argv[1]) > 2 &&
  352.       (! strncmp (argv[1], "0x", 2) || ! strncmp (argv[1], "0X", 2))) {
  353.     br_prio = strtoul(argv[1] + 2, 0, 16);
  354.   } else {
  355.     br_prio = strtoul(argv[1], 0, 10);
  356.   }
  357.   if (! br_prio) {
  358.     printf ("Warning: newPriority=0, are you sure ?n");
  359.   }
  360.   set_bridge_cfg_value (br_prio, BR_CFG_PRIO);
  361.   return 0;
  362. }
  363. static int cli_br_maxage (int argc, char** argv)
  364. {
  365.   long      value = 20L;
  366.   value = strtoul(argv[1], 0, 10);
  367.   set_bridge_cfg_value (value, BR_CFG_AGE);
  368.   return 0;
  369. }
  370. static int cli_br_fdelay (int argc, char** argv)
  371. {
  372.   long      value = 15L;
  373.   value = strtoul(argv[1], 0, 10);
  374.   set_bridge_cfg_value (value, BR_CFG_DELAY);
  375.   return 0;
  376. }
  377. static int cli_br_fvers (int argc, char** argv)
  378. {
  379.   long      value = 2L;
  380.   switch (argv[1][0]) {
  381.       case '0':
  382.       case '1':
  383.       case 'f':
  384.       case 'F':
  385.         value = 0L;
  386.         printf ("Accepted 'force_slow'n");
  387.         break;
  388.       case '2':
  389.       case 'r':
  390.       case 'R':
  391.         printf ("Accepted 'rapid'n");
  392.         value = 2L;
  393.         break;
  394.       default:
  395.         printf ("Invalid argument '%s'n", argv[1]);
  396.         return 0;
  397.   }
  398.   
  399.   set_bridge_cfg_value (value, BR_CFG_FORCE_VER);
  400.   return 0;
  401. }
  402. static void
  403. set_rstp_port_cfg_value (int port_index,
  404.                          unsigned long value,
  405.                          unsigned long val_mask)
  406. {
  407.   UID_STP_PORT_CFG_T uid_cfg;
  408.   int           rc, detail;
  409.   char          *val_name;
  410.   if (port_index > 0) {
  411.     BitmapClear(&uid_cfg.port_bmp);
  412.     BitmapSetBit(&uid_cfg.port_bmp, port_index - 1);
  413.     detail = 1;
  414.   } else {
  415.     BitmapSetAllBits(&uid_cfg.port_bmp);
  416.     detail = 0;
  417.   }
  418.   uid_cfg.field_mask = val_mask;
  419.   switch (val_mask) {
  420.     case PT_CFG_MCHECK:
  421.       val_name = "mcheck";
  422.       break;
  423.     case PT_CFG_COST:
  424.       uid_cfg.admin_port_path_cost = value;
  425.       val_name = "path cost";
  426.       break;
  427.     case PT_CFG_PRIO:
  428.       uid_cfg.port_priority = value;
  429.       val_name = "priority";
  430.       break;
  431.     case PT_CFG_P2P:
  432.       uid_cfg.admin_point2point = (ADMIN_P2P_T) value;
  433.       val_name = "p2p flag";
  434.       break;
  435.     case PT_CFG_EDGE:
  436.       uid_cfg.admin_edge = value;
  437.       val_name = "adminEdge";
  438.       break;
  439.     case PT_CFG_NON_STP:
  440.       uid_cfg.admin_non_stp = value;
  441.       val_name = "adminNonStp";
  442.       break;
  443. #ifdef STP_DBG
  444.     case PT_CFG_DBG_SKIP_TX:
  445.       uid_cfg.skip_tx = value;
  446.       val_name = "skip tx";
  447.       break;
  448.     case PT_CFG_DBG_SKIP_RX:
  449.       uid_cfg.skip_rx = value;
  450.       val_name = "skip rx";
  451.       break;
  452. #endif
  453.     case PT_CFG_STATE:
  454.     default:
  455.       printf ("Invalid value mask 0X%lxn", val_mask);
  456.       return;
  457.   }
  458.   rc = STP_IN_set_port_cfg (0, &uid_cfg);
  459.   if (0 != rc) {
  460.     printf ("can't change rstp port[s] %s: %sn",
  461.            val_name, STP_IN_get_error_explanation (rc));
  462.   } else {
  463.     printf ("changed rstp port[s] %sn", val_name);
  464.   }
  465.   /* show_rstp_port (&uid_cfg.port_bmp, 0); */
  466. }
  467. static int cli_prt_prio (int argc, char** argv)
  468. {
  469.   int port_index = 0;
  470.   unsigned long value = 128;
  471.   if ('a' != argv[1][0])
  472.     port_index = strtoul(argv[1], 0, 10);
  473.   value = strtoul(argv[2], 0, 10);
  474.   set_rstp_port_cfg_value (port_index, value, PT_CFG_PRIO);
  475.   return 0;
  476. }
  477. static int cli_prt_pcost (int argc, char** argv)
  478. {
  479.   int port_index = 0;
  480.   unsigned long value = 0;
  481.   if ('a' != argv[1][0])
  482.     port_index = strtoul(argv[1], 0, 10);
  483.   value = strtoul(argv[2], 0, 10);
  484.   set_rstp_port_cfg_value (port_index, value, PT_CFG_COST);
  485.   return 0;
  486. }
  487. static int cli_prt_mcheck (int argc, char** argv)
  488. {
  489.   int port_index = 0;
  490.   if ('a' != argv[1][0])
  491.     port_index = strtoul(argv[1], 0, 10);
  492.   set_rstp_port_cfg_value (port_index, 0, PT_CFG_MCHECK);
  493.   return 0;
  494. }
  495. static int get_bool_arg (int narg, int argc, char** argv,
  496.                          unsigned long* value)
  497. {
  498.   switch (argv[narg][0]) {
  499.     case 'y':
  500.     case 'Y':
  501.       *value = 1;
  502.       break;
  503.     case 'n':
  504.     case 'N':
  505.       *value = 0;
  506.       break;
  507.     default:
  508.       printf ("Invalid Bollean parameter '%s'n", argv[narg]);
  509.       return -1;
  510.   }
  511.   return 0;
  512. }
  513. static int cli_prt_edge (int argc, char** argv)
  514. {
  515.   int port_index = 0;
  516.   unsigned long value = 1;
  517.   if ('a' != argv[1][0])
  518.     port_index = strtoul(argv[1], 0, 10);
  519.   if (0 != get_bool_arg (2, argc, argv, &value))
  520.     return 0;
  521.   set_rstp_port_cfg_value (port_index, value, PT_CFG_EDGE);
  522.   return 0;
  523. }
  524. static int cli_prt_non_stp (int argc, char** argv)
  525. {
  526.   int port_index = 0;
  527.   unsigned long value = 0;
  528.   if ('a' != argv[1][0])
  529.     port_index = strtoul(argv[1], 0, 10);
  530.   if (0 != get_bool_arg (2, argc, argv, &value))
  531.     return 0;
  532.   set_rstp_port_cfg_value (port_index, value, PT_CFG_NON_STP);
  533.   return 0;
  534. }
  535. static int cli_prt_p2p (int argc, char** argv)
  536. {
  537.   int port_index = 0;
  538.   unsigned long value = P2P_FORCE_TRUE;
  539.   if ('a' != argv[1][0])
  540.     port_index = strtoul(argv[1], 0, 10);
  541.   switch (argv[2][0]) {
  542.       case 'y':
  543.       case 'Y':
  544.         value = P2P_FORCE_TRUE;
  545.         break;
  546.       case 'n':
  547.       case 'N':
  548.         value = P2P_FORCE_FALSE;
  549.         break;
  550.       case 'a':
  551.       case 'A':
  552.         value = P2P_AUTO;
  553.         break;
  554.       default:
  555.         printf ("Invalid parameter '%s'n", argv[2]);
  556.         return 0;
  557.   }
  558.   set_rstp_port_cfg_value (port_index, (ADMIN_P2P_T) value, PT_CFG_P2P);
  559.   return 0;
  560. }
  561. #ifdef STP_DBG
  562. static int cli_trace (int argc, char** argv)
  563. {
  564.   BITMAP_T ports_bitmap;
  565.   int port_index;
  566.   if ('a' == argv[1][0]) {
  567.     BitmapSetAllBits(&ports_bitmap);
  568.   } else {
  569.     port_index = strtoul(argv[1], 0, 10);
  570.     BitmapClear(&ports_bitmap);
  571.     BitmapSetBit(&ports_bitmap, port_index - 1);
  572.   }
  573.   STP_IN_dbg_set_port_trace (argv[2],
  574.                              argv[3][0] != 'n' && argv[3][0] != 'N',
  575.                              0, &ports_bitmap,
  576.                              1);
  577.   return 0;
  578. }
  579. /****
  580.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  581.   PARAM_ENUM("receive or/and transmit")
  582.     PARAM_ENUM_SEL("rx", "receive")
  583.     PARAM_ENUM_SEL("tx", "transmit")
  584.     PARAM_ENUM_DEFAULT("all")
  585.   PARAM_NUMBER("number of BPDU to skip", 0, 10000, "1")
  586. ****/
  587. static int cli_skip (int argc, char** argv)
  588. {
  589.   int port_index = 0, to_skip;
  590.   if ('a' != argv[1][0])
  591.     port_index = strtoul(argv[1], 0, 10);
  592.   to_skip = atoi (argv[3]);
  593.   if ('a' == argv[2][0] || 'r' == argv[2][0]) {
  594.     set_rstp_port_cfg_value (port_index, to_skip, PT_CFG_DBG_SKIP_RX);
  595.   }
  596.   if ('a' == argv[2][0] || 't' == argv[2][0]) {
  597.     set_rstp_port_cfg_value (port_index, to_skip, PT_CFG_DBG_SKIP_TX);
  598.   }
  599.   return 0;
  600. }
  601. static int cli_sleep (int argc, char** argv)
  602. {
  603.   int delay = atoi (argv[1]);
  604.   sleep (delay);
  605.   return 0;
  606. }
  607. #endif
  608. static CMD_DSCR_T lang[] = {
  609.   THE_COMMAND("enable", "enable rstp")
  610.   THE_FUNC(cli_enable)
  611.   THE_COMMAND("disable", "disable rstp")
  612.   THE_FUNC(cli_disable)
  613.   THE_COMMAND("show bridge", "get bridge config")
  614.   THE_FUNC(cli_br_get_cfg)
  615.   THE_COMMAND("show port", "get port config")
  616.   PARAM_NUMBER("port number on bridge", 1, NUMBER_OF_PORTS, "all")
  617.   THE_FUNC(cli_pr_get_cfg)
  618.   THE_COMMAND("bridge priority", "set bridge priority")
  619.   PARAM_NUMBER("priority", MIN_BR_PRIO, MAX_BR_PRIO, "0x8000")
  620.   THE_FUNC(cli_br_prio)
  621.   THE_COMMAND("bridge maxage", "set bridge maxAge")
  622.   PARAM_NUMBER("maxAge", MIN_BR_MAXAGE, MAX_BR_MAXAGE, "20")
  623.   THE_FUNC(cli_br_maxage)
  624.   THE_COMMAND("bridge fdelay", "set bridge forwardDelay")
  625.   PARAM_NUMBER("forwardDelay", MIN_BR_FWDELAY, MAX_BR_FWDELAY, "15")
  626.   THE_FUNC(cli_br_fdelay)
  627.   THE_COMMAND("bridge forseVersion", "set bridge forseVersion")
  628.   PARAM_BOOL("forseVersion", "forse slow", "regular", "no")
  629.   THE_FUNC(cli_br_fvers)
  630.   THE_COMMAND("port priority", "set port priority")
  631.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  632.   PARAM_NUMBER("priority", MIN_PORT_PRIO, MAX_PORT_PRIO, "128")
  633.   THE_FUNC(cli_prt_prio)
  634.   THE_COMMAND("port pcost", "set port path cost")
  635.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  636.   PARAM_NUMBER("path cost (0- for auto)", 0, 200000000, 0)
  637.   THE_FUNC(cli_prt_pcost)
  638.   THE_COMMAND("port mcheck", "set port mcheck")
  639.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  640.   THE_FUNC(cli_prt_mcheck)
  641.   THE_COMMAND("port edge", "set port adminEdge")
  642.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  643.   PARAM_BOOL("adminEdge", "Edge", "noEdge", "Y")
  644.   THE_FUNC(cli_prt_edge)
  645.   THE_COMMAND("port nonStp", "set port adminNonStp")
  646.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  647.   PARAM_BOOL("adminEdge", "Doesn't participate", "Paricipates", "n")
  648.   THE_FUNC(cli_prt_non_stp)
  649.   THE_COMMAND("port p2p", "set port adminPoit2Point")
  650.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  651.   PARAM_ENUM("adminPoit2Point")
  652.     PARAM_ENUM_SEL("y", "forcePointToPoint")
  653.     PARAM_ENUM_SEL("n", "forcePointToMultiPoint")
  654.     PARAM_ENUM_SEL("a", "autoPointToPoint")
  655.     PARAM_ENUM_DEFAULT("a")
  656.   THE_FUNC(cli_prt_p2p)
  657. #ifdef STP_DBG
  658.   THE_COMMAND("trace", "set port trace")
  659.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  660.   PARAM_ENUM("state machine name")
  661.     PARAM_ENUM_SEL("info", "info")
  662.     PARAM_ENUM_SEL("roletrns", "roletrns")
  663.     PARAM_ENUM_SEL("sttrans", "sttrans")
  664.     PARAM_ENUM_SEL("topoch", "topoch")
  665.     PARAM_ENUM_SEL("migrate", "migrate")
  666.     PARAM_ENUM_SEL("transmit", "transmit")
  667.     PARAM_ENUM_SEL("p2p", "p2p")
  668.     PARAM_ENUM_SEL("edge", "edge")
  669.     PARAM_ENUM_SEL("pcost", "pcost")
  670.     PARAM_ENUM_DEFAULT("all")
  671.   PARAM_BOOL("enable/disable", "trace it", "don't trace it", "n")
  672.   THE_FUNC(cli_trace)
  673.   THE_COMMAND("skip", "skip BPDU processing")
  674.   PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all")
  675.   PARAM_ENUM("receive or/and transmit")
  676.     PARAM_ENUM_SEL("rx", "receive")
  677.     PARAM_ENUM_SEL("tx", "transmit")
  678.     PARAM_ENUM_DEFAULT("all")
  679.   PARAM_NUMBER("number of BPDU to skip", 0, 10000, "1")
  680.   THE_FUNC(cli_skip)
  681.   THE_COMMAND("sleep", "sleep")
  682.   PARAM_NUMBER("delay in sec.", 1, 4000, "4")
  683.   THE_FUNC(cli_sleep)
  684. #endif
  685.   
  686.   END_OF_LANG
  687. };
  688. int stp_cli_init (void)
  689. {
  690.    I_am_a_stupid_hub = 0;
  691.    cli_register_language (lang);
  692.    return 0;
  693. }