阅读:4554回复:35
自己构造的ndis包发送不出去
如下:我的构造包的数据都是正确的,但不知道为什么,老是发送不出去(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; } |
|
沙发#
发布于:2004-11-19 15:10
通过Modem 好象不行。如果是Modem要做那些改动?
|
|
板凳#
发布于:2004-11-18 16:37
你看看这个地方的把,这个是我的可以工作的函数:http://www.pc578.com/sharelist.asp
sendcomplete里面事实上就是做你创建这个包的善后工作,但要注意,你自己创建的包和系统创建的包不一样,所以要区别对待,释放时注意这个就可以了 |
|
地板#
发布于:2004-11-18 14:18
tO:kangzh
我用了你这个代码,一运行就蓝屏,你SendCompelete是怎么处理 的? |
|
地下室#
发布于:2004-10-18 14:05
谢谢回复
网卡适配器句柄用什么函数能够得到? |
|
5楼#
发布于:2004-10-18 11:49
NdisAllocatePacketPool
NdisAllocateBufferPool NUM_OF_PACKETS我设的256,你可以找ddk看一下 |
|
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也是这么得到的吗? |
|
7楼#
发布于:2004-10-16 12:50
网卡适配器句柄
|
|
8楼#
发布于:2004-10-15 17:38
NDIS_STATUS SendPacket(
IN NDIS_HANDLE ProtocolBindingContext, IN PVOID pBuffer, IN ULONG uBufferSize) 中的参数ProtocolBindingContext怎么得到的? |
|
9楼#
发布于:2004-05-24 16:48
kangzh:现在又有一个问题了,怎么计算TCP的校验和。有空到“
请教一个关于TCPCHECKSUM(tcp校验和)的问题,各位大侠帮帮忙了 ”这里来座座,谢谢了 |
|
10楼#
发布于:2004-05-20 13:05
:)现在对了,谢谢了kangzh,在我修改包的IP时校验和是对的
|
|
11楼#
发布于:2004-05-20 10:16
但是我在checksum里面也把那个重新清0了,但不知道为什么就是不对。那我再试试在主程序里头清0 了。谢谢了,别忘了在kangzh,各位高手帮帮忙了,关于校验和的问题 这里去取分:)
|
|
12楼#
发布于:2004-05-20 10:05
ip和只计算ip头,在计算之前要将校验和位清零
|
|
13楼#
发布于:2004-05-20 09:56
我现在还没有计算UDP的校验和,只计算了IP 的校验和,sniffer就说我的IP校验和不对
|
|
14楼#
发布于:2004-05-20 09:43
1、把ushort换成int 是因为后面的和超过了ushort所表示的值,所以会溢出,
2、哦,你用这个函数是没错的,关键在于你在计算校验和时可能没有使用伪udp头,这个很关键,查看tcp/ip有关书籍,你会发现书中介绍udp校验和的方法是把伪udp头+udp头+udp数据中的每一个数据求反之后求和,而本程序的含义则是求和之后再求反,他们的结果经过实施验证时一样的。 |
|
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? } 谢谢了,我会另开新贴的 |
|
16楼#
发布于:2004-05-14 09:46
到网上下载个iris对数据包的分析很清楚,你就不必再直接看16进制代码来看数据报是否正确了。
|
|
17楼#
发布于:2004-05-11 09:37
asmsys大侠真是厉害啊,偶像,可否给我一个截获ip包的代码
|
|
18楼#
发布于:2004-05-11 09:03
呵呵,大家相互帮忙
|
|
19楼#
发布于:2004-05-10 20:45
谢了 kangzh,我正在调试。由于不大熟悉你的数据结构,费了好的劲才调好。然后装上后发现系统立刻就重新启动,:)可能是其他地方的问题了,比如资源释放什么的。我先调下,你的已经调试通过了。是吧,以后有什么问题还要向你请教,先谢了
|
|
上一页
下一页