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.

797 lines
22 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. cnprecv.c
  5. Abstract:
  6. Cluster Network Protocol receive processing code.
  7. Author:
  8. Mike Massa (mikemas) January 24, 1997
  9. Revision History:
  10. Who When What
  11. -------- -------- ----------------------------------------------
  12. mikemas 01-24-97 created
  13. Notes:
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #include "cnprecv.tmh"
  18. #ifdef ALLOC_PRAGMA
  19. #pragma alloc_text(PAGE, CnpCreateSendRequestPool)
  20. #endif // ALLOC_PRAGMA
  21. //
  22. // Local types
  23. //
  24. typedef struct {
  25. ULONG TdiReceiveDatagramFlags;
  26. ULONG TsduSize;
  27. PCNP_NETWORK Network;
  28. ULONG CnpReceiveFlags;
  29. } CNP_RECEIVE_CONTEXT, *PCNP_RECEIVE_CONTEXT;
  30. //
  31. // Local Data
  32. //
  33. PCN_RESOURCE_POOL CnpReceiveRequestPool = NULL;
  34. #define CNP_RECEIVE_REQUEST_POOL_DEPTH 2
  35. //
  36. // Routines exported within the Cluster Transport
  37. //
  38. NTSTATUS
  39. CnpLoad(
  40. VOID
  41. )
  42. {
  43. IF_CNDBG(CN_DEBUG_INIT){
  44. CNPRINT(("[CNP] Loading...\n"));
  45. }
  46. CnpReceiveRequestPool = CnpCreateReceiveRequestPool(
  47. sizeof(CNP_RECEIVE_CONTEXT),
  48. CNP_RECEIVE_REQUEST_POOL_DEPTH
  49. );
  50. if (CnpReceiveRequestPool == NULL) {
  51. return(STATUS_INSUFFICIENT_RESOURCES);
  52. }
  53. IF_CNDBG(CN_DEBUG_INIT){
  54. CNPRINT(("[CNP] Loading complete.\n"));
  55. }
  56. return(STATUS_SUCCESS);
  57. } // CnpInitializeReceive
  58. VOID
  59. CnpUnload(
  60. VOID
  61. )
  62. {
  63. IF_CNDBG(CN_DEBUG_INIT){
  64. CNPRINT(("[CNP] Unloading...\n"));
  65. }
  66. if (CnpReceiveRequestPool != NULL) {
  67. CnpDeleteReceiveRequestPool(CnpReceiveRequestPool);
  68. CnpReceiveRequestPool = NULL;
  69. }
  70. IF_CNDBG(CN_DEBUG_INIT){
  71. CNPRINT(("[CNP] Unloading complete.\n"));
  72. }
  73. return;
  74. } // CnpCleanupReceive
  75. //
  76. // Private Utility Fumctions
  77. //
  78. PCN_RESOURCE
  79. CnpCreateReceiveRequest(
  80. IN PVOID Context
  81. )
  82. {
  83. PCNP_RECEIVE_REQUEST_POOL_CONTEXT context = Context;
  84. PCNP_RECEIVE_REQUEST request;
  85. PIRP irp;
  86. //
  87. // Allocate a new receive request. Include space for the upper protocol
  88. // context.
  89. //
  90. request = CnAllocatePool(
  91. sizeof(CNP_RECEIVE_REQUEST) +
  92. context->UpperProtocolContextSize
  93. );
  94. if (request != NULL) {
  95. request->UpperProtocolContext = request + 1;
  96. }
  97. return(&(request->CnResource));
  98. } // CnpCreateReceiveRequest
  99. VOID
  100. CnpDeleteReceiveRequest(
  101. PCN_RESOURCE Resource
  102. )
  103. {
  104. PCNP_RECEIVE_REQUEST request = CONTAINING_RECORD(
  105. Resource,
  106. CNP_RECEIVE_REQUEST,
  107. CnResource
  108. );
  109. CnFreePool(request);
  110. return;
  111. } // CnpDeleteReceiveRequest
  112. //
  113. // Routines Exported within the Cluster Transport
  114. //
  115. PCN_RESOURCE_POOL
  116. CnpCreateReceiveRequestPool(
  117. IN ULONG UpperProtocolContextSize,
  118. IN USHORT PoolDepth
  119. )
  120. {
  121. PCN_RESOURCE_POOL pool;
  122. PCNP_RECEIVE_REQUEST_POOL_CONTEXT context;
  123. PAGED_CODE();
  124. pool = CnAllocatePool(
  125. sizeof(CN_RESOURCE_POOL) +
  126. sizeof(CNP_RECEIVE_REQUEST_POOL_CONTEXT)
  127. );
  128. if (pool != NULL) {
  129. context = (PCNP_RECEIVE_REQUEST_POOL_CONTEXT) (pool + 1);
  130. context->UpperProtocolContextSize = UpperProtocolContextSize;
  131. CnInitializeResourcePool(
  132. pool,
  133. PoolDepth,
  134. CnpCreateReceiveRequest,
  135. context,
  136. CnpDeleteReceiveRequest
  137. );
  138. }
  139. return(pool);
  140. } // CnpCreateReceiveRequestPool
  141. PCNP_RECEIVE_REQUEST
  142. CnpAllocateReceiveRequest(
  143. IN PCN_RESOURCE_POOL RequestPool,
  144. IN PVOID Network,
  145. IN ULONG BytesToReceive,
  146. IN PVOID CompletionRoutine
  147. )
  148. {
  149. PCNP_NETWORK network = Network;
  150. PCNP_RECEIVE_REQUEST request = (PCNP_RECEIVE_REQUEST)
  151. CnAllocateResource(RequestPool);
  152. if (request != NULL) {
  153. //
  154. // Allocate a buffer to hold the data.
  155. //
  156. request->DataBuffer = CnAllocatePool(BytesToReceive);
  157. if (request->DataBuffer != NULL) {
  158. request->Irp = IoAllocateIrp(
  159. network->DatagramDeviceObject->StackSize,
  160. FALSE
  161. );
  162. if (request->Irp != NULL) {
  163. PMDL mdl = IoAllocateMdl(
  164. request->DataBuffer,
  165. BytesToReceive,
  166. FALSE,
  167. FALSE,
  168. NULL
  169. );
  170. if (mdl != NULL) {
  171. PIRP irp = request->Irp;
  172. MmBuildMdlForNonPagedPool(mdl);
  173. //
  174. // Build the irp.
  175. //
  176. irp->Flags = 0;
  177. irp->RequestorMode = KernelMode;
  178. irp->PendingReturned = FALSE;
  179. irp->UserIosb = NULL;
  180. irp->UserEvent = NULL;
  181. irp->Overlay.AsynchronousParameters.UserApcRoutine =
  182. NULL;
  183. irp->AssociatedIrp.SystemBuffer = NULL;
  184. irp->UserBuffer = NULL;
  185. irp->Tail.Overlay.Thread = 0;
  186. irp->Tail.Overlay.OriginalFileObject =
  187. network->DatagramFileObject;
  188. irp->Tail.Overlay.AuxiliaryBuffer = NULL;
  189. TdiBuildReceiveDatagram(
  190. irp,
  191. network->DatagramDeviceObject,
  192. network->DatagramFileObject,
  193. CompletionRoutine,
  194. request,
  195. mdl,
  196. BytesToReceive,
  197. NULL,
  198. NULL,
  199. 0
  200. );
  201. //
  202. // Make the next stack location current.
  203. // Normally IoCallDriver would do this, but
  204. // since we're bypassing that, we do it directly.
  205. //
  206. IoSetNextIrpStackLocation( irp );
  207. return(request);
  208. }
  209. IoFreeIrp(request->Irp);
  210. request->Irp = NULL;
  211. }
  212. CnFreePool(request->DataBuffer);
  213. request->DataBuffer = NULL;
  214. }
  215. CnFreeResource((PCN_RESOURCE) request);
  216. }
  217. return(NULL);
  218. } // CnpAllocateReceiveRequest
  219. VOID
  220. CnpFreeReceiveRequest(
  221. PCNP_RECEIVE_REQUEST Request
  222. )
  223. {
  224. IoFreeMdl(Request->Irp->MdlAddress);
  225. Request->Irp->MdlAddress = NULL;
  226. IoFreeIrp(Request->Irp);
  227. Request->Irp = NULL;
  228. CnFreePool(Request->DataBuffer);
  229. Request->DataBuffer = NULL;
  230. CnFreeResource((PCN_RESOURCE) Request);
  231. return;
  232. } // CnpFreeReceiveRequest
  233. NTSTATUS
  234. CnpIndicateData(
  235. IN PCNP_NETWORK Network,
  236. IN UCHAR NextHeader,
  237. IN CL_NODE_ID SourceNodeId,
  238. IN ULONG CnpReceiveFlags,
  239. IN ULONG TdiReceiveDatagramFlags,
  240. IN ULONG BytesIndicated,
  241. IN ULONG BytesAvailable,
  242. OUT PULONG BytesTaken,
  243. IN PVOID Tsdu,
  244. OUT PIRP * Irp
  245. )
  246. /*++
  247. Routine Description:
  248. Indicate data to the next highest protocol.
  249. --*/
  250. {
  251. NTSTATUS status;
  252. if (NextHeader == PROTOCOL_CDP) {
  253. CnTrace(CNP_RECV_DETAIL, CnpTraceIndicateDataPacket,
  254. "[CNP] Indicating data packet from node %u net %u, "
  255. "BI %u, BA %u, CNP Flags %x.",
  256. SourceNodeId, // LOGULONG
  257. Network->Id, // LOGULONG
  258. BytesIndicated, // LOGULONG
  259. BytesAvailable, // LOGULONG
  260. CnpReceiveFlags // LOGXLONG
  261. );
  262. status = CdpReceivePacketHandler(
  263. Network,
  264. SourceNodeId,
  265. CnpReceiveFlags,
  266. TdiReceiveDatagramFlags,
  267. BytesIndicated,
  268. BytesAvailable,
  269. BytesTaken,
  270. Tsdu,
  271. Irp
  272. );
  273. }
  274. else if (NextHeader == PROTOCOL_CCMP) {
  275. CnTrace(CNP_RECV_DETAIL, CnpTraceIndicateControlPacket,
  276. "[CNP] Indicating control packet from node %u net %u, "
  277. "BI %u, BA %u, CNP Flags %x.",
  278. SourceNodeId, // LOGULONG
  279. Network->Id, // LOGULONG
  280. BytesIndicated, // LOGULONG
  281. BytesAvailable, // LOGULONG
  282. CnpReceiveFlags // LOGXLONG
  283. );
  284. status = CcmpReceivePacketHandler(
  285. Network,
  286. SourceNodeId,
  287. CnpReceiveFlags,
  288. TdiReceiveDatagramFlags,
  289. BytesIndicated,
  290. BytesAvailable,
  291. BytesTaken,
  292. Tsdu,
  293. Irp
  294. );
  295. }
  296. else {
  297. IF_CNDBG(CN_DEBUG_CNPRECV) {
  298. CNPRINT((
  299. "[CNP] Received packet for unknown protocol %u\n",
  300. NextHeader
  301. ));
  302. }
  303. CnTrace(CNP_RECV_DETAIL, CnpTraceRecvUnknownProtocol,
  304. "[CNP] Received packet for unknown protocol (%u) "
  305. " from node %u net %u, BI %u, BA %u, CNP Flags %x.",
  306. NextHeader,
  307. SourceNodeId, // LOGULONG
  308. Network->Id, // LOGULONG
  309. BytesIndicated, // LOGULONG
  310. BytesAvailable, // LOGULONG
  311. CnpReceiveFlags // LOGXLONG
  312. );
  313. status = STATUS_SUCCESS;
  314. }
  315. CnVerifyCpuLockMask(
  316. 0, // Required
  317. 0xFFFFFFFF, // Forbidden
  318. 0 // Maximum
  319. );
  320. return(status);
  321. } // CnpIndicateData
  322. NTSTATUS
  323. CnpCompleteReceivePacket(
  324. IN PDEVICE_OBJECT DeviceObject,
  325. IN PIRP Irp,
  326. IN PVOID Context
  327. )
  328. {
  329. NTSTATUS status;
  330. PCNP_RECEIVE_REQUEST request = Context;
  331. PCNP_RECEIVE_CONTEXT context = request->UpperProtocolContext;
  332. CNP_HEADER UNALIGNED * cnpHeader = request->DataBuffer;
  333. ULONG consumed;
  334. ULONG dataLength;
  335. PIRP irp = NULL;
  336. ULONG bytesTaken = 0;
  337. BOOLEAN currentMcastGroup = FALSE;
  338. if (Irp->IoStatus.Status == STATUS_SUCCESS) {
  339. CnAssert(Irp->IoStatus.Information == context->TsduSize);
  340. CnAssert(context->CnpReceiveFlags & CNP_RECV_FLAG_MULTICAST);
  341. CnAssert(
  342. !(context->CnpReceiveFlags & CNP_RECV_FLAG_SIGNATURE_VERIFIED)
  343. );
  344. CnAssert(
  345. !(context->CnpReceiveFlags & CNP_RECV_FLAG_CURRENT_MULTICAST_GROUP)
  346. );
  347. dataLength = (ULONG)Irp->IoStatus.Information;
  348. //
  349. // This routine is only called for multicast packets,
  350. // so we need to verify the signature.
  351. //
  352. status = CnpVerifyMulticastMessage(
  353. context->Network,
  354. cnpHeader + 1,
  355. dataLength - sizeof(CNP_HEADER),
  356. cnpHeader->PayloadLength,
  357. &consumed,
  358. &currentMcastGroup
  359. );
  360. if (status != SEC_E_OK) {
  361. CnTrace(CNP_RECV_ERROR, CnpTraceRecvBadSig,
  362. "[CNP] Failed to verify multicast "
  363. "packet, status %x, src node %u, net %u, "
  364. "data length %u, CNP flags %x.",
  365. status,
  366. cnpHeader->SourceAddress, // LOGULONG
  367. context->Network->Id,
  368. dataLength,
  369. context->CnpReceiveFlags
  370. );
  371. goto error_exit;
  372. }
  373. context->CnpReceiveFlags |= CNP_RECV_FLAG_SIGNATURE_VERIFIED;
  374. if (currentMcastGroup) {
  375. context->CnpReceiveFlags |= CNP_RECV_FLAG_CURRENT_MULTICAST_GROUP;
  376. }
  377. consumed += sizeof(CNP_HEADER);
  378. //
  379. // Indicate the data to the next highest protocol.
  380. //
  381. status = CnpIndicateData(
  382. context->Network,
  383. cnpHeader->NextHeader,
  384. cnpHeader->SourceAddress,
  385. context->CnpReceiveFlags,
  386. context->TdiReceiveDatagramFlags,
  387. dataLength - consumed,
  388. dataLength - consumed,
  389. &bytesTaken,
  390. (PUCHAR)cnpHeader + consumed,
  391. &irp
  392. );
  393. CnAssert(status != STATUS_MORE_PROCESSING_REQUIRED);
  394. CnAssert(bytesTaken == dataLength - consumed);
  395. CnAssert(irp == NULL);
  396. if (irp != NULL) {
  397. CnTrace(CNP_RECV_ERROR, CnpTraceCompleteReceiveIrp,
  398. "[CNP] Upper layer protocol requires more"
  399. "processing. Failing request."
  400. );
  401. irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
  402. irp->IoStatus.Information = 0;
  403. IoCompleteRequest(irp, IO_NETWORK_INCREMENT);
  404. }
  405. }
  406. else {
  407. CnTrace(CNP_RECV_ERROR, CnpTraceCompleteReceiveFailed,
  408. "[CNP] Failed to fetch packet, src node %u, "
  409. "status %!status!",
  410. cnpHeader->SourceAddress, // LOGULONG
  411. Irp->IoStatus.Status // LOGSTATUS
  412. );
  413. }
  414. error_exit:
  415. //
  416. // Drop the active reference on the network.
  417. //
  418. if (context->Network != NULL) {
  419. CnAcquireLock(&(context->Network->Lock), &(context->Network->Irql));
  420. CnpActiveDereferenceNetwork(context->Network);
  421. context->Network = NULL;
  422. }
  423. CnpFreeReceiveRequest(request);
  424. CnVerifyCpuLockMask(
  425. 0, // Required
  426. 0xFFFFFFFF, // Forbidden
  427. 0 // Maximum
  428. );
  429. return(STATUS_MORE_PROCESSING_REQUIRED);
  430. } // CdpCompleteReceivePacket
  431. NTSTATUS
  432. CnpTdiReceiveDatagramHandler(
  433. IN PVOID TdiEventContext,
  434. IN LONG SourceAddressLength,
  435. IN PVOID SourceAddress,
  436. IN LONG OptionsLength,
  437. IN PVOID Options,
  438. IN ULONG ReceiveDatagramFlags,
  439. IN ULONG BytesIndicated,
  440. IN ULONG BytesAvailable,
  441. OUT PULONG BytesTaken,
  442. IN PVOID Tsdu,
  443. OUT PIRP * Irp
  444. )
  445. {
  446. NTSTATUS status;
  447. CNP_HEADER UNALIGNED * cnpHeader = Tsdu;
  448. PCNP_NETWORK network = TdiEventContext;
  449. PCNP_NODE srcNode;
  450. ULONG cnpRecvFlags = 0;
  451. BOOLEAN cnpSigDataIndicated = FALSE;
  452. ULONG consumed;
  453. PCNP_RECEIVE_REQUEST request;
  454. CnAssert(KeGetCurrentIrql() == DISPATCH_LEVEL);
  455. CnAssert(network->State > ClusnetNetworkStateOffline);
  456. CnAssert(CnLocalNodeId != ClusterInvalidNodeId);
  457. CnAssert(CnpLocalNode != NULL);
  458. //
  459. // Validate the CNP header.
  460. //
  461. // First make sure it exists.
  462. //
  463. if (BytesIndicated < sizeof(CNP_HEADER)) {
  464. goto error_exit;
  465. }
  466. if ((cnpHeader->SourceAddress < CnMinValidNodeId) ||
  467. (cnpHeader->SourceAddress > CnMaxValidNodeId)) {
  468. goto error_exit;
  469. }
  470. if (cnpHeader->Version == CNP_VERSION_UNICAST) {
  471. //
  472. // Unicast checks.
  473. //
  474. if ((cnpHeader->PayloadLength +
  475. sizeof(CNP_HEADER) != BytesAvailable) ||
  476. (cnpHeader->DestinationAddress != CnLocalNodeId)) {
  477. goto error_exit;
  478. }
  479. } else if (cnpHeader->Version == CNP_VERSION_MULTICAST) {
  480. //
  481. // Multicast checks.
  482. //
  483. // Defer payload length check until the signature
  484. // length is known.
  485. //
  486. if (cnpHeader->DestinationAddress != ClusterAnyNodeId) {
  487. goto error_exit;
  488. }
  489. cnpRecvFlags |= CNP_RECV_FLAG_MULTICAST;
  490. }
  491. //
  492. // Validate the source and destination nodes.
  493. //
  494. CnAcquireLockAtDpc(&CnpNodeTableLock);
  495. srcNode = CnpNodeTable[cnpHeader->SourceAddress];
  496. if (srcNode == NULL) {
  497. CnReleaseLockFromDpc(&CnpNodeTableLock);
  498. goto error_exit;
  499. }
  500. if ( (srcNode->CommState == ClusnetNodeCommStateOnline) &&
  501. (CnpLocalNode->CommState == ClusnetNodeCommStateOnline)
  502. )
  503. {
  504. cnpRecvFlags |= CNP_RECV_FLAG_NODE_STATE_CHECK_PASSED;
  505. }
  506. CnReleaseLockFromDpc(&CnpNodeTableLock);
  507. if ((cnpRecvFlags & CNP_RECV_FLAG_MULTICAST) != 0) {
  508. //
  509. // Multicast packets need to be verified. Verification
  510. // cannot proceed unless the entire packet is present.
  511. //
  512. if (BytesIndicated == BytesAvailable) {
  513. BOOLEAN currentMcastGroup = FALSE;
  514. //
  515. // The entire message is indicated. We can
  516. // verify it now.
  517. //
  518. status = CnpVerifyMulticastMessage(
  519. network,
  520. cnpHeader + 1,
  521. BytesIndicated - sizeof(CNP_HEADER),
  522. cnpHeader->PayloadLength,
  523. &consumed,
  524. &currentMcastGroup
  525. );
  526. if (status != SEC_E_OK) {
  527. CnTrace(CNP_RECV_DETAIL, CdpTraceRecvBadSig,
  528. "[CNP] Failed to verify multicast "
  529. "packet, status %x, "
  530. "src node %u, BI %u, BA %u",
  531. status,
  532. cnpHeader->SourceAddress, // LOGULONG
  533. BytesIndicated, // LOGULONG
  534. BytesAvailable // LOGULONG
  535. );
  536. goto error_exit;
  537. }
  538. cnpRecvFlags |= CNP_RECV_FLAG_SIGNATURE_VERIFIED;
  539. if (currentMcastGroup) {
  540. cnpRecvFlags |= CNP_RECV_FLAG_CURRENT_MULTICAST_GROUP;
  541. }
  542. consumed += sizeof(CNP_HEADER);
  543. } else {
  544. //
  545. // The entire message is not indicated. We need
  546. // to submit a request and wait for the rest of
  547. // the data.
  548. //
  549. request = CnpAllocateReceiveRequest(
  550. CnpReceiveRequestPool,
  551. network,
  552. BytesAvailable,
  553. CnpCompleteReceivePacket
  554. );
  555. if (request != NULL) {
  556. PCNP_RECEIVE_CONTEXT context;
  557. context = request->UpperProtocolContext;
  558. context->TdiReceiveDatagramFlags = ReceiveDatagramFlags;
  559. context->TsduSize = BytesAvailable;
  560. context->Network = network;
  561. context->CnpReceiveFlags = cnpRecvFlags;
  562. //
  563. // Take a reference on the network so that it
  564. // doesn't disappear before the IRP completes.
  565. //
  566. CnAcquireLock(&(network->Lock), &(network->Irql));
  567. CnpActiveReferenceNetwork(network);
  568. CnReleaseLock(&(network->Lock), network->Irql);
  569. *Irp = request->Irp;
  570. CnTrace(CNP_RECV_DETAIL, CnpTraceCompleteReceive,
  571. "[CNP] Fetching CNP multicast data, src "
  572. "node %u, BI %u, BA %u, CNP flags %x.",
  573. cnpHeader->SourceAddress, // LOGULONG
  574. BytesIndicated, // LOGULONG
  575. BytesAvailable, // LOGULONG
  576. context->CnpReceiveFlags // LOGXLONG
  577. );
  578. CnVerifyCpuLockMask(
  579. 0, // Required
  580. 0xFFFFFFFF, // Forbidden
  581. 0 // Maximum
  582. );
  583. return(STATUS_MORE_PROCESSING_REQUIRED);
  584. }
  585. CnTrace(CNP_RECV_ERROR, CnpTraceDropReceiveNoIrp,
  586. "[CNP] Dropping packet: failed to allocate "
  587. "receive request."
  588. );
  589. //
  590. // Out of resources. Drop the packet.
  591. //
  592. goto error_exit;
  593. }
  594. } else {
  595. //
  596. // Unicast packets do not need to verified.
  597. //
  598. consumed = sizeof(CNP_HEADER);
  599. }
  600. //
  601. // Deliver the packet to the appropriate upper layer protocol.
  602. //
  603. *BytesTaken = consumed;
  604. BytesIndicated -= consumed;
  605. BytesAvailable -= consumed;
  606. return (CnpIndicateData(
  607. network,
  608. cnpHeader->NextHeader,
  609. cnpHeader->SourceAddress,
  610. cnpRecvFlags,
  611. ReceiveDatagramFlags,
  612. BytesIndicated,
  613. BytesAvailable,
  614. BytesTaken,
  615. (PUCHAR)Tsdu + consumed,
  616. Irp
  617. )
  618. );
  619. error_exit:
  620. //
  621. // Something went wrong. Drop the packet by
  622. // indicating that we consumed it.
  623. //
  624. *BytesTaken = BytesAvailable;
  625. *Irp = NULL;
  626. CnTrace(CNP_RECV_ERROR, CnpTraceDropReceive,
  627. "[CNP] Dropped packet from net %u, BI %u, BA %u, CNP flags %x.",
  628. network->Id, // LOGULONG
  629. BytesIndicated, // LOGULONG
  630. BytesAvailable, // LOGULONG
  631. cnpRecvFlags // LOGXLONG
  632. );
  633. IF_CNDBG(CN_DEBUG_CNPRECV) {
  634. CNPRINT(("[CNP] Dropped packet from net %u, BI %u, BA %u.\n",
  635. network->Id, BytesIndicated, BytesAvailable));
  636. }
  637. CnVerifyCpuLockMask(
  638. 0, // Required
  639. 0xFFFFFFFF, // Forbidden
  640. 0 // Maximum
  641. );
  642. return(STATUS_SUCCESS);
  643. } // CnpTdiReceiveDatagramHandler