tapdrvr.c 90 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147
  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. //========================================================
  48. // Check for truncated IPv4 packets, log errors if found.
  49. //========================================================
  50. #define PACKET_TRUNCATION_CHECK 0
  51. //========================================================
  52. // EXPERIMENTAL -- Configure TAP device object to be
  53. // accessible from non-administrative accounts, based
  54. // on an advanced properties setting.
  55. //
  56. // Duplicates the functionality of OpenVPN's
  57. // --allow-nonadmin directive.
  58. //========================================================
  59. #define ENABLE_NONADMIN 1
  60. #if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600
  61. #include <ndis.h>
  62. #include <ntstrsafe.h>
  63. #include <ntddk.h>
  64. #else
  65. #include <ntifs.h>
  66. #include <ndis.h>
  67. #include <ntstrsafe.h>
  68. #endif
  69. #include "lock.h"
  70. #include "constants.h"
  71. #include "proto.h"
  72. #include "error.h"
  73. #include "endian.h"
  74. #include "dhcp.h"
  75. #include "types.h"
  76. #include "prototypes.h"
  77. #include "mem.c"
  78. #include "macinfo.c"
  79. #include "error.c"
  80. #include "dhcp.c"
  81. #include "instance.c"
  82. #define IS_UP(ta) \
  83. ((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning)
  84. #define INCREMENT_STAT(s) ++(s)
  85. #define NAME_BUFFER_SIZE 80
  86. //========================================================
  87. // Globals
  88. //========================================================
  89. NDIS_HANDLE g_NdisWrapperHandle;
  90. const UINT g_SupportedOIDList[] = {
  91. OID_GEN_HARDWARE_STATUS,
  92. OID_GEN_MEDIA_SUPPORTED,
  93. OID_GEN_MEDIA_IN_USE,
  94. OID_GEN_MAXIMUM_LOOKAHEAD,
  95. OID_GEN_MAC_OPTIONS,
  96. OID_GEN_LINK_SPEED,
  97. OID_GEN_TRANSMIT_BLOCK_SIZE,
  98. OID_GEN_RECEIVE_BLOCK_SIZE,
  99. OID_GEN_VENDOR_DESCRIPTION,
  100. OID_GEN_DRIVER_VERSION,
  101. OID_GEN_XMIT_OK,
  102. OID_GEN_RCV_OK,
  103. OID_GEN_XMIT_ERROR,
  104. OID_GEN_RCV_ERROR,
  105. OID_802_3_PERMANENT_ADDRESS,
  106. OID_802_3_CURRENT_ADDRESS,
  107. OID_GEN_RCV_NO_BUFFER,
  108. OID_802_3_RCV_ERROR_ALIGNMENT,
  109. OID_802_3_XMIT_ONE_COLLISION,
  110. OID_802_3_XMIT_MORE_COLLISIONS,
  111. OID_802_3_MULTICAST_LIST,
  112. OID_802_3_MAXIMUM_LIST_SIZE,
  113. OID_GEN_VENDOR_ID,
  114. OID_GEN_CURRENT_LOOKAHEAD,
  115. OID_GEN_CURRENT_PACKET_FILTER,
  116. OID_GEN_PROTOCOL_OPTIONS,
  117. OID_GEN_MAXIMUM_TOTAL_SIZE,
  118. OID_GEN_TRANSMIT_BUFFER_SPACE,
  119. OID_GEN_RECEIVE_BUFFER_SPACE,
  120. OID_GEN_MAXIMUM_FRAME_SIZE,
  121. OID_GEN_VENDOR_DRIVER_VERSION,
  122. OID_GEN_MAXIMUM_SEND_PACKETS,
  123. OID_GEN_MEDIA_CONNECT_STATUS,
  124. OID_GEN_SUPPORTED_LIST
  125. };
  126. //============================================================
  127. // Driver Entry
  128. //============================================================
  129. #pragma NDIS_INIT_FUNCTION (DriverEntry)
  130. DRIVER_INITIALIZE DriverEntry;
  131. NTSTATUS
  132. DriverEntry (IN PDRIVER_OBJECT p_DriverObject,
  133. IN PUNICODE_STRING p_RegistryPath)
  134. {
  135. NDIS_STATUS l_Status = NDIS_STATUS_FAILURE;
  136. NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL;
  137. //========================================================
  138. // Notify NDIS that a new miniport driver is initializing.
  139. //========================================================
  140. NdisMInitializeWrapper (&g_NdisWrapperHandle,
  141. p_DriverObject,
  142. p_RegistryPath, NULL);
  143. //======================
  144. // Global initialization
  145. //======================
  146. #if DBG
  147. MyDebugInit (10000); // Allocate debugging text space
  148. #endif
  149. if (!InitInstanceList ())
  150. {
  151. DEBUGP (("[TAP] Allocation failed for adapter instance list\n"));
  152. goto cleanup;
  153. }
  154. //=======================================
  155. // Set and register miniport entry points
  156. //=======================================
  157. l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE);
  158. if (l_Properties == NULL)
  159. {
  160. DEBUGP (("[TAP] Allocation failed for miniport entry points\n"));
  161. goto cleanup;
  162. }
  163. l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
  164. l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
  165. l_Properties->InitializeHandler = AdapterCreate;
  166. l_Properties->HaltHandler = AdapterHalt;
  167. l_Properties->ResetHandler = AdapterReset; /* DISPATCH_LEVEL */
  168. l_Properties->TransferDataHandler = AdapterReceive; /* DISPATCH_LEVEL */
  169. l_Properties->SendHandler = AdapterTransmit; /* DISPATCH_LEVEL */
  170. l_Properties->QueryInformationHandler = AdapterQuery; /* DISPATCH_LEVEL */
  171. l_Properties->SetInformationHandler = AdapterModify; /* DISPATCH_LEVEL */
  172. switch (l_Status =
  173. NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties,
  174. sizeof (NDIS_MINIPORT_CHARACTERISTICS)))
  175. {
  176. case NDIS_STATUS_SUCCESS:
  177. {
  178. DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n",
  179. TAP_DRIVER_MAJOR_VERSION,
  180. TAP_DRIVER_MINOR_VERSION,
  181. __DATE__,
  182. __TIME__));
  183. DEBUGP (("Registry Path: '%.*S'\n", p_RegistryPath->Length/2, p_RegistryPath->Buffer));
  184. break;
  185. }
  186. case NDIS_STATUS_BAD_CHARACTERISTICS:
  187. {
  188. DEBUGP (("[TAP] Miniport characteristics were badly defined\n"));
  189. NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
  190. break;
  191. }
  192. case NDIS_STATUS_BAD_VERSION:
  193. {
  194. DEBUGP
  195. (("[TAP] NDIS Version is wrong for the given characteristics\n"));
  196. NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
  197. break;
  198. }
  199. case NDIS_STATUS_RESOURCES:
  200. {
  201. DEBUGP (("[TAP] Insufficient resources\n"));
  202. NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
  203. break;
  204. }
  205. default:
  206. case NDIS_STATUS_FAILURE:
  207. {
  208. DEBUGP (("[TAP] Unknown fatal registration error\n"));
  209. NdisTerminateWrapper (g_NdisWrapperHandle, NULL);
  210. break;
  211. }
  212. }
  213. cleanup:
  214. if (l_Properties)
  215. MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS));
  216. if (l_Status == NDIS_STATUS_SUCCESS)
  217. NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload);
  218. else
  219. TapDriverUnload (p_DriverObject);
  220. return l_Status;
  221. }
  222. //============================================================
  223. // Driver Unload
  224. //============================================================
  225. DRIVER_UNLOAD TapDriverUnload;
  226. VOID
  227. TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject)
  228. {
  229. DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n",
  230. TAP_DRIVER_MAJOR_VERSION,
  231. TAP_DRIVER_MINOR_VERSION,
  232. __DATE__,
  233. __TIME__,
  234. NInstances(),
  235. InstanceMaxBucketSize()));
  236. FreeInstanceList ();
  237. //==============================
  238. // Free debugging text space
  239. //==============================
  240. #if DBG
  241. MyDebugFree ();
  242. #endif
  243. }
  244. //==========================================================
  245. // Adapter Initialization
  246. //==========================================================
  247. NDIS_STATUS AdapterCreate
  248. (OUT PNDIS_STATUS p_ErrorStatus,
  249. OUT PUINT p_MediaIndex,
  250. IN PNDIS_MEDIUM p_Media,
  251. IN UINT p_MediaCount,
  252. IN NDIS_HANDLE p_AdapterHandle,
  253. IN NDIS_HANDLE p_ConfigurationHandle)
  254. {
  255. TapAdapterPointer l_Adapter = NULL;
  256. NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet
  257. BOOLEAN l_MacFromRegistry = FALSE;
  258. UINT l_Index;
  259. NDIS_STATUS status;
  260. #if ENABLE_NONADMIN
  261. BOOLEAN enable_non_admin = FALSE;
  262. #endif
  263. DEBUGP (("[TAP] AdapterCreate called\n"));
  264. //====================================
  265. // Make sure adapter type is supported
  266. //====================================
  267. for (l_Index = 0;
  268. l_Index < p_MediaCount && p_Media[l_Index] != l_PreferredMedium;
  269. ++l_Index);
  270. if (l_Index == p_MediaCount)
  271. {
  272. DEBUGP (("[TAP] Unsupported adapter type [wanted: %d]\n",
  273. l_PreferredMedium));
  274. return NDIS_STATUS_UNSUPPORTED_MEDIA;
  275. }
  276. *p_MediaIndex = l_Index;
  277. //=========================================
  278. // Allocate memory for TapAdapter structure
  279. //=========================================
  280. l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE);
  281. if (l_Adapter == NULL)
  282. {
  283. DEBUGP (("[TAP] Couldn't allocate adapter memory\n"));
  284. return NDIS_STATUS_RESOURCES;
  285. }
  286. //==========================================
  287. // Inform the NDIS library about significant
  288. // features of our virtual NIC.
  289. //==========================================
  290. NdisMSetAttributesEx
  291. (p_AdapterHandle,
  292. (NDIS_HANDLE) l_Adapter,
  293. 16,
  294. NDIS_ATTRIBUTE_DESERIALIZE
  295. | NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT
  296. | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT
  297. | NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
  298. NdisInterfaceInternal);
  299. //=====================================
  300. // Initialize simple Adapter parameters
  301. //=====================================
  302. l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD;
  303. l_Adapter->m_Medium = l_PreferredMedium;
  304. l_Adapter->m_DeviceState = '?';
  305. l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle;
  306. //==================================
  307. // Allocate spinlock for controlling
  308. // access to multicast address list.
  309. //==================================
  310. NdisAllocateSpinLock (&l_Adapter->m_MCLock);
  311. l_Adapter->m_MCLockAllocated = TRUE;
  312. //====================================================
  313. // Register a shutdown handler which will be called
  314. // on system restart/shutdown to halt our virtual NIC.
  315. //====================================================
  316. NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter,
  317. AdapterHalt);
  318. l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE;
  319. //============================================
  320. // Get parameters from registry which were set
  321. // in the adapter advanced properties dialog.
  322. //============================================
  323. {
  324. NDIS_STATUS status;
  325. NDIS_HANDLE configHandle;
  326. NDIS_CONFIGURATION_PARAMETER *parm;
  327. // set defaults in case our registry query fails
  328. l_Adapter->m_MTU = ETHERNET_MTU;
  329. l_Adapter->m_MediaStateAlwaysConnected = FALSE;
  330. l_Adapter->m_MediaState = FALSE;
  331. NdisOpenConfiguration (&status, &configHandle, p_ConfigurationHandle);
  332. if (status != NDIS_STATUS_SUCCESS)
  333. {
  334. DEBUGP (("[TAP] Couldn't open adapter registry\n"));
  335. AdapterFreeResources (l_Adapter);
  336. return status;
  337. }
  338. //====================================
  339. // Allocate and construct adapter name
  340. //====================================
  341. {
  342. NDIS_STRING mkey = NDIS_STRING_CONST("MiniportName");
  343. NDIS_STRING vkey = NDIS_STRING_CONST("NdisVersion");
  344. NDIS_STATUS vstatus;
  345. NDIS_CONFIGURATION_PARAMETER *vparm;
  346. NdisReadConfiguration (&vstatus, &vparm, configHandle, &vkey, NdisParameterInteger);
  347. if (vstatus == NDIS_STATUS_SUCCESS)
  348. DEBUGP (("[TAP] NdisReadConfiguration NdisVersion=%X\n", vparm->ParameterData.IntegerData));
  349. NdisReadConfiguration (&status, &parm, configHandle, &mkey, NdisParameterString);
  350. if (status == NDIS_STATUS_SUCCESS)
  351. {
  352. if (parm->ParameterType == NdisParameterString)
  353. {
  354. DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%.*S)\n",
  355. parm->ParameterData.StringData.Length/2,
  356. parm->ParameterData.StringData.Buffer));
  357. if (RtlUnicodeStringToAnsiString (
  358. &l_Adapter->m_NameAnsi,
  359. &parm->ParameterData.StringData,
  360. TRUE) != STATUS_SUCCESS)
  361. {
  362. DEBUGP (("[TAP] MiniportName failed\n"));
  363. status = NDIS_STATUS_RESOURCES;
  364. }
  365. }
  366. }
  367. else
  368. {
  369. /* "MiniportName" is available only XP and above. Not on Windows 2000. */
  370. if (vstatus == NDIS_STATUS_SUCCESS && vparm->ParameterData.IntegerData == 0x50000)
  371. {
  372. /* Fallback for Windows 2000 with NDIS version 5.00.00
  373. Don't use this on Vista, 'NDIS_MINIPORT_BLOCK' was changed! */
  374. if (RtlUnicodeStringToAnsiString (&l_Adapter->m_NameAnsi,
  375. &((struct WIN2K_NDIS_MINIPORT_BLOCK *) p_AdapterHandle)->MiniportName,
  376. TRUE) != STATUS_SUCCESS)
  377. {
  378. DEBUGP (("[TAP] MiniportName (W2K) failed\n"));
  379. status = NDIS_STATUS_RESOURCES;
  380. }
  381. else
  382. {
  383. DEBUGP (("[TAP] MiniportName (W2K) succeeded: %s\n", l_Adapter->m_NameAnsi.Buffer));
  384. status = NDIS_STATUS_SUCCESS;
  385. }
  386. }
  387. }
  388. }
  389. /* Can't continue without name (see macro 'NAME') */
  390. if (status != NDIS_STATUS_SUCCESS || !l_Adapter->m_NameAnsi.Buffer)
  391. {
  392. NdisCloseConfiguration (configHandle);
  393. AdapterFreeResources (l_Adapter);
  394. DEBUGP (("[TAP] failed to get miniport name\n"));
  395. return NDIS_STATUS_RESOURCES;
  396. }
  397. /* Read MTU setting from registry */
  398. {
  399. NDIS_STRING key = NDIS_STRING_CONST("MTU");
  400. NdisReadConfiguration (&status, &parm, configHandle,
  401. &key, NdisParameterInteger);
  402. if (status == NDIS_STATUS_SUCCESS)
  403. {
  404. if (parm->ParameterType == NdisParameterInteger)
  405. {
  406. int mtu = parm->ParameterData.IntegerData;
  407. if (mtu < MINIMUM_MTU)
  408. mtu = MINIMUM_MTU;
  409. if (mtu > MAXIMUM_MTU)
  410. mtu = MAXIMUM_MTU;
  411. l_Adapter->m_MTU = mtu;
  412. }
  413. }
  414. }
  415. /* Read Media Status setting from registry */
  416. {
  417. NDIS_STRING key = NDIS_STRING_CONST("MediaStatus");
  418. NdisReadConfiguration (&status, &parm, configHandle,
  419. &key, NdisParameterInteger);
  420. if (status == NDIS_STATUS_SUCCESS)
  421. {
  422. if (parm->ParameterType == NdisParameterInteger)
  423. {
  424. if (parm->ParameterData.IntegerData)
  425. {
  426. l_Adapter->m_MediaStateAlwaysConnected = TRUE;
  427. l_Adapter->m_MediaState = TRUE;
  428. }
  429. }
  430. }
  431. }
  432. #if ENABLE_NONADMIN
  433. /* Read AllowNonAdmin setting from registry */
  434. {
  435. NDIS_STRING key = NDIS_STRING_CONST("AllowNonAdmin");
  436. NdisReadConfiguration (&status, &parm, configHandle,
  437. &key, NdisParameterInteger);
  438. if (status == NDIS_STATUS_SUCCESS)
  439. {
  440. if (parm->ParameterType == NdisParameterInteger)
  441. {
  442. if (parm->ParameterData.IntegerData)
  443. {
  444. enable_non_admin = TRUE;
  445. }
  446. }
  447. }
  448. }
  449. #endif
  450. /* Read optional MAC setting from registry */
  451. {
  452. NDIS_STRING key = NDIS_STRING_CONST("MAC");
  453. ANSI_STRING mac_string;
  454. NdisReadConfiguration (&status, &parm, configHandle,
  455. &key, NdisParameterString);
  456. if (status == NDIS_STATUS_SUCCESS)
  457. {
  458. if (parm->ParameterType == NdisParameterString)
  459. {
  460. if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS)
  461. {
  462. l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer);
  463. RtlFreeAnsiString (&mac_string);
  464. }
  465. }
  466. }
  467. }
  468. NdisCloseConfiguration (configHandle);
  469. DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU));
  470. }
  471. //==================================
  472. // Store and update MAC address info
  473. //==================================
  474. if (!l_MacFromRegistry)
  475. GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter));
  476. DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",
  477. NAME (l_Adapter),
  478. l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],
  479. l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));
  480. //==================
  481. // Set broadcast MAC
  482. //==================
  483. {
  484. int i;
  485. for (i = 0; i < sizeof (MACADDR); ++i)
  486. l_Adapter->m_MAC_Broadcast[i] = 0xFF;
  487. }
  488. //====================================
  489. // Initialize TAP device
  490. //====================================
  491. {
  492. NDIS_STATUS tap_status;
  493. tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter));
  494. if (tap_status != NDIS_STATUS_SUCCESS)
  495. {
  496. AdapterFreeResources (l_Adapter);
  497. DEBUGP (("[TAP] CreateTapDevice failed\n"));
  498. return tap_status;
  499. }
  500. }
  501. if (!AddAdapterToInstanceList (l_Adapter))
  502. {
  503. NOTE_ERROR ();
  504. TapDeviceFreeResources (&l_Adapter->m_Extension);
  505. AdapterFreeResources (l_Adapter);
  506. DEBUGP (("[TAP] AddAdapterToInstanceList failed\n"));
  507. return NDIS_STATUS_RESOURCES;
  508. }
  509. l_Adapter->m_InterfaceIsRunning = TRUE;
  510. #if ENABLE_NONADMIN
  511. if (enable_non_admin)
  512. AllowNonAdmin (&l_Adapter->m_Extension);
  513. #endif
  514. return NDIS_STATUS_SUCCESS;
  515. }
  516. VOID
  517. AdapterHalt (IN NDIS_HANDLE p_AdapterContext)
  518. {
  519. BOOLEAN status;
  520. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  521. NOTE_ERROR ();
  522. l_Adapter->m_InterfaceIsRunning = FALSE;
  523. DEBUGP (("[%s] is being halted\n", NAME (l_Adapter)));
  524. DestroyTapDevice (&l_Adapter->m_Extension);
  525. // Free resources
  526. DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter)));
  527. AdapterFreeResources (l_Adapter);
  528. status = RemoveAdapterFromInstanceList (l_Adapter);
  529. DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status));
  530. DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n",
  531. TAP_DRIVER_MAJOR_VERSION,
  532. TAP_DRIVER_MINOR_VERSION,
  533. __DATE__,
  534. __TIME__));
  535. }
  536. VOID
  537. AdapterFreeResources (TapAdapterPointer p_Adapter)
  538. {
  539. MYASSERT (!p_Adapter->m_CalledAdapterFreeResources);
  540. p_Adapter->m_CalledAdapterFreeResources = TRUE;
  541. if (p_Adapter->m_NameAnsi.Buffer)
  542. RtlFreeAnsiString (&p_Adapter->m_NameAnsi);
  543. if (p_Adapter->m_RegisteredAdapterShutdownHandler)
  544. NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle);
  545. if (p_Adapter->m_MCLockAllocated)
  546. NdisFreeSpinLock (&p_Adapter->m_MCLock);
  547. }
  548. VOID
  549. DestroyTapDevice (TapExtensionPointer p_Extension)
  550. {
  551. DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName));
  552. //======================================
  553. // Let clients know we are shutting down
  554. //======================================
  555. p_Extension->m_TapIsRunning = FALSE;
  556. p_Extension->m_TapOpens = 0;
  557. p_Extension->m_Halt = TRUE;
  558. //=====================================
  559. // If we are concurrently executing in
  560. // TapDeviceHook or AdapterTransmit,
  561. // give those calls time to finish.
  562. // Note that we must be running at IRQL
  563. // < DISPATCH_LEVEL in order to call
  564. // NdisMSleep.
  565. //=====================================
  566. NdisMSleep (500000);
  567. //===========================================================
  568. // Exhaust IRP and packet queues. Any pending IRPs will
  569. // be cancelled, causing user-space to get this error
  570. // on overlapped reads:
  571. // The I/O operation has been aborted because of either a
  572. // thread exit or an application request. (code=995)
  573. // It's important that user-space close the device handle
  574. // when this code is returned, so that when we finally
  575. // do a NdisMDeregisterDevice, the device reference count
  576. // is 0. Otherwise the driver will not unload even if the
  577. // the last adapter has been halted.
  578. //===========================================================
  579. FlushQueues (p_Extension);
  580. NdisMSleep (500000); // give user space time to respond to IRP cancel
  581. TapDeviceFreeResources (p_Extension);
  582. }
  583. VOID
  584. TapDeviceFreeResources (TapExtensionPointer p_Extension)
  585. {
  586. MYASSERT (p_Extension);
  587. MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources);
  588. p_Extension->m_CalledTapDeviceFreeResources = TRUE;
  589. if (p_Extension->m_PacketQueue)
  590. QueueFree (p_Extension->m_PacketQueue);
  591. if (p_Extension->m_IrpQueue)
  592. QueueFree (p_Extension->m_IrpQueue);
  593. if (p_Extension->m_InjectQueue)
  594. QueueFree (p_Extension->m_InjectQueue);
  595. if (p_Extension->m_CreatedUnicodeLinkName)
  596. RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName);
  597. //==========================================================
  598. // According to DDK docs, the device is not actually deleted
  599. // until its reference count falls to zero. That means we
  600. // still need to gracefully fail TapDeviceHook requests
  601. // after this point, otherwise ugly things would happen if
  602. // the device was disabled (e.g. in the network connections
  603. // control panel) while a userspace app still held an open
  604. // file handle to it.
  605. //==========================================================
  606. if (p_Extension->m_TapDevice)
  607. {
  608. BOOLEAN status;
  609. status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle)
  610. == NDIS_STATUS_SUCCESS);
  611. DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status));
  612. }
  613. if (p_Extension->m_TapName)
  614. MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE);
  615. if (p_Extension->m_InjectDpcInitialized)
  616. KeRemoveQueueDpc (&p_Extension->m_InjectDpc);
  617. if (p_Extension->m_AllocatedSpinlocks)
  618. {
  619. NdisFreeSpinLock (&p_Extension->m_QueueLock);
  620. NdisFreeSpinLock (&p_Extension->m_InjectLock);
  621. }
  622. }
  623. //========================================================================
  624. // Tap Device Initialization
  625. //========================================================================
  626. NDIS_STATUS
  627. CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name)
  628. {
  629. # define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1))
  630. PDRIVER_DISPATCH *l_Dispatch = NULL;
  631. ANSI_STRING l_TapString, l_LinkString;
  632. UNICODE_STRING l_TapUnicode;
  633. BOOLEAN l_FreeTapUnicode = FALSE;
  634. NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS;
  635. const char *l_UsableName;
  636. DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
  637. TAP_DRIVER_MAJOR_VERSION,
  638. TAP_DRIVER_MINOR_VERSION,
  639. p_Name));
  640. NdisZeroMemory (p_Extension, sizeof (TapExtension));
  641. INIT_MUTEX (&p_Extension->m_OpenCloseMutex);
  642. l_LinkString.Buffer = NULL;
  643. l_TapString.Buffer = NULL;
  644. l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE;
  645. //=======================================
  646. // Set TAP device entry points
  647. //=======================================
  648. if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL)
  649. {
  650. DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name));
  651. l_Return = NDIS_STATUS_RESOURCES;
  652. goto cleanup;
  653. }
  654. l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook;
  655. l_Dispatch[IRP_MJ_READ] = TapDeviceHook;
  656. l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook;
  657. l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook;
  658. l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook;
  659. //==================================
  660. // Find the beginning of the GUID
  661. //==================================
  662. l_UsableName = p_Name;
  663. while (*l_UsableName != '{')
  664. {
  665. if (*l_UsableName == '\0')
  666. {
  667. DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name));
  668. l_Return = NDIS_STATUS_RESOURCES;
  669. goto cleanup;
  670. }
  671. ++l_UsableName;
  672. }
  673. //==================================
  674. // Allocate pool for TAP device name
  675. //==================================
  676. if ((p_Extension->m_TapName = l_TapString.Buffer =
  677. MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
  678. {
  679. DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name));
  680. l_Return = NDIS_STATUS_RESOURCES;
  681. goto cleanup;
  682. }
  683. //================================================
  684. // Allocate pool for TAP symbolic link name buffer
  685. //================================================
  686. if ((l_LinkString.Buffer =
  687. MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
  688. {
  689. DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n",
  690. p_Name));
  691. l_Return = NDIS_STATUS_RESOURCES;
  692. goto cleanup;
  693. }
  694. //=======================================================
  695. // Set TAP device name
  696. //=======================================================
  697. l_Status = RtlStringCchPrintfExA
  698. (l_TapString.Buffer,
  699. l_TapString.MaximumLength,
  700. NULL,
  701. NULL,
  702. STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
  703. "%s%s%s",
  704. SYSDEVICEDIR,
  705. l_UsableName,
  706. TAP_WIN_SUFFIX);
  707. if (l_Status != STATUS_SUCCESS)
  708. {
  709. DEBUGP (("[%s] couldn't format TAP device name\n",
  710. p_Name));
  711. l_Return = NDIS_STATUS_RESOURCES;
  712. goto cleanup;
  713. }
  714. l_TapString.Length = (USHORT) strlen (l_TapString.Buffer);
  715. DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer));
  716. //=======================================================
  717. // Set TAP link name
  718. //=======================================================
  719. l_Status = RtlStringCchPrintfExA
  720. (l_LinkString.Buffer,
  721. l_LinkString.MaximumLength,
  722. NULL,
  723. NULL,
  724. STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
  725. "%s%s%s",
  726. USERDEVICEDIR,
  727. l_UsableName,
  728. TAP_WIN_SUFFIX);
  729. if (l_Status != STATUS_SUCCESS)
  730. {
  731. DEBUGP (("[%s] couldn't format TAP device symbolic link\n",
  732. p_Name));
  733. l_Return = NDIS_STATUS_RESOURCES;
  734. goto cleanup;
  735. }
  736. l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer);
  737. DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer));
  738. //==================================================
  739. // Convert strings to unicode
  740. //==================================================
  741. if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) !=
  742. STATUS_SUCCESS)
  743. {
  744. DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n",
  745. p_Name));
  746. l_Return = NDIS_STATUS_RESOURCES;
  747. goto cleanup;
  748. }
  749. l_FreeTapUnicode = TRUE;
  750. if (RtlAnsiStringToUnicodeString
  751. (&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE)
  752. != STATUS_SUCCESS)
  753. {
  754. DEBUGP
  755. (("[%s] Couldn't allocate unicode string for symbolic link name\n",
  756. p_Name));
  757. l_Return = NDIS_STATUS_RESOURCES;
  758. goto cleanup;
  759. }
  760. p_Extension->m_CreatedUnicodeLinkName = TRUE;
  761. //==================================================
  762. // Create new TAP device with symbolic
  763. // link and associate with adapter.
  764. //==================================================
  765. l_Status = NdisMRegisterDevice
  766. (g_NdisWrapperHandle,
  767. &l_TapUnicode,
  768. &p_Extension->m_UnicodeLinkName,
  769. l_Dispatch,
  770. &p_Extension->m_TapDevice,
  771. &p_Extension->m_TapDeviceHandle
  772. );
  773. if (l_Status != STATUS_SUCCESS)
  774. {
  775. DEBUGP (("[%s] couldn't be created\n", p_Name));
  776. l_Return = NDIS_STATUS_RESOURCES;
  777. goto cleanup;
  778. }
  779. /* Set TAP device flags */
  780. p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO;
  781. //========================================================
  782. // Initialize Packet and IRP queues.
  783. //
  784. // The packet queue is used to buffer data which has been
  785. // "transmitted" by the virtual NIC, before user space
  786. // has had a chance to read it.
  787. //
  788. // The IRP queue is used to buffer pending I/O requests
  789. // from userspace, i.e. read requests on the TAP device
  790. // waiting for the system to "transmit" something through
  791. // the virtual NIC.
  792. //
  793. // Basically, packets in the packet queue are used
  794. // to satisfy IRP requests in the IRP queue.
  795. //
  796. // QueueLock is used to lock the packet queue used
  797. // for the TAP-Windows NIC -> User Space packet flow direction.
  798. //
  799. // All accesses to packet or IRP queues should be
  800. // bracketed by the QueueLock spinlock,
  801. // in order to be SMP-safe.
  802. //========================================================
  803. NdisAllocateSpinLock (&p_Extension->m_QueueLock);
  804. NdisAllocateSpinLock (&p_Extension->m_InjectLock);
  805. p_Extension->m_AllocatedSpinlocks = TRUE;
  806. p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE);
  807. p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE);
  808. p_Extension->m_InjectQueue = QueueInit (INJECT_QUEUE_SIZE);
  809. if (!p_Extension->m_PacketQueue
  810. || !p_Extension->m_IrpQueue
  811. || !p_Extension->m_InjectQueue)
  812. {
  813. DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name));
  814. l_Return = NDIS_STATUS_RESOURCES;
  815. goto cleanup;
  816. }
  817. //=================================================================
  818. // Initialize deferred procedure call for DHCP/ARP packet injection
  819. //=================================================================
  820. KeInitializeDpc (&p_Extension->m_InjectDpc, InjectPacketDpc, NULL);
  821. p_Extension->m_InjectDpcInitialized = TRUE;
  822. //========================
  823. // Finalize initialization
  824. //========================
  825. p_Extension->m_TapIsRunning = TRUE;
  826. DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name,
  827. p_Extension->m_TapName));
  828. cleanup:
  829. if (l_FreeTapUnicode)
  830. RtlFreeUnicodeString (&l_TapUnicode);
  831. if (l_LinkString.Buffer)
  832. MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE);
  833. if (l_Dispatch)
  834. MemFree (l_Dispatch, SIZEOF_DISPATCH);
  835. if (l_Return != NDIS_STATUS_SUCCESS)
  836. TapDeviceFreeResources (p_Extension);
  837. return l_Return;
  838. }
  839. #undef SIZEOF_DISPATCH
  840. //========================================================
  841. // Adapter Control
  842. //========================================================
  843. NDIS_STATUS
  844. AdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext)
  845. {
  846. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  847. DEBUGP (("[%s] is resetting\n", NAME (l_Adapter)));
  848. return NDIS_STATUS_SUCCESS;
  849. }
  850. NDIS_STATUS AdapterReceive
  851. (OUT PNDIS_PACKET p_Packet,
  852. OUT PUINT p_Transferred,
  853. IN NDIS_HANDLE p_AdapterContext,
  854. IN NDIS_HANDLE p_ReceiveContext,
  855. IN UINT p_Offset,
  856. IN UINT p_ToTransfer)
  857. {
  858. return NDIS_STATUS_SUCCESS;
  859. }
  860. //==============================================================
  861. // Adapter Option Query/Modification
  862. //==============================================================
  863. NDIS_STATUS AdapterQuery
  864. (IN NDIS_HANDLE p_AdapterContext,
  865. IN NDIS_OID p_OID,
  866. IN PVOID p_Buffer,
  867. IN ULONG p_BufferLength,
  868. OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded)
  869. {
  870. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  871. TapAdapterQuery l_Query, *l_QueryPtr = &l_Query;
  872. NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS;
  873. UINT l_QueryLength = 4;
  874. BOOLEAN lock_succeeded;
  875. NdisZeroMemory (&l_Query, sizeof (l_Query));
  876. switch (p_OID)
  877. {
  878. //===================================================================
  879. // Vendor & Driver version Info
  880. //===================================================================
  881. case OID_GEN_VENDOR_DESCRIPTION:
  882. l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_TAP_WIN_DEVICE_DESCRIPTION;
  883. l_QueryLength = strlen (PRODUCT_TAP_WIN_DEVICE_DESCRIPTION) + 1;
  884. break;
  885. case OID_GEN_VENDOR_ID:
  886. l_Query.m_Long = 0xffffff;
  887. break;
  888. case OID_GEN_DRIVER_VERSION:
  889. l_Query.m_Short =
  890. (((USHORT) TAP_NDIS_MAJOR_VERSION) << 8 | (USHORT)
  891. TAP_NDIS_MINOR_VERSION);
  892. l_QueryLength = sizeof (unsigned short);
  893. break;
  894. case OID_GEN_VENDOR_DRIVER_VERSION:
  895. l_Query.m_Long =
  896. (((USHORT) PRODUCT_TAP_WIN_MAJOR) << 8 | (USHORT)
  897. PRODUCT_TAP_WIN_MINOR);
  898. break;
  899. //=================================================================
  900. // Statistics
  901. //=================================================================
  902. case OID_GEN_RCV_NO_BUFFER:
  903. l_Query.m_Long = 0;
  904. break;
  905. case OID_802_3_RCV_ERROR_ALIGNMENT:
  906. l_Query.m_Long = 0;
  907. break;
  908. case OID_802_3_XMIT_ONE_COLLISION:
  909. l_Query.m_Long = 0;
  910. break;
  911. case OID_802_3_XMIT_MORE_COLLISIONS:
  912. l_Query.m_Long = 0;
  913. break;
  914. case OID_GEN_XMIT_OK:
  915. l_Query.m_Long = l_Adapter->m_Tx;
  916. break;
  917. case OID_GEN_RCV_OK:
  918. l_Query.m_Long = l_Adapter->m_Rx;
  919. break;
  920. case OID_GEN_XMIT_ERROR:
  921. l_Query.m_Long = l_Adapter->m_TxErr;
  922. break;
  923. case OID_GEN_RCV_ERROR:
  924. l_Query.m_Long = l_Adapter->m_RxErr;
  925. break;
  926. //===================================================================
  927. // Device & Protocol Options
  928. //===================================================================
  929. case OID_GEN_SUPPORTED_LIST:
  930. l_QueryPtr = (TapAdapterQueryPointer) g_SupportedOIDList;
  931. l_QueryLength = sizeof (g_SupportedOIDList);
  932. break;
  933. case OID_GEN_MAC_OPTIONS:
  934. // This MUST be here !!!
  935. l_Query.m_Long = (NDIS_MAC_OPTION_RECEIVE_SERIALIZED
  936. | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
  937. | NDIS_MAC_OPTION_NO_LOOPBACK
  938. | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND);
  939. break;
  940. case OID_GEN_CURRENT_PACKET_FILTER:
  941. l_Query.m_Long =
  942. (NDIS_PACKET_TYPE_ALL_LOCAL |
  943. NDIS_PACKET_TYPE_BROADCAST |
  944. NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL);
  945. break;
  946. case OID_GEN_PROTOCOL_OPTIONS:
  947. l_Query.m_Long = 0;
  948. break;
  949. //==================================================================
  950. // Device Info
  951. //==================================================================
  952. case OID_GEN_MEDIA_CONNECT_STATUS:
  953. l_Query.m_Long = l_Adapter->m_MediaState
  954. ? NdisMediaStateConnected : NdisMediaStateDisconnected;
  955. break;
  956. case OID_GEN_HARDWARE_STATUS:
  957. l_Query.m_HardwareStatus = NdisHardwareStatusReady;
  958. l_QueryLength = sizeof (NDIS_HARDWARE_STATUS);
  959. break;
  960. case OID_GEN_MEDIA_SUPPORTED:
  961. case OID_GEN_MEDIA_IN_USE:
  962. l_Query.m_Medium = l_Adapter->m_Medium;
  963. l_QueryLength = sizeof (NDIS_MEDIUM);
  964. break;
  965. case OID_GEN_PHYSICAL_MEDIUM:
  966. l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified;
  967. l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM);
  968. break;
  969. case OID_GEN_LINK_SPEED:
  970. l_Query.m_Long = 100000; // rate / 100 bps
  971. break;
  972. case OID_802_3_PERMANENT_ADDRESS:
  973. case OID_802_3_CURRENT_ADDRESS:
  974. COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC);
  975. l_QueryLength = sizeof (MACADDR);
  976. break;
  977. //==================================================================
  978. // Limits
  979. //==================================================================
  980. case OID_GEN_MAXIMUM_SEND_PACKETS:
  981. l_Query.m_Long = 1;
  982. break;
  983. case OID_802_3_MAXIMUM_LIST_SIZE:
  984. l_Query.m_Long = NIC_MAX_MCAST_LIST;
  985. break;
  986. case OID_GEN_CURRENT_LOOKAHEAD:
  987. l_Query.m_Long = l_Adapter->m_Lookahead;
  988. break;
  989. case OID_GEN_MAXIMUM_LOOKAHEAD:
  990. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  991. case OID_GEN_RECEIVE_BUFFER_SPACE:
  992. case OID_GEN_RECEIVE_BLOCK_SIZE:
  993. l_Query.m_Long = DEFAULT_PACKET_LOOKAHEAD;
  994. break;
  995. case OID_GEN_MAXIMUM_FRAME_SIZE:
  996. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  997. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  998. l_Query.m_Long = l_Adapter->m_MTU;
  999. break;
  1000. case OID_PNP_CAPABILITIES:
  1001. do
  1002. {
  1003. PNDIS_PNP_CAPABILITIES pPNPCapabilities;
  1004. PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct;
  1005. if (p_BufferLength >= sizeof (NDIS_PNP_CAPABILITIES))
  1006. {
  1007. pPNPCapabilities = (PNDIS_PNP_CAPABILITIES) (p_Buffer);
  1008. //
  1009. // Setting up the buffer to be returned
  1010. // to the Protocol above the Passthru miniport
  1011. //
  1012. pPMstruct = &pPNPCapabilities->WakeUpCapabilities;
  1013. pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
  1014. pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
  1015. pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
  1016. }
  1017. l_QueryLength = sizeof (NDIS_PNP_CAPABILITIES);
  1018. }
  1019. while (FALSE);
  1020. break;
  1021. case OID_PNP_QUERY_POWER:
  1022. break;
  1023. // Required OIDs that we don't support
  1024. case OID_GEN_SUPPORTED_GUIDS:
  1025. case OID_GEN_MEDIA_CAPABILITIES:
  1026. case OID_TCP_TASK_OFFLOAD:
  1027. case OID_FFP_SUPPORT:
  1028. l_Status = NDIS_STATUS_INVALID_OID;
  1029. break;
  1030. // Optional stats OIDs
  1031. case OID_GEN_DIRECTED_BYTES_XMIT:
  1032. case OID_GEN_DIRECTED_FRAMES_XMIT:
  1033. case OID_GEN_MULTICAST_BYTES_XMIT:
  1034. case OID_GEN_MULTICAST_FRAMES_XMIT:
  1035. case OID_GEN_BROADCAST_BYTES_XMIT:
  1036. case OID_GEN_BROADCAST_FRAMES_XMIT:
  1037. case OID_GEN_DIRECTED_BYTES_RCV:
  1038. case OID_GEN_DIRECTED_FRAMES_RCV:
  1039. case OID_GEN_MULTICAST_BYTES_RCV:
  1040. case OID_GEN_MULTICAST_FRAMES_RCV:
  1041. case OID_GEN_BROADCAST_BYTES_RCV:
  1042. case OID_GEN_BROADCAST_FRAMES_RCV:
  1043. l_Status = NDIS_STATUS_INVALID_OID;
  1044. break;
  1045. //===================================================================
  1046. // Not Handled
  1047. //===================================================================
  1048. default:
  1049. DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID));
  1050. l_Status = NDIS_STATUS_INVALID_OID;
  1051. break;
  1052. }
  1053. if (l_Status != NDIS_STATUS_SUCCESS)
  1054. ;
  1055. else if (l_QueryLength > p_BufferLength)
  1056. {
  1057. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1058. *p_BytesNeeded = l_QueryLength;
  1059. }
  1060. else
  1061. NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr,
  1062. (*p_BytesWritten = l_QueryLength));
  1063. return l_Status;
  1064. }
  1065. NDIS_STATUS AdapterModify
  1066. (IN NDIS_HANDLE p_AdapterContext,
  1067. IN NDIS_OID p_OID,
  1068. IN PVOID p_Buffer,
  1069. IN ULONG p_BufferLength,
  1070. OUT PULONG p_BytesRead,
  1071. OUT PULONG p_BytesNeeded)
  1072. {
  1073. TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer;
  1074. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  1075. NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID;
  1076. ULONG l_Long;
  1077. switch (p_OID)
  1078. {
  1079. //==================================================================
  1080. // Device Info
  1081. //==================================================================
  1082. case OID_802_3_MULTICAST_LIST:
  1083. DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n",
  1084. NAME (l_Adapter)));
  1085. *p_BytesNeeded = sizeof (ETH_ADDR);
  1086. *p_BytesRead = p_BufferLength;
  1087. if (p_BufferLength % sizeof (ETH_ADDR))
  1088. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1089. else if (p_BufferLength > sizeof (MC_LIST))
  1090. {
  1091. l_Status = NDIS_STATUS_MULTICAST_FULL;
  1092. *p_BytesNeeded = sizeof (MC_LIST);
  1093. }
  1094. else
  1095. {
  1096. NdisAcquireSpinLock (&l_Adapter->m_MCLock);
  1097. NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST));
  1098. NdisMoveMemory(&l_Adapter->m_MCList,
  1099. p_Buffer,
  1100. p_BufferLength);
  1101. l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR);
  1102. NdisReleaseSpinLock (&l_Adapter->m_MCLock);
  1103. l_Status = NDIS_STATUS_SUCCESS;
  1104. }
  1105. break;
  1106. case OID_GEN_CURRENT_PACKET_FILTER:
  1107. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1108. *p_BytesNeeded = 4;
  1109. if (p_BufferLength >= sizeof (ULONG))
  1110. {
  1111. DEBUGP
  1112. (("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n",
  1113. NAME (l_Adapter), l_Query->m_Long));
  1114. l_Status = NDIS_STATUS_SUCCESS;
  1115. *p_BytesRead = sizeof (ULONG);
  1116. }
  1117. break;
  1118. case OID_GEN_CURRENT_LOOKAHEAD:
  1119. if (p_BufferLength < sizeof (ULONG))
  1120. {
  1121. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1122. *p_BytesNeeded = 4;
  1123. }
  1124. else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD
  1125. || l_Query->m_Long <= 0)
  1126. {
  1127. l_Status = NDIS_STATUS_INVALID_DATA;
  1128. }
  1129. else
  1130. {
  1131. DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n",
  1132. NAME (l_Adapter), l_Query->m_Long));
  1133. l_Adapter->m_Lookahead = l_Query->m_Long;
  1134. l_Status = NDIS_STATUS_SUCCESS;
  1135. *p_BytesRead = sizeof (ULONG);
  1136. }
  1137. break;
  1138. case OID_GEN_NETWORK_LAYER_ADDRESSES:
  1139. l_Status = NDIS_STATUS_SUCCESS;
  1140. *p_BytesRead = *p_BytesNeeded = 0;
  1141. break;
  1142. case OID_GEN_TRANSPORT_HEADER_OFFSET:
  1143. l_Status = NDIS_STATUS_SUCCESS;
  1144. *p_BytesRead = *p_BytesNeeded = 0;
  1145. break;
  1146. case OID_PNP_SET_POWER:
  1147. do
  1148. {
  1149. NDIS_DEVICE_POWER_STATE NewDeviceState;
  1150. NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE) p_Buffer);
  1151. switch (NewDeviceState)
  1152. {
  1153. case NdisDeviceStateD0:
  1154. l_Adapter->m_DeviceState = '0';
  1155. break;
  1156. case NdisDeviceStateD1:
  1157. l_Adapter->m_DeviceState = '1';
  1158. break;
  1159. case NdisDeviceStateD2:
  1160. l_Adapter->m_DeviceState = '2';
  1161. break;
  1162. case NdisDeviceStateD3:
  1163. l_Adapter->m_DeviceState = '3';
  1164. break;
  1165. default:
  1166. l_Adapter->m_DeviceState = '?';
  1167. break;
  1168. }
  1169. l_Status = NDIS_STATUS_FAILURE;
  1170. //
  1171. // Check for invalid length
  1172. //
  1173. if (p_BufferLength < sizeof (NDIS_DEVICE_POWER_STATE))
  1174. {
  1175. l_Status = NDIS_STATUS_INVALID_LENGTH;
  1176. break;
  1177. }
  1178. if (NewDeviceState > NdisDeviceStateD0)
  1179. {
  1180. l_Adapter->m_InterfaceIsRunning = FALSE;
  1181. DEBUGP (("[%s] Power management device state OFF\n",
  1182. NAME (l_Adapter)));
  1183. }
  1184. else
  1185. {
  1186. l_Adapter->m_InterfaceIsRunning = TRUE;
  1187. DEBUGP (("[%s] Power management device state ON\n",
  1188. NAME (l_Adapter)));
  1189. }
  1190. l_Status = NDIS_STATUS_SUCCESS;
  1191. }
  1192. while (FALSE);
  1193. if (l_Status == NDIS_STATUS_SUCCESS)
  1194. {
  1195. *p_BytesRead = sizeof (NDIS_DEVICE_POWER_STATE);
  1196. *p_BytesNeeded = 0;
  1197. }
  1198. else
  1199. {
  1200. *p_BytesRead = 0;
  1201. *p_BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
  1202. }
  1203. break;
  1204. case OID_PNP_REMOVE_WAKE_UP_PATTERN:
  1205. case OID_PNP_ADD_WAKE_UP_PATTERN:
  1206. l_Status = NDIS_STATUS_SUCCESS;
  1207. *p_BytesRead = *p_BytesNeeded = 0;
  1208. break;
  1209. default:
  1210. DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter),
  1211. p_OID));
  1212. l_Status = NDIS_STATUS_INVALID_OID;
  1213. *p_BytesRead = *p_BytesNeeded = 0;
  1214. break;
  1215. }
  1216. return l_Status;
  1217. }
  1218. // checksum code for ICMPv6 packet, taken from dhcp.c / udp_checksum
  1219. // see RFC 4443, 2.3, and RFC 2460, 8.1
  1220. USHORT
  1221. icmpv6_checksum (const UCHAR *buf,
  1222. const int len_icmpv6,
  1223. const UCHAR *saddr6,
  1224. const UCHAR *daddr6)
  1225. {
  1226. USHORT word16;
  1227. ULONG sum = 0;
  1228. int i;
  1229. // make 16 bit words out of every two adjacent 8 bit words and
  1230. // calculate the sum of all 16 bit words
  1231. for (i = 0; i < len_icmpv6; i += 2){
  1232. word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_icmpv6) ? (buf[i+1] & 0xFF) : 0);
  1233. sum += word16;
  1234. }
  1235. // add the IPv6 pseudo header which contains the IP source and destination addresses
  1236. for (i = 0; i < 16; i += 2){
  1237. word16 =((saddr6[i] << 8) & 0xFF00) + (saddr6[i+1] & 0xFF);
  1238. sum += word16;
  1239. }
  1240. for (i = 0; i < 16; i += 2){
  1241. word16 =((daddr6[i] << 8) & 0xFF00) + (daddr6[i+1] & 0xFF);
  1242. sum += word16;
  1243. }
  1244. // the next-header number and the length of the ICMPv6 packet
  1245. sum += (USHORT) IPPROTO_ICMPV6 + (USHORT) len_icmpv6;
  1246. // keep only the last 16 bits of the 32 bit calculated sum and add the carries
  1247. while (sum >> 16)
  1248. sum = (sum & 0xFFFF) + (sum >> 16);
  1249. // Take the one's complement of sum
  1250. return ((USHORT) ~sum);
  1251. }
  1252. // check IPv6 packet for "is this an IPv6 Neighbor Solicitation that
  1253. // the tap driver needs to answer?"
  1254. // see RFC 4861 4.3 for the different cases
  1255. static IPV6ADDR IPV6_NS_TARGET_MCAST =
  1256. { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1257. 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x08 };
  1258. static IPV6ADDR IPV6_NS_TARGET_UNICAST =
  1259. { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1260. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 };
  1261. BOOLEAN
  1262. HandleIPv6NeighborDiscovery( TapAdapterPointer p_Adapter, UCHAR * m_Data )
  1263. {
  1264. const ETH_HEADER * e = (ETH_HEADER *) m_Data;
  1265. const IPV6HDR *ipv6 = (IPV6HDR *) (m_Data + sizeof (ETH_HEADER));
  1266. const ICMPV6_NS * icmpv6_ns = (ICMPV6_NS *) (m_Data + sizeof (ETH_HEADER) + sizeof (IPV6HDR));
  1267. ICMPV6_NA_PKT *na;
  1268. USHORT icmpv6_len, icmpv6_csum;
  1269. // we don't really care about the destination MAC address here
  1270. // - it's either a multicast MAC, or the userland destination MAC
  1271. // but since the TAP driver is point-to-point, all packets are "for us"
  1272. // IPv6 target address must be ff02::1::ff00:8 (multicast for
  1273. // initial NS) or fe80::1 (unicast for recurrent NUD)
  1274. if ( memcmp( ipv6->daddr, IPV6_NS_TARGET_MCAST,
  1275. sizeof(IPV6ADDR) ) != 0 &&
  1276. memcmp( ipv6->daddr, IPV6_NS_TARGET_UNICAST,
  1277. sizeof(IPV6ADDR) ) != 0 )
  1278. {
  1279. return FALSE; // wrong target address
  1280. }
  1281. // IPv6 Next-Header must be ICMPv6
  1282. if ( ipv6->nexthdr != IPPROTO_ICMPV6 )
  1283. {
  1284. return FALSE; // wrong next-header
  1285. }
  1286. // ICMPv6 type+code must be 135/0 for NS
  1287. if ( icmpv6_ns->type != ICMPV6_TYPE_NS ||
  1288. icmpv6_ns->code != ICMPV6_CODE_0 )
  1289. {
  1290. return FALSE; // wrong ICMPv6 type
  1291. }
  1292. // ICMPv6 target address must be fe80::8 (magic)
  1293. if ( memcmp( icmpv6_ns->target_addr, IPV6_NS_TARGET_UNICAST,
  1294. sizeof(IPV6ADDR) ) != 0 )
  1295. {
  1296. return FALSE; // not for us
  1297. }
  1298. // packet identified, build magic response packet
  1299. na = (ICMPV6_NA_PKT *) MemAlloc (sizeof (ICMPV6_NA_PKT), TRUE);
  1300. if ( !na ) return FALSE;
  1301. //------------------------------------------------
  1302. // Initialize Neighbour Advertisement reply packet
  1303. //------------------------------------------------
  1304. // ethernet header
  1305. na->eth.proto = htons(ETH_P_IPV6);
  1306. COPY_MAC(na->eth.dest, p_Adapter->m_MAC);
  1307. COPY_MAC(na->eth.src, p_Adapter->m_TapToUser.dest);
  1308. // IPv6 header
  1309. na->ipv6.version_prio = ipv6->version_prio;
  1310. NdisMoveMemory( na->ipv6.flow_lbl, ipv6->flow_lbl,
  1311. sizeof(na->ipv6.flow_lbl) );
  1312. icmpv6_len = sizeof(ICMPV6_NA_PKT) - sizeof(ETH_HEADER) - sizeof(IPV6HDR);
  1313. na->ipv6.payload_len = htons(icmpv6_len);
  1314. na->ipv6.nexthdr = IPPROTO_ICMPV6;
  1315. na->ipv6.hop_limit = 255;
  1316. NdisMoveMemory( na->ipv6.saddr, IPV6_NS_TARGET_UNICAST,
  1317. sizeof(IPV6ADDR) );
  1318. NdisMoveMemory( na->ipv6.daddr, ipv6->saddr,
  1319. sizeof(IPV6ADDR) );
  1320. // ICMPv6
  1321. na->icmpv6.type = ICMPV6_TYPE_NA;
  1322. na->icmpv6.code = ICMPV6_CODE_0;
  1323. na->icmpv6.checksum = 0;
  1324. na->icmpv6.rso_bits = 0x60; // Solicited + Override
  1325. NdisZeroMemory( na->icmpv6.reserved, sizeof(na->icmpv6.reserved) );
  1326. NdisMoveMemory( na->icmpv6.target_addr, IPV6_NS_TARGET_UNICAST,
  1327. sizeof(IPV6ADDR) );
  1328. // ICMPv6 option "Target Link Layer Address"
  1329. na->icmpv6.opt_type = ICMPV6_OPTION_TLLA;
  1330. na->icmpv6.opt_length = ICMPV6_LENGTH_TLLA;
  1331. COPY_MAC( na->icmpv6.target_macaddr, p_Adapter->m_TapToUser.dest );
  1332. // calculate and set checksum
  1333. icmpv6_csum = icmpv6_checksum ( (UCHAR*) &(na->icmpv6),
  1334. icmpv6_len,
  1335. na->ipv6.saddr,
  1336. na->ipv6.daddr );
  1337. na->icmpv6.checksum = htons( icmpv6_csum );
  1338. DUMP_PACKET ("HandleIPv6NeighborDiscovery",
  1339. (unsigned char *) na,
  1340. sizeof (ICMPV6_NA_PKT));
  1341. InjectPacketDeferred (p_Adapter, (UCHAR *) na, sizeof (ICMPV6_NA_PKT));
  1342. MemFree (na, sizeof (ICMPV6_NA_PKT));
  1343. return TRUE; // all fine
  1344. }
  1345. //====================================================================
  1346. // Adapter Transmission
  1347. //====================================================================
  1348. NDIS_STATUS
  1349. AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
  1350. IN PNDIS_PACKET p_Packet,
  1351. IN UINT p_Flags)
  1352. {
  1353. TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
  1354. ULONG l_Index = 0, l_PacketLength = 0;
  1355. UINT l_BufferLength = 0;
  1356. PIRP l_IRP;
  1357. TapPacketPointer l_PacketBuffer;
  1358. PNDIS_BUFFER l_NDIS_Buffer;
  1359. PUCHAR l_Buffer;
  1360. PVOID result;
  1361. NdisQueryPacket (p_Packet, NULL, NULL, &l_NDIS_Buffer, &l_PacketLength);
  1362. //====================================================
  1363. // Here we abandon the transmission attempt if any of
  1364. // the parameters is wrong or memory allocation fails
  1365. // but we do not indicate failure. The packet is
  1366. // silently dropped.
  1367. //====================================================
  1368. if (l_PacketLength < ETHERNET_HEADER_SIZE || l_PacketLength > 65535)
  1369. goto exit_fail;
  1370. else if (!l_Adapter->m_Extension.m_TapOpens || !l_Adapter->m_MediaState)
  1371. goto exit_success; // Nothing is bound to the TAP device
  1372. if (NdisAllocateMemoryWithTag (&l_PacketBuffer,
  1373. TAP_PACKET_SIZE (l_PacketLength),
  1374. '5PAT') != NDIS_STATUS_SUCCESS)
  1375. goto exit_no_resources;
  1376. if (l_PacketBuffer == NULL)
  1377. goto exit_no_resources;
  1378. l_PacketBuffer->m_SizeFlags = (l_PacketLength & TP_SIZE_MASK);
  1379. //===========================
  1380. // Reassemble packet contents
  1381. //===========================
  1382. __try
  1383. {
  1384. l_Index = 0;
  1385. while (l_NDIS_Buffer && l_Index < l_PacketLength)
  1386. {
  1387. ULONG newlen;
  1388. NdisQueryBuffer (l_NDIS_Buffer, (PVOID *) & l_Buffer,
  1389. &l_BufferLength);
  1390. newlen = l_Index + l_BufferLength;
  1391. if (newlen > l_PacketLength)
  1392. {
  1393. NOTE_ERROR ();
  1394. goto no_queue; /* overflow */
  1395. }
  1396. NdisMoveMemory (l_PacketBuffer->m_Data + l_Index, l_Buffer,
  1397. l_BufferLength);
  1398. l_Index = newlen;
  1399. NdisGetNextBuffer (l_NDIS_Buffer, &l_NDIS_Buffer);
  1400. }
  1401. if (l_Index != l_PacketLength)
  1402. {
  1403. NOTE_ERROR ();
  1404. goto no_queue; /* underflow */
  1405. }
  1406. DUMP_PACKET ("AdapterTransmit", l_PacketBuffer->m_Data, l_PacketLength);
  1407. //=====================================================
  1408. // If IPv4 packet, check whether or not packet
  1409. // was truncated.
  1410. //=====================================================
  1411. #if PACKET_TRUNCATION_CHECK
  1412. IPv4PacketSizeVerify (l_PacketBuffer->m_Data, l_PacketLength, FALSE, "TX", &l_Adapter->m_TxTrunc);
  1413. #endif
  1414. //=====================================================
  1415. // Are we running in DHCP server masquerade mode?
  1416. //
  1417. // If so, catch both DHCP requests and ARP queries
  1418. // to resolve the address of our virtual DHCP server.
  1419. //=====================================================
  1420. if (l_Adapter->m_dhcp_enabled)
  1421. {
  1422. const ETH_HEADER *eth = (ETH_HEADER *) l_PacketBuffer->m_Data;
  1423. const IPHDR *ip = (IPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER));
  1424. const UDPHDR *udp = (UDPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER) + sizeof (IPHDR));
  1425. // ARP packet?
  1426. if (l_PacketLength == sizeof (ARP_PACKET)
  1427. && eth->proto == htons (ETH_P_ARP)
  1428. && l_Adapter->m_dhcp_server_arp)
  1429. {
  1430. if (ProcessARP (l_Adapter,
  1431. (PARP_PACKET) l_PacketBuffer->m_Data,
  1432. l_Adapter->m_dhcp_addr,
  1433. l_Adapter->m_dhcp_server_ip,
  1434. ~0,
  1435. l_Adapter->m_dhcp_server_mac))
  1436. goto no_queue;
  1437. }
  1438. // DHCP packet?
  1439. else if (l_PacketLength >= sizeof (ETH_HEADER) + sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP)
  1440. && eth->proto == htons (ETH_P_IP)
  1441. && ip->version_len == 0x45 // IPv4, 20 byte header
  1442. && ip->protocol == IPPROTO_UDP
  1443. && udp->dest == htons (BOOTPS_PORT))
  1444. {
  1445. const DHCP *dhcp = (DHCP *) (l_PacketBuffer->m_Data
  1446. + sizeof (ETH_HEADER)
  1447. + sizeof (IPHDR)
  1448. + sizeof (UDPHDR));
  1449. const int optlen = l_PacketLength
  1450. - sizeof (ETH_HEADER)
  1451. - sizeof (IPHDR)
  1452. - sizeof (UDPHDR)
  1453. - sizeof (DHCP);
  1454. if (optlen > 0) // we must have at least one DHCP option
  1455. {
  1456. if (ProcessDHCP (l_Adapter, eth, ip, udp, dhcp, optlen))
  1457. goto no_queue;
  1458. }
  1459. else
  1460. goto no_queue;
  1461. }
  1462. }
  1463. //===============================================
  1464. // In Point-To-Point mode, check to see whether
  1465. // packet is ARP (handled) or IPv4 (sent to app).
  1466. // IPv6 packets are inspected for neighbour discovery
  1467. // (to be handled locally), and the rest is forwarded
  1468. // all other protocols are dropped
  1469. //===============================================
  1470. if (l_Adapter->m_tun)
  1471. {
  1472. ETH_HEADER *e;
  1473. if (l_PacketLength < ETHERNET_HEADER_SIZE)
  1474. goto no_queue;
  1475. e = (ETH_HEADER *) l_PacketBuffer->m_Data;
  1476. switch (ntohs (e->proto))
  1477. {
  1478. case ETH_P_ARP:
  1479. // Make sure that packet is the
  1480. // right size for ARP.
  1481. if (l_PacketLength != sizeof (ARP_PACKET))
  1482. goto no_queue;
  1483. ProcessARP (l_Adapter,
  1484. (PARP_PACKET) l_PacketBuffer->m_Data,
  1485. l_Adapter->m_localIP,
  1486. l_Adapter->m_remoteNetwork,
  1487. l_Adapter->m_remoteNetmask,
  1488. l_Adapter->m_TapToUser.dest);
  1489. default:
  1490. goto no_queue;
  1491. case ETH_P_IP:
  1492. // Make sure that packet is large
  1493. // enough to be IPv4.
  1494. if (l_PacketLength
  1495. < ETHERNET_HEADER_SIZE + IP_HEADER_SIZE)
  1496. goto no_queue;
  1497. // Only accept directed packets,
  1498. // not broadcasts.
  1499. if (memcmp (e, &l_Adapter->m_TapToUser, ETHERNET_HEADER_SIZE))
  1500. goto no_queue;
  1501. // Packet looks like IPv4, queue it.
  1502. l_PacketBuffer->m_SizeFlags |= TP_TUN;
  1503. break;
  1504. case ETH_P_IPV6:
  1505. // make sure that packet is large
  1506. // enough to be IPv6
  1507. if (l_PacketLength
  1508. < ETHERNET_HEADER_SIZE + IPV6_HEADER_SIZE)
  1509. goto no_queue;
  1510. // broadcasts and multicasts are handled specially
  1511. // (to be implemented)
  1512. // neighbor discovery packets to fe80::8 are special
  1513. // OpenVPN sets this next-hop to signal "handled by tapdrv"
  1514. if ( HandleIPv6NeighborDiscovery( l_Adapter,
  1515. l_PacketBuffer->m_Data ))
  1516. {
  1517. goto no_queue;
  1518. }
  1519. // Packet looks like IPv6, queue it :-)
  1520. l_PacketBuffer->m_SizeFlags |= TP_TUN;
  1521. }
  1522. }
  1523. //===============================================
  1524. // Push packet onto queue to wait for read from
  1525. // userspace.
  1526. //===============================================
  1527. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1528. result = NULL;
  1529. if (IS_UP (l_Adapter))
  1530. result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer);
  1531. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1532. if ((TapPacketPointer) result != l_PacketBuffer)
  1533. {
  1534. // adapter receive overrun
  1535. INCREMENT_STAT (l_Adapter->m_TxErr);
  1536. goto no_queue;
  1537. }
  1538. else
  1539. {
  1540. INCREMENT_STAT (l_Adapter->m_Tx);
  1541. }
  1542. //============================================================
  1543. // Cycle through IRPs and packets, try to satisfy each pending
  1544. // IRP with a queued packet.
  1545. //============================================================
  1546. while (TRUE)
  1547. {
  1548. l_IRP = NULL;
  1549. l_PacketBuffer = NULL;
  1550. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1551. if (IS_UP (l_Adapter)
  1552. && QueueCount (l_Adapter->m_Extension.m_PacketQueue)
  1553. && QueueCount (l_Adapter->m_Extension.m_IrpQueue))
  1554. {
  1555. l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue);
  1556. l_PacketBuffer = (TapPacketPointer)
  1557. QueuePop (l_Adapter->m_Extension.m_PacketQueue);
  1558. }
  1559. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1560. MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1);
  1561. if (l_IRP && l_PacketBuffer)
  1562. {
  1563. CompleteIRP (l_IRP,
  1564. l_PacketBuffer,
  1565. IO_NETWORK_INCREMENT);
  1566. }
  1567. else
  1568. break;
  1569. }
  1570. }
  1571. __except (EXCEPTION_EXECUTE_HANDLER)
  1572. {
  1573. }
  1574. return NDIS_STATUS_SUCCESS;
  1575. no_queue:
  1576. NdisFreeMemory (l_PacketBuffer,
  1577. TAP_PACKET_SIZE (l_PacketLength),
  1578. 0);
  1579. exit_success:
  1580. return NDIS_STATUS_SUCCESS;
  1581. exit_fail:
  1582. return NDIS_STATUS_FAILURE;
  1583. exit_no_resources:
  1584. return NDIS_STATUS_RESOURCES;
  1585. }
  1586. //======================================================================
  1587. // Hooks for catching TAP device IRP's.
  1588. //======================================================================
  1589. DRIVER_DISPATCH TapDeviceHook;
  1590. NTSTATUS
  1591. TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
  1592. {
  1593. TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
  1594. PIO_STACK_LOCATION l_IrpSp;
  1595. NTSTATUS l_Status = STATUS_SUCCESS;
  1596. BOOLEAN accessible;
  1597. l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP);
  1598. p_IRP->IoStatus.Status = STATUS_SUCCESS;
  1599. p_IRP->IoStatus.Information = 0;
  1600. if (!l_Adapter || l_Adapter->m_Extension.m_Halt)
  1601. {
  1602. DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n",
  1603. (int)l_IrpSp->MajorFunction));
  1604. if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE)
  1605. {
  1606. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1607. return STATUS_SUCCESS;
  1608. }
  1609. else
  1610. {
  1611. p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
  1612. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1613. return STATUS_NO_SUCH_DEVICE;
  1614. }
  1615. }
  1616. switch (l_IrpSp->MajorFunction)
  1617. {
  1618. //===========================================================
  1619. // Ioctl call handlers
  1620. //===========================================================
  1621. case IRP_MJ_DEVICE_CONTROL:
  1622. {
  1623. switch (l_IrpSp->Parameters.DeviceIoControl.IoControlCode)
  1624. {
  1625. case TAP_WIN_IOCTL_GET_MAC:
  1626. {
  1627. if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
  1628. >= sizeof (MACADDR))
  1629. {
  1630. COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer,
  1631. l_Adapter->m_MAC);
  1632. p_IRP->IoStatus.Information = sizeof (MACADDR);
  1633. }
  1634. else
  1635. {
  1636. NOTE_ERROR ();
  1637. p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
  1638. }
  1639. break;
  1640. }
  1641. case TAP_WIN_IOCTL_GET_VERSION:
  1642. {
  1643. const ULONG size = sizeof (ULONG) * 3;
  1644. if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
  1645. >= size)
  1646. {
  1647. ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]
  1648. = TAP_DRIVER_MAJOR_VERSION;
  1649. ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1]
  1650. = TAP_DRIVER_MINOR_VERSION;
  1651. ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2]
  1652. #if DBG
  1653. = 1;
  1654. #else
  1655. = 0;
  1656. #endif
  1657. p_IRP->IoStatus.Information = size;
  1658. }
  1659. else
  1660. {
  1661. NOTE_ERROR ();
  1662. p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
  1663. }
  1664. break;
  1665. }
  1666. case TAP_WIN_IOCTL_GET_MTU:
  1667. {
  1668. const ULONG size = sizeof (ULONG) * 1;
  1669. if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength
  1670. >= size)
  1671. {
  1672. ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]
  1673. = l_Adapter->m_MTU;
  1674. p_IRP->IoStatus.Information = size;
  1675. }
  1676. else
  1677. {
  1678. NOTE_ERROR ();
  1679. p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
  1680. }
  1681. break;
  1682. }
  1683. case TAP_WIN_IOCTL_GET_INFO:
  1684. {
  1685. char state[16];
  1686. if (l_Adapter->m_InterfaceIsRunning)
  1687. state[0] = 'A';
  1688. else
  1689. state[0] = 'a';
  1690. if (l_Adapter->m_Extension.m_TapIsRunning)
  1691. state[1] = 'T';
  1692. else
  1693. state[1] = 't';
  1694. state[2] = l_Adapter->m_DeviceState;
  1695. if (l_Adapter->m_MediaStateAlwaysConnected)
  1696. state[3] = 'C';
  1697. else
  1698. state[3] = 'c';
  1699. state[4] = '\0';
  1700. p_IRP->IoStatus.Status = l_Status = RtlStringCchPrintfExA (
  1701. ((LPTSTR) (p_IRP->AssociatedIrp.SystemBuffer)),
  1702. l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
  1703. NULL,
  1704. NULL,
  1705. STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
  1706. #if PACKET_TRUNCATION_CHECK
  1707. "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d,%d] Rx=[%d,%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]",
  1708. #else
  1709. "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]",
  1710. #endif
  1711. state,
  1712. g_LastErrorFilename,
  1713. g_LastErrorLineNumber,
  1714. (int)l_Adapter->m_Extension.m_NumTapOpens,
  1715. (int)l_Adapter->m_Tx,
  1716. (int)l_Adapter->m_TxErr,
  1717. #if PACKET_TRUNCATION_CHECK
  1718. (int)l_Adapter->m_TxTrunc,
  1719. #endif
  1720. (int)l_Adapter->m_Rx,
  1721. (int)l_Adapter->m_RxErr,
  1722. #if PACKET_TRUNCATION_CHECK
  1723. (int)l_Adapter->m_RxTrunc,
  1724. #endif
  1725. (int)l_Adapter->m_Extension.m_IrpQueue->size,
  1726. (int)l_Adapter->m_Extension.m_IrpQueue->max_size,
  1727. (int)IRP_QUEUE_SIZE,
  1728. (int)l_Adapter->m_Extension.m_PacketQueue->size,
  1729. (int)l_Adapter->m_Extension.m_PacketQueue->max_size,
  1730. (int)PACKET_QUEUE_SIZE,
  1731. (int)l_Adapter->m_Extension.m_InjectQueue->size,
  1732. (int)l_Adapter->m_Extension.m_InjectQueue->max_size,
  1733. (int)INJECT_QUEUE_SIZE
  1734. );
  1735. p_IRP->IoStatus.Information
  1736. = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  1737. break;
  1738. }
  1739. #if DBG
  1740. case TAP_WIN_IOCTL_GET_LOG_LINE:
  1741. {
  1742. if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer,
  1743. l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength))
  1744. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  1745. else
  1746. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1747. p_IRP->IoStatus.Information
  1748. = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  1749. break;
  1750. }
  1751. #endif
  1752. case TAP_WIN_IOCTL_CONFIG_TUN:
  1753. {
  1754. if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
  1755. (sizeof (IPADDR) * 3))
  1756. {
  1757. MACADDR dest;
  1758. l_Adapter->m_tun = FALSE;
  1759. GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);
  1760. l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
  1761. l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
  1762. l_Adapter->m_remoteNetmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2];
  1763. // sanity check on network/netmask
  1764. if ((l_Adapter->m_remoteNetwork & l_Adapter->m_remoteNetmask) != l_Adapter->m_remoteNetwork)
  1765. {
  1766. NOTE_ERROR ();
  1767. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1768. break;
  1769. }
  1770. COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC);
  1771. COPY_MAC (l_Adapter->m_TapToUser.dest, dest);
  1772. COPY_MAC (l_Adapter->m_UserToTap.src, dest);
  1773. COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC);
  1774. l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);
  1775. l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap;
  1776. l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6);
  1777. l_Adapter->m_tun = TRUE;
  1778. CheckIfDhcpAndTunMode (l_Adapter);
  1779. p_IRP->IoStatus.Information = 1; // Simple boolean value
  1780. }
  1781. else
  1782. {
  1783. NOTE_ERROR ();
  1784. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1785. }
  1786. break;
  1787. }
  1788. case TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT: // Obsoleted by TAP_WIN_IOCTL_CONFIG_TUN
  1789. {
  1790. if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
  1791. (sizeof (IPADDR) * 2))
  1792. {
  1793. MACADDR dest;
  1794. l_Adapter->m_tun = FALSE;
  1795. GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);
  1796. l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
  1797. l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
  1798. l_Adapter->m_remoteNetmask = ~0;
  1799. COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC);
  1800. COPY_MAC (l_Adapter->m_TapToUser.dest, dest);
  1801. COPY_MAC (l_Adapter->m_UserToTap.src, dest);
  1802. COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC);
  1803. l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);
  1804. l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap;
  1805. l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6);
  1806. l_Adapter->m_tun = TRUE;
  1807. CheckIfDhcpAndTunMode (l_Adapter);
  1808. p_IRP->IoStatus.Information = 1; // Simple boolean value
  1809. }
  1810. else
  1811. {
  1812. NOTE_ERROR ();
  1813. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1814. }
  1815. break;
  1816. }
  1817. case TAP_WIN_IOCTL_SET_MEDIA_STATUS:
  1818. {
  1819. if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
  1820. (sizeof (ULONG) * 1))
  1821. {
  1822. ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0];
  1823. SetMediaStatus (l_Adapter, (BOOLEAN) parm);
  1824. p_IRP->IoStatus.Information = 1;
  1825. }
  1826. else
  1827. {
  1828. NOTE_ERROR ();
  1829. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1830. }
  1831. break;
  1832. }
  1833. case TAP_WIN_IOCTL_CONFIG_DHCP_MASQ:
  1834. {
  1835. if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
  1836. (sizeof (IPADDR) * 4))
  1837. {
  1838. l_Adapter->m_dhcp_enabled = FALSE;
  1839. l_Adapter->m_dhcp_server_arp = FALSE;
  1840. l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
  1841. // Adapter IP addr / netmask
  1842. l_Adapter->m_dhcp_addr =
  1843. ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
  1844. l_Adapter->m_dhcp_netmask =
  1845. ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1];
  1846. // IP addr of DHCP masq server
  1847. l_Adapter->m_dhcp_server_ip =
  1848. ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2];
  1849. // Lease time in seconds
  1850. l_Adapter->m_dhcp_lease_time =
  1851. ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[3];
  1852. GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2);
  1853. l_Adapter->m_dhcp_enabled = TRUE;
  1854. l_Adapter->m_dhcp_server_arp = TRUE;
  1855. CheckIfDhcpAndTunMode (l_Adapter);
  1856. p_IRP->IoStatus.Information = 1; // Simple boolean value
  1857. }
  1858. else
  1859. {
  1860. NOTE_ERROR ();
  1861. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1862. }
  1863. break;
  1864. }
  1865. case TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT:
  1866. {
  1867. if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength <=
  1868. DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE
  1869. && l_Adapter->m_dhcp_enabled)
  1870. {
  1871. l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
  1872. NdisMoveMemory (l_Adapter->m_dhcp_user_supplied_options_buffer,
  1873. p_IRP->AssociatedIrp.SystemBuffer,
  1874. l_IrpSp->Parameters.DeviceIoControl.InputBufferLength);
  1875. l_Adapter->m_dhcp_user_supplied_options_buffer_len =
  1876. l_IrpSp->Parameters.DeviceIoControl.InputBufferLength;
  1877. p_IRP->IoStatus.Information = 1; // Simple boolean value
  1878. }
  1879. else
  1880. {
  1881. NOTE_ERROR ();
  1882. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1883. }
  1884. break;
  1885. }
  1886. default:
  1887. {
  1888. NOTE_ERROR ();
  1889. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1890. break;
  1891. }
  1892. }
  1893. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1894. break;
  1895. }
  1896. //===========================================================
  1897. // User mode thread issued a read request on the tap device
  1898. // If there are packets waiting to be read, then the request
  1899. // will be satisfied here. If not, then the request will be
  1900. // queued and satisfied by any packet that is not used to
  1901. // satisfy requests ahead of it.
  1902. //===========================================================
  1903. case IRP_MJ_READ:
  1904. {
  1905. TapPacketPointer l_PacketBuffer;
  1906. BOOLEAN pending = FALSE;
  1907. // Save IRP-accessible copy of buffer length
  1908. p_IRP->IoStatus.Information = l_IrpSp->Parameters.Read.Length;
  1909. if (p_IRP->MdlAddress == NULL)
  1910. {
  1911. DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n",
  1912. NAME (l_Adapter)));
  1913. NOTE_ERROR ();
  1914. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1915. p_IRP->IoStatus.Information = 0;
  1916. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1917. break;
  1918. }
  1919. else if ((p_IRP->AssociatedIrp.SystemBuffer =
  1920. MmGetSystemAddressForMdlSafe
  1921. (p_IRP->MdlAddress, NormalPagePriority)) == NULL)
  1922. {
  1923. DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n",
  1924. NAME (l_Adapter)));
  1925. NOTE_ERROR ();
  1926. p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
  1927. p_IRP->IoStatus.Information = 0;
  1928. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1929. break;
  1930. }
  1931. else if (!l_Adapter->m_InterfaceIsRunning)
  1932. {
  1933. DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n",
  1934. NAME (l_Adapter)));
  1935. NOTE_ERROR ();
  1936. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1937. p_IRP->IoStatus.Information = 0;
  1938. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1939. break;
  1940. }
  1941. //==================================
  1942. // Can we provide immediate service?
  1943. //==================================
  1944. l_PacketBuffer = NULL;
  1945. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1946. if (IS_UP (l_Adapter)
  1947. && QueueCount (l_Adapter->m_Extension.m_PacketQueue)
  1948. && QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0)
  1949. {
  1950. l_PacketBuffer = (TapPacketPointer)
  1951. QueuePop (l_Adapter->m_Extension.m_PacketQueue);
  1952. }
  1953. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1954. if (l_PacketBuffer)
  1955. {
  1956. l_Status = CompleteIRP (p_IRP,
  1957. l_PacketBuffer,
  1958. IO_NO_INCREMENT);
  1959. break;
  1960. }
  1961. //=============================
  1962. // Attempt to pend read request
  1963. //=============================
  1964. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1965. if (IS_UP (l_Adapter)
  1966. && QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP)
  1967. {
  1968. IoSetCancelRoutine (p_IRP, CancelIRPCallback);
  1969. l_Status = STATUS_PENDING;
  1970. IoMarkIrpPending (p_IRP);
  1971. pending = TRUE;
  1972. }
  1973. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
  1974. if (pending)
  1975. break;
  1976. // Can't queue anymore IRP's
  1977. DEBUGP (("[%s] TAP [%s] read IRP overrun\n",
  1978. NAME (l_Adapter), l_Adapter->m_Extension.m_TapName));
  1979. NOTE_ERROR ();
  1980. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  1981. p_IRP->IoStatus.Information = 0;
  1982. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  1983. break;
  1984. }
  1985. //==============================================================
  1986. // User mode issued a WriteFile request on the TAP file handle.
  1987. // The request will always get satisfied here. The call may
  1988. // fail if there are too many pending packets (queue full).
  1989. //==============================================================
  1990. case IRP_MJ_WRITE:
  1991. {
  1992. if (p_IRP->MdlAddress == NULL)
  1993. {
  1994. DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n",
  1995. NAME (l_Adapter)));
  1996. NOTE_ERROR ();
  1997. p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
  1998. p_IRP->IoStatus.Information = 0;
  1999. }
  2000. else if ((p_IRP->AssociatedIrp.SystemBuffer =
  2001. MmGetSystemAddressForMdlSafe
  2002. (p_IRP->MdlAddress, NormalPagePriority)) == NULL)
  2003. {
  2004. DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n",
  2005. NAME (l_Adapter)));
  2006. NOTE_ERROR ();
  2007. p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
  2008. p_IRP->IoStatus.Information = 0;
  2009. }
  2010. else if (!l_Adapter->m_InterfaceIsRunning)
  2011. {
  2012. DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n",
  2013. NAME (l_Adapter)));
  2014. NOTE_ERROR ();
  2015. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  2016. p_IRP->IoStatus.Information = 0;
  2017. }
  2018. else if (!l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE))
  2019. {
  2020. __try
  2021. {
  2022. p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length;
  2023. DUMP_PACKET ("IRP_MJ_WRITE ETH",
  2024. (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
  2025. l_IrpSp->Parameters.Write.Length);
  2026. //=====================================================
  2027. // If IPv4 packet, check whether or not packet
  2028. // was truncated.
  2029. //=====================================================
  2030. #if PACKET_TRUNCATION_CHECK
  2031. IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
  2032. l_IrpSp->Parameters.Write.Length,
  2033. FALSE,
  2034. "RX",
  2035. &l_Adapter->m_RxTrunc);
  2036. #endif
  2037. NdisMEthIndicateReceive
  2038. (l_Adapter->m_MiniportAdapterHandle,
  2039. (NDIS_HANDLE) l_Adapter,
  2040. (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
  2041. ETHERNET_HEADER_SIZE,
  2042. (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer + ETHERNET_HEADER_SIZE,
  2043. l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE,
  2044. l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE);
  2045. NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle);
  2046. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  2047. }
  2048. __except (EXCEPTION_EXECUTE_HANDLER)
  2049. {
  2050. DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n",
  2051. NAME (l_Adapter)));
  2052. NOTE_ERROR ();
  2053. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  2054. p_IRP->IoStatus.Information = 0;
  2055. }
  2056. }
  2057. else if (l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE))
  2058. {
  2059. __try
  2060. {
  2061. ETH_HEADER * p_UserToTap = &l_Adapter->m_UserToTap;
  2062. // for IPv6, need to use ethernet header with IPv6 proto
  2063. if ( IPH_GET_VER( ((IPHDR*) p_IRP->AssociatedIrp.SystemBuffer)->version_len) == 6 )
  2064. {
  2065. p_UserToTap = &l_Adapter->m_UserToTap_IPv6;
  2066. }
  2067. p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length;
  2068. DUMP_PACKET2 ("IRP_MJ_WRITE P2P",
  2069. p_UserToTap,
  2070. (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
  2071. l_IrpSp->Parameters.Write.Length);
  2072. //=====================================================
  2073. // If IPv4 packet, check whether or not packet
  2074. // was truncated.
  2075. //=====================================================
  2076. #if PACKET_TRUNCATION_CHECK
  2077. IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
  2078. l_IrpSp->Parameters.Write.Length,
  2079. TRUE,
  2080. "RX",
  2081. &l_Adapter->m_RxTrunc);
  2082. #endif
  2083. NdisMEthIndicateReceive
  2084. (l_Adapter->m_MiniportAdapterHandle,
  2085. (NDIS_HANDLE) l_Adapter,
  2086. (unsigned char *) p_UserToTap,
  2087. sizeof (ETH_HEADER),
  2088. (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer,
  2089. l_IrpSp->Parameters.Write.Length,
  2090. l_IrpSp->Parameters.Write.Length);
  2091. NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle);
  2092. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  2093. }
  2094. __except (EXCEPTION_EXECUTE_HANDLER)
  2095. {
  2096. DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n",
  2097. NAME (l_Adapter)));
  2098. NOTE_ERROR ();
  2099. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  2100. p_IRP->IoStatus.Information = 0;
  2101. }
  2102. }
  2103. else
  2104. {
  2105. DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",
  2106. NAME (l_Adapter),
  2107. l_IrpSp->Parameters.Write.Length));
  2108. NOTE_ERROR ();
  2109. p_IRP->IoStatus.Information = 0; // ETHERNET_HEADER_SIZE;
  2110. p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
  2111. }
  2112. if (l_Status == STATUS_SUCCESS)
  2113. INCREMENT_STAT (l_Adapter->m_Rx);
  2114. else
  2115. INCREMENT_STAT (l_Adapter->m_RxErr);
  2116. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  2117. break;
  2118. }
  2119. //--------------------------------------------------------------
  2120. // User mode thread has called CreateFile() on the tap device
  2121. //--------------------------------------------------------------
  2122. case IRP_MJ_CREATE:
  2123. {
  2124. BOOLEAN succeeded = FALSE;
  2125. BOOLEAN mutex_succeeded;
  2126. DEBUGP
  2127. (("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
  2128. NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
  2129. TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens));
  2130. ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
  2131. if (mutex_succeeded)
  2132. {
  2133. if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens)
  2134. {
  2135. ResetTapAdapterState (l_Adapter);
  2136. l_Adapter->m_Extension.m_TapOpens = 1;
  2137. succeeded = TRUE;
  2138. }
  2139. if (succeeded)
  2140. {
  2141. INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens);
  2142. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  2143. p_IRP->IoStatus.Information = 0;
  2144. }
  2145. else
  2146. {
  2147. DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
  2148. NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
  2149. NOTE_ERROR ();
  2150. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  2151. p_IRP->IoStatus.Information = 0;
  2152. }
  2153. RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
  2154. }
  2155. else
  2156. {
  2157. DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
  2158. NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
  2159. NOTE_ERROR ();
  2160. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  2161. p_IRP->IoStatus.Information = 0;
  2162. }
  2163. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  2164. break;
  2165. }
  2166. //-----------------------------------------------------------
  2167. // User mode thread called CloseHandle() on the tap device
  2168. //-----------------------------------------------------------
  2169. case IRP_MJ_CLOSE:
  2170. {
  2171. BOOLEAN mutex_succeeded;
  2172. DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n",
  2173. NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
  2174. TAP_DRIVER_MINOR_VERSION));
  2175. ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
  2176. if (mutex_succeeded)
  2177. {
  2178. l_Adapter->m_Extension.m_TapOpens = 0;
  2179. ResetTapAdapterState (l_Adapter);
  2180. FlushQueues (&l_Adapter->m_Extension);
  2181. SetMediaStatus (l_Adapter, FALSE);
  2182. RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
  2183. }
  2184. else
  2185. {
  2186. DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
  2187. NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
  2188. NOTE_ERROR ();
  2189. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  2190. p_IRP->IoStatus.Information = 0;
  2191. }
  2192. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  2193. break;
  2194. }
  2195. //------------------
  2196. // Strange Request
  2197. //------------------
  2198. default:
  2199. {
  2200. //NOTE_ERROR ();
  2201. p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
  2202. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  2203. break;
  2204. }
  2205. }
  2206. return l_Status;
  2207. }
  2208. //=============================================================
  2209. // CompleteIRP is normally called with an adapter -> userspace
  2210. // network packet and an IRP (Pending I/O request) from userspace.
  2211. //
  2212. // The IRP will normally represent a queued overlapped read
  2213. // operation from userspace that is in a wait state.
  2214. //
  2215. // Use the ethernet packet to satisfy the IRP.
  2216. //=============================================================
  2217. NTSTATUS
  2218. CompleteIRP (IN PIRP p_IRP,
  2219. IN TapPacketPointer p_PacketBuffer,
  2220. IN CCHAR PriorityBoost)
  2221. {
  2222. NTSTATUS l_Status = STATUS_UNSUCCESSFUL;
  2223. int offset;
  2224. int len;
  2225. MYASSERT (p_IRP);
  2226. MYASSERT (p_PacketBuffer);
  2227. IoSetCancelRoutine (p_IRP, NULL); // Disable cancel routine
  2228. //-------------------------------------------
  2229. // While p_PacketBuffer always contains a
  2230. // full ethernet packet, including the
  2231. // ethernet header, in point-to-point mode,
  2232. // we only want to return the IPv4
  2233. // component.
  2234. //-------------------------------------------
  2235. if (p_PacketBuffer->m_SizeFlags & TP_TUN)
  2236. {
  2237. offset = ETHERNET_HEADER_SIZE;
  2238. len = (int) (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE;
  2239. }
  2240. else
  2241. {
  2242. offset = 0;
  2243. len = (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK);
  2244. }
  2245. if (len < 0 || (int) p_IRP->IoStatus.Information < len)
  2246. {
  2247. p_IRP->IoStatus.Information = 0;
  2248. p_IRP->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
  2249. NOTE_ERROR ();
  2250. }
  2251. else
  2252. {
  2253. p_IRP->IoStatus.Information = len;
  2254. p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
  2255. __try
  2256. {
  2257. NdisMoveMemory (p_IRP->AssociatedIrp.SystemBuffer,
  2258. p_PacketBuffer->m_Data + offset,
  2259. len);
  2260. }
  2261. __except (EXCEPTION_EXECUTE_HANDLER)
  2262. {
  2263. NOTE_ERROR ();
  2264. p_IRP->IoStatus.Status = STATUS_UNSUCCESSFUL;
  2265. p_IRP->IoStatus.Information = 0;
  2266. }
  2267. }
  2268. __try
  2269. {
  2270. NdisFreeMemory (p_PacketBuffer,
  2271. TAP_PACKET_SIZE (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK),
  2272. 0);
  2273. }
  2274. __except (EXCEPTION_EXECUTE_HANDLER)
  2275. {
  2276. }
  2277. if (l_Status == STATUS_SUCCESS)
  2278. {
  2279. IoCompleteRequest (p_IRP, PriorityBoost);
  2280. }
  2281. else
  2282. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  2283. return l_Status;
  2284. }
  2285. //==============================================
  2286. // IRPs get cancelled for a number of reasons.
  2287. //
  2288. // The TAP device could be closed by userspace
  2289. // when there are still pending read operations.
  2290. //
  2291. // The user could disable the TAP adapter in the
  2292. // network connections control panel, while the
  2293. // device is still open by a process.
  2294. //==============================================
  2295. VOID
  2296. CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject,
  2297. IN PIRP p_IRP)
  2298. {
  2299. TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
  2300. CancelIRP (l_Adapter ? &l_Adapter->m_Extension : NULL, p_IRP, TRUE);
  2301. }
  2302. VOID
  2303. CancelIRP (TapExtensionPointer p_Extension,
  2304. IN PIRP p_IRP,
  2305. BOOLEAN callback)
  2306. {
  2307. BOOLEAN exists = FALSE;
  2308. MYASSERT (p_IRP);
  2309. if (p_Extension)
  2310. {
  2311. NdisAcquireSpinLock (&p_Extension->m_QueueLock);
  2312. exists = (QueueExtract (p_Extension->m_IrpQueue, p_IRP) == p_IRP);
  2313. NdisReleaseSpinLock (&p_Extension->m_QueueLock);
  2314. }
  2315. else
  2316. exists = TRUE;
  2317. if (exists)
  2318. {
  2319. IoSetCancelRoutine (p_IRP, NULL);
  2320. p_IRP->IoStatus.Status = STATUS_CANCELLED;
  2321. p_IRP->IoStatus.Information = 0;
  2322. }
  2323. if (callback)
  2324. IoReleaseCancelSpinLock (p_IRP->CancelIrql);
  2325. if (exists)
  2326. IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
  2327. }
  2328. //===========================================
  2329. // Exhaust packet, IRP, and injection queues.
  2330. //===========================================
  2331. VOID
  2332. FlushQueues (TapExtensionPointer p_Extension)
  2333. {
  2334. PIRP l_IRP;
  2335. TapPacketPointer l_PacketBuffer;
  2336. InjectPacketPointer l_InjectBuffer;
  2337. int n_IRP=0, n_Packet=0, n_Inject=0;
  2338. MYASSERT (p_Extension);
  2339. MYASSERT (p_Extension->m_TapDevice);
  2340. while (TRUE)
  2341. {
  2342. NdisAcquireSpinLock (&p_Extension->m_QueueLock);
  2343. l_IRP = QueuePop (p_Extension->m_IrpQueue);
  2344. NdisReleaseSpinLock (&p_Extension->m_QueueLock);
  2345. if (l_IRP)
  2346. {
  2347. ++n_IRP;
  2348. CancelIRP (NULL, l_IRP, FALSE);
  2349. }
  2350. else
  2351. break;
  2352. }
  2353. while (TRUE)
  2354. {
  2355. NdisAcquireSpinLock (&p_Extension->m_QueueLock);
  2356. l_PacketBuffer = QueuePop (p_Extension->m_PacketQueue);
  2357. NdisReleaseSpinLock (&p_Extension->m_QueueLock);
  2358. if (l_PacketBuffer)
  2359. {
  2360. ++n_Packet;
  2361. MemFree (l_PacketBuffer, TAP_PACKET_SIZE (l_PacketBuffer->m_SizeFlags & TP_SIZE_MASK));
  2362. }
  2363. else
  2364. break;
  2365. }
  2366. while (TRUE)
  2367. {
  2368. NdisAcquireSpinLock (&p_Extension->m_InjectLock);
  2369. l_InjectBuffer = QueuePop (p_Extension->m_InjectQueue);
  2370. NdisReleaseSpinLock (&p_Extension->m_InjectLock);
  2371. if (l_InjectBuffer)
  2372. {
  2373. ++n_Inject;
  2374. INJECT_PACKET_FREE(l_InjectBuffer);
  2375. }
  2376. else
  2377. break;
  2378. }
  2379. DEBUGP ((
  2380. "[%s] [TAP] FlushQueues n_IRP=[%d,%d,%d] n_Packet=[%d,%d,%d] n_Inject=[%d,%d,%d]\n",
  2381. p_Extension->m_TapName,
  2382. n_IRP,
  2383. p_Extension->m_IrpQueue->max_size,
  2384. IRP_QUEUE_SIZE,
  2385. n_Packet,
  2386. p_Extension->m_PacketQueue->max_size,
  2387. PACKET_QUEUE_SIZE,
  2388. n_Inject,
  2389. p_Extension->m_InjectQueue->max_size,
  2390. INJECT_QUEUE_SIZE
  2391. ));
  2392. }
  2393. //===================================================
  2394. // Tell Windows whether the TAP device should be
  2395. // considered "connected" or "disconnected".
  2396. //===================================================
  2397. VOID
  2398. SetMediaStatus (TapAdapterPointer p_Adapter, BOOLEAN state)
  2399. {
  2400. if (p_Adapter->m_MediaState != state && !p_Adapter->m_MediaStateAlwaysConnected)
  2401. {
  2402. if (state)
  2403. NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle,
  2404. NDIS_STATUS_MEDIA_CONNECT, NULL, 0);
  2405. else
  2406. NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle,
  2407. NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0);
  2408. NdisMIndicateStatusComplete (p_Adapter->m_MiniportAdapterHandle);
  2409. p_Adapter->m_MediaState = state;
  2410. }
  2411. }
  2412. //======================================================
  2413. // If DHCP mode is used together with tun
  2414. // mode, consider the fact that the P2P remote subnet
  2415. // might enclose the DHCP masq server address.
  2416. //======================================================
  2417. VOID
  2418. CheckIfDhcpAndTunMode (TapAdapterPointer p_Adapter)
  2419. {
  2420. if (p_Adapter->m_tun && p_Adapter->m_dhcp_enabled)
  2421. {
  2422. if ((p_Adapter->m_dhcp_server_ip & p_Adapter->m_remoteNetmask) == p_Adapter->m_remoteNetwork)
  2423. {
  2424. COPY_MAC (p_Adapter->m_dhcp_server_mac, p_Adapter->m_TapToUser.dest);
  2425. p_Adapter->m_dhcp_server_arp = FALSE;
  2426. }
  2427. }
  2428. }
  2429. //===================================================
  2430. // Generate an ARP reply message for specific kinds
  2431. // ARP queries.
  2432. //===================================================
  2433. BOOLEAN
  2434. ProcessARP (TapAdapterPointer p_Adapter,
  2435. const PARP_PACKET src,
  2436. const IPADDR adapter_ip,
  2437. const IPADDR ip_network,
  2438. const IPADDR ip_netmask,
  2439. const MACADDR mac)
  2440. {
  2441. //-----------------------------------------------
  2442. // Is this the kind of packet we are looking for?
  2443. //-----------------------------------------------
  2444. if (src->m_Proto == htons (ETH_P_ARP)
  2445. && MAC_EQUAL (src->m_MAC_Source, p_Adapter->m_MAC)
  2446. && MAC_EQUAL (src->m_ARP_MAC_Source, p_Adapter->m_MAC)
  2447. && MAC_EQUAL (src->m_MAC_Destination, p_Adapter->m_MAC_Broadcast)
  2448. && src->m_ARP_Operation == htons (ARP_REQUEST)
  2449. && src->m_MAC_AddressType == htons (MAC_ADDR_TYPE)
  2450. && src->m_MAC_AddressSize == sizeof (MACADDR)
  2451. && src->m_PROTO_AddressType == htons (ETH_P_IP)
  2452. && src->m_PROTO_AddressSize == sizeof (IPADDR)
  2453. && src->m_ARP_IP_Source == adapter_ip
  2454. && (src->m_ARP_IP_Destination & ip_netmask) == ip_network
  2455. && src->m_ARP_IP_Destination != adapter_ip)
  2456. {
  2457. ARP_PACKET *arp = (ARP_PACKET *) MemAlloc (sizeof (ARP_PACKET), TRUE);
  2458. if (arp)
  2459. {
  2460. //----------------------------------------------
  2461. // Initialize ARP reply fields
  2462. //----------------------------------------------
  2463. arp->m_Proto = htons (ETH_P_ARP);
  2464. arp->m_MAC_AddressType = htons (MAC_ADDR_TYPE);
  2465. arp->m_PROTO_AddressType = htons (ETH_P_IP);
  2466. arp->m_MAC_AddressSize = sizeof (MACADDR);
  2467. arp->m_PROTO_AddressSize = sizeof (IPADDR);
  2468. arp->m_ARP_Operation = htons (ARP_REPLY);
  2469. //----------------------------------------------
  2470. // ARP addresses
  2471. //----------------------------------------------
  2472. COPY_MAC (arp->m_MAC_Source, mac);
  2473. COPY_MAC (arp->m_MAC_Destination, p_Adapter->m_MAC);
  2474. COPY_MAC (arp->m_ARP_MAC_Source, mac);
  2475. COPY_MAC (arp->m_ARP_MAC_Destination, p_Adapter->m_MAC);
  2476. arp->m_ARP_IP_Source = src->m_ARP_IP_Destination;
  2477. arp->m_ARP_IP_Destination = adapter_ip;
  2478. DUMP_PACKET ("ProcessARP",
  2479. (unsigned char *) arp,
  2480. sizeof (ARP_PACKET));
  2481. InjectPacketDeferred (p_Adapter, (UCHAR *) arp, sizeof (ARP_PACKET));
  2482. MemFree (arp, sizeof (ARP_PACKET));
  2483. }
  2484. return TRUE;
  2485. }
  2486. else
  2487. return FALSE;
  2488. }
  2489. //===============================================================
  2490. // Used in cases where internally generated packets such as
  2491. // ARP or DHCP replies must be returned to the kernel, to be
  2492. // seen as an incoming packet "arriving" on the interface.
  2493. //===============================================================
  2494. // Defer packet injection till IRQL < DISPATCH_LEVEL
  2495. VOID
  2496. InjectPacketDeferred (TapAdapterPointer p_Adapter,
  2497. UCHAR *packet,
  2498. const unsigned int len)
  2499. {
  2500. InjectPacketPointer l_InjectBuffer;
  2501. PVOID result;
  2502. if (NdisAllocateMemoryWithTag (&l_InjectBuffer,
  2503. INJECT_PACKET_SIZE (len),
  2504. 'IPAT') == NDIS_STATUS_SUCCESS)
  2505. {
  2506. l_InjectBuffer->m_Size = len;
  2507. NdisMoveMemory (l_InjectBuffer->m_Data, packet, len);
  2508. NdisAcquireSpinLock (&p_Adapter->m_Extension.m_InjectLock);
  2509. result = QueuePush (p_Adapter->m_Extension.m_InjectQueue, l_InjectBuffer);
  2510. NdisReleaseSpinLock (&p_Adapter->m_Extension.m_InjectLock);
  2511. if (result)
  2512. KeInsertQueueDpc (&p_Adapter->m_Extension.m_InjectDpc, p_Adapter, NULL);
  2513. else
  2514. INJECT_PACKET_FREE(l_InjectBuffer);
  2515. }
  2516. }
  2517. // Handle the injection of previously deferred packets
  2518. VOID
  2519. InjectPacketDpc(KDPC *Dpc,
  2520. PVOID DeferredContext,
  2521. PVOID SystemArgument1,
  2522. PVOID SystemArgument2)
  2523. {
  2524. InjectPacketPointer l_InjectBuffer;
  2525. TapAdapterPointer l_Adapter = (TapAdapterPointer)SystemArgument1;
  2526. while (TRUE)
  2527. {
  2528. NdisAcquireSpinLock (&l_Adapter->m_Extension.m_InjectLock);
  2529. l_InjectBuffer = QueuePop (l_Adapter->m_Extension.m_InjectQueue);
  2530. NdisReleaseSpinLock (&l_Adapter->m_Extension.m_InjectLock);
  2531. if (l_InjectBuffer)
  2532. {
  2533. InjectPacketNow(l_Adapter, l_InjectBuffer->m_Data, l_InjectBuffer->m_Size);
  2534. INJECT_PACKET_FREE(l_InjectBuffer);
  2535. }
  2536. else
  2537. break;
  2538. }
  2539. }
  2540. // Do packet injection now
  2541. VOID
  2542. InjectPacketNow (TapAdapterPointer p_Adapter,
  2543. UCHAR *packet,
  2544. const unsigned int len)
  2545. {
  2546. MYASSERT (len >= ETHERNET_HEADER_SIZE);
  2547. __try
  2548. {
  2549. //------------------------------------------------------------
  2550. // NdisMEthIndicateReceive and NdisMEthIndicateReceiveComplete
  2551. // could potentially be called reentrantly both here and in
  2552. // TapDeviceHook/IRP_MJ_WRITE.
  2553. //
  2554. // The DDK docs imply that this is okay.
  2555. //
  2556. // Note that reentrant behavior could only occur if the
  2557. // non-deferred version of InjectPacket is used.
  2558. //------------------------------------------------------------
  2559. NdisMEthIndicateReceive
  2560. (p_Adapter->m_MiniportAdapterHandle,
  2561. (NDIS_HANDLE) p_Adapter,
  2562. packet,
  2563. ETHERNET_HEADER_SIZE,
  2564. packet + ETHERNET_HEADER_SIZE,
  2565. len - ETHERNET_HEADER_SIZE,
  2566. len - ETHERNET_HEADER_SIZE);
  2567. NdisMEthIndicateReceiveComplete (p_Adapter->m_MiniportAdapterHandle);
  2568. }
  2569. __except (EXCEPTION_EXECUTE_HANDLER)
  2570. {
  2571. DEBUGP (("[%s] NdisMEthIndicateReceive failed in InjectPacketNow\n",
  2572. NAME (p_Adapter)));
  2573. NOTE_ERROR ();
  2574. }
  2575. }
  2576. //===================================================================
  2577. // Go back to default TAP mode from Point-To-Point mode.
  2578. // Also reset (i.e. disable) DHCP Masq mode.
  2579. //===================================================================
  2580. VOID ResetTapAdapterState (TapAdapterPointer p_Adapter)
  2581. {
  2582. // Point-To-Point
  2583. p_Adapter->m_tun = FALSE;
  2584. p_Adapter->m_localIP = 0;
  2585. p_Adapter->m_remoteNetwork = 0;
  2586. p_Adapter->m_remoteNetmask = 0;
  2587. NdisZeroMemory (&p_Adapter->m_TapToUser, sizeof (p_Adapter->m_TapToUser));
  2588. NdisZeroMemory (&p_Adapter->m_UserToTap, sizeof (p_Adapter->m_UserToTap));
  2589. NdisZeroMemory (&p_Adapter->m_UserToTap_IPv6, sizeof (p_Adapter->m_UserToTap_IPv6));
  2590. // DHCP Masq
  2591. p_Adapter->m_dhcp_enabled = FALSE;
  2592. p_Adapter->m_dhcp_server_arp = FALSE;
  2593. p_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
  2594. p_Adapter->m_dhcp_addr = 0;
  2595. p_Adapter->m_dhcp_netmask = 0;
  2596. p_Adapter->m_dhcp_server_ip = 0;
  2597. p_Adapter->m_dhcp_lease_time = 0;
  2598. p_Adapter->m_dhcp_received_discover = FALSE;
  2599. p_Adapter->m_dhcp_bad_requests = 0;
  2600. NdisZeroMemory (p_Adapter->m_dhcp_server_mac, sizeof (MACADDR));
  2601. }
  2602. #if ENABLE_NONADMIN
  2603. //===================================================================
  2604. // Set TAP device handle to be accessible without admin privileges.
  2605. //===================================================================
  2606. VOID AllowNonAdmin (TapExtensionPointer p_Extension)
  2607. {
  2608. NTSTATUS stat;
  2609. SECURITY_DESCRIPTOR sd;
  2610. OBJECT_ATTRIBUTES oa;
  2611. IO_STATUS_BLOCK isb;
  2612. HANDLE hand = NULL;
  2613. NdisZeroMemory (&sd, sizeof (sd));
  2614. NdisZeroMemory (&oa, sizeof (oa));
  2615. NdisZeroMemory (&isb, sizeof (isb));
  2616. if (!p_Extension->m_CreatedUnicodeLinkName)
  2617. {
  2618. DEBUGP (("[TAP] AllowNonAdmin: UnicodeLinkName is uninitialized\n"));
  2619. NOTE_ERROR ();
  2620. return;
  2621. }
  2622. stat = RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
  2623. if (stat != STATUS_SUCCESS)
  2624. {
  2625. DEBUGP (("[TAP] AllowNonAdmin: RtlCreateSecurityDescriptor failed\n"));
  2626. NOTE_ERROR ();
  2627. return;
  2628. }
  2629. InitializeObjectAttributes (
  2630. &oa,
  2631. &p_Extension->m_UnicodeLinkName,
  2632. OBJ_KERNEL_HANDLE,
  2633. NULL,
  2634. NULL
  2635. );
  2636. stat = ZwOpenFile (
  2637. &hand,
  2638. WRITE_DAC,
  2639. &oa,
  2640. &isb,
  2641. 0,
  2642. 0
  2643. );
  2644. if (stat != STATUS_SUCCESS)
  2645. {
  2646. DEBUGP (("[TAP] AllowNonAdmin: ZwOpenFile failed, status=0x%08x\n", (unsigned int)stat));
  2647. NOTE_ERROR ();
  2648. return;
  2649. }
  2650. stat = ZwSetSecurityObject (hand, DACL_SECURITY_INFORMATION, &sd);
  2651. if (stat != STATUS_SUCCESS)
  2652. {
  2653. DEBUGP (("[TAP] AllowNonAdmin: ZwSetSecurityObject failed\n"));
  2654. NOTE_ERROR ();
  2655. return;
  2656. }
  2657. stat = ZwClose (hand);
  2658. if (stat != STATUS_SUCCESS)
  2659. {
  2660. DEBUGP (("[TAP] AllowNonAdmin: ZwClose failed\n"));
  2661. NOTE_ERROR ();
  2662. return;
  2663. }
  2664. DEBUGP (("[TAP] AllowNonAdmin: SUCCEEDED\n"));
  2665. }
  2666. #endif
  2667. #if PACKET_TRUNCATION_CHECK
  2668. VOID
  2669. IPv4PacketSizeVerify (const UCHAR *data, ULONG length, BOOLEAN tun, const char *prefix, LONG *counter)
  2670. {
  2671. const IPHDR *ip;
  2672. int len = length;
  2673. if (tun)
  2674. {
  2675. ip = (IPHDR *) data;
  2676. }
  2677. else
  2678. {
  2679. if (length >= sizeof (ETH_HEADER))
  2680. {
  2681. const ETH_HEADER *eth = (ETH_HEADER *) data;
  2682. if (eth->proto != htons (ETH_P_IP))
  2683. return;
  2684. ip = (IPHDR *) (data + sizeof (ETH_HEADER));
  2685. len -= sizeof (ETH_HEADER);
  2686. }
  2687. else
  2688. return;
  2689. }
  2690. if (len >= sizeof (IPHDR))
  2691. {
  2692. const int totlen = ntohs (ip->tot_len);
  2693. DEBUGP (("[TAP] IPv4PacketSizeVerify %s len=%d totlen=%d\n", prefix, len, totlen));
  2694. if (len != totlen)
  2695. ++(*counter);
  2696. }
  2697. }
  2698. #endif
  2699. //======================================================================
  2700. // End of Source
  2701. //======================================================================