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-2010 OpenVPN Technologies, Inc.,
8
* and is released under the GPL version 2 (see below).
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License version 2
12
* as published by the Free Software Foundation.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program (see the file COPYING included with this
21
* distribution); if not, write to the Free Software Foundation, Inc.,
22
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
//======================================================
26
// This driver is designed to work on Win 2000 or higher
27
// versions of Windows.
29
// It is SMP-safe and handles NDIS 5 power management.
31
// By default we operate as a "tap" virtual ethernet
32
// 802.3 interface, but we can emulate a "tun"
33
// interface (point-to-point IPv4) through the
34
// TAP_IOCTL_CONFIG_POINT_TO_POINT or
35
// TAP_IOCTL_CONFIG_TUN ioctl.
36
//======================================================
40
#error DDKVER_MAJOR must be defined as the major number of the DDK Version
43
#define NDIS_MINIPORT_DRIVER
44
#define BINARY_COMPATIBLE 0
45
#define NDIS50_MINIPORT 1
51
#define ALSO_DBGPRINT 1
52
#define DEBUGP_AT_DISPATCH 0
54
//========================================================
55
// Check for truncated IPv4 packets, log errors if found.
56
//========================================================
57
#define PACKET_TRUNCATION_CHECK 0
59
//========================================================
60
// EXPERIMENTAL -- Configure TAP device object to be
61
// accessible from non-administrative accounts, based
62
// on an advanced properties setting.
64
// Duplicates the functionality of OpenVPN's
65
// --allow-nonadmin directive.
66
//========================================================
67
#define ENABLE_NONADMIN 1
69
#if DDKVER_MAJOR < 5600
71
#include <ntstrsafe.h>
76
#include <ntstrsafe.h>
80
#include "constants.h"
86
#include "prototypes.h"
95
((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning)
97
#define INCREMENT_STAT(s) ++(s)
99
#define NAME_BUFFER_SIZE 80
101
//========================================================
103
//========================================================
105
NDIS_HANDLE g_NdisWrapperHandle;
107
const UINT g_SupportedOIDList[] = {
108
OID_GEN_HARDWARE_STATUS,
109
OID_GEN_MEDIA_SUPPORTED,
110
OID_GEN_MEDIA_IN_USE,
111
OID_GEN_MAXIMUM_LOOKAHEAD,
114
OID_GEN_TRANSMIT_BLOCK_SIZE,
115
OID_GEN_RECEIVE_BLOCK_SIZE,
116
OID_GEN_VENDOR_DESCRIPTION,
117
OID_GEN_DRIVER_VERSION,
122
OID_802_3_PERMANENT_ADDRESS,
123
OID_802_3_CURRENT_ADDRESS,
124
OID_GEN_RCV_NO_BUFFER,
125
OID_802_3_RCV_ERROR_ALIGNMENT,
126
OID_802_3_XMIT_ONE_COLLISION,
127
OID_802_3_XMIT_MORE_COLLISIONS,
128
OID_802_3_MULTICAST_LIST,
129
OID_802_3_MAXIMUM_LIST_SIZE,
131
OID_GEN_CURRENT_LOOKAHEAD,
132
OID_GEN_CURRENT_PACKET_FILTER,
133
OID_GEN_PROTOCOL_OPTIONS,
134
OID_GEN_MAXIMUM_TOTAL_SIZE,
135
OID_GEN_TRANSMIT_BUFFER_SPACE,
136
OID_GEN_RECEIVE_BUFFER_SPACE,
137
OID_GEN_MAXIMUM_FRAME_SIZE,
138
OID_GEN_VENDOR_DRIVER_VERSION,
139
OID_GEN_MAXIMUM_SEND_PACKETS,
140
OID_GEN_MEDIA_CONNECT_STATUS,
141
OID_GEN_SUPPORTED_LIST
144
//============================================================
146
//============================================================
147
#pragma NDIS_INIT_FUNCTION (DriverEntry)
150
DriverEntry (IN PDRIVER_OBJECT p_DriverObject,
151
IN PUNICODE_STRING p_RegistryPath)
153
NDIS_STATUS l_Status = NDIS_STATUS_FAILURE;
154
NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL;
156
//========================================================
157
// Notify NDIS that a new miniport driver is initializing.
158
//========================================================
160
NdisMInitializeWrapper (&g_NdisWrapperHandle,
162
p_RegistryPath, NULL);
164
//======================
165
// Global initialization
166
//======================
169
MyDebugInit (10000); // Allocate debugging text space
172
if (!InitInstanceList ())
174
DEBUGP (("[TAP] Allocation failed for adapter instance list\n"));
178
//=======================================
179
// Set and register miniport entry points
180
//=======================================
182
l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE);
184
if (l_Properties == NULL)
186
DEBUGP (("[TAP] Allocation failed for miniport entry points\n"));
190
l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
191
l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
192
l_Properties->InitializeHandler = AdapterCreate;
193
l_Properties->HaltHandler = AdapterHalt;
194
l_Properties->ResetHandler = AdapterReset; /* DISPATCH_LEVEL */
195
l_Properties->TransferDataHandler = AdapterReceive; /* DISPATCH_LEVEL */
196
l_Properties->SendHandler = AdapterTransmit; /* DISPATCH_LEVEL */
197
l_Properties->QueryInformationHandler = AdapterQuery; /* DISPATCH_LEVEL */
198
l_Properties->SetInformationHandler = AdapterModify; /* DISPATCH_LEVEL */
201
NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties,
202
sizeof (NDIS_MINIPORT_CHARACTERISTICS)))
204
case NDIS_STATUS_SUCCESS:
206
DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n",
207
TAP_DRIVER_MAJOR_VERSION,
208
TAP_DRIVER_MINOR_VERSION,
211
DEBUGP (("Registry Path: '%.*S'\n", p_RegistryPath->Length/2, p_RegistryPath->Buffer));
215
case NDIS_STATUS_BAD_CHARACTERISTICS:
217
DEBUGP (("[TAP] Miniport characteristics were badly defined\n"));
218
NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
222
case NDIS_STATUS_BAD_VERSION:
225
(("[TAP] NDIS Version is wrong for the given characteristics\n"));
226
NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
230
case NDIS_STATUS_RESOURCES:
232
DEBUGP (("[TAP] Insufficient resources\n"));
233
NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
238
case NDIS_STATUS_FAILURE:
240
DEBUGP (("[TAP] Unknown fatal registration error\n"));
241
NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
248
MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS));
250
if (l_Status == NDIS_STATUS_SUCCESS)
251
NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload);
253
TapDriverUnload (p_DriverObject);
258
//============================================================
260
//============================================================
262
TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject)
264
DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n",
265
TAP_DRIVER_MAJOR_VERSION,
266
TAP_DRIVER_MINOR_VERSION,
270
InstanceMaxBucketSize()));
274
//==============================
275
// Free debugging text space
276
//==============================
282
//==========================================================
283
// Adapter Initialization
284
//==========================================================
285
NDIS_STATUS AdapterCreate
286
(OUT PNDIS_STATUS p_ErrorStatus,
287
OUT PUINT p_MediaIndex,
288
IN PNDIS_MEDIUM p_Media,
289
IN UINT p_MediaCount,
290
IN NDIS_HANDLE p_AdapterHandle,
291
IN NDIS_HANDLE p_ConfigurationHandle)
293
TapAdapterPointer l_Adapter = NULL;
295
NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet
296
BOOLEAN l_MacFromRegistry = FALSE;
301
BOOLEAN enable_non_admin = FALSE;
304
DEBUGP (("[TAP] AdapterCreate called\n"));
306
//====================================
307
// Make sure adapter type is supported
308
//====================================
311
l_Index < p_MediaCount && p_Media[l_Index] != l_PreferredMedium;
314
if (l_Index == p_MediaCount)
316
DEBUGP (("[TAP] Unsupported adapter type [wanted: %d]\n",
318
return NDIS_STATUS_UNSUPPORTED_MEDIA;
321
*p_MediaIndex = l_Index;
323
//=========================================
324
// Allocate memory for TapAdapter structure
325
//=========================================
327
l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE);
329
if (l_Adapter == NULL)
331
DEBUGP (("[TAP] Couldn't allocate adapter memory\n"));
332
return NDIS_STATUS_RESOURCES;
335
//==========================================
336
// Inform the NDIS library about significant
337
// features of our virtual NIC.
338
//==========================================
342
(NDIS_HANDLE) l_Adapter,
344
NDIS_ATTRIBUTE_DESERIALIZE
345
| NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT
346
| NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT
347
| NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
348
NdisInterfaceInternal);
350
//=====================================
351
// Initialize simple Adapter parameters
352
//=====================================
354
l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD;
355
l_Adapter->m_Medium = l_PreferredMedium;
356
l_Adapter->m_DeviceState = '?';
357
l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle;
359
//==================================
360
// Allocate spinlock for controlling
361
// access to multicast address list.
362
//==================================
363
NdisAllocateSpinLock (&l_Adapter->m_MCLock);
364
l_Adapter->m_MCLockAllocated = TRUE;
366
//====================================================
367
// Register a shutdown handler which will be called
368
// on system restart/shutdown to halt our virtual NIC.
369
//====================================================
371
NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter,
373
l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE;
375
//============================================
376
// Get parameters from registry which were set
377
// in the adapter advanced properties dialog.
378
//============================================
381
NDIS_HANDLE configHandle;
382
NDIS_CONFIGURATION_PARAMETER *parm;
384
// set defaults in case our registry query fails
385
l_Adapter->m_MTU = ETHERNET_MTU;
386
l_Adapter->m_MediaStateAlwaysConnected = FALSE;
387
l_Adapter->m_MediaState = FALSE;
389
NdisOpenConfiguration (&status, &configHandle, p_ConfigurationHandle);
390
if (status != NDIS_STATUS_SUCCESS)
392
DEBUGP (("[TAP] Couldn't open adapter registry\n"));
393
AdapterFreeResources (l_Adapter);
397
//====================================
398
// Allocate and construct adapter name
399
//====================================
402
NDIS_STRING mkey = NDIS_STRING_CONST("MiniportName");
403
NDIS_STRING vkey = NDIS_STRING_CONST("NdisVersion");
405
NDIS_CONFIGURATION_PARAMETER *vparm;
407
NdisReadConfiguration (&vstatus, &vparm, configHandle, &vkey, NdisParameterInteger);
408
if (vstatus == NDIS_STATUS_SUCCESS)
409
DEBUGP (("[TAP] NdisReadConfiguration NdisVersion=%X\n", vparm->ParameterData.IntegerData));
411
NdisReadConfiguration (&status, &parm, configHandle, &mkey, NdisParameterString);
412
if (status == NDIS_STATUS_SUCCESS)
414
if (parm->ParameterType == NdisParameterString)
416
DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%.*S)\n",
417
parm->ParameterData.StringData.Length/2,
418
parm->ParameterData.StringData.Buffer));
420
if (RtlUnicodeStringToAnsiString (
421
&l_Adapter->m_NameAnsi,
422
&parm->ParameterData.StringData,
423
TRUE) != STATUS_SUCCESS)
425
DEBUGP (("[TAP] MiniportName failed\n"));
426
status = NDIS_STATUS_RESOURCES;
432
/* "MiniportName" is available only XP and above. Not on Windows 2000. */
433
if (vstatus == NDIS_STATUS_SUCCESS && vparm->ParameterData.IntegerData == 0x50000)
435
/* Fallback for Windows 2000 with NDIS version 5.00.00
436
Don't use this on Vista, 'NDIS_MINIPORT_BLOCK' was changed! */
437
if (RtlUnicodeStringToAnsiString (&l_Adapter->m_NameAnsi,
438
&((struct WIN2K_NDIS_MINIPORT_BLOCK *) p_AdapterHandle)->MiniportName,
439
TRUE) != STATUS_SUCCESS)
441
DEBUGP (("[TAP] MiniportName (W2K) failed\n"));
442
status = NDIS_STATUS_RESOURCES;
446
DEBUGP (("[TAP] MiniportName (W2K) succeeded: %s\n", l_Adapter->m_NameAnsi.Buffer));
447
status = NDIS_STATUS_SUCCESS;
453
/* Can't continue without name (see macro 'NAME') */
454
if (status != NDIS_STATUS_SUCCESS || !l_Adapter->m_NameAnsi.Buffer)
456
NdisCloseConfiguration (configHandle);
457
AdapterFreeResources (l_Adapter);
458
DEBUGP (("[TAP] failed to get miniport name\n"));
459
return NDIS_STATUS_RESOURCES;
462
/* Read MTU setting from registry */
464
NDIS_STRING key = NDIS_STRING_CONST("MTU");
465
NdisReadConfiguration (&status, &parm, configHandle,
466
&key, NdisParameterInteger);
467
if (status == NDIS_STATUS_SUCCESS)
469
if (parm->ParameterType == NdisParameterInteger)
471
int mtu = parm->ParameterData.IntegerData;
472
if (mtu < MINIMUM_MTU)
474
if (mtu > MAXIMUM_MTU)
476
l_Adapter->m_MTU = mtu;
481
/* Read Media Status setting from registry */
483
NDIS_STRING key = NDIS_STRING_CONST("MediaStatus");
484
NdisReadConfiguration (&status, &parm, configHandle,
485
&key, NdisParameterInteger);
486
if (status == NDIS_STATUS_SUCCESS)
488
if (parm->ParameterType == NdisParameterInteger)
490
if (parm->ParameterData.IntegerData)
492
l_Adapter->m_MediaStateAlwaysConnected = TRUE;
493
l_Adapter->m_MediaState = TRUE;
500
/* Read AllowNonAdmin setting from registry */
502
NDIS_STRING key = NDIS_STRING_CONST("AllowNonAdmin");
503
NdisReadConfiguration (&status, &parm, configHandle,
504
&key, NdisParameterInteger);
505
if (status == NDIS_STATUS_SUCCESS)
507
if (parm->ParameterType == NdisParameterInteger)
509
if (parm->ParameterData.IntegerData)
511
enable_non_admin = TRUE;
518
/* Read optional MAC setting from registry */
520
NDIS_STRING key = NDIS_STRING_CONST("MAC");
521
ANSI_STRING mac_string;
522
NdisReadConfiguration (&status, &parm, configHandle,
523
&key, NdisParameterString);
524
if (status == NDIS_STATUS_SUCCESS)
526
if (parm->ParameterType == NdisParameterString)
528
if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS)
530
l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer);
531
RtlFreeAnsiString (&mac_string);
537
NdisCloseConfiguration (configHandle);
539
DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU));
542
//==================================
543
// Store and update MAC address info
544
//==================================
546
if (!l_MacFromRegistry)
547
GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter));
549
DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",
551
l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],
552
l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));
559
for (i = 0; i < sizeof (MACADDR); ++i)
560
l_Adapter->m_MAC_Broadcast[i] = 0xFF;
563
//====================================
564
// Initialize TAP device
565
//====================================
567
NDIS_STATUS tap_status;
568
tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter));
569
if (tap_status != NDIS_STATUS_SUCCESS)
571
AdapterFreeResources (l_Adapter);
572
DEBUGP (("[TAP] CreateTapDevice failed\n"));
577
if (!AddAdapterToInstanceList (l_Adapter))
580
TapDeviceFreeResources (&l_Adapter->m_Extension);
581
AdapterFreeResources (l_Adapter);
582
DEBUGP (("[TAP] AddAdapterToInstanceList failed\n"));
583
return NDIS_STATUS_RESOURCES;
586
l_Adapter->m_InterfaceIsRunning = TRUE;
589
if (enable_non_admin)
590
AllowNonAdmin (&l_Adapter->m_Extension);
593
return NDIS_STATUS_SUCCESS;
597
AdapterHalt (IN NDIS_HANDLE p_AdapterContext)
601
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
605
l_Adapter->m_InterfaceIsRunning = FALSE;
607
DEBUGP (("[%s] is being halted\n", NAME (l_Adapter)));
609
DestroyTapDevice (&l_Adapter->m_Extension);
612
DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter)));
613
AdapterFreeResources (l_Adapter);
615
status = RemoveAdapterFromInstanceList (l_Adapter);
616
DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status));
618
DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n",
619
TAP_DRIVER_MAJOR_VERSION,
620
TAP_DRIVER_MINOR_VERSION,
626
AdapterFreeResources (TapAdapterPointer p_Adapter)
628
MYASSERT (!p_Adapter->m_CalledAdapterFreeResources);
629
p_Adapter->m_CalledAdapterFreeResources = TRUE;
631
if (p_Adapter->m_NameAnsi.Buffer)
632
RtlFreeAnsiString (&p_Adapter->m_NameAnsi);
634
if (p_Adapter->m_RegisteredAdapterShutdownHandler)
635
NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle);
637
if (p_Adapter->m_MCLockAllocated)
638
NdisFreeSpinLock (&p_Adapter->m_MCLock);
642
DestroyTapDevice (TapExtensionPointer p_Extension)
644
DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName));
646
//======================================
647
// Let clients know we are shutting down
648
//======================================
649
p_Extension->m_TapIsRunning = FALSE;
650
p_Extension->m_TapOpens = 0;
651
p_Extension->m_Halt = TRUE;
653
//=====================================
654
// If we are concurrently executing in
655
// TapDeviceHook or AdapterTransmit,
656
// give those calls time to finish.
657
// Note that we must be running at IRQL
658
// < DISPATCH_LEVEL in order to call
660
//=====================================
663
//===========================================================
664
// Exhaust IRP and packet queues. Any pending IRPs will
665
// be cancelled, causing user-space to get this error
666
// on overlapped reads:
667
// The I/O operation has been aborted because of either a
668
// thread exit or an application request. (code=995)
669
// It's important that user-space close the device handle
670
// when this code is returned, so that when we finally
671
// do a NdisMDeregisterDevice, the device reference count
672
// is 0. Otherwise the driver will not unload even if the
673
// the last adapter has been halted.
674
//===========================================================
675
FlushQueues (p_Extension);
676
NdisMSleep (500000); // give user space time to respond to IRP cancel
678
TapDeviceFreeResources (p_Extension);
682
TapDeviceFreeResources (TapExtensionPointer p_Extension)
684
MYASSERT (p_Extension);
685
MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources);
686
p_Extension->m_CalledTapDeviceFreeResources = TRUE;
688
if (p_Extension->m_PacketQueue)
689
QueueFree (p_Extension->m_PacketQueue);
690
if (p_Extension->m_IrpQueue)
691
QueueFree (p_Extension->m_IrpQueue);
692
if (p_Extension->m_InjectQueue)
693
QueueFree (p_Extension->m_InjectQueue);
695
if (p_Extension->m_CreatedUnicodeLinkName)
696
RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName);
698
//==========================================================
699
// According to DDK docs, the device is not actually deleted
700
// until its reference count falls to zero. That means we
701
// still need to gracefully fail TapDeviceHook requests
702
// after this point, otherwise ugly things would happen if
703
// the device was disabled (e.g. in the network connections
704
// control panel) while a userspace app still held an open
705
// file handle to it.
706
//==========================================================
708
if (p_Extension->m_TapDevice)
711
status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle)
712
== NDIS_STATUS_SUCCESS);
713
DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status));
716
if (p_Extension->m_TapName)
717
MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE);
719
if (p_Extension->m_InjectDpcInitialized)
720
KeRemoveQueueDpc (&p_Extension->m_InjectDpc);
722
if (p_Extension->m_AllocatedSpinlocks)
724
NdisFreeSpinLock (&p_Extension->m_QueueLock);
725
NdisFreeSpinLock (&p_Extension->m_InjectLock);
729
//========================================================================
730
// Tap Device Initialization
731
//========================================================================
734
CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name)
736
# define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1))
737
PDRIVER_DISPATCH *l_Dispatch = NULL;
738
ANSI_STRING l_TapString, l_LinkString;
739
UNICODE_STRING l_TapUnicode;
740
BOOLEAN l_FreeTapUnicode = FALSE;
741
NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS;
742
const char *l_UsableName;
744
DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
745
TAP_DRIVER_MAJOR_VERSION,
746
TAP_DRIVER_MINOR_VERSION,
749
NdisZeroMemory (p_Extension, sizeof (TapExtension));
751
INIT_MUTEX (&p_Extension->m_OpenCloseMutex);
753
l_LinkString.Buffer = NULL;
754
l_TapString.Buffer = NULL;
756
l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE;
758
//=======================================
759
// Set TAP device entry points
760
//=======================================
762
if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL)
764
DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name));
765
l_Return = NDIS_STATUS_RESOURCES;
769
l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook;
770
l_Dispatch[IRP_MJ_READ] = TapDeviceHook;
771
l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook;
772
l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook;
773
l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook;
775
//==================================
776
// Find the beginning of the GUID
777
//==================================
778
l_UsableName = p_Name;
779
while (*l_UsableName != '{')
781
if (*l_UsableName == '\0')
783
DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name));
784
l_Return = NDIS_STATUS_RESOURCES;
790
//==================================
791
// Allocate pool for TAP device name
792
//==================================
794
if ((p_Extension->m_TapName = l_TapString.Buffer =
795
MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
797
DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name));
798
l_Return = NDIS_STATUS_RESOURCES;
802
//================================================
803
// Allocate pool for TAP symbolic link name buffer
804
//================================================
806
if ((l_LinkString.Buffer =
807
MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
809
DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n",
811
l_Return = NDIS_STATUS_RESOURCES;
815
//=======================================================
816
// Set TAP device name
817
//=======================================================
819
l_Status = RtlStringCchPrintfExA
821
l_TapString.MaximumLength,
824
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
830
if (l_Status != STATUS_SUCCESS)
832
DEBUGP (("[%s] couldn't format TAP device name\n",
834
l_Return = NDIS_STATUS_RESOURCES;
837
l_TapString.Length = (USHORT) strlen (l_TapString.Buffer);
839
DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer));
841
//=======================================================
843
//=======================================================
845
l_Status = RtlStringCchPrintfExA
846
(l_LinkString.Buffer,
847
l_LinkString.MaximumLength,
850
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
856
if (l_Status != STATUS_SUCCESS)
858
DEBUGP (("[%s] couldn't format TAP device symbolic link\n",
860
l_Return = NDIS_STATUS_RESOURCES;
863
l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer);
865
DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer));
867
//==================================================
868
// Convert strings to unicode
869
//==================================================
870
if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) !=
873
DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n",
875
l_Return = NDIS_STATUS_RESOURCES;
878
l_FreeTapUnicode = TRUE;
880
if (RtlAnsiStringToUnicodeString
881
(&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE)
885
(("[%s] Couldn't allocate unicode string for symbolic link name\n",
887
l_Return = NDIS_STATUS_RESOURCES;
890
p_Extension->m_CreatedUnicodeLinkName = TRUE;
892
//==================================================
893
// Create new TAP device with symbolic
894
// link and associate with adapter.
895
//==================================================
897
l_Status = NdisMRegisterDevice
898
(g_NdisWrapperHandle,
900
&p_Extension->m_UnicodeLinkName,
902
&p_Extension->m_TapDevice,
903
&p_Extension->m_TapDeviceHandle
906
if (l_Status != STATUS_SUCCESS)
908
DEBUGP (("[%s] couldn't be created\n", p_Name));
909
l_Return = NDIS_STATUS_RESOURCES;
913
/* Set TAP device flags */
914
p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO;
916
//========================================================
917
// Initialize Packet and IRP queues.
919
// The packet queue is used to buffer data which has been
920
// "transmitted" by the virtual NIC, before user space
921
// has had a chance to read it.
923
// The IRP queue is used to buffer pending I/O requests
924
// from userspace, i.e. read requests on the TAP device
925
// waiting for the system to "transmit" something through
928
// Basically, packets in the packet queue are used
929
// to satisfy IRP requests in the IRP queue.
931
// QueueLock is used to lock the packet queue used
932
// for the TAP-Win32 NIC -> User Space packet flow direction.
934
// All accesses to packet or IRP queues should be
935
// bracketed by the QueueLock spinlock,
936
// in order to be SMP-safe.
937
//========================================================
939
NdisAllocateSpinLock (&p_Extension->m_QueueLock);
940
NdisAllocateSpinLock (&p_Extension->m_InjectLock);
941
p_Extension->m_AllocatedSpinlocks = TRUE;
943
p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE);
944
p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE);
945
p_Extension->m_InjectQueue = QueueInit (INJECT_QUEUE_SIZE);
946
if (!p_Extension->m_PacketQueue
947
|| !p_Extension->m_IrpQueue
948
|| !p_Extension->m_InjectQueue)
950
DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name));
951
l_Return = NDIS_STATUS_RESOURCES;
955
//=================================================================
956
// Initialize deferred procedure call for DHCP/ARP packet injection
957
//=================================================================
959
KeInitializeDpc (&p_Extension->m_InjectDpc, InjectPacketDpc, NULL);
960
p_Extension->m_InjectDpcInitialized = TRUE;
962
//========================
963
// Finalize initialization
964
//========================
966
p_Extension->m_TapIsRunning = TRUE;
968
DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name,
969
p_Extension->m_TapName));
972
if (l_FreeTapUnicode)
973
RtlFreeUnicodeString (&l_TapUnicode);
974
if (l_LinkString.Buffer)
975
MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE);
977
MemFree (l_Dispatch, SIZEOF_DISPATCH);
979
if (l_Return != NDIS_STATUS_SUCCESS)
980
TapDeviceFreeResources (p_Extension);
984
#undef SIZEOF_DISPATCH
986
//========================================================
988
//========================================================
990
AdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext)
992
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
993
DEBUGP (("[%s] is resetting\n", NAME (l_Adapter)));
994
return NDIS_STATUS_SUCCESS;
997
NDIS_STATUS AdapterReceive
998
(OUT PNDIS_PACKET p_Packet,
999
OUT PUINT p_Transferred,
1000
IN NDIS_HANDLE p_AdapterContext,
1001
IN NDIS_HANDLE p_ReceiveContext,
1003
IN UINT p_ToTransfer)
1005
return NDIS_STATUS_SUCCESS;
1008
//==============================================================
1009
// Adapter Option Query/Modification
1010
//==============================================================
1011
NDIS_STATUS AdapterQuery
1012
(IN NDIS_HANDLE p_AdapterContext,
1015
IN ULONG p_BufferLength,
1016
OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded)
1018
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1019
TapAdapterQuery l_Query, *l_QueryPtr = &l_Query;
1020
NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS;
1021
UINT l_QueryLength = 4;
1022
BOOLEAN lock_succeeded;
1024
NdisZeroMemory (&l_Query, sizeof (l_Query));
1028
//===================================================================
1029
// Vendor & Driver version Info
1030
//===================================================================
1031
case OID_GEN_VENDOR_DESCRIPTION:
1032
l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_STRING;
1033
l_QueryLength = strlen (PRODUCT_STRING) + 1;
1036
case OID_GEN_VENDOR_ID:
1037
l_Query.m_Long = 0xffffff;
1040
case OID_GEN_DRIVER_VERSION:
1042
(((USHORT) TAP_NDIS_MAJOR_VERSION) << 8 | (USHORT)
1043
TAP_NDIS_MINOR_VERSION);
1044
l_QueryLength = sizeof (unsigned short);
1047
case OID_GEN_VENDOR_DRIVER_VERSION:
1049
(((USHORT) TAP_DRIVER_MAJOR_VERSION) << 8 | (USHORT)
1050
TAP_DRIVER_MINOR_VERSION);
1053
//=================================================================
1055
//=================================================================
1056
case OID_GEN_RCV_NO_BUFFER:
1060
case OID_802_3_RCV_ERROR_ALIGNMENT:
1064
case OID_802_3_XMIT_ONE_COLLISION:
1068
case OID_802_3_XMIT_MORE_COLLISIONS:
1072
case OID_GEN_XMIT_OK:
1073
l_Query.m_Long = l_Adapter->m_Tx;
1076
case OID_GEN_RCV_OK:
1077
l_Query.m_Long = l_Adapter->m_Rx;
1080
case OID_GEN_XMIT_ERROR:
1081
l_Query.m_Long = l_Adapter->m_TxErr;
1084
case OID_GEN_RCV_ERROR:
1085
l_Query.m_Long = l_Adapter->m_RxErr;
1088
//===================================================================
1089
// Device & Protocol Options
1090
//===================================================================
1091
case OID_GEN_SUPPORTED_LIST:
1092
l_QueryPtr = (TapAdapterQueryPointer) g_SupportedOIDList;
1093
l_QueryLength = sizeof (g_SupportedOIDList);
1096
case OID_GEN_MAC_OPTIONS:
1097
// This MUST be here !!!
1098
l_Query.m_Long = (NDIS_MAC_OPTION_RECEIVE_SERIALIZED
1099
| NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
1100
| NDIS_MAC_OPTION_NO_LOOPBACK
1101
| NDIS_MAC_OPTION_TRANSFERS_NOT_PEND);
1105
case OID_GEN_CURRENT_PACKET_FILTER:
1107
(NDIS_PACKET_TYPE_ALL_LOCAL |
1108
NDIS_PACKET_TYPE_BROADCAST |
1109
NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL);
1113
case OID_GEN_PROTOCOL_OPTIONS:
1117
//==================================================================
1119
//==================================================================
1120
case OID_GEN_MEDIA_CONNECT_STATUS:
1121
l_Query.m_Long = l_Adapter->m_MediaState
1122
? NdisMediaStateConnected : NdisMediaStateDisconnected;
1125
case OID_GEN_HARDWARE_STATUS:
1126
l_Query.m_HardwareStatus = NdisHardwareStatusReady;
1127
l_QueryLength = sizeof (NDIS_HARDWARE_STATUS);
1130
case OID_GEN_MEDIA_SUPPORTED:
1131
case OID_GEN_MEDIA_IN_USE:
1132
l_Query.m_Medium = l_Adapter->m_Medium;
1133
l_QueryLength = sizeof (NDIS_MEDIUM);
1136
case OID_GEN_PHYSICAL_MEDIUM:
1137
l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified;
1138
l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM);
1141
case OID_GEN_LINK_SPEED:
1142
l_Query.m_Long = 100000; // rate / 100 bps
1145
case OID_802_3_PERMANENT_ADDRESS:
1146
case OID_802_3_CURRENT_ADDRESS:
1147
COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC);
1148
l_QueryLength = sizeof (MACADDR);
1151
//==================================================================
1153
//==================================================================
1155
case OID_GEN_MAXIMUM_SEND_PACKETS:
1159
case OID_802_3_MAXIMUM_LIST_SIZE:
1160
l_Query.m_Long = NIC_MAX_MCAST_LIST;
1163
case OID_GEN_CURRENT_LOOKAHEAD:
1164
l_Query.m_Long = l_Adapter->m_Lookahead;
1167
case OID_GEN_MAXIMUM_LOOKAHEAD:
1168
case OID_GEN_MAXIMUM_TOTAL_SIZE:
1169
case OID_GEN_RECEIVE_BUFFER_SPACE:
1170
case OID_GEN_RECEIVE_BLOCK_SIZE:
1171
l_Query.m_Long = DEFAULT_PACKET_LOOKAHEAD;
1174
case OID_GEN_MAXIMUM_FRAME_SIZE:
1175
case OID_GEN_TRANSMIT_BLOCK_SIZE:
1176
case OID_GEN_TRANSMIT_BUFFER_SPACE:
1177
l_Query.m_Long = l_Adapter->m_MTU;
1180
case OID_PNP_CAPABILITIES:
1183
PNDIS_PNP_CAPABILITIES pPNPCapabilities;
1184
PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct;
1186
if (p_BufferLength >= sizeof (NDIS_PNP_CAPABILITIES))
1188
pPNPCapabilities = (PNDIS_PNP_CAPABILITIES) (p_Buffer);
1191
// Setting up the buffer to be returned
1192
// to the Protocol above the Passthru miniport
1194
pPMstruct = &pPNPCapabilities->WakeUpCapabilities;
1195
pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
1196
pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
1197
pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
1199
l_QueryLength = sizeof (NDIS_PNP_CAPABILITIES);
1203
case OID_PNP_QUERY_POWER:
1206
// Required OIDs that we don't support
1208
case OID_GEN_SUPPORTED_GUIDS:
1209
case OID_GEN_MEDIA_CAPABILITIES:
1210
case OID_TCP_TASK_OFFLOAD:
1211
case OID_FFP_SUPPORT:
1212
l_Status = NDIS_STATUS_INVALID_OID;
1215
// Optional stats OIDs
1217
case OID_GEN_DIRECTED_BYTES_XMIT:
1218
case OID_GEN_DIRECTED_FRAMES_XMIT:
1219
case OID_GEN_MULTICAST_BYTES_XMIT:
1220
case OID_GEN_MULTICAST_FRAMES_XMIT:
1221
case OID_GEN_BROADCAST_BYTES_XMIT:
1222
case OID_GEN_BROADCAST_FRAMES_XMIT:
1223
case OID_GEN_DIRECTED_BYTES_RCV:
1224
case OID_GEN_DIRECTED_FRAMES_RCV:
1225
case OID_GEN_MULTICAST_BYTES_RCV:
1226
case OID_GEN_MULTICAST_FRAMES_RCV:
1227
case OID_GEN_BROADCAST_BYTES_RCV:
1228
case OID_GEN_BROADCAST_FRAMES_RCV:
1229
l_Status = NDIS_STATUS_INVALID_OID;
1232
//===================================================================
1234
//===================================================================
1236
DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID));
1237
l_Status = NDIS_STATUS_INVALID_OID;
1241
if (l_Status != NDIS_STATUS_SUCCESS)
1243
else if (l_QueryLength > p_BufferLength)
1245
l_Status = NDIS_STATUS_INVALID_LENGTH;
1246
*p_BytesNeeded = l_QueryLength;
1249
NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr,
1250
(*p_BytesWritten = l_QueryLength));
1255
NDIS_STATUS AdapterModify
1256
(IN NDIS_HANDLE p_AdapterContext,
1259
IN ULONG p_BufferLength,
1260
OUT PULONG p_BytesRead,
1261
OUT PULONG p_BytesNeeded)
1263
TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer;
1264
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1265
NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID;
1270
//==================================================================
1272
//==================================================================
1273
case OID_802_3_MULTICAST_LIST:
1274
DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n",
1277
*p_BytesNeeded = sizeof (ETH_ADDR);
1278
*p_BytesRead = p_BufferLength;
1280
if (p_BufferLength % sizeof (ETH_ADDR))
1281
l_Status = NDIS_STATUS_INVALID_LENGTH;
1282
else if (p_BufferLength > sizeof (MC_LIST))
1284
l_Status = NDIS_STATUS_MULTICAST_FULL;
1285
*p_BytesNeeded = sizeof (MC_LIST);
1289
NdisAcquireSpinLock (&l_Adapter->m_MCLock);
1291
NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST));
1293
NdisMoveMemory(&l_Adapter->m_MCList,
1297
l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR);
1299
NdisReleaseSpinLock (&l_Adapter->m_MCLock);
1301
l_Status = NDIS_STATUS_SUCCESS;
1305
case OID_GEN_CURRENT_PACKET_FILTER:
1306
l_Status = NDIS_STATUS_INVALID_LENGTH;
1309
if (p_BufferLength >= sizeof (ULONG))
1312
(("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n",
1313
NAME (l_Adapter), l_Query->m_Long));
1314
l_Status = NDIS_STATUS_SUCCESS;
1315
*p_BytesRead = sizeof (ULONG);
1319
case OID_GEN_CURRENT_LOOKAHEAD:
1320
if (p_BufferLength < sizeof (ULONG))
1322
l_Status = NDIS_STATUS_INVALID_LENGTH;
1325
else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD
1326
|| l_Query->m_Long <= 0)
1328
l_Status = NDIS_STATUS_INVALID_DATA;
1332
DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n",
1333
NAME (l_Adapter), l_Query->m_Long));
1334
l_Adapter->m_Lookahead = l_Query->m_Long;
1335
l_Status = NDIS_STATUS_SUCCESS;
1336
*p_BytesRead = sizeof (ULONG);
1340
case OID_GEN_NETWORK_LAYER_ADDRESSES:
1341
l_Status = NDIS_STATUS_SUCCESS;
1342
*p_BytesRead = *p_BytesNeeded = 0;
1345
case OID_GEN_TRANSPORT_HEADER_OFFSET:
1346
l_Status = NDIS_STATUS_SUCCESS;
1347
*p_BytesRead = *p_BytesNeeded = 0;
1350
case OID_PNP_SET_POWER:
1353
NDIS_DEVICE_POWER_STATE NewDeviceState;
1355
NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE) p_Buffer);
1357
switch (NewDeviceState)
1359
case NdisDeviceStateD0:
1360
l_Adapter->m_DeviceState = '0';
1362
case NdisDeviceStateD1:
1363
l_Adapter->m_DeviceState = '1';
1365
case NdisDeviceStateD2:
1366
l_Adapter->m_DeviceState = '2';
1368
case NdisDeviceStateD3:
1369
l_Adapter->m_DeviceState = '3';
1372
l_Adapter->m_DeviceState = '?';
1376
l_Status = NDIS_STATUS_FAILURE;
1379
// Check for invalid length
1381
if (p_BufferLength < sizeof (NDIS_DEVICE_POWER_STATE))
1383
l_Status = NDIS_STATUS_INVALID_LENGTH;
1387
if (NewDeviceState > NdisDeviceStateD0)
1389
l_Adapter->m_InterfaceIsRunning = FALSE;
1390
DEBUGP (("[%s] Power management device state OFF\n",
1395
l_Adapter->m_InterfaceIsRunning = TRUE;
1396
DEBUGP (("[%s] Power management device state ON\n",
1400
l_Status = NDIS_STATUS_SUCCESS;
1404
if (l_Status == NDIS_STATUS_SUCCESS)
1406
*p_BytesRead = sizeof (NDIS_DEVICE_POWER_STATE);
1412
*p_BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
1416
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
1417
case OID_PNP_ADD_WAKE_UP_PATTERN:
1418
l_Status = NDIS_STATUS_SUCCESS;
1419
*p_BytesRead = *p_BytesNeeded = 0;
1423
DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter),
1425
l_Status = NDIS_STATUS_INVALID_OID;
1426
*p_BytesRead = *p_BytesNeeded = 0;
1433
// checksum code for ICMPv6 packet, taken from dhcp.c / udp_checksum
1434
// see RFC 4443, 2.3, and RFC 2460, 8.1
1436
icmpv6_checksum (const UCHAR *buf,
1437
const int len_icmpv6,
1438
const UCHAR *saddr6,
1439
const UCHAR *daddr6)
1445
// make 16 bit words out of every two adjacent 8 bit words and
1446
// calculate the sum of all 16 bit words
1447
for (i = 0; i < len_icmpv6; i += 2){
1448
word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_icmpv6) ? (buf[i+1] & 0xFF) : 0);
1452
// add the IPv6 pseudo header which contains the IP source and destination addresses
1453
for (i = 0; i < 16; i += 2){
1454
word16 =((saddr6[i] << 8) & 0xFF00) + (saddr6[i+1] & 0xFF);
1457
for (i = 0; i < 16; i += 2){
1458
word16 =((daddr6[i] << 8) & 0xFF00) + (daddr6[i+1] & 0xFF);
1462
// the next-header number and the length of the ICMPv6 packet
1463
sum += (USHORT) IPPROTO_ICMPV6 + (USHORT) len_icmpv6;
1465
// keep only the last 16 bits of the 32 bit calculated sum and add the carries
1467
sum = (sum & 0xFFFF) + (sum >> 16);
1469
// Take the one's complement of sum
1470
return ((USHORT) ~sum);
1473
// check IPv6 packet for "is this an IPv6 Neighbor Solicitation that
1474
// the tap driver needs to answer?"
1475
// see RFC 4861 4.3 for the different cases
1476
static IPV6ADDR IPV6_NS_TARGET_MCAST =
1477
{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1478
0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x08 };
1479
static IPV6ADDR IPV6_NS_TARGET_UNICAST =
1480
{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1481
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 };
1484
HandleIPv6NeighborDiscovery( TapAdapterPointer p_Adapter, UCHAR * m_Data )
1486
const ETH_HEADER * e = (ETH_HEADER *) m_Data;
1487
const IPV6HDR *ipv6 = (IPV6HDR *) (m_Data + sizeof (ETH_HEADER));
1488
const ICMPV6_NS * icmpv6_ns = (ICMPV6_NS *) (m_Data + sizeof (ETH_HEADER) + sizeof (IPV6HDR));
1490
USHORT icmpv6_len, icmpv6_csum;
1492
// we don't really care about the destination MAC address here
1493
// - it's either a multicast MAC, or the userland destination MAC
1494
// but since the TAP driver is point-to-point, all packets are "for us"
1496
// IPv6 target address must be ff02::1::ff00:8 (multicast for
1497
// initial NS) or fe80::1 (unicast for recurrent NUD)
1498
if ( memcmp( ipv6->daddr, IPV6_NS_TARGET_MCAST,
1499
sizeof(IPV6ADDR) ) != 0 &&
1500
memcmp( ipv6->daddr, IPV6_NS_TARGET_UNICAST,
1501
sizeof(IPV6ADDR) ) != 0 )
1503
return FALSE; // wrong target address
1506
// IPv6 Next-Header must be ICMPv6
1507
if ( ipv6->nexthdr != IPPROTO_ICMPV6 )
1509
return FALSE; // wrong next-header
1512
// ICMPv6 type+code must be 135/0 for NS
1513
if ( icmpv6_ns->type != ICMPV6_TYPE_NS ||
1514
icmpv6_ns->code != ICMPV6_CODE_0 )
1516
return FALSE; // wrong ICMPv6 type
1519
// ICMPv6 target address must be fe80::8 (magic)
1520
if ( memcmp( icmpv6_ns->target_addr, IPV6_NS_TARGET_UNICAST,
1521
sizeof(IPV6ADDR) ) != 0 )
1523
return FALSE; // not for us
1526
// packet identified, build magic response packet
1528
na = (ICMPV6_NA_PKT *) MemAlloc (sizeof (ICMPV6_NA_PKT), TRUE);
1529
if ( !na ) return FALSE;
1531
//------------------------------------------------
1532
// Initialize Neighbour Advertisement reply packet
1533
//------------------------------------------------
1536
na->eth.proto = htons(ETH_P_IPV6);
1537
COPY_MAC(na->eth.dest, p_Adapter->m_MAC);
1538
COPY_MAC(na->eth.src, p_Adapter->m_TapToUser.dest);
1541
na->ipv6.version_prio = ipv6->version_prio;
1542
NdisMoveMemory( na->ipv6.flow_lbl, ipv6->flow_lbl,
1543
sizeof(na->ipv6.flow_lbl) );
1544
icmpv6_len = sizeof(ICMPV6_NA_PKT) - sizeof(ETH_HEADER) - sizeof(IPV6HDR);
1545
na->ipv6.payload_len = htons(icmpv6_len);
1546
na->ipv6.nexthdr = IPPROTO_ICMPV6;
1547
na->ipv6.hop_limit = 255;
1548
NdisMoveMemory( na->ipv6.saddr, IPV6_NS_TARGET_UNICAST,
1550
NdisMoveMemory( na->ipv6.daddr, ipv6->saddr,
1554
na->icmpv6.type = ICMPV6_TYPE_NA;
1555
na->icmpv6.code = ICMPV6_CODE_0;
1556
na->icmpv6.checksum = 0;
1557
na->icmpv6.rso_bits = 0x60; // Solicited + Override
1558
NdisZeroMemory( na->icmpv6.reserved, sizeof(na->icmpv6.reserved) );
1559
NdisMoveMemory( na->icmpv6.target_addr, IPV6_NS_TARGET_UNICAST,
1562
// ICMPv6 option "Target Link Layer Address"
1563
na->icmpv6.opt_type = ICMPV6_OPTION_TLLA;
1564
na->icmpv6.opt_length = ICMPV6_LENGTH_TLLA;
1565
COPY_MAC( na->icmpv6.target_macaddr, p_Adapter->m_TapToUser.dest );
1567
// calculate and set checksum
1568
icmpv6_csum = icmpv6_checksum ( (UCHAR*) &(na->icmpv6),
1572
na->icmpv6.checksum = htons( icmpv6_csum );
1574
DUMP_PACKET ("HandleIPv6NeighborDiscovery",
1575
(unsigned char *) na,
1576
sizeof (ICMPV6_NA_PKT));
1578
InjectPacketDeferred (p_Adapter, (UCHAR *) na, sizeof (ICMPV6_NA_PKT));
1580
MemFree (na, sizeof (ICMPV6_NA_PKT));
1582
return TRUE; // all fine
1585
//====================================================================
1586
// Adapter Transmission
1587
//====================================================================
1589
AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
1590
IN PNDIS_PACKET p_Packet,
1593
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1594
ULONG l_Index = 0, l_PacketLength = 0;
1595
UINT l_BufferLength = 0;
1597
TapPacketPointer l_PacketBuffer;
1598
PNDIS_BUFFER l_NDIS_Buffer;
1602
NdisQueryPacket (p_Packet, NULL, NULL, &l_NDIS_Buffer, &l_PacketLength);
1604
//====================================================
1605
// Here we abandon the transmission attempt if any of
1606
// the parameters is wrong or memory allocation fails
1607
// but we do not indicate failure. The packet is
1608
// silently dropped.
1609
//====================================================
1611
if (l_PacketLength < ETHERNET_HEADER_SIZE || l_PacketLength > 65535)
1613
else if (!l_Adapter->m_Extension.m_TapOpens || !l_Adapter->m_MediaState)
1614
goto exit_success; // Nothing is bound to the TAP device
1616
if (NdisAllocateMemoryWithTag (&l_PacketBuffer,
1617
TAP_PACKET_SIZE (l_PacketLength),
1618
'5PAT') != NDIS_STATUS_SUCCESS)
1619
goto exit_no_resources;
1621
if (l_PacketBuffer == NULL)
1622
goto exit_no_resources;
1624
l_PacketBuffer->m_SizeFlags = (l_PacketLength & TP_SIZE_MASK);
1626
//===========================
1627
// Reassemble packet contents
1628
//===========================
1633
while (l_NDIS_Buffer && l_Index < l_PacketLength)
1636
NdisQueryBuffer (l_NDIS_Buffer, (PVOID *) & l_Buffer,
1638
newlen = l_Index + l_BufferLength;
1639
if (newlen > l_PacketLength)
1642
goto no_queue; /* overflow */
1644
NdisMoveMemory (l_PacketBuffer->m_Data + l_Index, l_Buffer,
1647
NdisGetNextBuffer (l_NDIS_Buffer, &l_NDIS_Buffer);
1649
if (l_Index != l_PacketLength)
1652
goto no_queue; /* underflow */
1655
DUMP_PACKET ("AdapterTransmit", l_PacketBuffer->m_Data, l_PacketLength);
1657
//=====================================================
1658
// If IPv4 packet, check whether or not packet
1660
//=====================================================
1661
#if PACKET_TRUNCATION_CHECK
1662
IPv4PacketSizeVerify (l_PacketBuffer->m_Data, l_PacketLength, FALSE, "TX", &l_Adapter->m_TxTrunc);
1665
//=====================================================
1666
// Are we running in DHCP server masquerade mode?
1668
// If so, catch both DHCP requests and ARP queries
1669
// to resolve the address of our virtual DHCP server.
1670
//=====================================================
1671
if (l_Adapter->m_dhcp_enabled)
1673
const ETH_HEADER *eth = (ETH_HEADER *) l_PacketBuffer->m_Data;
1674
const IPHDR *ip = (IPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER));
1675
const UDPHDR *udp = (UDPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER) + sizeof (IPHDR));
1678
if (l_PacketLength == sizeof (ARP_PACKET)
1679
&& eth->proto == htons (ETH_P_ARP)
1680
&& l_Adapter->m_dhcp_server_arp)
1682
if (ProcessARP (l_Adapter,
1683
(PARP_PACKET) l_PacketBuffer->m_Data,
1684
l_Adapter->m_dhcp_addr,
1685
l_Adapter->m_dhcp_server_ip,
1687
l_Adapter->m_dhcp_server_mac))
1692
else if (l_PacketLength >= sizeof (ETH_HEADER) + sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP)
1693
&& eth->proto == htons (ETH_P_IP)
1694
&& ip->version_len == 0x45 // IPv4, 20 byte header
1695
&& ip->protocol == IPPROTO_UDP
1696
&& udp->dest == htons (BOOTPS_PORT))
1698
const DHCP *dhcp = (DHCP *) (l_PacketBuffer->m_Data
1699
+ sizeof (ETH_HEADER)
1703
const int optlen = l_PacketLength
1704
- sizeof (ETH_HEADER)
1709
if (optlen > 0) // we must have at least one DHCP option
1711
if (ProcessDHCP (l_Adapter, eth, ip, udp, dhcp, optlen))
1719
//===============================================
1720
// In Point-To-Point mode, check to see whether
1721
// packet is ARP (handled) or IPv4 (sent to app).
1722
// IPv6 packets are inspected for neighbour discovery
1723
// (to be handled locally), and the rest is forwarded
1724
// all other protocols are dropped
1725
//===============================================
1726
if (l_Adapter->m_tun)
1730
if (l_PacketLength < ETHERNET_HEADER_SIZE)
1733
e = (ETH_HEADER *) l_PacketBuffer->m_Data;
1735
switch (ntohs (e->proto))
1739
// Make sure that packet is the
1740
// right size for ARP.
1741
if (l_PacketLength != sizeof (ARP_PACKET))
1744
ProcessARP (l_Adapter,
1745
(PARP_PACKET) l_PacketBuffer->m_Data,
1746
l_Adapter->m_localIP,
1747
l_Adapter->m_remoteNetwork,
1748
l_Adapter->m_remoteNetmask,
1749
l_Adapter->m_TapToUser.dest);
1756
// Make sure that packet is large
1757
// enough to be IPv4.
1759
< ETHERNET_HEADER_SIZE + IP_HEADER_SIZE)
1762
// Only accept directed packets,
1764
if (memcmp (e, &l_Adapter->m_TapToUser, ETHERNET_HEADER_SIZE))
1767
// Packet looks like IPv4, queue it.
1768
l_PacketBuffer->m_SizeFlags |= TP_TUN;
1771
// make sure that packet is large
1772
// enough to be IPv6
1774
< ETHERNET_HEADER_SIZE + IPV6_HEADER_SIZE)
1777
// broadcasts and multicasts are handled specially
1778
// (to be implemented)
1780
// neighbor discovery packets to fe80::8 are special
1781
// OpenVPN sets this next-hop to signal "handled by tapdrv"
1782
if ( HandleIPv6NeighborDiscovery( l_Adapter,
1783
l_PacketBuffer->m_Data ))
1788
// Packet looks like IPv6, queue it :-)
1789
l_PacketBuffer->m_SizeFlags |= TP_TUN;
1793
//===============================================
1794
// Push packet onto queue to wait for read from
1796
//===============================================
1798
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1801
if (IS_UP (l_Adapter))
1802
result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer);
1804
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1806
if ((TapPacketPointer) result != l_PacketBuffer)
1808
// adapter receive overrun
1809
INCREMENT_STAT (l_Adapter->m_TxErr);
1814
INCREMENT_STAT (l_Adapter->m_Tx);
1817
//============================================================
1818
// Cycle through IRPs and packets, try to satisfy each pending
1819
// IRP with a queued packet.
1820
//============================================================
1824
l_PacketBuffer = NULL;
1826
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1828
if (IS_UP (l_Adapter)
1829
&& QueueCount (l_Adapter->m_Extension.m_PacketQueue)
1830
&& QueueCount (l_Adapter->m_Extension.m_IrpQueue))
1832
l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue);
1833
l_PacketBuffer = (TapPacketPointer)
1834
QueuePop (l_Adapter->m_Extension.m_PacketQueue);
1837
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1839
MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1);
1841
if (l_IRP && l_PacketBuffer)
1845
IO_NETWORK_INCREMENT);
1851
__except (EXCEPTION_EXECUTE_HANDLER)
1855
return NDIS_STATUS_SUCCESS;
1858
NdisFreeMemory (l_PacketBuffer,
1859
TAP_PACKET_SIZE (l_PacketLength),
1863
return NDIS_STATUS_SUCCESS;
1866
return NDIS_STATUS_FAILURE;
1869
return NDIS_STATUS_RESOURCES;
1872
//======================================================================
1873
// Hooks for catching TAP device IRP's.
1874
//======================================================================
1877
TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
1879
TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
1880
PIO_STACK_LOCATION l_IrpSp;
1881
NTSTATUS l_Status = STATUS_SUCCESS;
1884
l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP);
1886
p_IRP->IoStatus.Status = STATUS_SUCCESS;
1887
p_IRP->IoStatus.Information = 0;
1889
if (!l_Adapter || l_Adapter->m_Extension.m_Halt)
1891
DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n",
1892
(int)l_IrpSp->MajorFunction));
1894
if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE)
1896
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1897
return STATUS_SUCCESS;
1901
p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
1902
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1903
return STATUS_NO_SUCH_DEVICE;
1907
switch (l_IrpSp->MajorFunction)
1909
//===========================================================
1910
// Ioctl call handlers
1911
//===========================================================
1912
case IRP_MJ_DEVICE_CONTROL:
1914
switch (l_IrpSp->Parameters.DeviceIoControl.IoControlCode)
1916
case TAP_IOCTL_GET_MAC:
1918
if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
1919
>= sizeof (MACADDR))
1921
COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer,
1923
p_IRP->IoStatus.Information = sizeof (MACADDR);
1928
p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1932
case TAP_IOCTL_GET_VERSION:
1934
const ULONG size = sizeof (ULONG) * 3;
1935
if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
1938
((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]
1939
= TAP_DRIVER_MAJOR_VERSION;
1940
((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1]
1941
= TAP_DRIVER_MINOR_VERSION;
1942
((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2]
1948
p_IRP->IoStatus.Information = size;
1953
p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1958
case TAP_IOCTL_GET_MTU:
1960
const ULONG size = sizeof (ULONG) * 1;
1961
if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
1964
((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]
1966
p_IRP->IoStatus.Information = size;
1971
p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1976
case TAP_IOCTL_GET_INFO:
1979
if (l_Adapter->m_InterfaceIsRunning)
1983
if (l_Adapter->m_Extension.m_TapIsRunning)
1987
state[2] = l_Adapter->m_DeviceState;
1988
if (l_Adapter->m_MediaStateAlwaysConnected)
1994
p_IRP->IoStatus.Status = l_Status = RtlStringCchPrintfExA (
1995
((LPTSTR) (p_IRP->AssociatedIrp.SystemBuffer)),
1996
l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
1999
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
2000
#if PACKET_TRUNCATION_CHECK
2001
"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]",
2003
"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]",
2006
g_LastErrorFilename,
2007
g_LastErrorLineNumber,
2008
(int)l_Adapter->m_Extension.m_NumTapOpens,
2009
(int)l_Adapter->m_Tx,
2010
(int)l_Adapter->m_TxErr,
2011
#if PACKET_TRUNCATION_CHECK
2012
(int)l_Adapter->m_TxTrunc,
2014
(int)l_Adapter->m_Rx,
2015
(int)l_Adapter->m_RxErr,
2016
#if PACKET_TRUNCATION_CHECK
2017
(int)l_Adapter->m_RxTrunc,
2019
(int)l_Adapter->m_Extension.m_IrpQueue->size,
2020
(int)l_Adapter->m_Extension.m_IrpQueue->max_size,
2021
(int)IRP_QUEUE_SIZE,
2022
(int)l_Adapter->m_Extension.m_PacketQueue->size,
2023
(int)l_Adapter->m_Extension.m_PacketQueue->max_size,
2024
(int)PACKET_QUEUE_SIZE,
2025
(int)l_Adapter->m_Extension.m_InjectQueue->size,
2026
(int)l_Adapter->m_Extension.m_InjectQueue->max_size,
2027
(int)INJECT_QUEUE_SIZE
2030
p_IRP->IoStatus.Information
2031
= l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
2037
case TAP_IOCTL_GET_LOG_LINE:
2039
if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer,
2040
l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength))
2041
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2043
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2045
p_IRP->IoStatus.Information
2046
= l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
2052
case TAP_IOCTL_CONFIG_TUN:
2054
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
2055
(sizeof (IPADDR) * 3))
2059
l_Adapter->m_tun = FALSE;
2061
GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);
2063
l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
2064
l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
2065
l_Adapter->m_remoteNetmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2];
2067
// sanity check on network/netmask
2068
if ((l_Adapter->m_remoteNetwork & l_Adapter->m_remoteNetmask) != l_Adapter->m_remoteNetwork)
2071
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2075
COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC);
2076
COPY_MAC (l_Adapter->m_TapToUser.dest, dest);
2077
COPY_MAC (l_Adapter->m_UserToTap.src, dest);
2078
COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC);
2080
l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);
2081
l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap;
2082
l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6);
2084
l_Adapter->m_tun = TRUE;
2086
CheckIfDhcpAndTunMode (l_Adapter);
2088
p_IRP->IoStatus.Information = 1; // Simple boolean value
2093
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2099
case TAP_IOCTL_CONFIG_POINT_TO_POINT: // Obsoleted by TAP_IOCTL_CONFIG_TUN
2101
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
2102
(sizeof (IPADDR) * 2))
2106
l_Adapter->m_tun = FALSE;
2108
GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);
2110
l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
2111
l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
2112
l_Adapter->m_remoteNetmask = ~0;
2114
COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC);
2115
COPY_MAC (l_Adapter->m_TapToUser.dest, dest);
2116
COPY_MAC (l_Adapter->m_UserToTap.src, dest);
2117
COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC);
2119
l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);
2120
l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap;
2121
l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6);
2123
l_Adapter->m_tun = TRUE;
2125
CheckIfDhcpAndTunMode (l_Adapter);
2127
p_IRP->IoStatus.Information = 1; // Simple boolean value
2132
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2138
case TAP_IOCTL_SET_MEDIA_STATUS:
2140
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
2141
(sizeof (ULONG) * 1))
2143
ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0];
2144
SetMediaStatus (l_Adapter, (BOOLEAN) parm);
2145
p_IRP->IoStatus.Information = 1;
2150
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2155
case TAP_IOCTL_CONFIG_DHCP_MASQ:
2157
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
2158
(sizeof (IPADDR) * 4))
2160
l_Adapter->m_dhcp_enabled = FALSE;
2161
l_Adapter->m_dhcp_server_arp = FALSE;
2162
l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
2164
// Adapter IP addr / netmask
2165
l_Adapter->m_dhcp_addr =
2166
((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
2167
l_Adapter->m_dhcp_netmask =
2168
((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
2170
// IP addr of DHCP masq server
2171
l_Adapter->m_dhcp_server_ip =
2172
((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2];
2174
// Lease time in seconds
2175
l_Adapter->m_dhcp_lease_time =
2176
((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[3];
2178
GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2);
2180
l_Adapter->m_dhcp_enabled = TRUE;
2181
l_Adapter->m_dhcp_server_arp = TRUE;
2183
CheckIfDhcpAndTunMode (l_Adapter);
2185
p_IRP->IoStatus.Information = 1; // Simple boolean value
2190
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2196
case TAP_IOCTL_CONFIG_DHCP_SET_OPT:
2198
if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength <=
2199
DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE
2200
&& l_Adapter->m_dhcp_enabled)
2202
l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
2204
NdisMoveMemory (l_Adapter->m_dhcp_user_supplied_options_buffer,
2205
p_IRP->AssociatedIrp.SystemBuffer,
2206
l_IrpSp->Parameters.DeviceIoControl.InputBufferLength);
2208
l_Adapter->m_dhcp_user_supplied_options_buffer_len =
2209
l_IrpSp->Parameters.DeviceIoControl.InputBufferLength;
2211
p_IRP->IoStatus.Information = 1; // Simple boolean value
2216
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2225
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2230
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2234
//===========================================================
2235
// User mode thread issued a read request on the tap device
2236
// If there are packets waiting to be read, then the request
2237
// will be satisfied here. If not, then the request will be
2238
// queued and satisfied by any packet that is not used to
2239
// satisfy requests ahead of it.
2240
//===========================================================
2243
TapPacketPointer l_PacketBuffer;
2244
BOOLEAN pending = FALSE;
2246
// Save IRP-accessible copy of buffer length
2247
p_IRP->IoStatus.Information = l_IrpSp->Parameters.Read.Length;
2249
if (p_IRP->MdlAddress == NULL)
2251
DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n",
2254
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2255
p_IRP->IoStatus.Information = 0;
2256
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2259
else if ((p_IRP->AssociatedIrp.SystemBuffer =
2260
MmGetSystemAddressForMdlSafe
2261
(p_IRP->MdlAddress, NormalPagePriority)) == NULL)
2263
DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n",
2266
p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
2267
p_IRP->IoStatus.Information = 0;
2268
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2271
else if (!l_Adapter->m_InterfaceIsRunning)
2273
DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n",
2276
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2277
p_IRP->IoStatus.Information = 0;
2278
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2282
//==================================
2283
// Can we provide immediate service?
2284
//==================================
2286
l_PacketBuffer = NULL;
2288
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
2290
if (IS_UP (l_Adapter)
2291
&& QueueCount (l_Adapter->m_Extension.m_PacketQueue)
2292
&& QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0)
2294
l_PacketBuffer = (TapPacketPointer)
2295
QueuePop (l_Adapter->m_Extension.m_PacketQueue);
2298
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
2302
l_Status = CompleteIRP (p_IRP,
2308
//=============================
2309
// Attempt to pend read request
2310
//=============================
2312
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
2314
if (IS_UP (l_Adapter)
2315
&& QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP)
2317
IoSetCancelRoutine (p_IRP, CancelIRPCallback);
2318
l_Status = STATUS_PENDING;
2319
IoMarkIrpPending (p_IRP);
2323
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
2328
// Can't queue anymore IRP's
2329
DEBUGP (("[%s] TAP [%s] read IRP overrun\n",
2330
NAME (l_Adapter), l_Adapter->m_Extension.m_TapName));
2332
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2333
p_IRP->IoStatus.Information = 0;
2334
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2338
//==============================================================
2339
// User mode issued a WriteFile request on the TAP file handle.
2340
// The request will always get satisfied here. The call may
2341
// fail if there are too many pending packets (queue full).
2342
//==============================================================
2345
if (p_IRP->MdlAddress == NULL)
2347
DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n",
2350
p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
2351
p_IRP->IoStatus.Information = 0;
2353
else if ((p_IRP->AssociatedIrp.SystemBuffer =
2354
MmGetSystemAddressForMdlSafe
2355
(p_IRP->MdlAddress, NormalPagePriority)) == NULL)
2357
DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n",
2360
p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
2361
p_IRP->IoStatus.Information = 0;
2363
else if (!l_Adapter->m_InterfaceIsRunning)
2365
DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n",
2368
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2369
p_IRP->IoStatus.Information = 0;
2371
else if (!l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE))
2375
p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length;
2377
DUMP_PACKET ("IRP_MJ_WRITE ETH",
2378
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2379
l_IrpSp->Parameters.Write.Length);
2381
//=====================================================
2382
// If IPv4 packet, check whether or not packet
2384
//=====================================================
2385
#if PACKET_TRUNCATION_CHECK
2386
IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2387
l_IrpSp->Parameters.Write.Length,
2390
&l_Adapter->m_RxTrunc);
2393
NdisMEthIndicateReceive
2394
(l_Adapter->m_MiniportAdapterHandle,
2395
(NDIS_HANDLE) l_Adapter,
2396
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2397
ETHERNET_HEADER_SIZE,
2398
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer + ETHERNET_HEADER_SIZE,
2399
l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE,
2400
l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE);
2402
NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle);
2404
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2406
__except (EXCEPTION_EXECUTE_HANDLER)
2408
DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n",
2411
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2412
p_IRP->IoStatus.Information = 0;
2415
else if (l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE))
2419
ETH_HEADER * p_UserToTap = &l_Adapter->m_UserToTap;
2421
// for IPv6, need to use ethernet header with IPv6 proto
2422
if ( IPH_GET_VER( ((IPHDR*) p_IRP->AssociatedIrp.SystemBuffer)->version_len) == 6 )
2424
p_UserToTap = &l_Adapter->m_UserToTap_IPv6;
2427
p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length;
2429
DUMP_PACKET2 ("IRP_MJ_WRITE P2P",
2431
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2432
l_IrpSp->Parameters.Write.Length);
2434
//=====================================================
2435
// If IPv4 packet, check whether or not packet
2437
//=====================================================
2438
#if PACKET_TRUNCATION_CHECK
2439
IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2440
l_IrpSp->Parameters.Write.Length,
2443
&l_Adapter->m_RxTrunc);
2446
NdisMEthIndicateReceive
2447
(l_Adapter->m_MiniportAdapterHandle,
2448
(NDIS_HANDLE) l_Adapter,
2449
(unsigned char *) p_UserToTap,
2450
sizeof (ETH_HEADER),
2451
(unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
2452
l_IrpSp->Parameters.Write.Length,
2453
l_IrpSp->Parameters.Write.Length);
2455
NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle);
2457
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2459
__except (EXCEPTION_EXECUTE_HANDLER)
2461
DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n",
2464
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2465
p_IRP->IoStatus.Information = 0;
2470
DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",
2472
l_IrpSp->Parameters.Write.Length));
2474
p_IRP->IoStatus.Information = 0; // ETHERNET_HEADER_SIZE;
2475
p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
2478
if (l_Status == STATUS_SUCCESS)
2479
INCREMENT_STAT (l_Adapter->m_Rx);
2481
INCREMENT_STAT (l_Adapter->m_RxErr);
2483
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2487
//--------------------------------------------------------------
2488
// User mode thread has called CreateFile() on the tap device
2489
//--------------------------------------------------------------
2492
BOOLEAN succeeded = FALSE;
2493
BOOLEAN mutex_succeeded;
2496
(("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
2497
NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
2498
TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens));
2500
ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
2501
if (mutex_succeeded)
2503
if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens)
2505
ResetTapAdapterState (l_Adapter);
2506
l_Adapter->m_Extension.m_TapOpens = 1;
2512
INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens);
2513
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2514
p_IRP->IoStatus.Information = 0;
2518
DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
2519
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2521
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2522
p_IRP->IoStatus.Information = 0;
2525
RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
2529
DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
2530
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2532
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2533
p_IRP->IoStatus.Information = 0;
2536
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2540
//-----------------------------------------------------------
2541
// User mode thread called CloseHandle() on the tap device
2542
//-----------------------------------------------------------
2545
BOOLEAN mutex_succeeded;
2547
DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n",
2548
NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
2549
TAP_DRIVER_MINOR_VERSION));
2551
ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
2552
if (mutex_succeeded)
2554
l_Adapter->m_Extension.m_TapOpens = 0;
2555
ResetTapAdapterState (l_Adapter);
2556
FlushQueues (&l_Adapter->m_Extension);
2557
SetMediaStatus (l_Adapter, FALSE);
2558
RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
2562
DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
2563
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2565
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2566
p_IRP->IoStatus.Information = 0;
2569
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2573
//------------------
2575
//------------------
2579
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2580
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2588
//=============================================================
2589
// CompleteIRP is normally called with an adapter -> userspace
2590
// network packet and an IRP (Pending I/O request) from userspace.
2592
// The IRP will normally represent a queued overlapped read
2593
// operation from userspace that is in a wait state.
2595
// Use the ethernet packet to satisfy the IRP.
2596
//=============================================================
2599
CompleteIRP (IN PIRP p_IRP,
2600
IN TapPacketPointer p_PacketBuffer,
2601
IN CCHAR PriorityBoost)
2603
NTSTATUS l_Status = STATUS_UNSUCCESSFUL;
2609
MYASSERT (p_PacketBuffer);
2611
IoSetCancelRoutine (p_IRP, NULL); // Disable cancel routine
2613
//-------------------------------------------
2614
// While p_PacketBuffer always contains a
2615
// full ethernet packet, including the
2616
// ethernet header, in point-to-point mode,
2617
// we only want to return the IPv4
2619
//-------------------------------------------
2621
if (p_PacketBuffer->m_SizeFlags & TP_TUN)
2623
offset = ETHERNET_HEADER_SIZE;
2624
len = (int) (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE;
2629
len = (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK);
2632
if (len < 0 || (int) p_IRP->IoStatus.Information < len)
2634
p_IRP->IoStatus.Information = 0;
2635
p_IRP->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
2640
p_IRP->IoStatus.Information = len;
2641
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2645
NdisMoveMemory (p_IRP->AssociatedIrp.SystemBuffer,
2646
p_PacketBuffer->m_Data + offset,
2649
__except (EXCEPTION_EXECUTE_HANDLER)
2652
p_IRP->IoStatus.Status = STATUS_UNSUCCESSFUL;
2653
p_IRP->IoStatus.Information = 0;
2659
NdisFreeMemory (p_PacketBuffer,
2660
TAP_PACKET_SIZE (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK),
2663
__except (EXCEPTION_EXECUTE_HANDLER)
2667
if (l_Status == STATUS_SUCCESS)
2669
IoCompleteRequest (p_IRP, PriorityBoost);
2672
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2677
//==============================================
2678
// IRPs get cancelled for a number of reasons.
2680
// The TAP device could be closed by userspace
2681
// when there are still pending read operations.
2683
// The user could disable the TAP adapter in the
2684
// network connections control panel, while the
2685
// device is still open by a process.
2686
//==============================================
2688
CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject,
2691
TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
2692
CancelIRP (l_Adapter ? &l_Adapter->m_Extension : NULL, p_IRP, TRUE);
2696
CancelIRP (TapExtensionPointer p_Extension,
2700
BOOLEAN exists = FALSE;
2706
NdisAcquireSpinLock (&p_Extension->m_QueueLock);
2707
exists = (QueueExtract (p_Extension->m_IrpQueue, p_IRP) == p_IRP);
2708
NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2715
IoSetCancelRoutine (p_IRP, NULL);
2716
p_IRP->IoStatus.Status = STATUS_CANCELLED;
2717
p_IRP->IoStatus.Information = 0;
2721
IoReleaseCancelSpinLock (p_IRP->CancelIrql);
2724
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2727
//===========================================
2728
// Exhaust packet, IRP, and injection queues.
2729
//===========================================
2731
FlushQueues (TapExtensionPointer p_Extension)
2734
TapPacketPointer l_PacketBuffer;
2735
InjectPacketPointer l_InjectBuffer;
2736
int n_IRP=0, n_Packet=0, n_Inject=0;
2738
MYASSERT (p_Extension);
2739
MYASSERT (p_Extension->m_TapDevice);
2743
NdisAcquireSpinLock (&p_Extension->m_QueueLock);
2744
l_IRP = QueuePop (p_Extension->m_IrpQueue);
2745
NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2749
CancelIRP (NULL, l_IRP, FALSE);
2757
NdisAcquireSpinLock (&p_Extension->m_QueueLock);
2758
l_PacketBuffer = QueuePop (p_Extension->m_PacketQueue);
2759
NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2763
MemFree (l_PacketBuffer, TAP_PACKET_SIZE (l_PacketBuffer->m_SizeFlags & TP_SIZE_MASK));
2771
NdisAcquireSpinLock (&p_Extension->m_InjectLock);
2772
l_InjectBuffer = QueuePop (p_Extension->m_InjectQueue);
2773
NdisReleaseSpinLock (&p_Extension->m_InjectLock);
2777
INJECT_PACKET_FREE(l_InjectBuffer);
2784
"[%s] [TAP] FlushQueues n_IRP=[%d,%d,%d] n_Packet=[%d,%d,%d] n_Inject=[%d,%d,%d]\n",
2785
p_Extension->m_TapName,
2787
p_Extension->m_IrpQueue->max_size,
2790
p_Extension->m_PacketQueue->max_size,
2793
p_Extension->m_InjectQueue->max_size,
2798
//===================================================
2799
// Tell Windows whether the TAP device should be
2800
// considered "connected" or "disconnected".
2801
//===================================================
2803
SetMediaStatus (TapAdapterPointer p_Adapter, BOOLEAN state)
2805
if (p_Adapter->m_MediaState != state && !p_Adapter->m_MediaStateAlwaysConnected)
2808
NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle,
2809
NDIS_STATUS_MEDIA_CONNECT, NULL, 0);
2811
NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle,
2812
NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0);
2814
NdisMIndicateStatusComplete (p_Adapter->m_MiniportAdapterHandle);
2815
p_Adapter->m_MediaState = state;
2820
//======================================================
2821
// If DHCP mode is used together with tun
2822
// mode, consider the fact that the P2P remote subnet
2823
// might enclose the DHCP masq server address.
2824
//======================================================
2826
CheckIfDhcpAndTunMode (TapAdapterPointer p_Adapter)
2828
if (p_Adapter->m_tun && p_Adapter->m_dhcp_enabled)
2830
if ((p_Adapter->m_dhcp_server_ip & p_Adapter->m_remoteNetmask) == p_Adapter->m_remoteNetwork)
2832
COPY_MAC (p_Adapter->m_dhcp_server_mac, p_Adapter->m_TapToUser.dest);
2833
p_Adapter->m_dhcp_server_arp = FALSE;
2838
//===================================================
2839
// Generate an ARP reply message for specific kinds
2841
//===================================================
2843
ProcessARP (TapAdapterPointer p_Adapter,
2844
const PARP_PACKET src,
2845
const IPADDR adapter_ip,
2846
const IPADDR ip_network,
2847
const IPADDR ip_netmask,
2850
//-----------------------------------------------
2851
// Is this the kind of packet we are looking for?
2852
//-----------------------------------------------
2853
if (src->m_Proto == htons (ETH_P_ARP)
2854
&& MAC_EQUAL (src->m_MAC_Source, p_Adapter->m_MAC)
2855
&& MAC_EQUAL (src->m_ARP_MAC_Source, p_Adapter->m_MAC)
2856
&& MAC_EQUAL (src->m_MAC_Destination, p_Adapter->m_MAC_Broadcast)
2857
&& src->m_ARP_Operation == htons (ARP_REQUEST)
2858
&& src->m_MAC_AddressType == htons (MAC_ADDR_TYPE)
2859
&& src->m_MAC_AddressSize == sizeof (MACADDR)
2860
&& src->m_PROTO_AddressType == htons (ETH_P_IP)
2861
&& src->m_PROTO_AddressSize == sizeof (IPADDR)
2862
&& src->m_ARP_IP_Source == adapter_ip
2863
&& (src->m_ARP_IP_Destination & ip_netmask) == ip_network
2864
&& src->m_ARP_IP_Destination != adapter_ip)
2866
ARP_PACKET *arp = (ARP_PACKET *) MemAlloc (sizeof (ARP_PACKET), TRUE);
2869
//----------------------------------------------
2870
// Initialize ARP reply fields
2871
//----------------------------------------------
2872
arp->m_Proto = htons (ETH_P_ARP);
2873
arp->m_MAC_AddressType = htons (MAC_ADDR_TYPE);
2874
arp->m_PROTO_AddressType = htons (ETH_P_IP);
2875
arp->m_MAC_AddressSize = sizeof (MACADDR);
2876
arp->m_PROTO_AddressSize = sizeof (IPADDR);
2877
arp->m_ARP_Operation = htons (ARP_REPLY);
2879
//----------------------------------------------
2881
//----------------------------------------------
2882
COPY_MAC (arp->m_MAC_Source, mac);
2883
COPY_MAC (arp->m_MAC_Destination, p_Adapter->m_MAC);
2884
COPY_MAC (arp->m_ARP_MAC_Source, mac);
2885
COPY_MAC (arp->m_ARP_MAC_Destination, p_Adapter->m_MAC);
2886
arp->m_ARP_IP_Source = src->m_ARP_IP_Destination;
2887
arp->m_ARP_IP_Destination = adapter_ip;
2889
DUMP_PACKET ("ProcessARP",
2890
(unsigned char *) arp,
2891
sizeof (ARP_PACKET));
2893
InjectPacketDeferred (p_Adapter, (UCHAR *) arp, sizeof (ARP_PACKET));
2895
MemFree (arp, sizeof (ARP_PACKET));
2904
//===============================================================
2905
// Used in cases where internally generated packets such as
2906
// ARP or DHCP replies must be returned to the kernel, to be
2907
// seen as an incoming packet "arriving" on the interface.
2908
//===============================================================
2910
// Defer packet injection till IRQL < DISPATCH_LEVEL
2912
InjectPacketDeferred (TapAdapterPointer p_Adapter,
2914
const unsigned int len)
2916
InjectPacketPointer l_InjectBuffer;
2919
if (NdisAllocateMemoryWithTag (&l_InjectBuffer,
2920
INJECT_PACKET_SIZE (len),
2921
'IPAT') == NDIS_STATUS_SUCCESS)
2923
l_InjectBuffer->m_Size = len;
2924
NdisMoveMemory (l_InjectBuffer->m_Data, packet, len);
2925
NdisAcquireSpinLock (&p_Adapter->m_Extension.m_InjectLock);
2926
result = QueuePush (p_Adapter->m_Extension.m_InjectQueue, l_InjectBuffer);
2927
NdisReleaseSpinLock (&p_Adapter->m_Extension.m_InjectLock);
2929
KeInsertQueueDpc (&p_Adapter->m_Extension.m_InjectDpc, p_Adapter, NULL);
2931
INJECT_PACKET_FREE(l_InjectBuffer);
2935
// Handle the injection of previously deferred packets
2937
InjectPacketDpc(KDPC *Dpc,
2938
PVOID DeferredContext,
2939
PVOID SystemArgument1,
2940
PVOID SystemArgument2)
2942
InjectPacketPointer l_InjectBuffer;
2943
TapAdapterPointer l_Adapter = (TapAdapterPointer)SystemArgument1;
2946
NdisAcquireSpinLock (&l_Adapter->m_Extension.m_InjectLock);
2947
l_InjectBuffer = QueuePop (l_Adapter->m_Extension.m_InjectQueue);
2948
NdisReleaseSpinLock (&l_Adapter->m_Extension.m_InjectLock);
2951
InjectPacketNow(l_Adapter, l_InjectBuffer->m_Data, l_InjectBuffer->m_Size);
2952
INJECT_PACKET_FREE(l_InjectBuffer);
2959
// Do packet injection now
2961
InjectPacketNow (TapAdapterPointer p_Adapter,
2963
const unsigned int len)
2965
MYASSERT (len >= ETHERNET_HEADER_SIZE);
2969
//------------------------------------------------------------
2970
// NdisMEthIndicateReceive and NdisMEthIndicateReceiveComplete
2971
// could potentially be called reentrantly both here and in
2972
// TapDeviceHook/IRP_MJ_WRITE.
2974
// The DDK docs imply that this is okay.
2976
// Note that reentrant behavior could only occur if the
2977
// non-deferred version of InjectPacket is used.
2978
//------------------------------------------------------------
2979
NdisMEthIndicateReceive
2980
(p_Adapter->m_MiniportAdapterHandle,
2981
(NDIS_HANDLE) p_Adapter,
2983
ETHERNET_HEADER_SIZE,
2984
packet + ETHERNET_HEADER_SIZE,
2985
len - ETHERNET_HEADER_SIZE,
2986
len - ETHERNET_HEADER_SIZE);
2988
NdisMEthIndicateReceiveComplete (p_Adapter->m_MiniportAdapterHandle);
2990
__except (EXCEPTION_EXECUTE_HANDLER)
2992
DEBUGP (("[%s] NdisMEthIndicateReceive failed in InjectPacketNow\n",
2998
//===================================================================
2999
// Go back to default TAP mode from Point-To-Point mode.
3000
// Also reset (i.e. disable) DHCP Masq mode.
3001
//===================================================================
3002
VOID ResetTapAdapterState (TapAdapterPointer p_Adapter)
3005
p_Adapter->m_tun = FALSE;
3006
p_Adapter->m_localIP = 0;
3007
p_Adapter->m_remoteNetwork = 0;
3008
p_Adapter->m_remoteNetmask = 0;
3009
NdisZeroMemory (&p_Adapter->m_TapToUser, sizeof (p_Adapter->m_TapToUser));
3010
NdisZeroMemory (&p_Adapter->m_UserToTap, sizeof (p_Adapter->m_UserToTap));
3011
NdisZeroMemory (&p_Adapter->m_UserToTap_IPv6, sizeof (p_Adapter->m_UserToTap_IPv6));
3014
p_Adapter->m_dhcp_enabled = FALSE;
3015
p_Adapter->m_dhcp_server_arp = FALSE;
3016
p_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
3017
p_Adapter->m_dhcp_addr = 0;
3018
p_Adapter->m_dhcp_netmask = 0;
3019
p_Adapter->m_dhcp_server_ip = 0;
3020
p_Adapter->m_dhcp_lease_time = 0;
3021
p_Adapter->m_dhcp_received_discover = FALSE;
3022
p_Adapter->m_dhcp_bad_requests = 0;
3023
NdisZeroMemory (p_Adapter->m_dhcp_server_mac, sizeof (MACADDR));
3028
//===================================================================
3029
// Set TAP device handle to be accessible without admin privileges.
3030
//===================================================================
3031
VOID AllowNonAdmin (TapExtensionPointer p_Extension)
3034
SECURITY_DESCRIPTOR sd;
3035
OBJECT_ATTRIBUTES oa;
3036
IO_STATUS_BLOCK isb;
3039
NdisZeroMemory (&sd, sizeof (sd));
3040
NdisZeroMemory (&oa, sizeof (oa));
3041
NdisZeroMemory (&isb, sizeof (isb));
3043
if (!p_Extension->m_CreatedUnicodeLinkName)
3045
DEBUGP (("[TAP] AllowNonAdmin: UnicodeLinkName is uninitialized\n"));
3050
stat = RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
3051
if (stat != STATUS_SUCCESS)
3053
DEBUGP (("[TAP] AllowNonAdmin: RtlCreateSecurityDescriptor failed\n"));
3058
InitializeObjectAttributes (
3060
&p_Extension->m_UnicodeLinkName,
3074
if (stat != STATUS_SUCCESS)
3076
DEBUGP (("[TAP] AllowNonAdmin: ZwOpenFile failed, status=0x%08x\n", (unsigned int)stat));
3081
stat = ZwSetSecurityObject (hand, DACL_SECURITY_INFORMATION, &sd);
3082
if (stat != STATUS_SUCCESS)
3084
DEBUGP (("[TAP] AllowNonAdmin: ZwSetSecurityObject failed\n"));
3089
stat = ZwClose (hand);
3090
if (stat != STATUS_SUCCESS)
3092
DEBUGP (("[TAP] AllowNonAdmin: ZwClose failed\n"));
3097
DEBUGP (("[TAP] AllowNonAdmin: SUCCEEDED\n"));
3102
#if PACKET_TRUNCATION_CHECK
3105
IPv4PacketSizeVerify (const UCHAR *data, ULONG length, BOOLEAN tun, const char *prefix, LONG *counter)
3112
ip = (IPHDR *) data;
3116
if (length >= sizeof (ETH_HEADER))
3118
const ETH_HEADER *eth = (ETH_HEADER *) data;
3120
if (eth->proto != htons (ETH_P_IP))
3123
ip = (IPHDR *) (data + sizeof (ETH_HEADER));
3124
len -= sizeof (ETH_HEADER);
3130
if (len >= sizeof (IPHDR))
3132
const int totlen = ntohs (ip->tot_len);
3134
DEBUGP (("[TAP] IPv4PacketSizeVerify %s len=%d totlen=%d\n", prefix, len, totlen));
3143
//======================================================================
3145
//======================================================================