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

📄 tapdrvr.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 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) James Yonan, 2003-2004, *  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 as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  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 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#include <ndis.h>#include <ntstrsafe.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;  //====================================  // 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;  //====================================  // Allocate and construct adapter name  //====================================  if (RtlUnicodeStringToAnsiString (       &l_Adapter->m_NameAnsi,       &((PNDIS_MINIPORT_BLOCK) p_AdapterHandle)->MiniportName,       TRUE) != STATUS_SUCCESS)    {      AdapterFreeResources (l_Adapter);      return NDIS_STATUS_RESOURCES;    }  //============================================  // 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)      {	/* 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)		{		  int mtu = parm->ParameterData.IntegerData;		  if (mtu < MINIMUM_MTU)		    mtu = MINIMUM_MTU;		  if (mtu > MAXIMUM_MTU)		    mtu = MAXIMUM_MTU;		  l_Adapter->m_MTU = mtu;		}	    }	}	/* Read Media Status setting from registry */	{	  NDIS_STRING key = NDIS_STRING_CONST("MediaStatus");	  NdisReadConfiguration (&status, &parm, configHandle,				 &key, NdisParameterInteger);	  if (status == NDIS_STATUS_SUCCESS)	    {	      if (parm->ParameterType == NdisParameterInteger)		{		  if (parm->ParameterData.IntegerData)		    {		      l_Adapter->m_MediaStateAlwaysConnected = TRUE;		      l_Adapter->m_MediaState = TRUE;		    }		}	    }	}	/* Read optional MAC setting from registry */	{	  NDIS_STRING key = NDIS_STRING_CONST("MAC");	  ANSI_STRING mac_string;	  NdisReadConfiguration (&status, &parm, configHandle,				 &key, NdisParameterString);	  if (status == NDIS_STATUS_SUCCESS)	    {	      if (parm->ParameterType == NdisParameterString)		{		  if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS)		    {		      l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer);		      RtlFreeAnsiString (&mac_string);		    }		}	    }	}	NdisCloseConfiguration (configHandle);      }    DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU));  }  //==================================  // Store and update MAC address info  //==================================  if (!l_MacFromRegistry)    GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter));  DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",	    NAME (l_Adapter),	    l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],	    l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));  //==================  // Set broadcast MAC  //==================  {

⌨️ 快捷键说明

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