txpath.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  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-2014 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. // Include files.
  26. //
  27. #include "tap.h"
  28. //======================================================================
  29. // TAP Send Path Support
  30. //======================================================================
  31. #ifdef ALLOC_PRAGMA
  32. #pragma alloc_text( PAGE, TapDeviceRead)
  33. #endif // ALLOC_PRAGMA
  34. // checksum code for ICMPv6 packet, taken from dhcp.c / udp_checksum
  35. // see RFC 4443, 2.3, and RFC 2460, 8.1
  36. USHORT
  37. icmpv6_checksum(
  38. __in const UCHAR *buf,
  39. __in const int len_icmpv6,
  40. __in const UCHAR *saddr6,
  41. __in const UCHAR *daddr6
  42. )
  43. {
  44. USHORT word16;
  45. ULONG sum = 0;
  46. int i;
  47. // make 16 bit words out of every two adjacent 8 bit words and
  48. // calculate the sum of all 16 bit words
  49. for (i = 0; i < len_icmpv6; i += 2)
  50. {
  51. word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_icmpv6) ? (buf[i+1] & 0xFF) : 0);
  52. sum += word16;
  53. }
  54. // add the IPv6 pseudo header which contains the IP source and destination addresses
  55. for (i = 0; i < 16; i += 2)
  56. {
  57. word16 =((saddr6[i] << 8) & 0xFF00) + (saddr6[i+1] & 0xFF);
  58. sum += word16;
  59. }
  60. for (i = 0; i < 16; i += 2)
  61. {
  62. word16 =((daddr6[i] << 8) & 0xFF00) + (daddr6[i+1] & 0xFF);
  63. sum += word16;
  64. }
  65. // the next-header number and the length of the ICMPv6 packet
  66. sum += (USHORT) IPPROTO_ICMPV6 + (USHORT) len_icmpv6;
  67. // keep only the last 16 bits of the 32 bit calculated sum and add the carries
  68. while (sum >> 16)
  69. sum = (sum & 0xFFFF) + (sum >> 16);
  70. // Take the one's complement of sum
  71. return ((USHORT) ~sum);
  72. }
  73. /*
  74. // check IPv6 packet for "is this an IPv6 Neighbor Solicitation that
  75. // the tap driver needs to answer?"
  76. // see RFC 4861 4.3 for the different cases
  77. static IPV6ADDR IPV6_NS_TARGET_MCAST =
  78. { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  79. 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x08 };
  80. static IPV6ADDR IPV6_NS_TARGET_UNICAST =
  81. { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  82. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 };
  83. BOOLEAN
  84. HandleIPv6NeighborDiscovery(
  85. __in PTAP_ADAPTER_CONTEXT Adapter,
  86. __in UCHAR * m_Data
  87. )
  88. {
  89. const ETH_HEADER * e = (ETH_HEADER *) m_Data;
  90. const IPV6HDR *ipv6 = (IPV6HDR *) (m_Data + sizeof (ETH_HEADER));
  91. const ICMPV6_NS * icmpv6_ns = (ICMPV6_NS *) (m_Data + sizeof (ETH_HEADER) + sizeof (IPV6HDR));
  92. ICMPV6_NA_PKT *na;
  93. USHORT icmpv6_len, icmpv6_csum;
  94. // we don't really care about the destination MAC address here
  95. // - it's either a multicast MAC, or the userland destination MAC
  96. // but since the TAP driver is point-to-point, all packets are "for us"
  97. // IPv6 target address must be ff02::1::ff00:8 (multicast for
  98. // initial NS) or fe80::1 (unicast for recurrent NUD)
  99. if ( memcmp( ipv6->daddr, IPV6_NS_TARGET_MCAST,
  100. sizeof(IPV6ADDR) ) != 0 &&
  101. memcmp( ipv6->daddr, IPV6_NS_TARGET_UNICAST,
  102. sizeof(IPV6ADDR) ) != 0 )
  103. {
  104. return FALSE; // wrong target address
  105. }
  106. // IPv6 Next-Header must be ICMPv6
  107. if ( ipv6->nexthdr != IPPROTO_ICMPV6 )
  108. {
  109. return FALSE; // wrong next-header
  110. }
  111. // ICMPv6 type+code must be 135/0 for NS
  112. if ( icmpv6_ns->type != ICMPV6_TYPE_NS ||
  113. icmpv6_ns->code != ICMPV6_CODE_0 )
  114. {
  115. return FALSE; // wrong ICMPv6 type
  116. }
  117. // ICMPv6 target address must be fe80::8 (magic)
  118. if ( memcmp( icmpv6_ns->target_addr, IPV6_NS_TARGET_UNICAST,
  119. sizeof(IPV6ADDR) ) != 0 )
  120. {
  121. return FALSE; // not for us
  122. }
  123. // packet identified, build magic response packet
  124. na = (ICMPV6_NA_PKT *) MemAlloc (sizeof (ICMPV6_NA_PKT), TRUE);
  125. if ( !na ) return FALSE;
  126. //------------------------------------------------
  127. // Initialize Neighbour Advertisement reply packet
  128. //------------------------------------------------
  129. // ethernet header
  130. na->eth.proto = htons(NDIS_ETH_TYPE_IPV6);
  131. ETH_COPY_NETWORK_ADDRESS(na->eth.dest, Adapter->PermanentAddress);
  132. ETH_COPY_NETWORK_ADDRESS(na->eth.src, Adapter->m_TapToUser.dest);
  133. // IPv6 header
  134. na->ipv6.version_prio = ipv6->version_prio;
  135. NdisMoveMemory( na->ipv6.flow_lbl, ipv6->flow_lbl,
  136. sizeof(na->ipv6.flow_lbl) );
  137. icmpv6_len = sizeof(ICMPV6_NA_PKT) - sizeof(ETH_HEADER) - sizeof(IPV6HDR);
  138. na->ipv6.payload_len = htons(icmpv6_len);
  139. na->ipv6.nexthdr = IPPROTO_ICMPV6;
  140. na->ipv6.hop_limit = 255;
  141. NdisMoveMemory( na->ipv6.saddr, IPV6_NS_TARGET_UNICAST,
  142. sizeof(IPV6ADDR) );
  143. NdisMoveMemory( na->ipv6.daddr, ipv6->saddr,
  144. sizeof(IPV6ADDR) );
  145. // ICMPv6
  146. na->icmpv6.type = ICMPV6_TYPE_NA;
  147. na->icmpv6.code = ICMPV6_CODE_0;
  148. na->icmpv6.checksum = 0;
  149. na->icmpv6.rso_bits = 0x60; // Solicited + Override
  150. NdisZeroMemory( na->icmpv6.reserved, sizeof(na->icmpv6.reserved) );
  151. NdisMoveMemory( na->icmpv6.target_addr, IPV6_NS_TARGET_UNICAST,
  152. sizeof(IPV6ADDR) );
  153. // ICMPv6 option "Target Link Layer Address"
  154. na->icmpv6.opt_type = ICMPV6_OPTION_TLLA;
  155. na->icmpv6.opt_length = ICMPV6_LENGTH_TLLA;
  156. ETH_COPY_NETWORK_ADDRESS( na->icmpv6.target_macaddr, Adapter->m_TapToUser.dest );
  157. // calculate and set checksum
  158. icmpv6_csum = icmpv6_checksum (
  159. (UCHAR*) &(na->icmpv6),
  160. icmpv6_len,
  161. na->ipv6.saddr,
  162. na->ipv6.daddr
  163. );
  164. na->icmpv6.checksum = htons( icmpv6_csum );
  165. DUMP_PACKET ("HandleIPv6NeighborDiscovery",
  166. (unsigned char *) na,
  167. sizeof (ICMPV6_NA_PKT));
  168. IndicateReceivePacket (Adapter, (UCHAR *) na, sizeof (ICMPV6_NA_PKT));
  169. MemFree (na, sizeof (ICMPV6_NA_PKT));
  170. return TRUE; // all fine
  171. }
  172. //===================================================
  173. // Generate an ARP reply message for specific kinds
  174. // ARP queries.
  175. //===================================================
  176. BOOLEAN
  177. ProcessARP(
  178. __in PTAP_ADAPTER_CONTEXT Adapter,
  179. __in const PARP_PACKET src,
  180. __in const IPADDR adapter_ip,
  181. __in const IPADDR ip_network,
  182. __in const IPADDR ip_netmask,
  183. __in const MACADDR mac
  184. )
  185. {
  186. //-----------------------------------------------
  187. // Is this the kind of packet we are looking for?
  188. //-----------------------------------------------
  189. if (src->m_Proto == htons (NDIS_ETH_TYPE_ARP)
  190. && MAC_EQUAL (src->m_MAC_Source, Adapter->PermanentAddress)
  191. && MAC_EQUAL (src->m_ARP_MAC_Source, Adapter->PermanentAddress)
  192. && ETH_IS_BROADCAST(src->m_MAC_Destination)
  193. && src->m_ARP_Operation == htons (ARP_REQUEST)
  194. && src->m_MAC_AddressType == htons (MAC_ADDR_TYPE)
  195. && src->m_MAC_AddressSize == sizeof (MACADDR)
  196. && src->m_PROTO_AddressType == htons (NDIS_ETH_TYPE_IPV4)
  197. && src->m_PROTO_AddressSize == sizeof (IPADDR)
  198. && src->m_ARP_IP_Source == adapter_ip
  199. && (src->m_ARP_IP_Destination & ip_netmask) == ip_network
  200. && src->m_ARP_IP_Destination != adapter_ip)
  201. {
  202. ARP_PACKET *arp = (ARP_PACKET *) MemAlloc (sizeof (ARP_PACKET), TRUE);
  203. if (arp)
  204. {
  205. //----------------------------------------------
  206. // Initialize ARP reply fields
  207. //----------------------------------------------
  208. arp->m_Proto = htons (NDIS_ETH_TYPE_ARP);
  209. arp->m_MAC_AddressType = htons (MAC_ADDR_TYPE);
  210. arp->m_PROTO_AddressType = htons (NDIS_ETH_TYPE_IPV4);
  211. arp->m_MAC_AddressSize = sizeof (MACADDR);
  212. arp->m_PROTO_AddressSize = sizeof (IPADDR);
  213. arp->m_ARP_Operation = htons (ARP_REPLY);
  214. //----------------------------------------------
  215. // ARP addresses
  216. //----------------------------------------------
  217. ETH_COPY_NETWORK_ADDRESS (arp->m_MAC_Source, mac);
  218. ETH_COPY_NETWORK_ADDRESS (arp->m_MAC_Destination, Adapter->PermanentAddress);
  219. ETH_COPY_NETWORK_ADDRESS (arp->m_ARP_MAC_Source, mac);
  220. ETH_COPY_NETWORK_ADDRESS (arp->m_ARP_MAC_Destination, Adapter->PermanentAddress);
  221. arp->m_ARP_IP_Source = src->m_ARP_IP_Destination;
  222. arp->m_ARP_IP_Destination = adapter_ip;
  223. DUMP_PACKET ("ProcessARP",
  224. (unsigned char *) arp,
  225. sizeof (ARP_PACKET));
  226. IndicateReceivePacket (Adapter, (UCHAR *) arp, sizeof (ARP_PACKET));
  227. MemFree (arp, sizeof (ARP_PACKET));
  228. }
  229. return TRUE;
  230. }
  231. else
  232. return FALSE;
  233. }
  234. */
  235. //=============================================================
  236. // CompleteIRP is normally called with an adapter -> userspace
  237. // network packet and an IRP (Pending I/O request) from userspace.
  238. //
  239. // The IRP will normally represent a queued overlapped read
  240. // operation from userspace that is in a wait state.
  241. //
  242. // Use the ethernet packet to satisfy the IRP.
  243. //=============================================================
  244. VOID
  245. tapCompletePendingReadIrp(
  246. __in PIRP Irp,
  247. __in PTAP_PACKET TapPacket
  248. )
  249. {
  250. int offset;
  251. int len;
  252. NTSTATUS status = STATUS_UNSUCCESSFUL;
  253. ASSERT(Irp);
  254. ASSERT(TapPacket);
  255. //-------------------------------------------
  256. // While TapPacket always contains a
  257. // full ethernet packet, including the
  258. // ethernet header, in point-to-point mode,
  259. // we only want to return the IPv4
  260. // component.
  261. //-------------------------------------------
  262. if (TapPacket->m_SizeFlags & TP_TUN)
  263. {
  264. offset = ETHERNET_HEADER_SIZE;
  265. len = (int) (TapPacket->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE;
  266. }
  267. else
  268. {
  269. offset = 0;
  270. len = (TapPacket->m_SizeFlags & TP_SIZE_MASK);
  271. }
  272. if (len < 0 || (int) Irp->IoStatus.Information < len)
  273. {
  274. Irp->IoStatus.Information = 0;
  275. Irp->IoStatus.Status = status = STATUS_BUFFER_OVERFLOW;
  276. NOTE_ERROR ();
  277. }
  278. else
  279. {
  280. Irp->IoStatus.Information = len;
  281. Irp->IoStatus.Status = status = STATUS_SUCCESS;
  282. // Copy packet data
  283. NdisMoveMemory(
  284. Irp->AssociatedIrp.SystemBuffer,
  285. TapPacket->m_Data + offset,
  286. len
  287. );
  288. }
  289. // Free the TAP packet
  290. NdisFreeMemory(TapPacket,0,0);
  291. // Complete the IRP
  292. IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);
  293. }
  294. VOID
  295. tapProcessSendPacketQueue(
  296. __in PTAP_ADAPTER_CONTEXT Adapter
  297. )
  298. {
  299. KIRQL irql;
  300. // Process the send packet queue
  301. KeAcquireSpinLock(&Adapter->SendPacketQueue.QueueLock,&irql);
  302. while(Adapter->SendPacketQueue.Count > 0 )
  303. {
  304. PIRP irp;
  305. PTAP_PACKET tapPacket;
  306. // Fetch a read IRP
  307. irp = IoCsqRemoveNextIrp(
  308. &Adapter->PendingReadIrpQueue.CsqQueue,
  309. NULL
  310. );
  311. if( irp == NULL )
  312. {
  313. // No IRP to satisfy
  314. break;
  315. }
  316. // Fetch a queued TAP send packet
  317. tapPacket = tapPacketRemoveHeadLocked(
  318. &Adapter->SendPacketQueue
  319. );
  320. ASSERT(tapPacket);
  321. // BUGBUG!!! Investigate whether release/reacquire can cause
  322. // out-of-order IRP completion. Also, whether user-mode can
  323. // tolerate out-of-order packets.
  324. // Release packet queue lock while completing the IRP
  325. //KeReleaseSpinLock(&Adapter->SendPacketQueue.QueueLock,irql);
  326. // Complete the read IRP from queued TAP send packet.
  327. tapCompletePendingReadIrp(irp,tapPacket);
  328. // Reqcquire packet queue lock after completing the IRP
  329. //KeAcquireSpinLock(&Adapter->SendPacketQueue.QueueLock,&irql);
  330. }
  331. KeReleaseSpinLock(&Adapter->SendPacketQueue.QueueLock,irql);
  332. }
  333. // Flush the pending send TAP packet queue.
  334. VOID
  335. tapFlushSendPacketQueue(
  336. __in PTAP_ADAPTER_CONTEXT Adapter
  337. )
  338. {
  339. KIRQL irql;
  340. // Process the send packet queue
  341. KeAcquireSpinLock(&Adapter->SendPacketQueue.QueueLock,&irql);
  342. DEBUGP (("[TAP] tapFlushSendPacketQueue: Flushing %d TAP packets\n",
  343. Adapter->SendPacketQueue.Count));
  344. while(Adapter->SendPacketQueue.Count > 0 )
  345. {
  346. PTAP_PACKET tapPacket;
  347. // Fetch a queued TAP send packet
  348. tapPacket = tapPacketRemoveHeadLocked(
  349. &Adapter->SendPacketQueue
  350. );
  351. ASSERT(tapPacket);
  352. // Free the TAP packet
  353. NdisFreeMemory(tapPacket,0,0);
  354. }
  355. KeReleaseSpinLock(&Adapter->SendPacketQueue.QueueLock,irql);
  356. }
  357. VOID
  358. tapAdapterTransmit(
  359. __in PTAP_ADAPTER_CONTEXT Adapter,
  360. __in PNET_BUFFER NetBuffer,
  361. __in BOOLEAN DispatchLevel
  362. )
  363. /*++
  364. Routine Description:
  365. This routine is called to transmit an individual net buffer using a
  366. style similar to the previous NDIS 5 AdapterTransmit function.
  367. In this implementation adapter state and NB length checks have already
  368. been done before this function has been called.
  369. The net buffer will be completed by the calling routine after this
  370. routine exits. So, under this design it is necessary to make a deep
  371. copy of frame data in the net buffer.
  372. This routine creates a flat buffer copy of NB frame data. This is an
  373. unnecessary performance bottleneck. However, the bottleneck is probably
  374. not significant or measurable except for adapters running at 1Gbps or
  375. greater speeds. Since this adapter is currently running at 100Mbps this
  376. defect can be ignored.
  377. Runs at IRQL <= DISPATCH_LEVEL
  378. Arguments:
  379. Adapter Pointer to our adapter context
  380. NetBuffer Pointer to the net buffer to transmit
  381. DispatchLevel TRUE if called at IRQL == DISPATCH_LEVEL
  382. Return Value:
  383. None.
  384. In the Microsoft NDIS 6 architecture there is no per-packet status.
  385. --*/
  386. {
  387. NDIS_STATUS status;
  388. ULONG packetLength;
  389. PTAP_PACKET tapPacket;
  390. PVOID packetData;
  391. packetLength = NET_BUFFER_DATA_LENGTH(NetBuffer);
  392. // Allocate TAP packet memory
  393. tapPacket = (PTAP_PACKET )NdisAllocateMemoryWithTagPriority(
  394. Adapter->MiniportAdapterHandle,
  395. TAP_PACKET_SIZE (packetLength),
  396. TAP_PACKET_TAG,
  397. NormalPoolPriority
  398. );
  399. if(tapPacket == NULL)
  400. {
  401. DEBUGP (("[TAP] tapAdapterTransmit: TAP packet allocation failed\n"));
  402. return;
  403. }
  404. tapPacket->m_SizeFlags = (packetLength & TP_SIZE_MASK);
  405. //
  406. // Reassemble packet contents
  407. // --------------------------
  408. // NdisGetDataBuffer does most of the work. There are two cases:
  409. //
  410. // 1.) If the NB data was not contiguous it will copy the entire
  411. // NB's data to m_data and return pointer to m_data.
  412. // 2.) If the NB data was contiguous it returns a pointer to the
  413. // first byte of the contiguous data instead of a pointer to m_Data.
  414. // In this case the data will not have been copied to m_Data. Copy
  415. // to m_Data will need to be done in an extra step.
  416. //
  417. // Case 1.) is the most likely in normal operation.
  418. //
  419. packetData = NdisGetDataBuffer(NetBuffer,packetLength,tapPacket->m_Data,1,0);
  420. if(packetData == NULL)
  421. {
  422. DEBUGP (("[TAP] tapAdapterTransmit: Could not get packet data\n"));
  423. NdisFreeMemory(tapPacket,0,0);
  424. return;
  425. }
  426. if(packetData != tapPacket->m_Data)
  427. {
  428. // Packet data was contiguous and not yet copied to m_Data.
  429. NdisMoveMemory(tapPacket->m_Data,packetData,packetLength);
  430. }
  431. DUMP_PACKET ("AdapterTransmit", tapPacket->m_Data, packetLength);
  432. //=====================================================
  433. // If IPv4 packet, check whether or not packet
  434. // was truncated.
  435. //=====================================================
  436. #if PACKET_TRUNCATION_CHECK
  437. IPv4PacketSizeVerify(
  438. tapPacket->m_Data,
  439. packetLength,
  440. FALSE,
  441. "TX",
  442. &Adapter->m_TxTrunc
  443. );
  444. #endif
  445. //=====================================================
  446. // Are we running in DHCP server masquerade mode?
  447. //
  448. // If so, catch both DHCP requests and ARP queries
  449. // to resolve the address of our virtual DHCP server.
  450. //=====================================================
  451. #if 0
  452. if (Adapter->m_dhcp_enabled)
  453. {
  454. const ETH_HEADER *eth = (ETH_HEADER *) tapPacket->m_Data;
  455. const IPHDR *ip = (IPHDR *) (tapPacket->m_Data + sizeof (ETH_HEADER));
  456. const UDPHDR *udp = (UDPHDR *) (tapPacket->m_Data + sizeof (ETH_HEADER) + sizeof (IPHDR));
  457. // ARP packet?
  458. if (packetLength == sizeof (ARP_PACKET)
  459. && eth->proto == htons (NDIS_ETH_TYPE_ARP)
  460. && Adapter->m_dhcp_server_arp
  461. )
  462. {
  463. if (ProcessARP(
  464. Adapter,
  465. (PARP_PACKET) tapPacket->m_Data,
  466. Adapter->m_dhcp_addr,
  467. Adapter->m_dhcp_server_ip,
  468. ~0,
  469. Adapter->m_dhcp_server_mac)
  470. )
  471. {
  472. goto no_queue;
  473. }
  474. }
  475. // DHCP packet?
  476. else if (packetLength >= sizeof (ETH_HEADER) + sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP)
  477. && eth->proto == htons (NDIS_ETH_TYPE_IPV4)
  478. && ip->version_len == 0x45 // IPv4, 20 byte header
  479. && ip->protocol == IPPROTO_UDP
  480. && udp->dest == htons (BOOTPS_PORT)
  481. )
  482. {
  483. const DHCP *dhcp = (DHCP *) (tapPacket->m_Data
  484. + sizeof (ETH_HEADER)
  485. + sizeof (IPHDR)
  486. + sizeof (UDPHDR));
  487. const int optlen = packetLength
  488. - sizeof (ETH_HEADER)
  489. - sizeof (IPHDR)
  490. - sizeof (UDPHDR)
  491. - sizeof (DHCP);
  492. if (optlen > 0) // we must have at least one DHCP option
  493. {
  494. if (ProcessDHCP (Adapter, eth, ip, udp, dhcp, optlen))
  495. {
  496. goto no_queue;
  497. }
  498. }
  499. else
  500. {
  501. goto no_queue;
  502. }
  503. }
  504. }
  505. #endif
  506. //===============================================
  507. // In Point-To-Point mode, check to see whether
  508. // packet is ARP (handled) or IPv4 (sent to app).
  509. // IPv6 packets are inspected for neighbour discovery
  510. // (to be handled locally), and the rest is forwarded
  511. // all other protocols are dropped
  512. //===============================================
  513. #if 0
  514. if (Adapter->m_tun)
  515. {
  516. ETH_HEADER *e;
  517. e = (ETH_HEADER *) tapPacket->m_Data;
  518. switch (ntohs (e->proto))
  519. {
  520. case NDIS_ETH_TYPE_ARP:
  521. // Make sure that packet is the right size for ARP.
  522. if (packetLength != sizeof (ARP_PACKET))
  523. {
  524. goto no_queue;
  525. }
  526. ProcessARP (
  527. Adapter,
  528. (PARP_PACKET) tapPacket->m_Data,
  529. Adapter->m_localIP,
  530. Adapter->m_remoteNetwork,
  531. Adapter->m_remoteNetmask,
  532. Adapter->m_TapToUser.dest
  533. );
  534. default:
  535. goto no_queue;
  536. case NDIS_ETH_TYPE_IPV4:
  537. // Make sure that packet is large enough to be IPv4.
  538. if (packetLength < (ETHERNET_HEADER_SIZE + IP_HEADER_SIZE))
  539. {
  540. goto no_queue;
  541. }
  542. // Only accept directed packets, not broadcasts.
  543. if (memcmp (e, &Adapter->m_TapToUser, ETHERNET_HEADER_SIZE))
  544. {
  545. goto no_queue;
  546. }
  547. // Packet looks like IPv4, queue it. :-)
  548. tapPacket->m_SizeFlags |= TP_TUN;
  549. break;
  550. case NDIS_ETH_TYPE_IPV6:
  551. // Make sure that packet is large enough to be IPv6.
  552. if (packetLength < (ETHERNET_HEADER_SIZE + IPV6_HEADER_SIZE))
  553. {
  554. goto no_queue;
  555. }
  556. // Broadcasts and multicasts are handled specially
  557. // (to be implemented)
  558. // Neighbor discovery packets to fe80::8 are special
  559. // OpenVPN sets this next-hop to signal "handled by tapdrv"
  560. if ( HandleIPv6NeighborDiscovery(Adapter,tapPacket->m_Data) )
  561. {
  562. goto no_queue;
  563. }
  564. // Packet looks like IPv6, queue it. :-)
  565. tapPacket->m_SizeFlags |= TP_TUN;
  566. }
  567. }
  568. #endif
  569. //===============================================
  570. // Push packet onto queue to wait for read from
  571. // userspace.
  572. //===============================================
  573. if(tapAdapterReadAndWriteReady(Adapter))
  574. {
  575. tapPacketQueueInsertTail(&Adapter->SendPacketQueue,tapPacket);
  576. }
  577. else
  578. {
  579. //
  580. // Tragedy. All this work and the packet is of no use...
  581. //
  582. NdisFreeMemory(tapPacket,0,0);
  583. }
  584. // Return after queuing or freeing TAP packet.
  585. return;
  586. // Free TAP packet without queuing.
  587. no_queue:
  588. if(tapPacket != NULL )
  589. {
  590. NdisFreeMemory(tapPacket,0,0);
  591. }
  592. exit_success:
  593. return;
  594. }
  595. VOID
  596. tapSendNetBufferListsComplete(
  597. __in PTAP_ADAPTER_CONTEXT Adapter,
  598. __in PNET_BUFFER_LIST NetBufferLists,
  599. __in NDIS_STATUS SendCompletionStatus,
  600. __in BOOLEAN DispatchLevel
  601. )
  602. {
  603. PNET_BUFFER_LIST currentNbl;
  604. PNET_BUFFER_LIST nextNbl = NULL;
  605. ULONG sendCompleteFlags = 0;
  606. for (
  607. currentNbl = NetBufferLists;
  608. currentNbl != NULL;
  609. currentNbl = nextNbl
  610. )
  611. {
  612. ULONG frameType;
  613. ULONG netBufferCount;
  614. ULONG byteCount;
  615. nextNbl = NET_BUFFER_LIST_NEXT_NBL(currentNbl);
  616. // Set NBL completion status.
  617. NET_BUFFER_LIST_STATUS(currentNbl) = SendCompletionStatus;
  618. // Fetch first NBs frame type. All linked NBs will have same type.
  619. frameType = tapGetNetBufferFrameType(NET_BUFFER_LIST_FIRST_NB(currentNbl));
  620. // Fetch statistics for all NBs linked to the NB.
  621. netBufferCount = tapGetNetBufferCountsFromNetBufferList(
  622. currentNbl,
  623. &byteCount
  624. );
  625. // Update statistics by frame type
  626. if(SendCompletionStatus == NDIS_STATUS_SUCCESS)
  627. {
  628. switch(frameType)
  629. {
  630. case NDIS_PACKET_TYPE_DIRECTED:
  631. Adapter->FramesTxDirected += netBufferCount;
  632. Adapter->BytesTxDirected += byteCount;
  633. break;
  634. case NDIS_PACKET_TYPE_BROADCAST:
  635. Adapter->FramesTxBroadcast += netBufferCount;
  636. Adapter->BytesTxBroadcast += byteCount;
  637. break;
  638. case NDIS_PACKET_TYPE_MULTICAST:
  639. Adapter->FramesTxMulticast += netBufferCount;
  640. Adapter->BytesTxMulticast += byteCount;
  641. break;
  642. default:
  643. ASSERT(FALSE);
  644. break;
  645. }
  646. }
  647. else
  648. {
  649. // Transmit error.
  650. Adapter->TransmitFailuresOther += netBufferCount;
  651. }
  652. currentNbl = nextNbl;
  653. }
  654. if(DispatchLevel)
  655. {
  656. sendCompleteFlags |= NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL;
  657. }
  658. // Complete the NBLs
  659. NdisMSendNetBufferListsComplete(
  660. Adapter->MiniportAdapterHandle,
  661. NetBufferLists,
  662. sendCompleteFlags
  663. );
  664. }
  665. BOOLEAN
  666. tapNetBufferListNetBufferLengthsValid(
  667. __in PTAP_ADAPTER_CONTEXT Adapter,
  668. __in PNET_BUFFER_LIST NetBufferLists
  669. )
  670. /*++
  671. Routine Description:
  672. Scan all NBLs and their linked NBs for valid lengths.
  673. Fairly absurd to find and packets with bogus lengths, but wise
  674. to check anyway. If ANY packet has a bogus length, then abort the
  675. entire send.
  676. The only time that one might see this check fail might be during
  677. HCK driver testing. The HKC test might send oversize packets to
  678. determine if the miniport can gracefully deal with them.
  679. This check is fairly fast. Unlike NDIS 5 packets, fetching NDIS 6
  680. packets lengths do not require any computation.
  681. Arguments:
  682. Adapter Pointer to our adapter context
  683. NetBufferLists Head of a list of NBLs to examine
  684. Return Value:
  685. Returns TRUE if all NBs have reasonable lengths.
  686. Otherwise, returns FALSE.
  687. --*/
  688. {
  689. PNET_BUFFER_LIST currentNbl;
  690. currentNbl = NetBufferLists;
  691. while (currentNbl)
  692. {
  693. PNET_BUFFER_LIST nextNbl;
  694. PNET_BUFFER currentNb;
  695. // Locate next NBL
  696. nextNbl = NET_BUFFER_LIST_NEXT_NBL(currentNbl);
  697. // Locate first NB (aka "packet")
  698. currentNb = NET_BUFFER_LIST_FIRST_NB(currentNbl);
  699. //
  700. // Process all NBs linked to this NBL
  701. //
  702. while(currentNb)
  703. {
  704. PNET_BUFFER nextNb;
  705. ULONG packetLength;
  706. // Locate next NB
  707. nextNb = NET_BUFFER_NEXT_NB(currentNb);
  708. packetLength = NET_BUFFER_DATA_LENGTH(currentNb);
  709. // Minimum packet size is size of Ethernet plus IPv4 headers.
  710. ASSERT(packetLength >= (ETHERNET_HEADER_SIZE + IP_HEADER_SIZE));
  711. if(packetLength < (ETHERNET_HEADER_SIZE + IP_HEADER_SIZE))
  712. {
  713. return FALSE;
  714. }
  715. // Maximum size should be Ethernet header size plus MTU plus modest pad for
  716. // VLAN tag.
  717. ASSERT( packetLength <= (ETHERNET_HEADER_SIZE + VLAN_TAG_SIZE + Adapter->MtuSize));
  718. if(packetLength > (ETHERNET_HEADER_SIZE + VLAN_TAG_SIZE + Adapter->MtuSize))
  719. {
  720. return FALSE;
  721. }
  722. // Move to next NB
  723. currentNb = nextNb;
  724. }
  725. // Move to next NBL
  726. currentNbl = nextNbl;
  727. }
  728. return TRUE;
  729. }
  730. VOID
  731. AdapterSendNetBufferLists(
  732. __in NDIS_HANDLE MiniportAdapterContext,
  733. __in PNET_BUFFER_LIST NetBufferLists,
  734. __in NDIS_PORT_NUMBER PortNumber,
  735. __in ULONG SendFlags
  736. )
  737. /*++
  738. Routine Description:
  739. Send Packet Array handler. Called by NDIS whenever a protocol
  740. bound to our miniport sends one or more packets.
  741. The input packet descriptor pointers have been ordered according
  742. to the order in which the packets should be sent over the network
  743. by the protocol driver that set up the packet array. The NDIS
  744. library preserves the protocol-determined ordering when it submits
  745. each packet array to MiniportSendPackets
  746. As a deserialized driver, we are responsible for holding incoming send
  747. packets in our internal queue until they can be transmitted over the
  748. network and for preserving the protocol-determined ordering of packet
  749. descriptors incoming to its MiniportSendPackets function.
  750. A deserialized miniport driver must complete each incoming send packet
  751. with NdisMSendComplete, and it cannot call NdisMSendResourcesAvailable.
  752. Runs at IRQL <= DISPATCH_LEVEL
  753. Arguments:
  754. MiniportAdapterContext Pointer to our adapter
  755. NetBufferLists Head of a list of NBLs to send
  756. PortNumber A miniport adapter port. Default is 0.
  757. SendFlags Additional flags for the send operation
  758. Return Value:
  759. None. Write status directly into each NBL with the NET_BUFFER_LIST_STATUS
  760. macro.
  761. --*/
  762. {
  763. NDIS_STATUS status;
  764. PTAP_ADAPTER_CONTEXT adapter = (PTAP_ADAPTER_CONTEXT )MiniportAdapterContext;
  765. BOOLEAN DispatchLevel = (SendFlags & NDIS_SEND_FLAGS_DISPATCH_LEVEL);
  766. PNET_BUFFER_LIST currentNbl;
  767. BOOLEAN validNbLengths;
  768. UNREFERENCED_PARAMETER(NetBufferLists);
  769. UNREFERENCED_PARAMETER(PortNumber);
  770. UNREFERENCED_PARAMETER(SendFlags);
  771. ASSERT(PortNumber == 0); // Only the default port is supported
  772. //
  773. // Can't process sends if TAP device is not open.
  774. // ----------------------------------------------
  775. // Just perform a "lying send" and return packets as if they
  776. // were successfully sent.
  777. //
  778. if(adapter->TapFileObject == NULL)
  779. {
  780. //
  781. // Complete all NBLs and return if adapter not ready.
  782. //
  783. tapSendNetBufferListsComplete(
  784. adapter,
  785. NetBufferLists,
  786. NDIS_STATUS_SUCCESS,
  787. DispatchLevel
  788. );
  789. return;
  790. }
  791. //
  792. // Check Adapter send/receive ready state.
  793. //
  794. status = tapAdapterSendAndReceiveReady(adapter);
  795. if(status != NDIS_STATUS_SUCCESS)
  796. {
  797. //
  798. // Complete all NBLs and return if adapter not ready.
  799. //
  800. tapSendNetBufferListsComplete(
  801. adapter,
  802. NetBufferLists,
  803. status,
  804. DispatchLevel
  805. );
  806. return;
  807. }
  808. //
  809. // Scan all NBLs and linked packets for valid lengths.
  810. // ---------------------------------------------------
  811. // If _ANY_ NB length is invalid, then fail the entire send operation.
  812. //
  813. // BUGBUG!!! Perhaps this should be less agressive. Fail only individual
  814. // NBLs...
  815. //
  816. // If length check is valid, then TAP_PACKETS can be safely allocated
  817. // and processed for all NBs being sent.
  818. //
  819. validNbLengths = tapNetBufferListNetBufferLengthsValid(
  820. adapter,
  821. NetBufferLists
  822. );
  823. if(!validNbLengths)
  824. {
  825. //
  826. // Complete all NBLs and return if and NB length is invalid.
  827. //
  828. tapSendNetBufferListsComplete(
  829. adapter,
  830. NetBufferLists,
  831. NDIS_STATUS_INVALID_LENGTH,
  832. DispatchLevel
  833. );
  834. return;
  835. }
  836. //
  837. // Process each NBL individually
  838. //
  839. currentNbl = NetBufferLists;
  840. while (currentNbl)
  841. {
  842. PNET_BUFFER_LIST nextNbl;
  843. PNET_BUFFER currentNb;
  844. // Locate next NBL
  845. nextNbl = NET_BUFFER_LIST_NEXT_NBL(currentNbl);
  846. // Locate first NB (aka "packet")
  847. currentNb = NET_BUFFER_LIST_FIRST_NB(currentNbl);
  848. // Transmit all NBs linked to this NBL
  849. while(currentNb)
  850. {
  851. PNET_BUFFER nextNb;
  852. // Locate next NB
  853. nextNb = NET_BUFFER_NEXT_NB(currentNb);
  854. // Transmit the NB
  855. tapAdapterTransmit(adapter,currentNb,DispatchLevel);
  856. // Move to next NB
  857. currentNb = nextNb;
  858. }
  859. // Move to next NBL
  860. currentNbl = nextNbl;
  861. }
  862. // Complete all NBLs
  863. tapSendNetBufferListsComplete(
  864. adapter,
  865. NetBufferLists,
  866. NDIS_STATUS_SUCCESS,
  867. DispatchLevel
  868. );
  869. // Attempt to complete pending read IRPs from pending TAP
  870. // send packet queue.
  871. tapProcessSendPacketQueue(adapter);
  872. }
  873. VOID
  874. AdapterCancelSend(
  875. __in NDIS_HANDLE MiniportAdapterContext,
  876. __in PVOID CancelId
  877. )
  878. {
  879. PTAP_ADAPTER_CONTEXT adapter = (PTAP_ADAPTER_CONTEXT )MiniportAdapterContext;
  880. //
  881. // This miniport completes its sends quickly, so it isn't strictly
  882. // neccessary to implement MiniportCancelSend.
  883. //
  884. // If we did implement it, we'd have to walk the Adapter->SendWaitList
  885. // and look for any NB that points to a NBL where the CancelId matches
  886. // NDIS_GET_NET_BUFFER_LIST_CANCEL_ID(Nbl). For any NB that so matches,
  887. // we'd remove the NB from the SendWaitList and set the NBL's status to
  888. // NDIS_STATUS_SEND_ABORTED, then complete the NBL.
  889. //
  890. }
  891. // IRP_MJ_READ callback.
  892. NTSTATUS
  893. TapDeviceRead(
  894. PDEVICE_OBJECT DeviceObject,
  895. PIRP Irp
  896. )
  897. {
  898. NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
  899. PIO_STACK_LOCATION irpSp;// Pointer to current stack location
  900. PTAP_ADAPTER_CONTEXT adapter = NULL;
  901. PAGED_CODE();
  902. irpSp = IoGetCurrentIrpStackLocation( Irp );
  903. //
  904. // Fetch adapter context for this device.
  905. // --------------------------------------
  906. // Adapter pointer was stashed in FsContext when handle was opened.
  907. //
  908. adapter = (PTAP_ADAPTER_CONTEXT )(irpSp->FileObject)->FsContext;
  909. ASSERT(adapter);
  910. //
  911. // Sanity checks on state variables
  912. //
  913. if (!tapAdapterReadAndWriteReady(adapter))
  914. {
  915. //DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n",
  916. // MINIPORT_INSTANCE_ID (adapter)));
  917. //NOTE_ERROR();
  918. Irp->IoStatus.Status = ntStatus = STATUS_CANCELLED;
  919. Irp->IoStatus.Information = 0;
  920. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  921. return ntStatus;
  922. }
  923. // Save IRP-accessible copy of buffer length
  924. Irp->IoStatus.Information = irpSp->Parameters.Read.Length;
  925. if (Irp->MdlAddress == NULL)
  926. {
  927. DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n",
  928. MINIPORT_INSTANCE_ID (adapter)));
  929. NOTE_ERROR();
  930. Irp->IoStatus.Status = ntStatus = STATUS_INVALID_PARAMETER;
  931. Irp->IoStatus.Information = 0;
  932. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  933. return ntStatus;
  934. }
  935. if ((Irp->AssociatedIrp.SystemBuffer
  936. = MmGetSystemAddressForMdlSafe(
  937. Irp->MdlAddress,
  938. NormalPagePriority
  939. ) ) == NULL
  940. )
  941. {
  942. DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n",
  943. MINIPORT_INSTANCE_ID (adapter)));
  944. NOTE_ERROR();
  945. Irp->IoStatus.Status = ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  946. Irp->IoStatus.Information = 0;
  947. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  948. return ntStatus;
  949. }
  950. // BUGBUG!!! Use RemoveLock???
  951. //
  952. // Queue the IRP and return STATUS_PENDING.
  953. // ----------------------------------------
  954. // Note: IoCsqInsertIrp marks the IRP pending.
  955. //
  956. // BUGBUG!!! NDIS 5 implementation has IRP_QUEUE_SIZE of 16 and
  957. // does not queue IRP if this capacity is exceeded.
  958. //
  959. // Is this needed???
  960. //
  961. IoCsqInsertIrp(&adapter->PendingReadIrpQueue.CsqQueue, Irp, NULL);
  962. // Attempt to complete pending read IRPs from pending TAP
  963. // send packet queue.
  964. tapProcessSendPacketQueue(adapter);
  965. ntStatus = STATUS_PENDING;
  966. return ntStatus;
  967. }