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

📄 kernel_socket.c

📁 zebra测试源代码用于 SOCKET 通信
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Kernel communication using routing socket. * Copyright (C) 1999 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 "if.h"#include "prefix.h"#include "sockunion.h"#include "connected.h"#include "memory.h"#include "ioctl.h"#include "log.h"#include "str.h"#include "table.h"#include "rib.h"#include "zebra/interface.h"#include "zebra/zserv.h"#include "zebra/debug.h"/* Socket length roundup function. */#define ROUNDUP(a) \  ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))/* And this macro is wrapper for handling sa_len. */#ifdef HAVE_SA_LEN#define WRAPUP(X)   ROUNDUP(((struct sockaddr *)(X))->sa_len)#else#define WRAPUP(X)   ROUNDUP(sizeof (struct sockaddr))#endif /* HAVE_SA_LEN *//* Routing socket message types. */struct message rtm_type_str[] ={  {RTM_ADD,      "RTM_ADD"},  {RTM_DELETE,   "RTM_DELETE"},  {RTM_CHANGE,   "RTM_CHANGE"},  {RTM_GET,      "RTM_GET"},  {RTM_LOSING,   "RTM_LOSING"},  {RTM_REDIRECT, "RTM_REDIRECT"},  {RTM_MISS,     "RTM_MISS"},  {RTM_LOCK,     "RTM_LOCK"},  {RTM_OLDADD,   "RTM_OLDADD"},  {RTM_OLDDEL,   "RTM_OLDDEL"},  {RTM_RESOLVE,  "RTM_RESOLVE"},  {RTM_NEWADDR,  "RTM_NEWADDR"},  {RTM_DELADDR,  "RTM_DELADDR"},  {RTM_IFINFO,   "RTM_IFINFO"},#ifdef RTM_OIFINFO  {RTM_OIFINFO,   "RTM_OIFINFO"},#endif /* RTM_OIFINFO */#ifdef RTM_NEWMADDR  {RTM_NEWMADDR, "RTM_NEWMADDR"},#endif /* RTM_NEWMADDR */#ifdef RTM_DELMADDR  {RTM_DELMADDR, "RTM_DELMADDR"},#endif /* RTM_DELMADDR */#ifdef RTM_IFANNOUNCE  {RTM_IFANNOUNCE, "RTM_IFANNOUNCE"},#endif /* RTM_IFANNOUNCE */  {0,            NULL}};struct message rtm_flag_str[] ={  {RTF_UP,        "UP"},  {RTF_GATEWAY,   "GATEWAY"},  {RTF_HOST,      "HOST"},  {RTF_REJECT,    "REJECT"},  {RTF_DYNAMIC,   "DYNAMIC"},  {RTF_MODIFIED,  "MODIFIED"},  {RTF_DONE,      "DONE"},#ifdef RTF_MASK  {RTF_MASK,      "MASK"},#endif /* RTF_MASK */  {RTF_CLONING,   "CLONING"},  {RTF_XRESOLVE,  "XRESOLVE"},  {RTF_LLINFO,    "LLINFO"},  {RTF_STATIC,    "STATIC"},  {RTF_BLACKHOLE, "BLACKHOLE"},  {RTF_PROTO1,    "PROTO1"},  {RTF_PROTO2,    "PROTO2"},#ifdef RTF_PRCLONING  {RTF_PRCLONING, "PRCLONING"},#endif /* RTF_PRCLONING */#ifdef RTF_WASCLONED  {RTF_WASCLONED, "WASCLONED"},#endif /* RTF_WASCLONED */#ifdef RTF_PROTO3  {RTF_PROTO3,    "PROTO3"},#endif /* RTF_PROTO3 */#ifdef RTF_PINNED  {RTF_PINNED,    "PINNED"},#endif /* RTF_PINNED */#ifdef RTF_LOCAL  {RTF_LOCAL,    "LOCAL"},#endif /* RTF_LOCAL */#ifdef RTF_BROADCAST  {RTF_BROADCAST, "BROADCAST"},#endif /* RTF_BROADCAST */#ifdef RTF_MULTICAST  {RTF_MULTICAST, "MULTICAST"},#endif /* RTF_MULTICAST */  {0,             NULL}};/* Kernel routing update socket. */int routing_sock = -1;/* Yes I'm checking ugly routing socket behavior. *//* #define DEBUG *//* Supported address family check. */static intaf_check (int family){  if (family == AF_INET)    return 1;#ifdef HAVE_IPV6  if (family == AF_INET6)    return 1;#endif /* HAVE_IPV6 */  return 0;}/* Dump routing table flag for debug purpose. */voidrtm_flag_dump (int flag){  struct message *mes;  static char buf[BUFSIZ];  buf[0] = '0';  for (mes = rtm_flag_str; mes->key != 0; mes++)    {      if (mes->key & flag)	{	  strlcat (buf, mes->str, BUFSIZ);	  strlcat (buf, " ", BUFSIZ);	}    }  zlog_info ("Kernel: %s", buf);}#ifdef RTM_IFANNOUNCE/* Interface adding function */intifan_read (struct if_announcemsghdr *ifan){  struct interface *ifp;  ifp = if_lookup_by_index (ifan->ifan_index);  if (ifp == NULL && ifan->ifan_what == IFAN_ARRIVAL)    {      /* Create Interface */      ifp = if_get_by_name (ifan->ifan_name);      ifp->ifindex = ifan->ifan_index;      if_add_update (ifp);    }  else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE)    {      if_delete_update (ifp);      if_delete (ifp);    }  if_get_flags (ifp);  if_get_mtu (ifp);  if_get_metric (ifp);  if (IS_ZEBRA_DEBUG_KERNEL)    zlog_info ("interface %s index %d", ifp->name, ifp->ifindex);  return 0;}#endif /* RTM_IFANNOUNCE *//* Interface adding function called from interface_list. */intifm_read (struct if_msghdr *ifm){  struct interface *ifp;  struct sockaddr_dl *sdl = NULL;  sdl = (struct sockaddr_dl *)(ifm + 1);  /* Use sdl index. */  ifp = if_lookup_by_index (ifm->ifm_index);  if (ifp == NULL)    {      /* Check interface's address.*/      if (! (ifm->ifm_addrs & RTA_IFP))	{	  zlog_warn ("There must be RTA_IFP address for ifindex %d\n",		     ifm->ifm_index);	  return -1;	}      ifp = if_create ();      strncpy (ifp->name, sdl->sdl_data, sdl->sdl_nlen);      ifp->ifindex = ifm->ifm_index;      ifp->flags = ifm->ifm_flags;#if defined(__bsdi__)      if_kvm_get_mtu (ifp);#else      if_get_mtu (ifp);#endif /* __bsdi__ */      if_get_metric (ifp);      /* Fetch hardware address. */      if (sdl->sdl_family != AF_LINK)	{	  zlog_warn ("sockaddr_dl->sdl_family is not AF_LINK");	  return -1;	}      memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl));      if_add_update (ifp);    }  else    {      /* There is a case of promisc, allmulti flag modification. */      if (if_is_up (ifp))	{	  ifp->flags = ifm->ifm_flags;	  if (! if_is_up (ifp))	    if_down (ifp);	}      else	{	  ifp->flags = ifm->ifm_flags;	  if (if_is_up (ifp))	    if_up (ifp);	}    }  #ifdef HAVE_NET_RT_IFLIST  ifp->stats = ifm->ifm_data;#endif /* HAVE_NET_RT_IFLIST */  if (IS_ZEBRA_DEBUG_KERNEL)    zlog_info ("interface %s index %d", ifp->name, ifp->ifindex);  return 0;}/* Address read from struct ifa_msghdr. */voidifam_read_mesg (struct ifa_msghdr *ifm,		union sockunion *addr,		union sockunion *mask,		union sockunion *dest){  caddr_t pnt, end;  pnt = (caddr_t)(ifm + 1);  end = ((caddr_t)ifm) + ifm->ifam_msglen;#define IFAMADDRGET(X,R) \    if (ifm->ifam_addrs & (R)) \      { \        int len = WRAPUP(pnt); \        if (((X) != NULL) && af_check (((struct sockaddr *)pnt)->sa_family)) \          memcpy ((caddr_t)(X), pnt, len); \        pnt += len; \      }#define IFAMMASKGET(X,R) \    if (ifm->ifam_addrs & (R)) \      { \	int len = WRAPUP(pnt); \        if ((X) != NULL) \	  memcpy ((caddr_t)(X), pnt, len); \	pnt += len; \      }  /* Be sure structure is cleared */  memset (mask, 0, sizeof (union sockunion));  memset (addr, 0, sizeof (union sockunion));  memset (dest, 0, sizeof (union sockunion));  /* We fetch each socket variable into sockunion. */  IFAMADDRGET (NULL, RTA_DST);  IFAMADDRGET (NULL, RTA_GATEWAY);  IFAMMASKGET (mask, RTA_NETMASK);  IFAMADDRGET (NULL, RTA_GENMASK);  IFAMADDRGET (NULL, RTA_IFP);  IFAMADDRGET (addr, RTA_IFA);  IFAMADDRGET (NULL, RTA_AUTHOR);  IFAMADDRGET (dest, RTA_BRD);  /* Assert read up end point matches to end point */  if (pnt != end)    zlog_warn ("ifam_read() does't read all socket data");}/* Interface's address information get. */intifam_read (struct ifa_msghdr *ifam){  struct interface *ifp;  union sockunion addr, mask, gate;  /* Check does this interface exist or not. */  ifp = if_lookup_by_index (ifam->ifam_index);  if (ifp == NULL)     {      zlog_warn ("no interface for index %d", ifam->ifam_index);       return -1;    }  /* Allocate and read address information. */  ifam_read_mesg (ifam, &addr, &mask, &gate);  /* Check interface flag for implicit up of the interface. */  if_refresh (ifp);  /* Add connected address. */  switch (sockunion_family (&addr))    {    case AF_INET:      if (ifam->ifam_type == RTM_NEWADDR)	connected_add_ipv4 (ifp, 0, &addr.sin.sin_addr, 			    ip_masklen (mask.sin.sin_addr),			    &gate.sin.sin_addr, NULL);      else	connected_delete_ipv4 (ifp, 0, &addr.sin.sin_addr, 			       ip_masklen (mask.sin.sin_addr),			       &gate.sin.sin_addr, NULL);      break;#ifdef HAVE_IPV6    case AF_INET6:      /* Unset interface index from link-local address when IPv6 stack	 is KAME. */      if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr))	SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0);      if (ifam->ifam_type == RTM_NEWADDR)	connected_add_ipv6 (ifp,			    &addr.sin6.sin6_addr, 			    ip6_masklen (mask.sin6.sin6_addr),			    &gate.sin6.sin6_addr);      else	connected_delete_ipv6 (ifp,			       &addr.sin6.sin6_addr, 			       ip6_masklen (mask.sin6.sin6_addr),			       &gate.sin6.sin6_addr);      break;#endif /* HAVE_IPV6 */    default:      /* Unsupported family silently ignore... */      break;    }  return 0;}/* Interface function for reading kernel routing table information. */intrtm_read_mesg (struct rt_msghdr *rtm,	       union sockunion *dest,	       union sockunion *mask,	       union sockunion *gate){  caddr_t pnt, end;  /* Pnt points out socket data start point. */  pnt = (caddr_t)(rtm + 1);  end = ((caddr_t)rtm) + rtm->rtm_msglen;  /* rt_msghdr version check. */  if (rtm->rtm_version != RTM_VERSION)       zlog (NULL, LOG_WARNING,	      "Routing message version different %d should be %d."	      "This may cause problem\n", rtm->rtm_version, RTM_VERSION);#define RTMADDRGET(X,R) \    if (rtm->rtm_addrs & (R)) \      { \	int len = WRAPUP (pnt); \        if (((X) != NULL) && af_check (((struct sockaddr *)pnt)->sa_family)) \	  memcpy ((caddr_t)(X), pnt, len); \	pnt += len; \      }#define RTMMASKGET(X,R) \    if (rtm->rtm_addrs & (R)) \      { \	int len = WRAPUP (pnt); \        if ((X) != NULL) \

⌨️ 快捷键说明

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