tapdrvr.c 90 KB

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