⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zserv.c

📁 zebra测试源代码用于 SOCKET 通信
💻 C
📖 第 1 页 / 共 3 页
字号:
	    {	    case ZEBRA_NEXTHOP_IPV6:	      stream_get (&nexthop, s, 16);	      break;	    case ZEBRA_NEXTHOP_IFINDEX:	      ifindex = stream_getl (s);	      break;	    }	}    }  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))    api.distance = stream_getc (s);  else    api.distance = 0;  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))    api.metric = stream_getl (s);  else    api.metric = 0;      if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))    rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);  else    rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);}voidzebra_read_ipv6 (int command, struct zserv *client, u_short length){  u_char type;  u_char flags;  struct in6_addr nexthop, *gate;  u_char *lim;  u_char *pnt;  unsigned int ifindex;  pnt = stream_pnt (client->ibuf);  lim = pnt + length;  type = stream_getc (client->ibuf);  flags = stream_getc (client->ibuf);  stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr));    while (stream_pnt (client->ibuf) < lim)    {      int size;      struct prefix_ipv6 p;            ifindex = stream_getl (client->ibuf);      memset (&p, 0, sizeof (struct prefix_ipv6));      p.family = AF_INET6;      p.prefixlen = stream_getc (client->ibuf);      size = PSIZE(p.prefixlen);      stream_get (&p.prefix, client->ibuf, size);      if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))        gate = NULL;      else        gate = &nexthop;      if (command == ZEBRA_IPV6_ROUTE_ADD)	rib_add_ipv6 (type, flags, &p, gate, ifindex, 0);      else	rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);    }}voidzread_ipv6_nexthop_lookup (struct zserv *client, u_short length){  struct in6_addr addr;  char buf[BUFSIZ];  stream_get (&addr, client->ibuf, 16);  printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ));  zsend_ipv6_nexthop_lookup (client, &addr);}#endif /* HAVE_IPV6 *//* Close zebra client. */voidzebra_client_close (struct zserv *client){  /* Close file descriptor. */  if (client->sock)    {      close (client->sock);      client->sock = -1;    }  /* Free stream buffers. */  if (client->ibuf)    stream_free (client->ibuf);  if (client->obuf)    stream_free (client->obuf);  /* Release threads. */  if (client->t_read)    thread_cancel (client->t_read);  if (client->t_write)    thread_cancel (client->t_write);  /* Free client structure. */  listnode_delete (client_list, client);  XFREE (0, client);}/* Make new client. */voidzebra_client_create (int sock){  struct zserv *client;  client = XCALLOC (0, sizeof (struct zserv));  /* Make client input/output buffer. */  client->sock = sock;  client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);  client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);  /* Set table number. */  client->rtm_table = rtm_table_default;  /* Add this client to linked list. */  listnode_add (client_list, client);    /* Make new read thread. */  zebra_event (ZEBRA_READ, sock, client);}/* Handler of zebra service request. */intzebra_client_read (struct thread *thread){  int sock;  struct zserv *client;  int nbyte;  u_short length;  u_char command;  /* Get thread data.  Reset reading thread because I'm running. */  sock = THREAD_FD (thread);  client = THREAD_ARG (thread);  client->t_read = NULL;  /* Read length and command. */  nbyte = stream_read (client->ibuf, sock, 3);  if (nbyte <= 0)     {      if (IS_ZEBRA_DEBUG_EVENT)	zlog_info ("connection closed socket [%d]", sock);      zebra_client_close (client);      return -1;    }  length = stream_getw (client->ibuf);  command = stream_getc (client->ibuf);  if (length < 3)     {      if (IS_ZEBRA_DEBUG_EVENT)	zlog_info ("length %d is less than 3 ", length);      zebra_client_close (client);      return -1;    }  length -= 3;  /* Read rest of data. */  if (length)    {      nbyte = stream_read (client->ibuf, sock, length);      if (nbyte <= 0) 	{	  if (IS_ZEBRA_DEBUG_EVENT)	    zlog_info ("connection closed [%d] when reading zebra data", sock);	  zebra_client_close (client);	  return -1;	}    }  /* Debug packet information. */  if (IS_ZEBRA_DEBUG_EVENT)    zlog_info ("zebra message comes from socket [%d]", sock);  if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)    zlog_info ("zebra message received [%s] %d", 	       zebra_command_str[command], length);  switch (command)     {    case ZEBRA_INTERFACE_ADD:      zread_interface_add (client, length);      break;    case ZEBRA_INTERFACE_DELETE:      zread_interface_delete (client, length);      break;    case ZEBRA_IPV4_ROUTE_ADD:      zread_ipv4_add (client, length);      break;    case ZEBRA_IPV4_ROUTE_DELETE:      zread_ipv4_delete (client, length);      break;#ifdef HAVE_IPV6    case ZEBRA_IPV6_ROUTE_ADD:      zread_ipv6_add (client, length);      break;    case ZEBRA_IPV6_ROUTE_DELETE:      zread_ipv6_delete (client, length);      break;#endif /* HAVE_IPV6 */    case ZEBRA_REDISTRIBUTE_ADD:      zebra_redistribute_add (command, client, length);      break;    case ZEBRA_REDISTRIBUTE_DELETE:      zebra_redistribute_delete (command, client, length);      break;    case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:      zebra_redistribute_default_add (command, client, length);      break;    case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:      zebra_redistribute_default_delete (command, client, length);      break;    case ZEBRA_IPV4_NEXTHOP_LOOKUP:      zread_ipv4_nexthop_lookup (client, length);      break;#ifdef HAVE_IPV6    case ZEBRA_IPV6_NEXTHOP_LOOKUP:      zread_ipv6_nexthop_lookup (client, length);      break;#endif /* HAVE_IPV6 */    case ZEBRA_IPV4_IMPORT_LOOKUP:      zread_ipv4_import_lookup (client, length);      break;    default:      zlog_info ("Zebra received unknown command %d", command);      break;    }  stream_reset (client->ibuf);  zebra_event (ZEBRA_READ, sock, client);  return 0;}/* Write output buffer to the socket. */voidzebra_write (struct thread *thread){  int sock;  struct zserv *client;  /* Thread treatment. */  sock = THREAD_FD (thread);  client = THREAD_ARG (thread);  client->t_write = NULL;  stream_flush (client->obuf, sock);}/* Accept code of zebra server socket. */intzebra_accept (struct thread *thread){  int val;  int accept_sock;  int client_sock;  struct sockaddr_in client;  socklen_t len;  accept_sock = THREAD_FD (thread);  len = sizeof (struct sockaddr_in);  client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);  if (client_sock < 0)    {      zlog_warn ("Can't accept zebra socket: %s", strerror (errno));      return -1;    }  /* Make client socket non-blocking.  */  val = fcntl (client_sock, F_GETFL, 0);  fcntl (client_sock, F_SETFL, (val | O_NONBLOCK));  /* Create new zebra client. */  zebra_client_create (client_sock);  /* Register myself. */  zebra_event (ZEBRA_SERV, accept_sock, NULL);  return 0;}/* Make zebra's server socket. */voidzebra_serv (){  int ret;  int accept_sock;  struct sockaddr_in addr;  accept_sock = socket (AF_INET, SOCK_STREAM, 0);  if (accept_sock < 0)     {      zlog_warn ("Can't bind to socket: %s", strerror (errno));      zlog_warn ("zebra can't provice full functionality due to above error");      return;    }  memset (&addr, 0, sizeof (struct sockaddr_in));  addr.sin_family = AF_INET;  addr.sin_port = htons (ZEBRA_PORT);#ifdef HAVE_SIN_LEN  addr.sin_len = sizeof (struct sockaddr_in);#endif /* HAVE_SIN_LEN */  addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);  sockopt_reuseaddr (accept_sock);  sockopt_reuseport (accept_sock);  ret  = bind (accept_sock, (struct sockaddr *)&addr, 	       sizeof (struct sockaddr_in));  if (ret < 0)    {      zlog_warn ("Can't bind to socket: %s", strerror (errno));      zlog_warn ("zebra can't provice full functionality due to above error");      close (accept_sock);      /* Avoid sd leak. */      return;    }  ret = listen (accept_sock, 1);  if (ret < 0)    {      zlog_warn ("Can't listen to socket: %s", strerror (errno));      zlog_warn ("zebra can't provice full functionality due to above error");      close (accept_sock);	/* Avoid sd leak. */      return;    }  zebra_event (ZEBRA_SERV, accept_sock, NULL);}/* For sockaddr_un. */#include <sys/un.h>/* zebra server UNIX domain socket. */voidzebra_serv_un (char *path){  int ret;  int sock, len;  struct sockaddr_un serv;  mode_t old_mask;  /* First of all, unlink existing socket */  unlink (path);  /* Set umask */  old_mask = umask (0077);  /* Make UNIX domain socket. */  sock = socket (AF_UNIX, SOCK_STREAM, 0);  if (sock < 0)    {      perror ("sock");      return;    }  /* Make server socket. */  memset (&serv, 0, sizeof (struct sockaddr_un));  serv.sun_family = AF_UNIX;  strncpy (serv.sun_path, path, strlen (path));#ifdef HAVE_SUN_LEN  len = serv.sun_len = SUN_LEN(&serv);#else  len = sizeof (serv.sun_family) + strlen (serv.sun_path);#endif /* HAVE_SUN_LEN */  ret = bind (sock, (struct sockaddr *) &serv, len);  if (ret < 0)    {      perror ("bind");      close (sock);      return;    }  ret = listen (sock, 5);  if (ret < 0)    {      perror ("listen");      close (sock);      return;    }  umask (old_mask);  zebra_event (ZEBRA_SERV, sock, NULL);}/* Zebra's event management function. */extern struct thread_master *master;voidzebra_event (enum event event, int sock, struct zserv *client){  switch (event)    {    case ZEBRA_SERV:      thread_add_read (master, zebra_accept, client, sock);      break;    case ZEBRA_READ:      client->t_read = 	thread_add_read (master, zebra_client_read, client, sock);      break;    case ZEBRA_WRITE:      /**/      break;    }}/* Display default rtm_table for all clients. */DEFUN (show_table,       show_table_cmd,       "show table",       SHOW_STR       "default routing table to use for all clients\n"){  vty_out (vty, "table %d%s", rtm_table_default,	   VTY_NEWLINE);  return CMD_SUCCESS;}DEFUN (config_table,        config_table_cmd,       "table TABLENO",       "Configure target kernel routing table\n"       "TABLE integer\n"){  rtm_table_default = strtol (argv[0], (char**)0, 10);  return CMD_SUCCESS;}DEFUN (no_ip_forwarding,       no_ip_forwarding_cmd,       "no ip forwarding",       NO_STR       IP_STR       "Turn off IP forwarding"){  int ret;  ret = ipforward ();  if (ret == 0)    {      vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE);       return CMD_ERR_NOTHING_TODO;    }  ret = ipforward_off ();  if (ret != 0)    {      vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);      return CMD_WARNING;    }  return CMD_SUCCESS;}/* This command is for debugging purpose. */DEFUN (show_zebra_client,       show_zebra_client_cmd,       "show zebra client",       SHOW_STR       "Zebra information"       "Client information"){  listnode node;  struct zserv *client;  for (node = listhead (client_list); node; nextnode (node))    {      client = getdata (node);      vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);    }  return CMD_SUCCESS;}/* Table configuration write function. */intconfig_write_table (struct vty *vty){  if (rtm_table_default)    vty_out (vty, "table %d%s", rtm_table_default,	     VTY_NEWLINE);  return 0;}/* table node for routing tables. */struct cmd_node table_node ={  TABLE_NODE,  "",				/* This node has no interface. */  1};/* Only display ip forwarding is enabled or not. */DEFUN (show_ip_forwarding,       show_ip_forwarding_cmd,       "show ip forwarding",       SHOW_STR       IP_STR       "IP forwarding status\n"){  int ret;  ret = ipforward ();  if (ret == 0)    vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);  else    vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);  return CMD_SUCCESS;}#ifdef HAVE_IPV6/* Only display ipv6 forwarding is enabled or not. */DEFUN (show_ipv6_forwarding,       show_ipv6_forwarding_cmd,       "show ipv6 forwarding",       SHOW_STR       "IPv6 information\n"       "Forwarding status\n"){  int ret;  ret = ipforward_ipv6 ();  switch (ret)    {    case -1:      vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);      break;    case 0:      vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);      break;    case 1:      vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);      break;    default:      vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);      break;    }  return CMD_SUCCESS;}DEFUN (no_ipv6_forwarding,       no_ipv6_forwarding_cmd,       "no ipv6 forwarding",       NO_STR       IP_STR       "Doesn't forward IPv6 protocol packet"){  int ret;  ret = ipforward_ipv6_off ();  if (ret != 0)    {      vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);      return CMD_WARNING;    }  return CMD_SUCCESS;}#endif /* HAVE_IPV6 *//* IPForwarding configuration write function. */intconfig_write_forwarding (struct vty *vty){  if (! ipforward ())    vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);#ifdef HAVE_IPV6  if (! ipforward_ipv6 ())    vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);#endif /* HAVE_IPV6 */  vty_out (vty, "!%s", VTY_NEWLINE);  return 0;}/* table node for routing tables. */struct cmd_node forwarding_node ={  FORWARDING_NODE,  "",				/* This node has no interface. */  1};/* Initialisation of zebra and installation of commands. */voidzebra_init (){  /* Client list init. */  client_list = list_new ();  /* Forwarding is on by default. */  ipforward_on ();#ifdef HAVE_IPV6  ipforward_ipv6_on ();#endif /* HAVE_IPV6 */  /* Make zebra server socket. */#ifdef HAVE_TCP_ZEBRA  zebra_serv ();#else  zebra_serv_un (ZEBRA_SERV_PATH);#endif /* HAVE_TCP_ZEBRA */  /* Install configuration write function. */  install_node (&table_node, config_write_table);  install_node (&forwarding_node, config_write_forwarding);  install_element (VIEW_NODE, &show_ip_forwarding_cmd);  install_element (ENABLE_NODE, &show_ip_forwarding_cmd);  install_element (CONFIG_NODE, &no_ip_forwarding_cmd);  install_element (ENABLE_NODE, &show_zebra_client_cmd);#ifdef HAVE_NETLINK  install_element (VIEW_NODE, &show_table_cmd);  install_element (ENABLE_NODE, &show_table_cmd);  install_element (CONFIG_NODE, &config_table_cmd);#endif /* HAVE_NETLINK */#ifdef HAVE_IPV6  install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);  install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);  install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);#endif /* HAVE_IPV6 */  FIFO_INIT(&message_queue);  t_write = NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -