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

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 <stdio.h>
  23. #include <stdlib.h>
  24. #include <time.h>
  25. #include <string.h>
  26. #include <sys/wait.h>
  27. #include <sys/time.h>
  28. #include <sys/types.h>
  29. #include <signal.h>
  30. #include <unistd.h>
  31. #include <errno.h>
  32. #include <readline/readline.h>
  33. #include "cli.h"
  34. #include "bitmap.h"
  35. #include "uid.h"
  36. UID_SOCKET_T    main_sock;
  37. typedef struct port_s {
  38.   int port;
  39.   struct bridge_s *bridge_partner;
  40.   int             port_partner;
  41. } PORT_T;
  42. typedef struct bridge_s {
  43.   long      pid;
  44.   long      number_of_ports;
  45.   PORT_T*   ports;
  46.   UID_SOCKET_T  sock;
  47.   struct bridge_s* next;
  48. } BRIDGE_T;
  49. static BRIDGE_T* br_lst = 0;
  50. int disconnect_port (PORT_T* port, char reset_myself)
  51. {
  52.   UID_MSG_T     msg;
  53.   if (! port->bridge_partner) {
  54.     printf ("can't disconnect from port p%02d: it has not a partnern",
  55.             port->port_partner);
  56.     return -1;
  57.   }
  58.   printf ("disconnect from port p%02d for bridge B%ldn",
  59.           port->port_partner, port->bridge_partner->pid);
  60.   
  61.   msg.header.sender_pid = getpid ();
  62.   msg.header.cmd_type = UID_CNTRL;
  63.   msg.body.cntrl.cmd = UID_PORT_DISCONNECT;
  64.   msg.header.destination_port = port->port_partner;
  65.   UiD_SocketSendto (&port->bridge_partner->sock, &msg, sizeof (UID_MSG_T));
  66.   if (reset_myself)
  67.     port->bridge_partner = NULL;
  68.   else {
  69.     port = port->bridge_partner->ports + port->port_partner - 1;
  70.     port->bridge_partner = NULL;
  71.   }
  72.   return 0;
  73. }
  74. int register_bridge (UID_MSG_T* msg, UID_SOCKET_T* socket_4_reply)
  75. {
  76.   register BRIDGE_T* newbr;
  77.   /* check if such bridge has just been registered */
  78.   for (newbr = br_lst; newbr; newbr = newbr->next)
  79.     if (newbr->pid == msg->header.sender_pid) {
  80.       printf ("Sorry, such bridge has just been registeredn");
  81.       /* TBT: may be send him SHUTDOWN ? */
  82.     }
  83.   newbr = (BRIDGE_T*) malloc (sizeof (BRIDGE_T));
  84.   if (! newbr) {
  85.     printf ("Sorry, there is no memory for it :(n");
  86.     return 0;
  87.   }
  88.   newbr->pid = msg->header.sender_pid;
  89.   newbr->ports = (PORT_T*) calloc (msg->body.cntrl.param1, sizeof (PORT_T));
  90.   if (! newbr->ports) {
  91.     printf ("Sorry, there is no memory for its ports :(n");
  92.     free (newbr);
  93.     return 0;
  94.   }
  95.   newbr->number_of_ports = msg->body.cntrl.param1;
  96.   memcpy (&newbr->sock, socket_4_reply, sizeof (UID_SOCKET_T));
  97.   /* bind it to the begin of list */
  98.   newbr->next = br_lst;
  99.   br_lst = newbr;
  100.   return 0;
  101. }
  102. int unregister_bridge (UID_MSG_T* msg)
  103. {
  104.   register BRIDGE_T* oldbr;
  105.   register BRIDGE_T* prev = NULL;
  106.   register PORT_T*   port;
  107.   register int      indx;
  108.   /* check if such bridge has just been registered */
  109.   for (oldbr = br_lst; oldbr; oldbr = oldbr->next)
  110.     if (oldbr->pid == msg->header.sender_pid) {
  111.       break;
  112.     } else
  113.       prev = oldbr;
  114.   if (! oldbr) {
  115.     printf ("Sorry, this bridge has not yet been registered ? :(n");
  116.     return 0;
  117.   }
  118.   /* disconnect all its connceted ports */
  119.   for (indx = 0; indx < oldbr->number_of_ports; indx++) {
  120.     port = oldbr->ports + indx;
  121.     if (port->bridge_partner) {
  122.       disconnect_port (port, 0);
  123.     }
  124.   } 
  125.   
  126.   /* delete from the list & free */
  127.   if (prev)
  128.     prev->next = oldbr->next;
  129.   else
  130.     br_lst = oldbr->next;
  131.     
  132.   free (oldbr->ports);
  133.   free (oldbr);
  134.   return 0;
  135. }
  136. static long scan_br_name (char* param)
  137. {
  138.   if ('B' == param[0])
  139.     return strtoul(param + 1, 0, 10);
  140.   else
  141.     return strtoul(param, 0, 10);
  142. }
  143. static int show_bridge (int argc, char** argv)
  144. {
  145.   long           pid = 0;
  146.   register BRIDGE_T* br = NULL;
  147.   register PORT_T*   port;
  148.   register int       indx, cnt = 0;
  149.   if (argc > 1) {
  150.     pid = scan_br_name (argv[1]);
  151.     printf ("You wanted to see B%ld, didn't you ?n", pid);
  152.   }
  153.   for (br = br_lst; br; br = br->next) 
  154.     if (! pid || pid == br->pid) {
  155.       printf ("%2d. Bridge B%ld has %ld ports:n",
  156.               ++cnt,
  157.               (long) br->pid, br->number_of_ports);
  158.       for (indx = 0; indx < br->number_of_ports; indx++) {
  159.         port = br->ports + indx;
  160.         if (port->bridge_partner) {
  161.           printf ("port p%02d ", (int) indx + 1);
  162.           printf ("connected to B%ld port p%02dn",
  163.                   port->bridge_partner->pid,
  164.                   port->port_partner);
  165.         }
  166.       }
  167.     }
  168.   
  169.   if (! cnt) {
  170.     printf ("There are no such bridges :(n");
  171.   }
  172.   return 0;
  173. }
  174. static void _link_two_ports (BRIDGE_T* br1, PORT_T* port1,  int indx1,
  175.                              BRIDGE_T* br2, PORT_T* port2,  int indx2)
  176. {
  177.   UID_MSG_T     msg;
  178.   port1->bridge_partner = br2;
  179.   port1->port_partner = indx2;
  180.   port2->bridge_partner = br1;
  181.   port2->port_partner = indx1;
  182.   msg.header.sender_pid = getpid ();
  183.   msg.header.cmd_type = UID_CNTRL;
  184.   msg.body.cntrl.cmd = UID_PORT_CONNECT;
  185.   msg.header.destination_port = indx1;
  186.   UiD_SocketSendto (&br1->sock, &msg, sizeof (UID_MSG_T));
  187.   msg.header.destination_port = indx2;
  188.   UiD_SocketSendto (&br2->sock, &msg, sizeof (UID_MSG_T));
  189. }
  190. static int link_bridges (int argc, char** argv)
  191. {
  192.   long       pid1, pid2;
  193.   int        indx1, indx2;
  194.   BRIDGE_T*  br;
  195.   BRIDGE_T*  br1;
  196.   BRIDGE_T*  br2;
  197.   PORT_T*    port1;
  198.   PORT_T*    port2;
  199.   if (argc < 5) {
  200.     printf ("for this command must be 4 argumenta :(n");
  201.     return 0;
  202.   }
  203.   pid1 = scan_br_name (argv[1]);
  204.   indx1 = strtoul(argv[2], 0, 10);
  205.   pid2 = scan_br_name (argv[3]);
  206.   indx2 = strtoul(argv[4], 0, 10);
  207.   printf ("connect B%ld port p%02d to B%ld port p%02dn",
  208.           pid1, indx1, pid2, indx2);
  209.   for (br = br_lst; br; br = br->next) {
  210.      //printf ("check B%ldn", br->pid);
  211.      if (br->pid == pid1) br1 = br;
  212.      if (br->pid == pid2) br2 = br;
  213.   }
  214.   if (! br1 || ! br2) {
  215.     printf ("Sorry, one of these bridges is absent :(n");
  216.     return 0;
  217.   }
  218.   if (indx1 > br1->number_of_ports || indx1 < 0) {
  219.     printf ("Sorry, p%02d invalidn", indx1);
  220.     return 0;
  221.   }
  222.   if (indx2 > br2->number_of_ports || indx2 < 0) {
  223.     printf ("Sorry, p%02d invalidn", indx2);
  224.     return 0;
  225.   }
  226.   
  227.   port1 = br1->ports + indx1 - 1;
  228.   port2 = br2->ports + indx2 - 1;
  229.   if (port1->bridge_partner)
  230.     printf ("port p%02d is connectedn", indx1);
  231.   if (port2->bridge_partner)
  232.     printf ("port p%02d is connectedn", indx2);
  233.   if (port1->bridge_partner || port2->bridge_partner)
  234.     return 0;
  235.   _link_two_ports (br1, port1, indx1,
  236.                    br2, port2, indx2);
  237.   return 0;
  238. }
  239. static int unlink_port (int argc, char** argv)
  240. {
  241.   long pid1;
  242.   int indx1;
  243.   BRIDGE_T*     br;
  244.   BRIDGE_T*     br1;
  245.   BRIDGE_T*     br2;
  246.   PORT_T*       port1;
  247.   PORT_T*       port2;
  248.   if (argc < 3) {
  249.     printf ("for this command must be 2 argumenta :(n");
  250.     return 0;
  251.   }
  252.   pid1 = scan_br_name (argv[1]);
  253.   indx1 = strtoul(argv[2], 0, 10);
  254.   for (br = br_lst; br; br = br->next) {
  255.      //printf ("check B%ldn", br->pid);
  256.      if (br->pid == pid1) br1 = br;
  257.   }
  258.   if (! br1) {
  259.     printf ("Sorry, the bridge B%ldis absent :(n", pid1);
  260.     return 0;
  261.   }
  262.   if (indx1 > br1->number_of_ports || indx1 < 0) {
  263.     printf ("Sorry, port p%02d invalidn", indx1);
  264.     return 0;
  265.   }
  266.   port1 = br1->ports + indx1 - 1;
  267.   if (! port1->bridge_partner) {
  268.     printf ("port p%02d is disconnectedn", indx1);
  269.     return 0;
  270.   }
  271.   br2 = port1->bridge_partner;
  272.   port2 = br2->ports + port1->port_partner - 1;
  273.   disconnect_port (port1, 1);
  274.   disconnect_port (port2, 1);
  275.   return 0;
  276. }
  277. static int link_ring (int argc, char** argv)
  278. {
  279.   BRIDGE_T*     br1;
  280.   BRIDGE_T*     br2;
  281.   PORT_T*       port1;
  282.   PORT_T*       port2;
  283.   register int indx;
  284.   /* unlink all */
  285.   for (br1 = br_lst; br1; br1 = br1->next) {
  286.     /* disconnect all its connceted ports */
  287.     for (indx = 0; indx < br1->number_of_ports; indx++) {
  288.       port1 = br1->ports + indx;
  289.       if (port1->bridge_partner) {
  290.         printf ("disconnect B%ld ", br1->pid);
  291.         printf ("port p%02d (with B%ld-p%02d)n",
  292.                   indx + 1,
  293.                   port1->bridge_partner->pid,
  294.                   port1->port_partner);
  295.         br2 = port1->bridge_partner;
  296.         port2 = br2->ports + port1->port_partner - 1;
  297.         disconnect_port (port1, 1);
  298.         disconnect_port (port2, 1);
  299.       }
  300.     } 
  301.   }
  302.   /* buid ring */
  303.   for (br1 = br_lst; br1; br1 = br1->next) {
  304.     br2 = br1->next;
  305.     if (! br2)  br2 = br_lst;
  306.     _link_two_ports (br1, br1->ports + 1, 2,
  307.                      br2, br2->ports + 0, 1);
  308.   }
  309.   return 0;
  310. }
  311. static CMD_DSCR_T lang[] = {
  312.   THE_COMMAND("show", "get bridge[s] connuctivity")
  313.   PARAM_STRING("bridge name", "all")
  314.   THE_FUNC(show_bridge)
  315.   THE_COMMAND("link", "link two bridges")
  316.   PARAM_STRING("first bridge name", NULL)
  317.   PARAM_NUMBER("port number on first bridge", 1, NUMBER_OF_PORTS, NULL)
  318.   PARAM_STRING("second bridge name", NULL)
  319.   PARAM_NUMBER("port number on second bridge", 1, NUMBER_OF_PORTS, NULL)
  320.   THE_FUNC(link_bridges)
  321.   THE_COMMAND("unlink", "unlink the port of the bridge")
  322.   PARAM_STRING("bridge name", NULL)
  323.   PARAM_NUMBER("port number on bridge", 1, NUMBER_OF_PORTS, NULL)
  324.   THE_FUNC(unlink_port)
  325.   THE_COMMAND("ring", "link all bridges into a ring")
  326.   THE_FUNC(link_ring)
  327.   END_OF_LANG
  328. };
  329. void mngr_start (void)
  330. {
  331.   if (0 != UiD_SocketInit (&main_sock, UID_REPL_PATH, UID_BIND_AS_SERVER)) {
  332.     printf ("FATAL: can't init the connectionn");
  333.     exit (-3);
  334.   }
  335.   cli_register_language (lang);
  336. }
  337. void mngr_shutdown (void)
  338. {
  339.   UID_MSG_T msg;
  340.   BRIDGE_T* br;
  341.   msg.header.sender_pid = getpid ();
  342.   msg.header.cmd_type = UID_CNTRL;
  343.   msg.body.cntrl.cmd = UID_BRIDGE_SHUTDOWN;
  344.   for (br = br_lst; br; br = br->next) {
  345.      UiD_SocketSendto (&br->sock, &msg, sizeof (UID_MSG_T));
  346.   }
  347. }
  348. char *get_prompt (void)
  349. {
  350.   static char prompt[MAX_CLI_PROMT];
  351.   snprintf (prompt, MAX_CLI_PROMT - 1, "%s Mngr > ", UT_sprint_time_stamp());
  352.   return prompt;
  353. }
  354. int mngr_control (UID_MSG_T* msg, UID_SOCKET_T* sock_4_reply)
  355. {
  356.   switch (msg->body.cntrl.cmd) {
  357.     default:
  358.     case UID_PORT_CONNECT:
  359.     case UID_PORT_DISCONNECT:
  360.       printf ("Unexpected contol message '%d'n", (int) msg->body.cntrl.cmd);
  361.       break;
  362.     case UID_BRIDGE_SHUTDOWN:
  363.       printf ("Bridge B%ld shutdown :(n", (long) msg->header.sender_pid);
  364.       unregister_bridge (msg);
  365.       break;
  366.     case UID_BRIDGE_HANDSHAKE:
  367.       printf ("Bridge B%ld hello :)n", (long) msg->header.sender_pid);
  368.       register_bridge (msg, sock_4_reply);
  369.       break;
  370.   }
  371.   return 0;
  372. }
  373. int mngr_rx_bpdu (UID_MSG_T* msg, size_t msgsize)
  374. {
  375.   BRIDGE_T*     br;
  376.   PORT_T*   port;
  377.   
  378.   for (br = br_lst; br; br = br->next) {
  379.      if (br->pid == msg->header.sender_pid) {
  380.        break;
  381.      }
  382.   }
  383.   if (! br) {
  384.     printf ("RX BPDU from unknown B%ldn", msg->header.sender_pid);
  385.     return 0;
  386.   }
  387.   port = br->ports + msg->header.source_port - 1;
  388.   if (! port->bridge_partner) {
  389.     printf ("RX BPDU from unlinked port p%02d of bridge B%ld ?n",
  390.             (int) msg->header.source_port,
  391.             msg->header.sender_pid);
  392.     return 0;
  393.   }
  394.  
  395.   br = port->bridge_partner;
  396.   msg->header.destination_port = port->port_partner;
  397.   UiD_SocketSendto (&br->sock, msg, sizeof (UID_MSG_T));
  398.   
  399.   return 0;
  400. }
  401. char read_uid (void)
  402. {
  403.   UID_SOCKET_T  sock_4_reply;
  404.   UID_MSG_T msg;
  405.   size_t    msgsize;
  406.   int       rc = 0;
  407.   msgsize = UiD_SocketRecvfrom (&main_sock, &msg, MAX_UID_MSG_SIZE, &sock_4_reply);
  408.   if (msgsize <= 0) {
  409.     printf ("Something wrong in UIF ?n");
  410.     return 0;
  411.   }
  412.   switch (msg.header.cmd_type) {
  413.     case UID_CNTRL:
  414.       rc =  mngr_control (&msg, &sock_4_reply);
  415.       break;
  416.     case UID_BPDU:
  417.       rc =  mngr_rx_bpdu (&msg, msgsize);
  418.       break;
  419.     default:
  420.       printf ("Unknown message type %dn", (int) msg.header.cmd_type);
  421.       rc = 0;
  422.   }
  423.   return rc;
  424. }
  425. char shutdown_flag = 0;
  426. int main_loop (void)
  427. {
  428.   fd_set                readfds;
  429.   int                   rc, numfds, sock, kkk;
  430.   //rl_callback_handler_install (get_prompt (), rl_read_cli);
  431.   sock = GET_FILE_DESCRIPTOR(&main_sock);
  432.   do {
  433.     numfds = -1;
  434.     FD_ZERO(&readfds);
  435.     kkk = 0; /* stdin for commands */
  436.     FD_SET(kkk, &readfds);
  437.     if (kkk > numfds) numfds = kkk;
  438.     FD_SET(sock, &readfds);
  439.     if (sock > numfds) numfds = sock;
  440.     if (numfds < 0)
  441.       numfds = 0;
  442.     else
  443.       numfds++;
  444.     rc = select (numfds, &readfds, NULL, NULL, NULL);
  445.     if (rc < 0) {             // Error
  446.       if (EINTR == errno) continue; // don't break
  447.       printf ("FATAL_MODE:select failed: %sn", strerror(errno));
  448.       return -2;
  449.     }
  450.     if (FD_ISSET(0, &readfds)) {
  451.       rl_callback_read_char ();
  452.     }
  453.     if (FD_ISSET(sock, &readfds)) {
  454.       shutdown_flag |= read_uid ();
  455.     }
  456.   } while(! shutdown_flag);
  457.   return 0;
  458. }
  459. int main (int argc, char** argv)
  460. {
  461.   rl_init ();
  462.   
  463.   mngr_start ();
  464.   main_loop ();
  465.   mngr_shutdown ();
  466.   rl_shutdown ();
  467.   return 0;
  468. }