aboutsummaryrefslogtreecommitdiff
path: root/tap-win32
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2005-09-26 07:40:02 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2005-09-26 07:40:02 +0000
commit3c7f2f553be4b3ba9412c1b3f64a258c469d78f4 (patch)
tree9d58836b0f1eade372de7ce15c41d6555d55ef21 /tap-win32
parentThis is the start of the BETA21 branch. (diff)
downloadopenvpn-3c7f2f553be4b3ba9412c1b3f64a258c469d78f4.tar.xz
version 2.1_beta1
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@581 e7ae566f-a301-0410-adde-c780ea21d3b5
Diffstat (limited to 'tap-win32')
-rwxr-xr-xtap-win32/SOURCES2
-rwxr-xr-xtap-win32/common.h7
-rwxr-xr-xtap-win32/i386/OemWin2k.inf43
-rwxr-xr-xtap-win32/prototypes.h36
-rwxr-xr-xtap-win32/tapdrvr.c331
-rwxr-xr-xtap-win32/types.h12
6 files changed, 376 insertions, 55 deletions
diff --git a/tap-win32/SOURCES b/tap-win32/SOURCES
index 5320ae3..f7c8dd6 100755
--- a/tap-win32/SOURCES
+++ b/tap-win32/SOURCES
@@ -15,7 +15,7 @@ INCLUDES=$(DDK_INCLUDE_PATH)
# config-win32.h
C_DEFINES=
C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MAJOR_VERSION=8
-C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MINOR_VERSION=1
+C_DEFINES=$(C_DEFINES) -DTAP_DRIVER_MINOR_VERSION=307
# Use 00:FF:XX:XX:XX:XX format MAC addresses where
# the Xs are random (like Linux tap driver).
diff --git a/tap-win32/common.h b/tap-win32/common.h
index ef121b1..3c183c2 100755
--- a/tap-win32/common.h
+++ b/tap-win32/common.h
@@ -39,6 +39,8 @@
#define TAP_CONTROL_CODE(request,method) \
CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
+// Present in 8.1
+
#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED)
#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED)
#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED)
@@ -49,6 +51,11 @@
#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED)
#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED)
+// Added in 8.2
+
+/* obsoletes TAP_IOCTL_CONFIG_POINT_TO_POINT */
+#define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE (10, METHOD_BUFFERED)
+
//=================
// Registry keys
//=================
diff --git a/tap-win32/i386/OemWin2k.inf b/tap-win32/i386/OemWin2k.inf
index eb1e071..681c4b7 100755
--- a/tap-win32/i386/OemWin2k.inf
+++ b/tap-win32/i386/OemWin2k.inf
@@ -10,6 +10,11 @@
; chkinf c:\src\openvpn\tap-win32\i386\oemwin2k.inf
; OUTPUT -> file:///c:/WINDDK/3790/tools/chkinf/htm/c%23+src+openvpn+tap-win32+i386+__OemWin2k.htm
+; INSTALL/REMOVE DRIVER
+; tapinstall install OemWin2k.inf TAP0801
+; tapinstall update OemWin2k.inf TAP0801
+; tapinstall remove TAP0801
+
;*********************************************************
; Note to Developers:
;
@@ -91,22 +96,28 @@
HKR, , ProductName, 0, "%DeviceDescription%"
[tap0801.params.reg]
- HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
- HKR, Ndi\params\MTU, Type, 0, "int"
- HKR, Ndi\params\MTU, Default, 0, "1500"
- HKR, Ndi\params\MTU, Optional, 0, "0"
- HKR, Ndi\params\MTU, Min, 0, "100"
- HKR, Ndi\params\MTU, Max, 0, "1500"
- HKR, Ndi\params\MTU, Step, 0, "1"
- HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
- HKR, Ndi\params\MediaStatus, Type, 0, "enum"
- HKR, Ndi\params\MediaStatus, Default, 0, "0"
- HKR, Ndi\params\MediaStatus, Optional, 0, "0"
- HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
- HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected"
- HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address"
- HKR, Ndi\params\MAC, Type, 0, "edit"
- HKR, Ndi\params\MAC, Optional, 0, "1"
+ HKR, Ndi\params\MTU, ParamDesc, 0, "MTU"
+ HKR, Ndi\params\MTU, Type, 0, "int"
+ HKR, Ndi\params\MTU, Default, 0, "1500"
+ HKR, Ndi\params\MTU, Optional, 0, "0"
+ HKR, Ndi\params\MTU, Min, 0, "100"
+ HKR, Ndi\params\MTU, Max, 0, "1500"
+ HKR, Ndi\params\MTU, Step, 0, "1"
+ HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status"
+ HKR, Ndi\params\MediaStatus, Type, 0, "enum"
+ HKR, Ndi\params\MediaStatus, Default, 0, "0"
+ HKR, Ndi\params\MediaStatus, Optional, 0, "0"
+ HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled"
+ HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected"
+ HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address"
+ HKR, Ndi\params\MAC, Type, 0, "edit"
+ HKR, Ndi\params\MAC, Optional, 0, "1"
+ HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access"
+ HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum"
+ HKR, Ndi\params\AllowNonAdmin, Default, 0, "1"
+ HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0"
+ HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed"
+ HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed"
;----------------------------------------------------------------
; Service Section
diff --git a/tap-win32/prototypes.h b/tap-win32/prototypes.h
index 81f58f4..2237ed0 100755
--- a/tap-win32/prototypes.h
+++ b/tap-win32/prototypes.h
@@ -160,7 +160,8 @@ BOOLEAN ProcessARP
TapAdapterPointer p_Adapter,
const PARP_PACKET src,
const IPADDR adapter_ip,
- const IPADDR ip,
+ const IPADDR ip_network,
+ const IPADDR ip_netmask,
const MACADDR mac
);
@@ -177,11 +178,42 @@ VOID InjectPacket
const unsigned int len
);
-VOID CheckIfDhcpAndPointToPointMode
+VOID CheckIfDhcpAndTunMode
(
TapAdapterPointer p_Adapter
);
VOID HookDispatchFunctions();
+#if ENABLE_NONADMIN
+
+typedef struct _SECURITY_DESCRIPTOR {
+ unsigned char opaque[20];
+} SECURITY_DESCRIPTOR;
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+ZwSetSecurityObject (
+ IN HANDLE Handle,
+ IN SECURITY_INFORMATION SecurityInformation,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor);
+
+VOID AllowNonAdmin (TapExtensionPointer p_Extension);
+
+#endif
+
+#if PACKET_TRUNCATION_CHECK
+
+VOID IPv4PacketSizeVerify
+ (
+ const UCHAR *data,
+ ULONG length,
+ BOOLEAN tun,
+ const char *prefix,
+ LONG *counter
+ );
+
+#endif
+
#endif
diff --git a/tap-win32/tapdrvr.c b/tap-win32/tapdrvr.c
index 7eecca7..0997bd5 100755
--- a/tap-win32/tapdrvr.c
+++ b/tap-win32/tapdrvr.c
@@ -35,7 +35,8 @@
// 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.
+// TAP_IOCTL_CONFIG_POINT_TO_POINT or
+// TAP_IOCTL_CONFIG_TUN ioctl.
//======================================================
#define NDIS_MINIPORT_DRIVER
@@ -46,11 +47,27 @@
#define NTSTRSAFE_LIB
// Debug info output
-#define ALSO_DBGPRINT 1
-#define DEBUGP_AT_DISPATCH 0
+#define ALSO_DBGPRINT 1
+#define DEBUGP_AT_DISPATCH 0
+
+//========================================================
+// Check for truncated IPv4 packets, log errors if found.
+//========================================================
+#define PACKET_TRUNCATION_CHECK 1 // 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"
@@ -274,6 +291,10 @@ NDIS_STATUS AdapterCreate
UINT l_Index;
NDIS_STATUS status;
+#if ENABLE_NONADMIN
+ BOOLEAN enable_non_admin = FALSE;
+#endif
+
//====================================
// Make sure adapter type is supported
//====================================
@@ -410,6 +431,25 @@ NDIS_STATUS AdapterCreate
}
}
+#if ENABLE_NONADMIN
+ /* Read AllowNonAdmin setting from registry */
+ {
+ NDIS_STRING key = NDIS_STRING_CONST("AllowNonAdmin");
+ NdisReadConfiguration (&status, &parm, configHandle,
+ &key, NdisParameterInteger);
+ if (status == NDIS_STATUS_SUCCESS)
+ {
+ if (parm->ParameterType == NdisParameterInteger)
+ {
+ if (parm->ParameterData.IntegerData)
+ {
+ enable_non_admin = TRUE;
+ }
+ }
+ }
+ }
+#endif
+
/* Read optional MAC setting from registry */
{
NDIS_STRING key = NDIS_STRING_CONST("MAC");
@@ -479,6 +519,11 @@ NDIS_STATUS AdapterCreate
l_Adapter->m_InterfaceIsRunning = TRUE;
+#if ENABLE_NONADMIN
+ if (enable_non_admin)
+ AllowNonAdmin (&l_Adapter->m_Extension);
+#endif
+
return NDIS_STATUS_SUCCESS;
}
@@ -1011,7 +1056,7 @@ NDIS_STATUS AdapterQuery
break;
case OID_GEN_LINK_SPEED:
- l_Query.m_Long = 100000;
+ l_Query.m_Long = 100000; // rate / 100 bps
break;
case OID_802_3_PERMANENT_ADDRESS:
@@ -1348,19 +1393,40 @@ AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
__try
{
- for (l_Index = 0; l_NDIS_Buffer && l_Index < l_PacketLength;
- l_Index += l_BufferLength)
+ l_Index = 0;
+ while (l_NDIS_Buffer && l_Index < l_PacketLength)
{
+ ULONG newlen;
NdisQueryBuffer (l_NDIS_Buffer, (PVOID *) & l_Buffer,
&l_BufferLength);
+ newlen = l_Index + l_BufferLength;
+ if (newlen > l_PacketLength)
+ {
+ NOTE_ERROR ();
+ goto no_queue; /* overflow */
+ }
NdisMoveMemory (l_PacketBuffer->m_Data + l_Index, l_Buffer,
l_BufferLength);
+ l_Index = newlen;
NdisGetNextBuffer (l_NDIS_Buffer, &l_NDIS_Buffer);
}
+ if (l_Index != l_PacketLength)
+ {
+ NOTE_ERROR ();
+ goto no_queue; /* underflow */
+ }
DUMP_PACKET ("AdapterTransmit", l_PacketBuffer->m_Data, l_PacketLength);
//=====================================================
+ // If IPv4 packet, check whether or not packet
+ // was truncated.
+ //=====================================================
+#if PACKET_TRUNCATION_CHECK
+ IPv4PacketSizeVerify (l_PacketBuffer->m_Data, l_PacketLength, FALSE, "TX", &l_Adapter->m_TxTrunc);
+#endif
+
+ //=====================================================
// Are we running in DHCP server masquerade mode?
//
// If so, catch both DHCP requests and ARP queries
@@ -1381,6 +1447,7 @@ AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
(PARP_PACKET) l_PacketBuffer->m_Data,
l_Adapter->m_dhcp_addr,
l_Adapter->m_dhcp_server_ip,
+ ~0,
l_Adapter->m_dhcp_server_mac))
goto no_queue;
}
@@ -1417,7 +1484,7 @@ AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
// In Point-To-Point mode, check to see whether
// packet is ARP or IPv4 (if neither, then drop).
//===============================================
- if (l_Adapter->m_PointToPoint)
+ if (l_Adapter->m_tun)
{
ETH_HEADER *e;
@@ -1438,7 +1505,8 @@ AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
ProcessARP (l_Adapter,
(PARP_PACKET) l_PacketBuffer->m_Data,
l_Adapter->m_localIP,
- l_Adapter->m_remoteIP,
+ l_Adapter->m_remoteNetwork,
+ l_Adapter->m_remoteNetmask,
l_Adapter->m_TapToUser.dest);
default:
@@ -1458,7 +1526,7 @@ AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
goto no_queue;
// Packet looks like IPv4, queue it.
- l_PacketBuffer->m_SizeFlags |= TP_POINT_TO_POINT;
+ l_PacketBuffer->m_SizeFlags |= TP_TUN;
}
}
@@ -1669,15 +1737,25 @@ TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
NULL,
NULL,
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
+#if PACKET_TRUNCATION_CHECK
+ "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d,%d] Rx=[%d,%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d]",
+#else
"State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d]",
+#endif
state,
g_LastErrorFilename,
g_LastErrorLineNumber,
(int)l_Adapter->m_Extension.m_NumTapOpens,
(int)l_Adapter->m_Tx,
(int)l_Adapter->m_TxErr,
+#if PACKET_TRUNCATION_CHECK
+ (int)l_Adapter->m_TxTrunc,
+#endif
(int)l_Adapter->m_Rx,
(int)l_Adapter->m_RxErr,
+#if PACKET_TRUNCATION_CHECK
+ (int)l_Adapter->m_RxTrunc,
+#endif
(int)l_Adapter->m_Extension.m_IrpQueue->size,
(int)l_Adapter->m_Extension.m_IrpQueue->max_size,
(int)IRP_QUEUE_SIZE,
@@ -1708,21 +1786,65 @@ TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
}
#endif
- case TAP_IOCTL_CONFIG_POINT_TO_POINT:
+ case TAP_IOCTL_CONFIG_TUN:
+ {
+ if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
+ (sizeof (IPADDR) * 3))
+ {
+ MACADDR dest;
+
+ l_Adapter->m_tun = FALSE;
+
+ GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);
+
+ l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
+ l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
+ l_Adapter->m_remoteNetmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2];
+
+ // sanity check on network/netmask
+ if ((l_Adapter->m_remoteNetwork & l_Adapter->m_remoteNetmask) != l_Adapter->m_remoteNetwork)
+ {
+ NOTE_ERROR ();
+ p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ 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_tun = TRUE;
+
+ CheckIfDhcpAndTunMode (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_POINT_TO_POINT: // Obsoleted by TAP_IOCTL_CONFIG_TUN
{
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
(sizeof (IPADDR) * 2))
{
MACADDR dest;
- l_Adapter->m_PointToPoint = FALSE;
+ l_Adapter->m_tun = 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];
+ l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
+ l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
+ l_Adapter->m_remoteNetmask = ~0;
COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC);
COPY_MAC (l_Adapter->m_TapToUser.dest, dest);
@@ -1731,9 +1853,9 @@ TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);
- l_Adapter->m_PointToPoint = TRUE;
+ l_Adapter->m_tun = TRUE;
- CheckIfDhcpAndPointToPointMode (l_Adapter);
+ CheckIfDhcpAndTunMode (l_Adapter);
p_IRP->IoStatus.Information = 1; // Simple boolean value
}
@@ -1791,7 +1913,7 @@ TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
l_Adapter->m_dhcp_enabled = TRUE;
l_Adapter->m_dhcp_server_arp = TRUE;
- CheckIfDhcpAndPointToPointMode (l_Adapter);
+ CheckIfDhcpAndTunMode (l_Adapter);
p_IRP->IoStatus.Information = 1; // Simple boolean value
}
@@ -1979,7 +2101,7 @@ TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
p_IRP->IoStatus.Information = 0;
}
- else if (!l_Adapter->m_PointToPoint && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE))
+ else if (!l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE))
{
__try
{
@@ -1989,6 +2111,18 @@ TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
l_IrpSp->Parameters.Write.Length);
+ //=====================================================
+ // If IPv4 packet, check whether or not packet
+ // was truncated.
+ //=====================================================
+#if PACKET_TRUNCATION_CHECK
+ IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
+ l_IrpSp->Parameters.Write.Length,
+ FALSE,
+ "RX",
+ &l_Adapter->m_RxTrunc);
+#endif
+
NdisMEthIndicateReceive
(l_Adapter->m_MiniportAdapterHandle,
(NDIS_HANDLE) l_Adapter,
@@ -2011,7 +2145,7 @@ TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
p_IRP->IoStatus.Information = 0;
}
}
- else if (l_Adapter->m_PointToPoint && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE))
+ else if (l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE))
{
__try
{
@@ -2022,6 +2156,18 @@ TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
l_IrpSp->Parameters.Write.Length);
+ //=====================================================
+ // If IPv4 packet, check whether or not packet
+ // was truncated.
+ //=====================================================
+#if PACKET_TRUNCATION_CHECK
+ IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
+ l_IrpSp->Parameters.Write.Length,
+ TRUE,
+ "RX",
+ &l_Adapter->m_RxTrunc);
+#endif
+
NdisMEthIndicateReceive
(l_Adapter->m_MiniportAdapterHandle,
(NDIS_HANDLE) l_Adapter,
@@ -2197,7 +2343,7 @@ CompleteIRP (IN PIRP p_IRP,
// component.
//-------------------------------------------
- if (p_PacketBuffer->m_SizeFlags & TP_POINT_TO_POINT)
+ if (p_PacketBuffer->m_SizeFlags & TP_TUN)
{
offset = ETHERNET_HEADER_SIZE;
len = (int) (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE;
@@ -2379,16 +2525,16 @@ SetMediaStatus (TapAdapterPointer p_Adapter, BOOLEAN state)
//======================================================
-// If DHCP mode is used together with Point-to-point
-// mode, consider the fact that the P2P remote endpoint
-// might be equal to the DHCP masq server address.
+// If DHCP mode is used together with tun
+// mode, consider the fact that the P2P remote subnet
+// might enclose the DHCP masq server address.
//======================================================
VOID
-CheckIfDhcpAndPointToPointMode (TapAdapterPointer p_Adapter)
+CheckIfDhcpAndTunMode (TapAdapterPointer p_Adapter)
{
- if (p_Adapter->m_PointToPoint && p_Adapter->m_dhcp_enabled)
+ if (p_Adapter->m_tun && p_Adapter->m_dhcp_enabled)
{
- if (p_Adapter->m_dhcp_server_ip == p_Adapter->m_remoteIP)
+ if ((p_Adapter->m_dhcp_server_ip & p_Adapter->m_remoteNetmask) == p_Adapter->m_remoteNetwork)
{
COPY_MAC (p_Adapter->m_dhcp_server_mac, p_Adapter->m_TapToUser.dest);
p_Adapter->m_dhcp_server_arp = FALSE;
@@ -2404,7 +2550,8 @@ BOOLEAN
ProcessARP (TapAdapterPointer p_Adapter,
const PARP_PACKET src,
const IPADDR adapter_ip,
- const IPADDR ip,
+ const IPADDR ip_network,
+ const IPADDR ip_netmask,
const MACADDR mac)
{
//-----------------------------------------------
@@ -2420,7 +2567,8 @@ ProcessARP (TapAdapterPointer p_Adapter,
&& src->m_PROTO_AddressType == htons (ETH_P_IP)
&& src->m_PROTO_AddressSize == sizeof (IPADDR)
&& src->m_ARP_IP_Source == adapter_ip
- && src->m_ARP_IP_Destination == ip)
+ && (src->m_ARP_IP_Destination & ip_netmask) == ip_network
+ && src->m_ARP_IP_Destination != adapter_ip)
{
ARP_PACKET *arp = (ARP_PACKET *) MemAlloc (sizeof (ARP_PACKET), TRUE);
if (arp)
@@ -2442,7 +2590,7 @@ ProcessARP (TapAdapterPointer p_Adapter,
COPY_MAC (arp->m_MAC_Destination, p_Adapter->m_MAC);
COPY_MAC (arp->m_ARP_MAC_Source, mac);
COPY_MAC (arp->m_ARP_MAC_Destination, p_Adapter->m_MAC);
- arp->m_ARP_IP_Source = ip;
+ arp->m_ARP_IP_Source = src->m_ARP_IP_Destination;
arp->m_ARP_IP_Destination = adapter_ip;
DUMP_PACKET ("ProcessARP",
@@ -2508,9 +2656,10 @@ InjectPacket (TapAdapterPointer p_Adapter,
VOID ResetTapAdapterState (TapAdapterPointer p_Adapter)
{
// Point-To-Point
- p_Adapter->m_PointToPoint = FALSE;
+ p_Adapter->m_tun = FALSE;
p_Adapter->m_localIP = 0;
- p_Adapter->m_remoteIP = 0;
+ p_Adapter->m_remoteNetwork = 0;
+ p_Adapter->m_remoteNetmask = 0;
NdisZeroMemory (&p_Adapter->m_TapToUser, sizeof (p_Adapter->m_TapToUser));
NdisZeroMemory (&p_Adapter->m_UserToTap, sizeof (p_Adapter->m_UserToTap));
@@ -2526,6 +2675,124 @@ VOID ResetTapAdapterState (TapAdapterPointer p_Adapter)
p_Adapter->m_dhcp_bad_requests = 0;
NdisZeroMemory (p_Adapter->m_dhcp_server_mac, sizeof (MACADDR));
}
+
+#if ENABLE_NONADMIN
+
+//===================================================================
+// Set TAP device handle to be accessible without admin privileges.
+//===================================================================
+VOID AllowNonAdmin (TapExtensionPointer p_Extension)
+{
+ NTSTATUS stat;
+ SECURITY_DESCRIPTOR sd;
+ OBJECT_ATTRIBUTES oa;
+ IO_STATUS_BLOCK isb;
+ HANDLE hand = NULL;
+
+ NdisZeroMemory (&sd, sizeof (sd));
+ NdisZeroMemory (&oa, sizeof (oa));
+ NdisZeroMemory (&isb, sizeof (isb));
+
+ if (!p_Extension->m_CreatedUnicodeLinkName)
+ {
+ DEBUGP (("[TAP] AllowNonAdmin: UnicodeLinkName is uninitialized\n"));
+ NOTE_ERROR ();
+ return;
+ }
+
+ stat = RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
+ if (stat != STATUS_SUCCESS)
+ {
+ DEBUGP (("[TAP] AllowNonAdmin: RtlCreateSecurityDescriptor failed\n"));
+ NOTE_ERROR ();
+ return;
+ }
+
+ InitializeObjectAttributes (
+ &oa,
+ &p_Extension->m_UnicodeLinkName,
+ OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL
+ );
+
+ stat = ZwOpenFile (
+ &hand,
+ WRITE_DAC,
+ &oa,
+ &isb,
+ 0,
+ 0
+ );
+ if (stat != STATUS_SUCCESS)
+ {
+ DEBUGP (("[TAP] AllowNonAdmin: ZwOpenFile failed, status=0x%08x\n", (unsigned int)stat));
+ NOTE_ERROR ();
+ return;
+ }
+
+ stat = ZwSetSecurityObject (hand, DACL_SECURITY_INFORMATION, &sd);
+ if (stat != STATUS_SUCCESS)
+ {
+ DEBUGP (("[TAP] AllowNonAdmin: ZwSetSecurityObject failed\n"));
+ NOTE_ERROR ();
+ return;
+ }
+
+ stat = ZwClose (hand);
+ if (stat != STATUS_SUCCESS)
+ {
+ DEBUGP (("[TAP] AllowNonAdmin: ZwClose failed\n"));
+ NOTE_ERROR ();
+ return;
+ }
+
+ DEBUGP (("[TAP] AllowNonAdmin: SUCCEEDED\n"));
+}
+
+#endif
+
+#if PACKET_TRUNCATION_CHECK
+
+VOID
+IPv4PacketSizeVerify (const UCHAR *data, ULONG length, BOOLEAN tun, const char *prefix, LONG *counter)
+{
+ const IPHDR *ip;
+ int len = length;
+
+ if (tun)
+ {
+ ip = (IPHDR *) data;
+ }
+ else
+ {
+ if (length >= sizeof (ETH_HEADER))
+ {
+ const ETH_HEADER *eth = (ETH_HEADER *) data;
+
+ if (eth->proto != htons (ETH_P_IP))
+ return;
+
+ ip = (IPHDR *) (data + sizeof (ETH_HEADER));
+ len -= sizeof (ETH_HEADER);
+ }
+ else
+ return;
+ }
+
+ if (len >= sizeof (IPHDR))
+ {
+ const int totlen = ntohs (ip->tot_len);
+
+ DEBUGP (("[TAP] IPv4PacketSizeVerify %s len=%d totlen=%d\n", prefix, len, totlen));
+
+ if (len != totlen)
+ ++(*counter);
+ }
+}
+
+#endif
+
//======================================================================
// End of Source
//======================================================================
diff --git a/tap-win32/types.h b/tap-win32/types.h
index f5a4291..45e0033 100755
--- a/tap-win32/types.h
+++ b/tap-win32/types.h
@@ -92,8 +92,8 @@ TapExtension, *TapExtensionPointer;
typedef struct _TapPacket
{
# define TAP_PACKET_SIZE(data_size) (sizeof (TapPacket) + (data_size))
-# define TP_POINT_TO_POINT 0x80000000
-# define TP_SIZE_MASK (~TP_POINT_TO_POINT)
+# define TP_TUN 0x80000000
+# define TP_SIZE_MASK (~TP_TUN)
ULONG m_SizeFlags;
UCHAR m_Data []; // m_Data must be the last struct member
}
@@ -107,6 +107,9 @@ typedef struct _TapAdapter
BOOLEAN m_InterfaceIsRunning;
NDIS_HANDLE m_MiniportAdapterHandle;
LONG m_Rx, m_Tx, m_RxErr, m_TxErr;
+#if PACKET_TRUNCATION_CHECK
+ LONG m_RxTrunc, m_TxTrunc;
+#endif
NDIS_MEDIUM m_Medium;
ULONG m_Lookahead;
ULONG m_MTU;
@@ -123,9 +126,10 @@ typedef struct _TapAdapter
char m_DeviceState;
// Info for point-to-point mode
- BOOLEAN m_PointToPoint;
+ BOOLEAN m_tun;
IPADDR m_localIP;
- IPADDR m_remoteIP;
+ IPADDR m_remoteNetwork;
+ IPADDR m_remoteNetmask;
ETH_HEADER m_TapToUser;
ETH_HEADER m_UserToTap;
MACADDR m_MAC_Broadcast;