|
修改的 passthru 实现发送自定义包,结果发现无论如何对方都收不到(NDIS 5.1环境)。
- NTSTATUS SendRaw(IN PDEVICE_OBJECT driverObject, IN PIRP irp)
- {
- NDIS_STATUS status;
- PADAPT adapt = g_currAdapt; // 这个正常,可以肯定。
- PNDIS_PACKET ndisPacket = NULL;
- PNDIS_BUFFER ndisBuffer = NULL;
- PUCHAR sendBuffer = NULL;
- PSEND_RSVD sendRsvd = NULL;
- PUCHAR buffer;
- ULONG length;
- DBGPRINT(("==> SendRaw\n"));
- buffer = irp->AssociatedIrp.SystemBuffer;
- length = IoGetCurrentIrpStackLocation(irp)->Parameters.DeviceIoControl.InputBufferLength;
- ASSERT(buffer != NULL);
- ASSERT(length <= ETH_MAX_PACKET_SIZE);
- if (adapt == NULL)
- {
- irp->IoStatus.Information = 0;
- irp->IoStatus.Status = NDIS_STATUS_FAILURE;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- return NDIS_STATUS_FAILURE;
- }
- do
- {
- NdisAcquireSpinLock(&adapt->Lock);
- if(adapt->MPDeviceState > NdisDeviceStateD0) // 如果微端口处于低能状态,不能发送此包
- {
- NdisReleaseSpinLock(&adapt->Lock);
- status = NDIS_STATUS_FAILURE;
- DBGPRINT(("Below miniport is going to low power.\n"));
- break;
- }
- adapt->OutstandingSends++;
- NdisReleaseSpinLock(&adapt->Lock);
- status = NdisAllocateMemoryWithTag(&sendBuffer, length, TAG);
- if (status != NDIS_STATUS_SUCCESS)
- break;
- RtlMoveMemory(sendBuffer, buffer, length);
- NdisDprAllocatePacket(&status, &ndisPacket, adapt->SendPacketPoolHandle);
- if (status != NDIS_STATUS_SUCCESS)
- {
- NdisFreeMemory(sendBuffer, length, 0);
- break;
- }
- NdisAllocateBuffer(&status, &ndisBuffer, adapt->SendPacketPoolHandle, sendBuffer, length);
- if (status != NDIS_STATUS_SUCCESS)
- {
- NdisFreeMemory(sendBuffer, length, 0);
- NdisDprFreePacket(ndisPacket);
- break;
- }
- NdisChainBufferAtFront(ndisPacket, ndisBuffer);
- NdisSetPacketFlags(ndisPacket, NDIS_FLAGS_DONT_LOOPBACK); // 广播包不回现
- sendRsvd = (PSEND_RSVD)(ndisPacket->ProtocolReserved);
- sendRsvd->OriginalPkt = (PNDIS_PACKET)1; // 标记自定义包
- sendRsvd->Irp = irp; // 保持irp
- DBGPRINT(("%d\n", NDIS_GET_PACKET_STATUS(ndisPacket))); // 0
- DBGPRINT(("SendRaw -> Now send!\n"));
- IoMarkIrpPending(irp); // 标记pending
- NdisSend(&status, adapt->BindingHandle, ndisPacket); // 发送,这里总是返回 NDIS_STATUS_PENDING
- DBGPRINT(("%d\n", NDIS_GET_PACKET_STATUS(ndisPacket)));
- DBGPRINT(("SendRaw -> Send Status = %d\n", status));
- if (status == NDIS_STATUS_PENDING) // 所以这里就返回了
- return STATUS_PENDING;
- // 下面的代码没有执行到
- // Ndis同步调用,释放资源:
- DBGPRINT(("SendRaw -> Free!\n"));
- NdisUnchainBufferAtFront(ndisPacket, &ndisBuffer);
- NdisQueryBufferSafe(ndisBuffer, &sendBuffer, &length, NormalPagePriority);
- NdisFreeBuffer(ndisBuffer);
- NdisFreeMemory(sendBuffer, length, 0);
- NdisDprFreePacket(ndisPacket);
- } while(FALSE);
- // 结束 IO 请求
- ADAPT_DECR_PENDING_SENDS(adapt);
- irp->IoStatus.Information = 0;
- irp->IoStatus.Status = status;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- DBGPRINT(("<== SendRaw\n"));
- return status;
- }
- VOID
- PtSendComplete(
- IN NDIS_HANDLE ProtocolBindingContext,
- IN PNDIS_PACKET Packet,
- IN NDIS_STATUS Status
- )
- {
- PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
- PNDIS_PACKET Pkt;
- NDIS_HANDLE PoolHandle;
- // -------------------------------------------------------------------------
- PNDIS_BUFFER ndisBuffer = NULL;
- PUCHAR sendBuffer = NULL;
- ULONG length;
- PIRP irp = ((PSEND_RSVD)(Packet->ProtocolReserved))->Irp;
- Pkt = ((PSEND_RSVD)(Packet->ProtocolReserved))->OriginalPkt;
- if ((int)Pkt == 1 && irp != NULL) // 自己的包?
- {
- DBGPRINT(("PtSendComplete -> Send Status = %d\n", Status)); // 总是0,也就是成功
- DBGPRINT(("PtSendComplete -> Now free!\n"));
- DBGPRINT(("%d\n", NDIS_GET_PACKET_STATUS(Packet))); // 总是 0
- // 释放资源
- NdisUnchainBufferAtFront(Packet, &ndisBuffer);
- NdisQueryBufferSafe(ndisBuffer, &sendBuffer, &length, NormalPagePriority);
- NdisFreeBuffer(ndisBuffer);
- NdisFreeMemory(sendBuffer, length, 0);
- NdisDprFreePacket(Packet);
- // 结束 IO 请求
- ADAPT_DECR_PENDING_SENDS(pAdapt);
- irp->IoStatus.Information = 0;
- irp->IoStatus.Status = Status;
- IoCompleteRequest(irp, IO_NO_INCREMENT); // 完毕
- DBGPRINT(("PtSendComplete -> Free successed!\n"));
- return;
- }
- // -------------------------------------------------------------------------
- #ifdef NDIS51
- PoolHandle = NdisGetPoolFromPacket(Packet);
- if (PoolHandle != pAdapt->SendPacketPoolHandle)
- {
- NdisMSendComplete(pAdapt->MiniportHandle,
- Packet,
- Status);
- }
- else
- #endif // NDIS51
- {
- PSEND_RSVD SendRsvd;
- SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved);
- Pkt = SendRsvd->OriginalPkt;
-
- #ifndef WIN9X
- NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
- #endif
-
- NdisDprFreePacket(Packet);
- NdisMSendComplete(pAdapt->MiniportHandle,
- Pkt,
- Status);
- }
- //
- // Decrease the outstanding send count
- //
- ADAPT_DECR_PENDING_SENDS(pAdapt);
- }
复制代码
debugview显示结果:
Quicksand: \Device\{0E0D5AF6-DCEE-4078-B46B-6B7C5856E745} selected (正常的adapter)
Quicksand: ==> SendRaw
Quicksand: 0
Quicksand: SendRaw -> Now send!
Quicksand: PtSendComplete -> Send Status = 0
Quicksand: PtSendComplete -> Now free!
Quicksand: 0
Quicksand: PtSendComplete -> Free successed!
Quicksand: 0
Quicksand: SendRaw -> Send Status = 259 // NDIS_STATUS_PENDING == 259
可是对方死活接收不到!包肯定没有问题,试过了各种包(MAC地址确定没错):
- static unsigned char pckARP[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 目标地址:广播
- 0x00,0x0C,0x29,0x44,0x67,0xB5, // 源地址
- 0x08,0x06, // 协议类型:ARP
- 0x00,0x01, // 硬件类型:以太网
- 0x08,0x00, // 发送方提供的高层协议类型:IP协议
- 0x06, // 硬件地址长度:6
- 0x04, // 协议地址长度:4
- 0x00,0x01, // 操作字段:ARP请求(ARP请求为1,响应为2;RARP请求为3,响应为4)
- 0x00,0x0C,0x29,0x44,0x67,0xB5, // 源物理地址
- 0xC0,0xA8,0xDA,0x81, // 源协议地址:192.168.218.129
- 0x00,0x00,0x00,0x00,0x00,0x00, // 目标物理地址:全0
- 0x0A,0xEA,0x28,0x6E, // 目标协议地址:10.234.40.110
- // -- 填充字节 -----------------------------
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
复制代码
还有一个现象,如果注释掉NdisSetPacketFlags(ndisPacket, NDIS_FLAGS_DONT_LOOPBACK); // 广播包不回现
那么当目标mac是广播地址的时候(ff ff ff ff ff ff)本地可以回显到(在NdisSend的输出后面出现),
sniffer也可以抓到,而组播地址就不可以。
开启这个选项以后什么都看不到。。sniffer也什么都抓不到。。。。
|
|