kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:4554回复:35

自己构造的ndis包发送不出去

楼主#
更多 发布于:2004-04-21 11:32
如下:我的构造包的数据都是正确的,但不知道为什么,老是发送不出去(sniffer在别的机器上监控),ndissend返回状态为pending,我怀疑构造包有些问题,谢谢大家帮我指点!


NDIS_STATUS SendPacket(
 IN NDIS_HANDLE ProtocolBindingContext,
 IN PVOID pBuffer,
 IN ULONG uBufferSize)
{
 PADAPT pAdapt = (PADAPT)ProtocolBindingContext;

 PNDIS_PACKET MyPacket;
 NDIS_STATUS  Status;

 PNDIS_BUFFER pNdis_Ether;
 PEtherHeader pEtherheader;  //以太网头
 PIPHeader  pIpHeader;
 PUDPHeader  pUdpHeader;
 PUCHAR   pData;
 PUCHAR   pMemory;
 PRSVD   Rsvd;

 UINT i = 0;
 UINT uOffset;
 USHORT iLen;

 int j;

 UINT uTotalLen=sizeof(EtherHeader)+sizeof(IPHeader)+sizeof(UDPHeader)+uBufferSize;
 if(uTotalLen>MAX_ETHER_SIZE)
  return NDIS_STATUS_FAILURE;

 //分配一个包
 NdisAllocatePacket(&Status,&MyPacket,pAdapt->SendPacketPoolHandle);
 if(Status != NDIS_STATUS_SUCCESS)
 {
  DbgPrint(\"nNdisAllocatePacket() failed\\n\");
  return Status;
 }
 Rsvd = (PRSVD)(MyPacket->ProtocolReserved);
 Rsvd->OriginalPkt = NULL;
 
 //分配以太网包头NDIS_MEMORY_NONCACHED
 Status = NdisAllocateMemory(&pMemory,BUFFER_SIZE,0,HighestAcceptableMax);
 if(Status != NDIS_STATUS_SUCCESS)
 {
  NdisDprFreePacket(MyPacket);
  return Status;
 }
 uOffset=0;
 pEtherheader=(PEtherHeader)&pMemory[uOffset];

 for(i = 0;i<6;i++)
  pEtherheader->ether_dst = gDestMac;
 for(i = 0;i<6;i++)
  pEtherheader->ether_src= gSrcMac ;

 pEtherheader->type = htons(IP);    //IP数据报

 uOffset=sizeof(EtherHeader);
 pIpHeader=(PIPHeader)&(((PUCHAR)pEtherheader)[uOffset]);

 pIpHeader->version=5;   //版本:主机顺序,如果是网络顺序则是首部长度
 pIpHeader->header_len=IPVERSION;//sizeof(IPHeader); //首部长度:主机顺序,如果是网络顺序则是版本号
 pIpHeader->type=0;      //服务类型
 iLen=sizeof(IPHeader)+sizeof(UDPHeader)+uBufferSize;
 pIpHeader->length=htons(iLen);//总长度
 pIpHeader->id=0;      //标识符
 pIpHeader->flag_offset=0;    //标志(3)偏移(13)
 pIpHeader->time=0;      //生成时间
 pIpHeader->protocol=PROT_UDP;   //协议类型
 pIpHeader->crc_val=Checksum((USHORT *)pIpHeader,sizeof(IPHeader));     //校验和
 pIpHeader->src_addr=gSrcIp;    //源地址
 pIpHeader->des_addr=gDestIp;   //目的地址
 
 uOffset=sizeof(EtherHeader)+sizeof(IPHeader);
 pUdpHeader=(PUDPHeader)&(((PUCHAR)pEtherheader)[uOffset]);
 
 pUdpHeader->uh_dport=htons(SERVER_PORT);
 pUdpHeader->uh_sport=htons(HOST_PORT);
 pUdpHeader->uh_sum=Checksum((USHORT *)pUdpHeader,sizeof(UDPHeader));
 iLen=sizeof(UDPHeader)+uBufferSize;
 pUdpHeader->uh_ulen=htons(iLen);
 
 uOffset=sizeof(EtherHeader)+sizeof(IPHeader)+sizeof(UDPHeader);
 pData=&(((PUCHAR)pEtherheader)[uOffset]);
 NdisMoveMemory(pData,pBuffer,uBufferSize);
 iLen=1;

 for(i=0;iLen!=0;i++)
 {
  for(j=0;j<16;j++)
  {
   iLen=i*16+j;
   if(iLen<uTotalLen)
    DbgPrint(\"%2x  \",pMemory[iLen]);
   else
   {
    iLen=0;
    break;
   }
  }
  DbgPrint(\"\\n\");
 }

 NdisAllocateBuffer(
  &Status,
  &pNdis_Ether,
  pAdapt->SendPacketPoolHandle,
  pEtherheader,
  BUFFER_SIZE);
 if(Status != NDIS_STATUS_SUCCESS)
 {
  NdisFreePacket(MyPacket);
  NdisFreeMemory(pMemory,BUFFER_SIZE,0);
  return Status;
 }
 pNdis_Ether->Next = NULL;
 //将以太网头送入包中
 NdisChainBufferAtBack(MyPacket,pNdis_Ether);

 //NdisSetPacketFlags(MyPacket,pAdapt->Medium);

 NdisSend(&Status, pAdapt->BindingHandle, MyPacket);
 DbgPrint(\"Status=%d,pAdapt->BindingHandle=%x\\n\",Status,pAdapt->BindingHandle);
 if (Status != NDIS_STATUS_PENDING)
 {
  NdisFreePacket(MyPacket);
  NdisFreeMemory(pMemory,BUFFER_SIZE,0);
  NdisFreeBuffer(pNdis_Ether);
 }
 return Status;
}


最新喜欢:

kgdiwsskgdiws... temptemptempte...
stevehe
驱动牛犊
驱动牛犊
  • 注册日期2002-12-15
  • 最后登录2011-02-16
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望24点
  • 贡献值0点
  • 好评度18点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-11-19 15:10
通过Modem 好象不行。如果是Modem要做那些改动?
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-11-18 16:37
你看看这个地方的把,这个是我的可以工作的函数:http://www.pc578.com/sharelist.asp

sendcomplete里面事实上就是做你创建这个包的善后工作,但要注意,你自己创建的包和系统创建的包不一样,所以要区别对待,释放时注意这个就可以了
stevehe
驱动牛犊
驱动牛犊
  • 注册日期2002-12-15
  • 最后登录2011-02-16
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望24点
  • 贡献值0点
  • 好评度18点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-11-18 14:18
tO:kangzh
我用了你这个代码,一运行就蓝屏,你SendCompelete是怎么处理
的?
stevehe
驱动牛犊
驱动牛犊
  • 注册日期2002-12-15
  • 最后登录2011-02-16
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望24点
  • 贡献值0点
  • 好评度18点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-10-18 14:05
谢谢回复

网卡适配器句柄用什么函数能够得到?
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-10-18 11:49
NdisAllocatePacketPool
NdisAllocateBufferPool
NUM_OF_PACKETS我设的256,你可以找ddk看一下
stevehe
驱动牛犊
驱动牛犊
  • 注册日期2002-12-15
  • 最后登录2011-02-16
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望24点
  • 贡献值0点
  • 好评度18点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-10-18 10:50
***********************************************************

请问其中的gBufferPool 变量是怎样得到的?

NdisAllocateBufferPool(&Status,&gBufferPool,NUM_OF_BUFFERS);
if(Status != NDIS_STATUS_SUCCESS)
return Status;


if(gBufferPool)
NdisFreeBufferPool(gBufferPool);
********************************************************
一般取 NUM_OF_BUFFERS 为多大合适?和什么有关系?
另外,变量gPacketPool也是这么得到的吗?

kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-10-16 12:50
网卡适配器句柄
stevehe
驱动牛犊
驱动牛犊
  • 注册日期2002-12-15
  • 最后登录2011-02-16
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望24点
  • 贡献值0点
  • 好评度18点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-10-15 17:38
NDIS_STATUS SendPacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PVOID pBuffer,
IN ULONG uBufferSize)

中的参数ProtocolBindingContext怎么得到的?
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-05-24 16:48
kangzh:现在又有一个问题了,怎么计算TCP的校验和。有空到“
请教一个关于TCPCHECKSUM(tcp校验和)的问题,各位大侠帮帮忙了 ”这里来座座,谢谢了
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-05-20 13:05
:)现在对了,谢谢了kangzh,在我修改包的IP时校验和是对的
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-05-20 10:16
但是我在checksum里面也把那个重新清0了,但不知道为什么就是不对。那我再试试在主程序里头清0 了。谢谢了,别忘了在kangzh,各位高手帮帮忙了,关于校验和的问题 这里去取分:)
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-05-20 10:05
ip和只计算ip头,在计算之前要将校验和位清零
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-05-20 09:56
我现在还没有计算UDP的校验和,只计算了IP 的校验和,sniffer就说我的IP校验和不对
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-05-20 09:43
1、把ushort换成int 是因为后面的和超过了ushort所表示的值,所以会溢出,
2、哦,你用这个函数是没错的,关键在于你在计算校验和时可能没有使用伪udp头,这个很关键,查看tcp/ip有关书籍,你会发现书中介绍udp校验和的方法是把伪udp头+udp头+udp数据中的每一个数据求反之后求和,而本程序的含义则是求和之后再求反,他们的结果经过实施验证时一样的。
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-05-20 09:29
kangzh,我在调试创建一个UDP包,老是发现ip的校验和不对,我是用sniffer监控的,它在ip中显示,Headerchcksum =28cf,shoud be 0176;我想这就是校验和不对的征兆吧,看了一下你的程序,有些地方不是太懂,你说把USHORT sum=0;换为int sum=0;我试了一下,发现还是不行。再说校验码本来就是两个字节的,short就够了,为什么要用int呢?还有进行累加的时候,是不是先要把原来的IP段数据的校验码字段赋值为0,然后相加的时候这个字段也为0,而不是原来的数值。当然这个字段在创建的时候可能为0,如果你的pAddr结构为空的话。
USHORT Checksum(USHORT *pAddr, int len)
{
USHORT sum=0;
//这里是不是应该加个*(pAddr+5)=0;也就是将原来的校验码字段置0?
while(len>1)
{
sum+=*pAddr++;
len-=2;
}
if(len>0)
sum+=*(UCHAR *)pAddr;
//现面这两句不大懂,校验码字段的定义是:将IP数据收不看成为16bit的序列。现将检验和字段置零,将所有的16bit字相加后,将和的二进制反码写入检验和字段。为什么还要搞sum=(sum >> 16)+(sum & 0xffff);
sum+=(sum >> 16);
这两句,而不直接返回return (~sum)?
sum=(sum >> 16)+(sum & 0xffff);
sum+=(sum >> 16);
return (~sum) & 0xffff;//(~sum) & 0xffff不就是(~sum) 吗,如果sum是short,为什么还要搞个&0xffff?
}

谢谢了,我会另开新贴的
chili
驱动牛犊
驱动牛犊
  • 注册日期2004-03-31
  • 最后登录2011-03-29
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-05-14 09:46
到网上下载个iris对数据包的分析很清楚,你就不必再直接看16进制代码来看数据报是否正确了。
cmymfc
驱动牛犊
驱动牛犊
  • 注册日期2003-11-30
  • 最后登录2012-06-20
  • 粉丝0
  • 关注0
  • 积分62分
  • 威望8点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-05-11 09:37
asmsys大侠真是厉害啊,偶像,可否给我一个截获ip包的代码
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-05-11 09:03
呵呵,大家相互帮忙
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2004-05-10 20:45
谢了 kangzh,我正在调试。由于不大熟悉你的数据结构,费了好的劲才调好。然后装上后发现系统立刻就重新启动,:)可能是其他地方的问题了,比如资源释放什么的。我先调下,你的已经调试通过了。是吧,以后有什么问题还要向你请教,先谢了
上一页
游客

返回顶部