Source code of Windows XP (NT5)
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.

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