3545|2

79

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

passthru发送自定义包无效 [复制链接]

修改的 passthru 实现发送自定义包,结果发现无论如何对方都收不到(NDIS 5.1环境)。


  1. NTSTATUS SendRaw(IN PDEVICE_OBJECT driverObject, IN PIRP irp)
  2. {
  3.     NDIS_STATUS     status;
  4.     PADAPT          adapt = g_currAdapt; // 这个正常,可以肯定。
  5.     PNDIS_PACKET    ndisPacket = NULL;
  6.     PNDIS_BUFFER    ndisBuffer = NULL;
  7.     PUCHAR          sendBuffer = NULL;

  8.     PSEND_RSVD      sendRsvd = NULL;
  9.     PUCHAR          buffer;
  10.     ULONG           length;

  11.     DBGPRINT(("==> SendRaw\n"));
  12.     buffer = irp->AssociatedIrp.SystemBuffer;
  13.     length = IoGetCurrentIrpStackLocation(irp)->Parameters.DeviceIoControl.InputBufferLength;

  14.     ASSERT(buffer != NULL);
  15.     ASSERT(length <= ETH_MAX_PACKET_SIZE);

  16.     if (adapt == NULL)
  17.     {
  18.         irp->IoStatus.Information = 0;
  19.         irp->IoStatus.Status = NDIS_STATUS_FAILURE;
  20.         IoCompleteRequest(irp, IO_NO_INCREMENT);
  21.         return NDIS_STATUS_FAILURE;
  22.     }

  23.     do
  24.     {
  25.         NdisAcquireSpinLock(&adapt->Lock);
  26.         if(adapt->MPDeviceState > NdisDeviceStateD0) // 如果微端口处于低能状态,不能发送此包
  27.         {
  28.             NdisReleaseSpinLock(&adapt->Lock);
  29.             status = NDIS_STATUS_FAILURE;
  30.             DBGPRINT(("Below miniport is going to low power.\n"));
  31.             break;
  32.         }
  33.         adapt->OutstandingSends++;
  34.         NdisReleaseSpinLock(&adapt->Lock);

  35.         status = NdisAllocateMemoryWithTag(&sendBuffer, length, TAG);
  36.         if (status != NDIS_STATUS_SUCCESS)
  37.             break;
  38.         RtlMoveMemory(sendBuffer, buffer, length);

  39.         NdisDprAllocatePacket(&status, &ndisPacket, adapt->SendPacketPoolHandle);
  40.         if (status != NDIS_STATUS_SUCCESS)
  41.         {
  42.             NdisFreeMemory(sendBuffer, length, 0);
  43.             break;
  44.         }

  45.         NdisAllocateBuffer(&status, &ndisBuffer, adapt->SendPacketPoolHandle, sendBuffer, length);
  46.         if (status != NDIS_STATUS_SUCCESS)
  47.         {
  48.             NdisFreeMemory(sendBuffer, length, 0);
  49.             NdisDprFreePacket(ndisPacket);
  50.             break;
  51.         }

  52.         NdisChainBufferAtFront(ndisPacket, ndisBuffer);
  53.         NdisSetPacketFlags(ndisPacket, NDIS_FLAGS_DONT_LOOPBACK); // 广播包不回现

  54.         sendRsvd = (PSEND_RSVD)(ndisPacket->ProtocolReserved);
  55.         sendRsvd->OriginalPkt = (PNDIS_PACKET)1; // 标记自定义包
  56.         sendRsvd->Irp = irp; // 保持irp

  57.         DBGPRINT(("%d\n", NDIS_GET_PACKET_STATUS(ndisPacket))); // 0
  58.         DBGPRINT(("SendRaw -> Now send!\n"));
  59.         IoMarkIrpPending(irp);            // 标记pending
  60.         NdisSend(&status, adapt->BindingHandle, ndisPacket);   // 发送,这里总是返回 NDIS_STATUS_PENDING
  61.         DBGPRINT(("%d\n", NDIS_GET_PACKET_STATUS(ndisPacket)));
  62.         DBGPRINT(("SendRaw -> Send Status = %d\n", status));

  63.         if (status == NDIS_STATUS_PENDING)  // 所以这里就返回了
  64.             return STATUS_PENDING;

  65.          // 下面的代码没有执行到
  66.         // Ndis同步调用,释放资源:
  67.         DBGPRINT(("SendRaw -> Free!\n"));
  68.         NdisUnchainBufferAtFront(ndisPacket, &ndisBuffer);
  69.         NdisQueryBufferSafe(ndisBuffer, &sendBuffer, &length, NormalPagePriority);
  70.         NdisFreeBuffer(ndisBuffer);
  71.         NdisFreeMemory(sendBuffer, length, 0);
  72.         NdisDprFreePacket(ndisPacket);
  73.     } while(FALSE);

  74.     // 结束 IO 请求
  75.     ADAPT_DECR_PENDING_SENDS(adapt);
  76.     irp->IoStatus.Information = 0;
  77.     irp->IoStatus.Status = status;
  78.     IoCompleteRequest(irp, IO_NO_INCREMENT);
  79.     DBGPRINT(("<== SendRaw\n"));
  80.     return status;
  81. }

  82. VOID
  83. PtSendComplete(
  84.     IN  NDIS_HANDLE            ProtocolBindingContext,
  85.     IN  PNDIS_PACKET           Packet,
  86.     IN  NDIS_STATUS            Status
  87.     )
  88. {
  89.     PADAPT            pAdapt = (PADAPT)ProtocolBindingContext;
  90.     PNDIS_PACKET      Pkt;
  91.     NDIS_HANDLE       PoolHandle;

  92.     // -------------------------------------------------------------------------
  93.     PNDIS_BUFFER    ndisBuffer = NULL;
  94.     PUCHAR          sendBuffer = NULL;
  95.     ULONG           length;
  96.     PIRP irp = ((PSEND_RSVD)(Packet->ProtocolReserved))->Irp;

  97.     Pkt = ((PSEND_RSVD)(Packet->ProtocolReserved))->OriginalPkt;
  98.     if ((int)Pkt == 1 && irp != NULL) // 自己的包?
  99.     {
  100.         DBGPRINT(("PtSendComplete -> Send Status = %d\n", Status)); // 总是0,也就是成功
  101.         DBGPRINT(("PtSendComplete -> Now free!\n"));

  102.         DBGPRINT(("%d\n", NDIS_GET_PACKET_STATUS(Packet))); // 总是 0
  103.         // 释放资源
  104.         NdisUnchainBufferAtFront(Packet, &ndisBuffer);
  105.         NdisQueryBufferSafe(ndisBuffer, &sendBuffer, &length, NormalPagePriority);
  106.         NdisFreeBuffer(ndisBuffer);
  107.         NdisFreeMemory(sendBuffer, length, 0);
  108.         NdisDprFreePacket(Packet);

  109.         // 结束 IO 请求
  110.         ADAPT_DECR_PENDING_SENDS(pAdapt);
  111.         irp->IoStatus.Information = 0;
  112.         irp->IoStatus.Status = Status;
  113.         IoCompleteRequest(irp, IO_NO_INCREMENT); // 完毕
  114.         DBGPRINT(("PtSendComplete -> Free successed!\n"));
  115.         return;
  116.     }
  117.     // -------------------------------------------------------------------------

  118. #ifdef NDIS51
  119.     PoolHandle = NdisGetPoolFromPacket(Packet);
  120.     if (PoolHandle != pAdapt->SendPacketPoolHandle)
  121.     {
  122.         NdisMSendComplete(pAdapt->MiniportHandle,
  123.                           Packet,
  124.                           Status);
  125.     }
  126.     else
  127. #endif // NDIS51
  128.     {
  129.         PSEND_RSVD        SendRsvd;

  130.         SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved);
  131.         Pkt = SendRsvd->OriginalPkt;
  132.    
  133. #ifndef WIN9X
  134.         NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
  135. #endif
  136.    
  137.         NdisDprFreePacket(Packet);

  138.         NdisMSendComplete(pAdapt->MiniportHandle,
  139.                                  Pkt,
  140.                                  Status);
  141.     }
  142.     //
  143.     // Decrease the outstanding send count
  144.     //
  145.     ADAPT_DECR_PENDING_SENDS(pAdapt);
  146. }
