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

📄 tapdrvr.c

📁 一个Windows下的Linux专用虚拟机
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  TAP-Win32 -- A kernel driver to provide virtual tap device *               functionality on Windows.  Originally derived *               from the CIPE-Win32 project by Damion K. Wilson, *               with extensive modifications by James Yonan. * *  All source code which derives from the CIPE-Win32 project is *  Copyright (C) Damion K. Wilson, 2003, and is released under the *  GPL version 2 (see below). * *  All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC, *  and is released under the GPL version 2 (see below). * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 *  as published by the Free Software Foundation. * *  This program 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 this program (see the file COPYING included with this *  distribution); if not, write to the Free Software Foundation, Inc., *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *///======================================================// This driver is designed to work on Win 2000 or higher// versions of Windows.//// It is SMP-safe and handles NDIS 5 power management.//// By default we operate as a "tap" virtual ethernet// 802.3 interface, but we can emulate a "tun"// interface (point-to-point IPv4) through the// TAP_IOCTL_CONFIG_POINT_TO_POINT or// TAP_IOCTL_CONFIG_TUN ioctl.//======================================================#define NDIS_MINIPORT_DRIVER#define BINARY_COMPATIBLE 0#define NDIS50_MINIPORT 1#define NDIS_WDM 0#define NDIS50 1#define NTSTRSAFE_LIB// Debug info output#define ALSO_DBGPRINT           1#define DEBUGP_AT_DISPATCH      0//========================================================// Check for truncated IPv4 packets, log errors if found.//========================================================#define PACKET_TRUNCATION_CHECK 0 // JYFIXME//========================================================// EXPERIMENTAL -- Configure TAP device object to be// accessible from non-administrative accounts, based// on an advanced properties setting.//// Duplicates the functionality of OpenVPN's// --allow-nonadmin directive.//========================================================#define ENABLE_NONADMIN 1         // JYFIXME#include <ndis.h>#include <ntstrsafe.h>#include <ntddk.h>#include "lock.h"#include "constants.h"#include "common.h"#include "proto.h"#include "error.h"#include "endian.h"#include "dhcp.h"#include "types.h"#include "prototypes.h"#include "mem.c"#include "macinfo.c"#include "error.c"#include "dhcp.c"#include "instance.c"#define IS_UP(ta) \  ((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning)#define INCREMENT_STAT(s) ++(s)#define NAME_BUFFER_SIZE 80//========================================================//                            Globals//========================================================NDIS_HANDLE g_NdisWrapperHandle;const UINT g_SupportedOIDList[] = {  OID_GEN_HARDWARE_STATUS,  OID_GEN_MEDIA_SUPPORTED,  OID_GEN_MEDIA_IN_USE,  OID_GEN_MAXIMUM_LOOKAHEAD,  OID_GEN_MAC_OPTIONS,  OID_GEN_LINK_SPEED,  OID_GEN_TRANSMIT_BLOCK_SIZE,  OID_GEN_RECEIVE_BLOCK_SIZE,  OID_GEN_VENDOR_DESCRIPTION,  OID_GEN_DRIVER_VERSION,  OID_GEN_XMIT_OK,  OID_GEN_RCV_OK,  OID_GEN_XMIT_ERROR,  OID_GEN_RCV_ERROR,  OID_802_3_PERMANENT_ADDRESS,  OID_802_3_CURRENT_ADDRESS,  OID_GEN_RCV_NO_BUFFER,  OID_802_3_RCV_ERROR_ALIGNMENT,  OID_802_3_XMIT_ONE_COLLISION,  OID_802_3_XMIT_MORE_COLLISIONS,  OID_802_3_MULTICAST_LIST,  OID_802_3_MAXIMUM_LIST_SIZE,  OID_GEN_VENDOR_ID,  OID_GEN_CURRENT_LOOKAHEAD,  OID_GEN_CURRENT_PACKET_FILTER,  OID_GEN_PROTOCOL_OPTIONS,  OID_GEN_MAXIMUM_TOTAL_SIZE,  OID_GEN_TRANSMIT_BUFFER_SPACE,  OID_GEN_RECEIVE_BUFFER_SPACE,  OID_GEN_MAXIMUM_FRAME_SIZE,  OID_GEN_VENDOR_DRIVER_VERSION,  OID_GEN_MAXIMUM_SEND_PACKETS,  OID_GEN_MEDIA_CONNECT_STATUS,  OID_GEN_SUPPORTED_LIST};//============================================================//                         Driver Entry//============================================================#pragma NDIS_INIT_FUNCTION (DriverEntry)NTSTATUSDriverEntry (IN PDRIVER_OBJECT p_DriverObject,	     IN PUNICODE_STRING p_RegistryPath){  NDIS_STATUS l_Status = NDIS_STATUS_FAILURE;  NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL;  //========================================================  // Notify NDIS that a new miniport driver is initializing.  //========================================================  NdisMInitializeWrapper (&g_NdisWrapperHandle,			  p_DriverObject,			  p_RegistryPath, NULL);  //======================  // Global initialization  //======================#if DBG  MyDebugInit (10000); // Allocate debugging text space#endif  if (!InitInstanceList ())    {      DEBUGP (("[TAP] Allocation failed for adapter instance list\n"));      goto cleanup;    }  //=======================================  // Set and register miniport entry points  //=======================================  l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE);  if (l_Properties == NULL)    {      DEBUGP (("[TAP] Allocation failed for miniport entry points\n"));      goto cleanup;    }  l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;  l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION;  l_Properties->InitializeHandler = AdapterCreate;  l_Properties->HaltHandler = AdapterHalt;  l_Properties->ResetHandler = AdapterReset;               /* DISPATCH_LEVEL */  l_Properties->TransferDataHandler = AdapterReceive;      /* DISPATCH_LEVEL */  l_Properties->SendHandler = AdapterTransmit;             /* DISPATCH_LEVEL */  l_Properties->QueryInformationHandler = AdapterQuery;    /* DISPATCH_LEVEL */  l_Properties->SetInformationHandler = AdapterModify;     /* DISPATCH_LEVEL */  switch (l_Status =	  NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties,				 sizeof (NDIS_MINIPORT_CHARACTERISTICS)))    {    case NDIS_STATUS_SUCCESS:      {	DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n",		 TAP_DRIVER_MAJOR_VERSION,		 TAP_DRIVER_MINOR_VERSION,		 __DATE__,		 __TIME__));	DEBUGP (("Registry Path: '%S'\n", p_RegistryPath->Buffer));	break;      }    case NDIS_STATUS_BAD_CHARACTERISTICS:      {	DEBUGP (("[TAP] Miniport characteristics were badly defined\n"));	NdisTerminateWrapper (g_NdisWrapperHandle, NULL);	break;      }    case NDIS_STATUS_BAD_VERSION:      {	DEBUGP	  (("[TAP] NDIS Version is wrong for the given characteristics\n"));	NdisTerminateWrapper (g_NdisWrapperHandle, NULL);	break;      }    case NDIS_STATUS_RESOURCES:      {	DEBUGP (("[TAP] Insufficient resources\n"));	NdisTerminateWrapper (g_NdisWrapperHandle, NULL);	break;      }    default:    case NDIS_STATUS_FAILURE:      {	DEBUGP (("[TAP] Unknown fatal registration error\n"));	NdisTerminateWrapper (g_NdisWrapperHandle, NULL);	break;      }    } cleanup:  if (l_Properties)    MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS));  if (l_Status == NDIS_STATUS_SUCCESS)    NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload);  else    TapDriverUnload (p_DriverObject);  return l_Status;}//============================================================//                         Driver Unload//============================================================VOID TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject){  DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n",	   TAP_DRIVER_MAJOR_VERSION,	   TAP_DRIVER_MINOR_VERSION,	   __DATE__,	   __TIME__,	   NInstances(),	   InstanceMaxBucketSize()));  FreeInstanceList ();  //==============================  // Free debugging text space  //==============================#if DBG  MyDebugFree ();#endif}//==========================================================//                            Adapter Initialization//==========================================================NDIS_STATUS AdapterCreate  (OUT PNDIS_STATUS p_ErrorStatus,   OUT PUINT p_MediaIndex,   IN PNDIS_MEDIUM p_Media,   IN UINT p_MediaCount,   IN NDIS_HANDLE p_AdapterHandle,   IN NDIS_HANDLE p_ConfigurationHandle){  TapAdapterPointer l_Adapter = NULL;  NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet  BOOLEAN l_MacFromRegistry = FALSE;  UINT l_Index;  NDIS_STATUS status;#if ENABLE_NONADMIN  BOOLEAN enable_non_admin = FALSE;#endif  //====================================  // Make sure adapter type is supported  //====================================  for (l_Index = 0;       l_Index < p_MediaCount && p_Media[l_Index] != l_PreferredMedium;       ++l_Index);  if (l_Index == p_MediaCount)    {      DEBUGP (("[TAP] Unsupported adapter type [wanted: %d]\n",	       l_PreferredMedium));      return NDIS_STATUS_UNSUPPORTED_MEDIA;    }  *p_MediaIndex = l_Index;  //=========================================  // Allocate memory for TapAdapter structure  //=========================================  l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE);  if (l_Adapter == NULL)    {      DEBUGP (("[TAP] Couldn't allocate adapter memory\n"));      return NDIS_STATUS_RESOURCES;    }  //==========================================  // Inform the NDIS library about significant  // features of our virtual NIC.  //==========================================  NdisMSetAttributesEx    (p_AdapterHandle,     (NDIS_HANDLE) l_Adapter,     16,     NDIS_ATTRIBUTE_DESERIALIZE     | NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT     | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT     | NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,     NdisInterfaceInternal);  //=====================================  // Initialize simple Adapter parameters  //=====================================  l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD;  l_Adapter->m_Medium = l_PreferredMedium;  l_Adapter->m_DeviceState = '?';  l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle;  //==================================  // Allocate spinlock for controlling  // access to multicast address list.  //==================================  NdisAllocateSpinLock (&l_Adapter->m_MCLock);  l_Adapter->m_MCLockAllocated = TRUE;  //====================================================  // Register a shutdown handler which will be called  // on system restart/shutdown to halt our virtual NIC.  //====================================================  NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter,				       AdapterHalt);  l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE;  //============================================  // Get parameters from registry which were set  // in the adapter advanced properties dialog.  //============================================  {    NDIS_STATUS status;    NDIS_HANDLE configHandle;    NDIS_CONFIGURATION_PARAMETER *parm;    // set defaults in case our registry query fails    l_Adapter->m_MTU = ETHERNET_MTU;    l_Adapter->m_MediaStateAlwaysConnected = FALSE;    l_Adapter->m_MediaState = FALSE;    NdisOpenConfiguration (&status, &configHandle, p_ConfigurationHandle);    if (status != NDIS_STATUS_SUCCESS)      {	  DEBUGP (("[TAP] Couldn't open adapter registry\n"));	  AdapterFreeResources (l_Adapter);	  return status;      }    //====================================    // Allocate and construct adapter name    //====================================    {      NDIS_STRING key = NDIS_STRING_CONST("MiniportName");      NdisReadConfiguration (&status, &parm, configHandle, &key, NdisParameterString);      if (status == NDIS_STATUS_SUCCESS)	{	  if (parm->ParameterType == NdisParameterString)	    {	      DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%s)\n", parm->ParameterData.StringData.Buffer));	      if (RtlUnicodeStringToAnsiString (			&l_Adapter->m_NameAnsi,			&parm->ParameterData.StringData,			TRUE) != STATUS_SUCCESS)		{		  DEBUGP (("[TAP] RtlUnicodeStringToAnsiString MiniportName failed\n"));		  status = NDIS_STATUS_RESOURCES;		}	    }	} else {	  /* "MiniportName" is available only XP and above.  Not on Windows 2000. */	  NDIS_STRING key = NDIS_STRING_CONST("NdisVersion");	  NdisReadConfiguration (&status, &parm, configHandle, &key, NdisParameterInteger);	  if (status == NDIS_STATUS_SUCCESS)	    {	      if (parm->ParameterData.IntegerData == 0x50000)		{		  /* Fallback for Windows 2000 with NDIS version 5.00.00		     Don't use this on Vista, 'NDIS_MINIPORT_BLOCK' was changed! */		  DEBUGP (("[TAP] NdisReadConfiguration NdisVersion (Int=%X)\n", parm->ParameterData.IntegerData));		  if (RtlUnicodeStringToAnsiString (			&l_Adapter->m_NameAnsi,			&((PNDIS_MINIPORT_BLOCK) p_AdapterHandle)->MiniportName,			TRUE) != STATUS_SUCCESS)		    {		      DEBUGP (("[TAP] RtlUnicodeStringToAnsiString MiniportName (W2K) failed\n"));		      status = NDIS_STATUS_RESOURCES;		    }		}	    }	}    }    /* Can't continue without name (see macro 'NAME') */    if (status != NDIS_STATUS_SUCCESS || !l_Adapter->m_NameAnsi.Buffer)      {	NdisCloseConfiguration (configHandle);	AdapterFreeResources (l_Adapter);	return NDIS_STATUS_RESOURCES;      }	/* Read MTU setting from registry */	{	  NDIS_STRING key = NDIS_STRING_CONST("MTU");	  NdisReadConfiguration (&status, &parm, configHandle,				 &key, NdisParameterInteger);	  if (status == NDIS_STATUS_SUCCESS)	    {	      if (parm->ParameterType == NdisParameterInteger)

⌨️ 快捷键说明

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