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

📄 zserv.c

📁 zebra测试源代码用于 SOCKET 通信
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Zebra daemon server routine. * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro * * This file is part of GNU Zebra. * * GNU Zebra is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  * Boston, MA 02111-1307, USA.   */#include <zebra.h>#include "prefix.h"#include "command.h"#include "if.h"#include "thread.h"#include "stream.h"#include "memory.h"#include "table.h"#include "rib.h"#include "network.h"#include "sockunion.h"#include "log.h"#include "zclient.h"#include "zebra/zserv.h"#include "zebra/redistribute.h"#include "zebra/debug.h"#include "zebra/ipforward.h"/* Event list of zebra. */enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };/* Zebra client list. */list client_list;/* Default rtm_table for all clients */int rtm_table_default = 0;void zebra_event (enum event event, int sock, struct zserv *client);extern struct thread_master *master;/* For logging of zebra meesages. */char *zebra_command_str [] ={  "NULL",  "ZEBRA_INTERFACE_ADD",  "ZEBRA_INTERFACE_DELETE",  "ZEBRA_INTERFACE_ADDRESS_ADD",  "ZEBRA_INTERFACE_ADDRESS_DELETE",  "ZEBRA_INTERFACE_UP",  "ZEBRA_INTERFACE_DOWN",  "ZEBRA_IPV4_ROUTE_ADD",  "ZEBRA_IPV4_ROUTE_DELETE",  "ZEBRA_IPV6_ROUTE_ADD",  "ZEBRA_IPV6_ROUTE_DELETE",  "ZEBRA_REDISTRIBUTE_ADD",  "ZEBRA_REDISTRIBUTE_DELETE",  "ZEBRA_REDISTRIBUTE_DEFAULT_ADD",  "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE",  "ZEBRA_IPV4_NEXTHOP_LOOKUP",  "ZEBRA_IPV6_NEXTHOP_LOOKUP",  "ZEBRA_IPV4_IMPORT_LOOKUP",  "ZEBRA_IPV6_IMPORT_LOOKUP"};struct zebra_message_queue{  struct nsm_message_queue *next;  struct nsm_message_queue *prev;  u_char *buf;  u_int16_t length;  u_int16_t written;};struct thread *t_write;struct fifo message_queue;intzebra_server_dequeue (struct thread *t){  int sock;  int nbytes;  struct zebra_message_queue *queue;  sock = THREAD_FD (t);  t_write = NULL;  queue = (struct zebra_message_queue *) FIFO_HEAD (&message_queue);  if (queue)    {      nbytes = write (sock, queue->buf + queue->written,		      queue->length - queue->written);      if (nbytes <= 0)        {          if (errno != EAGAIN)	    return -1;        }      else if (nbytes != (queue->length - queue->written))	{	  queue->written += nbytes;	}      else        {          FIFO_DEL (queue);          XFREE (MTYPE_TMP, queue->buf);          XFREE (MTYPE_TMP, queue);        }    }  if (FIFO_TOP (&message_queue))    THREAD_WRITE_ON (master, t_write, zebra_server_dequeue, NULL, sock);  return 0;}/* Enqueu message.  */voidzebra_server_enqueue (int sock, u_char *buf, unsigned long length,		      unsigned long written){  struct zebra_message_queue *queue;  queue = XCALLOC (MTYPE_TMP, sizeof (struct zebra_message_queue));  queue->buf = XMALLOC (MTYPE_TMP, length);  memcpy (queue->buf, buf, length);  queue->length = length;  queue->written = written;  FIFO_ADD (&message_queue, queue);  THREAD_WRITE_ON (master, t_write, zebra_server_dequeue, NULL, sock);}intzebra_server_send_message (int sock, u_char *buf, unsigned long length){  int nbytes;  if (FIFO_TOP (&message_queue))    {      zebra_server_enqueue (sock, buf, length, 0);      return 0;    }  /* Send message.  */  nbytes = write (sock, buf, length);  if (nbytes <= 0)    {      if (errno == EAGAIN)        zebra_server_enqueue (sock, buf, length, 0);      else	return -1;    }  else if (nbytes != length)    zebra_server_enqueue (sock, buf, length, nbytes);  return 0;}/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */intzsend_interface_add (struct zserv *client, struct interface *ifp){  struct stream *s;  /* Check this client need interface information. */  if (! client->ifinfo)    return -1;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  /* Message type. */  stream_putc (s, ZEBRA_INTERFACE_ADD);  /* Interface information. */  stream_put (s, ifp->name, INTERFACE_NAMSIZ);  stream_putl (s, ifp->ifindex);  stream_putl (s, ifp->flags);  stream_putl (s, ifp->metric);  stream_putl (s, ifp->mtu);  stream_putl (s, ifp->bandwidth);#ifdef HAVE_SOCKADDR_DL  stream_put (s, &ifp->sdl, sizeof (ifp->sdl));#else  stream_putl (s, ifp->hw_addr_len);  if (ifp->hw_addr_len)    stream_put (s, ifp->hw_addr, ifp->hw_addr_len);#endif /* HAVE_SOCKADDR_DL */  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}/* Interface deletion from zebra daemon. */intzsend_interface_delete (struct zserv *client, struct interface *ifp){  struct stream *s;  /* Check this client need interface information. */  if (! client->ifinfo)    return -1;  s = client->obuf;  stream_reset (s);  /* Packet length placeholder. */  stream_putw (s, 0);  /* Interface information. */  stream_putc (s, ZEBRA_INTERFACE_DELETE);  stream_put (s, ifp->name, INTERFACE_NAMSIZ);  stream_putl (s, ifp->ifindex);  stream_putl (s, ifp->flags);  stream_putl (s, ifp->metric);  stream_putl (s, ifp->mtu);  stream_putl (s, ifp->bandwidth);  /* Write packet length. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}/* Interface address is added. Send ZEBRA_INTERFACE_ADDRESS_ADD to the   client. */intzsend_interface_address_add (struct zserv *client, struct interface *ifp, 			     struct connected *ifc){  int blen;  struct stream *s;  struct prefix *p;  /* Check this client need interface information. */  if (! client->ifinfo)    return -1;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  stream_putc (s, ZEBRA_INTERFACE_ADDRESS_ADD);  stream_putl (s, ifp->ifindex);  /* Interface address flag. */  stream_putc (s, ifc->flags);  /* Prefix information. */  p = ifc->address;  stream_putc (s, p->family);  blen = prefix_blen (p);  stream_put (s, &p->u.prefix, blen);  stream_putc (s, p->prefixlen);  /* Destination. */  p = ifc->destination;  if (p)    stream_put (s, &p->u.prefix, blen);  else    stream_put (s, NULL, blen);  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}/* Interface address is deleted. Send ZEBRA_INTERFACE_ADDRESS_DELETE   to the client. */intzsend_interface_address_delete (struct zserv *client, struct interface *ifp,				struct connected *ifc){  int blen;  struct stream *s;  struct prefix *p;  /* Check this client need interface information. */  if (! client->ifinfo)    return -1;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  stream_putc (s, ZEBRA_INTERFACE_ADDRESS_DELETE);  stream_putl (s, ifp->ifindex);  /* Interface address flag. */  stream_putc (s, ifc->flags);  /* Prefix information. */  p = ifc->address;  stream_putc (s, p->family);  blen = prefix_blen (p);  stream_put (s, &p->u.prefix, blen);  p = ifc->destination;  if (p)    stream_put (s, &p->u.prefix, blen);  else    stream_put (s, NULL, blen);  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}intzsend_interface_up (struct zserv *client, struct interface *ifp){  struct stream *s;  /* Check this client need interface information. */  if (! client->ifinfo)    return -1;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  /* Zebra command. */  stream_putc (s, ZEBRA_INTERFACE_UP);  /* Interface information. */  stream_put (s, ifp->name, INTERFACE_NAMSIZ);  stream_putl (s, ifp->ifindex);  stream_putl (s, ifp->flags);  stream_putl (s, ifp->metric);  stream_putl (s, ifp->mtu);  stream_putl (s, ifp->bandwidth);  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}intzsend_interface_down (struct zserv *client, struct interface *ifp){  struct stream *s;  /* Check this client need interface information. */  if (! client->ifinfo)    return -1;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  /* Zebra command. */  stream_putc (s, ZEBRA_INTERFACE_DOWN);  /* Interface information. */  stream_put (s, ifp->name, INTERFACE_NAMSIZ);  stream_putl (s, ifp->ifindex);  stream_putl (s, ifp->flags);  stream_putl (s, ifp->metric);  stream_putl (s, ifp->mtu);  stream_putl (s, ifp->bandwidth);  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}intzsend_ipv4_add_multipath (struct zserv *client, struct prefix *p, 			  struct rib *rib){  int psize;  struct stream *s;  struct nexthop *nexthop;  struct in_addr empty;  empty.s_addr = 0;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  /* Put command, type and nexthop. */  stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);  stream_putc (s, rib->type);  stream_putc (s, rib->flags);  stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC);  /* Prefix. */  psize = PSIZE (p->prefixlen);  stream_putc (s, p->prefixlen);  stream_write (s, (u_char *)&p->u.prefix, psize);  /* Nexthop */  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)    {      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))	{	  stream_putc (s, 1);	  if (nexthop->type == NEXTHOP_TYPE_IPV4	      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)	    stream_put_in_addr (s, &nexthop->gate.ipv4);	  else	    stream_put_in_addr (s, &empty);	  /* Interface index. */	  stream_putc (s, 1);	  stream_putl (s, nexthop->ifindex);	  break;	}    }  /* Metric */  stream_putl (s, rib->metric);  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}intzsend_ipv4_delete_multipath (struct zserv *client, struct prefix *p,			     struct rib *rib){  int psize;  struct stream *s;  struct nexthop *nexthop;  struct in_addr empty;  empty.s_addr = 0;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  /* Put command, type and nexthop. */  stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);  stream_putc (s, rib->type);  stream_putc (s, rib->flags);  stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);  /* Prefix. */  psize = PSIZE (p->prefixlen);  stream_putc (s, p->prefixlen);  stream_write (s, (u_char *)&p->u.prefix, psize);  /* Nexthop */  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)    {      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))	{	  stream_putc (s, 1);	  if (nexthop->type == NEXTHOP_TYPE_IPV4)	    stream_put_in_addr (s, &nexthop->gate.ipv4);	  else	    stream_put_in_addr (s, &empty);	  /* Interface index. */	  stream_putc (s, 1);	  stream_putl (s, nexthop->ifindex);	  break;	}    }  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}intzsend_ipv4_add (struct zserv *client, int type, int flags,		struct prefix_ipv4 *p, struct in_addr *nexthop,		unsigned int ifindex){  int psize;  struct stream *s;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  /* Put command, type and nexthop. */  stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);  stream_putc (s, type);  stream_putc (s, flags);  stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);  /* Prefix. */  psize = PSIZE (p->prefixlen);  stream_putc (s, p->prefixlen);  stream_write (s, (u_char *)&p->prefix, psize);  /* Nexthop */  stream_putc (s, 1);  stream_put_in_addr (s, nexthop);  /* Interface index. */  stream_putc (s, 1);  stream_putl (s, ifindex);  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}intzsend_ipv4_delete (struct zserv *client, int type, int flags,		   struct prefix_ipv4 *p, struct in_addr *nexthop,		   unsigned int ifindex){  int psize;  struct stream *s;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  /* Put command, type and nexthop. */  stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);  stream_putc (s, type);  stream_putc (s, flags);  stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);  /* Prefix. */  psize = PSIZE (p->prefixlen);  stream_putc (s, p->prefixlen);  stream_write (s, (u_char *)&p->prefix, psize);  /* Nexthop */  stream_putc (s, 1);  stream_put_in_addr (s, nexthop);  /* Interface index. */  stream_putc (s, 1);  stream_putl (s, ifindex);  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}#ifdef HAVE_IPV6intzsend_ipv6_add (struct zserv *client, int type, int flags,		struct prefix_ipv6 *p, struct in6_addr *nexthop,		unsigned int ifindex){  int psize;  struct stream *s;  s = client->obuf;  stream_reset (s);  /* Place holder for size. */  stream_putw (s, 0);  /* Put command, type and nexthop. */  stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);  stream_putc (s, type);  stream_putc (s, flags);  stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX);  /* Prefix. */  psize = PSIZE (p->prefixlen);  stream_putc (s, p->prefixlen);  stream_write (s, (u_char *)&p->prefix, psize);  /* Nexthop */  stream_putc (s, 1);  stream_write (s, (u_char *)nexthop, 16);  /* Interface index. */  stream_putc (s, 1);  stream_putl (s, ifindex);  /* Write packet size. */  stream_putw_at (s, 0, stream_get_endp (s));  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));  return 0;}

⌨️ 快捷键说明

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