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.

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