Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

959 lines
34 KiB

  1. // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
  2. //
  3. // Copyright (c) 1985-2000 Microsoft Corporation
  4. //
  5. // This file is part of the Microsoft Research IPv6 Network Protocol Stack.
  6. // You should have received a copy of the Microsoft End-User License Agreement
  7. // for this software along with this release; see the file "license.txt".
  8. // If not, please see http://www.research.microsoft.com/msripv6/license.htm,
  9. // or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
  10. //
  11. // Abstract:
  12. //
  13. // User Datagram Protocol code.
  14. //
  15. #include "oscfg.h"
  16. #include "ndis.h"
  17. #include "ip6imp.h"
  18. #include "ip6def.h"
  19. #include "icmp.h"
  20. #include "tdi.h"
  21. #include "tdint.h"
  22. #include "tdistat.h"
  23. #include "queue.h"
  24. #include "transprt.h"
  25. #include "addr.h"
  26. #include "udp.h"
  27. #include "info.h"
  28. #include "route.h"
  29. #include "security.h"
  30. //
  31. // TDI_CMSG_SPACE generates the following warning.
  32. //
  33. #pragma warning(disable:4116) // unnamed type definition in parentheses
  34. #define NO_TCP_DEFS 1
  35. #include "tcpdeb.h"
  36. //
  37. // REVIEW: Shouldn't this be in an include file somewhere?
  38. //
  39. #ifdef POOL_TAGGING
  40. #ifdef ExAllocatePool
  41. #undef ExAllocatePool
  42. #endif
  43. #define ExAllocatePool(type, size) ExAllocatePoolWithTag(type, size, '6PDU')
  44. #endif // POOL_TAGGING
  45. extern KSPIN_LOCK AddrObjTableLock;
  46. extern TDI_STATUS MapIPError(IP_STATUS IPError,TDI_STATUS Default);
  47. //* UDPSend - Send a user datagram.
  48. //
  49. // The real send datagram routine. We assume that the busy bit is
  50. // set on the input AddrObj, and that the address of the SendReq
  51. // has been verified.
  52. //
  53. // We start by sending the input datagram, and we loop until there's
  54. // nothing left on the send queue.
  55. //
  56. void // Returns: Nothing.
  57. UDPSend(
  58. AddrObj *SrcAO, // Address Object of endpoint doing the send.
  59. DGSendReq *SendReq) // Datagram send request describing the send.
  60. {
  61. KIRQL Irql0;
  62. RouteCacheEntry *RCE;
  63. NetTableEntryOrInterface *NTEorIF;
  64. NetTableEntry *NTE;
  65. Interface *IF;
  66. IPv6Header UNALIGNED *IP;
  67. UDPHeader UNALIGNED *UDP;
  68. uint PayloadLength;
  69. PNDIS_PACKET Packet;
  70. PNDIS_BUFFER UDPBuffer;
  71. void *Memory;
  72. IP_STATUS Status;
  73. NDIS_STATUS NdisStatus;
  74. TDI_STATUS ErrorValue;
  75. uint Offset;
  76. uint HeaderLength;
  77. uint ChecksumLength = 0;
  78. int Hops;
  79. CHECK_STRUCT(SrcAO, ao);
  80. ASSERT(SrcAO->ao_usecnt != 0);
  81. //
  82. // Loop while we have something to send, and can get
  83. // the resources to send it.
  84. //
  85. for (;;) {
  86. CHECK_STRUCT(SendReq, dsr);
  87. //
  88. // Determine NTE to send on (if user cares).
  89. // We do this prior to allocating packet header buffers so
  90. // we know how much room to leave for the link-level header.
  91. //
  92. // REVIEW: We may need to add a DHCP case later that checks for
  93. // REVIEW: the AO_DHCP_FLAG and allows src addr to be unspecified.
  94. //
  95. if (!IsUnspecified(&SrcAO->ao_addr)) {
  96. //
  97. // Convert the bound address to a NTE.
  98. //
  99. NTE = FindNetworkWithAddress(&SrcAO->ao_addr, SrcAO->ao_scope_id);
  100. if (NTE == NULL) {
  101. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_USER_ERROR,
  102. "UDPSend: Bad source address\n"));
  103. ErrorValue = TDI_INVALID_REQUEST;
  104. ReturnError:
  105. //
  106. // If possible, complete the request with an error.
  107. // Free the request structure.
  108. //
  109. if (SendReq->dsr_rtn != NULL)
  110. (*SendReq->dsr_rtn)(SendReq->dsr_context,
  111. ErrorValue, 0);
  112. KeAcquireSpinLock(&DGSendReqLock, &Irql0);
  113. FreeDGSendReq(SendReq);
  114. KeReleaseSpinLock(&DGSendReqLock, Irql0);
  115. goto SendComplete;
  116. }
  117. } else {
  118. //
  119. // We are not binding to any address.
  120. //
  121. NTE = NULL;
  122. }
  123. NTEorIF = CastFromNTE(NTE);
  124. //
  125. // If this is a multicast packet, check if the application
  126. // has specified an interface. Note that ao_mcast_if
  127. // overrides ao_addr if both are specified and they conflict.
  128. //
  129. if (IsMulticast(&SendReq->dsr_addr) && (SrcAO->ao_mcast_if != 0) &&
  130. ((NTE == NULL) || (NTE->IF->Index != SrcAO->ao_mcast_if))) {
  131. if (NTE != NULL) {
  132. ReleaseNTE(NTE);
  133. NTE = NULL;
  134. }
  135. IF = FindInterfaceFromIndex(SrcAO->ao_mcast_if);
  136. if (IF == NULL) {
  137. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_USER_ERROR,
  138. "UDPSend: Bad mcast interface number\n"));
  139. ErrorValue = TDI_INVALID_REQUEST;
  140. goto ReturnError;
  141. }
  142. NTEorIF = CastFromIF(IF);
  143. } else {
  144. IF = NULL;
  145. }
  146. //
  147. // Get the route.
  148. //
  149. Status = RouteToDestination(&SendReq->dsr_addr, SendReq->dsr_scope_id,
  150. NTEorIF, RTD_FLAG_NORMAL, &RCE);
  151. if (IF != NULL)
  152. ReleaseIF(IF);
  153. if (Status != IP_SUCCESS) {
  154. //
  155. // Failed to get a route to the destination. Error out.
  156. //
  157. if ((Status == IP_PARAMETER_PROBLEM) ||
  158. (Status == IP_BAD_ROUTE))
  159. ErrorValue = TDI_BAD_ADDR;
  160. else if (Status == IP_NO_RESOURCES)
  161. ErrorValue = TDI_NO_RESOURCES;
  162. else
  163. ErrorValue = TDI_DEST_UNREACHABLE;
  164. if (NTE != NULL)
  165. ReleaseNTE(NTE);
  166. goto ReturnError;
  167. }
  168. //
  169. // If our address object didn't have a source address,
  170. // take the one of the sending net from the RCE.
  171. // Otherwise, use address from AO.
  172. //
  173. if (NTE == NULL) {
  174. NTE = RCE->NTE;
  175. AddRefNTE(NTE);
  176. }
  177. //
  178. // Allocate a packet header to anchor the buffer list.
  179. //
  180. NdisAllocatePacket(&NdisStatus, &Packet, IPv6PacketPool);
  181. if (NdisStatus != NDIS_STATUS_SUCCESS) {
  182. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  183. "UDPSend: Couldn't allocate packet header!?!\n"));
  184. //
  185. // If we can't get a packet header from the pool, we push
  186. // the send request back on the queue and queue the address
  187. // object for when we get resources.
  188. //
  189. OutOfResources:
  190. ReleaseRCE(RCE);
  191. ReleaseNTE(NTE);
  192. KeAcquireSpinLock(&SrcAO->ao_lock, &Irql0);
  193. PUSHQ(&SrcAO->ao_sendq, &SendReq->dsr_q);
  194. PutPendingQ(SrcAO);
  195. KeReleaseSpinLock(&SrcAO->ao_lock, Irql0);
  196. return;
  197. }
  198. InitializeNdisPacket(Packet);
  199. PC(Packet)->CompletionHandler = DGSendComplete;
  200. PC(Packet)->CompletionData = SendReq;
  201. //
  202. // Our header buffer has extra space at the beginning for other
  203. // headers to be prepended to ours without requiring further
  204. // allocation calls.
  205. //
  206. Offset = RCE->NCE->IF->LinkHeaderSize;
  207. HeaderLength = Offset + sizeof(*IP) + sizeof(*UDP);
  208. Memory = ExAllocatePool(NonPagedPool, HeaderLength);
  209. if (Memory == NULL) {
  210. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  211. "UDPSend: couldn't allocate header memory!?!\n"));
  212. NdisFreePacket(Packet);
  213. goto OutOfResources;
  214. }
  215. NdisAllocateBuffer(&NdisStatus, &UDPBuffer, IPv6BufferPool,
  216. Memory, HeaderLength);
  217. if (NdisStatus != NDIS_STATUS_SUCCESS) {
  218. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  219. "UDPSend: couldn't allocate buffer!?!\n"));
  220. ExFreePool(Memory);
  221. NdisFreePacket(Packet);
  222. goto OutOfResources;
  223. }
  224. //
  225. // Link the data buffers from the send request onto the buffer
  226. // chain headed by our header buffer. Then attach this chain
  227. // to the packet.
  228. //
  229. NDIS_BUFFER_LINKAGE(UDPBuffer) = SendReq->dsr_buffer;
  230. NdisChainBufferAtFront(Packet, UDPBuffer);
  231. //
  232. // We now have all the resources we need to send.
  233. // Prepare the actual packet.
  234. //
  235. PayloadLength = SendReq->dsr_size + sizeof(UDPHeader);
  236. //
  237. // Our UDP Header buffer has extra space for other buffers to be
  238. // prepended to ours without requiring further allocation calls.
  239. // Put the actual UDP/IP header at the end of the buffer.
  240. //
  241. IP = (IPv6Header UNALIGNED *)((uchar *)Memory + Offset);
  242. IP->VersClassFlow = IP_VERSION;
  243. IP->NextHeader = IP_PROTOCOL_UDP;
  244. IP->Source = NTE->Address;
  245. IP->Dest = SendReq->dsr_addr;
  246. //
  247. // Apply the multicast or unicast hop limit, as appropriate.
  248. //
  249. if (IsMulticast(AlignAddr(&IP->Dest))) {
  250. //
  251. // Also disable multicast loopback, if requested.
  252. //
  253. if (! SrcAO->ao_mcast_loop)
  254. PC(Packet)->Flags |= NDIS_FLAGS_DONT_LOOPBACK;
  255. Hops = SrcAO->ao_mcast_hops;
  256. }
  257. else
  258. Hops = SrcAO->ao_ucast_hops;
  259. if (Hops != -1)
  260. IP->HopLimit = (uchar) Hops;
  261. else
  262. IP->HopLimit = (uchar) RCE->NCE->IF->CurHopLimit;
  263. //
  264. // Fill in UDP Header fields.
  265. //
  266. UDP = (UDPHeader UNALIGNED *)(IP + 1);
  267. UDP->Source = SrcAO->ao_port;
  268. UDP->Dest = SendReq->dsr_port;
  269. //
  270. // Check if the user specified a partial UDP checksum.
  271. // The possible values are 0, 8, or greater.
  272. //
  273. if ((SrcAO->ao_udp_cksum_cover > PayloadLength) ||
  274. (SrcAO->ao_udp_cksum_cover == 0) ||
  275. (SrcAO->ao_udp_cksum_cover == (ushort)-1)) {
  276. //
  277. // The checksum coverage is the default so just use the
  278. // payload length. Or, the checksum coverage is bigger
  279. // than the actual payload so include the payload length.
  280. //
  281. if ((PayloadLength > MAX_IPv6_PAYLOAD) ||
  282. (SrcAO->ao_udp_cksum_cover == (ushort)-1)) {
  283. //
  284. // If the PayloadLength is too large for the UDP Length field,
  285. // set the field to zero. Or for testing:
  286. // if the ao_udp_cksum_cover is -1.
  287. //
  288. UDP->Length = 0;
  289. } else {
  290. //
  291. // For backwards-compatibility, set the UDP Length field
  292. // to the payload length.
  293. //
  294. UDP->Length = net_short((ushort)PayloadLength);
  295. }
  296. ChecksumLength = PayloadLength;
  297. } else {
  298. //
  299. // The checksum coverage is less than the actual payload
  300. // so use it in the length field.
  301. //
  302. UDP->Length = net_short(SrcAO->ao_udp_cksum_cover);
  303. ChecksumLength = SrcAO->ao_udp_cksum_cover;
  304. }
  305. //
  306. // Compute the UDP checksum. It covers the entire UDP datagram
  307. // starting with the UDP header, plus the IPv6 pseudo-header.
  308. //
  309. UDP->Checksum = 0;
  310. UDP->Checksum = ChecksumPacket(
  311. Packet, Offset + sizeof *IP, NULL, ChecksumLength,
  312. AlignAddr(&IP->Source), AlignAddr(&IP->Dest), IP_PROTOCOL_UDP);
  313. if (UDP->Checksum == 0) {
  314. //
  315. // ChecksumPacket failed, so abort the transmission.
  316. //
  317. IPv6SendComplete(NULL, Packet, IP_NO_RESOURCES);
  318. }
  319. else {
  320. //
  321. // Allow the AO to receive data when in firewall mode.
  322. //
  323. SET_AO_SENTDATA(SrcAO);
  324. //
  325. // Everything's ready. Now send the packet.
  326. //
  327. // Note that IPv6Send does not return a status code.
  328. // Instead it *always* completes the packet
  329. // with an appropriate status code.
  330. //
  331. UStats.us_outdatagrams++;
  332. IPv6Send(Packet, Offset, IP, PayloadLength, RCE, 0,
  333. IP_PROTOCOL_UDP,
  334. net_short(UDP->Source),
  335. net_short(UDP->Dest));
  336. }
  337. //
  338. // Release the route and NTE.
  339. //
  340. ReleaseRCE(RCE);
  341. ReleaseNTE(NTE);
  342. SendComplete:
  343. //
  344. // Check the send queue for more to send.
  345. //
  346. KeAcquireSpinLock(&SrcAO->ao_lock, &Irql0);
  347. if (!EMPTYQ(&SrcAO->ao_sendq)) {
  348. //
  349. // More to go. Dequeue next request and loop back to top.
  350. //
  351. DEQUEUE(&SrcAO->ao_sendq, SendReq, DGSendReq, dsr_q);
  352. KeReleaseSpinLock(&SrcAO->ao_lock, Irql0);
  353. } else {
  354. //
  355. // Nothing more to send.
  356. //
  357. CLEAR_AO_REQUEST(SrcAO, AO_SEND);
  358. KeReleaseSpinLock(&SrcAO->ao_lock, Irql0);
  359. return;
  360. }
  361. }
  362. }
  363. //* UDPDeliver - Deliver a datagram to a user.
  364. //
  365. // This routine delivers a datagram to a UDP user. We're called with
  366. // the AddrObj to deliver on, and with the lock for that AddrObj held.
  367. // We try to find a receive on the specified AddrObj, and if we do
  368. // we remove it and copy the data into the buffer. Otherwise we'll
  369. // call the receive datagram event handler, if there is one. If that
  370. // fails we'll discard the datagram.
  371. //
  372. void // Returns: Nothing.
  373. UDPDeliver(
  374. AddrObj *RcvAO, // AddrObj to receive datagram.
  375. IPv6Packet *Packet, // Packet handed up by IP.
  376. uint SrcScopeId, // Scope id for source address.
  377. ushort SrcPort, // Source port of datagram.
  378. uint Length, // Size of UDP payload data.
  379. KIRQL Irql0) // IRQL prior to acquiring AddrObj table lock.
  380. {
  381. Queue *CurrentQ;
  382. DGRcvReq *RcvReq;
  383. ULONG BytesTaken = 0;
  384. uchar AddressBuffer[TCP_TA_SIZE];
  385. uint RcvdSize;
  386. EventRcvBuffer *ERB = NULL;
  387. uint Position = Packet->Position;
  388. CHECK_STRUCT(RcvAO, ao);
  389. if (AO_VALID(RcvAO)) {
  390. CurrentQ = QHEAD(&RcvAO->ao_rcvq);
  391. // Walk the list, looking for a receive buffer that matches.
  392. while (CurrentQ != QEND(&RcvAO->ao_rcvq)) {
  393. RcvReq = QSTRUCT(DGRcvReq, CurrentQ, drr_q);
  394. CHECK_STRUCT(RcvReq, drr);
  395. //
  396. // If this request is a wildcard request, or matches the source IP
  397. // address and scope id, check the port.
  398. //
  399. if (IsUnspecified(&RcvReq->drr_addr) ||
  400. (IP6_ADDR_EQUAL(&RcvReq->drr_addr, Packet->SrcAddr) &&
  401. (RcvReq->drr_scope_id == SrcScopeId))) {
  402. //
  403. // The remote address matches, check the port.
  404. // We'll match either 0 or the actual port.
  405. //
  406. if (RcvReq->drr_port == 0 || RcvReq->drr_port == SrcPort) {
  407. TDI_STATUS Status;
  408. // The ports matched. Remove this from the queue.
  409. REMOVEQ(&RcvReq->drr_q);
  410. // We're done. We can free the AddrObj lock now.
  411. KeReleaseSpinLock(&RcvAO->ao_lock, Irql0);
  412. // Copy the data, and then complete the request.
  413. RcvdSize = CopyToBufferChain(RcvReq->drr_buffer, 0,
  414. Packet->NdisPacket,
  415. Position,
  416. Packet->FlatData,
  417. MIN(Length,
  418. RcvReq->drr_size));
  419. ASSERT(RcvdSize <= RcvReq->drr_size);
  420. Status = UpdateConnInfo(RcvReq->drr_conninfo,
  421. Packet->SrcAddr, SrcScopeId,
  422. SrcPort);
  423. UStats.us_indatagrams++;
  424. (*RcvReq->drr_rtn)(RcvReq->drr_context, Status, RcvdSize);
  425. FreeDGRcvReq(RcvReq);
  426. return; // All done.
  427. }
  428. }
  429. //
  430. // Either the IP address or the port didn't match.
  431. // Get the next one.
  432. //
  433. CurrentQ = QNEXT(CurrentQ);
  434. }
  435. //
  436. // We've walked the list, and not found a buffer.
  437. // Call the receive handler now, if we have one.
  438. //
  439. if (RcvAO->ao_rcvdg != NULL) {
  440. PRcvDGEvent RcvEvent = RcvAO->ao_rcvdg;
  441. PVOID RcvContext = RcvAO->ao_rcvdgcontext;
  442. TDI_STATUS RcvStatus;
  443. ULONG Flags = TDI_RECEIVE_COPY_LOOKAHEAD;
  444. int BufferSize = 0;
  445. PVOID BufferToSend = NULL;
  446. uchar *CurrPosition;
  447. REF_AO(RcvAO);
  448. KeReleaseSpinLock(&RcvAO->ao_lock, Irql0);
  449. BuildTDIAddress(AddressBuffer, Packet->SrcAddr, SrcScopeId,
  450. SrcPort);
  451. UStats.us_indatagrams++;
  452. if (IsMulticast(AlignAddr(&Packet->IP->Dest))) {
  453. Flags |= TDI_RECEIVE_MULTICAST;
  454. }
  455. // If the IPV6_PKTINFO or IPV6_HOPLIMIT options were set, then
  456. // create the control information to be passed to the handler.
  457. // Currently this is the only place such options are filled in,
  458. // so we just have one buffer. If other places are added in the
  459. // future, we may want to support a list or array of buffers to
  460. // copy into the user's buffer.
  461. //
  462. if (AO_PKTINFO(RcvAO)) {
  463. BufferSize += TDI_CMSG_SPACE(sizeof(IN6_PKTINFO));
  464. }
  465. if (AO_RCV_HOPLIMIT(RcvAO)) {
  466. BufferSize += TDI_CMSG_SPACE(sizeof(int));
  467. }
  468. if (BufferSize > 0) {
  469. CurrPosition = BufferToSend = ExAllocatePool(NonPagedPool,
  470. BufferSize);
  471. if (BufferToSend == NULL) {
  472. BufferSize = 0;
  473. } else {
  474. if (AO_PKTINFO(RcvAO)) {
  475. DGFillIpv6PktInfo(&Packet->IP->Dest,
  476. Packet->NTEorIF->IF->Index,
  477. &CurrPosition);
  478. // Set the receive flag so the receive handler knows
  479. // we are passing up control info.
  480. //
  481. Flags |= TDI_RECEIVE_CONTROL_INFO;
  482. }
  483. if (AO_RCV_HOPLIMIT(RcvAO)) {
  484. DGFillIpv6HopLimit(Packet->IP->HopLimit, &CurrPosition);
  485. Flags |= TDI_RECEIVE_CONTROL_INFO;
  486. }
  487. }
  488. }
  489. RcvStatus = (*RcvEvent)(RcvContext, TCP_TA_SIZE,
  490. (PTRANSPORT_ADDRESS)AddressBuffer,
  491. BufferSize, BufferToSend, Flags,
  492. Packet->ContigSize, Length, &BytesTaken,
  493. Packet->Data, &ERB);
  494. if (BufferToSend) {
  495. ExFreePool(BufferToSend);
  496. }
  497. if (RcvStatus == TDI_MORE_PROCESSING) {
  498. PIO_STACK_LOCATION IrpSp;
  499. PTDI_REQUEST_KERNEL_RECEIVEDG DatagramInformation;
  500. ASSERT(ERB != NULL);
  501. ASSERT(BytesTaken <= Packet->ContigSize);
  502. //
  503. // For NT, ERBs are really IRPs.
  504. //
  505. IrpSp = IoGetCurrentIrpStackLocation(ERB);
  506. DatagramInformation = (PTDI_REQUEST_KERNEL_RECEIVEDG)
  507. &(IrpSp->Parameters);
  508. //
  509. // Copy data to the IRP, skipping the bytes
  510. // that were already taken.
  511. //
  512. Position += BytesTaken;
  513. Length -= BytesTaken;
  514. RcvdSize = CopyToBufferChain(ERB->MdlAddress, 0,
  515. Packet->NdisPacket,
  516. Position,
  517. Packet->FlatData,
  518. Length);
  519. //
  520. // Update the return address info.
  521. //
  522. RcvStatus = UpdateConnInfo(
  523. DatagramInformation->ReturnDatagramInformation,
  524. Packet->SrcAddr, SrcScopeId, SrcPort);
  525. //
  526. // Complete the IRP.
  527. //
  528. ERB->IoStatus.Information = RcvdSize;
  529. ERB->IoStatus.Status = RcvStatus;
  530. IoCompleteRequest(ERB, 2);
  531. } else {
  532. ASSERT((RcvStatus == TDI_SUCCESS) ||
  533. (RcvStatus == TDI_NOT_ACCEPTED));
  534. ASSERT(ERB == NULL);
  535. }
  536. DELAY_DEREF_AO(RcvAO);
  537. return;
  538. } else
  539. UStats.us_inerrors++;
  540. //
  541. // When we get here, we didn't have a buffer to put this data into.
  542. // Fall through to the return case.
  543. //
  544. } else
  545. UStats.us_inerrors++;
  546. KeReleaseSpinLock(&RcvAO->ao_lock, Irql0);
  547. }
  548. //* UDPReceive - Receive a UDP datagram.
  549. //
  550. // The routine called by IP when a UDP datagram arrived. We look up the
  551. // port/local address pair in our address table, and deliver the data to
  552. // a user if we find one. For multicast frames we may deliver it to
  553. // multiple users.
  554. //
  555. // Returns the next header value. Since no other header is allowed to
  556. // follow the UDP header, this is always IP_PROTOCOL_NONE.
  557. //
  558. uchar
  559. UDPReceive(
  560. IPv6Packet *Packet) // Packet IP handed up to us.
  561. {
  562. Interface *IF = Packet->NTEorIF->IF;
  563. UDPHeader *UDP;
  564. KIRQL OldIrql;
  565. AddrObj *ReceivingAO;
  566. uint Length;
  567. ushort Checksum;
  568. AOMCastAddr *AMA, *PrevAMA;
  569. int MCastReceiverFound;
  570. uint SrcScopeId, DestScopeId;
  571. uint Loop;
  572. //
  573. // Verify that the source address is reasonable.
  574. //
  575. ASSERT(!IsInvalidSourceAddress(Packet->SrcAddr));
  576. if (IsUnspecified(Packet->SrcAddr)) {
  577. UStats.us_inerrors++;
  578. return IP_PROTOCOL_NONE; // Drop packet.
  579. }
  580. //
  581. // Verify that we have enough contiguous data to overlay a UDPHeader
  582. // structure on the incoming packet. Then do so.
  583. //
  584. if (! PacketPullup(Packet, sizeof(UDPHeader),
  585. __builtin_alignof(UDPHeader), 0)) {
  586. // Pullup failed.
  587. UStats.us_inerrors++;
  588. if (Packet->TotalSize < sizeof(UDPHeader)) {
  589. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  590. "UDPv6: data buffer too small to contain UDP header\n"));
  591. ICMPv6SendError(Packet,
  592. ICMPv6_PARAMETER_PROBLEM,
  593. ICMPv6_ERRONEOUS_HEADER_FIELD,
  594. FIELD_OFFSET(IPv6Header, PayloadLength),
  595. IP_PROTOCOL_NONE, FALSE);
  596. }
  597. return IP_PROTOCOL_NONE; // Drop packet.
  598. }
  599. UDP = (UDPHeader *)Packet->Data;
  600. //
  601. // Verify IPSec was performed.
  602. //
  603. if (InboundSecurityCheck(Packet, IP_PROTOCOL_UDP, net_short(UDP->Source),
  604. net_short(UDP->Dest), IF) != TRUE) {
  605. //
  606. // No policy was found or the policy found was to drop the packet.
  607. //
  608. UStats.us_inerrors++;
  609. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  610. "UDPReceive: IPSec Policy caused packet to be dropped\n"));
  611. return IP_PROTOCOL_NONE; // Drop packet.
  612. }
  613. //
  614. // Verify UDP length is reasonable.
  615. //
  616. // NB: If Length < PayloadLength, then UDP-Lite semantics apply.
  617. // We checksum only the UDP Length bytes, but we deliver
  618. // all the bytes to the application.
  619. //
  620. Length = (uint) net_short(UDP->Length);
  621. if ((Length > Packet->TotalSize) || (Length < sizeof *UDP)) {
  622. //
  623. // UDP jumbo-gram support: if the UDP length is zero,
  624. // then use the payload length from IP.
  625. //
  626. if (Length != 0) {
  627. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  628. "UDPv6: bogus UDP length (%u vs %u payload)\n",
  629. Length, Packet->TotalSize));
  630. UStats.us_inerrors++;
  631. return IP_PROTOCOL_NONE; // Drop packet.
  632. }
  633. Length = Packet->TotalSize;
  634. }
  635. //
  636. // Set the source's scope id value as appropriate.
  637. //
  638. SrcScopeId = DetermineScopeId(Packet->SrcAddr, IF);
  639. //
  640. // At this point, we've decided it's okay to accept the packet.
  641. // Figure out who to give it to.
  642. //
  643. if (IsMulticast(AlignAddr(&Packet->IP->Dest))) {
  644. //
  645. // This is a multicast packet, so we need to find all interested
  646. // AddrObj's. We get the AddrObjTable lock, and then loop through
  647. // all AddrObj's and give the packet to any who are listening to
  648. // this multicast address, interface & port.
  649. // REVIEW: We match on interface, NOT scope id. Multicast is weird.
  650. //
  651. KeAcquireSpinLock(&AddrObjTableLock, &OldIrql);
  652. MCastReceiverFound = FALSE;
  653. for (Loop = 0; Loop < AddrObjTableSize; Loop++) {
  654. for (ReceivingAO = AddrObjTable[Loop]; ReceivingAO != NULL;
  655. ReceivingAO = ReceivingAO->ao_next) {
  656. CHECK_STRUCT(ReceivingAO, ao);
  657. if (ReceivingAO->ao_prot != IP_PROTOCOL_UDP ||
  658. ReceivingAO->ao_port != UDP->Dest)
  659. continue;
  660. if ((AMA = FindAOMCastAddr(ReceivingAO,
  661. AlignAddr(&Packet->IP->Dest),
  662. IF->Index, &PrevAMA,
  663. FALSE)) == NULL)
  664. continue;
  665. //
  666. // We have a matching address object. Trade in the table lock
  667. // for a lock on just this object.
  668. //
  669. KeAcquireSpinLockAtDpcLevel(&ReceivingAO->ao_lock);
  670. KeReleaseSpinLockFromDpcLevel(&AddrObjTableLock);
  671. //
  672. // If this is the first AO we've found, verify the checksum.
  673. //
  674. if (!MCastReceiverFound) {
  675. Checksum = ChecksumPacket(Packet->NdisPacket,
  676. Packet->Position,
  677. Packet->FlatData,
  678. Length,
  679. Packet->SrcAddr,
  680. AlignAddr(&Packet->IP->Dest),
  681. IP_PROTOCOL_UDP);
  682. if ((Checksum != 0xffff) || (UDP->Checksum == 0)) {
  683. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  684. "UDPReceive: Checksum failed %0x\n",
  685. Checksum));
  686. KeReleaseSpinLock(&ReceivingAO->ao_lock, OldIrql);
  687. UStats.us_inerrors++;
  688. return IP_PROTOCOL_NONE; // Drop packet.
  689. }
  690. //
  691. // Skip over the UDP header.
  692. //
  693. AdjustPacketParams(Packet, sizeof(UDPHeader));
  694. MCastReceiverFound = TRUE;
  695. }
  696. UDPDeliver(ReceivingAO, Packet, SrcScopeId, UDP->Source,
  697. Packet->TotalSize, OldIrql);
  698. //
  699. // UDPDeliver released the lock on the address object.
  700. // We earlier released the AddrObjTableLock, so grab it again.
  701. //
  702. KeAcquireSpinLock(&AddrObjTableLock, &OldIrql);
  703. }
  704. }
  705. if (!MCastReceiverFound)
  706. UStats.us_noports++;
  707. KeReleaseSpinLock(&AddrObjTableLock, OldIrql);
  708. } else {
  709. //
  710. // This is a unicast packet. We need to perform the checksum
  711. // regardless of whether or not we find a matching AddrObj,
  712. // since we send an ICMP port unreachable message for unicast
  713. // packets that don't match a port. So verify the checksum now.
  714. //
  715. Checksum = ChecksumPacket(Packet->NdisPacket, Packet->Position,
  716. Packet->FlatData, Length, Packet->SrcAddr,
  717. AlignAddr(&Packet->IP->Dest),
  718. IP_PROTOCOL_UDP);
  719. if ((Checksum != 0xffff) || (UDP->Checksum == 0)) {
  720. UStats.us_inerrors++;
  721. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  722. "UDPReceive: Checksum failed %0x\n", Checksum));
  723. return IP_PROTOCOL_NONE; // Drop packet.
  724. }
  725. //
  726. // Skip over the UDP header.
  727. //
  728. AdjustPacketParams(Packet, sizeof(UDPHeader));
  729. //
  730. // Try to find an AddrObj to give this packet to.
  731. //
  732. DestScopeId = DetermineScopeId(AlignAddr(&Packet->IP->Dest), IF);
  733. KeAcquireSpinLock(&AddrObjTableLock, &OldIrql);
  734. ReceivingAO = GetBestAddrObj(AlignAddr(&Packet->IP->Dest),
  735. Packet->SrcAddr,
  736. DestScopeId, UDP->Dest,
  737. IP_PROTOCOL_UDP, IF);
  738. if (ReceivingAO != NULL) {
  739. //
  740. // We have a matching address object. Trade in the table lock
  741. // for a lock on just this object, and then deliver the packet.
  742. //
  743. KeAcquireSpinLockAtDpcLevel(&ReceivingAO->ao_lock);
  744. KeReleaseSpinLockFromDpcLevel(&AddrObjTableLock);
  745. UDPDeliver(ReceivingAO, Packet, SrcScopeId, UDP->Source,
  746. Packet->TotalSize, OldIrql);
  747. // Note UDPDeliver released the lock on the address object.
  748. } else {
  749. KeReleaseSpinLock(&AddrObjTableLock, OldIrql);
  750. // Send ICMP Destination Port Unreachable.
  751. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  752. "UDPReceive: No match for packet's address and port\n"));
  753. ICMPv6SendError(Packet,
  754. ICMPv6_DESTINATION_UNREACHABLE,
  755. ICMPv6_PORT_UNREACHABLE, 0,
  756. IP_PROTOCOL_NONE, FALSE);
  757. UStats.us_noports++;
  758. }
  759. }
  760. return IP_PROTOCOL_NONE;
  761. }
  762. //* UDPControlReceive - handler for UDP control messages.
  763. //
  764. // This routine is called if we receive an ICMPv6 error message that
  765. // was generated by some remote site as a result of receiving a UDP
  766. // packet from us.
  767. //
  768. uchar
  769. UDPControlReceive(
  770. IPv6Packet *Packet, // Packet handed to us by ICMPv6ErrorReceive.
  771. StatusArg *StatArg) // Error Code, Argument, and invoking IP header.
  772. {
  773. UDPHeader *InvokingUDP;
  774. Interface *IF = Packet->NTEorIF->IF;
  775. uint SrcScopeId, DestScopeId;
  776. KIRQL Irql0;
  777. AddrObj *AO;
  778. //
  779. // Handle ICMPv6 errors that are meaningful to UDP clients.
  780. //
  781. switch (StatArg->Status) {
  782. case IP_DEST_ADDR_UNREACHABLE:
  783. case IP_DEST_PORT_UNREACHABLE:
  784. case IP_DEST_UNREACHABLE:
  785. //
  786. // The next thing in the packet should be the UDP header of the
  787. // original packet which invoked this error.
  788. //
  789. if (! PacketPullup(Packet, sizeof(UDPHeader),
  790. __builtin_alignof(UDPHeader), 0)) {
  791. // Pullup failed.
  792. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  793. "UDPv6: Packet too small to contain UDP header "
  794. "from invoking packet\n"));
  795. return IP_PROTOCOL_NONE; // Drop packet.
  796. }
  797. InvokingUDP = (UDPHeader *)Packet->Data;
  798. //
  799. // Determining the scope identifiers for the addreses in the
  800. // invoking packet is potentially problematic, since we have
  801. // no way to be certain which interface we sent the packet on.
  802. // Use the interface the icmp error arrived on to determine
  803. // the scope ids for both the local and remote addresses.
  804. //
  805. SrcScopeId = DetermineScopeId(AlignAddr(&StatArg->IP->Source), IF);
  806. KeAcquireSpinLock(&AddrObjTableLock, &Irql0);
  807. AO = GetBestAddrObj(AlignAddr(&StatArg->IP->Source),
  808. AlignAddr(&StatArg->IP->Dest), SrcScopeId,
  809. InvokingUDP->Source, IP_PROTOCOL_UDP, IF);
  810. if (AO != NULL && AO_VALID(AO) && (AO->ao_errorex != NULL)) {
  811. uchar AddressBuffer[TCP_TA_SIZE];
  812. PVOID ErrContext = AO->ao_errorexcontext;
  813. PTDI_IND_ERROR_EX ErrEvent = AO->ao_errorex;;
  814. KeAcquireSpinLockAtDpcLevel(&AO->ao_lock);
  815. KeReleaseSpinLockFromDpcLevel(&AddrObjTableLock);
  816. REF_AO(AO);
  817. KeReleaseSpinLock(&AO->ao_lock, Irql0);
  818. DestScopeId = DetermineScopeId(AlignAddr(&StatArg->IP->Dest), IF);
  819. BuildTDIAddress(AddressBuffer, AlignAddr(&StatArg->IP->Dest),
  820. DestScopeId, InvokingUDP->Dest);
  821. (*ErrEvent) (ErrContext,
  822. MapIPError(StatArg->Status, TDI_DEST_UNREACHABLE),
  823. AddressBuffer);
  824. DELAY_DEREF_AO(AO);
  825. } else {
  826. KeReleaseSpinLock(&AddrObjTableLock, Irql0);
  827. }
  828. }
  829. return IP_PROTOCOL_NONE;
  830. }