2
* TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap
3
* device functionality on Windows.
5
* This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
7
* This source code is Copyright (C) 2002-2009 OpenVPN Technologies, Inc.,
8
* and is released under the GPL version 2 (see below), however due
9
* to the extra costs of supporting Windows Vista, OpenVPN Solutions
10
* LLC reserves the right to change the terms of the TAP-Win32/TAP-Win64
11
* license for versions 9.1 and higher prior to the official release of
14
* This program is free software; you can redistribute it and/or modify
15
* it under the terms of the GNU General Public License version 2
16
* as published by the Free Software Foundation.
18
* This program is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU General Public License for more details.
23
* You should have received a copy of the GNU General Public License
24
* along with this program (see the file COPYING included with this
25
* distribution); if not, write to the Free Software Foundation, Inc.,
26
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29
//======================================================
30
// This driver is designed to work on Win 2000 or higher
31
// versions of Windows.
33
// It is SMP-safe and handles NDIS 5 power management.
35
// By default we operate as a "tap" virtual ethernet
36
// 802.3 interface, but we can emulate a "tun"
37
// interface (point-to-point IPv4) through the
38
// TAP_IOCTL_CONFIG_POINT_TO_POINT or
39
// TAP_IOCTL_CONFIG_TUN ioctl.
40
//======================================================
42
#include "../../autodefs/defs.h"
44
#error DDKVER_MAJOR must be defined as the major number of the DDK Version
47
#define NDIS_MINIPORT_DRIVER
48
#define BINARY_COMPATIBLE 0
49
#define NDIS50_MINIPORT 1
55
#define ALSO_DBGPRINT 1
56
#define DEBUGP_AT_DISPATCH 0
58
//========================================================
59
// Check for truncated IPv4 packets, log errors if found.
60
//========================================================
61
#define PACKET_TRUNCATION_CHECK 0
63
//========================================================
64
// EXPERIMENTAL -- Configure TAP device object to be
65
// accessible from non-administrative accounts, based
66
// on an advanced properties setting.
68
// Duplicates the functionality of OpenVPN's
69
// --allow-nonadmin directive.
70
//========================================================
71
#define ENABLE_NONADMIN 1
73
#if DDKVER_MAJOR < 5600
75
#include <ntstrsafe.h>
80
#include <ntstrsafe.h>
84
#include "constants.h"
91
#include "prototypes.h"
100
((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning)
102
#define INCREMENT_STAT(s) ++(s)
104
#define NAME_BUFFER_SIZE 80
106
//========================================================
108
//========================================================
110
NDIS_HANDLE g_NdisWrapperHandle;
112
const UINT g_SupportedOIDList[] = {
113
OID_GEN_HARDWARE_STATUS,
114
OID_GEN_MEDIA_SUPPORTED,
115
OID_GEN_MEDIA_IN_USE,
116
OID_GEN_MAXIMUM_LOOKAHEAD,
119
OID_GEN_TRANSMIT_BLOCK_SIZE,
120
OID_GEN_RECEIVE_BLOCK_SIZE,
121
OID_GEN_VENDOR_DESCRIPTION,
122
OID_GEN_DRIVER_VERSION,
127
OID_802_3_PERMANENT_ADDRESS,
128
OID_802_3_CURRENT_ADDRESS,
129
OID_GEN_RCV_NO_BUFFER,
130
OID_802_3_RCV_ERROR_ALIGNMENT,
131
OID_802_3_XMIT_ONE_COLLISION,
132
OID_802_3_XMIT_MORE_COLLISIONS,
133
OID_802_3_MULTICAST_LIST,
134
OID_802_3_MAXIMUM_LIST_SIZE,
136
OID_GEN_CURRENT_LOOKAHEAD,
137
OID_GEN_CURRENT_PACKET_FILTER,
138
OID_GEN_PROTOCOL_OPTIONS,
139
OID_GEN_MAXIMUM_TOTAL_SIZE,
140
OID_GEN_TRANSMIT_BUFFER_SPACE,
141
OID_GEN_RECEIVE_BUFFER_SPACE,
142
OID_GEN_MAXIMUM_FRAME_SIZE,
143
OID_GEN_VENDOR_DRIVER_VERSION,
144
OID_GEN_MAXIMUM_SEND_PACKETS,
145
OID_GEN_MEDIA_CONNECT_STATUS,
146
OID_GEN_SUPPORTED_LIST
149
//============================================================
151
//============================================================
152
#pragma NDIS_INIT_FUNCTION (DriverEntry)
155
DriverEntry (IN PDRIVER_OBJECT p_DriverObject,
156
IN PUNICODE_STRING p_RegistryPath)
158
NDIS_STATUS l_Status = NDIS_STATUS_FAILURE;
159
NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL;
161
//========================================================
162
// Notify NDIS that a new miniport driver is initializing.
163
//========================================================
165
NdisMInitializeWrapper (&g_NdisWrapperHandle,
167
p_RegistryPath, NULL);
169
//======================
170
// Global initialization
171
//======================
174
MyDebugInit (10000); // Allocate debugging text space
177
if (!InitInstanceList ())
179
DEBUGP (("[TAP] Allocation failed for adapter instance list\n"));
183
//=======================================
184
// Set and register miniport entry points
185
//=======================================
187
l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE);
189
if (l_Properties == NULL)
191
DEBUGP (("[TAP] Allocation failed for miniport entry points\n"));
195
l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
196
l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
197
l_Properties->InitializeHandler = AdapterCreate;
198
l_Properties->HaltHandler = AdapterHalt;
199
l_Properties->ResetHandler = AdapterReset; /* DISPATCH_LEVEL */
200
l_Properties->TransferDataHandler = AdapterReceive; /* DISPATCH_LEVEL */
201
l_Properties->SendHandler = AdapterTransmit; /* DISPATCH_LEVEL */
202
l_Properties->QueryInformationHandler = AdapterQuery; /* DISPATCH_LEVEL */
203
l_Properties->SetInformationHandler = AdapterModify; /* DISPATCH_LEVEL */
206
NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties,
207
sizeof (NDIS_MINIPORT_CHARACTERISTICS)))
209
case NDIS_STATUS_SUCCESS:
211
DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n",
212
TAP_DRIVER_MAJOR_VERSION,
213
TAP_DRIVER_MINOR_VERSION,
216
DEBUGP (("Registry Path: '%S'\n", p_RegistryPath->Buffer));
220
case NDIS_STATUS_BAD_CHARACTERISTICS:
222
DEBUGP (("[TAP] Miniport characteristics were badly defined\n"));
223
NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
227
case NDIS_STATUS_BAD_VERSION:
230
(("[TAP] NDIS Version is wrong for the given characteristics\n"));
231
NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
235
case NDIS_STATUS_RESOURCES:
237
DEBUGP (("[TAP] Insufficient resources\n"));
238
NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
243
case NDIS_STATUS_FAILURE:
245
DEBUGP (("[TAP] Unknown fatal registration error\n"));
246
NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
253
MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS));
255
if (l_Status == NDIS_STATUS_SUCCESS)
256
NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload);
258
TapDriverUnload (p_DriverObject);
263
//============================================================
265
//============================================================
267
TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject)
269
DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n",
270
TAP_DRIVER_MAJOR_VERSION,
271
TAP_DRIVER_MINOR_VERSION,
275
InstanceMaxBucketSize()));
279
//==============================
280
// Free debugging text space
281
//==============================
287
//==========================================================
288
// Adapter Initialization
289
//==========================================================
290
NDIS_STATUS AdapterCreate
291
(OUT PNDIS_STATUS p_ErrorStatus,
292
OUT PUINT p_MediaIndex,
293
IN PNDIS_MEDIUM p_Media,
294
IN UINT p_MediaCount,
295
IN NDIS_HANDLE p_AdapterHandle,
296
IN NDIS_HANDLE p_ConfigurationHandle)
298
TapAdapterPointer l_Adapter = NULL;
300
NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet
301
BOOLEAN l_MacFromRegistry = FALSE;
306
BOOLEAN enable_non_admin = FALSE;
309
DEBUGP (("[TAP] AdapterCreate called\n"));
311
//====================================
312
// Make sure adapter type is supported
313
//====================================
316
l_Index < p_MediaCount && p_Media[l_Index] != l_PreferredMedium;
319
if (l_Index == p_MediaCount)
321
DEBUGP (("[TAP] Unsupported adapter type [wanted: %d]\n",
323
return NDIS_STATUS_UNSUPPORTED_MEDIA;
326
*p_MediaIndex = l_Index;
328
//=========================================
329
// Allocate memory for TapAdapter structure
330
//=========================================
332
l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE);
334
if (l_Adapter == NULL)
336
DEBUGP (("[TAP] Couldn't allocate adapter memory\n"));
337
return NDIS_STATUS_RESOURCES;
340
//==========================================
341
// Inform the NDIS library about significant
342
// features of our virtual NIC.
343
//==========================================
347
(NDIS_HANDLE) l_Adapter,
349
NDIS_ATTRIBUTE_DESERIALIZE
350
| NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT
351
| NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT
352
| NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
353
NdisInterfaceInternal);
355
//=====================================
356
// Initialize simple Adapter parameters
357
//=====================================
359
l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD;
360
l_Adapter->m_Medium = l_PreferredMedium;
361
l_Adapter->m_DeviceState = '?';
362
l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle;
364
//==================================
365
// Allocate spinlock for controlling
366
// access to multicast address list.
367
//==================================
368
NdisAllocateSpinLock (&l_Adapter->m_MCLock);
369
l_Adapter->m_MCLockAllocated = TRUE;
371
//====================================================
372
// Register a shutdown handler which will be called
373
// on system restart/shutdown to halt our virtual NIC.
374
//====================================================
376
NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter,
378
l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE;
380
//============================================
381
// Get parameters from registry which were set
382
// in the adapter advanced properties dialog.
383
//============================================
386
NDIS_HANDLE configHandle;
387
NDIS_CONFIGURATION_PARAMETER *parm;
389
// set defaults in case our registry query fails
390
l_Adapter->m_MTU = ETHERNET_MTU;
391
l_Adapter->m_MediaStateAlwaysConnected = FALSE;
392
l_Adapter->m_MediaState = FALSE;
394
NdisOpenConfiguration (&status, &configHandle, p_ConfigurationHandle);
395
if (status != NDIS_STATUS_SUCCESS)
397
DEBUGP (("[TAP] Couldn't open adapter registry\n"));
398
AdapterFreeResources (l_Adapter);
402
//====================================
403
// Allocate and construct adapter name
404
//====================================
407
NDIS_STRING mkey = NDIS_STRING_CONST("MiniportName");
408
NDIS_STRING vkey = NDIS_STRING_CONST("NdisVersion");
410
NDIS_CONFIGURATION_PARAMETER *vparm;
412
NdisReadConfiguration (&vstatus, &vparm, configHandle, &vkey, NdisParameterInteger);
413
if (vstatus == NDIS_STATUS_SUCCESS)
414
DEBUGP (("[TAP] NdisReadConfiguration NdisVersion=%X\n", vparm->ParameterData.IntegerData));
416
NdisReadConfiguration (&status, &parm, configHandle, &mkey, NdisParameterString);
417
if (status == NDIS_STATUS_SUCCESS)
419
if (parm->ParameterType == NdisParameterString)
421
DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%S)\n", parm->ParameterData.StringData.Buffer));
423
if (RtlUnicodeStringToAnsiString (
424
&l_Adapter->m_NameAnsi,
425
&parm->ParameterData.StringData,
426
TRUE) != STATUS_SUCCESS)
428
DEBUGP (("[TAP] MiniportName failed\n"));
429
status = NDIS_STATUS_RESOURCES;
435
/* "MiniportName" is available only XP and above. Not on Windows 2000. */
436
if (vstatus == NDIS_STATUS_SUCCESS && vparm->ParameterData.IntegerData == 0x50000)
438
/* Fallback for Windows 2000 with NDIS version 5.00.00
439
Don't use this on Vista, 'NDIS_MINIPORT_BLOCK' was changed! */
440
if (RtlUnicodeStringToAnsiString (&l_Adapter->m_NameAnsi,
441
&((struct WIN2K_NDIS_MINIPORT_BLOCK *) p_AdapterHandle)->MiniportName,
442
TRUE) != STATUS_SUCCESS)
444
DEBUGP (("[TAP] MiniportName (W2K) failed\n"));
445
status = NDIS_STATUS_RESOURCES;
449
DEBUGP (("[TAP] MiniportName (W2K) succeeded: %s\n", l_Adapter->m_NameAnsi.Buffer));
450
status = NDIS_STATUS_SUCCESS;
456
/* Can't continue without name (see macro 'NAME') */
457
if (status != NDIS_STATUS_SUCCESS || !l_Adapter->m_NameAnsi.Buffer)
459
NdisCloseConfiguration (configHandle);
460
AdapterFreeResources (l_Adapter);
461
DEBUGP (("[TAP] failed to get miniport name\n"));
462
return NDIS_STATUS_RESOURCES;
465
/* Read MTU setting from registry */
467
NDIS_STRING key = NDIS_STRING_CONST("MTU");
468
NdisReadConfiguration (&status, &parm, configHandle,
469
&key, NdisParameterInteger);
470
if (status == NDIS_STATUS_SUCCESS)
472
if (parm->ParameterType == NdisParameterInteger)
474
int mtu = parm->ParameterData.IntegerData;
475
if (mtu < MINIMUM_MTU)
477
if (mtu > MAXIMUM_MTU)
479
l_Adapter->m_MTU = mtu;
484
/* Read Media Status setting from registry */
486
NDIS_STRING key = NDIS_STRING_CONST("MediaStatus");
487
NdisReadConfiguration (&status, &parm, configHandle,
488
&key, NdisParameterInteger);
489
if (status == NDIS_STATUS_SUCCESS)
491
if (parm->ParameterType == NdisParameterInteger)
493
if (parm->ParameterData.IntegerData)
495
l_Adapter->m_MediaStateAlwaysConnected = TRUE;
496
l_Adapter->m_MediaState = TRUE;
503
/* Read AllowNonAdmin setting from registry */
505
NDIS_STRING key = NDIS_STRING_CONST("AllowNonAdmin");
506
NdisReadConfiguration (&status, &parm, configHandle,
507
&key, NdisParameterInteger);
508
if (status == NDIS_STATUS_SUCCESS)
510
if (parm->ParameterType == NdisParameterInteger)
512
if (parm->ParameterData.IntegerData)
514
enable_non_admin = TRUE;
521
/* Read optional MAC setting from registry */
523
NDIS_STRING key = NDIS_STRING_CONST("MAC");
524
ANSI_STRING mac_string;
525
NdisReadConfiguration (&status, &parm, configHandle,
526
&key, NdisParameterString);
527
if (status == NDIS_STATUS_SUCCESS)
529
if (parm->ParameterType == NdisParameterString)
531
if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS)
533
l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer);
534
RtlFreeAnsiString (&mac_string);
540
NdisCloseConfiguration (configHandle);
542
DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU));
545
//==================================
546
// Store and update MAC address info
547
//==================================
549
if (!l_MacFromRegistry)
550
GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter));
552
DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",
554
l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],
555
l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));
562
for (i = 0; i < sizeof (MACADDR); ++i)
563
l_Adapter->m_MAC_Broadcast[i] = 0xFF;
566
//====================================
567
// Initialize TAP device
568
//====================================
570
NDIS_STATUS tap_status;
571
tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter));
572
if (tap_status != NDIS_STATUS_SUCCESS)
574
AdapterFreeResources (l_Adapter);
575
DEBUGP (("[TAP] CreateTapDevice failed\n"));
580
if (!AddAdapterToInstanceList (l_Adapter))
583
TapDeviceFreeResources (&l_Adapter->m_Extension);
584
AdapterFreeResources (l_Adapter);
585
DEBUGP (("[TAP] AddAdapterToInstanceList failed\n"));
586
return NDIS_STATUS_RESOURCES;
589
l_Adapter->m_InterfaceIsRunning = TRUE;
592
if (enable_non_admin)
593
AllowNonAdmin (&l_Adapter->m_Extension);
596
return NDIS_STATUS_SUCCESS;
600
AdapterHalt (IN NDIS_HANDLE p_AdapterContext)
604
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
608
l_Adapter->m_InterfaceIsRunning = FALSE;
610
DEBUGP (("[%s] is being halted\n", NAME (l_Adapter)));
612
DestroyTapDevice (&l_Adapter->m_Extension);
615
DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter)));
616
AdapterFreeResources (l_Adapter);
618
status = RemoveAdapterFromInstanceList (l_Adapter);
619
DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status));
621
DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n",
622
TAP_DRIVER_MAJOR_VERSION,
623
TAP_DRIVER_MINOR_VERSION,
629
AdapterFreeResources (TapAdapterPointer p_Adapter)
631
MYASSERT (!p_Adapter->m_CalledAdapterFreeResources);
632
p_Adapter->m_CalledAdapterFreeResources = TRUE;
634
if (p_Adapter->m_NameAnsi.Buffer)
635
RtlFreeAnsiString (&p_Adapter->m_NameAnsi);
637
if (p_Adapter->m_RegisteredAdapterShutdownHandler)
638
NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle);
640
if (p_Adapter->m_MCLockAllocated)
641
NdisFreeSpinLock (&p_Adapter->m_MCLock);
645
DestroyTapDevice (TapExtensionPointer p_Extension)
647
DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName));
649
//======================================
650
// Let clients know we are shutting down
651
//======================================
652
p_Extension->m_TapIsRunning = FALSE;
653
p_Extension->m_TapOpens = 0;
654
p_Extension->m_Halt = TRUE;
656
//=====================================
657
// If we are concurrently executing in
658
// TapDeviceHook or AdapterTransmit,
659
// give those calls time to finish.
660
// Note that we must be running at IRQL
661
// < DISPATCH_LEVEL in order to call
663
//=====================================
666
//===========================================================
667
// Exhaust IRP and packet queues. Any pending IRPs will
668
// be cancelled, causing user-space to get this error
669
// on overlapped reads:
670
// The I/O operation has been aborted because of either a
671
// thread exit or an application request. (code=995)
672
// It's important that user-space close the device handle
673
// when this code is returned, so that when we finally
674
// do a NdisMDeregisterDevice, the device reference count
675
// is 0. Otherwise the driver will not unload even if the
676
// the last adapter has been halted.
677
//===========================================================
678
FlushQueues (p_Extension);
679
NdisMSleep (500000); // give user space time to respond to IRP cancel
681
TapDeviceFreeResources (p_Extension);
685
TapDeviceFreeResources (TapExtensionPointer p_Extension)
687
MYASSERT (p_Extension);
688
MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources);
689
p_Extension->m_CalledTapDeviceFreeResources = TRUE;
691
if (p_Extension->m_PacketQueue)
692
QueueFree (p_Extension->m_PacketQueue);
693
if (p_Extension->m_IrpQueue)
694
QueueFree (p_Extension->m_IrpQueue);
695
if (p_Extension->m_InjectQueue)
696
QueueFree (p_Extension->m_InjectQueue);
698
if (p_Extension->m_CreatedUnicodeLinkName)
699
RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName);
701
//==========================================================
702
// According to DDK docs, the device is not actually deleted
703
// until its reference count falls to zero. That means we
704
// still need to gracefully fail TapDeviceHook requests
705
// after this point, otherwise ugly things would happen if
706
// the device was disabled (e.g. in the network connections
707
// control panel) while a userspace app still held an open
708
// file handle to it.
709
//==========================================================
711
if (p_Extension->m_TapDevice)
714
status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle)
715
== NDIS_STATUS_SUCCESS);
716
DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status));
719
if (p_Extension->m_TapName)
720
MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE);
722
if (p_Extension->m_InjectDpcInitialized)
723
KeRemoveQueueDpc (&p_Extension->m_InjectDpc);
725
if (p_Extension->m_AllocatedSpinlocks)
727
NdisFreeSpinLock (&p_Extension->m_QueueLock);
728
NdisFreeSpinLock (&p_Extension->m_InjectLock);
732
//========================================================================
733
// Tap Device Initialization
734
//========================================================================
737
CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name)
739
# define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1))
740
PDRIVER_DISPATCH *l_Dispatch = NULL;
741
ANSI_STRING l_TapString, l_LinkString;
742
UNICODE_STRING l_TapUnicode;
743
BOOLEAN l_FreeTapUnicode = FALSE;
744
NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS;
745
const char *l_UsableName;
747
DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
748
TAP_DRIVER_MAJOR_VERSION,
749
TAP_DRIVER_MINOR_VERSION,
752
NdisZeroMemory (p_Extension, sizeof (TapExtension));
754
INIT_MUTEX (&p_Extension->m_OpenCloseMutex);
756
l_LinkString.Buffer = NULL;
757
l_TapString.Buffer = NULL;
759
l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE;
761
//=======================================
762
// Set TAP device entry points
763
//=======================================
765
if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL)
767
DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name));
768
l_Return = NDIS_STATUS_RESOURCES;
772
l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook;
773
l_Dispatch[IRP_MJ_READ] = TapDeviceHook;
774
l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook;
775
l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook;
776
l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook;
778
//==================================
779
// Find the beginning of the GUID
780
//==================================
781
l_UsableName = p_Name;
782
while (*l_UsableName != '{')
784
if (*l_UsableName == '\0')
786
DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name));
787
l_Return = NDIS_STATUS_RESOURCES;
793
//==================================
794
// Allocate pool for TAP device name
795
//==================================
797
if ((p_Extension->m_TapName = l_TapString.Buffer =
798
MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
800
DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name));
801
l_Return = NDIS_STATUS_RESOURCES;
805
//================================================
806
// Allocate pool for TAP symbolic link name buffer
807
//================================================
809
if ((l_LinkString.Buffer =
810
MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
812
DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n",
814
l_Return = NDIS_STATUS_RESOURCES;
818
//=======================================================
819
// Set TAP device name
820
//=======================================================
822
l_Status = RtlStringCchPrintfExA
824
l_TapString.MaximumLength,
827
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
833
if (l_Status != STATUS_SUCCESS)
835
DEBUGP (("[%s] couldn't format TAP device name\n",
837
l_Return = NDIS_STATUS_RESOURCES;
840
l_TapString.Length = (USHORT) strlen (l_TapString.Buffer);
842
DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer));
844
//=======================================================
846
//=======================================================
848
l_Status = RtlStringCchPrintfExA
849
(l_LinkString.Buffer,
850
l_LinkString.MaximumLength,
853
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
859
if (l_Status != STATUS_SUCCESS)
861
DEBUGP (("[%s] couldn't format TAP device symbolic link\n",
863
l_Return = NDIS_STATUS_RESOURCES;
866
l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer);
868
DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer));
870
//==================================================
871
// Convert strings to unicode
872
//==================================================
873
if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) !=
876
DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n",
878
l_Return = NDIS_STATUS_RESOURCES;
881
l_FreeTapUnicode = TRUE;
883
if (RtlAnsiStringToUnicodeString
884
(&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE)
888
(("[%s] Couldn't allocate unicode string for symbolic link name\n",
890
l_Return = NDIS_STATUS_RESOURCES;
893
p_Extension->m_CreatedUnicodeLinkName = TRUE;
895
//==================================================
896
// Create new TAP device with symbolic
897
// link and associate with adapter.
898
//==================================================
900
l_Status = NdisMRegisterDevice
901
(g_NdisWrapperHandle,
903
&p_Extension->m_UnicodeLinkName,
905
&p_Extension->m_TapDevice,
906
&p_Extension->m_TapDeviceHandle
909
if (l_Status != STATUS_SUCCESS)
911
DEBUGP (("[%s] couldn't be created\n", p_Name));
912
l_Return = NDIS_STATUS_RESOURCES;
916
/* Set TAP device flags */
917
p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO;
919
//========================================================
920
// Initialize Packet and IRP queues.
922
// The packet queue is used to buffer data which has been
923
// "transmitted" by the virtual NIC, before user space
924
// has had a chance to read it.
926
// The IRP queue is used to buffer pending I/O requests
927
// from userspace, i.e. read requests on the TAP device
928
// waiting for the system to "transmit" something through
931
// Basically, packets in the packet queue are used
932
// to satisfy IRP requests in the IRP queue.
934
// QueueLock is used to lock the packet queue used
935
// for the TAP-Win32 NIC -> User Space packet flow direction.
937
// All accesses to packet or IRP queues should be
938
// bracketed by the QueueLock spinlock,
939
// in order to be SMP-safe.
940
//========================================================
942
NdisAllocateSpinLock (&p_Extension->m_QueueLock);
943
NdisAllocateSpinLock (&p_Extension->m_InjectLock);
944
p_Extension->m_AllocatedSpinlocks = TRUE;
946
p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE);
947
p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE);
948
p_Extension->m_InjectQueue = QueueInit (INJECT_QUEUE_SIZE);
949
if (!p_Extension->m_PacketQueue
950
|| !p_Extension->m_IrpQueue
951
|| !p_Extension->m_InjectQueue)
953
DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name));
954
l_Return = NDIS_STATUS_RESOURCES;
958
//=================================================================
959
// Initialize deferred procedure call for DHCP/ARP packet injection
960
//=================================================================
962
KeInitializeDpc (&p_Extension->m_InjectDpc, InjectPacketDpc, NULL);
963
p_Extension->m_InjectDpcInitialized = TRUE;
965
//========================
966
// Finalize initialization
967
//========================
969
p_Extension->m_TapIsRunning = TRUE;
971
DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name,
972
p_Extension->m_TapName));
975
if (l_FreeTapUnicode)
976
RtlFreeUnicodeString (&l_TapUnicode);
977
if (l_LinkString.Buffer)
978
MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE);
980
MemFree (l_Dispatch, SIZEOF_DISPATCH);
982
if (l_Return != NDIS_STATUS_SUCCESS)
983
TapDeviceFreeResources (p_Extension);
987
#undef SIZEOF_DISPATCH
989
//========================================================
991
//========================================================
993
AdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext)
995
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
996
DEBUGP (("[%s] is resetting\n", NAME (l_Adapter)));
997
return NDIS_STATUS_SUCCESS;
1000
NDIS_STATUS AdapterReceive
1001
(OUT PNDIS_PACKET p_Packet,
1002
OUT PUINT p_Transferred,
1003
IN NDIS_HANDLE p_AdapterContext,
1004
IN NDIS_HANDLE p_ReceiveContext,
1006
IN UINT p_ToTransfer)
1008
return NDIS_STATUS_SUCCESS;
1011
//==============================================================
1012
// Adapter Option Query/Modification
1013
//==============================================================
1014
NDIS_STATUS AdapterQuery
1015
(IN NDIS_HANDLE p_AdapterContext,
1018
IN ULONG p_BufferLength,
1019
OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded)
1021
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1022
TapAdapterQuery l_Query, *l_QueryPtr = &l_Query;
1023
NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS;
1024
UINT l_QueryLength = 4;
1025
BOOLEAN lock_succeeded;
1027
NdisZeroMemory (&l_Query, sizeof (l_Query));
1031
//===================================================================
1032
// Vendor & Driver version Info
1033
//===================================================================
1034
case OID_GEN_VENDOR_DESCRIPTION:
1035
l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_STRING;
1036
l_QueryLength = strlen (PRODUCT_STRING) + 1;
1039
case OID_GEN_VENDOR_ID:
1040
l_Query.m_Long = 0xffffff;
1043
case OID_GEN_DRIVER_VERSION:
1045
(((USHORT) TAP_NDIS_MAJOR_VERSION) << 8 | (USHORT)
1046
TAP_NDIS_MINOR_VERSION);
1047
l_QueryLength = sizeof (unsigned short);
1050
case OID_GEN_VENDOR_DRIVER_VERSION:
1052
(((USHORT) TAP_DRIVER_MAJOR_VERSION) << 8 | (USHORT)
1053
TAP_DRIVER_MINOR_VERSION);
1056
//=================================================================
1058
//=================================================================
1059
case OID_GEN_RCV_NO_BUFFER:
1063
case OID_802_3_RCV_ERROR_ALIGNMENT:
1067
case OID_802_3_XMIT_ONE_COLLISION:
1071
case OID_802_3_XMIT_MORE_COLLISIONS:
1075
case OID_GEN_XMIT_OK:
1076
l_Query.m_Long = l_Adapter->m_Tx;
1079
case OID_GEN_RCV_OK:
1080
l_Query.m_Long = l_Adapter->m_Rx;
1083
case OID_GEN_XMIT_ERROR:
1084
l_Query.m_Long = l_Adapter->m_TxErr;
1087
case OID_GEN_RCV_ERROR:
1088
l_Query.m_Long = l_Adapter->m_RxErr;
1091
//===================================================================
1092
// Device & Protocol Options
1093
//===================================================================
1094
case OID_GEN_SUPPORTED_LIST:
1095
l_QueryPtr = (TapAdapterQueryPointer) g_SupportedOIDList;
1096
l_QueryLength = sizeof (g_SupportedOIDList);
1099
case OID_GEN_MAC_OPTIONS:
1100
// This MUST be here !!!
1101
l_Query.m_Long = (NDIS_MAC_OPTION_RECEIVE_SERIALIZED
1102
| NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
1103
| NDIS_MAC_OPTION_NO_LOOPBACK
1104
| NDIS_MAC_OPTION_TRANSFERS_NOT_PEND);
1108
case OID_GEN_CURRENT_PACKET_FILTER:
1110
(NDIS_PACKET_TYPE_ALL_LOCAL |
1111
NDIS_PACKET_TYPE_BROADCAST |
1112
NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL);
1116
case OID_GEN_PROTOCOL_OPTIONS:
1120
//==================================================================
1122
//==================================================================
1123
case OID_GEN_MEDIA_CONNECT_STATUS:
1124
l_Query.m_Long = l_Adapter->m_MediaState
1125
? NdisMediaStateConnected : NdisMediaStateDisconnected;
1128
case OID_GEN_HARDWARE_STATUS:
1129
l_Query.m_HardwareStatus = NdisHardwareStatusReady;
1130
l_QueryLength = sizeof (NDIS_HARDWARE_STATUS);
1133
case OID_GEN_MEDIA_SUPPORTED:
1134
case OID_GEN_MEDIA_IN_USE:
1135
l_Query.m_Medium = l_Adapter->m_Medium;
1136
l_QueryLength = sizeof (NDIS_MEDIUM);
1139
case OID_GEN_PHYSICAL_MEDIUM:
1140
l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified;
1141
l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM);
1144
case OID_GEN_LINK_SPEED:
1145
l_Query.m_Long = 100000; // rate / 100 bps
1148
case OID_802_3_PERMANENT_ADDRESS:
1149
case OID_802_3_CURRENT_ADDRESS:
1150
COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC);
1151
l_QueryLength = sizeof (MACADDR);
1154
//==================================================================
1156
//==================================================================
1158
case OID_GEN_MAXIMUM_SEND_PACKETS:
1162
case OID_802_3_MAXIMUM_LIST_SIZE:
1163
l_Query.m_Long = NIC_MAX_MCAST_LIST;
1166
case OID_GEN_CURRENT_LOOKAHEAD:
1167
l_Query.m_Long = l_Adapter->m_Lookahead;
1170
case OID_GEN_MAXIMUM_LOOKAHEAD:
1171
case OID_GEN_MAXIMUM_TOTAL_SIZE:
1172
case OID_GEN_RECEIVE_BUFFER_SPACE:
1173
case OID_GEN_RECEIVE_BLOCK_SIZE:
1174
l_Query.m_Long = DEFAULT_PACKET_LOOKAHEAD;
1177
case OID_GEN_MAXIMUM_FRAME_SIZE:
1178
case OID_GEN_TRANSMIT_BLOCK_SIZE:
1179
case OID_GEN_TRANSMIT_BUFFER_SPACE:
1180
l_Query.m_Long = l_Adapter->m_MTU;
1183
case OID_PNP_CAPABILITIES:
1186
PNDIS_PNP_CAPABILITIES pPNPCapabilities;
1187
PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct;
1189
if (p_BufferLength >= sizeof (NDIS_PNP_CAPABILITIES))
1191
pPNPCapabilities = (PNDIS_PNP_CAPABILITIES) (p_Buffer);
1194
// Setting up the buffer to be returned
1195
// to the Protocol above the Passthru miniport
1197
pPMstruct = &pPNPCapabilities->WakeUpCapabilities;
1198
pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
1199
pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
1200
pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
1202
l_QueryLength = sizeof (NDIS_PNP_CAPABILITIES);
1206
case OID_PNP_QUERY_POWER:
1209
// Required OIDs that we don't support
1211
case OID_GEN_SUPPORTED_GUIDS:
1212
case OID_GEN_MEDIA_CAPABILITIES:
1213
case OID_TCP_TASK_OFFLOAD:
1214
case OID_FFP_SUPPORT:
1215
l_Status = NDIS_STATUS_INVALID_OID;
1218
// Optional stats OIDs
1220
case OID_GEN_DIRECTED_BYTES_XMIT:
1221
case OID_GEN_DIRECTED_FRAMES_XMIT:
1222
case OID_GEN_MULTICAST_BYTES_XMIT:
1223
case OID_GEN_MULTICAST_FRAMES_XMIT:
1224
case OID_GEN_BROADCAST_BYTES_XMIT:
1225
case OID_GEN_BROADCAST_FRAMES_XMIT:
1226
case OID_GEN_DIRECTED_BYTES_RCV:
1227
case OID_GEN_DIRECTED_FRAMES_RCV:
1228
case OID_GEN_MULTICAST_BYTES_RCV:
1229
case OID_GEN_MULTICAST_FRAMES_RCV:
1230
case OID_GEN_BROADCAST_BYTES_RCV:
1231
case OID_GEN_BROADCAST_FRAMES_RCV:
1232
l_Status = NDIS_STATUS_INVALID_OID;
1235
//===================================================================
1237
//===================================================================
1239
DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID));
1240
l_Status = NDIS_STATUS_INVALID_OID;
1244
if (l_Status != NDIS_STATUS_SUCCESS)
1246
else if (l_QueryLength > p_BufferLength)
1248
l_Status = NDIS_STATUS_INVALID_LENGTH;
1249
*p_BytesNeeded = l_QueryLength;
1252
NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr,
1253
(*p_BytesWritten = l_QueryLength));
1258
NDIS_STATUS AdapterModify
1259
(IN NDIS_HANDLE p_AdapterContext,
1262
IN ULONG p_BufferLength,
1263
OUT PULONG p_BytesRead,
1264
OUT PULONG p_BytesNeeded)
1266
TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer;
1267
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1268
NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID;
1273
//==================================================================
1275
//==================================================================
1276
case OID_802_3_MULTICAST_LIST:
1277
DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n",
1280
*p_BytesNeeded = sizeof (ETH_ADDR);
1281
*p_BytesRead = p_BufferLength;
1283
if (p_BufferLength % sizeof (ETH_ADDR))
1284
l_Status = NDIS_STATUS_INVALID_LENGTH;
1285
else if (p_BufferLength > sizeof (MC_LIST))
1287
l_Status = NDIS_STATUS_MULTICAST_FULL;
1288
*p_BytesNeeded = sizeof (MC_LIST);
1292
NdisAcquireSpinLock (&l_Adapter->m_MCLock);
1294
NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST));
1296
NdisMoveMemory(&l_Adapter->m_MCList,
1300
l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR);
1302
NdisReleaseSpinLock (&l_Adapter->m_MCLock);
1304
l_Status = NDIS_STATUS_SUCCESS;
1308
case OID_GEN_CURRENT_PACKET_FILTER:
1309
l_Status = NDIS_STATUS_INVALID_LENGTH;
1312
if (p_BufferLength >= sizeof (ULONG))
1315
(("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n",
1316
NAME (l_Adapter), l_Query->m_Long));
1317
l_Status = NDIS_STATUS_SUCCESS;
1318
*p_BytesRead = sizeof (ULONG);
1322
case OID_GEN_CURRENT_LOOKAHEAD:
1323
if (p_BufferLength < sizeof (ULONG))
1325
l_Status = NDIS_STATUS_INVALID_LENGTH;
1328
else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD
1329
|| l_Query->m_Long <= 0)
1331
l_Status = NDIS_STATUS_INVALID_DATA;
1335
DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n",
1336
NAME (l_Adapter), l_Query->m_Long));
1337
l_Adapter->m_Lookahead = l_Query->m_Long;
1338
l_Status = NDIS_STATUS_SUCCESS;
1339
*p_BytesRead = sizeof (ULONG);
1343
case OID_GEN_NETWORK_LAYER_ADDRESSES:
1344
l_Status = NDIS_STATUS_SUCCESS;
1345
*p_BytesRead = *p_BytesNeeded = 0;
1348
case OID_GEN_TRANSPORT_HEADER_OFFSET:
1349
l_Status = NDIS_STATUS_SUCCESS;
1350
*p_BytesRead = *p_BytesNeeded = 0;
1353
case OID_PNP_SET_POWER:
1356
NDIS_DEVICE_POWER_STATE NewDeviceState;
1358
NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE) p_Buffer);
1360
switch (NewDeviceState)
1362
case NdisDeviceStateD0:
1363
l_Adapter->m_DeviceState = '0';
1365
case NdisDeviceStateD1:
1366
l_Adapter->m_DeviceState = '1';
1368
case NdisDeviceStateD2:
1369
l_Adapter->m_DeviceState = '2';
1371
case NdisDeviceStateD3:
1372
l_Adapter->m_DeviceState = '3';
1375
l_Adapter->m_DeviceState = '?';
1379
l_Status = NDIS_STATUS_FAILURE;
1382
// Check for invalid length
1384
if (p_BufferLength < sizeof (NDIS_DEVICE_POWER_STATE))
1386
l_Status = NDIS_STATUS_INVALID_LENGTH;
1390
if (NewDeviceState > NdisDeviceStateD0)
1392
l_Adapter->m_InterfaceIsRunning = FALSE;
1393
DEBUGP (("[%s] Power management device state OFF\n",
1398
l_Adapter->m_InterfaceIsRunning = TRUE;
1399
DEBUGP (("[%s] Power management device state ON\n",
1403
l_Status = NDIS_STATUS_SUCCESS;
1407
if (l_Status == NDIS_STATUS_SUCCESS)
1409
*p_BytesRead = sizeof (NDIS_DEVICE_POWER_STATE);
1415
*p_BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
1419
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
1420
case OID_PNP_ADD_WAKE_UP_PATTERN:
1421
l_Status = NDIS_STATUS_SUCCESS;
1422
*p_BytesRead = *p_BytesNeeded = 0;
1426
DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter),
1428
l_Status = NDIS_STATUS_INVALID_OID;
1429
*p_BytesRead = *p_BytesNeeded = 0;
1436
//====================================================================
1437
// Adapter Transmission
1438
//====================================================================
1440
AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
1441
IN PNDIS_PACKET p_Packet,
1444
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1445
ULONG l_Index = 0, l_PacketLength = 0;
1446
UINT l_BufferLength = 0;
1448
TapPacketPointer l_PacketBuffer;
1449
PNDIS_BUFFER l_NDIS_Buffer;
1453
NdisQueryPacket (p_Packet, NULL, NULL, &l_NDIS_Buffer, &l_PacketLength);
1455
//====================================================
1456
// Here we abandon the transmission attempt if any of
1457
// the parameters is wrong or memory allocation fails
1458
// but we do not indicate failure. The packet is
1459
// silently dropped.
1460
//====================================================
1462
if (l_PacketLength < ETHERNET_HEADER_SIZE || l_PacketLength > 65535)
1464
else if (!l_Adapter->m_Extension.m_TapOpens || !l_Adapter->m_MediaState)
1465
goto exit_success; // Nothing is bound to the TAP device
1467
if (NdisAllocateMemoryWithTag (&l_PacketBuffer,
1468
TAP_PACKET_SIZE (l_PacketLength),
1469
'5PAT') != NDIS_STATUS_SUCCESS)
1470
goto exit_no_resources;
1472
if (l_PacketBuffer == NULL)
1473
goto exit_no_resources;
1475
l_PacketBuffer->m_SizeFlags = (l_PacketLength & TP_SIZE_MASK);
1477
//===========================
1478
// Reassemble packet contents
1479
//===========================
1484
while (l_NDIS_Buffer && l_Index < l_PacketLength)
1487
NdisQueryBuffer (l_NDIS_Buffer, (PVOID *) & l_Buffer,
1489
newlen = l_Index + l_BufferLength;
1490
if (newlen > l_PacketLength)
1493
goto no_queue; /* overflow */
1495
NdisMoveMemory (l_PacketBuffer->m_Data + l_Index, l_Buffer,
1498
NdisGetNextBuffer (l_NDIS_Buffer, &l_NDIS_Buffer);
1500
if (l_Index != l_PacketLength)
1503
goto no_queue; /* underflow */
1506
DUMP_PACKET ("AdapterTransmit", l_PacketBuffer->m_Data, l_PacketLength);
1508
//=====================================================
1509
// If IPv4 packet, check whether or not packet
1511
//=====================================================
1512
#if PACKET_TRUNCATION_CHECK
1513
IPv4PacketSizeVerify (l_PacketBuffer->m_Data, l_PacketLength, FALSE, "TX", &l_Adapter->m_TxTrunc);
1516
//=====================================================
1517
// Are we running in DHCP server masquerade mode?
1519
// If so, catch both DHCP requests and ARP queries
1520
// to resolve the address of our virtual DHCP server.
1521
//=====================================================
1522
if (l_Adapter->m_dhcp_enabled)
1524
const ETH_HEADER *eth = (ETH_HEADER *) l_PacketBuffer->m_Data;
1525
const IPHDR *ip = (IPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER));
1526
const UDPHDR *udp = (UDPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER) + sizeof (IPHDR));
1529
if (l_PacketLength == sizeof (ARP_PACKET)
1530
&& eth->proto == htons (ETH_P_ARP)
1531
&& l_Adapter->m_dhcp_server_arp)
1533
if (ProcessARP (l_Adapter,
1534
(PARP_PACKET) l_PacketBuffer->m_Data,
1535
l_Adapter->m_dhcp_addr,
1536
l_Adapter->m_dhcp_server_ip,
1538
l_Adapter->m_dhcp_server_mac))
1543
else if (l_PacketLength >= sizeof (ETH_HEADER) + sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP)
1544
&& eth->proto == htons (ETH_P_IP)
1545
&& ip->version_len == 0x45 // IPv4, 20 byte header
1546
&& ip->protocol == IPPROTO_UDP
1547
&& udp->dest == htons (BOOTPS_PORT))
1549
const DHCP *dhcp = (DHCP *) (l_PacketBuffer->m_Data
1550
+ sizeof (ETH_HEADER)
1554
const int optlen = l_PacketLength
1555
- sizeof (ETH_HEADER)
1560
if (optlen > 0) // we must have at least one DHCP option
1562
if (ProcessDHCP (l_Adapter, eth, ip, udp, dhcp, optlen))
1570
//===============================================
1571
// In Point-To-Point mode, check to see whether
1572
// packet is ARP or IPv4 (if neither, then drop).
1573
//===============================================
1574
if (l_Adapter->m_tun)
1578
if (l_PacketLength < ETHERNET_HEADER_SIZE)
1581
e = (ETH_HEADER *) l_PacketBuffer->m_Data;
1583
switch (ntohs (e->proto))
1587
// Make sure that packet is the
1588
// right size for ARP.
1589
if (l_PacketLength != sizeof (ARP_PACKET))
1592
ProcessARP (l_Adapter,
1593
(PARP_PACKET) l_PacketBuffer->m_Data,
1594
l_Adapter->m_localIP,
1595
l_Adapter->m_remoteNetwork,
1596
l_Adapter->m_remoteNetmask,
1597
l_Adapter->m_TapToUser.dest);
1604
// Make sure that packet is large
1605
// enough to be IPv4.
1607
< ETHERNET_HEADER_SIZE + IP_HEADER_SIZE)
1610
// Only accept directed packets,
1612
if (memcmp (e, &l_Adapter->m_TapToUser, ETHERNET_HEADER_SIZE))
1615
// Packet looks like IPv4, queue it.
1616
l_PacketBuffer->m_SizeFlags |= TP_TUN;
1620
//===============================================
1621
// Push packet onto queue to wait for read from
1623
//===============================================
1625
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1628
if (IS_UP (l_Adapter))
1629
result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer);
1631
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1633
if ((TapPacketPointer) result != l_PacketBuffer)
1635
// adapter receive overrun
1636
INCREMENT_STAT (l_Adapter->m_TxErr);
1641
INCREMENT_STAT (l_Adapter->m_Tx);
1644
//============================================================
1645
// Cycle through IRPs and packets, try to satisfy each pending
1646
// IRP with a queued packet.
1647
//============================================================
1651
l_PacketBuffer = NULL;
1653
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1655
if (IS_UP (l_Adapter)
1656
&& QueueCount (l_Adapter->m_Extension.m_PacketQueue)
1657
&& QueueCount (l_Adapter->m_Extension.m_IrpQueue))
1659
l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue);
1660
l_PacketBuffer = (TapPacketPointer)
1661
QueuePop (l_Adapter->m_Extension.m_PacketQueue);
1664
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1666
MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1);
1668
if (l_IRP && l_PacketBuffer)
1672
IO_NETWORK_INCREMENT);
1678
__except (EXCEPTION_EXECUTE_HANDLER)
1682
return NDIS_STATUS_SUCCESS;
1685
NdisFreeMemory (l_PacketBuffer,
1686
TAP_PACKET_SIZE (l_PacketLength),
1690
return NDIS_STATUS_SUCCESS;
1693
return NDIS_STATUS_FAILURE;
1696
return NDIS_STATUS_RESOURCES;
1699
//======================================================================
1700
// Hooks for catching TAP device IRP's.
1701
//======================================================================
1704
TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
1706
TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
1707
PIO_STACK_LOCATION l_IrpSp;
1708
NTSTATUS l_Status = STATUS_SUCCESS;
1711
l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP);
1713
p_IRP->IoStatus.Status = STATUS_SUCCESS;
1714
p_IRP->IoStatus.Information = 0;
1716
if (!l_Adapter || l_Adapter->m_Extension.m_Halt)
1718
DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n",
1719
(int)l_IrpSp->MajorFunction));
1721
if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE)
1723
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1724
return STATUS_SUCCESS;
1728
p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
1729
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1730
return STATUS_NO_SUCH_DEVICE;
1734
switch (l_IrpSp->MajorFunction)
1736
//===========================================================
1737
// Ioctl call handlers
1738
//===========================================================
1739
case IRP_MJ_DEVICE_CONTROL:
1741
switch (l_IrpSp->Parameters.DeviceIoControl.IoControlCode)
1743
case TAP_IOCTL_GET_MAC:
1745
if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
1746
>= sizeof (MACADDR))
1748
COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer,
1750
p_IRP->IoStatus.Information = sizeof (MACADDR);
1755
p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1759
case TAP_IOCTL_GET_VERSION:
1761
const ULONG size = sizeof (ULONG) * 3;
1762
if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
1765
((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]
1766
= TAP_DRIVER_MAJOR_VERSION;
1767
((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1]
1768
= TAP_DRIVER_MINOR_VERSION;
1769
((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2]
1775
p_IRP->IoStatus.Information = size;
1780
p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1785
case TAP_IOCTL_GET_MTU:
1787
const ULONG size = sizeof (ULONG) * 1;
1788
if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
1791
((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]
1793
p_IRP->IoStatus.Information = size;
1798
p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1803
case TAP_IOCTL_GET_INFO:
1806
if (l_Adapter->m_InterfaceIsRunning)
1810
if (l_Adapter->m_Extension.m_TapIsRunning)
1814
state[2] = l_Adapter->m_DeviceState;
1815
if (l_Adapter->m_MediaStateAlwaysConnected)
1821
p_IRP->IoStatus.Status = l_Status = RtlStringCchPrintfExA (
1822
((LPTSTR) (p_IRP->AssociatedIrp.SystemBuffer)),
1823
l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
1826
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
1827
#if PACKET_TRUNCATION_CHECK
1828
"State=%s Err=[%s/%d] #O=%d Tx=[%d,%d,%d] Rx=[%d,%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]",
1830
"State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]",
1833
g_LastErrorFilename,
1834
g_LastErrorLineNumber,
1835
(int)l_Adapter->m_Extension.m_NumTapOpens,
1836
(int)l_Adapter->m_Tx,
1837
(int)l_Adapter->m_TxErr,
1838
#if PACKET_TRUNCATION_CHECK
1839
(int)l_Adapter->m_TxTrunc,
1841
(int)l_Adapter->m_Rx,
1842
(int)l_Adapter->m_RxErr,
1843
#if PACKET_TRUNCATION_CHECK
1844
(int)l_Adapter->m_RxTrunc,
1846
(int)l_Adapter->m_Extension.m_IrpQueue->size,
1847
(int)l_Adapter->m_Extension.m_IrpQueue->max_size,
1848
(int)IRP_QUEUE_SIZE,
1849
(int)l_Adapter->m_Extension.m_PacketQueue->size,
1850
(int)l_Adapter->m_Extension.m_PacketQueue->max_size,
1851
(int)PACKET_QUEUE_SIZE,
1852
(int)l_Adapter->m_Extension.m_InjectQueue->size,
1853
(int)l_Adapter->m_Extension.m_InjectQueue->max_size,
1854
(int)INJECT_QUEUE_SIZE
1857
p_IRP->IoStatus.Information
1858
= l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
1864
case TAP_IOCTL_GET_LOG_LINE:
1866
if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer,
1867
l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength))
1868
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
1870
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
1872
p_IRP->IoStatus.Information
1873
= l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
1879
case TAP_IOCTL_CONFIG_TUN:
1881
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
1882
(sizeof (IPADDR) * 3))
1886
l_Adapter->m_tun = FALSE;
1888
GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);
1890
l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
1891
l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
1892
l_Adapter->m_remoteNetmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2];
1894
// sanity check on network/netmask
1895
if ((l_Adapter->m_remoteNetwork & l_Adapter->m_remoteNetmask) != l_Adapter->m_remoteNetwork)
1898
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1902
COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC);
1903
COPY_MAC (l_Adapter->m_TapToUser.dest, dest);
1904
COPY_MAC (l_Adapter->m_UserToTap.src, dest);
1905
COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC);
1907
l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);
1909
l_Adapter->m_tun = TRUE;
1911
CheckIfDhcpAndTunMode (l_Adapter);
1913
p_IRP->IoStatus.Information = 1; // Simple boolean value
1918
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1924
case TAP_IOCTL_CONFIG_POINT_TO_POINT: // Obsoleted by TAP_IOCTL_CONFIG_TUN
1926
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
1927
(sizeof (IPADDR) * 2))
1931
l_Adapter->m_tun = FALSE;
1933
GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);
1935
l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
1936
l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
1937
l_Adapter->m_remoteNetmask = ~0;
1939
COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC);
1940
COPY_MAC (l_Adapter->m_TapToUser.dest, dest);
1941
COPY_MAC (l_Adapter->m_UserToTap.src, dest);
1942
COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC);
1944
l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);
1946
l_Adapter->m_tun = TRUE;
1948
CheckIfDhcpAndTunMode (l_Adapter);
1950
p_IRP->IoStatus.Information = 1; // Simple boolean value
1955
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1961
case TAP_IOCTL_SET_MEDIA_STATUS:
1963
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
1964
(sizeof (ULONG) * 1))
1966
ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0];
1967
SetMediaStatus (l_Adapter, (BOOLEAN) parm);
1968
p_IRP->IoStatus.Information = 1;
1973
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1978
case TAP_IOCTL_CONFIG_DHCP_MASQ:
1980
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
1981
(sizeof (IPADDR) * 4))
1983
l_Adapter->m_dhcp_enabled = FALSE;
1984
l_Adapter->m_dhcp_server_arp = FALSE;
1985
l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
1987
// Adapter IP addr / netmask
1988
l_Adapter->m_dhcp_addr =
1989
((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
1990
l_Adapter->m_dhcp_netmask =
1991
((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
1993
// IP addr of DHCP masq server
1994
l_Adapter->m_dhcp_server_ip =
1995
((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2];
1997
// Lease time in seconds
1998
l_Adapter->m_dhcp_lease_time =
1999
((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[3];
2001
GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2);
2003
l_Adapter->m_dhcp_enabled = TRUE;
2004
l_Adapter->m_dhcp_server_arp = TRUE;
2006
CheckIfDhcpAndTunMode (l_Adapter);
2008
p_IRP->IoStatus.Information = 1; // Simple boolean value
2013
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2019
case TAP_IOCTL_CONFIG_DHCP_SET_OPT:
2021
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength <=
2022
DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE
2023
&& l_Adapter->m_dhcp_enabled)
2025
l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
2027
NdisMoveMemory (l_Adapter->m_dhcp_user_supplied_options_buffer,
2028
p_IRP->AssociatedIrp.SystemBuffer,
2029
l_IrpSp->Parameters.DeviceIoControl.InputBufferLength);
2031
l_Adapter->m_dhcp_user_supplied_options_buffer_len =
2032
l_IrpSp->Parameters.DeviceIoControl.InputBufferLength;
2034
p_IRP->IoStatus.Information = 1; // Simple boolean value
2039
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2048
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2053
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2057
//===========================================================
2058
// User mode thread issued a read request on the tap device
2059
// If there are packets waiting to be read, then the request
2060
// will be satisfied here. If not, then the request will be
2061
// queued and satisfied by any packet that is not used to
2062
// satisfy requests ahead of it.
2063
//===========================================================
2066
TapPacketPointer l_PacketBuffer;
2067
BOOLEAN pending = FALSE;
2069
// Save IRP-accessible copy of buffer length
2070
p_IRP->IoStatus.Information = l_IrpSp->Parameters.Read.Length;
2072
if (p_IRP->MdlAddress == NULL)
2074
DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n",
2077
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2078
p_IRP->IoStatus.Information = 0;
2079
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2082
else if ((p_IRP->AssociatedIrp.SystemBuffer =
2083
MmGetSystemAddressForMdlSafe
2084
(p_IRP->MdlAddress, NormalPagePriority)) == NULL)
2086
DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n",
2089
p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
2090
p_IRP->IoStatus.Information = 0;
2091
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2094
else if (!l_Adapter->m_InterfaceIsRunning)
2096
DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n",
2099
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2100
p_IRP->IoStatus.Information = 0;
2101
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2105
//==================================
2106
// Can we provide immediate service?
2107
//==================================
2109
l_PacketBuffer = NULL;
2111
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
2113
if (IS_UP (l_Adapter)
2114
&& QueueCount (l_Adapter->m_Extension.m_PacketQueue)
2115
&& QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0)
2117
l_PacketBuffer = (TapPacketPointer)
2118
QueuePop (l_Adapter->m_Extension.m_PacketQueue);
2121
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
2125
l_Status = CompleteIRP (p_IRP,
2131
//=============================
2132
// Attempt to pend read request
2133
//=============================
2135
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
2137
if (IS_UP (l_Adapter)
2138
&& QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP)
2140
IoSetCancelRoutine (p_IRP, CancelIRPCallback);
2141
l_Status = STATUS_PENDING;
2142
IoMarkIrpPending (p_IRP);
2146
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
2151
// Can't queue anymore IRP's
2152
DEBUGP (("[%s] TAP [%s] read IRP overrun\n",
2153
NAME (l_Adapter), l_Adapter->m_Extension.m_TapName));
2155
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2156
p_IRP->IoStatus.Information = 0;
2157
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2161
//==============================================================
2162
// User mode issued a WriteFile request on the TAP file handle.
2163
// The request will always get satisfied here. The call may
2164
// fail if there are too many pending packets (queue full).
2165
//==============================================================
2168
if (p_IRP->MdlAddress == NULL)
2170
DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n",
2173
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2174
p_IRP->IoStatus.Information = 0;
2176
else if ((p_IRP->AssociatedIrp.SystemBuffer =
2177
MmGetSystemAddressForMdlSafe
2178
(p_IRP->MdlAddress, NormalPagePriority)) == NULL)
2180
DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n",
2183
p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
2184
p_IRP->IoStatus.Information = 0;
2186
else if (!l_Adapter->m_InterfaceIsRunning)
2188
DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n",
2191
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2192
p_IRP->IoStatus.Information = 0;
2194
else if (!l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE))
2198
p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length;
2200
DUMP_PACKET ("IRP_MJ_WRITE ETH",
2201
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2202
l_IrpSp->Parameters.Write.Length);
2204
//=====================================================
2205
// If IPv4 packet, check whether or not packet
2207
//=====================================================
2208
#if PACKET_TRUNCATION_CHECK
2209
IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2210
l_IrpSp->Parameters.Write.Length,
2213
&l_Adapter->m_RxTrunc);
2216
NdisMEthIndicateReceive
2217
(l_Adapter->m_MiniportAdapterHandle,
2218
(NDIS_HANDLE) l_Adapter,
2219
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2220
ETHERNET_HEADER_SIZE,
2221
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer + ETHERNET_HEADER_SIZE,
2222
l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE,
2223
l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE);
2225
NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle);
2227
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2229
__except (EXCEPTION_EXECUTE_HANDLER)
2231
DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n",
2234
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2235
p_IRP->IoStatus.Information = 0;
2238
else if (l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE))
2242
p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length;
2244
DUMP_PACKET2 ("IRP_MJ_WRITE P2P",
2245
&l_Adapter->m_UserToTap,
2246
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2247
l_IrpSp->Parameters.Write.Length);
2249
//=====================================================
2250
// If IPv4 packet, check whether or not packet
2252
//=====================================================
2253
#if PACKET_TRUNCATION_CHECK
2254
IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2255
l_IrpSp->Parameters.Write.Length,
2258
&l_Adapter->m_RxTrunc);
2261
NdisMEthIndicateReceive
2262
(l_Adapter->m_MiniportAdapterHandle,
2263
(NDIS_HANDLE) l_Adapter,
2264
(unsigned char *) &l_Adapter->m_UserToTap,
2265
sizeof (l_Adapter->m_UserToTap),
2266
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2267
l_IrpSp->Parameters.Write.Length,
2268
l_IrpSp->Parameters.Write.Length);
2270
NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle);
2272
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2274
__except (EXCEPTION_EXECUTE_HANDLER)
2276
DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n",
2279
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2280
p_IRP->IoStatus.Information = 0;
2285
DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",
2287
l_IrpSp->Parameters.Write.Length));
2289
p_IRP->IoStatus.Information = 0; // ETHERNET_HEADER_SIZE;
2290
p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
2293
if (l_Status == STATUS_SUCCESS)
2294
INCREMENT_STAT (l_Adapter->m_Rx);
2296
INCREMENT_STAT (l_Adapter->m_RxErr);
2298
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2302
//--------------------------------------------------------------
2303
// User mode thread has called CreateFile() on the tap device
2304
//--------------------------------------------------------------
2307
BOOLEAN succeeded = FALSE;
2308
BOOLEAN mutex_succeeded;
2311
(("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
2312
NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
2313
TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens));
2315
ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
2316
if (mutex_succeeded)
2318
if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens)
2320
ResetTapAdapterState (l_Adapter);
2321
l_Adapter->m_Extension.m_TapOpens = 1;
2327
INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens);
2328
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2329
p_IRP->IoStatus.Information = 0;
2333
DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
2334
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2336
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2337
p_IRP->IoStatus.Information = 0;
2340
RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
2344
DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
2345
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2347
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2348
p_IRP->IoStatus.Information = 0;
2351
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2355
//-----------------------------------------------------------
2356
// User mode thread called CloseHandle() on the tap device
2357
//-----------------------------------------------------------
2360
BOOLEAN mutex_succeeded;
2362
DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n",
2363
NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
2364
TAP_DRIVER_MINOR_VERSION));
2366
ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
2367
if (mutex_succeeded)
2369
l_Adapter->m_Extension.m_TapOpens = 0;
2370
ResetTapAdapterState (l_Adapter);
2371
FlushQueues (&l_Adapter->m_Extension);
2372
SetMediaStatus (l_Adapter, FALSE);
2373
RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
2377
DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
2378
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2380
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2381
p_IRP->IoStatus.Information = 0;
2384
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2388
//------------------
2390
//------------------
2394
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2395
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2403
//=============================================================
2404
// CompleteIRP is normally called with an adapter -> userspace
2405
// network packet and an IRP (Pending I/O request) from userspace.
2407
// The IRP will normally represent a queued overlapped read
2408
// operation from userspace that is in a wait state.
2410
// Use the ethernet packet to satisfy the IRP.
2411
//=============================================================
2414
CompleteIRP (IN PIRP p_IRP,
2415
IN TapPacketPointer p_PacketBuffer,
2416
IN CCHAR PriorityBoost)
2418
NTSTATUS l_Status = STATUS_UNSUCCESSFUL;
2424
MYASSERT (p_PacketBuffer);
2426
IoSetCancelRoutine (p_IRP, NULL); // Disable cancel routine
2428
//-------------------------------------------
2429
// While p_PacketBuffer always contains a
2430
// full ethernet packet, including the
2431
// ethernet header, in point-to-point mode,
2432
// we only want to return the IPv4
2434
//-------------------------------------------
2436
if (p_PacketBuffer->m_SizeFlags & TP_TUN)
2438
offset = ETHERNET_HEADER_SIZE;
2439
len = (int) (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE;
2444
len = (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK);
2447
if (len < 0 || (int) p_IRP->IoStatus.Information < len)
2449
p_IRP->IoStatus.Information = 0;
2450
p_IRP->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
2455
p_IRP->IoStatus.Information = len;
2456
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2460
NdisMoveMemory (p_IRP->AssociatedIrp.SystemBuffer,
2461
p_PacketBuffer->m_Data + offset,
2464
__except (EXCEPTION_EXECUTE_HANDLER)
2467
p_IRP->IoStatus.Status = STATUS_UNSUCCESSFUL;
2468
p_IRP->IoStatus.Information = 0;
2474
NdisFreeMemory (p_PacketBuffer,
2475
TAP_PACKET_SIZE (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK),
2478
__except (EXCEPTION_EXECUTE_HANDLER)
2482
if (l_Status == STATUS_SUCCESS)
2484
IoCompleteRequest (p_IRP, PriorityBoost);
2487
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2492
//==============================================
2493
// IRPs get cancelled for a number of reasons.
2495
// The TAP device could be closed by userspace
2496
// when there are still pending read operations.
2498
// The user could disable the TAP adapter in the
2499
// network connections control panel, while the
2500
// device is still open by a process.
2501
//==============================================
2503
CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject,
2506
TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
2507
CancelIRP (l_Adapter ? &l_Adapter->m_Extension : NULL, p_IRP, TRUE);
2511
CancelIRP (TapExtensionPointer p_Extension,
2515
BOOLEAN exists = FALSE;
2521
NdisAcquireSpinLock (&p_Extension->m_QueueLock);
2522
exists = (QueueExtract (p_Extension->m_IrpQueue, p_IRP) == p_IRP);
2523
NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2530
IoSetCancelRoutine (p_IRP, NULL);
2531
p_IRP->IoStatus.Status = STATUS_CANCELLED;
2532
p_IRP->IoStatus.Information = 0;
2536
IoReleaseCancelSpinLock (p_IRP->CancelIrql);
2539
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2542
//===========================================
2543
// Exhaust packet, IRP, and injection queues.
2544
//===========================================
2546
FlushQueues (TapExtensionPointer p_Extension)
2549
TapPacketPointer l_PacketBuffer;
2550
InjectPacketPointer l_InjectBuffer;
2551
int n_IRP=0, n_Packet=0, n_Inject=0;
2553
MYASSERT (p_Extension);
2554
MYASSERT (p_Extension->m_TapDevice);
2558
NdisAcquireSpinLock (&p_Extension->m_QueueLock);
2559
l_IRP = QueuePop (p_Extension->m_IrpQueue);
2560
NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2564
CancelIRP (NULL, l_IRP, FALSE);
2572
NdisAcquireSpinLock (&p_Extension->m_QueueLock);
2573
l_PacketBuffer = QueuePop (p_Extension->m_PacketQueue);
2574
NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2578
MemFree (l_PacketBuffer, TAP_PACKET_SIZE (l_PacketBuffer->m_SizeFlags & TP_SIZE_MASK));
2586
NdisAcquireSpinLock (&p_Extension->m_InjectLock);
2587
l_InjectBuffer = QueuePop (p_Extension->m_InjectQueue);
2588
NdisReleaseSpinLock (&p_Extension->m_InjectLock);
2592
INJECT_PACKET_FREE(l_InjectBuffer);
2599
"[%s] [TAP] FlushQueues n_IRP=[%d,%d,%d] n_Packet=[%d,%d,%d] n_Inject=[%d,%d,%d]\n",
2600
p_Extension->m_TapName,
2602
p_Extension->m_IrpQueue->max_size,
2605
p_Extension->m_PacketQueue->max_size,
2608
p_Extension->m_InjectQueue->max_size,
2613
//===================================================
2614
// Tell Windows whether the TAP device should be
2615
// considered "connected" or "disconnected".
2616
//===================================================
2618
SetMediaStatus (TapAdapterPointer p_Adapter, BOOLEAN state)
2620
if (p_Adapter->m_MediaState != state && !p_Adapter->m_MediaStateAlwaysConnected)
2623
NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle,
2624
NDIS_STATUS_MEDIA_CONNECT, NULL, 0);
2626
NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle,
2627
NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0);
2629
NdisMIndicateStatusComplete (p_Adapter->m_MiniportAdapterHandle);
2630
p_Adapter->m_MediaState = state;
2635
//======================================================
2636
// If DHCP mode is used together with tun
2637
// mode, consider the fact that the P2P remote subnet
2638
// might enclose the DHCP masq server address.
2639
//======================================================
2641
CheckIfDhcpAndTunMode (TapAdapterPointer p_Adapter)
2643
if (p_Adapter->m_tun && p_Adapter->m_dhcp_enabled)
2645
if ((p_Adapter->m_dhcp_server_ip & p_Adapter->m_remoteNetmask) == p_Adapter->m_remoteNetwork)
2647
COPY_MAC (p_Adapter->m_dhcp_server_mac, p_Adapter->m_TapToUser.dest);
2648
p_Adapter->m_dhcp_server_arp = FALSE;
2653
//===================================================
2654
// Generate an ARP reply message for specific kinds
2656
//===================================================
2658
ProcessARP (TapAdapterPointer p_Adapter,
2659
const PARP_PACKET src,
2660
const IPADDR adapter_ip,
2661
const IPADDR ip_network,
2662
const IPADDR ip_netmask,
2665
//-----------------------------------------------
2666
// Is this the kind of packet we are looking for?
2667
//-----------------------------------------------
2668
if (src->m_Proto == htons (ETH_P_ARP)
2669
&& MAC_EQUAL (src->m_MAC_Source, p_Adapter->m_MAC)
2670
&& MAC_EQUAL (src->m_ARP_MAC_Source, p_Adapter->m_MAC)
2671
&& MAC_EQUAL (src->m_MAC_Destination, p_Adapter->m_MAC_Broadcast)
2672
&& src->m_ARP_Operation == htons (ARP_REQUEST)
2673
&& src->m_MAC_AddressType == htons (MAC_ADDR_TYPE)
2674
&& src->m_MAC_AddressSize == sizeof (MACADDR)
2675
&& src->m_PROTO_AddressType == htons (ETH_P_IP)
2676
&& src->m_PROTO_AddressSize == sizeof (IPADDR)
2677
&& src->m_ARP_IP_Source == adapter_ip
2678
&& (src->m_ARP_IP_Destination & ip_netmask) == ip_network
2679
&& src->m_ARP_IP_Destination != adapter_ip)
2681
ARP_PACKET *arp = (ARP_PACKET *) MemAlloc (sizeof (ARP_PACKET), TRUE);
2684
//----------------------------------------------
2685
// Initialize ARP reply fields
2686
//----------------------------------------------
2687
arp->m_Proto = htons (ETH_P_ARP);
2688
arp->m_MAC_AddressType = htons (MAC_ADDR_TYPE);
2689
arp->m_PROTO_AddressType = htons (ETH_P_IP);
2690
arp->m_MAC_AddressSize = sizeof (MACADDR);
2691
arp->m_PROTO_AddressSize = sizeof (IPADDR);
2692
arp->m_ARP_Operation = htons (ARP_REPLY);
2694
//----------------------------------------------
2696
//----------------------------------------------
2697
COPY_MAC (arp->m_MAC_Source, mac);
2698
COPY_MAC (arp->m_MAC_Destination, p_Adapter->m_MAC);
2699
COPY_MAC (arp->m_ARP_MAC_Source, mac);
2700
COPY_MAC (arp->m_ARP_MAC_Destination, p_Adapter->m_MAC);
2701
arp->m_ARP_IP_Source = src->m_ARP_IP_Destination;
2702
arp->m_ARP_IP_Destination = adapter_ip;
2704
DUMP_PACKET ("ProcessARP",
2705
(unsigned char *) arp,
2706
sizeof (ARP_PACKET));
2708
InjectPacketDeferred (p_Adapter, (UCHAR *) arp, sizeof (ARP_PACKET));
2710
MemFree (arp, sizeof (ARP_PACKET));
2719
//===============================================================
2720
// Used in cases where internally generated packets such as
2721
// ARP or DHCP replies must be returned to the kernel, to be
2722
// seen as an incoming packet "arriving" on the interface.
2723
//===============================================================
2725
// Defer packet injection till IRQL < DISPATCH_LEVEL
2727
InjectPacketDeferred (TapAdapterPointer p_Adapter,
2729
const unsigned int len)
2731
InjectPacketPointer l_InjectBuffer;
2734
if (NdisAllocateMemoryWithTag (&l_InjectBuffer,
2735
INJECT_PACKET_SIZE (len),
2736
'IPAT') == NDIS_STATUS_SUCCESS)
2738
l_InjectBuffer->m_Size = len;
2739
NdisMoveMemory (l_InjectBuffer->m_Data, packet, len);
2740
NdisAcquireSpinLock (&p_Adapter->m_Extension.m_InjectLock);
2741
result = QueuePush (p_Adapter->m_Extension.m_InjectQueue, l_InjectBuffer);
2742
NdisReleaseSpinLock (&p_Adapter->m_Extension.m_InjectLock);
2744
KeInsertQueueDpc (&p_Adapter->m_Extension.m_InjectDpc, p_Adapter, NULL);
2746
INJECT_PACKET_FREE(l_InjectBuffer);
2750
// Handle the injection of previously deferred packets
2752
InjectPacketDpc(KDPC *Dpc,
2753
PVOID DeferredContext,
2754
PVOID SystemArgument1,
2755
PVOID SystemArgument2)
2757
InjectPacketPointer l_InjectBuffer;
2758
TapAdapterPointer l_Adapter = (TapAdapterPointer)SystemArgument1;
2761
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_InjectLock);
2762
l_InjectBuffer = QueuePop (l_Adapter->m_Extension.m_InjectQueue);
2763
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_InjectLock);
2766
InjectPacketNow(l_Adapter, l_InjectBuffer->m_Data, l_InjectBuffer->m_Size);
2767
INJECT_PACKET_FREE(l_InjectBuffer);
2774
// Do packet injection now
2776
InjectPacketNow (TapAdapterPointer p_Adapter,
2778
const unsigned int len)
2780
MYASSERT (len >= ETHERNET_HEADER_SIZE);
2784
//------------------------------------------------------------
2785
// NdisMEthIndicateReceive and NdisMEthIndicateReceiveComplete
2786
// could potentially be called reentrantly both here and in
2787
// TapDeviceHook/IRP_MJ_WRITE.
2789
// The DDK docs imply that this is okay.
2791
// Note that reentrant behavior could only occur if the
2792
// non-deferred version of InjectPacket is used.
2793
//------------------------------------------------------------
2794
NdisMEthIndicateReceive
2795
(p_Adapter->m_MiniportAdapterHandle,
2796
(NDIS_HANDLE) p_Adapter,
2798
ETHERNET_HEADER_SIZE,
2799
packet + ETHERNET_HEADER_SIZE,
2800
len - ETHERNET_HEADER_SIZE,
2801
len - ETHERNET_HEADER_SIZE);
2803
NdisMEthIndicateReceiveComplete (p_Adapter->m_MiniportAdapterHandle);
2805
__except (EXCEPTION_EXECUTE_HANDLER)
2807
DEBUGP (("[%s] NdisMEthIndicateReceive failed in InjectPacketNow\n",
2813
//===================================================================
2814
// Go back to default TAP mode from Point-To-Point mode.
2815
// Also reset (i.e. disable) DHCP Masq mode.
2816
//===================================================================
2817
VOID ResetTapAdapterState (TapAdapterPointer p_Adapter)
2820
p_Adapter->m_tun = FALSE;
2821
p_Adapter->m_localIP = 0;
2822
p_Adapter->m_remoteNetwork = 0;
2823
p_Adapter->m_remoteNetmask = 0;
2824
NdisZeroMemory (&p_Adapter->m_TapToUser, sizeof (p_Adapter->m_TapToUser));
2825
NdisZeroMemory (&p_Adapter->m_UserToTap, sizeof (p_Adapter->m_UserToTap));
2828
p_Adapter->m_dhcp_enabled = FALSE;
2829
p_Adapter->m_dhcp_server_arp = FALSE;
2830
p_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
2831
p_Adapter->m_dhcp_addr = 0;
2832
p_Adapter->m_dhcp_netmask = 0;
2833
p_Adapter->m_dhcp_server_ip = 0;
2834
p_Adapter->m_dhcp_lease_time = 0;
2835
p_Adapter->m_dhcp_received_discover = FALSE;
2836
p_Adapter->m_dhcp_bad_requests = 0;
2837
NdisZeroMemory (p_Adapter->m_dhcp_server_mac, sizeof (MACADDR));
2842
//===================================================================
2843
// Set TAP device handle to be accessible without admin privileges.
2844
//===================================================================
2845
VOID AllowNonAdmin (TapExtensionPointer p_Extension)
2848
SECURITY_DESCRIPTOR sd;
2849
OBJECT_ATTRIBUTES oa;
2850
IO_STATUS_BLOCK isb;
2853
NdisZeroMemory (&sd, sizeof (sd));
2854
NdisZeroMemory (&oa, sizeof (oa));
2855
NdisZeroMemory (&isb, sizeof (isb));
2857
if (!p_Extension->m_CreatedUnicodeLinkName)
2859
DEBUGP (("[TAP] AllowNonAdmin: UnicodeLinkName is uninitialized\n"));
2864
stat = RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
2865
if (stat != STATUS_SUCCESS)
2867
DEBUGP (("[TAP] AllowNonAdmin: RtlCreateSecurityDescriptor failed\n"));
2872
InitializeObjectAttributes (
2874
&p_Extension->m_UnicodeLinkName,
2888
if (stat != STATUS_SUCCESS)
2890
DEBUGP (("[TAP] AllowNonAdmin: ZwOpenFile failed, status=0x%08x\n", (unsigned int)stat));
2895
stat = ZwSetSecurityObject (hand, DACL_SECURITY_INFORMATION, &sd);
2896
if (stat != STATUS_SUCCESS)
2898
DEBUGP (("[TAP] AllowNonAdmin: ZwSetSecurityObject failed\n"));
2903
stat = ZwClose (hand);
2904
if (stat != STATUS_SUCCESS)
2906
DEBUGP (("[TAP] AllowNonAdmin: ZwClose failed\n"));
2911
DEBUGP (("[TAP] AllowNonAdmin: SUCCEEDED\n"));
2916
#if PACKET_TRUNCATION_CHECK
2919
IPv4PacketSizeVerify (const UCHAR *data, ULONG length, BOOLEAN tun, const char *prefix, LONG *counter)
2926
ip = (IPHDR *) data;
2930
if (length >= sizeof (ETH_HEADER))
2932
const ETH_HEADER *eth = (ETH_HEADER *) data;
2934
if (eth->proto != htons (ETH_P_IP))
2937
ip = (IPHDR *) (data + sizeof (ETH_HEADER));
2938
len -= sizeof (ETH_HEADER);
2944
if (len >= sizeof (IPHDR))
2946
const int totlen = ntohs (ip->tot_len);
2948
DEBUGP (("[TAP] IPv4PacketSizeVerify %s len=%d totlen=%d\n", prefix, len, totlen));
2957
//======================================================================
2959
//======================================================================