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-2008 Telethra, 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
);
696 if (p_Extension
->m_CreatedUnicodeLinkName
)
697 RtlFreeUnicodeString (&p_Extension
->m_UnicodeLinkName
);
699 //==========================================================
700 // According to DDK docs, the device is not actually deleted
701 // until its reference count falls to zero. That means we
702 // still need to gracefully fail TapDeviceHook requests
703 // after this point, otherwise ugly things would happen if
704 // the device was disabled (e.g. in the network connections
705 // control panel) while a userspace app still held an open
706 // file handle to it.
707 //==========================================================
709 if (p_Extension
->m_TapDevice
)
712 status
= (NdisMDeregisterDevice (p_Extension
->m_TapDeviceHandle
)
713 == NDIS_STATUS_SUCCESS
);
714 DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status
));
717 if (p_Extension
->m_TapName
)
718 MemFree (p_Extension
->m_TapName
, NAME_BUFFER_SIZE
);
720 if (p_Extension
->m_AllocatedSpinlocks
)
721 NdisFreeSpinLock (&p_Extension
->m_QueueLock
);
724 //========================================================================
725 // Tap Device Initialization
726 //========================================================================
729 CreateTapDevice (TapExtensionPointer p_Extension
, const char *p_Name
)
731 # define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1))
732 PDRIVER_DISPATCH
*l_Dispatch
= NULL
;
733 ANSI_STRING l_TapString
, l_LinkString
;
734 UNICODE_STRING l_TapUnicode
;
735 BOOLEAN l_FreeTapUnicode
= FALSE
;
736 NTSTATUS l_Status
, l_Return
= NDIS_STATUS_SUCCESS
;
737 const char *l_UsableName
;
739 DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
740 TAP_DRIVER_MAJOR_VERSION
,
741 TAP_DRIVER_MINOR_VERSION
,
744 NdisZeroMemory (p_Extension
, sizeof (TapExtension
));
746 INIT_MUTEX (&p_Extension
->m_OpenCloseMutex
);
748 l_LinkString
.Buffer
= NULL
;
749 l_TapString
.Buffer
= NULL
;
751 l_TapString
.MaximumLength
= l_LinkString
.MaximumLength
= NAME_BUFFER_SIZE
;
753 //=======================================
754 // Set TAP device entry points
755 //=======================================
757 if ((l_Dispatch
= MemAlloc (SIZEOF_DISPATCH
, TRUE
)) == NULL
)
759 DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name
));
760 l_Return
= NDIS_STATUS_RESOURCES
;
764 l_Dispatch
[IRP_MJ_DEVICE_CONTROL
] = TapDeviceHook
;
765 l_Dispatch
[IRP_MJ_READ
] = TapDeviceHook
;
766 l_Dispatch
[IRP_MJ_WRITE
] = TapDeviceHook
;
767 l_Dispatch
[IRP_MJ_CREATE
] = TapDeviceHook
;
768 l_Dispatch
[IRP_MJ_CLOSE
] = TapDeviceHook
;
770 //==================================
771 // Find the beginning of the GUID
772 //==================================
773 l_UsableName
= p_Name
;
774 while (*l_UsableName
!= '{')
776 if (*l_UsableName
== '\0')
778 DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name
));
779 l_Return
= NDIS_STATUS_RESOURCES
;
785 //==================================
786 // Allocate pool for TAP device name
787 //==================================
789 if ((p_Extension
->m_TapName
= l_TapString
.Buffer
=
790 MemAlloc (NAME_BUFFER_SIZE
, TRUE
)) == NULL
)
792 DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name
));
793 l_Return
= NDIS_STATUS_RESOURCES
;
797 //================================================
798 // Allocate pool for TAP symbolic link name buffer
799 //================================================
801 if ((l_LinkString
.Buffer
=
802 MemAlloc (NAME_BUFFER_SIZE
, TRUE
)) == NULL
)
804 DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n",
806 l_Return
= NDIS_STATUS_RESOURCES
;
810 //=======================================================
811 // Set TAP device name
812 //=======================================================
814 l_Status
= RtlStringCchPrintfExA
816 l_TapString
.MaximumLength
,
819 STRSAFE_FILL_BEHIND_NULL
| STRSAFE_IGNORE_NULLS
,
825 if (l_Status
!= STATUS_SUCCESS
)
827 DEBUGP (("[%s] couldn't format TAP device name\n",
829 l_Return
= NDIS_STATUS_RESOURCES
;
832 l_TapString
.Length
= (USHORT
) strlen (l_TapString
.Buffer
);
834 DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString
.Buffer
));
836 //=======================================================
838 //=======================================================
840 l_Status
= RtlStringCchPrintfExA
841 (l_LinkString
.Buffer
,
842 l_LinkString
.MaximumLength
,
845 STRSAFE_FILL_BEHIND_NULL
| STRSAFE_IGNORE_NULLS
,
851 if (l_Status
!= STATUS_SUCCESS
)
853 DEBUGP (("[%s] couldn't format TAP device symbolic link\n",
855 l_Return
= NDIS_STATUS_RESOURCES
;
858 l_LinkString
.Length
= (USHORT
) strlen (l_LinkString
.Buffer
);
860 DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString
.Buffer
));
862 //==================================================
863 // Convert strings to unicode
864 //==================================================
865 if (RtlAnsiStringToUnicodeString (&l_TapUnicode
, &l_TapString
, TRUE
) !=
868 DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n",
870 l_Return
= NDIS_STATUS_RESOURCES
;
873 l_FreeTapUnicode
= TRUE
;
875 if (RtlAnsiStringToUnicodeString
876 (&p_Extension
->m_UnicodeLinkName
, &l_LinkString
, TRUE
)
880 (("[%s] Couldn't allocate unicode string for symbolic link name\n",
882 l_Return
= NDIS_STATUS_RESOURCES
;
885 p_Extension
->m_CreatedUnicodeLinkName
= TRUE
;
887 //==================================================
888 // Create new TAP device with symbolic
889 // link and associate with adapter.
890 //==================================================
892 l_Status
= NdisMRegisterDevice
893 (g_NdisWrapperHandle
,
895 &p_Extension
->m_UnicodeLinkName
,
897 &p_Extension
->m_TapDevice
,
898 &p_Extension
->m_TapDeviceHandle
901 if (l_Status
!= STATUS_SUCCESS
)
903 DEBUGP (("[%s] couldn't be created\n", p_Name
));
904 l_Return
= NDIS_STATUS_RESOURCES
;
908 /* Set TAP device flags */
909 p_Extension
->m_TapDevice
->Flags
|= DO_DIRECT_IO
;
911 //========================================================
912 // Initialize Packet and IRP queues.
914 // The packet queue is used to buffer data which has been
915 // "transmitted" by the virtual NIC, before user space
916 // has had a chance to read it.
918 // The IRP queue is used to buffer pending I/O requests
919 // from userspace, i.e. read requests on the TAP device
920 // waiting for the system to "transmit" something through
923 // Basically, packets in the packet queue are used
924 // to satisfy IRP requests in the IRP queue.
926 // QueueLock is used to lock the packet queue used
927 // for the TAP-Win32 NIC -> User Space packet flow direction.
929 // All accesses to packet or IRP queues should be
930 // bracketed by the QueueLock spinlock,
931 // in order to be SMP-safe.
932 //========================================================
934 NdisAllocateSpinLock (&p_Extension
->m_QueueLock
);
935 p_Extension
->m_AllocatedSpinlocks
= TRUE
;
937 p_Extension
->m_PacketQueue
= QueueInit (PACKET_QUEUE_SIZE
);
938 p_Extension
->m_IrpQueue
= QueueInit (IRP_QUEUE_SIZE
);
940 if (!p_Extension
->m_PacketQueue
941 || !p_Extension
->m_IrpQueue
)
943 DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name
));
944 l_Return
= NDIS_STATUS_RESOURCES
;
948 //========================
949 // Finalize initialization
950 //========================
952 p_Extension
->m_TapIsRunning
= TRUE
;
954 DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name
,
955 p_Extension
->m_TapName
));
958 if (l_FreeTapUnicode
)
959 RtlFreeUnicodeString (&l_TapUnicode
);
960 if (l_LinkString
.Buffer
)
961 MemFree (l_LinkString
.Buffer
, NAME_BUFFER_SIZE
);
963 MemFree (l_Dispatch
, SIZEOF_DISPATCH
);
965 if (l_Return
!= NDIS_STATUS_SUCCESS
)
966 TapDeviceFreeResources (p_Extension
);
970 #undef SIZEOF_DISPATCH
972 //========================================================
974 //========================================================
976 AdapterReset (OUT PBOOLEAN p_AddressingReset
, IN NDIS_HANDLE p_AdapterContext
)
978 TapAdapterPointer l_Adapter
= (TapAdapterPointer
) p_AdapterContext
;
979 DEBUGP (("[%s] is resetting\n", NAME (l_Adapter
)));
980 return NDIS_STATUS_SUCCESS
;
983 NDIS_STATUS AdapterReceive
984 (OUT PNDIS_PACKET p_Packet
,
985 OUT PUINT p_Transferred
,
986 IN NDIS_HANDLE p_AdapterContext
,
987 IN NDIS_HANDLE p_ReceiveContext
,
989 IN UINT p_ToTransfer
)
991 return NDIS_STATUS_SUCCESS
;
994 //==============================================================
995 // Adapter Option Query/Modification
996 //==============================================================
997 NDIS_STATUS AdapterQuery
998 (IN NDIS_HANDLE p_AdapterContext
,
1001 IN ULONG p_BufferLength
,
1002 OUT PULONG p_BytesWritten
, OUT PULONG p_BytesNeeded
)
1004 TapAdapterPointer l_Adapter
= (TapAdapterPointer
) p_AdapterContext
;
1005 TapAdapterQuery l_Query
, *l_QueryPtr
= &l_Query
;
1006 NDIS_STATUS l_Status
= NDIS_STATUS_SUCCESS
;
1007 UINT l_QueryLength
= 4;
1008 BOOLEAN lock_succeeded
;
1010 NdisZeroMemory (&l_Query
, sizeof (l_Query
));
1014 //===================================================================
1015 // Vendor & Driver version Info
1016 //===================================================================
1017 case OID_GEN_VENDOR_DESCRIPTION
:
1018 l_QueryPtr
= (TapAdapterQueryPointer
) PRODUCT_STRING
;
1019 l_QueryLength
= strlen (PRODUCT_STRING
) + 1;
1022 case OID_GEN_VENDOR_ID
:
1023 l_Query
.m_Long
= 0xffffff;
1026 case OID_GEN_DRIVER_VERSION
:
1028 (((USHORT
) TAP_NDIS_MAJOR_VERSION
) << 8 | (USHORT
)
1029 TAP_NDIS_MINOR_VERSION
);
1030 l_QueryLength
= sizeof (unsigned short);
1033 case OID_GEN_VENDOR_DRIVER_VERSION
:
1035 (((USHORT
) TAP_DRIVER_MAJOR_VERSION
) << 8 | (USHORT
)
1036 TAP_DRIVER_MINOR_VERSION
);
1039 //=================================================================
1041 //=================================================================
1042 case OID_GEN_RCV_NO_BUFFER
:
1046 case OID_802_3_RCV_ERROR_ALIGNMENT
:
1050 case OID_802_3_XMIT_ONE_COLLISION
:
1054 case OID_802_3_XMIT_MORE_COLLISIONS
:
1058 case OID_GEN_XMIT_OK
:
1059 l_Query
.m_Long
= l_Adapter
->m_Tx
;
1062 case OID_GEN_RCV_OK
:
1063 l_Query
.m_Long
= l_Adapter
->m_Rx
;
1066 case OID_GEN_XMIT_ERROR
:
1067 l_Query
.m_Long
= l_Adapter
->m_TxErr
;
1070 case OID_GEN_RCV_ERROR
:
1071 l_Query
.m_Long
= l_Adapter
->m_RxErr
;
1074 //===================================================================
1075 // Device & Protocol Options
1076 //===================================================================
1077 case OID_GEN_SUPPORTED_LIST
:
1078 l_QueryPtr
= (TapAdapterQueryPointer
) g_SupportedOIDList
;
1079 l_QueryLength
= sizeof (g_SupportedOIDList
);
1082 case OID_GEN_MAC_OPTIONS
:
1083 // This MUST be here !!!
1084 l_Query
.m_Long
= (NDIS_MAC_OPTION_RECEIVE_SERIALIZED
1085 | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
1086 | NDIS_MAC_OPTION_NO_LOOPBACK
1087 | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
);
1091 case OID_GEN_CURRENT_PACKET_FILTER
:
1093 (NDIS_PACKET_TYPE_ALL_LOCAL
|
1094 NDIS_PACKET_TYPE_BROADCAST
|
1095 NDIS_PACKET_TYPE_DIRECTED
| NDIS_PACKET_TYPE_ALL_FUNCTIONAL
);
1099 case OID_GEN_PROTOCOL_OPTIONS
:
1103 //==================================================================
1105 //==================================================================
1106 case OID_GEN_MEDIA_CONNECT_STATUS
:
1107 l_Query
.m_Long
= l_Adapter
->m_MediaState
1108 ? NdisMediaStateConnected
: NdisMediaStateDisconnected
;
1111 case OID_GEN_HARDWARE_STATUS
:
1112 l_Query
.m_HardwareStatus
= NdisHardwareStatusReady
;
1113 l_QueryLength
= sizeof (NDIS_HARDWARE_STATUS
);
1116 case OID_GEN_MEDIA_SUPPORTED
:
1117 case OID_GEN_MEDIA_IN_USE
:
1118 l_Query
.m_Medium
= l_Adapter
->m_Medium
;
1119 l_QueryLength
= sizeof (NDIS_MEDIUM
);
1122 case OID_GEN_PHYSICAL_MEDIUM
:
1123 l_Query
.m_PhysicalMedium
= NdisPhysicalMediumUnspecified
;
1124 l_QueryLength
= sizeof (NDIS_PHYSICAL_MEDIUM
);
1127 case OID_GEN_LINK_SPEED
:
1128 l_Query
.m_Long
= 100000; // rate / 100 bps
1131 case OID_802_3_PERMANENT_ADDRESS
:
1132 case OID_802_3_CURRENT_ADDRESS
:
1133 COPY_MAC (l_Query
.m_MacAddress
, l_Adapter
->m_MAC
);
1134 l_QueryLength
= sizeof (MACADDR
);
1137 //==================================================================
1139 //==================================================================
1141 case OID_GEN_MAXIMUM_SEND_PACKETS
:
1145 case OID_802_3_MAXIMUM_LIST_SIZE
:
1146 l_Query
.m_Long
= NIC_MAX_MCAST_LIST
;
1149 case OID_GEN_CURRENT_LOOKAHEAD
:
1150 l_Query
.m_Long
= l_Adapter
->m_Lookahead
;
1153 case OID_GEN_MAXIMUM_LOOKAHEAD
:
1154 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
1155 case OID_GEN_RECEIVE_BUFFER_SPACE
:
1156 case OID_GEN_RECEIVE_BLOCK_SIZE
:
1157 l_Query
.m_Long
= DEFAULT_PACKET_LOOKAHEAD
;
1160 case OID_GEN_MAXIMUM_FRAME_SIZE
:
1161 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
1162 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
1163 l_Query
.m_Long
= l_Adapter
->m_MTU
;
1166 case OID_PNP_CAPABILITIES
:
1169 PNDIS_PNP_CAPABILITIES pPNPCapabilities
;
1170 PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct
;
1172 if (p_BufferLength
>= sizeof (NDIS_PNP_CAPABILITIES
))
1174 pPNPCapabilities
= (PNDIS_PNP_CAPABILITIES
) (p_Buffer
);
1177 // Setting up the buffer to be returned
1178 // to the Protocol above the Passthru miniport
1180 pPMstruct
= &pPNPCapabilities
->WakeUpCapabilities
;
1181 pPMstruct
->MinMagicPacketWakeUp
= NdisDeviceStateUnspecified
;
1182 pPMstruct
->MinPatternWakeUp
= NdisDeviceStateUnspecified
;
1183 pPMstruct
->MinLinkChangeWakeUp
= NdisDeviceStateUnspecified
;
1185 l_QueryLength
= sizeof (NDIS_PNP_CAPABILITIES
);
1189 case OID_PNP_QUERY_POWER
:
1192 // Required OIDs that we don't support
1194 case OID_GEN_SUPPORTED_GUIDS
:
1195 case OID_GEN_MEDIA_CAPABILITIES
:
1196 case OID_TCP_TASK_OFFLOAD
:
1197 case OID_FFP_SUPPORT
:
1198 l_Status
= NDIS_STATUS_INVALID_OID
;
1201 // Optional stats OIDs
1203 case OID_GEN_DIRECTED_BYTES_XMIT
:
1204 case OID_GEN_DIRECTED_FRAMES_XMIT
:
1205 case OID_GEN_MULTICAST_BYTES_XMIT
:
1206 case OID_GEN_MULTICAST_FRAMES_XMIT
:
1207 case OID_GEN_BROADCAST_BYTES_XMIT
:
1208 case OID_GEN_BROADCAST_FRAMES_XMIT
:
1209 case OID_GEN_DIRECTED_BYTES_RCV
:
1210 case OID_GEN_DIRECTED_FRAMES_RCV
:
1211 case OID_GEN_MULTICAST_BYTES_RCV
:
1212 case OID_GEN_MULTICAST_FRAMES_RCV
:
1213 case OID_GEN_BROADCAST_BYTES_RCV
:
1214 case OID_GEN_BROADCAST_FRAMES_RCV
:
1215 l_Status
= NDIS_STATUS_INVALID_OID
;
1218 //===================================================================
1220 //===================================================================
1222 DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter
), p_OID
));
1223 l_Status
= NDIS_STATUS_INVALID_OID
;
1227 if (l_Status
!= NDIS_STATUS_SUCCESS
)
1229 else if (l_QueryLength
> p_BufferLength
)
1231 l_Status
= NDIS_STATUS_INVALID_LENGTH
;
1232 *p_BytesNeeded
= l_QueryLength
;
1235 NdisMoveMemory (p_Buffer
, (PVOID
) l_QueryPtr
,
1236 (*p_BytesWritten
= l_QueryLength
));
1241 NDIS_STATUS AdapterModify
1242 (IN NDIS_HANDLE p_AdapterContext
,
1245 IN ULONG p_BufferLength
,
1246 OUT PULONG p_BytesRead
,
1247 OUT PULONG p_BytesNeeded
)
1249 TapAdapterQueryPointer l_Query
= (TapAdapterQueryPointer
) p_Buffer
;
1250 TapAdapterPointer l_Adapter
= (TapAdapterPointer
) p_AdapterContext
;
1251 NDIS_STATUS l_Status
= NDIS_STATUS_INVALID_OID
;
1256 //==================================================================
1258 //==================================================================
1259 case OID_802_3_MULTICAST_LIST
:
1260 DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n",
1263 *p_BytesNeeded
= sizeof (ETH_ADDR
);
1264 *p_BytesRead
= p_BufferLength
;
1266 if (p_BufferLength
% sizeof (ETH_ADDR
))
1267 l_Status
= NDIS_STATUS_INVALID_LENGTH
;
1268 else if (p_BufferLength
> sizeof (MC_LIST
))
1270 l_Status
= NDIS_STATUS_MULTICAST_FULL
;
1271 *p_BytesNeeded
= sizeof (MC_LIST
);
1275 NdisAcquireSpinLock (&l_Adapter
->m_MCLock
);
1277 NdisZeroMemory(&l_Adapter
->m_MCList
, sizeof (MC_LIST
));
1279 NdisMoveMemory(&l_Adapter
->m_MCList
,
1283 l_Adapter
->m_MCListSize
= p_BufferLength
/ sizeof (ETH_ADDR
);
1285 NdisReleaseSpinLock (&l_Adapter
->m_MCLock
);
1287 l_Status
= NDIS_STATUS_SUCCESS
;
1291 case OID_GEN_CURRENT_PACKET_FILTER
:
1292 l_Status
= NDIS_STATUS_INVALID_LENGTH
;
1295 if (p_BufferLength
>= sizeof (ULONG
))
1298 (("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n",
1299 NAME (l_Adapter
), l_Query
->m_Long
));
1300 l_Status
= NDIS_STATUS_SUCCESS
;
1301 *p_BytesRead
= sizeof (ULONG
);
1305 case OID_GEN_CURRENT_LOOKAHEAD
:
1306 if (p_BufferLength
< sizeof (ULONG
))
1308 l_Status
= NDIS_STATUS_INVALID_LENGTH
;
1311 else if (l_Query
->m_Long
> DEFAULT_PACKET_LOOKAHEAD
1312 || l_Query
->m_Long
<= 0)
1314 l_Status
= NDIS_STATUS_INVALID_DATA
;
1318 DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n",
1319 NAME (l_Adapter
), l_Query
->m_Long
));
1320 l_Adapter
->m_Lookahead
= l_Query
->m_Long
;
1321 l_Status
= NDIS_STATUS_SUCCESS
;
1322 *p_BytesRead
= sizeof (ULONG
);
1326 case OID_GEN_NETWORK_LAYER_ADDRESSES
:
1327 l_Status
= NDIS_STATUS_SUCCESS
;
1328 *p_BytesRead
= *p_BytesNeeded
= 0;
1331 case OID_GEN_TRANSPORT_HEADER_OFFSET
:
1332 l_Status
= NDIS_STATUS_SUCCESS
;
1333 *p_BytesRead
= *p_BytesNeeded
= 0;
1336 case OID_PNP_SET_POWER
:
1339 NDIS_DEVICE_POWER_STATE NewDeviceState
;
1341 NewDeviceState
= (*(PNDIS_DEVICE_POWER_STATE
) p_Buffer
);
1343 switch (NewDeviceState
)
1345 case NdisDeviceStateD0
:
1346 l_Adapter
->m_DeviceState
= '0';
1348 case NdisDeviceStateD1
:
1349 l_Adapter
->m_DeviceState
= '1';
1351 case NdisDeviceStateD2
:
1352 l_Adapter
->m_DeviceState
= '2';
1354 case NdisDeviceStateD3
:
1355 l_Adapter
->m_DeviceState
= '3';
1358 l_Adapter
->m_DeviceState
= '?';
1362 l_Status
= NDIS_STATUS_FAILURE
;
1365 // Check for invalid length
1367 if (p_BufferLength
< sizeof (NDIS_DEVICE_POWER_STATE
))
1369 l_Status
= NDIS_STATUS_INVALID_LENGTH
;
1373 if (NewDeviceState
> NdisDeviceStateD0
)
1375 l_Adapter
->m_InterfaceIsRunning
= FALSE
;
1376 DEBUGP (("[%s] Power management device state OFF\n",
1381 l_Adapter
->m_InterfaceIsRunning
= TRUE
;
1382 DEBUGP (("[%s] Power management device state ON\n",
1386 l_Status
= NDIS_STATUS_SUCCESS
;
1390 if (l_Status
== NDIS_STATUS_SUCCESS
)
1392 *p_BytesRead
= sizeof (NDIS_DEVICE_POWER_STATE
);
1398 *p_BytesNeeded
= sizeof (NDIS_DEVICE_POWER_STATE
);
1402 case OID_PNP_REMOVE_WAKE_UP_PATTERN
:
1403 case OID_PNP_ADD_WAKE_UP_PATTERN
:
1404 l_Status
= NDIS_STATUS_SUCCESS
;
1405 *p_BytesRead
= *p_BytesNeeded
= 0;
1409 DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter
),
1411 l_Status
= NDIS_STATUS_INVALID_OID
;
1412 *p_BytesRead
= *p_BytesNeeded
= 0;
1419 //====================================================================
1420 // Adapter Transmission
1421 //====================================================================
1423 AdapterTransmit (IN NDIS_HANDLE p_AdapterContext
,
1424 IN PNDIS_PACKET p_Packet
,
1427 TapAdapterPointer l_Adapter
= (TapAdapterPointer
) p_AdapterContext
;
1428 ULONG l_Index
= 0, l_PacketLength
= 0;
1429 UINT l_BufferLength
= 0;
1431 TapPacketPointer l_PacketBuffer
;
1432 PNDIS_BUFFER l_NDIS_Buffer
;
1436 NdisQueryPacket (p_Packet
, NULL
, NULL
, &l_NDIS_Buffer
, &l_PacketLength
);
1438 //====================================================
1439 // Here we abandon the transmission attempt if any of
1440 // the parameters is wrong or memory allocation fails
1441 // but we do not indicate failure. The packet is
1442 // silently dropped.
1443 //====================================================
1445 if (l_PacketLength
< ETHERNET_HEADER_SIZE
|| l_PacketLength
> 65535)
1447 else if (!l_Adapter
->m_Extension
.m_TapOpens
|| !l_Adapter
->m_MediaState
)
1448 goto exit_success
; // Nothing is bound to the TAP device
1450 if (NdisAllocateMemoryWithTag (&l_PacketBuffer
,
1451 TAP_PACKET_SIZE (l_PacketLength
),
1452 '5PAT') != NDIS_STATUS_SUCCESS
)
1453 goto exit_no_resources
;
1455 if (l_PacketBuffer
== NULL
)
1456 goto exit_no_resources
;
1458 l_PacketBuffer
->m_SizeFlags
= (l_PacketLength
& TP_SIZE_MASK
);
1460 //===========================
1461 // Reassemble packet contents
1462 //===========================
1467 while (l_NDIS_Buffer
&& l_Index
< l_PacketLength
)
1470 NdisQueryBuffer (l_NDIS_Buffer
, (PVOID
*) & l_Buffer
,
1472 newlen
= l_Index
+ l_BufferLength
;
1473 if (newlen
> l_PacketLength
)
1476 goto no_queue
; /* overflow */
1478 NdisMoveMemory (l_PacketBuffer
->m_Data
+ l_Index
, l_Buffer
,
1481 NdisGetNextBuffer (l_NDIS_Buffer
, &l_NDIS_Buffer
);
1483 if (l_Index
!= l_PacketLength
)
1486 goto no_queue
; /* underflow */
1489 DUMP_PACKET ("AdapterTransmit", l_PacketBuffer
->m_Data
, l_PacketLength
);
1491 //=====================================================
1492 // If IPv4 packet, check whether or not packet
1494 //=====================================================
1495 #if PACKET_TRUNCATION_CHECK
1496 IPv4PacketSizeVerify (l_PacketBuffer
->m_Data
, l_PacketLength
, FALSE
, "TX", &l_Adapter
->m_TxTrunc
);
1499 //=====================================================
1500 // Are we running in DHCP server masquerade mode?
1502 // If so, catch both DHCP requests and ARP queries
1503 // to resolve the address of our virtual DHCP server.
1504 //=====================================================
1505 if (l_Adapter
->m_dhcp_enabled
)
1507 const ETH_HEADER
*eth
= (ETH_HEADER
*) l_PacketBuffer
->m_Data
;
1508 const IPHDR
*ip
= (IPHDR
*) (l_PacketBuffer
->m_Data
+ sizeof (ETH_HEADER
));
1509 const UDPHDR
*udp
= (UDPHDR
*) (l_PacketBuffer
->m_Data
+ sizeof (ETH_HEADER
) + sizeof (IPHDR
));
1512 if (l_PacketLength
== sizeof (ARP_PACKET
)
1513 && eth
->proto
== htons (ETH_P_ARP
)
1514 && l_Adapter
->m_dhcp_server_arp
)
1516 if (ProcessARP (l_Adapter
,
1517 (PARP_PACKET
) l_PacketBuffer
->m_Data
,
1518 l_Adapter
->m_dhcp_addr
,
1519 l_Adapter
->m_dhcp_server_ip
,
1521 l_Adapter
->m_dhcp_server_mac
))
1526 else if (l_PacketLength
>= sizeof (ETH_HEADER
) + sizeof (IPHDR
) + sizeof (UDPHDR
) + sizeof (DHCP
)
1527 && eth
->proto
== htons (ETH_P_IP
)
1528 && ip
->version_len
== 0x45 // IPv4, 20 byte header
1529 && ip
->protocol
== IPPROTO_UDP
1530 && udp
->dest
== htons (BOOTPS_PORT
))
1532 const DHCP
*dhcp
= (DHCP
*) (l_PacketBuffer
->m_Data
1533 + sizeof (ETH_HEADER
)
1537 const int optlen
= l_PacketLength
1538 - sizeof (ETH_HEADER
)
1543 if (optlen
> 0) // we must have at least one DHCP option
1545 if (ProcessDHCP (l_Adapter
, eth
, ip
, udp
, dhcp
, optlen
))
1553 //===============================================
1554 // In Point-To-Point mode, check to see whether
1555 // packet is ARP or IPv4 (if neither, then drop).
1556 //===============================================
1557 if (l_Adapter
->m_tun
)
1561 if (l_PacketLength
< ETHERNET_HEADER_SIZE
)
1564 e
= (ETH_HEADER
*) l_PacketBuffer
->m_Data
;
1566 switch (ntohs (e
->proto
))
1570 // Make sure that packet is the
1571 // right size for ARP.
1572 if (l_PacketLength
!= sizeof (ARP_PACKET
))
1575 ProcessARP (l_Adapter
,
1576 (PARP_PACKET
) l_PacketBuffer
->m_Data
,
1577 l_Adapter
->m_localIP
,
1578 l_Adapter
->m_remoteNetwork
,
1579 l_Adapter
->m_remoteNetmask
,
1580 l_Adapter
->m_TapToUser
.dest
);
1587 // Make sure that packet is large
1588 // enough to be IPv4.
1590 < ETHERNET_HEADER_SIZE
+ IP_HEADER_SIZE
)
1593 // Only accept directed packets,
1595 if (memcmp (e
, &l_Adapter
->m_TapToUser
, ETHERNET_HEADER_SIZE
))
1598 // Packet looks like IPv4, queue it.
1599 l_PacketBuffer
->m_SizeFlags
|= TP_TUN
;
1603 //===============================================
1604 // Push packet onto queue to wait for read from
1606 //===============================================
1608 NdisAcquireSpinLock (&l_Adapter
->m_Extension
.m_QueueLock
);
1611 if (IS_UP (l_Adapter
))
1612 result
= QueuePush (l_Adapter
->m_Extension
.m_PacketQueue
, l_PacketBuffer
);
1614 NdisReleaseSpinLock (&l_Adapter
->m_Extension
.m_QueueLock
);
1616 if ((TapPacketPointer
) result
!= l_PacketBuffer
)
1618 // adapter receive overrun
1619 INCREMENT_STAT (l_Adapter
->m_TxErr
);
1624 INCREMENT_STAT (l_Adapter
->m_Tx
);
1627 //============================================================
1628 // Cycle through IRPs and packets, try to satisfy each pending
1629 // IRP with a queued packet.
1630 //============================================================
1634 l_PacketBuffer
= NULL
;
1636 NdisAcquireSpinLock (&l_Adapter
->m_Extension
.m_QueueLock
);
1638 if (IS_UP (l_Adapter
)
1639 && QueueCount (l_Adapter
->m_Extension
.m_PacketQueue
)
1640 && QueueCount (l_Adapter
->m_Extension
.m_IrpQueue
))
1642 l_IRP
= (PIRP
) QueuePop (l_Adapter
->m_Extension
.m_IrpQueue
);
1643 l_PacketBuffer
= (TapPacketPointer
)
1644 QueuePop (l_Adapter
->m_Extension
.m_PacketQueue
);
1647 NdisReleaseSpinLock (&l_Adapter
->m_Extension
.m_QueueLock
);
1649 MYASSERT ((l_IRP
!= NULL
) + (l_PacketBuffer
!= NULL
) != 1);
1651 if (l_IRP
&& l_PacketBuffer
)
1655 IO_NETWORK_INCREMENT
);
1661 __except (EXCEPTION_EXECUTE_HANDLER
)
1665 return NDIS_STATUS_SUCCESS
;
1668 NdisFreeMemory (l_PacketBuffer
,
1669 TAP_PACKET_SIZE (l_PacketLength
),
1673 return NDIS_STATUS_SUCCESS
;
1676 return NDIS_STATUS_FAILURE
;
1679 return NDIS_STATUS_RESOURCES
;
1682 //======================================================================
1683 // Hooks for catching TAP device IRP's.
1684 //======================================================================
1687 TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject
, IN PIRP p_IRP
)
1689 TapAdapterPointer l_Adapter
= LookupAdapterInInstanceList (p_DeviceObject
);
1690 PIO_STACK_LOCATION l_IrpSp
;
1691 NTSTATUS l_Status
= STATUS_SUCCESS
;
1694 l_IrpSp
= IoGetCurrentIrpStackLocation (p_IRP
);
1696 p_IRP
->IoStatus
.Status
= STATUS_SUCCESS
;
1697 p_IRP
->IoStatus
.Information
= 0;
1699 if (!l_Adapter
|| l_Adapter
->m_Extension
.m_Halt
)
1701 DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n",
1702 (int)l_IrpSp
->MajorFunction
));
1704 if (l_IrpSp
->MajorFunction
== IRP_MJ_CLOSE
)
1706 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
1707 return STATUS_SUCCESS
;
1711 p_IRP
->IoStatus
.Status
= STATUS_NO_SUCH_DEVICE
;
1712 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
1713 return STATUS_NO_SUCH_DEVICE
;
1717 switch (l_IrpSp
->MajorFunction
)
1719 //===========================================================
1720 // Ioctl call handlers
1721 //===========================================================
1722 case IRP_MJ_DEVICE_CONTROL
:
1724 switch (l_IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
)
1726 case TAP_IOCTL_GET_MAC
:
1728 if (l_IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
1729 >= sizeof (MACADDR
))
1731 COPY_MAC (p_IRP
->AssociatedIrp
.SystemBuffer
,
1733 p_IRP
->IoStatus
.Information
= sizeof (MACADDR
);
1738 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_BUFFER_TOO_SMALL
;
1742 case TAP_IOCTL_GET_VERSION
:
1744 const ULONG size
= sizeof (ULONG
) * 3;
1745 if (l_IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
1748 ((PULONG
) (p_IRP
->AssociatedIrp
.SystemBuffer
))[0]
1749 = TAP_DRIVER_MAJOR_VERSION
;
1750 ((PULONG
) (p_IRP
->AssociatedIrp
.SystemBuffer
))[1]
1751 = TAP_DRIVER_MINOR_VERSION
;
1752 ((PULONG
) (p_IRP
->AssociatedIrp
.SystemBuffer
))[2]
1758 p_IRP
->IoStatus
.Information
= size
;
1763 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_BUFFER_TOO_SMALL
;
1768 case TAP_IOCTL_GET_MTU
:
1770 const ULONG size
= sizeof (ULONG
) * 1;
1771 if (l_IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
1774 ((PULONG
) (p_IRP
->AssociatedIrp
.SystemBuffer
))[0]
1776 p_IRP
->IoStatus
.Information
= size
;
1781 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_BUFFER_TOO_SMALL
;
1786 case TAP_IOCTL_GET_INFO
:
1789 if (l_Adapter
->m_InterfaceIsRunning
)
1793 if (l_Adapter
->m_Extension
.m_TapIsRunning
)
1797 state
[2] = l_Adapter
->m_DeviceState
;
1798 if (l_Adapter
->m_MediaStateAlwaysConnected
)
1804 p_IRP
->IoStatus
.Status
= l_Status
= RtlStringCchPrintfExA (
1805 ((LPTSTR
) (p_IRP
->AssociatedIrp
.SystemBuffer
)),
1806 l_IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
,
1809 STRSAFE_FILL_BEHIND_NULL
| STRSAFE_IGNORE_NULLS
,
1810 #if PACKET_TRUNCATION_CHECK
1811 "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d,%d] Rx=[%d,%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d]",
1813 "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d]",
1816 g_LastErrorFilename
,
1817 g_LastErrorLineNumber
,
1818 (int)l_Adapter
->m_Extension
.m_NumTapOpens
,
1819 (int)l_Adapter
->m_Tx
,
1820 (int)l_Adapter
->m_TxErr
,
1821 #if PACKET_TRUNCATION_CHECK
1822 (int)l_Adapter
->m_TxTrunc
,
1824 (int)l_Adapter
->m_Rx
,
1825 (int)l_Adapter
->m_RxErr
,
1826 #if PACKET_TRUNCATION_CHECK
1827 (int)l_Adapter
->m_RxTrunc
,
1829 (int)l_Adapter
->m_Extension
.m_IrpQueue
->size
,
1830 (int)l_Adapter
->m_Extension
.m_IrpQueue
->max_size
,
1831 (int)IRP_QUEUE_SIZE
,
1832 (int)l_Adapter
->m_Extension
.m_PacketQueue
->size
,
1833 (int)l_Adapter
->m_Extension
.m_PacketQueue
->max_size
,
1834 (int)PACKET_QUEUE_SIZE
1837 p_IRP
->IoStatus
.Information
1838 = l_IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1844 case TAP_IOCTL_GET_LOG_LINE
:
1846 if (GetDebugLine ((LPTSTR
)p_IRP
->AssociatedIrp
.SystemBuffer
,
1847 l_IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
))
1848 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_SUCCESS
;
1850 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
1852 p_IRP
->IoStatus
.Information
1853 = l_IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1859 case TAP_IOCTL_CONFIG_TUN
:
1861 if (l_IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
>=
1862 (sizeof (IPADDR
) * 3))
1866 l_Adapter
->m_tun
= FALSE
;
1868 GenerateRelatedMAC (dest
, l_Adapter
->m_MAC
, 1);
1870 l_Adapter
->m_localIP
= ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[0];
1871 l_Adapter
->m_remoteNetwork
= ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[1];
1872 l_Adapter
->m_remoteNetmask
= ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[2];
1874 // sanity check on network/netmask
1875 if ((l_Adapter
->m_remoteNetwork
& l_Adapter
->m_remoteNetmask
) != l_Adapter
->m_remoteNetwork
)
1878 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
1882 COPY_MAC (l_Adapter
->m_TapToUser
.src
, l_Adapter
->m_MAC
);
1883 COPY_MAC (l_Adapter
->m_TapToUser
.dest
, dest
);
1884 COPY_MAC (l_Adapter
->m_UserToTap
.src
, dest
);
1885 COPY_MAC (l_Adapter
->m_UserToTap
.dest
, l_Adapter
->m_MAC
);
1887 l_Adapter
->m_TapToUser
.proto
= l_Adapter
->m_UserToTap
.proto
= htons (ETH_P_IP
);
1889 l_Adapter
->m_tun
= TRUE
;
1891 CheckIfDhcpAndTunMode (l_Adapter
);
1893 p_IRP
->IoStatus
.Information
= 1; // Simple boolean value
1898 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
1904 case TAP_IOCTL_CONFIG_POINT_TO_POINT
: // Obsoleted by TAP_IOCTL_CONFIG_TUN
1906 if (l_IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
>=
1907 (sizeof (IPADDR
) * 2))
1911 l_Adapter
->m_tun
= FALSE
;
1913 GenerateRelatedMAC (dest
, l_Adapter
->m_MAC
, 1);
1915 l_Adapter
->m_localIP
= ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[0];
1916 l_Adapter
->m_remoteNetwork
= ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[1];
1917 l_Adapter
->m_remoteNetmask
= ~0;
1919 COPY_MAC (l_Adapter
->m_TapToUser
.src
, l_Adapter
->m_MAC
);
1920 COPY_MAC (l_Adapter
->m_TapToUser
.dest
, dest
);
1921 COPY_MAC (l_Adapter
->m_UserToTap
.src
, dest
);
1922 COPY_MAC (l_Adapter
->m_UserToTap
.dest
, l_Adapter
->m_MAC
);
1924 l_Adapter
->m_TapToUser
.proto
= l_Adapter
->m_UserToTap
.proto
= htons (ETH_P_IP
);
1926 l_Adapter
->m_tun
= TRUE
;
1928 CheckIfDhcpAndTunMode (l_Adapter
);
1930 p_IRP
->IoStatus
.Information
= 1; // Simple boolean value
1935 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
1941 case TAP_IOCTL_SET_MEDIA_STATUS
:
1943 if (l_IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
>=
1944 (sizeof (ULONG
) * 1))
1946 ULONG parm
= ((PULONG
) (p_IRP
->AssociatedIrp
.SystemBuffer
))[0];
1947 SetMediaStatus (l_Adapter
, (BOOLEAN
) parm
);
1948 p_IRP
->IoStatus
.Information
= 1;
1953 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
1958 case TAP_IOCTL_CONFIG_DHCP_MASQ
:
1960 if (l_IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
>=
1961 (sizeof (IPADDR
) * 4))
1963 l_Adapter
->m_dhcp_enabled
= FALSE
;
1964 l_Adapter
->m_dhcp_server_arp
= FALSE
;
1965 l_Adapter
->m_dhcp_user_supplied_options_buffer_len
= 0;
1967 // Adapter IP addr / netmask
1968 l_Adapter
->m_dhcp_addr
=
1969 ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[0];
1970 l_Adapter
->m_dhcp_netmask
=
1971 ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[1];
1973 // IP addr of DHCP masq server
1974 l_Adapter
->m_dhcp_server_ip
=
1975 ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[2];
1977 // Lease time in seconds
1978 l_Adapter
->m_dhcp_lease_time
=
1979 ((IPADDR
*) (p_IRP
->AssociatedIrp
.SystemBuffer
))[3];
1981 GenerateRelatedMAC (l_Adapter
->m_dhcp_server_mac
, l_Adapter
->m_MAC
, 2);
1983 l_Adapter
->m_dhcp_enabled
= TRUE
;
1984 l_Adapter
->m_dhcp_server_arp
= TRUE
;
1986 CheckIfDhcpAndTunMode (l_Adapter
);
1988 p_IRP
->IoStatus
.Information
= 1; // Simple boolean value
1993 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
1999 case TAP_IOCTL_CONFIG_DHCP_SET_OPT
:
2001 if (l_IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
<=
2002 DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE
2003 && l_Adapter
->m_dhcp_enabled
)
2005 l_Adapter
->m_dhcp_user_supplied_options_buffer_len
= 0;
2007 NdisMoveMemory (l_Adapter
->m_dhcp_user_supplied_options_buffer
,
2008 p_IRP
->AssociatedIrp
.SystemBuffer
,
2009 l_IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
);
2011 l_Adapter
->m_dhcp_user_supplied_options_buffer_len
=
2012 l_IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
2014 p_IRP
->IoStatus
.Information
= 1; // Simple boolean value
2019 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
2028 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
2033 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2037 //===========================================================
2038 // User mode thread issued a read request on the tap device
2039 // If there are packets waiting to be read, then the request
2040 // will be satisfied here. If not, then the request will be
2041 // queued and satisfied by any packet that is not used to
2042 // satisfy requests ahead of it.
2043 //===========================================================
2046 TapPacketPointer l_PacketBuffer
;
2047 BOOLEAN pending
= FALSE
;
2049 // Save IRP-accessible copy of buffer length
2050 p_IRP
->IoStatus
.Information
= l_IrpSp
->Parameters
.Read
.Length
;
2052 if (p_IRP
->MdlAddress
== NULL
)
2054 DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n",
2057 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
2058 p_IRP
->IoStatus
.Information
= 0;
2059 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2062 else if ((p_IRP
->AssociatedIrp
.SystemBuffer
=
2063 MmGetSystemAddressForMdlSafe
2064 (p_IRP
->MdlAddress
, NormalPagePriority
)) == NULL
)
2066 DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n",
2069 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INSUFFICIENT_RESOURCES
;
2070 p_IRP
->IoStatus
.Information
= 0;
2071 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2074 else if (!l_Adapter
->m_InterfaceIsRunning
)
2076 DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n",
2079 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2080 p_IRP
->IoStatus
.Information
= 0;
2081 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2085 //==================================
2086 // Can we provide immediate service?
2087 //==================================
2089 l_PacketBuffer
= NULL
;
2091 NdisAcquireSpinLock (&l_Adapter
->m_Extension
.m_QueueLock
);
2093 if (IS_UP (l_Adapter
)
2094 && QueueCount (l_Adapter
->m_Extension
.m_PacketQueue
)
2095 && QueueCount (l_Adapter
->m_Extension
.m_IrpQueue
) == 0)
2097 l_PacketBuffer
= (TapPacketPointer
)
2098 QueuePop (l_Adapter
->m_Extension
.m_PacketQueue
);
2101 NdisReleaseSpinLock (&l_Adapter
->m_Extension
.m_QueueLock
);
2105 l_Status
= CompleteIRP (p_IRP
,
2111 //=============================
2112 // Attempt to pend read request
2113 //=============================
2115 NdisAcquireSpinLock (&l_Adapter
->m_Extension
.m_QueueLock
);
2117 if (IS_UP (l_Adapter
)
2118 && QueuePush (l_Adapter
->m_Extension
.m_IrpQueue
, p_IRP
) == (PIRP
) p_IRP
)
2120 IoSetCancelRoutine (p_IRP
, CancelIRPCallback
);
2121 l_Status
= STATUS_PENDING
;
2122 IoMarkIrpPending (p_IRP
);
2126 NdisReleaseSpinLock (&l_Adapter
->m_Extension
.m_QueueLock
);
2131 // Can't queue anymore IRP's
2132 DEBUGP (("[%s] TAP [%s] read IRP overrun\n",
2133 NAME (l_Adapter
), l_Adapter
->m_Extension
.m_TapName
));
2135 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2136 p_IRP
->IoStatus
.Information
= 0;
2137 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2141 //==============================================================
2142 // User mode issued a WriteFile request on the TAP file handle.
2143 // The request will always get satisfied here. The call may
2144 // fail if there are too many pending packets (queue full).
2145 //==============================================================
2148 if (p_IRP
->MdlAddress
== NULL
)
2150 DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n",
2153 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INVALID_PARAMETER
;
2154 p_IRP
->IoStatus
.Information
= 0;
2156 else if ((p_IRP
->AssociatedIrp
.SystemBuffer
=
2157 MmGetSystemAddressForMdlSafe
2158 (p_IRP
->MdlAddress
, NormalPagePriority
)) == NULL
)
2160 DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n",
2163 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_INSUFFICIENT_RESOURCES
;
2164 p_IRP
->IoStatus
.Information
= 0;
2166 else if (!l_Adapter
->m_InterfaceIsRunning
)
2168 DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n",
2171 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2172 p_IRP
->IoStatus
.Information
= 0;
2174 else if (!l_Adapter
->m_tun
&& ((l_IrpSp
->Parameters
.Write
.Length
) >= ETHERNET_HEADER_SIZE
))
2178 p_IRP
->IoStatus
.Information
= l_IrpSp
->Parameters
.Write
.Length
;
2180 DUMP_PACKET ("IRP_MJ_WRITE ETH",
2181 (unsigned char *) p_IRP
->AssociatedIrp
.SystemBuffer
,
2182 l_IrpSp
->Parameters
.Write
.Length
);
2184 //=====================================================
2185 // If IPv4 packet, check whether or not packet
2187 //=====================================================
2188 #if PACKET_TRUNCATION_CHECK
2189 IPv4PacketSizeVerify ((unsigned char *) p_IRP
->AssociatedIrp
.SystemBuffer
,
2190 l_IrpSp
->Parameters
.Write
.Length
,
2193 &l_Adapter
->m_RxTrunc
);
2196 NdisMEthIndicateReceive
2197 (l_Adapter
->m_MiniportAdapterHandle
,
2198 (NDIS_HANDLE
) l_Adapter
,
2199 (unsigned char *) p_IRP
->AssociatedIrp
.SystemBuffer
,
2200 ETHERNET_HEADER_SIZE
,
2201 (unsigned char *) p_IRP
->AssociatedIrp
.SystemBuffer
+ ETHERNET_HEADER_SIZE
,
2202 l_IrpSp
->Parameters
.Write
.Length
- ETHERNET_HEADER_SIZE
,
2203 l_IrpSp
->Parameters
.Write
.Length
- ETHERNET_HEADER_SIZE
);
2205 NdisMEthIndicateReceiveComplete (l_Adapter
->m_MiniportAdapterHandle
);
2207 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_SUCCESS
;
2209 __except (EXCEPTION_EXECUTE_HANDLER
)
2211 DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n",
2214 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2215 p_IRP
->IoStatus
.Information
= 0;
2218 else if (l_Adapter
->m_tun
&& ((l_IrpSp
->Parameters
.Write
.Length
) >= IP_HEADER_SIZE
))
2222 p_IRP
->IoStatus
.Information
= l_IrpSp
->Parameters
.Write
.Length
;
2224 DUMP_PACKET2 ("IRP_MJ_WRITE P2P",
2225 &l_Adapter
->m_UserToTap
,
2226 (unsigned char *) p_IRP
->AssociatedIrp
.SystemBuffer
,
2227 l_IrpSp
->Parameters
.Write
.Length
);
2229 //=====================================================
2230 // If IPv4 packet, check whether or not packet
2232 //=====================================================
2233 #if PACKET_TRUNCATION_CHECK
2234 IPv4PacketSizeVerify ((unsigned char *) p_IRP
->AssociatedIrp
.SystemBuffer
,
2235 l_IrpSp
->Parameters
.Write
.Length
,
2238 &l_Adapter
->m_RxTrunc
);
2241 NdisMEthIndicateReceive
2242 (l_Adapter
->m_MiniportAdapterHandle
,
2243 (NDIS_HANDLE
) l_Adapter
,
2244 (unsigned char *) &l_Adapter
->m_UserToTap
,
2245 sizeof (l_Adapter
->m_UserToTap
),
2246 (unsigned char *) p_IRP
->AssociatedIrp
.SystemBuffer
,
2247 l_IrpSp
->Parameters
.Write
.Length
,
2248 l_IrpSp
->Parameters
.Write
.Length
);
2250 NdisMEthIndicateReceiveComplete (l_Adapter
->m_MiniportAdapterHandle
);
2252 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_SUCCESS
;
2254 __except (EXCEPTION_EXECUTE_HANDLER
)
2256 DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n",
2259 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2260 p_IRP
->IoStatus
.Information
= 0;
2265 DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",
2267 l_IrpSp
->Parameters
.Write
.Length
));
2269 p_IRP
->IoStatus
.Information
= 0; // ETHERNET_HEADER_SIZE;
2270 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_BUFFER_TOO_SMALL
;
2273 if (l_Status
== STATUS_SUCCESS
)
2274 INCREMENT_STAT (l_Adapter
->m_Rx
);
2276 INCREMENT_STAT (l_Adapter
->m_RxErr
);
2278 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2282 //--------------------------------------------------------------
2283 // User mode thread has called CreateFile() on the tap device
2284 //--------------------------------------------------------------
2287 BOOLEAN succeeded
= FALSE
;
2288 BOOLEAN mutex_succeeded
;
2291 (("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
2292 NAME (l_Adapter
), TAP_DRIVER_MAJOR_VERSION
,
2293 TAP_DRIVER_MINOR_VERSION
, l_Adapter
->m_Extension
.m_TapOpens
));
2295 ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter
->m_Extension
.m_OpenCloseMutex
, mutex_succeeded
);
2296 if (mutex_succeeded
)
2298 if (l_Adapter
->m_Extension
.m_TapIsRunning
&& !l_Adapter
->m_Extension
.m_TapOpens
)
2300 ResetTapAdapterState (l_Adapter
);
2301 l_Adapter
->m_Extension
.m_TapOpens
= 1;
2307 INCREMENT_STAT (l_Adapter
->m_Extension
.m_NumTapOpens
);
2308 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_SUCCESS
;
2309 p_IRP
->IoStatus
.Information
= 0;
2313 DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
2314 NAME (l_Adapter
), l_Adapter
->m_Extension
.m_TapOpens
));
2316 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2317 p_IRP
->IoStatus
.Information
= 0;
2320 RELEASE_MUTEX (&l_Adapter
->m_Extension
.m_OpenCloseMutex
);
2324 DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
2325 NAME (l_Adapter
), l_Adapter
->m_Extension
.m_TapOpens
));
2327 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2328 p_IRP
->IoStatus
.Information
= 0;
2331 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2335 //-----------------------------------------------------------
2336 // User mode thread called CloseHandle() on the tap device
2337 //-----------------------------------------------------------
2340 BOOLEAN mutex_succeeded
;
2342 DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n",
2343 NAME (l_Adapter
), TAP_DRIVER_MAJOR_VERSION
,
2344 TAP_DRIVER_MINOR_VERSION
));
2346 ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter
->m_Extension
.m_OpenCloseMutex
, mutex_succeeded
);
2347 if (mutex_succeeded
)
2349 l_Adapter
->m_Extension
.m_TapOpens
= 0;
2350 ResetTapAdapterState (l_Adapter
);
2351 FlushQueues (&l_Adapter
->m_Extension
);
2352 SetMediaStatus (l_Adapter
, FALSE
);
2353 RELEASE_MUTEX (&l_Adapter
->m_Extension
.m_OpenCloseMutex
);
2357 DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
2358 NAME (l_Adapter
), l_Adapter
->m_Extension
.m_TapOpens
));
2360 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2361 p_IRP
->IoStatus
.Information
= 0;
2364 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2368 //------------------
2370 //------------------
2374 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_UNSUCCESSFUL
;
2375 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2383 //=============================================================
2384 // CompleteIRP is normally called with an adapter -> userspace
2385 // network packet and an IRP (Pending I/O request) from userspace.
2387 // The IRP will normally represent a queued overlapped read
2388 // operation from userspace that is in a wait state.
2390 // Use the ethernet packet to satisfy the IRP.
2391 //=============================================================
2394 CompleteIRP (IN PIRP p_IRP
,
2395 IN TapPacketPointer p_PacketBuffer
,
2396 IN CCHAR PriorityBoost
)
2398 NTSTATUS l_Status
= STATUS_UNSUCCESSFUL
;
2404 MYASSERT (p_PacketBuffer
);
2406 IoSetCancelRoutine (p_IRP
, NULL
); // Disable cancel routine
2408 //-------------------------------------------
2409 // While p_PacketBuffer always contains a
2410 // full ethernet packet, including the
2411 // ethernet header, in point-to-point mode,
2412 // we only want to return the IPv4
2414 //-------------------------------------------
2416 if (p_PacketBuffer
->m_SizeFlags
& TP_TUN
)
2418 offset
= ETHERNET_HEADER_SIZE
;
2419 len
= (int) (p_PacketBuffer
->m_SizeFlags
& TP_SIZE_MASK
) - ETHERNET_HEADER_SIZE
;
2424 len
= (p_PacketBuffer
->m_SizeFlags
& TP_SIZE_MASK
);
2427 if (len
< 0 || (int) p_IRP
->IoStatus
.Information
< len
)
2429 p_IRP
->IoStatus
.Information
= 0;
2430 p_IRP
->IoStatus
.Status
= STATUS_BUFFER_OVERFLOW
;
2435 p_IRP
->IoStatus
.Information
= len
;
2436 p_IRP
->IoStatus
.Status
= l_Status
= STATUS_SUCCESS
;
2440 NdisMoveMemory (p_IRP
->AssociatedIrp
.SystemBuffer
,
2441 p_PacketBuffer
->m_Data
+ offset
,
2444 __except (EXCEPTION_EXECUTE_HANDLER
)
2447 p_IRP
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
2448 p_IRP
->IoStatus
.Information
= 0;
2454 NdisFreeMemory (p_PacketBuffer
,
2455 TAP_PACKET_SIZE (p_PacketBuffer
->m_SizeFlags
& TP_SIZE_MASK
),
2458 __except (EXCEPTION_EXECUTE_HANDLER
)
2462 if (l_Status
== STATUS_SUCCESS
)
2464 IoCompleteRequest (p_IRP
, PriorityBoost
);
2467 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2472 //==============================================
2473 // IRPs get cancelled for a number of reasons.
2475 // The TAP device could be closed by userspace
2476 // when there are still pending read operations.
2478 // The user could disable the TAP adapter in the
2479 // network connections control panel, while the
2480 // device is still open by a process.
2481 //==============================================
2483 CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject
,
2486 TapAdapterPointer l_Adapter
= LookupAdapterInInstanceList (p_DeviceObject
);
2487 CancelIRP (l_Adapter
? &l_Adapter
->m_Extension
: NULL
, p_IRP
, TRUE
);
2491 CancelIRP (TapExtensionPointer p_Extension
,
2495 BOOLEAN exists
= FALSE
;
2501 NdisAcquireSpinLock (&p_Extension
->m_QueueLock
);
2502 exists
= (QueueExtract (p_Extension
->m_IrpQueue
, p_IRP
) == p_IRP
);
2503 NdisReleaseSpinLock (&p_Extension
->m_QueueLock
);
2510 IoSetCancelRoutine (p_IRP
, NULL
);
2511 p_IRP
->IoStatus
.Status
= STATUS_CANCELLED
;
2512 p_IRP
->IoStatus
.Information
= 0;
2516 IoReleaseCancelSpinLock (p_IRP
->CancelIrql
);
2519 IoCompleteRequest (p_IRP
, IO_NO_INCREMENT
);
2522 //====================================
2523 // Exhaust packet and IRP queues.
2524 //====================================
2526 FlushQueues (TapExtensionPointer p_Extension
)
2529 TapPacketPointer l_PacketBuffer
;
2530 int n_IRP
=0, n_Packet
=0;
2532 MYASSERT (p_Extension
);
2533 MYASSERT (p_Extension
->m_TapDevice
);
2537 NdisAcquireSpinLock (&p_Extension
->m_QueueLock
);
2538 l_IRP
= QueuePop (p_Extension
->m_IrpQueue
);
2539 NdisReleaseSpinLock (&p_Extension
->m_QueueLock
);
2543 CancelIRP (NULL
, l_IRP
, FALSE
);
2551 NdisAcquireSpinLock (&p_Extension
->m_QueueLock
);
2552 l_PacketBuffer
= QueuePop (p_Extension
->m_PacketQueue
);
2553 NdisReleaseSpinLock (&p_Extension
->m_QueueLock
);
2557 MemFree (l_PacketBuffer
, TAP_PACKET_SIZE (l_PacketBuffer
->m_SizeFlags
& TP_SIZE_MASK
));
2564 "[%s] [TAP] FlushQueues n_IRP=[%d,%d,%d] n_Packet=[%d,%d,%d]\n",
2565 p_Extension
->m_TapName
,
2567 p_Extension
->m_IrpQueue
->max_size
,
2570 p_Extension
->m_PacketQueue
->max_size
,
2575 //===================================================
2576 // Tell Windows whether the TAP device should be
2577 // considered "connected" or "disconnected".
2578 //===================================================
2580 SetMediaStatus (TapAdapterPointer p_Adapter
, BOOLEAN state
)
2582 if (p_Adapter
->m_MediaState
!= state
&& !p_Adapter
->m_MediaStateAlwaysConnected
)
2585 NdisMIndicateStatus (p_Adapter
->m_MiniportAdapterHandle
,
2586 NDIS_STATUS_MEDIA_CONNECT
, NULL
, 0);
2588 NdisMIndicateStatus (p_Adapter
->m_MiniportAdapterHandle
,
2589 NDIS_STATUS_MEDIA_DISCONNECT
, NULL
, 0);
2591 NdisMIndicateStatusComplete (p_Adapter
->m_MiniportAdapterHandle
);
2592 p_Adapter
->m_MediaState
= state
;
2597 //======================================================
2598 // If DHCP mode is used together with tun
2599 // mode, consider the fact that the P2P remote subnet
2600 // might enclose the DHCP masq server address.
2601 //======================================================
2603 CheckIfDhcpAndTunMode (TapAdapterPointer p_Adapter
)
2605 if (p_Adapter
->m_tun
&& p_Adapter
->m_dhcp_enabled
)
2607 if ((p_Adapter
->m_dhcp_server_ip
& p_Adapter
->m_remoteNetmask
) == p_Adapter
->m_remoteNetwork
)
2609 COPY_MAC (p_Adapter
->m_dhcp_server_mac
, p_Adapter
->m_TapToUser
.dest
);
2610 p_Adapter
->m_dhcp_server_arp
= FALSE
;
2615 //===================================================
2616 // Generate an ARP reply message for specific kinds
2618 //===================================================
2620 ProcessARP (TapAdapterPointer p_Adapter
,
2621 const PARP_PACKET src
,
2622 const IPADDR adapter_ip
,
2623 const IPADDR ip_network
,
2624 const IPADDR ip_netmask
,
2627 //-----------------------------------------------
2628 // Is this the kind of packet we are looking for?
2629 //-----------------------------------------------
2630 if (src
->m_Proto
== htons (ETH_P_ARP
)
2631 && MAC_EQUAL (src
->m_MAC_Source
, p_Adapter
->m_MAC
)
2632 && MAC_EQUAL (src
->m_ARP_MAC_Source
, p_Adapter
->m_MAC
)
2633 && MAC_EQUAL (src
->m_MAC_Destination
, p_Adapter
->m_MAC_Broadcast
)
2634 && src
->m_ARP_Operation
== htons (ARP_REQUEST
)
2635 && src
->m_MAC_AddressType
== htons (MAC_ADDR_TYPE
)
2636 && src
->m_MAC_AddressSize
== sizeof (MACADDR
)
2637 && src
->m_PROTO_AddressType
== htons (ETH_P_IP
)
2638 && src
->m_PROTO_AddressSize
== sizeof (IPADDR
)
2639 && src
->m_ARP_IP_Source
== adapter_ip
2640 && (src
->m_ARP_IP_Destination
& ip_netmask
) == ip_network
2641 && src
->m_ARP_IP_Destination
!= adapter_ip
)
2643 ARP_PACKET
*arp
= (ARP_PACKET
*) MemAlloc (sizeof (ARP_PACKET
), TRUE
);
2646 //----------------------------------------------
2647 // Initialize ARP reply fields
2648 //----------------------------------------------
2649 arp
->m_Proto
= htons (ETH_P_ARP
);
2650 arp
->m_MAC_AddressType
= htons (MAC_ADDR_TYPE
);
2651 arp
->m_PROTO_AddressType
= htons (ETH_P_IP
);
2652 arp
->m_MAC_AddressSize
= sizeof (MACADDR
);
2653 arp
->m_PROTO_AddressSize
= sizeof (IPADDR
);
2654 arp
->m_ARP_Operation
= htons (ARP_REPLY
);
2656 //----------------------------------------------
2658 //----------------------------------------------
2659 COPY_MAC (arp
->m_MAC_Source
, mac
);
2660 COPY_MAC (arp
->m_MAC_Destination
, p_Adapter
->m_MAC
);
2661 COPY_MAC (arp
->m_ARP_MAC_Source
, mac
);
2662 COPY_MAC (arp
->m_ARP_MAC_Destination
, p_Adapter
->m_MAC
);
2663 arp
->m_ARP_IP_Source
= src
->m_ARP_IP_Destination
;
2664 arp
->m_ARP_IP_Destination
= adapter_ip
;
2666 DUMP_PACKET ("ProcessARP",
2667 (unsigned char *) arp
,
2668 sizeof (ARP_PACKET
));
2670 InjectPacket (p_Adapter
, (UCHAR
*) arp
, sizeof (ARP_PACKET
));
2672 MemFree (arp
, sizeof (ARP_PACKET
));
2681 //===============================================================
2682 // Used in cases where internally generated packets such as
2683 // ARP or DHCP replies must be returned to the kernel, to be
2684 // seen as an incoming packet "arriving" on the interface.
2685 //===============================================================
2688 InjectPacket (TapAdapterPointer p_Adapter
,
2690 const unsigned int len
)
2692 MYASSERT (len
>= ETHERNET_HEADER_SIZE
);
2696 //------------------------------------------------------------
2697 // NdisMEthIndicateReceive and NdisMEthIndicateReceiveComplete
2698 // could potentially be called reentrantly both here and in
2699 // TapDeviceHook/IRP_MJ_WRITE.
2701 // The DDK docs imply that this is okay.
2702 //------------------------------------------------------------
2703 NdisMEthIndicateReceive
2704 (p_Adapter
->m_MiniportAdapterHandle
,
2705 (NDIS_HANDLE
) p_Adapter
,
2707 ETHERNET_HEADER_SIZE
,
2708 packet
+ ETHERNET_HEADER_SIZE
,
2709 len
- ETHERNET_HEADER_SIZE
,
2710 len
- ETHERNET_HEADER_SIZE
);
2712 NdisMEthIndicateReceiveComplete (p_Adapter
->m_MiniportAdapterHandle
);
2714 __except (EXCEPTION_EXECUTE_HANDLER
)
2716 DEBUGP (("[%s] NdisMEthIndicateReceive failed in InjectPacket\n",
2722 //===================================================================
2723 // Go back to default TAP mode from Point-To-Point mode.
2724 // Also reset (i.e. disable) DHCP Masq mode.
2725 //===================================================================
2726 VOID
ResetTapAdapterState (TapAdapterPointer p_Adapter
)
2729 p_Adapter
->m_tun
= FALSE
;
2730 p_Adapter
->m_localIP
= 0;
2731 p_Adapter
->m_remoteNetwork
= 0;
2732 p_Adapter
->m_remoteNetmask
= 0;
2733 NdisZeroMemory (&p_Adapter
->m_TapToUser
, sizeof (p_Adapter
->m_TapToUser
));
2734 NdisZeroMemory (&p_Adapter
->m_UserToTap
, sizeof (p_Adapter
->m_UserToTap
));
2737 p_Adapter
->m_dhcp_enabled
= FALSE
;
2738 p_Adapter
->m_dhcp_server_arp
= FALSE
;
2739 p_Adapter
->m_dhcp_user_supplied_options_buffer_len
= 0;
2740 p_Adapter
->m_dhcp_addr
= 0;
2741 p_Adapter
->m_dhcp_netmask
= 0;
2742 p_Adapter
->m_dhcp_server_ip
= 0;
2743 p_Adapter
->m_dhcp_lease_time
= 0;
2744 p_Adapter
->m_dhcp_received_discover
= FALSE
;
2745 p_Adapter
->m_dhcp_bad_requests
= 0;
2746 NdisZeroMemory (p_Adapter
->m_dhcp_server_mac
, sizeof (MACADDR
));
2751 //===================================================================
2752 // Set TAP device handle to be accessible without admin privileges.
2753 //===================================================================
2754 VOID
AllowNonAdmin (TapExtensionPointer p_Extension
)
2757 SECURITY_DESCRIPTOR sd
;
2758 OBJECT_ATTRIBUTES oa
;
2759 IO_STATUS_BLOCK isb
;
2762 NdisZeroMemory (&sd
, sizeof (sd
));
2763 NdisZeroMemory (&oa
, sizeof (oa
));
2764 NdisZeroMemory (&isb
, sizeof (isb
));
2766 if (!p_Extension
->m_CreatedUnicodeLinkName
)
2768 DEBUGP (("[TAP] AllowNonAdmin: UnicodeLinkName is uninitialized\n"));
2773 stat
= RtlCreateSecurityDescriptor (&sd
, SECURITY_DESCRIPTOR_REVISION
);
2774 if (stat
!= STATUS_SUCCESS
)
2776 DEBUGP (("[TAP] AllowNonAdmin: RtlCreateSecurityDescriptor failed\n"));
2781 InitializeObjectAttributes (
2783 &p_Extension
->m_UnicodeLinkName
,
2797 if (stat
!= STATUS_SUCCESS
)
2799 DEBUGP (("[TAP] AllowNonAdmin: ZwOpenFile failed, status=0x%08x\n", (unsigned int)stat
));
2804 stat
= ZwSetSecurityObject (hand
, DACL_SECURITY_INFORMATION
, &sd
);
2805 if (stat
!= STATUS_SUCCESS
)
2807 DEBUGP (("[TAP] AllowNonAdmin: ZwSetSecurityObject failed\n"));
2812 stat
= ZwClose (hand
);
2813 if (stat
!= STATUS_SUCCESS
)
2815 DEBUGP (("[TAP] AllowNonAdmin: ZwClose failed\n"));
2820 DEBUGP (("[TAP] AllowNonAdmin: SUCCEEDED\n"));
2825 #if PACKET_TRUNCATION_CHECK
2828 IPv4PacketSizeVerify (const UCHAR
*data
, ULONG length
, BOOLEAN tun
, const char *prefix
, LONG
*counter
)
2835 ip
= (IPHDR
*) data
;
2839 if (length
>= sizeof (ETH_HEADER
))
2841 const ETH_HEADER
*eth
= (ETH_HEADER
*) data
;
2843 if (eth
->proto
!= htons (ETH_P_IP
))
2846 ip
= (IPHDR
*) (data
+ sizeof (ETH_HEADER
));
2847 len
-= sizeof (ETH_HEADER
);
2853 if (len
>= sizeof (IPHDR
))
2855 const int totlen
= ntohs (ip
->tot_len
);
2857 DEBUGP (("[TAP] IPv4PacketSizeVerify %s len=%d totlen=%d\n", prefix
, len
, totlen
));
2866 //======================================================================
2868 //======================================================================