You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
348 lines
12 KiB
348 lines
12 KiB
/* |
|
* TAP-Windows -- A kernel driver to provide virtual tap |
|
* device functionality on Windows. |
|
* |
|
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. |
|
* |
|
* This source code is Copyright (C) 2002-2014 OpenVPN Technologies, Inc., |
|
* 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 |
|
*/ |
|
#ifndef __TAP_ADAPTER_CONTEXT_H_ |
|
#define __TAP_ADAPTER_CONTEXT_H_ |
|
|
|
#include "tap.h" |
|
|
|
// Memory allocation tags. |
|
#define TAP_ADAPTER_TAG ((ULONG)'ApaT') // "TapA |
|
#define TAP_RX_NBL_TAG ((ULONG)'RpaT') // "TapR |
|
#define TAP_RX_INJECT_BUFFER_TAG ((ULONG)'IpaT') // "TapI |
|
|
|
#define TAP_MAX_NDIS_NAME_LENGTH 64 // 38 character GUID string plus extra.. |
|
|
|
// TAP receive indication NBL flag definitions. |
|
#define TAP_RX_NBL_FLAGS NBL_FLAGS_MINIPORT_RESERVED |
|
#define TAP_RX_NBL_FLAGS_CLEAR_ALL(_NBL) ((_NBL)->Flags &= ~TAP_RX_NBL_FLAGS) |
|
#define TAP_RX_NBL_FLAG_SET(_NBL, _F) ((_NBL)->Flags |= ((_F) & TAP_RX_NBL_FLAGS)) |
|
#define TAP_RX_NBL_FLAG_CLEAR(_NBL, _F) ((_NBL)->Flags &= ~((_F) & TAP_RX_NBL_FLAGS)) |
|
#define TAP_RX_NBL_FLAG_TEST(_NBL, _F) (((_NBL)->Flags & ((_F) & TAP_RX_NBL_FLAGS)) != 0) |
|
|
|
#define TAP_RX_NBL_FLAGS_IS_P2P 0x00001000 |
|
#define TAP_RX_NBL_FLAGS_IS_INJECTED 0x00002000 |
|
|
|
// MSDN Ref: http://msdn.microsoft.com/en-us/library/windows/hardware/ff560490(v=vs.85).aspx |
|
typedef |
|
enum _TAP_MINIPORT_ADAPTER_STATE |
|
{ |
|
// The Halted state is the initial state of all adapters. When an |
|
// adapter is in the Halted state, NDIS can call the driver's |
|
// MiniportInitializeEx function to initialize the adapter. |
|
MiniportHaltedState, |
|
|
|
// In the Shutdown state, a system shutdown and restart must occur |
|
// before the system can use the adapter again. |
|
MiniportShutdownState, |
|
|
|
// In the Initializing state, a miniport driver completes any |
|
//operations that are required to initialize an adapter. |
|
MiniportInitializingState, |
|
|
|
// Entering the Paused state... |
|
MiniportPausingState, |
|
|
|
// In the Paused state, the adapter does not indicate received |
|
// network data or accept send requests. |
|
MiniportPausedState, |
|
|
|
// In the Running state, a miniport driver performs send and |
|
// receive processing for an adapter. |
|
MiniportRunning, |
|
|
|
// In the Restarting state, a miniport driver completes any |
|
// operations that are required to restart send and receive |
|
// operations for an adapter. |
|
MiniportRestartingState |
|
} TAP_MINIPORT_ADAPTER_STATE, *PTAP_MINIPORT_ADAPTER_STATE; |
|
|
|
// |
|
// Each adapter managed by this driver has a TapAdapter struct. |
|
// ------------------------------------------------------------ |
|
// Since there is a one-to-one relationship between adapter instances |
|
// and device instances this structure is the device extension as well. |
|
// |
|
typedef struct _TAP_ADAPTER_CONTEXT |
|
{ |
|
LIST_ENTRY AdapterListLink; |
|
|
|
volatile LONG RefCount; |
|
|
|
NDIS_HANDLE MiniportAdapterHandle; |
|
|
|
NDIS_SPIN_LOCK AdapterLock; // Lock for protection of state and outstanding sends and recvs |
|
|
|
// |
|
// All fields that are protected by the AdapterLock are included |
|
// in the Locked structure to remind us to take the Lock |
|
// before accessing them :) |
|
// |
|
struct |
|
{ |
|
TAP_MINIPORT_ADAPTER_STATE AdapterState; |
|
} Locked; |
|
|
|
BOOLEAN ResetInProgress; |
|
|
|
// |
|
// NetCfgInstanceId as UNICODE_STRING |
|
// ---------------------------------- |
|
// This a GUID string provided by NDIS that identifies the adapter instance. |
|
// An example is: |
|
// |
|
// NetCfgInstanceId={410EB49D-2381-4FE7-9B36-498E22619DF0} |
|
// |
|
// Other names are derived from NetCfgInstanceId. For example, MiniportName: |
|
// |
|
// MiniportName=\DEVICE\{410EB49D-2381-4FE7-9B36-498E22619DF0} |
|
// |
|
NDIS_STRING NetCfgInstanceId; |
|
WCHAR NetCfgInstanceIdBuffer[TAP_MAX_NDIS_NAME_LENGTH]; |
|
|
|
# define MINIPORT_INSTANCE_ID(a) ((a)->NetCfgInstanceIdAnsi.Buffer) |
|
ANSI_STRING NetCfgInstanceIdAnsi; // Used occasionally |
|
|
|
ULONG MtuSize; // 1500 byte (typical) |
|
|
|
// TRUE if adapter should always be "connected" even when device node |
|
// is not open by a userspace process. |
|
// |
|
// FALSE if connection state is application controlled. |
|
BOOLEAN MediaStateAlwaysConnected; |
|
|
|
// TRUE if device is "connected". |
|
BOOLEAN LogicalMediaState; |
|
|
|
NDIS_DEVICE_POWER_STATE CurrentPowerState; |
|
|
|
BOOLEAN AllowNonAdmin; |
|
|
|
MACADDR PermanentAddress; // From registry, if available |
|
MACADDR CurrentAddress; |
|
|
|
// Device registration parameters from NdisRegisterDeviceEx. |
|
NDIS_STRING DeviceName; |
|
WCHAR DeviceNameBuffer[TAP_MAX_NDIS_NAME_LENGTH]; |
|
|
|
NDIS_STRING LinkName; |
|
WCHAR LinkNameBuffer[TAP_MAX_NDIS_NAME_LENGTH]; |
|
|
|
NDIS_HANDLE DeviceHandle; |
|
PDEVICE_OBJECT DeviceObject; |
|
BOOLEAN TapDeviceCreated; // WAS: m_TapIsRunning |
|
|
|
PFILE_OBJECT TapFileObject; // Exclusive access |
|
BOOLEAN TapFileIsOpen; // WAS: m_TapOpens |
|
LONG TapFileOpenCount; // WAS: m_NumTapOpens |
|
|
|
// Cancel-Safe read IRP queue. |
|
TAP_IRP_CSQ PendingReadIrpQueue; |
|
|
|
// Queue containing TAP packets representing host send NBs. These are |
|
// waiting to be read by user-mode application. |
|
TAP_PACKET_QUEUE SendPacketQueue; |
|
|
|
// NBL pool for making TAP receive indications. |
|
NDIS_HANDLE ReceiveNblPool; |
|
|
|
volatile LONG ReceiveNblInFlightCount; |
|
#define TAP_WAIT_POLL_LOOP_TIMEOUT 3000 // 3 seconds |
|
NDIS_EVENT ReceiveNblInFlightCountZeroEvent; |
|
|
|
// Info for point-to-point mode |
|
BOOLEAN m_tun; |
|
IPADDR m_localIP; |
|
IPADDR m_remoteNetwork; |
|
IPADDR m_remoteNetmask; |
|
ETH_HEADER m_TapToUser; |
|
ETH_HEADER m_UserToTap; |
|
ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6 |
|
|
|
// Info for DHCP server masquerade |
|
BOOLEAN m_dhcp_enabled; |
|
IPADDR m_dhcp_addr; |
|
ULONG m_dhcp_netmask; |
|
IPADDR m_dhcp_server_ip; |
|
BOOLEAN m_dhcp_server_arp; |
|
MACADDR m_dhcp_server_mac; |
|
ULONG m_dhcp_lease_time; |
|
UCHAR m_dhcp_user_supplied_options_buffer[DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE]; |
|
ULONG m_dhcp_user_supplied_options_buffer_len; |
|
BOOLEAN m_dhcp_received_discover; |
|
ULONG m_dhcp_bad_requests; |
|
|
|
// Multicast list. Fixed size. |
|
ULONG ulMCListSize; |
|
UCHAR MCList[TAP_MAX_MCAST_LIST][MACADDR_SIZE]; |
|
|
|
ULONG PacketFilter; |
|
ULONG ulLookahead; |
|
|
|
// |
|
// Statistics |
|
// ------------------------------------------------------------------------- |
|
// |
|
|
|
// Packet counts |
|
ULONG64 FramesRxDirected; |
|
ULONG64 FramesRxMulticast; |
|
ULONG64 FramesRxBroadcast; |
|
ULONG64 FramesTxDirected; |
|
ULONG64 FramesTxMulticast; |
|
ULONG64 FramesTxBroadcast; |
|
|
|
// Byte counts |
|
ULONG64 BytesRxDirected; |
|
ULONG64 BytesRxMulticast; |
|
ULONG64 BytesRxBroadcast; |
|
ULONG64 BytesTxDirected; |
|
ULONG64 BytesTxMulticast; |
|
ULONG64 BytesTxBroadcast; |
|
|
|
// Count of transmit errors |
|
ULONG TxAbortExcessCollisions; |
|
ULONG TxLateCollisions; |
|
ULONG TxDmaUnderrun; |
|
ULONG TxLostCRS; |
|
ULONG TxOKButDeferred; |
|
ULONG OneRetry; |
|
ULONG MoreThanOneRetry; |
|
ULONG TotalRetries; |
|
ULONG TransmitFailuresOther; |
|
|
|
// Count of receive errors |
|
ULONG RxCrcErrors; |
|
ULONG RxAlignmentErrors; |
|
ULONG RxResourceErrors; |
|
ULONG RxDmaOverrunErrors; |
|
ULONG RxCdtFrames; |
|
ULONG RxRuntErrors; |
|
|
|
#if PACKET_TRUNCATION_CHECK |
|
LONG m_RxTrunc, m_TxTrunc; |
|
#endif |
|
|
|
BOOLEAN m_InterfaceIsRunning; |
|
LONG m_Rx, m_RxErr; |
|
NDIS_MEDIUM m_Medium; |
|
|
|
// Help to tear down the adapter by keeping |
|
// some state information on allocated |
|
// resources. |
|
BOOLEAN m_CalledAdapterFreeResources; |
|
BOOLEAN m_RegisteredAdapterShutdownHandler; |
|
|
|
} TAP_ADAPTER_CONTEXT, *PTAP_ADAPTER_CONTEXT; |
|
|
|
FORCEINLINE |
|
LONG |
|
tapAdapterContextReference( |
|
__in PTAP_ADAPTER_CONTEXT Adapter |
|
) |
|
{ |
|
LONG refCount = NdisInterlockedIncrement(&Adapter->RefCount); |
|
|
|
ASSERT(refCount>1); // Cannot dereference a zombie. |
|
|
|
return refCount; |
|
} |
|
|
|
VOID |
|
tapAdapterContextFree( |
|
__in PTAP_ADAPTER_CONTEXT Adapter |
|
); |
|
|
|
FORCEINLINE |
|
LONG |
|
tapAdapterContextDereference( |
|
IN PTAP_ADAPTER_CONTEXT Adapter |
|
) |
|
{ |
|
LONG refCount = NdisInterlockedDecrement(&Adapter->RefCount); |
|
ASSERT(refCount >= 0); |
|
if (!refCount) |
|
{ |
|
tapAdapterContextFree(Adapter); |
|
} |
|
|
|
return refCount; |
|
} |
|
|
|
VOID |
|
tapAdapterAcquireLock( |
|
__in PTAP_ADAPTER_CONTEXT Adapter, |
|
__in BOOLEAN DispatchLevel |
|
); |
|
|
|
VOID |
|
tapAdapterReleaseLock( |
|
__in PTAP_ADAPTER_CONTEXT Adapter, |
|
__in BOOLEAN DispatchLevel |
|
); |
|
|
|
// Returns with added reference on adapter context. |
|
PTAP_ADAPTER_CONTEXT |
|
tapAdapterContextFromDeviceObject( |
|
__in PDEVICE_OBJECT DeviceObject |
|
); |
|
|
|
BOOLEAN |
|
tapAdapterReadAndWriteReady( |
|
__in PTAP_ADAPTER_CONTEXT Adapter |
|
); |
|
|
|
NDIS_STATUS |
|
tapAdapterSendAndReceiveReady( |
|
__in PTAP_ADAPTER_CONTEXT Adapter |
|
); |
|
|
|
ULONG |
|
tapGetNetBufferFrameType( |
|
__in PNET_BUFFER NetBuffer |
|
); |
|
|
|
ULONG |
|
tapGetNetBufferCountsFromNetBufferList( |
|
__in PNET_BUFFER_LIST NetBufferList, |
|
__inout_opt PULONG TotalByteCount // Of all linked NBs |
|
); |
|
|
|
// Prototypes for standard NDIS miniport entry points |
|
MINIPORT_SET_OPTIONS AdapterSetOptions; |
|
MINIPORT_INITIALIZE AdapterCreate; |
|
MINIPORT_HALT AdapterHalt; |
|
MINIPORT_UNLOAD TapDriverUnload; |
|
MINIPORT_PAUSE AdapterPause; |
|
MINIPORT_RESTART AdapterRestart; |
|
MINIPORT_OID_REQUEST AdapterOidRequest; |
|
MINIPORT_SEND_NET_BUFFER_LISTS AdapterSendNetBufferLists; |
|
MINIPORT_RETURN_NET_BUFFER_LISTS AdapterReturnNetBufferLists; |
|
MINIPORT_CANCEL_SEND AdapterCancelSend; |
|
MINIPORT_CHECK_FOR_HANG AdapterCheckForHangEx; |
|
MINIPORT_RESET AdapterReset; |
|
MINIPORT_DEVICE_PNP_EVENT_NOTIFY AdapterDevicePnpEventNotify; |
|
MINIPORT_SHUTDOWN AdapterShutdownEx; |
|
MINIPORT_CANCEL_OID_REQUEST AdapterCancelOidRequest; |
|
|
|
#endif // __TAP_ADAPTER_CONTEXT_H_
|