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

📄 route.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (r->metric_defined)    buf_printf (&buf, " -rtt %d", r->metric);#endif  buf_printf (&buf, " %s -netmask %s %s",	      network,	      netmask,	      gateway);  msg (D_ROUTE, "%s", BSTR (&buf));  status = system_check (BSTR (&buf), "ERROR: Solaris route add command failed", false);#elif defined(TARGET_FREEBSD)  buf_printf (&buf, ROUTE_PATH " add");#if 0  if (r->metric_defined)    buf_printf (&buf, " -rtt %d", r->metric);#endif  buf_printf (&buf, " -net %s %s %s",	      network,	      gateway,	      netmask);  msg (D_ROUTE, "%s", BSTR (&buf));  status = system_check (BSTR (&buf), "ERROR: FreeBSD route add command failed", false);#elif defined(TARGET_DARWIN)  buf_printf (&buf, ROUTE_PATH " add");#if 0  if (r->metric_defined)    buf_printf (&buf, " -rtt %d", r->metric);#endif  buf_printf (&buf, " -net %s %s %s",              network,              gateway,              netmask);  msg (D_ROUTE, "%s", BSTR (&buf));  status = system_check (BSTR (&buf), "ERROR: FreeBSD route add command failed", false);#elif defined(TARGET_OPENBSD)  buf_printf (&buf, ROUTE_PATH " add");#if 0  if (r->metric_defined)    buf_printf (&buf, " -rtt %d", r->metric);#endif  buf_printf (&buf, " -net %s %s -netmask %s",	      network,	      gateway,	      netmask);  msg (D_ROUTE, "%s", BSTR (&buf));  status = system_check (BSTR (&buf), "ERROR: OpenBSD route add command failed", false);#else  msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system.  Try putting your routes in a --route-up script");#endif  r->defined = status;  gc_free (&gc);}static voiddelete_route (const struct route *r){  struct gc_arena gc;  struct buffer buf;  const char *network;  const char *netmask;  const char *gateway;  if (!r->defined)    return;  gc_init (&gc);  buf = alloc_buf_gc (256, &gc);  network = print_in_addr_t (r->network, false, &gc);  netmask = print_in_addr_t (r->netmask, false, &gc);  gateway = print_in_addr_t (r->gateway, false, &gc);#if defined(TARGET_LINUX)#ifdef CONFIG_FEATURE_IPROUTE  buf_printf (&buf, IPROUTE_PATH " route del %s/%d",	      network,	      count_netmask_bits(netmask));#else  buf_printf (&buf, ROUTE_PATH " del -net %s netmask %s",	      network,	      netmask);#endif /*CONFIG_FEATURE_IPROUTE*/  msg (D_ROUTE, "%s", BSTR (&buf));  system_check (BSTR (&buf), "ERROR: Linux route delete command failed", false);#elif defined (WIN32)  buf_printf (&buf, ROUTE_PATH " DELETE %s",	      network);  netcmd_semaphore_lock ();  msg (D_ROUTE, "%s", BSTR (&buf));  system_check (BSTR (&buf), "ERROR: Windows route delete command failed", false);  netcmd_semaphore_release ();#elif defined (TARGET_SOLARIS)  buf_printf (&buf, ROUTE_PATH " delete %s -netmask %s %s",	      network,	      netmask,	      gateway);  msg (D_ROUTE, "%s", BSTR (&buf));  system_check (BSTR (&buf), "ERROR: Solaris route delete command failed", false);#elif defined(TARGET_FREEBSD)  buf_printf (&buf, ROUTE_PATH " delete -net %s %s %s",	      network,	      gateway,	      netmask);  msg (D_ROUTE, "%s", BSTR (&buf));  system_check (BSTR (&buf), "ERROR: FreeBSD route delete command failed", false);#elif defined(TARGET_DARWIN)  buf_printf (&buf, ROUTE_PATH " delete -net %s %s %s",              network,              gateway,              netmask);  msg (D_ROUTE, "%s", BSTR (&buf));  system_check (BSTR (&buf), "ERROR: Darwin route delete command failed", false);#elif defined(TARGET_OPENBSD)  buf_printf (&buf, ROUTE_PATH " delete -net %s %s -netmask %s",	      network,	      gateway,	      netmask);  msg (D_ROUTE, "%s", BSTR (&buf));  system_check (BSTR (&buf), "ERROR: OpenBSD route delete command failed", false);#else  msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system.  Try putting your routes in a --route-up script");#endif  gc_free (&gc);}/* * The --redirect-gateway option requires OS-specific code below * to get the current default gateway. */#if defined(WIN32)static boolget_default_gateway (in_addr_t *ret){  struct gc_arena gc = gc_new ();  ULONG size = 0;  DWORD status;  bool ret_bool = false;  if ((status = GetIpForwardTable (NULL, &size, TRUE)) == ERROR_INSUFFICIENT_BUFFER)    {      int i;      PMIB_IPFORWARDTABLE routes = (PMIB_IPFORWARDTABLE) gc_malloc (size, false, &gc);      ASSERT (routes);      if ((status = GetIpForwardTable (routes, &size, TRUE)) != NO_ERROR)	goto done;      for (i = 0; i < routes->dwNumEntries; ++i)	{	  const MIB_IPFORWARDROW *row = &routes->table[i];	  const in_addr_t net = ntohl (row->dwForwardDest);	  const in_addr_t mask = ntohl (row->dwForwardMask);	  const in_addr_t gw = ntohl (row->dwForwardNextHop);#if 0	  msg (M_INFO, "route[%d] %s %s %s",	       i,	       print_in_addr_t ((in_addr_t) net, false, &gc),	       print_in_addr_t ((in_addr_t) mask, false, &gc),	       print_in_addr_t ((in_addr_t) gw, false, &gc));#endif	  if (!net && !mask)	    {	      *ret = gw;	      ret_bool = true;	      break;	    }	}    } done:  gc_free (&gc);  return ret_bool;}#elif defined(TARGET_LINUX)static boolget_default_gateway (in_addr_t *ret){  struct gc_arena gc = gc_new ();  FILE *fp = fopen ("/proc/net/route", "r");  if (fp)    {      char line[256];      int count = 0;      while (fgets (line, sizeof (line), fp) != NULL)	{	  if (count)	    {	      unsigned int net_x = 0;	      unsigned int mask_x = 0;	      unsigned int gw_x = 0;	      const int np = sscanf (line, "%*s\t%x\t%x\t%*s\t%*s\t%*s\t%*s\t%x",				     &net_x,				     &gw_x,				     &mask_x);	      if (np == 3)		{		  const in_addr_t net = ntohl (net_x);		  const in_addr_t mask = ntohl (mask_x);		  const in_addr_t gw = ntohl (gw_x);#if 0		  msg (M_INFO, "route %s %s %s",		       print_in_addr_t ((in_addr_t) net, false, &gc),		       print_in_addr_t ((in_addr_t) mask, false, &gc),		       print_in_addr_t ((in_addr_t) gw, false, &gc));#endif		  if (!net && !mask)		    {		      fclose (fp);		      *ret = gw;		      gc_free (&gc);		      return true;		    }		}	    }	  ++count;	}      fclose (fp);    }  gc_free (&gc);  return false;}#elif defined(TARGET_FREEBSD)#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>/* all of this is taken from <net/route.h> in FreeBSD */#define RTA_DST     0x1#define RTA_GATEWAY 0x2#define RTA_NETMASK 0x4#define RTM_GET     0x4#define RTM_VERSION 5#define RTF_UP      0x1#define RTF_GATEWAY 0x2/* * These numbers are used by reliable protocols for determining * retransmission behavior and are included in the routing structure. */struct rt_metrics {        u_long  rmx_locks;      /* Kernel must leave these values alone */        u_long  rmx_mtu;        /* MTU for this path */        u_long  rmx_hopcount;   /* max hops expected */        u_long  rmx_expire;     /* lifetime for route, e.g. redirect */        u_long  rmx_recvpipe;   /* inbound delay-bandwidth product */        u_long  rmx_sendpipe;   /* outbound delay-bandwidth product */        u_long  rmx_ssthresh;   /* outbound gateway buffer limit */        u_long  rmx_rtt;        /* estimated round trip time */        u_long  rmx_rttvar;     /* estimated rtt variance */        u_long  rmx_pksent;     /* packets sent using this route */        u_long  rmx_filler[4];  /* will be used for T/TCP later */};/* * Structures for routing messages. */struct rt_msghdr {        u_short rtm_msglen;     /* to skip over non-understood messages */        u_char  rtm_version;    /* future binary compatibility */        u_char  rtm_type;       /* message type */        u_short rtm_index;      /* index for associated ifp */        int     rtm_flags;      /* flags, incl. kern & message, e.g. DONE */        int     rtm_addrs;      /* bitmask identifying sockaddrs in msg */        pid_t   rtm_pid;        /* identify sender */        int     rtm_seq;        /* for sender to identify action */        int     rtm_errno;      /* why failed */        int     rtm_use;        /* from rtentry */        u_long  rtm_inits;      /* which metrics we are initializing */        struct  rt_metrics rtm_rmx; /* metrics themselves */};struct {  struct rt_msghdr m_rtm;  char       m_space[512];} m_rtmsg;#define ROUNDUP(a) \        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))static boolget_default_gateway (in_addr_t *ret){  struct gc_arena gc = gc_new ();  int s, seq, l, pid, rtm_addrs, i;  struct sockaddr so_dst, so_mask;  char *cp = m_rtmsg.m_space;   struct sockaddr *gate = NULL, *sa;  struct  rt_msghdr *rtm_aux;#define NEXTADDR(w, u) \        if (rtm_addrs & (w)) {\            l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\        }#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))#define rtm m_rtmsg.m_rtm  pid = getpid();  seq = 0;  rtm_addrs = RTA_DST | RTA_NETMASK;  bzero(&so_dst, sizeof(so_dst));  bzero(&so_mask, sizeof(so_mask));  bzero(&rtm, sizeof(struct rt_msghdr));  rtm.rtm_type = RTM_GET;  rtm.rtm_flags = RTF_UP | RTF_GATEWAY;  rtm.rtm_version = RTM_VERSION;  rtm.rtm_seq = ++seq;  rtm.rtm_addrs = rtm_addrs;   so_dst.sa_family = AF_INET;  so_dst.sa_len = sizeof(struct sockaddr_in);  so_mask.sa_family = AF_INET;  so_mask.sa_len = sizeof(struct sockaddr_in);  NEXTADDR(RTA_DST, so_dst);  NEXTADDR(RTA_NETMASK, so_mask);  rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;  s = socket(PF_ROUTE, SOCK_RAW, 0);  if (write(s, (char *)&m_rtmsg, l) < 0)    {      warn("writing to routing socket");      gc_free (&gc);      return false;    }  do {    l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));  } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));                          rtm_aux = &rtm;  cp = ((char *)(rtm_aux + 1));  if (rtm_aux->rtm_addrs) {    for (i = 1; i; i <<= 1)      if (i & rtm_aux->rtm_addrs) {	sa = (struct sockaddr *)cp;	if (i == RTA_GATEWAY )	  gate = sa;	ADVANCE(cp, sa);      }  }  else    {      gc_free (&gc);      return false;    }  if (gate != NULL )    {      *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);#if 1      msg (M_INFO, "gw %s",	   print_in_addr_t ((in_addr_t) *ret, false, &gc));#endif      gc_free (&gc);      return true;    }  else    {      gc_free (&gc);      return false;    }}#elif defined(TARGET_DARWIN)#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>/* all of this is taken from <net/route.h> in Darwin */#define RTA_DST     0x1#define RTA_GATEWAY 0x2#define RTA_NETMASK 0x4#define RTM_GET     0x4#define RTM_VERSION 5#define RTF_UP      0x1#define RTF_GATEWAY 0x2/* * These numbers are used by reliable protocols for determining * retransmission behavior and are included in the routing structure. */struct rt_metrics {        u_long  rmx_locks;      /* Kernel must leave these values alone */        u_long  rmx_mtu;        /* MTU for this path */        u_long  rmx_hopcount;   /* max hops expected */        u_long  rmx_expire;     /* lifetime for route, e.g. redirect */        u_long  rmx_recvpipe;   /* inbound delay-bandwidth product */        u_long  rmx_sendpipe;   /* outbound delay-bandwidth product */        u_long  rmx_ssthresh;   /* outbound gateway buffer limit */        u_long  rmx_rtt;        /* estimated round trip time */        u_long  rmx_rttvar;     /* estimated rtt variance */        u_long  rmx_pksent;     /* packets sent using this route */        u_long  rmx_filler[4];  /* will be used for T/TCP later */};/* * Structures for routing messages. */struct rt_msghdr {        u_short rtm_msglen;     /* to skip over non-understood messages */        u_char  rtm_version;    /* future binary compatibility */        u_char  rtm_type;       /* message type */        u_short rtm_index;      /* index for associated ifp */        int     rtm_flags;      /* flags, incl. kern & message, e.g. DONE */        int     rtm_addrs;      /* bitmask identifying sockaddrs in msg */        pid_t   rtm_pid;        /* identify sender */        int     rtm_seq;        /* for sender to identify action */        int     rtm_errno;      /* why failed */        int     rtm_use;        /* from rtentry */        u_long  rtm_inits;      /* which metrics we are initializing */        struct  rt_metrics rtm_rmx; /* metrics themselves */};struct {  struct rt_msghdr m_rtm;  char       m_space[512];} m_rtmsg;#define ROUNDUP(a) \        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))static boolget_default_gateway (in_addr_t *ret){  struct gc_arena gc = gc_new ();  int s, seq, l, pid, rtm_addrs, i;  struct sockaddr so_dst, so_mask;  char *cp = m_rtmsg.m_space;   struct sockaddr *gate = NULL, *sa;  struct  rt_msghdr *rtm_aux;#define NEXTADDR(w, u) \        if (rtm_addrs & (w)) {\            l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\        }#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))#define rtm m_rtmsg.m_rtm  pid = getpid();  seq = 0;  rtm_addrs = RTA_DST | RTA_NETMASK;  bzero(&so_dst, sizeof(so_dst));  bzero(&so_mask, sizeof(so_mask));  bzero(&rtm, sizeof(struct rt_msghdr));  rtm.rtm_type = RTM_GET;  rtm.rtm_flags = RTF_UP | RTF_GATEWAY;  rtm.rtm_version = RTM_VERSION;  rtm.rtm_seq = ++seq;  rtm.rtm_addrs = rtm_addrs;   so_dst.sa_family = AF_INET;  so_dst.sa_len = sizeof(struct sockaddr_in);  so_mask.sa_family = AF_INET;  so_mask.sa_len = sizeof(struct sockaddr_in);  NEXTADDR(RTA_DST, so_dst);  NEXTADDR(RTA_NETMASK, so_mask);  rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;  s = socket(PF_ROUTE, SOCK_RAW, 0);  if (write(s, (char *)&m_rtmsg, l) < 0)    {      msg (M_WARN, "ROUTE: problem writing to routing socket");      gc_free (&gc);      return false;    }  do {    l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));  } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));                          rtm_aux = &rtm;  cp = ((char *)(rtm_aux + 1));  if (rtm_aux->rtm_addrs) {    for (i = 1; i; i <<= 1)      if (i & rtm_aux->rtm_addrs) {	sa = (struct sockaddr *)cp;	if (i == RTA_GATEWAY )	  gate = sa;	ADVANCE(cp, sa);      }  }  else    {      gc_free (&gc);      return false;    }  if (gate != NULL )    {      *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);#if 1      msg (M_INFO, "gw %s",	   print_in_addr_t ((in_addr_t) *ret, false, &gc));#endif      gc_free (&gc);      return true;    }  else    {      gc_free (&gc);      return false;    }}#elsestatic boolget_default_gateway (in_addr_t *ret){  return false;}#endifboolnetmask_to_netbits (in_addr_t network, in_addr_t netmask, int *netbits){  int i;  const int addrlen = sizeof (in_addr_t) * 8;  if ((network & netmask) == network)    {      for (i = 0; i <= addrlen; ++i)	{	  in_addr_t mask = netbits_to_netmask (i);	  if (mask == netmask)	    {	      if (i == addrlen)		*netbits = -1;	      else		*netbits = i;	      return true;	    }	}    }  return false;}

⌨️ 快捷键说明

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