复制代码


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地址确定没错):

  1. static unsigned char pckARP[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 目标地址:广播
  2.                                  0x00,0x0C,0x29,0x44,0x67,0xB5, // 源地址
  3.                                  0x08,0x06, // 协议类型:ARP
  4.                                  0x00,0x01, // 硬件类型:以太网
  5.                                  0x08,0x00, // 发送方提供的高层协议类型:IP协议
  6.                                  0x06, // 硬件地址长度:6
  7.                                  0x04, // 协议地址长度:4
  8.                                  0x00,0x01, // 操作字段:ARP请求(ARP请求为1,响应为2;RARP请求为3,响应为4)

  9.                                  0x00,0x0C,0x29,0x44,0x67,0xB5, // 源物理地址
  10.                                  0xC0,0xA8,0xDA,0x81, // 源协议地址:192.168.218.129
  11.                                  0x00,0x00,0x00,0x00,0x00,0x00, // 目标物理地址:全0
  12.                                  0x0A,0xEA,0x28,0x6E, // 目标协议地址:10.234.40.110

  13.                                  // -- 填充字节 -----------------------------
  14.                                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  15.                                  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也什么都抓不到。。。。

最新回复

友情up  详情 回复 发表于 2009-2-24 09:07
点赞 关注

回复
举报

73

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
友情up
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
友情up
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表