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

📄 tapdrvr.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
📖 第 1 页 / 共 5 页
字号:
    //=====================================================    // Are we running in DHCP server masquerade mode?    //    // If so, catch both DHCP requests and ARP queries    // to resolve the address of our virtual DHCP server.    //=====================================================    if (l_Adapter->m_dhcp_enabled)      {	const ETH_HEADER *eth = (ETH_HEADER *) l_PacketBuffer->m_Data;	const IPHDR *ip = (IPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER));	const UDPHDR *udp = (UDPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER) + sizeof (IPHDR));	// ARP packet?	if (l_PacketLength == sizeof (ARP_PACKET)	    && eth->proto == htons (ETH_P_ARP)	    && l_Adapter->m_dhcp_server_arp)	  {	    if (ProcessARP (l_Adapter,			    (PARP_PACKET) l_PacketBuffer->m_Data,			    l_Adapter->m_dhcp_addr,			    l_Adapter->m_dhcp_server_ip,			    l_Adapter->m_dhcp_server_mac))	      goto no_queue;	  }	// DHCP packet?	else if (l_PacketLength >= sizeof (ETH_HEADER) + sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP)		 && eth->proto == htons (ETH_P_IP)		 && ip->version_len == 0x45 // IPv4, 20 byte header		 && ip->protocol == IPPROTO_UDP		 && udp->dest == htons (BOOTPS_PORT))	  {	    const DHCP *dhcp = (DHCP *) (l_PacketBuffer->m_Data					 + sizeof (ETH_HEADER)					 + sizeof (IPHDR)					 + sizeof (UDPHDR));	    const int optlen = l_PacketLength	      - sizeof (ETH_HEADER)	      - sizeof (IPHDR)	      - sizeof (UDPHDR)	      - sizeof (DHCP);	    if (optlen > 0) // we must have at least one DHCP option	      {		if (ProcessDHCP (l_Adapter, eth, ip, udp, dhcp, optlen))		  goto no_queue;	      }	    else	      goto no_queue;	  }      }    //===============================================    // In Point-To-Point mode, check to see whether    // packet is ARP or IPv4 (if neither, then drop).    //===============================================    if (l_Adapter->m_PointToPoint)      {	ETH_HEADER *e;	if (l_PacketLength < ETHERNET_HEADER_SIZE)	  goto no_queue;	e = (ETH_HEADER *) l_PacketBuffer->m_Data;	switch (ntohs (e->proto))	  {	  case ETH_P_ARP:	    // Make sure that packet is the	    // right size for ARP.	    if (l_PacketLength != sizeof (ARP_PACKET))	      goto no_queue;	    ProcessARP (l_Adapter,			(PARP_PACKET) l_PacketBuffer->m_Data,			l_Adapter->m_localIP,			l_Adapter->m_remoteIP,			l_Adapter->m_TapToUser.dest);	  default:	    goto no_queue;	  case ETH_P_IP:	    // Make sure that packet is large	    // enough to be IPv4.	    if (l_PacketLength		< ETHERNET_HEADER_SIZE + IP_HEADER_SIZE)	      goto no_queue;	    // Only accept directed packets,	    // not broadcasts.	    if (memcmp (e, &l_Adapter->m_TapToUser, ETHERNET_HEADER_SIZE))	      goto no_queue;	    // Packet looks like IPv4, queue it.	    l_PacketBuffer->m_SizeFlags |= TP_POINT_TO_POINT;	  }      }    //===============================================    // Push packet onto queue to wait for read from    // userspace.    //===============================================    NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);    result = NULL;    if (IS_UP (l_Adapter))      result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer);    NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);    if ((TapPacketPointer) result != l_PacketBuffer)      {	// adapter receive overrun	INCREMENT_STAT (l_Adapter->m_TxErr);	goto no_queue;      }    else      {	INCREMENT_STAT (l_Adapter->m_Tx);      }    //============================================================    // Cycle through IRPs and packets, try to satisfy each pending    // IRP with a queued packet.    //============================================================    while (TRUE)      {	l_IRP = NULL;	l_PacketBuffer = NULL;	NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);	if (IS_UP (l_Adapter)	    && QueueCount (l_Adapter->m_Extension.m_PacketQueue)	    && QueueCount (l_Adapter->m_Extension.m_IrpQueue))	  {	    l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue);	    l_PacketBuffer = (TapPacketPointer)	      QueuePop (l_Adapter->m_Extension.m_PacketQueue);	  }	NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);	MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1);	if (l_IRP && l_PacketBuffer)	  {	    CompleteIRP (l_IRP,			 l_PacketBuffer, 			 IO_NETWORK_INCREMENT);	  }	else	  break;      }  }  __except (EXCEPTION_EXECUTE_HANDLER)    {    }  return NDIS_STATUS_SUCCESS; no_queue:  NdisFreeMemory (l_PacketBuffer,		  TAP_PACKET_SIZE (l_PacketLength),		  0);   exit_success:  return NDIS_STATUS_SUCCESS;     exit_fail:  return NDIS_STATUS_FAILURE; exit_no_resources:  return NDIS_STATUS_RESOURCES;}//======================================================================// Hooks for catching TAP device IRP's.//======================================================================NTSTATUSTapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP){  TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);  PIO_STACK_LOCATION l_IrpSp;  NTSTATUS l_Status = STATUS_SUCCESS;  BOOLEAN accessible;  l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP);  p_IRP->IoStatus.Status = STATUS_SUCCESS;  p_IRP->IoStatus.Information = 0;  if (!l_Adapter || l_Adapter->m_Extension.m_Halt)    {      DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n",	       (int)l_IrpSp->MajorFunction));      if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE)	{	  IoCompleteRequest (p_IRP, IO_NO_INCREMENT);	  return STATUS_SUCCESS;	}      else	{	  p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;	  IoCompleteRequest (p_IRP, IO_NO_INCREMENT);	  return STATUS_NO_SUCH_DEVICE;	}    }  switch (l_IrpSp->MajorFunction)    {      //===========================================================      //                 Ioctl call handlers      //===========================================================    case IRP_MJ_DEVICE_CONTROL:      {	switch (l_IrpSp->Parameters.DeviceIoControl.IoControlCode)	  {	  case TAP_IOCTL_GET_MAC:	    {	      if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength		  >= sizeof (MACADDR))		{		  COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer,			    l_Adapter->m_MAC);		  p_IRP->IoStatus.Information = sizeof (MACADDR);		}	      else		{		  NOTE_ERROR ();		  p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;		}	      break;	    }	  case TAP_IOCTL_GET_VERSION:	    {	      const ULONG size = sizeof (ULONG) * 3;	      if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength		  >= size)		{		  ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]		    = TAP_DRIVER_MAJOR_VERSION;		  ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1]		    = TAP_DRIVER_MINOR_VERSION;		  ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2]#if DBG		    = 1;#else		  = 0;#endif		  p_IRP->IoStatus.Information = size;		}	      else		{		  NOTE_ERROR ();		  p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;		}	      break;	    }	  case TAP_IOCTL_GET_MTU:	    {	      const ULONG size = sizeof (ULONG) * 1;	      if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength		  >= size)		{		  ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]		    = l_Adapter->m_MTU;		  p_IRP->IoStatus.Information = size;		}	      else		{		  NOTE_ERROR ();		  p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;		}	      break;	    }	  case TAP_IOCTL_GET_INFO:	    {	      char state[16];	      if (l_Adapter->m_InterfaceIsRunning)		state[0] = 'A';	      else		state[0] = 'a';	      if (l_Adapter->m_Extension.m_TapIsRunning)		state[1] = 'T';	      else		state[1] = 't';	      state[2] = l_Adapter->m_DeviceState;	      if (l_Adapter->m_MediaStateAlwaysConnected)		state[3] = 'C';	      else		state[3] = 'c';	      state[4] = '\0';	      p_IRP->IoStatus.Status = l_Status = RtlStringCchPrintfExA (	        ((LPTSTR) (p_IRP->AssociatedIrp.SystemBuffer)),		l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength,		NULL,		NULL,		STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,		"State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d]",		state,		g_LastErrorFilename,		g_LastErrorLineNumber,		(int)l_Adapter->m_Extension.m_NumTapOpens,		(int)l_Adapter->m_Tx,		(int)l_Adapter->m_TxErr,		(int)l_Adapter->m_Rx,		(int)l_Adapter->m_RxErr,		(int)l_Adapter->m_Extension.m_IrpQueue->size,		(int)l_Adapter->m_Extension.m_IrpQueue->max_size,		(int)IRP_QUEUE_SIZE,		(int)l_Adapter->m_Extension.m_PacketQueue->size,		(int)l_Adapter->m_Extension.m_PacketQueue->max_size,		(int)PACKET_QUEUE_SIZE		);	      p_IRP->IoStatus.Information		= l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;	      break;	    }#if DBG	  case TAP_IOCTL_GET_LOG_LINE:	    {	      if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer,				l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength))		p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;	      else		p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;	      p_IRP->IoStatus.Information		= l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;	      break;	    }#endif	  case TAP_IOCTL_CONFIG_POINT_TO_POINT:	    {	      if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=		  (sizeof (IPADDR) * 2))		{		  MACADDR dest;		  l_Adapter->m_PointToPoint = FALSE;		  GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);		  l_Adapter->m_localIP =		    ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];		  l_Adapter->m_remoteIP =		    ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];		  COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC);		  COPY_MAC (l_Adapter->m_TapToUser.dest, dest);		  COPY_MAC (l_Adapter->m_UserToTap.src, dest);		  COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC);		  l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);		  l_Adapter->m_PointToPoint = TRUE;		  CheckIfDhcpAndPointToPointMode (l_Adapter);		  p_IRP->IoStatus.Information = 1; // Simple boolean value		}	      else		{		  NOTE_ERROR ();		  p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;		}	      	      break;	    }	  case TAP_IOCTL_SET_MEDIA_STATUS:	    {	      if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=		  (sizeof (ULONG) * 1))		{		  ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0];		  SetMediaStatus (l_Adapter, (BOOLEAN) parm);		  p_IRP->IoStatus.Information = 1;		}	      else		{		  NOTE_ERROR ();		  p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;		}	      break;	    }	  case TAP_IOCTL_CONFIG_DHCP_MASQ:	    {	      if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=		  (sizeof (IPADDR) * 4))		{		  l_Adapter->m_dhcp_enabled = FALSE;		  l_Adapter->m_dhcp_server_arp = FALSE;		  l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;		  // Adapter IP addr / netmask		  l_Adapter->m_dhcp_addr =		    ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];		  l_Adapter->m_dhcp_netmask =		    ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];		  // IP addr of DHCP masq server		  l_Adapter->m_dhcp_server_ip =		    ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2];		  // Lease time in seconds		  l_Adapter->m_dhcp_lease_time =		    ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[3];		  GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2);		  l_Adapter->m_dhcp_enabled = TRUE;		  l_Adapter->m_dhcp_server_arp = TRUE;		  CheckIfDhcpAndPointToPointMode (l_Adapter);		  p_IRP->IoStatus.Information = 1; // Simple boolean value		}	      else		{		  NOTE_ERROR ();		  p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;		}	      	      break;	    }	  case TAP_IOCTL_CONFIG_DHCP_SET_OPT:	    {	      if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength <=		  DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE		  && l_Adapter->m_dhcp_enabled)		{		  l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;		  NdisMoveMemory (l_Adapter->m_dhcp_user_supplied_options_buffer,

⌨️ 快捷键说明

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