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

📄 kernel_socket.c

📁 zebra测试源代码用于 SOCKET 通信
💻 C
📖 第 1 页 / 共 2 页
字号:
	  memcpy ((caddr_t)(X), pnt, len); \	pnt += len; \      }  /* Be sure structure is cleared */  memset (dest, 0, sizeof (union sockunion));  memset (gate, 0, sizeof (union sockunion));  memset (mask, 0, sizeof (union sockunion));  /* We fetch each socket variable into sockunion. */  RTMADDRGET (dest, RTA_DST);  RTMADDRGET (gate, RTA_GATEWAY);  RTMMASKGET (mask, RTA_NETMASK);  RTMADDRGET (NULL, RTA_GENMASK);  RTMADDRGET (NULL, RTA_IFP);  RTMADDRGET (NULL, RTA_IFA);  RTMADDRGET (NULL, RTA_AUTHOR);  RTMADDRGET (NULL, RTA_BRD);  /* If there is netmask information set it's family same as     destination family*/  if (rtm->rtm_addrs & RTA_NETMASK)    mask->sa.sa_family = dest->sa.sa_family;  /* Assert read up to the end of pointer. */  if (pnt != end)       zlog (NULL, LOG_WARNING, "rtm_read() does't read all socket data.");  return rtm->rtm_flags;}voidrtm_read (struct rt_msghdr *rtm){  int flags;  u_char zebra_flags;  union sockunion dest, mask, gate;  zebra_flags = 0;  /* Discard self send message. */  if (rtm->rtm_type != RTM_GET       && (rtm->rtm_pid == pid || rtm->rtm_pid == old_pid))    return;  /* Read destination and netmask and gateway from rtm message     structure. */  flags = rtm_read_mesg (rtm, &dest, &mask, &gate);#ifdef RTF_CLONED	/*bsdi, netbsd 1.6*/  if (flags & RTF_CLONED)    return;#endif#ifdef RTF_WASCLONED	/*freebsd*/  if (flags & RTF_WASCLONED)    return;#endif  if ((rtm->rtm_type == RTM_ADD) && ! (flags & RTF_UP))    return;  /* This is connected route. */  if (! (flags & RTF_GATEWAY))      return;  if (flags & RTF_PROTO1)    SET_FLAG (zebra_flags, ZEBRA_FLAG_SELFROUTE);  /* This is persistent route. */  if (flags & RTF_STATIC)    SET_FLAG (zebra_flags, ZEBRA_FLAG_STATIC);  if (dest.sa.sa_family == AF_INET)    {      struct prefix_ipv4 p;      p.family = AF_INET;      p.prefix = dest.sin.sin_addr;      if (flags & RTF_HOST)	p.prefixlen = IPV4_MAX_PREFIXLEN;      else	p.prefixlen = ip_masklen (mask.sin.sin_addr);      if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD)	rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 		      &p, &gate.sin.sin_addr, 0, 0, 0, 0);      else	rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 		      &p, &gate.sin.sin_addr, 0, 0);    }#ifdef HAVE_IPV6  if (dest.sa.sa_family == AF_INET6)    {      struct prefix_ipv6 p;      unsigned int ifindex = 0;      p.family = AF_INET6;      p.prefix = dest.sin6.sin6_addr;      if (flags & RTF_HOST)	p.prefixlen = IPV6_MAX_PREFIXLEN;      else	p.prefixlen = ip6_masklen (mask.sin6.sin6_addr);#ifdef KAME      if (IN6_IS_ADDR_LINKLOCAL (&gate.sin6.sin6_addr))	{	  ifindex = IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr);	  SET_IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr, 0);	}#endif /* KAME */      if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD)	rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,		      &p, &gate.sin6.sin6_addr, ifindex, 0);      else	rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,			 &p, &gate.sin6.sin6_addr, ifindex, 0);    }#endif /* HAVE_IPV6 */}/* Interface function for the kernel routing table updates.  Support   for RTM_CHANGE will be needed. */intrtm_write (int message,	   union sockunion *dest,	   union sockunion *mask,	   union sockunion *gate,	   unsigned int index,	   int zebra_flags,	   int metric){  int ret;  caddr_t pnt;  struct interface *ifp;  struct sockaddr_in tmp_gate;#ifdef HAVE_IPV6  struct sockaddr_in6 tmp_gate6;#endif /* HAVE_IPV6 */  /* Sequencial number of routing message. */  static int msg_seq = 0;  /* Struct of rt_msghdr and buffer for storing socket's data. */  struct   {    struct rt_msghdr rtm;    char buf[512];  } msg;    memset (&tmp_gate, 0, sizeof (struct sockaddr_in));  tmp_gate.sin_family = AF_INET;#ifdef HAVE_SIN_LEN  tmp_gate.sin_len = sizeof (struct sockaddr_in);#endif /* HAVE_SIN_LEN */#ifdef HAVE_IPV6  memset (&tmp_gate6, 0, sizeof (struct sockaddr_in6));  tmp_gate6.sin6_family = AF_INET6;#ifdef SIN6_LEN  tmp_gate6.sin6_len = sizeof (struct sockaddr_in6);#endif /* SIN6_LEN */#endif /* HAVE_IPV6 */  if (routing_sock < 0)    return ZEBRA_ERR_EPERM;  /* Clear and set rt_msghdr values */  memset (&msg, 0, sizeof (struct rt_msghdr));  msg.rtm.rtm_version = RTM_VERSION;  msg.rtm.rtm_type = message;  msg.rtm.rtm_seq = msg_seq++;  msg.rtm.rtm_addrs = RTA_DST;  msg.rtm.rtm_addrs |= RTA_GATEWAY;  msg.rtm.rtm_flags = RTF_UP;  msg.rtm.rtm_index = index;  if (metric != 0)    {      msg.rtm.rtm_rmx.rmx_hopcount = metric;      msg.rtm.rtm_inits |= RTV_HOPCOUNT;    }  ifp = if_lookup_by_index (index);  if (gate && message == RTM_ADD)    msg.rtm.rtm_flags |= RTF_GATEWAY;  if (! gate && message == RTM_ADD && ifp &&      (ifp->flags & IFF_POINTOPOINT) == 0)    msg.rtm.rtm_flags |= RTF_CLONING;  /* If no protocol specific gateway is specified, use link     address for gateway. */  if (! gate)    {      if (!ifp)        {          zlog_warn ("no gateway found for interface index %d", index);          return -1;        }      gate = (union sockunion *) & ifp->sdl;    }  if (mask)    msg.rtm.rtm_addrs |= RTA_NETMASK;  else if (message == RTM_ADD)     msg.rtm.rtm_flags |= RTF_HOST;  /* Tagging route with flags */  msg.rtm.rtm_flags |= (RTF_PROTO1);  /* Additional flags. */  if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)    msg.rtm.rtm_flags |= RTF_BLACKHOLE;#ifdef HAVE_SIN_LEN#define SOCKADDRSET(X,R) \  if (msg.rtm.rtm_addrs & (R)) \    { \      int len = ROUNDUP ((X)->sa.sa_len); \      memcpy (pnt, (caddr_t)(X), len); \      pnt += len; \    }#else #define SOCKADDRSET(X,R) \  if (msg.rtm.rtm_addrs & (R)) \    { \      int len = ROUNDUP (sizeof((X)->sa)); \      memcpy (pnt, (caddr_t)(X), len); \      pnt += len; \    }#endif /* HAVE_SIN_LEN */  pnt = (caddr_t) msg.buf;  /* Write each socket data into rtm message buffer */  SOCKADDRSET (dest, RTA_DST);  SOCKADDRSET (gate, RTA_GATEWAY);  SOCKADDRSET (mask, RTA_NETMASK);  msg.rtm.rtm_msglen = pnt - (caddr_t) &msg;  ret = write (routing_sock, &msg, msg.rtm.rtm_msglen);  if (ret != msg.rtm.rtm_msglen)     {      if (errno == EEXIST) 	return ZEBRA_ERR_RTEXIST;      if (errno == ENETUNREACH)	return ZEBRA_ERR_RTUNREACH;            zlog_warn ("write : %s (%d)", strerror (errno), errno);      return -1;    }  return 0;}#include "thread.h"#include "zebra/zserv.h"extern struct thread_master *master;/* For debug purpose. */voidrtmsg_debug (struct rt_msghdr *rtm){  char *type = "Unknown";  struct message *mes;  for (mes = rtm_type_str; mes->str; mes++)    if (mes->key == rtm->rtm_type)      {	type = mes->str;	break;      }  zlog_info ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, type);  rtm_flag_dump (rtm->rtm_flags);  zlog_info ("Kernel: message seq %d", rtm->rtm_seq);  zlog_info ("Kernel: pid %d", rtm->rtm_pid);}/* This is pretty gross, better suggestions welcome -- mhandler */#ifndef RTAX_MAX#ifdef RTA_NUMBITS#define RTAX_MAX	RTA_NUMBITS#else#define RTAX_MAX	8#endif /* RTA_NUMBITS */#endif /* RTAX_MAX *//* Kernel routing table and interface updates via routing socket. */intkernel_read (struct thread *thread){  int sock;  int nbytes;  struct rt_msghdr *rtm;  union   {    /* Routing information. */    struct     {      struct rt_msghdr rtm;      struct sockaddr addr[RTAX_MAX];    } r;    /* Interface information. */    struct    {      struct if_msghdr ifm;      struct sockaddr addr[RTAX_MAX];    } im;    /* Interface address information. */    struct    {      struct ifa_msghdr ifa;      struct sockaddr addr[RTAX_MAX];    } ia;#ifdef RTM_IFANNOUNCE    /* Interface arrival/departure */    struct    {      struct if_announcemsghdr ifan;      struct sockaddr addr[RTAX_MAX];    } ian;#endif /* RTM_IFANNOUNCE */  } buf;  /* Fetch routing socket. */  sock = THREAD_FD (thread);  nbytes= read (sock, &buf, sizeof buf);  if (nbytes <= 0)    {      if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN)	zlog_warn ("routing socket error: %s", strerror (errno));      return 0;    }  thread_add_read (master, kernel_read, NULL, sock);#ifdef DEBUG  rtmsg_debug (&buf.r.rtm);#endif /* DEBUG */  rtm = &buf.r.rtm;  switch (rtm->rtm_type)    {    case RTM_ADD:    case RTM_DELETE:      rtm_read (rtm);      break;    case RTM_IFINFO:      ifm_read (&buf.im.ifm);      break;    case RTM_NEWADDR:    case RTM_DELADDR:      ifam_read (&buf.ia.ifa);      break;#ifdef RTM_IFANNOUNCE    case RTM_IFANNOUNCE:      ifan_read (&buf.ian.ifan);      break;#endif /* RTM_IFANNOUNCE */    default:      break;    }  return 0;}/* Make routing socket. */voidrouting_socket (){  routing_sock = socket (AF_ROUTE, SOCK_RAW, 0);  if (routing_sock < 0)     {      zlog_warn ("Can't init kernel routing socket");      return;    }  if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0)     zlog_warn ("Can't set O_NONBLOCK to routing socket");  /* kernel_read needs rewrite. */  thread_add_read (master, kernel_read, NULL, routing_sock);}/* Exported interface function.  This function simply calls   routing_socket (). */voidkernel_init (){  routing_socket ();}

⌨️ 快捷键说明

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