tapdrvr.c 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183
  1. /*
  2. * TAP-Windows -- A kernel driver to provide virtual tap
  3. * device functionality on Windows.
  4. *
  5. * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
  6. *
  7. * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
  8. * and is released under the GPL version 2 (see below).
  9. *
  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.
  13. *
  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.
  18. *
  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
  23. */
  24. //======================================================
  25. // This driver is designed to work on Win 2000 or higher
  26. // versions of Windows.
  27. //
  28. // It is SMP-safe and handles NDIS 5 power management.
  29. //
  30. // By default we operate as a "tap" virtual ethernet
  31. // 802.3 interface, but we can emulate a "tun"
  32. // interface (point-to-point IPv4) through the
  33. // TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT or
  34. // TAP_WIN_IOCTL_CONFIG_TUN ioctl.
  35. //======================================================
  36. #include "tap-windows.h"
  37. #include "config.h"
  38. #define NDIS_MINIPORT_DRIVER
  39. #define BINARY_COMPATIBLE 0
  40. #define NDIS50_MINIPORT 1
  41. #define NDIS_WDM 0
  42. #define NDIS50 1
  43. #define NTSTRSAFE_LIB
  44. // Debug info output
  45. #define ALSO_DBGPRINT 1
  46. #define DEBUGP_AT_DISPATCH 0
  47. #if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600
  48. #include <ndis.h>
  49. #include <ntstrsafe.h>
  50. #include <ntddk.h>
  51. #else
  52. #include <ntifs.h>
  53. #include <ndis.h>
  54. #include <ntstrsafe.h>
  55. #endif
  56. #include "lock.h"
  57. #include "constants.h"
  58. #include "proto.h"
  59. #include "error.h"
  60. #include "endian.h"
  61. #include "types.h"
  62. #include "prototypes.h"
  63. #include "mem.c"
  64. #include "macinfo.c"
  65. #include "error.c"
  66. #include "instance.c"
  67. #define IS_UP(ta) \
  68. ((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning)
  69. #define INCREMENT_STAT(s) ++(s)
  70. #define NAME_BUFFER_SIZE 80
  71. //========================================================
  72. // Globals
  73. //========================================================
  74. NDIS_HANDLE g_NdisWrapperHandle;
  75. const UINT g_SupportedOIDList[] = {
  76. OID_GEN_HARDWARE_STATUS,
  77. OID_GEN_MEDIA_SUPPORTED,
  78. OID_GEN_MEDIA_IN_USE,
  79. OID_GEN_MAXIMUM_LOOKAHEAD,
  80. OID_GEN_MAC_OPTIONS,
  81. OID_GEN_LINK_SPEED,
  82. OID_GEN_TRANSMIT_BLOCK_SIZE,
  83. OID_GEN_RECEIVE_BLOCK_SIZE,
  84. OID_GEN_VENDOR_DESCRIPTION,
  85. OID_GEN_DRIVER_VERSION,
  86. OID_GEN_XMIT_OK,
  87. OID_GEN_RCV_OK,
  88. OID_GEN_XMIT_ERROR,
  89. OID_GEN_RCV_ERROR,
  90. OID_802_3_PERMANENT_ADDRESS,
  91. OID_802_3_CURRENT_ADDRESS,
  92. OID_GEN_RCV_NO_BUFFER,
  93. OID_802_3_RCV_ERROR_ALIGNMENT,
  94. OID_802_3_XMIT_ONE_COLLISION,
  95. OID_802_3_XMIT_MORE_COLLISIONS,
  96. OID_802_3_MULTICAST_LIST,
  97. OID_802_3_MAXIMUM_LIST_SIZE,
  98. OID_GEN_VENDOR_ID,
  99. OID_GEN_CURRENT_LOOKAHEAD,
  100. OID_GEN_CURRENT_PACKET_FILTER,
  101. OID_GEN_PROTOCOL_OPTIONS,
  102. OID_GEN_MAXIMUM_TOTAL_SIZE,
  103. OID_GEN_TRANSMIT_BUFFER_SPACE,
  104. OID_GEN_RECEIVE_BUFFER_SPACE,
  105. OID_GEN_MAXIMUM_FRAME_SIZE,
  106. OID_GEN_VENDOR_DRIVER_VERSION,
  107. OID_GEN_MAXIMUM_SEND_PACKETS,
  108. OID_GEN_MEDIA_CONNECT_STATUS,
  109. OID_GEN_SUPPORTED_LIST
  110. };
  111. //============================================================
  112. // Driver Entry
  113. //============================================================
  114. #pragma NDIS_INIT_FUNCTION (DriverEntry)
  115. DRIVER_INITIALIZE DriverEntry;
  116. NTSTATUS
  117. DriverEntry (IN PDRIVER_OBJECT p_DriverObject,
  118. IN PUNICODE_STRING p_RegistryPath)
  119. {
  120. NDIS_STATUS l_Status = NDIS_STATUS_FAILURE;
  121. NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL;
  122. //========================================================
  123. // Notify NDIS that a new miniport driver is initializing.
  124. //========================================================
  125. NdisMInitializeWrapper (&g_NdisWrapperHandle,
  126. p_DriverObject,
  127. p_RegistryPath, NULL);
  128. //======================
  129. // Global initialization
  130. //======================
  131. #if DBG
  132. MyDebugInit (10000); // Allocate debugging text space
  133. #endif
  134. if (!InitInstanceList ())
  135. {
  136. DEBUGP (("[TAP] Allocation failed for adapter instance list\n"));
  137. goto cleanup;
  138. }
  139. //=======================================
  140. // Set and register miniport entry points
  141. //=======================================
  142. l_Properties = (NDIS_MINIPORT_CHARACTERISTICS *)MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE);
  143. if (l_Properties == NULL)
  144. {
  145. DEBUGP (("[TAP] Allocation failed for miniport entry points\n"));
  146. goto cleanup;
  147. }
  148. l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
  149. l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
  150. l_Properties->InitializeHandler = AdapterCreate;
  151. l_Properties->HaltHandler = AdapterHalt;
  152. l_Properties->ResetHandler = AdapterReset; /* DISPATCH_LEVEL */
  153. l_Properties->TransferDataHandler = AdapterReceive; /* DISPATCH_LEVEL */
  154. l_Properties->SendHandler = AdapterTransmit; /* DISPATCH_LEVEL */
  155. l_Properties->QueryInformationHandler = AdapterQuery; /* DISPATCH_LEVEL */
  156. l_Properties->SetInformationHandler = AdapterModify; /* DISPATCH_LEVEL */
  157. switch (l_Status =
  158. NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties,
  159. sizeof (NDIS_MINIPORT_CHARACTERISTICS)))
  160. {
  161. case NDIS_STATUS_SUCCESS:
  162. {
  163. DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n",
  164. TAP_DRIVER_MAJOR_VERSION,
  165. TAP_DRIVER_MINOR_VERSION,
  166. __DATE__,
  167. __TIME__));
  168. DEBUGP (("Registry Path: '%.*S'\n", p_RegistryPath->Length/2, p_RegistryPath->Buffer));
  169. break;
  170. }
  171. case NDIS_STATUS_BAD_CHARACTERISTICS:
  172. {
  173. DEBUGP (("[TAP] Miniport characteristics were badly defined\n"));
  174. NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
  175. break;
  176. }
  177. case NDIS_STATUS_BAD_VERSION:
  178. {
  179. DEBUGP
  180. (("[TAP] NDIS Version is wrong for the given characteristics\n"));
  181. NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
  182. break;
  183. }
  184. case NDIS_STATUS_RESOURCES:
  185. {
  186. DEBUGP (("[TAP] Insufficient resources\n"));
  187. NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
  188. break;
  189. }
  190. default:
  191. case NDIS_STATUS_FAILURE:
  192. {
  193. DEBUGP (("[TAP] Unknown fatal registration error\n"));
  194. NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
  195. break;
  196. }
  197. }
  198. cleanup:
  199. if (l_Properties)
  200. MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS));
  201. if (l_Status == NDIS_STATUS_SUCCESS)
  202. NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload);
  203. else
  204. TapDriverUnload (p_DriverObject);
  205. return l_Status;
  206. }
  207. //============================================================
  208. // Driver Unload
  209. //============================================================
  210. DRIVER_UNLOAD TapDriverUnload;
  211. VOID
  212. TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject)
  213. {
  214. DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n",
  215. TAP_DRIVER_MAJOR_VERSION,
  216. TAP_DRIVER_MINOR_VERSION,
  217. __DATE__,
  218. __TIME__,
  219. NInstances(),
  220. InstanceMaxBucketSize()));
  221. FreeInstanceList ();
  222. //==============================
  223. // Free debugging text space
  224. //==============================
  225. #if DBG
  226. MyDebugFree ();
  227. #endif
  228. }
  229. //==========================================================
  230. // Adapter Initialization
  231. //==========================================================
  232. NDIS_STATUS AdapterCreate
  233. (OUT PNDIS_STATUS p_ErrorStatus,
  234. OUT PUINT p_MediaIndex,
  235. IN PNDIS_MEDIUM p_Media,
  236. IN UINT p_MediaCount,
  237. IN NDIS_HANDLE p_AdapterHandle,
  238. IN NDIS_HANDLE p_ConfigurationHandle)
  239. {
  240. TapAdapterPointer l_Adapter = NULL;
  241. NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet
  242. BOOLEAN l_MacFromRegistry = FALSE;
  243. UINT l_Index;
  244. NDIS_STATUS status;
  245. DEBUGP (("[TAP] AdapterCreate called\n"));
  246. //====================================
  247. // Make sure adapter type is supported
  248. //====================================
  249. for (l_Index = 0;
  250. l_Index < p_MediaCount && p_Media[l_Index] != l_PreferredMedium;
  251. ++l_Index);
  252. if (l_Index == p_MediaCount)
  253. {
  254. DEBUGP (("[TAP] Unsupported adapter type [wanted: %d]\n",
  255. l_PreferredMedium));
  256. return NDIS_STATUS_UNSUPPORTED_MEDIA;
  257. }
  258. *p_MediaIndex = l_Index;
  259. //=========================================
  260. // Allocate memory for TapAdapter structure
  261. //=========================================
  262. l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE);
  263. if (l_Adapter == NULL)
  264. {
  265. DEBUGP (("[TAP] Couldn't allocate adapter memory\n"));
  266. return NDIS_STATUS_RESOURCES;
  267. }
  268. //==========================================
  269. // Inform the NDIS library about significant
  270. // features of our virtual NIC.
  271. //==========================================
  272. NdisMSetAttributesEx
  273. (p_AdapterHandle,
  274. (NDIS_HANDLE) l_Adapter,
  275. 16,
  276. NDIS_ATTRIBUTE_DESERIALIZE
  277. | NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT
  278. | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT
  279. | NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
  280. NdisInterfaceInternal);
  281. //=====================================
  282. // Initialize simple Adapter parameters
  283. //=====================================
  284. l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD;
  285. l_Adapter->m_Medium = l_PreferredMedium;
  286. l_Adapter->m_DeviceState = '?';
  287. l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle;
  288. //==================================
  289. // Allocate spinlock for controlling
  290. // access to multicast address list.
  291. //==================================
  292. NdisAllocateSpinLock (&l_Adapter->m_MCLock);
  293. l_Adapter->m_MCLockAllocated = TRUE;
  294. //====================================================
  295. // Register a shutdown handler which will be called
  296. // on system restart/shutdown to halt our virtual NIC.
  297. //====================================================
  298. NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter,
  299. AdapterHalt);
  300. l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE;
  301. //============================================
  302. // Get parameters from registry which were set
  303. // in the adapter advanced properties dialog.
  304. //============================================
  305. {
  306. NDIS_STATUS status;
  307. NDIS_HANDLE configHandle;
  308. NDIS_CONFIGURATION_PARAMETER *parm;
  309. // set defaults in case our registry query fails
  310. l_Adapter->m_MTU = ETHERNET_MTU;
  311. l_Adapter->m_MediaStateAlwaysConnected = FALSE;
  312. l_Adapter->m_MediaState = FALSE;
  313. NdisOpenConfiguration (&status, &configHandle, p_ConfigurationHandle);
  314. if (status != NDIS_STATUS_SUCCESS)
  315. {
  316. DEBUGP (("[TAP] Couldn't open adapter registry\n"));
  317. AdapterFreeResources (l_Adapter);
  318. return status;
  319. }
  320. //====================================
  321. // Allocate and construct adapter name
  322. //====================================
  323. {
  324. NDIS_STRING mkey = NDIS_STRING_CONST("MiniportName");
  325. NDIS_STRING vkey = NDIS_STRING_CONST("NdisVersion");
  326. NDIS_STATUS vstatus;
  327. NDIS_CONFIGURATION_PARAMETER *vparm;
  328. NdisReadConfiguration (&vstatus, &vparm, configHandle, &vkey, NdisParameterInteger);
  329. if (vstatus == NDIS_STATUS_SUCCESS)
  330. DEBUGP (("[TAP] NdisReadConfiguration NdisVersion=%X\n", vparm->ParameterData.IntegerData));
  331. NdisReadConfiguration (&status, &parm, configHandle, &mkey, NdisParameterString);
  332. if (status == NDIS_STATUS_SUCCESS)
  333. {
  334. if (parm->ParameterType == NdisParameterString)
  335. {
  336. DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%.*S)\n",
  337. parm->ParameterData.StringData.Length/2,
  338. parm->ParameterData.StringData.Buffer));
  339. if (RtlUnicodeStringToAnsiString (
  340. &l_Adapter->m_NameAnsi,
  341. &parm->ParameterData.StringData,
  342. TRUE) != STATUS_SUCCESS)
  343. {
  344. DEBUGP (("[TAP] MiniportName failed\n"));
  345. status = NDIS_STATUS_RESOURCES;
  346. }
  347. }
  348. }
  349. else
  350. {
  351. /* "MiniportName" is available only XP and above. Not on Windows 2000. */
  352. if (vstatus == NDIS_STATUS_SUCCESS && vparm->ParameterData.IntegerData == 0x50000)
  353. {
  354. /* Fallback for Windows 2000 with NDIS version 5.00.00
  355. Don't use this on Vista, 'NDIS_MINIPORT_BLOCK' was changed! */
  356. if (RtlUnicodeStringToAnsiString (&l_Adapter->m_NameAnsi,
  357. &((struct WIN2K_NDIS_MINIPORT_BLOCK *) p_AdapterHandle)->MiniportName,
  358. TRUE) != STATUS_SUCCESS)
  359. {
  360. DEBUGP (("[TAP] MiniportName (W2K) failed\n"));
  361. status = NDIS_STATUS_RESOURCES;
  362. }
  363. else
  364. {
  365. DEBUGP (("[TAP] MiniportName (W2K) succeeded: %s\n", l_Adapter->m_NameAnsi.Buffer));
  366. status = NDIS_STATUS_SUCCESS;
  367. }
  368. }
  369. }
  370. }
  371. /* Can't continue without name (see macro 'NAME') */
  372. if (status != NDIS_STATUS_SUCCESS || !l_Adapter->m_NameAnsi.Buffer)
  373. {
  374. NdisCloseConfiguration (configHandle);
  375. AdapterFreeResources (l_Adapter);
  376. DEBUGP (("[TAP] failed to get miniport name\n"));
  377. return NDIS_STATUS_RESOURCES;
  378. }
  379. /* Read MTU setting from registry */
  380. {
  381. NDIS_STRING key = NDIS_STRING_CONST("MTU");
  382. NdisReadConfiguration (&status, &parm, configHandle,
  383. &key, NdisParameterInteger);
  384. if (status == NDIS_STATUS_SUCCESS)
  385. {
  386. if (parm->ParameterType == NdisParameterInteger)
  387. {
  388. int mtu = parm->ParameterData.IntegerData;
  389. if (mtu < MINIMUM_MTU)
  390. mtu = MINIMUM_MTU;
  391. if (mtu > MAXIMUM_MTU)
  392. mtu = MAXIMUM_MTU;
  393. l_Adapter->m_MTU = mtu;
  394. }
  395. }
  396. }
  397. /* Read Media Status setting from registry */
  398. {
  399. NDIS_STRING key = NDIS_STRING_CONST("MediaStatus");
  400. NdisReadConfiguration (&status, &parm, configHandle,
  401. &key, NdisParameterInteger);
  402. if (status == NDIS_STATUS_SUCCESS)
  403. {
  404. if (parm->ParameterType == NdisParameterInteger)
  405. {
  406. if (parm->ParameterData.IntegerData)
  407. {
  408. l_Adapter->m_MediaStateAlwaysConnected = TRUE;
  409. l_Adapter->m_MediaState = TRUE;
  410. }
  411. }
  412. }
  413. }
  414. /* Read optional MAC setting from registry */
  415. {
  416. NDIS_STRING key = NDIS_STRING_CONST("MAC");
  417. ANSI_STRING mac_string;
  418. NdisReadConfiguration (&status, &parm, configHandle,
  419. &key, NdisParameterString);
  420. if (status == NDIS_STATUS_SUCCESS)
  421. {
  422. if (parm->ParameterType == NdisParameterString)
  423. {
  424. if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS)
  425. {
  426. l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer);
  427. RtlFreeAnsiString (&mac_string);
  428. }
  429. }
  430. }
  431. }
  432. NdisCloseConfiguration (configHandle);
  433. DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU));
  434. }
  435. //==================================
  436. // Store and update MAC address info
  437. //==================================
  438. if (!l_MacFromRegistry)
  439. GenerateRandomMac (l_Adapter->m_MAC, (const unsigned char *)NAME (l_Adapter));
  440. DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",
  441. NAME (l_Adapter),
  442. l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],
  443. l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));
  444. //====================================
  445. // Initialize TAP device
  446. //====================================
  447. {
  448. NDIS_STATUS tap_status;
  449. tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter));
  450. if (tap_status != NDIS_STATUS_SUCCESS)
  451. {
  452. AdapterFreeResources (l_Adapter);
  453. DEBUGP (("[TAP] CreateTapDevice failed\n"));
  454. return tap_status;
  455. }
  456. }
  457. if (!AddAdapterToInstanceList (l_Adapter))
  458. {
  459. NOTE_ERROR ();
  460. TapDeviceFreeResources (&l_Adapter->m_Extension);
  461. AdapterFreeResources (l_Adapter);
  462. DEBUGP (("[TAP] AddAdapterToInstanceList failed\n"));
  463. return NDIS_STATUS_RESOURCES;
  464. }
  465. l_Adapter->m_InterfaceIsRunning = TRUE;
  466. return NDIS_STATUS_SUCCESS;
  467. }
  468. VOID
  469. AdapterHalt (IN NDIS_HANDLE p_AdapterContext)
  470. {
  471. BOOLEAN status;
  472. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  473. NOTE_ERROR ();
  474. l_Adapter->m_InterfaceIsRunning = FALSE;
  475. DEBUGP (("[%s] is being halted\n", NAME (l_Adapter)));
  476. DestroyTapDevice (&l_Adapter->m_Extension);
  477. // Free resources
  478. DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter)));
  479. AdapterFreeResources (l_Adapter);
  480. status = RemoveAdapterFromInstanceList (l_Adapter);
  481. DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status));
  482. DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n",
  483. TAP_DRIVER_MAJOR_VERSION,
  484. TAP_DRIVER_MINOR_VERSION,
  485. __DATE__,
  486. __TIME__));
  487. }
  488. VOID
  489. AdapterFreeResources (TapAdapterPointer p_Adapter)
  490. {
  491. MYASSERT (!p_Adapter->m_CalledAdapterFreeResources);
  492. p_Adapter->m_CalledAdapterFreeResources = TRUE;
  493. if (p_Adapter->m_NameAnsi.Buffer)
  494. RtlFreeAnsiString (&p_Adapter->m_NameAnsi);
  495. if (p_Adapter->m_RegisteredAdapterShutdownHandler)
  496. NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle);
  497. if (p_Adapter->m_MCLockAllocated)
  498. NdisFreeSpinLock (&p_Adapter->m_MCLock);
  499. }
  500. VOID
  501. DestroyTapDevice (TapExtensionPointer p_Extension)
  502. {
  503. DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName));
  504. //======================================
  505. // Let clients know we are shutting down
  506. //======================================
  507. p_Extension->m_TapIsRunning = FALSE;
  508. p_Extension->m_TapOpens = 0;
  509. p_Extension->m_Halt = TRUE;
  510. //=====================================
  511. // If we are concurrently executing in
  512. // TapDeviceHook or AdapterTransmit,
  513. // give those calls time to finish.
  514. // Note that we must be running at IRQL
  515. // < DISPATCH_LEVEL in order to call
  516. // NdisMSleep.
  517. //=====================================
  518. NdisMSleep (500000);
  519. //===========================================================
  520. // Exhaust IRP and packet queues. Any pending IRPs will
  521. // be cancelled, causing user-space to get this error
  522. // on overlapped reads:
  523. // The I/O operation has been aborted because of either a
  524. // thread exit or an application request. (code=995)
  525. // It's important that user-space close the device handle
  526. // when this code is returned, so that when we finally
  527. // do a NdisMDeregisterDevice, the device reference count
  528. // is 0. Otherwise the driver will not unload even if the
  529. // the last adapter has been halted.
  530. //===========================================================
  531. FlushQueues (p_Extension);
  532. NdisMSleep (500000); // give user space time to respond to IRP cancel
  533. TapDeviceFreeResources (p_Extension);
  534. }
  535. VOID
  536. TapDeviceFreeResources (TapExtensionPointer p_Extension)
  537. {
  538. MYASSERT (p_Extension);
  539. MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources);
  540. p_Extension->m_CalledTapDeviceFreeResources = TRUE;
  541. if (p_Extension->m_PacketQueue)
  542. QueueFree (p_Extension->m_PacketQueue);
  543. if (p_Extension->m_IrpQueue)
  544. QueueFree (p_Extension->m_IrpQueue);
  545. if (p_Extension->m_CreatedUnicodeLinkName)
  546. RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName);
  547. //==========================================================
  548. // According to DDK docs, the device is not actually deleted
  549. // until its reference count falls to zero. That means we
  550. // still need to gracefully fail TapDeviceHook requests
  551. // after this point, otherwise ugly things would happen if
  552. // the device was disabled (e.g. in the network connections
  553. // control panel) while a userspace app still held an open
  554. // file handle to it.
  555. //==========================================================
  556. if (p_Extension->m_TapDevice)
  557. {
  558. BOOLEAN status;
  559. status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle)
  560. == NDIS_STATUS_SUCCESS);
  561. DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status));
  562. }
  563. if (p_Extension->m_TapName)
  564. MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE);
  565. if (p_Extension->m_AllocatedSpinlocks)
  566. {
  567. NdisFreeSpinLock (&p_Extension->m_QueueLock);
  568. }
  569. }
  570. //========================================================================
  571. // Tap Device Initialization
  572. //========================================================================
  573. NDIS_STATUS
  574. CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name)
  575. {
  576. # define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1))
  577. PDRIVER_DISPATCH *l_Dispatch = NULL;
  578. ANSI_STRING l_TapString, l_LinkString;
  579. UNICODE_STRING l_TapUnicode;
  580. BOOLEAN l_FreeTapUnicode = FALSE;
  581. NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS;
  582. const char *l_UsableName;
  583. DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
  584. TAP_DRIVER_MAJOR_VERSION,
  585. TAP_DRIVER_MINOR_VERSION,
  586. p_Name));
  587. NdisZeroMemory (p_Extension, sizeof (TapExtension));
  588. INIT_MUTEX (&p_Extension->m_OpenCloseMutex);
  589. l_LinkString.Buffer = NULL;
  590. l_TapString.Buffer = NULL;
  591. l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE;
  592. //=======================================
  593. // Set TAP device entry points
  594. //=======================================
  595. if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL)
  596. {
  597. DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name));
  598. l_Return = NDIS_STATUS_RESOURCES;
  599. goto cleanup;
  600. }
  601. l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook;
  602. l_Dispatch[IRP_MJ_READ] = TapDeviceHook;
  603. l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook;
  604. l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook;
  605. l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook;
  606. //==================================
  607. // Find the beginning of the GUID
  608. //==================================
  609. l_UsableName = p_Name;
  610. while (*l_UsableName != '{')
  611. {
  612. if (*l_UsableName == '\0')
  613. {
  614. DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name));
  615. l_Return = NDIS_STATUS_RESOURCES;
  616. goto cleanup;
  617. }
  618. ++l_UsableName;
  619. }
  620. //==================================
  621. // Allocate pool for TAP device name
  622. //==================================
  623. if ((p_Extension->m_TapName = l_TapString.Buffer =
  624. MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
  625. {
  626. DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name));
  627. l_Return = NDIS_STATUS_RESOURCES;
  628. goto cleanup;
  629. }
  630. //================================================
  631. // Allocate pool for TAP symbolic link name buffer
  632. //================================================
  633. if ((l_LinkString.Buffer =
  634. (PCHAR)MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
  635. {
  636. DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n",
  637. p_Name));
  638. l_Return = NDIS_STATUS_RESOURCES;
  639. goto cleanup;
  640. }
  641. //=======================================================
  642. // Set TAP device name
  643. //=======================================================
  644. l_Status = RtlStringCchPrintfExA
  645. (l_TapString.Buffer,
  646. l_TapString.MaximumLength,
  647. NULL,
  648. NULL,
  649. STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
  650. "%s%s%s",
  651. SYSDEVICEDIR,
  652. l_UsableName,
  653. TAP_WIN_SUFFIX);
  654. if (l_Status != STATUS_SUCCESS)
  655. {
  656. DEBUGP (("[%s] couldn't format TAP device name\n",
  657. p_Name));
  658. l_Return = NDIS_STATUS_RESOURCES;
  659. goto cleanup;
  660. }
  661. l_TapString.Length = (USHORT) strlen (l_TapString.Buffer);
  662. DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer));
  663. //=======================================================
  664. // Set TAP link name
  665. //=======================================================
  666. l_Status = RtlStringCchPrintfExA
  667. (l_LinkString.Buffer,
  668. l_LinkString.MaximumLength,
  669. NULL,
  670. NULL,
  671. STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
  672. "%s%s%s",
  673. USERDEVICEDIR,
  674. l_UsableName,
  675. TAP_WIN_SUFFIX);
  676. if (l_Status != STATUS_SUCCESS)
  677. {
  678. DEBUGP (("[%s] couldn't format TAP device symbolic link\n",
  679. p_Name));
  680. l_Return = NDIS_STATUS_RESOURCES;
  681. goto cleanup;
  682. }
  683. l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer);
  684. DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer));
  685. //==================================================
  686. // Convert strings to unicode
  687. //==================================================
  688. if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) !=
  689. STATUS_SUCCESS)
  690. {
  691. DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n",
  692. p_Name));
  693. l_Return = NDIS_STATUS_RESOURCES;
  694. goto cleanup;
  695. }
  696. l_FreeTapUnicode = TRUE;
  697. if (RtlAnsiStringToUnicodeString
  698. (&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE)
  699. != STATUS_SUCCESS)
  700. {
  701. DEBUGP
  702. (("[%s] Couldn't allocate unicode string for symbolic link name\n",
  703. p_Name));
  704. l_Return = NDIS_STATUS_RESOURCES;
  705. goto cleanup;
  706. }
  707. p_Extension->m_CreatedUnicodeLinkName = TRUE;
  708. //==================================================
  709. // Create new TAP device with symbolic
  710. // link and associate with adapter.
  711. //==================================================
  712. l_Status = NdisMRegisterDevice
  713. (g_NdisWrapperHandle,
  714. &l_TapUnicode,
  715. &p_Extension->m_UnicodeLinkName,
  716. l_Dispatch,
  717. &p_Extension->m_TapDevice,
  718. &p_Extension->m_TapDeviceHandle
  719. );
  720. if (l_Status != STATUS_SUCCESS)
  721. {
  722. DEBUGP (("[%s] couldn't be created\n", p_Name));
  723. l_Return = NDIS_STATUS_RESOURCES;
  724. goto cleanup;
  725. }
  726. /* Set TAP device flags */
  727. p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO;
  728. //========================================================
  729. // Initialize Packet and IRP queues.
  730. //
  731. // The packet queue is used to buffer data which has been
  732. // "transmitted" by the virtual NIC, before user space
  733. // has had a chance to read it.
  734. //
  735. // The IRP queue is used to buffer pending I/O requests
  736. // from userspace, i.e. read requests on the TAP device
  737. // waiting for the system to "transmit" something through
  738. // the virtual NIC.
  739. //
  740. // Basically, packets in the packet queue are used
  741. // to satisfy IRP requests in the IRP queue.
  742. //
  743. // QueueLock is used to lock the packet queue used
  744. // for the TAP-Windows NIC -> User Space packet flow direction.
  745. //
  746. // All accesses to packet or IRP queues should be
  747. // bracketed by the QueueLock spinlock,
  748. // in order to be SMP-safe.
  749. //========================================================
  750. NdisAllocateSpinLock (&p_Extension->m_QueueLock);
  751. p_Extension->m_AllocatedSpinlocks = TRUE;
  752. p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE);
  753. p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE);
  754. if (!p_Extension->m_PacketQueue
  755. || !p_Extension->m_IrpQueue)
  756. {
  757. DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name));
  758. l_Return = NDIS_STATUS_RESOURCES;
  759. goto cleanup;
  760. }
  761. //========================
  762. // Finalize initialization
  763. //========================
  764. p_Extension->m_TapIsRunning = TRUE;
  765. DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name,
  766. p_Extension->m_TapName));
  767. cleanup:
  768. if (l_FreeTapUnicode)
  769. RtlFreeUnicodeString (&l_TapUnicode);
  770. if (l_LinkString.Buffer)
  771. MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE);
  772. if (l_Dispatch)
  773. MemFree (l_Dispatch, SIZEOF_DISPATCH);
  774. if (l_Return != NDIS_STATUS_SUCCESS)
  775. TapDeviceFreeResources (p_Extension);
  776. return l_Return;
  777. }
  778. #undef SIZEOF_DISPATCH
  779. //========================================================
  780. // Adapter Control
  781. //========================================================
  782. NDIS_STATUS
  783. AdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext)
  784. {
  785. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  786. DEBUGP (("[%s] is resetting\n", NAME (l_Adapter)));
  787. return NDIS_STATUS_SUCCESS;
  788. }
  789. NDIS_STATUS AdapterReceive
  790. (OUT PNDIS_PACKET p_Packet,
  791. OUT PUINT p_Transferred,
  792. IN NDIS_HANDLE p_AdapterContext,
  793. IN NDIS_HANDLE p_ReceiveContext,
  794. IN UINT p_Offset,
  795. IN UINT p_ToTransfer)
  796. {
  797. return NDIS_STATUS_SUCCESS;
  798. }
  799. //==============================================================
  800. // Adapter Option Query/Modification
  801. //==============================================================
  802. NDIS_STATUS AdapterQuery
  803. (IN NDIS_HANDLE p_AdapterContext,
  804. IN NDIS_OID p_OID,
  805. IN PVOID p_Buffer,
  806. IN ULONG p_BufferLength,
  807. OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded)
  808. {
  809. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  810. TapAdapterQuery l_Query, *l_QueryPtr = &l_Query;
  811. NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS;
  812. UINT l_QueryLength = 4;
  813. BOOLEAN lock_succeeded;
  814. NdisZeroMemory (&l_Query, sizeof (l_Query));
  815. switch (p_OID)
  816. {
  817. //===================================================================
  818. // Vendor & Driver version Info
  819. //===================================================================
  820. case OID_GEN_VENDOR_DESCRIPTION:
  821. l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_TAP_WIN_DEVICE_DESCRIPTION;
  822. l_QueryLength = strlen (PRODUCT_TAP_WIN_DEVICE_DESCRIPTION) + 1;
  823. break;
  824. case OID_GEN_VENDOR_ID:
  825. l_Query.m_Long = 0xffffff;
  826. break;
  827. case OID_GEN_DRIVER_VERSION:
  828. l_Query.m_Short =
  829. (((USHORT) TAP_NDIS_MAJOR_VERSION) << 8 | (USHORT)
  830. TAP_NDIS_MINOR_VERSION);
  831. l_QueryLength = sizeof (unsigned short);
  832. break;
  833. case OID_GEN_VENDOR_DRIVER_VERSION:
  834. l_Query.m_Long =
  835. (((USHORT) PRODUCT_TAP_WIN_MAJOR) << 8 | (USHORT)
  836. PRODUCT_TAP_WIN_MINOR);
  837. break;
  838. //=================================================================
  839. // Statistics
  840. //=================================================================
  841. case OID_GEN_RCV_NO_BUFFER:
  842. l_Query.m_Long = 0;
  843. break;
  844. case OID_802_3_RCV_ERROR_ALIGNMENT:
  845. l_Query.m_Long = 0;
  846. break;
  847. case OID_802_3_XMIT_ONE_COLLISION:
  848. l_Query.m_Long = 0;
  849. break;
  850. case OID_802_3_XMIT_MORE_COLLISIONS:
  851. l_Query.m_Long = 0;
  852. break;
  853. case OID_GEN_XMIT_OK:
  854. l_Query.m_Long = l_Adapter->m_Tx;
  855. break;
  856. case OID_GEN_RCV_OK:
  857. l_Query.m_Long = l_Adapter->m_Rx;
  858. break;
  859. case OID_GEN_XMIT_ERROR:
  860. l_Query.m_Long = l_Adapter->m_TxErr;
  861. break;
  862. case OID_GEN_RCV_ERROR:
  863. l_Query.m_Long = l_Adapter->m_RxErr;
  864. break;
  865. //===================================================================
  866. // Device & Protocol Options
  867. //===================================================================
  868. case OID_GEN_SUPPORTED_LIST:
  869. l_QueryPtr = (TapAdapterQueryPointer) g_SupportedOIDList;
  870. l_QueryLength = sizeof (g_SupportedOIDList);
  871. break;
  872. case OID_GEN_MAC_OPTIONS:
  873. // This MUST be here !!!
  874. l_Query.m_Long = (NDIS_MAC_OPTION_RECEIVE_SERIALIZED
  875. | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
  876. | NDIS_MAC_OPTION_NO_LOOPBACK
  877. | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND);
  878. break;
  879. case OID_GEN_CURRENT_PACKET_FILTER:
  880. l_Query.m_Long =
  881. (NDIS_PACKET_TYPE_ALL_LOCAL |
  882. NDIS_PACKET_TYPE_BROADCAST |
  883. NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL);
  884. break;
  885. case OID_GEN_PROTOCOL_OPTIONS:
  886. l_Query.m_Long = 0;
  887. break;
  888. //==================================================================
  889. // Device Info
  890. //==================================================================
  891. case OID_GEN_MEDIA_CONNECT_STATUS:
  892. l_Query.m_Long = l_Adapter->m_MediaState
  893. ? NdisMediaStateConnected : NdisMediaStateDisconnected;
  894. break;
  895. case OID_GEN_HARDWARE_STATUS:
  896. l_Query.m_HardwareStatus = NdisHardwareStatusReady;
  897. l_QueryLength = sizeof (NDIS_HARDWARE_STATUS);
  898. break;
  899. case OID_GEN_MEDIA_SUPPORTED:
  900. case OID_GEN_MEDIA_IN_USE:
  901. l_Query.m_Medium = l_Adapter->m_Medium;
  902. l_QueryLength = sizeof (NDIS_MEDIUM);
  903. break;
  904. case OID_GEN_PHYSICAL_MEDIUM:
  905. l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified;
  906. l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM);
  907. break;
  908. case OID_GEN_LINK_SPEED:
  909. l_Query.m_Long = 100000; // rate / 100 bps
  910. break;
  911. case OID_802_3_PERMANENT_ADDRESS:
  912. case OID_802_3_CURRENT_ADDRESS:
  913. COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC);
  914. l_QueryLength = sizeof (MACADDR);
  915. break;
  916. //==================================================================
  917. // Limits
  918. //==================================================================
  919. case OID_GEN_MAXIMUM_SEND_PACKETS:
  920. l_Query.m_Long = 1;
  921. break;
  922. case OID_802_3_MAXIMUM_LIST_SIZE:
  923. l_Query.m_Long = NIC_MAX_MCAST_LIST;
  924. break;
  925. case OID_GEN_CURRENT_LOOKAHEAD:
  926. l_Query.m_Long = l_Adapter->m_Lookahead;
  927. break;
  928. case OID_GEN_MAXIMUM_LOOKAHEAD:
  929. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  930. case OID_GEN_RECEIVE_BUFFER_SPACE:
  931. case OID_GEN_RECEIVE_BLOCK_SIZE:
  932. l_Query.m_Long = DEFAULT_PACKET_LOOKAHEAD;
  933. break;
  934. case OID_GEN_MAXIMUM_FRAME_SIZE:
  935. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  936. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  937. l_Query.m_Long = l_Adapter->m_MTU;
  938. break;
  939. case OID_PNP_CAPABILITIES:
  940. do
  941. {
  942. PNDIS_PNP_CAPABILITIES pPNPCapabilities;
  943. PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct;
  944. if (p_BufferLength >= sizeof (NDIS_PNP_CAPABILITIES))
  945. {
  946. pPNPCapabilities = (PNDIS_PNP_CAPABILITIES) (p_Buffer);
  947. //
  948. // Setting up the buffer to be returned
  949. // to the Protocol above the Passthru miniport
  950. //
  951. pPMstruct = &pPNPCapabilities->WakeUpCapabilities;
  952. pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
  953. pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
  954. pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
  955. }
  956. l_QueryLength = sizeof (NDIS_PNP_CAPABILITIES);
  957. }
  958. while (FALSE);
  959. break;
  960. case OID_PNP_QUERY_POWER:
  961. break;
  962. // Required OIDs that we don't support
  963. case OID_GEN_SUPPORTED_GUIDS:
  964. case OID_GEN_MEDIA_CAPABILITIES:
  965. case OID_TCP_TASK_OFFLOAD:
  966. case OID_FFP_SUPPORT:
  967. l_Status = NDIS_STATUS_INVALID_OID;
  968. break;
  969. // Optional stats OIDs
  970. case OID_GEN_DIRECTED_BYTES_XMIT:
  971. case OID_GEN_DIRECTED_FRAMES_XMIT:
  972. case OID_GEN_MULTICAST_BYTES_XMIT:
  973. case OID_GEN_MULTICAST_FRAMES_XMIT:
  974. case OID_GEN_BROADCAST_BYTES_XMIT:
  975. case OID_GEN_BROADCAST_FRAMES_XMIT:
  976. case OID_GEN_DIRECTED_BYTES_RCV:
  977. case OID_GEN_DIRECTED_FRAMES_RCV:
  978. case OID_GEN_MULTICAST_BYTES_RCV:
  979. case OID_GEN_MULTICAST_FRAMES_RCV:
  980. case OID_GEN_BROADCAST_BYTES_RCV:
  981. case OID_GEN_BROADCAST_FRAMES_RCV:
  982. l_Status = NDIS_STATUS_INVALID_OID;
  983. break;
  984. //===================================================================
  985. // Not Handled
  986. //===================================================================
  987. default:
  988. DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID));
  989. l_Status = NDIS_STATUS_INVALID_OID;
  990. break;
  991. }
  992. if (l_Status != NDIS_STATUS_SUCCESS)
  993. ;
  994. else if (l_QueryLength > p_BufferLength)
  995. {
  996. l_Status = NDIS_STATUS_INVALID_LENGTH;
  997. *p_BytesNeeded = l_QueryLength;
  998. }
  999. else
  1000. NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr,
  1001. (*p_BytesWritten = l_QueryLength));
  1002. return l_Status;
  1003. }
  1004. NDIS_STATUS AdapterModify
  1005. (IN NDIS_HANDLE p_AdapterContext,
  1006. IN NDIS_OID p_OID,
  1007. IN PVOID p_Buffer,
  1008. IN ULONG p_BufferLength,
  1009. OUT PULONG p_BytesRead,
  1010. OUT PULONG p_BytesNeeded)
  1011. {
  1012. TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer;
  1013. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  1014. NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID;
  1015. ULONG l_Long;
  1016. switch (p_OID)
  1017. {
  1018. //==================================================================
  1019. // Device Info
  1020. //==================================================================
  1021. case OID_802_3_MULTICAST_LIST:
  1022. DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n",
  1023. NAME (l_Adapter)));
  1024. *p_BytesNeeded = sizeof (ETH_ADDR);
  1025. *p_BytesRead = p_BufferLength;
  1026. if (p_BufferLength % sizeof (ETH_ADDR))
  1027. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1028. else if (p_BufferLength > sizeof (MC_LIST))
  1029. {
  1030. l_Status = NDIS_STATUS_MULTICAST_FULL;
  1031. *p_BytesNeeded = sizeof (MC_LIST);
  1032. }
  1033. else
  1034. {
  1035. NdisAcquireSpinLock (&l_Adapter->m_MCLock);
  1036. NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST));
  1037. NdisMoveMemory(&l_Adapter->m_MCList,
  1038. p_Buffer,
  1039. p_BufferLength);
  1040. l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR);
  1041. NdisReleaseSpinLock (&l_Adapter->m_MCLock);
  1042. l_Status = NDIS_STATUS_SUCCESS;
  1043. }
  1044. break;
  1045. case OID_GEN_CURRENT_PACKET_FILTER:
  1046. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1047. *p_BytesNeeded = 4;
  1048. if (p_BufferLength >= sizeof (ULONG))
  1049. {
  1050. DEBUGP
  1051. (("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n",
  1052. NAME (l_Adapter), l_Query->m_Long));
  1053. l_Status = NDIS_STATUS_SUCCESS;
  1054. *p_BytesRead = sizeof (ULONG);
  1055. }
  1056. break;
  1057. case OID_GEN_CURRENT_LOOKAHEAD:
  1058. if (p_BufferLength < sizeof (ULONG))
  1059. {
  1060. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1061. *p_BytesNeeded = 4;
  1062. }
  1063. else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD
  1064. || l_Query->m_Long <= 0)
  1065. {
  1066. l_Status = NDIS_STATUS_INVALID_DATA;
  1067. }
  1068. else
  1069. {
  1070. DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n",
  1071. NAME (l_Adapter), l_Query->m_Long));
  1072. l_Adapter->m_Lookahead = l_Query->m_Long;
  1073. l_Status = NDIS_STATUS_SUCCESS;
  1074. *p_BytesRead = sizeof (ULONG);
  1075. }
  1076. break;
  1077. case OID_GEN_NETWORK_LAYER_ADDRESSES:
  1078. l_Status = NDIS_STATUS_SUCCESS;
  1079. *p_BytesRead = *p_BytesNeeded = 0;
  1080. break;
  1081. case OID_GEN_TRANSPORT_HEADER_OFFSET:
  1082. l_Status = NDIS_STATUS_SUCCESS;
  1083. *p_BytesRead = *p_BytesNeeded = 0;
  1084. break;
  1085. case OID_PNP_SET_POWER:
  1086. do
  1087. {
  1088. NDIS_DEVICE_POWER_STATE NewDeviceState;
  1089. NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE) p_Buffer);
  1090. switch (NewDeviceState)
  1091. {
  1092. case NdisDeviceStateD0:
  1093. l_Adapter->m_DeviceState = '0';
  1094. break;
  1095. case NdisDeviceStateD1:
  1096. l_Adapter->m_DeviceState = '1';
  1097. break;
  1098. case NdisDeviceStateD2:
  1099. l_Adapter->m_DeviceState = '2';
  1100. break;
  1101. case NdisDeviceStateD3:
  1102. l_Adapter->m_DeviceState = '3';
  1103. break;
  1104. default:
  1105. l_Adapter->m_DeviceState = '?';
  1106. break;
  1107. }
  1108. l_Status = NDIS_STATUS_FAILURE;
  1109. //
  1110. // Check for invalid length
  1111. //
  1112. if (p_BufferLength < sizeof (NDIS_DEVICE_POWER_STATE))
  1113. {
  1114. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1115. break;
  1116. }
  1117. if (NewDeviceState > NdisDeviceStateD0)
  1118. {
  1119. l_Adapter->m_InterfaceIsRunning = FALSE;
  1120. DEBUGP (("[%s] Power management device state OFF\n",
  1121. NAME (l_Adapter)));
  1122. }
  1123. else
  1124. {
  1125. l_Adapter->m_InterfaceIsRunning = TRUE;
  1126. DEBUGP (("[%s] Power management device state ON\n",
  1127. NAME (l_Adapter)));
  1128. }
  1129. l_Status = NDIS_STATUS_SUCCESS;
  1130. }
  1131. while (FALSE);
  1132. if (l_Status == NDIS_STATUS_SUCCESS)
  1133. {
  1134. *p_BytesRead = sizeof (NDIS_DEVICE_POWER_STATE);
  1135. *p_BytesNeeded = 0;
  1136. }
  1137. else
  1138. {
  1139. *p_BytesRead = 0;
  1140. *p_BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
  1141. }
  1142. break;
  1143. case OID_PNP_REMOVE_WAKE_UP_PATTERN:
  1144. case OID_PNP_ADD_WAKE_UP_PATTERN:
  1145. l_Status = NDIS_STATUS_SUCCESS;
  1146. *p_BytesRead = *p_BytesNeeded = 0;
  1147. break;
  1148. default:
  1149. DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter),
  1150. p_OID));
  1151. l_Status = NDIS_STATUS_INVALID_OID;
  1152. *p_BytesRead = *p_BytesNeeded = 0;
  1153. break;
  1154. }
  1155. return l_Status;
  1156. }
  1157. //====================================================================
  1158. // Adapter Transmission
  1159. //====================================================================
  1160. NDIS_STATUS
  1161. AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
  1162. IN PNDIS_PACKET p_Packet,
  1163. IN UINT p_Flags)
  1164. {
  1165. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  1166. ULONG l_Index = 0, l_PacketLength = 0;
  1167. UINT l_BufferLength = 0;
  1168. PIRP l_IRP;
  1169. TapPacketPointer l_PacketBuffer;
  1170. PNDIS_BUFFER l_NDIS_Buffer;
  1171. PUCHAR l_Buffer;
  1172. PVOID result;
  1173. NdisQueryPacket (p_Packet, NULL, NULL, &l_NDIS_Buffer, &l_PacketLength);
  1174. //====================================================
  1175. // Here we abandon the transmission attempt if any of
  1176. // the parameters is wrong or memory allocation fails
  1177. // but we do not indicate failure. The packet is
  1178. // silently dropped.
  1179. //====================================================
  1180. if (l_PacketLength < ETHERNET_HEADER_SIZE || l_PacketLength > 65535)
  1181. goto exit_fail;
  1182. else if (!l_Adapter->m_Extension.m_TapOpens || !l_Adapter->m_MediaState)
  1183. goto exit_success; // Nothing is bound to the TAP device
  1184. if (NdisAllocateMemoryWithTag (&l_PacketBuffer,
  1185. TAP_PACKET_SIZE (l_PacketLength),
  1186. '5PAT') != NDIS_STATUS_SUCCESS)
  1187. goto exit_no_resources;
  1188. if (l_PacketBuffer == NULL)
  1189. goto exit_no_resources;
  1190. l_PacketBuffer->m_SizeFlags = (l_PacketLength & TP_SIZE_MASK);
  1191. //===========================
  1192. // Reassemble packet contents
  1193. //===========================
  1194. __try
  1195. {
  1196. l_Index = 0;
  1197. while (l_NDIS_Buffer && l_Index < l_PacketLength)
  1198. {
  1199. ULONG newlen;
  1200. NdisQueryBuffer (l_NDIS_Buffer, (PVOID *) & l_Buffer,
  1201. &l_BufferLength);
  1202. newlen = l_Index + l_BufferLength;
  1203. if (newlen > l_PacketLength)
  1204. {
  1205. NOTE_ERROR ();
  1206. goto no_queue; /* overflow */
  1207. }
  1208. NdisMoveMemory (l_PacketBuffer->m_Data + l_Index, l_Buffer,
  1209. l_BufferLength);
  1210. l_Index = newlen;
  1211. NdisGetNextBuffer (l_NDIS_Buffer, &l_NDIS_Buffer);
  1212. }
  1213. if (l_Index != l_PacketLength)
  1214. {
  1215. NOTE_ERROR ();
  1216. goto no_queue; /* underflow */
  1217. }
  1218. DUMP_PACKET ("AdapterTransmit", l_PacketBuffer->m_Data, l_PacketLength);
  1219. //===============================================
  1220. // Push packet onto queue to wait for read from
  1221. // userspace.
  1222. //===============================================
  1223. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1224. result = NULL;
  1225. if (IS_UP (l_Adapter))
  1226. result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer);
  1227. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1228. if ((TapPacketPointer) result != l_PacketBuffer)
  1229. {
  1230. // adapter receive overrun
  1231. INCREMENT_STAT (l_Adapter->m_TxErr);
  1232. goto no_queue;
  1233. }
  1234. else
  1235. {
  1236. INCREMENT_STAT (l_Adapter->m_Tx);
  1237. }
  1238. //============================================================
  1239. // Cycle through IRPs and packets, try to satisfy each pending
  1240. // IRP with a queued packet.
  1241. //============================================================
  1242. while (TRUE)
  1243. {
  1244. l_IRP = NULL;
  1245. l_PacketBuffer = NULL;
  1246. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1247. if (IS_UP (l_Adapter)
  1248. && QueueCount (l_Adapter->m_Extension.m_PacketQueue)
  1249. && QueueCount (l_Adapter->m_Extension.m_IrpQueue))
  1250. {
  1251. l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue);
  1252. l_PacketBuffer = (TapPacketPointer)
  1253. QueuePop (l_Adapter->m_Extension.m_PacketQueue);
  1254. }
  1255. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1256. MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1);
  1257. if (l_IRP && l_PacketBuffer)
  1258. {
  1259. CompleteIRP (l_IRP,
  1260. l_PacketBuffer,
  1261. IO_NETWORK_INCREMENT);
  1262. }
  1263. else
  1264. break;
  1265. }
  1266. }
  1267. __except (EXCEPTION_EXECUTE_HANDLER)
  1268. {
  1269. }
  1270. return NDIS_STATUS_SUCCESS;
  1271. no_queue:
  1272. NdisFreeMemory (l_PacketBuffer,
  1273. TAP_PACKET_SIZE (l_PacketLength),
  1274. 0);
  1275. exit_success:
  1276. return NDIS_STATUS_SUCCESS;
  1277. exit_fail:
  1278. return NDIS_STATUS_FAILURE;
  1279. exit_no_resources:
  1280. return NDIS_STATUS_RESOURCES;
  1281. }
  1282. //======================================================================
  1283. // Hooks for catching TAP device IRP's.
  1284. //======================================================================
  1285. DRIVER_DISPATCH TapDeviceHook;
  1286. NTSTATUS
  1287. TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
  1288. {
  1289. TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
  1290. PIO_STACK_LOCATION l_IrpSp;
  1291. NTSTATUS l_Status = STATUS_SUCCESS;
  1292. BOOLEAN accessible;
  1293. ULONG i,j;
  1294. l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP);
  1295. p_IRP->IoStatus.Status = STATUS_SUCCESS;
  1296. p_IRP->IoStatus.Information = 0;
  1297. if (!l_Adapter || l_Adapter->m_Extension.m_Halt)
  1298. {
  1299. DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n",
  1300. (int)l_IrpSp->MajorFunction));
  1301. if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE)
  1302. {
  1303. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1304. return STATUS_SUCCESS;
  1305. }
  1306. else
  1307. {
  1308. p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
  1309. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1310. return STATUS_NO_SUCH_DEVICE;
  1311. }
  1312. }
  1313. switch (l_IrpSp->MajorFunction)
  1314. {
  1315. //===========================================================
  1316. // Ioctl call handlers
  1317. //===========================================================
  1318. case IRP_MJ_DEVICE_CONTROL:
  1319. {
  1320. switch (l_IrpSp->Parameters.DeviceIoControl.IoControlCode)
  1321. {
  1322. case TAP_WIN_IOCTL_GET_MAC:
  1323. {
  1324. if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
  1325. >= sizeof (MACADDR))
  1326. {
  1327. COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer,
  1328. l_Adapter->m_MAC);
  1329. p_IRP->IoStatus.Information = sizeof (MACADDR);
  1330. }
  1331. else
  1332. {
  1333. NOTE_ERROR ();
  1334. p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
  1335. }
  1336. break;
  1337. }
  1338. case TAP_WIN_IOCTL_GET_VERSION:
  1339. {
  1340. const ULONG size = sizeof (ULONG) * 3;
  1341. if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
  1342. >= size)
  1343. {
  1344. ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]
  1345. = TAP_DRIVER_MAJOR_VERSION;
  1346. ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1]
  1347. = TAP_DRIVER_MINOR_VERSION;
  1348. ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2]
  1349. #if DBG
  1350. = 1;
  1351. #else
  1352. = 0;
  1353. #endif
  1354. p_IRP->IoStatus.Information = size;
  1355. }
  1356. else
  1357. {
  1358. NOTE_ERROR ();
  1359. p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
  1360. }
  1361. break;
  1362. }
  1363. case TAP_WIN_IOCTL_GET_MTU:
  1364. {
  1365. const ULONG size = sizeof (ULONG) * 1;
  1366. if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
  1367. >= size)
  1368. {
  1369. ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]
  1370. = l_Adapter->m_MTU;
  1371. p_IRP->IoStatus.Information = size;
  1372. }
  1373. else
  1374. {
  1375. NOTE_ERROR ();
  1376. p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
  1377. }
  1378. break;
  1379. }
  1380. #if DBG
  1381. case TAP_WIN_IOCTL_GET_LOG_LINE:
  1382. {
  1383. if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer,
  1384. l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength))
  1385. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  1386. else
  1387. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1388. p_IRP->IoStatus.Information
  1389. = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  1390. break;
  1391. }
  1392. #endif
  1393. // Allow ZeroTier One to get multicast memberships at the L2 level in a
  1394. // protocol-neutral manner.
  1395. case TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS:
  1396. {
  1397. if (&l_Adapter->m_MCLockAllocated)
  1398. NdisAcquireSpinLock (&l_Adapter->m_MCLock);
  1399. if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength < TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE) {
  1400. /* output buffer too small */
  1401. NOTE_ERROR ();
  1402. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1403. } else {
  1404. char *out = (char *)p_IRP->AssociatedIrp.SystemBuffer;
  1405. char *end = out + TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE;
  1406. for(i=0;i<l_Adapter->m_MCListSize;++i) {
  1407. if (i >= TAP_MAX_MCAST_LIST)
  1408. break;
  1409. for(j=0;j<6;++j)
  1410. *(out++) = l_Adapter->m_MCList.list[i].addr[j];
  1411. if (out >= end)
  1412. break;
  1413. }
  1414. while (out < end)
  1415. *(out++) = (char)0;
  1416. p_IRP->IoStatus.Information
  1417. = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  1418. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  1419. }
  1420. if (&l_Adapter->m_MCLockAllocated)
  1421. NdisReleaseSpinLock (&l_Adapter->m_MCLock);
  1422. break;
  1423. }
  1424. case TAP_WIN_IOCTL_SET_MEDIA_STATUS:
  1425. {
  1426. if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
  1427. (sizeof (ULONG) * 1))
  1428. {
  1429. ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0];
  1430. SetMediaStatus (l_Adapter, (BOOLEAN) parm);
  1431. p_IRP->IoStatus.Information = 1;
  1432. }
  1433. else
  1434. {
  1435. NOTE_ERROR ();
  1436. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1437. }
  1438. break;
  1439. }
  1440. default:
  1441. {
  1442. NOTE_ERROR ();
  1443. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1444. break;
  1445. }
  1446. }
  1447. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1448. break;
  1449. }
  1450. //===========================================================
  1451. // User mode thread issued a read request on the tap device
  1452. // If there are packets waiting to be read, then the request
  1453. // will be satisfied here. If not, then the request will be
  1454. // queued and satisfied by any packet that is not used to
  1455. // satisfy requests ahead of it.
  1456. //===========================================================
  1457. case IRP_MJ_READ:
  1458. {
  1459. TapPacketPointer l_PacketBuffer;
  1460. BOOLEAN pending = FALSE;
  1461. // Save IRP-accessible copy of buffer length
  1462. p_IRP->IoStatus.Information = l_IrpSp->Parameters.Read.Length;
  1463. if (p_IRP->MdlAddress == NULL)
  1464. {
  1465. DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n",
  1466. NAME (l_Adapter)));
  1467. NOTE_ERROR ();
  1468. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1469. p_IRP->IoStatus.Information = 0;
  1470. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1471. break;
  1472. }
  1473. else if ((p_IRP->AssociatedIrp.SystemBuffer =
  1474. MmGetSystemAddressForMdlSafe
  1475. (p_IRP->MdlAddress, NormalPagePriority)) == NULL)
  1476. {
  1477. DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n",
  1478. NAME (l_Adapter)));
  1479. NOTE_ERROR ();
  1480. p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
  1481. p_IRP->IoStatus.Information = 0;
  1482. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1483. break;
  1484. }
  1485. else if (!l_Adapter->m_InterfaceIsRunning)
  1486. {
  1487. DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n",
  1488. NAME (l_Adapter)));
  1489. NOTE_ERROR ();
  1490. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1491. p_IRP->IoStatus.Information = 0;
  1492. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1493. break;
  1494. }
  1495. //==================================
  1496. // Can we provide immediate service?
  1497. //==================================
  1498. l_PacketBuffer = NULL;
  1499. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1500. if (IS_UP (l_Adapter)
  1501. && QueueCount (l_Adapter->m_Extension.m_PacketQueue)
  1502. && QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0)
  1503. {
  1504. l_PacketBuffer = (TapPacketPointer)
  1505. QueuePop (l_Adapter->m_Extension.m_PacketQueue);
  1506. }
  1507. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1508. if (l_PacketBuffer)
  1509. {
  1510. l_Status = CompleteIRP (p_IRP,
  1511. l_PacketBuffer,
  1512. IO_NO_INCREMENT);
  1513. break;
  1514. }
  1515. //=============================
  1516. // Attempt to pend read request
  1517. //=============================
  1518. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1519. if (IS_UP (l_Adapter)
  1520. && QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP)
  1521. {
  1522. IoSetCancelRoutine (p_IRP, CancelIRPCallback);
  1523. l_Status = STATUS_PENDING;
  1524. IoMarkIrpPending (p_IRP);
  1525. pending = TRUE;
  1526. }
  1527. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1528. if (pending)
  1529. break;
  1530. // Can't queue anymore IRP's
  1531. DEBUGP (("[%s] TAP [%s] read IRP overrun\n",
  1532. NAME (l_Adapter), l_Adapter->m_Extension.m_TapName));
  1533. NOTE_ERROR ();
  1534. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1535. p_IRP->IoStatus.Information = 0;
  1536. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1537. break;
  1538. }
  1539. //==============================================================
  1540. // User mode issued a WriteFile request on the TAP file handle.
  1541. // The request will always get satisfied here. The call may
  1542. // fail if there are too many pending packets (queue full).
  1543. //==============================================================
  1544. case IRP_MJ_WRITE:
  1545. {
  1546. if (p_IRP->MdlAddress == NULL)
  1547. {
  1548. DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n",
  1549. NAME (l_Adapter)));
  1550. NOTE_ERROR ();
  1551. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1552. p_IRP->IoStatus.Information = 0;
  1553. }
  1554. else if ((p_IRP->AssociatedIrp.SystemBuffer =
  1555. MmGetSystemAddressForMdlSafe
  1556. (p_IRP->MdlAddress, NormalPagePriority)) == NULL)
  1557. {
  1558. DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n",
  1559. NAME (l_Adapter)));
  1560. NOTE_ERROR ();
  1561. p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
  1562. p_IRP->IoStatus.Information = 0;
  1563. }
  1564. else if (!l_Adapter->m_InterfaceIsRunning)
  1565. {
  1566. DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n",
  1567. NAME (l_Adapter)));
  1568. NOTE_ERROR ();
  1569. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1570. p_IRP->IoStatus.Information = 0;
  1571. }
  1572. else if ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE)
  1573. {
  1574. __try
  1575. {
  1576. p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length;
  1577. DUMP_PACKET ("IRP_MJ_WRITE ETH",
  1578. (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
  1579. l_IrpSp->Parameters.Write.Length);
  1580. NdisMEthIndicateReceive
  1581. (l_Adapter->m_MiniportAdapterHandle,
  1582. (NDIS_HANDLE) l_Adapter,
  1583. (PCHAR)p_IRP->AssociatedIrp.SystemBuffer,
  1584. ETHERNET_HEADER_SIZE,
  1585. (unsigned char *)p_IRP->AssociatedIrp.SystemBuffer + ETHERNET_HEADER_SIZE,
  1586. l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE,
  1587. l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE);
  1588. NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle);
  1589. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  1590. }
  1591. __except (EXCEPTION_EXECUTE_HANDLER)
  1592. {
  1593. DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n",
  1594. NAME (l_Adapter)));
  1595. NOTE_ERROR ();
  1596. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1597. p_IRP->IoStatus.Information = 0;
  1598. }
  1599. }
  1600. else
  1601. {
  1602. DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",
  1603. NAME (l_Adapter),
  1604. l_IrpSp->Parameters.Write.Length));
  1605. NOTE_ERROR ();
  1606. p_IRP->IoStatus.Information = 0; // ETHERNET_HEADER_SIZE;
  1607. p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
  1608. }
  1609. if (l_Status == STATUS_SUCCESS)
  1610. INCREMENT_STAT (l_Adapter->m_Rx);
  1611. else
  1612. INCREMENT_STAT (l_Adapter->m_RxErr);
  1613. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1614. break;
  1615. }
  1616. //--------------------------------------------------------------
  1617. // User mode thread has called CreateFile() on the tap device
  1618. //--------------------------------------------------------------
  1619. case IRP_MJ_CREATE:
  1620. {
  1621. BOOLEAN succeeded = FALSE;
  1622. BOOLEAN mutex_succeeded;
  1623. DEBUGP
  1624. (("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
  1625. NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
  1626. TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens));
  1627. ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
  1628. if (mutex_succeeded)
  1629. {
  1630. if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens)
  1631. {
  1632. l_Adapter->m_Extension.m_TapOpens = 1;
  1633. succeeded = TRUE;
  1634. }
  1635. if (succeeded)
  1636. {
  1637. INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens);
  1638. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  1639. p_IRP->IoStatus.Information = 0;
  1640. }
  1641. else
  1642. {
  1643. DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
  1644. NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
  1645. NOTE_ERROR ();
  1646. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1647. p_IRP->IoStatus.Information = 0;
  1648. }
  1649. RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
  1650. }
  1651. else
  1652. {
  1653. DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
  1654. NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
  1655. NOTE_ERROR ();
  1656. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1657. p_IRP->IoStatus.Information = 0;
  1658. }
  1659. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1660. break;
  1661. }
  1662. //-----------------------------------------------------------
  1663. // User mode thread called CloseHandle() on the tap device
  1664. //-----------------------------------------------------------
  1665. case IRP_MJ_CLOSE:
  1666. {
  1667. BOOLEAN mutex_succeeded;
  1668. DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n",
  1669. NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
  1670. TAP_DRIVER_MINOR_VERSION));
  1671. ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
  1672. if (mutex_succeeded)
  1673. {
  1674. l_Adapter->m_Extension.m_TapOpens = 0;
  1675. FlushQueues (&l_Adapter->m_Extension);
  1676. SetMediaStatus (l_Adapter, FALSE);
  1677. RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
  1678. }
  1679. else
  1680. {
  1681. DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
  1682. NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
  1683. NOTE_ERROR ();
  1684. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1685. p_IRP->IoStatus.Information = 0;
  1686. }
  1687. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1688. break;
  1689. }
  1690. //------------------
  1691. // Strange Request
  1692. //------------------
  1693. default:
  1694. {
  1695. //NOTE_ERROR ();
  1696. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1697. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1698. break;
  1699. }
  1700. }
  1701. return l_Status;
  1702. }
  1703. //=============================================================
  1704. // CompleteIRP is normally called with an adapter -> userspace
  1705. // network packet and an IRP (Pending I/O request) from userspace.
  1706. //
  1707. // The IRP will normally represent a queued overlapped read
  1708. // operation from userspace that is in a wait state.
  1709. //
  1710. // Use the ethernet packet to satisfy the IRP.
  1711. //=============================================================
  1712. NTSTATUS
  1713. CompleteIRP (IN PIRP p_IRP,
  1714. IN TapPacketPointer p_PacketBuffer,
  1715. IN CCHAR PriorityBoost)
  1716. {
  1717. NTSTATUS l_Status = STATUS_UNSUCCESSFUL;
  1718. int offset;
  1719. int len;
  1720. MYASSERT (p_IRP);
  1721. MYASSERT (p_PacketBuffer);
  1722. IoSetCancelRoutine (p_IRP, NULL); // Disable cancel routine
  1723. //-------------------------------------------
  1724. // While p_PacketBuffer always contains a
  1725. // full ethernet packet, including the
  1726. // ethernet header, in point-to-point mode,
  1727. // we only want to return the IPv4
  1728. // component.
  1729. //-------------------------------------------
  1730. if (p_PacketBuffer->m_SizeFlags & TP_TUN)
  1731. {
  1732. offset = ETHERNET_HEADER_SIZE;
  1733. len = (int) (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE;
  1734. }
  1735. else
  1736. {
  1737. offset = 0;
  1738. len = (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK);
  1739. }
  1740. if (len < 0 || (int) p_IRP->IoStatus.Information < len)
  1741. {
  1742. p_IRP->IoStatus.Information = 0;
  1743. p_IRP->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
  1744. NOTE_ERROR ();
  1745. }
  1746. else
  1747. {
  1748. p_IRP->IoStatus.Information = len;
  1749. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  1750. __try
  1751. {
  1752. NdisMoveMemory (p_IRP->AssociatedIrp.SystemBuffer,
  1753. p_PacketBuffer->m_Data + offset,
  1754. len);
  1755. }
  1756. __except (EXCEPTION_EXECUTE_HANDLER)
  1757. {
  1758. NOTE_ERROR ();
  1759. p_IRP->IoStatus.Status = STATUS_UNSUCCESSFUL;
  1760. p_IRP->IoStatus.Information = 0;
  1761. }
  1762. }
  1763. __try
  1764. {
  1765. NdisFreeMemory (p_PacketBuffer,
  1766. TAP_PACKET_SIZE (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK),
  1767. 0);
  1768. }
  1769. __except (EXCEPTION_EXECUTE_HANDLER)
  1770. {
  1771. }
  1772. if (l_Status == STATUS_SUCCESS)
  1773. {
  1774. IoCompleteRequest (p_IRP, PriorityBoost);
  1775. }
  1776. else
  1777. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1778. return l_Status;
  1779. }
  1780. //==============================================
  1781. // IRPs get cancelled for a number of reasons.
  1782. //
  1783. // The TAP device could be closed by userspace
  1784. // when there are still pending read operations.
  1785. //
  1786. // The user could disable the TAP adapter in the
  1787. // network connections control panel, while the
  1788. // device is still open by a process.
  1789. //==============================================
  1790. VOID
  1791. CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject,
  1792. IN PIRP p_IRP)
  1793. {
  1794. TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
  1795. CancelIRP (l_Adapter ? &l_Adapter->m_Extension : NULL, p_IRP, TRUE);
  1796. }
  1797. VOID
  1798. CancelIRP (TapExtensionPointer p_Extension,
  1799. IN PIRP p_IRP,
  1800. BOOLEAN callback)
  1801. {
  1802. BOOLEAN exists = FALSE;
  1803. MYASSERT (p_IRP);
  1804. if (p_Extension)
  1805. {
  1806. NdisAcquireSpinLock (&p_Extension->m_QueueLock);
  1807. exists = (QueueExtract (p_Extension->m_IrpQueue, p_IRP) == p_IRP);
  1808. NdisReleaseSpinLock (&p_Extension->m_QueueLock);
  1809. }
  1810. else
  1811. exists = TRUE;
  1812. if (exists)
  1813. {
  1814. IoSetCancelRoutine (p_IRP, NULL);
  1815. p_IRP->IoStatus.Status = STATUS_CANCELLED;
  1816. p_IRP->IoStatus.Information = 0;
  1817. }
  1818. if (callback)
  1819. IoReleaseCancelSpinLock (p_IRP->CancelIrql);
  1820. if (exists)
  1821. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1822. }
  1823. //===========================================
  1824. // Exhaust packet, IRP, and injection queues.
  1825. //===========================================
  1826. VOID
  1827. FlushQueues (TapExtensionPointer p_Extension)
  1828. {
  1829. PIRP l_IRP;
  1830. TapPacketPointer l_PacketBuffer;
  1831. MYASSERT (p_Extension);
  1832. MYASSERT (p_Extension->m_TapDevice);
  1833. while (TRUE)
  1834. {
  1835. NdisAcquireSpinLock (&p_Extension->m_QueueLock);
  1836. l_IRP = (PIRP)QueuePop (p_Extension->m_IrpQueue);
  1837. NdisReleaseSpinLock (&p_Extension->m_QueueLock);
  1838. if (l_IRP)
  1839. {
  1840. CancelIRP (NULL, l_IRP, FALSE);
  1841. }
  1842. else
  1843. break;
  1844. }
  1845. while (TRUE)
  1846. {
  1847. NdisAcquireSpinLock (&p_Extension->m_QueueLock);
  1848. l_PacketBuffer = (TapPacketPointer)QueuePop (p_Extension->m_PacketQueue);
  1849. NdisReleaseSpinLock (&p_Extension->m_QueueLock);
  1850. if (l_PacketBuffer)
  1851. {
  1852. MemFree (l_PacketBuffer, TAP_PACKET_SIZE (l_PacketBuffer->m_SizeFlags & TP_SIZE_MASK));
  1853. }
  1854. else
  1855. break;
  1856. }
  1857. }
  1858. //===================================================
  1859. // Tell Windows whether the TAP device should be
  1860. // considered "connected" or "disconnected".
  1861. //===================================================
  1862. VOID
  1863. SetMediaStatus (TapAdapterPointer p_Adapter, BOOLEAN state)
  1864. {
  1865. if (p_Adapter->m_MediaState != state && !p_Adapter->m_MediaStateAlwaysConnected)
  1866. {
  1867. if (state)
  1868. NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle,
  1869. NDIS_STATUS_MEDIA_CONNECT, NULL, 0);
  1870. else
  1871. NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle,
  1872. NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0);
  1873. NdisMIndicateStatusComplete (p_Adapter->m_MiniportAdapterHandle);
  1874. p_Adapter->m_MediaState = state;
  1875. }
  1876. }