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

📄 tun.c

📁 tun虚拟网卡设备源码
💻 C
📖 第 1 页 / 共 5 页
字号:
      for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)	{	  if (tr != tr1 && !strcmp (tr->guid, tr1->guid))	    warn_tap_dup = true;	}    }  /* warn on registry inconsistencies */  if (warn_tap_dup)    msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate GUIDs");  if (warn_panel_dup)    msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate links from the Network Connections control panel");  if (warn_panel_null)    msg (warnlev, "WARNING: Some TAP-Win32 adapters have no link from the Network Connections control panel");  gc_free (&gc);}/* * Confirm that GUID is a TAP-Win32 adapter. */static boolis_tap_win32 (const char *guid, const struct tap_reg *tap_reg){  const struct tap_reg *tr;  for (tr = tap_reg; tr != NULL; tr = tr->next)    {      if (guid && !strcmp (tr->guid, guid))	return true;    }  return false;}static const char *guid_to_name (const char *guid, const struct panel_reg *panel_reg){  const struct panel_reg *pr;  for (pr = panel_reg; pr != NULL; pr = pr->next)    {      if (guid && !strcmp (pr->guid, guid))	return pr->name;    }  return NULL;}static const char *name_to_guid (const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg){  const struct panel_reg *pr;  for (pr = panel_reg; pr != NULL; pr = pr->next)    {      if (name && !strcmp (pr->name, name) && is_tap_win32 (pr->guid, tap_reg))	return pr->guid;    }  return NULL;}static voidat_least_one_tap_win32 (const struct tap_reg *tap_reg){  if (!tap_reg)    msg (M_FATAL, "There are no TAP-Win32 adapters on this system.  You should be able to create a TAP-Win32 adapter by going to Start -> All Programs -> " PACKAGE_NAME " -> Add a new TAP-Win32 virtual ethernet adapter.");}/* * Get an adapter GUID and optional actual_name from the  * registry for the TAP device # = device_number. */static const char *get_unspecified_device_guid (const int device_number,		             char *actual_name,		             int actual_name_size,			     const struct tap_reg *tap_reg_src,			     const struct panel_reg *panel_reg_src,		             struct gc_arena *gc){  const struct tap_reg *tap_reg = tap_reg_src;  struct buffer ret = clear_buf ();  struct buffer actual = clear_buf ();  int i;  ASSERT (device_number >= 0);  /* Make sure we have at least one TAP adapter */  if (!tap_reg)    return NULL;  /* The actual_name output buffer may be NULL */  if (actual_name)    {      ASSERT (actual_name_size > 0);      buf_set_write (&actual, actual_name, actual_name_size);    }  /* Move on to specified device number */  for (i = 0; i < device_number; i++)    {      tap_reg = tap_reg->next;      if (!tap_reg)	return NULL;    }  /* Save Network Panel name (if exists) in actual_name */  if (actual_name)    {      const char *act = guid_to_name (tap_reg->guid, panel_reg_src);      if (act)	buf_printf (&actual, "%s", act);      else	buf_printf (&actual, "NULL");    }  /* Save GUID for return value */  ret = alloc_buf_gc (256, gc);  buf_printf (&ret, "%s", tap_reg->guid);  return BSTR (&ret);}/* * Lookup a --dev-node adapter name in the registry * returning the GUID and optional actual_name. */static const char *get_device_guid (const char *name,		 char *actual_name,		 int actual_name_size,		 const struct tap_reg *tap_reg,		 const struct panel_reg *panel_reg,		 struct gc_arena *gc){  struct buffer ret = alloc_buf_gc (256, gc);  struct buffer actual = clear_buf ();  /* Make sure we have at least one TAP adapter */  if (!tap_reg)    return NULL;  /* The actual_name output buffer may be NULL */  if (actual_name)    {      ASSERT (actual_name_size > 0);      buf_set_write (&actual, actual_name, actual_name_size);    }  /* Check if GUID was explicitly specified as --dev-node parameter */  if (is_tap_win32 (name, tap_reg))    {      const char *act = guid_to_name (name, panel_reg);      buf_printf (&ret, "%s", name);      if (act)	buf_printf (&actual, "%s", act);      else	buf_printf (&actual, "NULL");      return BSTR (&ret);    }  /* Lookup TAP adapter in network connections list */  {    const char *guid = name_to_guid (name, tap_reg, panel_reg);    if (guid)      {	buf_printf (&actual, "%s", name);	buf_printf (&ret, "%s", guid);	return BSTR (&ret);      }  }  return NULL;}/* * Return a TAP name for netsh commands. */const char *get_netsh_id (const char *dev_node, struct gc_arena *gc){  const struct tap_reg *tap_reg = get_tap_reg (gc);  const struct panel_reg *panel_reg = get_panel_reg (gc);  struct buffer actual = alloc_buf_gc (256, gc);  const char *guid;  at_least_one_tap_win32 (tap_reg);  if (dev_node)    {      guid = get_device_guid (dev_node, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);    }  else    {      guid = get_unspecified_device_guid (0, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);      if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Win32 adapter */	guid = NULL;    }  if (!guid)    return "NULL";         /* not found */  else if (strcmp (BPTR (&actual), "NULL"))    return BPTR (&actual); /* control panel name */  else    return guid;           /* no control panel name, return GUID instead */}/* * Get adapter info list */const IP_ADAPTER_INFO *get_adapter_info_list (struct gc_arena *gc){  ULONG size = 0;  IP_ADAPTER_INFO *pi = NULL;  DWORD status;  if ((status = GetAdaptersInfo (NULL, &size)) != ERROR_BUFFER_OVERFLOW)    {      msg (M_INFO, "GetAdaptersInfo #1 failed (status=%u) : %s",	   (unsigned int)status,	   strerror_win32 (status, gc));    }  else    {      pi = (PIP_ADAPTER_INFO) gc_malloc (size, false, gc);      if ((status = GetAdaptersInfo (pi, &size)) == NO_ERROR)	return pi;      else	{	  msg (M_INFO, "GetAdaptersInfo #2 failed (status=%u) : %s",	       (unsigned int)status,	       strerror_win32 (status, gc));	}    }  return pi;}static const IP_INTERFACE_INFO *get_interface_info_list (struct gc_arena *gc){  ULONG size = 0;  IP_INTERFACE_INFO *ii = NULL;  DWORD status;  if ((status = GetInterfaceInfo (NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)    {      msg (M_INFO, "GetInterfaceInfo #1 failed (status=%u) : %s",	   (unsigned int)status,	   strerror_win32 (status, gc));    }  else    {      ii = (PIP_INTERFACE_INFO) gc_malloc (size, false, gc);      if ((status = GetInterfaceInfo (ii, &size)) == NO_ERROR)	return ii;      else	{	  msg (M_INFO, "GetInterfaceInfo #2 failed (status=%u) : %s",	       (unsigned int)status,	       strerror_win32 (status, gc));	}    }  return ii;}static const IP_ADAPTER_INDEX_MAP *get_interface_info (DWORD index, struct gc_arena *gc){  const IP_INTERFACE_INFO *list = get_interface_info_list (gc);  if (list)    {      int i;      for (i = 0; i < list->NumAdapters; ++i)	{	  const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];	  if (index == inter->Index)	    return inter;	}    }  return NULL;}/* * Given an adapter index, return a pointer to the * IP_ADAPTER_INFO structure for that adapter. */static const IP_ADAPTER_INFO *get_adapter (const IP_ADAPTER_INFO *ai, DWORD index){  if (ai && index != (DWORD)~0)    {      const IP_ADAPTER_INFO *a;      /* find index in the linked list */      for (a = ai; a != NULL; a = a->Next)	{	  if (a->Index == index)	    return a;	}    }  return NULL;}static const IP_ADAPTER_INFO *get_adapter_info (DWORD index, struct gc_arena *gc){  return get_adapter (get_adapter_info_list (gc), index);}static intget_adapter_n_ip_netmask (const IP_ADAPTER_INFO *ai){  if (ai)    {      int n = 0;      const IP_ADDR_STRING *ip = &ai->IpAddressList;      while (ip)	{	  ++n;	  ip = ip->Next;	}      return n;    }  else    return 0;}static boolget_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask){  bool ret = false;  *ip = 0;  *netmask = 0;  if (ai)    {      const IP_ADDR_STRING *iplist = &ai->IpAddressList;      int i = 0;      while (iplist)	{	  if (i == n)	    break;	  ++i;	  iplist = iplist->Next;	}      if (iplist)	{	  const unsigned int getaddr_flags = GETADDR_HOST_ORDER;	  const char *ip_str = iplist->IpAddress.String;	  const char *netmask_str = iplist->IpMask.String;	  bool succeed1 = false;	  bool succeed2 = false;	  if (ip_str && netmask_str && strlen (ip_str) && strlen (netmask_str))	    {	      *ip = getaddr (getaddr_flags, ip_str, 0, &succeed1, NULL);	      *netmask = getaddr (getaddr_flags, netmask_str, 0, &succeed2, NULL);	      ret = (succeed1 == true && succeed2 == true);	    }	}    }  return ret;}const IP_ADAPTER_INFO *get_tun_adapter (const struct tuntap *tt, const IP_ADAPTER_INFO *list){  if (list && tt)    return get_adapter (list, tt->adapter_index);  else    return NULL;}boolis_adapter_up (const struct tuntap *tt, const IP_ADAPTER_INFO *list){  int i;  bool ret = false;  const IP_ADAPTER_INFO *ai = get_tun_adapter (tt, list);  if (ai)    {      const int n = get_adapter_n_ip_netmask (ai);      /* loop once for every IP/netmask assigned to adapter */      for (i = 0; i < n; ++i)	{	  in_addr_t ip, netmask;	  if (get_adapter_ip_netmask (ai, i, &ip, &netmask))	    {	      if (tt->local && tt->adapter_netmask)		{		  /* wait for our --ifconfig parms to match the actual adapter parms */		  if (tt->local == ip && tt->adapter_netmask == netmask)		    ret = true;		}	      else		{		  /* --ifconfig was not defined, maybe using a real DHCP server */		  if (ip && netmask)		    ret = true;		}	    }	}    }  else    ret = true; /* this can occur when TAP adapter is bridged */  return ret;}boolis_ip_in_adapter_subnet (const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask){  int i;  bool ret = false;  if (highest_netmask)    *highest_netmask = 0;  if (ai)    {      const int n = get_adapter_n_ip_netmask (ai);      for (i = 0; i < n; ++i)	{	  in_addr_t adapter_ip, adapter_netmask;	  if (get_adapter_ip_netmask (ai, i, &adapter_ip, &adapter_netmask))	    {	      if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))		{		  if (highest_netmask && adapter_netmask > *highest_netmask)		    *highest_netmask = adapter_netmask;		  ret = true;		}	    }	}    }  return ret;}DWORDadapter_index_of_ip (const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count){  struct gc_arena gc = gc_new ();  DWORD ret = ~0;  in_addr_t highest_netmask = 0;  bool first = true;  if (count)    *count = 0;  while (list)    {      in_addr_t hn;      if (is_ip_in_adapter_subnet (list, ip, &hn))	{	  if (first || hn > highest_netmask)	    {	      highest_netmask = hn;	      if (count)		*count = 1;	      ret = list->Index;	      first = false;	    }	  else if (hn == highest_netmask)	    {	      if (count)		++*count;	    }	}      list = list->Next;    }  dmsg (D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d",       print_in_addr_t (ip, 0, &gc),       print_in_addr_t (highest_netmask, 0, &gc),       (int)ret,       count ? *count : -1);  if (ret == ~0 && count)    *count = 0;  gc_free (&gc);  return ret;}/* * Given an adapter index, return true if the adapter * is DHCP disabled. */static booldhcp_disabled (DWORD index){  struct gc_arena gc = gc_new ();  const IP_ADAPTER_INFO *ai = get_adapter_info (index, &gc);  bool ret = false;  if (ai && !ai->DhcpEnabled)    ret = true;  gc_free (&gc);  return ret;}/* * Delete all temporary address/netmask pairs which were added * to adapter (given by index) by previous calls to AddIPAddress. */static voiddelete_temp_addresses (DWORD index){  struct gc_arena gc = gc_new ();  const IP_ADAPTER_INFO *a = get_adapter_info (index, &gc);  if (a)    {      const IP_ADDR_STRING *ip = &a->IpAddressList;      while (ip)	{	  DWORD status;	  const DWORD c

⌨️ 快捷键说明

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