阅读:1760回复:5
请问:ndissend可否发udp广播包
我在定时器中用ndissend发送本子网段的udp广播包
没次发送都蓝屏??? 需要将网卡的模式变为广播模式?? |
|
沙发#
发布于:2004-10-09 19:53
注意发送广播包的时候,要将包的标志设成non loopback,否则ndis会将包派发到你的receive中,如果你在receive中再次进入发包过程,就会引起死循环,堆栈溢出了。
具体的资料,可以google一下loopback |
|
板凳#
发布于:2004-10-09 19:35
这是我在ptsendcomplete里的释放资源的一段:
SendRsvd = (PRECV_RSVD)(Packet->ProtocolReserved); Pkt = SendRsvd->OriginalPkt; if(Pkt) { //不为空,则说明是系统自己申请 #ifndef WIN9X NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); #endif NdisDprFreePacket(Packet); DbgPrint("@IN PtSendComplete: pkt not null-NdisMSendComplete release resource begin!!!\n"); NdisMSendComplete(pAdapt->MiniportHandle, Pkt, Status); DbgPrint("@IN PtSendComplete: pkt not null-NdisMSendComplete release resource end!!!\n"); } else { //说明是自己申请,需要释放所有资源,并不需要返回NdisMSendComplete DbgPrint("@IN PtSendComplete: pkt null-release resource begin!!!\n"); NdisUnchainBufferAtFront(Packet, &SendBuffer); NdisQueryBufferSafe(SendBuffer, (PVOID *)&pBackContent, &BufferLen, 32); NdisFreeBuffer(SendBuffer); NdisFreeMemory(pBackContent, BufferLen, 0); // @20041008 BUFFER_SIZE 改为 BufferLen NdisFreePacket(Packet); DbgPrint("@IN PtSendComplete: pkt null-release resource end!!!\n"); } 依旧是蓝屏。 但只要将广播形式的mac和ip地址改为对某一固定主机,既点对点的,测试通过。。。。。。郁闷ing 望各位大侠能施以援手,小弟不甚感谢,马上兑现给分!!!! |
|
地板#
发布于:2004-10-09 18:44
调用ndissend之后要记得在ptsendcomplete中释放资源
|
|
地下室#
发布于:2004-10-09 09:01
以下是我的代码,蓝屏出现在ndissend,望各位大侠在百忙中能帮菜鸟看看:
// // 自定义时间处理函数 // 仅输出执行标志 // // @自定义变量段 PADAPT pAdapt = (PADAPT)FunctionContext; // FunctionContext == pAdapt (system give the value) PNDIS_PACKET pMyPacket = NULL; // 发送包描述符 PNDIS_BUFFER pPacketBuffer = NULL; // 发送数据缓冲 PUCHAR pPacketMemory = NULL; // 存放包中的所有数据 PIPHEADER pIPHeader = NULL; // IP数据头 PMACHEADER pMacHeader = NULL; // MAC数据头 PUDPHEADER pUdpHeader = NULL; // UDP数据头 PNLPHEADER pNlpHeader = NULL; // NLP数据头 UINT PacketLen; // Packet length UINT PacketHeaderLen; // Packet_Header length UCHAR pPacketContent[38]; // Packet Content UCHAR pPacketDigest[20]; // Packet Digest PUCHAR pData = NULL; // @目的MAC地址(广播:ffffffffffff) unsigned char gDestMac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // @源MAC地址 (000d619ab61f) unsigned char gSrcMac[6] = {0x00, 0x0d, 0x61,0x9a, 0xb6, 0x1f}; // @源地址 (211.69.195.73) unsigned int gSrcIp = (unsigned int)211 << 24 | (unsigned int)69 << 16 | (unsigned int)195 << 8 | (unsigned int)73; // @目的地址(广播:211.69.195.127) unsigned int gDestIp = (unsigned int)211 << 24 | (unsigned int)69 << 16 | (unsigned int)195 << 8 | (unsigned int)127; unsigned short SERVER_PORT = 5678; // 源服务端口号 (暂时:5678) unsigned short HOST_PORT = 5678; // 目的服务端口号(暂时:5678) NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PRECV_RSVD Rsvd = NULL; PVOID MediaSpecificInfo = NULL; ULONG MediaSpecificSize = 0; UINT i, j, iLen; // 循环赋值变量 NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress; HighestAcceptableAddress.LowPart = -1; HighestAcceptableAddress.HighPart = -1; // @自定义变量段 // @自定义函数段 // @整个包的长度 PacketLen = sizeof(MACHEADER) + sizeof(IPHEADER) + sizeof(UDPHEADER) + NLP_CONTENT_SIZE + NLP_DIGEST_SIZE; if(!pAdapt->MiniportHandle) { Status = NDIS_STATUS_FAILURE; } else do { DbgPrint("@IN PacketProcessTimerCallback: Allocate Resource\n"); // @判断包的长度是否越界 if(PacketLen > MAX_ETHER_SIZE) // MAX_ETHER_SIZE in Packet.h { Status = NDIS_STATUS_FAILURE; break; } // @分配一个包描述符 NdisAllocatePacket(&Status, &pMyPacket, pAdapt->SendPacketPoolHandle); if(Status != NDIS_STATUS_SUCCESS) { DbgPrint("@IN PacketProcessTimerCallback: NdisAllocatePacket() failed\n"); break; } Rsvd = (PRECV_RSVD)(pMyPacket->ProtocolReserved); Rsvd->OriginalPkt = NULL; // @分配以太网包头NDIS_MEMORY_NONCACHED Status = NdisAllocateMemory(&pPacketMemory, PacketLen, 0, HighestAcceptableAddress); if(Status != NDIS_STATUS_SUCCESS) { NdisDprFreePacket((PNDIS_PACKET)pPacketMemory); break; } DbgPrint("@IN PacketProcessTimerCallback: Allocate Resource end\n"); DbgPrint("@IN PacketProcessTimerCallback: give the value\n"); // @填充MAC数据头 pMacHeader=(PMACHEADER)pPacketMemory; for(i = 0; i < 6; i++) { pMacHeader->chDestinateMAC = gDestMac; pMacHeader->chSourceMAC = gSrcMac ; } // @IP数据报类型(IP 帧) pMacHeader->nEtherType = htons(0x0800); // @填充IP数据头 pIPHeader=(PIPHEADER)&(((PUCHAR)pPacketMemory)[sizeof(MACHEADER)]); // @填充iVersion_iHeaderLength数据头 iVersion = 4 & iHeaderLength = 5 // @iHeaderLength为32位字的数目 pIPHeader->iVersion_iHeaderLength = ((unsigned short)4 << 4)|(unsigned short)(5); pIPHeader->chServerType = 0; // 服务类型 pIPHeader->iPacketLength = htons((USHORT)(PacketLen - sizeof(MACHEADER))); // 总长度,不包括MAC头 pIPHeader->iFragmentID = 0; // 标识符 pIPHeader->iFragFlags = 0; // 标志(3)偏移(13) pIPHeader->chTimeAlive = 128; // 生成时间 pIPHeader->szProtocol = 17; // 协议类型UDP = 17 pIPHeader->iSourceIP = htonl(gSrcIp); // 源地址 pIPHeader->iDestinateIP = htonl(gDestIp); // 目的地址 pIPHeader->iChecksum = 0; // 计算校验和先清零 pIPHeader->iChecksum = GetChecksum((USHORT *)pIPHeader, sizeof(IPHEADER)); // 校验和 // @填充UDP数据头 pUdpHeader = (PUDPHEADER)&(((PUCHAR)pPacketMemory)[sizeof(MACHEADER) + sizeof(IPHEADER)]); pUdpHeader->nDestinatePort = htons(SERVER_PORT); pUdpHeader->nSourcePort = htons(HOST_PORT); pUdpHeader->nUDPLength = htons((USHORT)(sizeof(UDPHEADER) + NLP_CONTENT_SIZE + NLP_DIGEST_SIZE)); pUdpHeader->nCheckSum = 0; // 用伪UDP头计算UDP校验和先清零 pUdpHeader->nCheckSum = GetChecksum((USHORT *)pUdpHeader, sizeof(UDPHEADER)); // 未完成 // @填充NLP数据头 pNlpHeader = (PNLPHEADER)&(((PUCHAR)pPacketMemory)[PacketLen - NLP_CONTENT_SIZE - NLP_DIGEST_SIZE]); pNlpHeader->cPacketType = 1; // 包类型 pNlpHeader->cReserved = 0; // 保留字段 pNlpHeader->iPacketLen = NLP_CONTENT_SIZE + NLP_DIGEST_SIZE; // 包长度 NdisAcquireSpinLock(&GlobalLock); pNlpHeader->iRefreshSeq = htonl(localNode.iNLPSeq++); // 更新序列号 NdisReleaseSpinLock(&GlobalLock); pNlpHeader->iReportID = localNode.iLocalID; // 发布者标识(未完成) pNlpHeader->iReportAddr = htonl(gSrcIp); // 发布者地址(未完成) // // @计算单跳MAC // @NLP包内容 + 单跳广播密钥作为计算的输入 // pData = &(((PUCHAR)pPacketMemory)[PacketLen - NLP_CONTENT_SIZE - NLP_DIGEST_SIZE]); NdisMoveMemory(pPacketContent, pData, NLP_CONTENT_SIZE); NdisMoveMemory(pPacketContent + NLP_CONTENT_SIZE, localNode.iSingleTopKey, 16); ShaDigestProcess(pPacketContent, pPacketDigest); // @将单跳MAC链接到NLP数据包后 pData = &(((PUCHAR)pPacketMemory)[PacketLen - NLP_DIGEST_SIZE]); NdisMoveMemory(pData, pPacketDigest, NLP_DIGEST_SIZE); iLen=1; for(i = 0; iLen != 0; i++) { for(j = 0; j < 16; j++) { iLen = i * 16 + j; if(iLen < PacketLen) { DbgPrint("%2x ", pPacketMemory[iLen]); } else { iLen = 0; break; } } DbgPrint("\n"); } DbgPrint("@IN PacketProcessTimerCallback: give the value end\n"); // @分配发送缓冲 NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->SendPacketPoolHandle, pPacketMemory, PacketLen); if(Status != NDIS_STATUS_SUCCESS) { NdisFreePacket(pMyPacket); NdisFreeMemory(pPacketMemory, PacketLen, 0); break; } // @将以太网头链接到包描述符 NdisChainBufferAtFront(pMyPacket, pPacketBuffer); pMyPacket->Private.Head->Next = NULL; pMyPacket->Private.Tail = NULL; NDIS_SET_PACKET_HEADER_SIZE(pMyPacket, 14); NdisSetPacketFlags(pMyPacket, NDIS_FLAGS_BROADCAST_PACKET); // @将构造好的包发送出去 // @@@@@@@@@@@@@@ DbgPrint("@IN PacketProcessTimerCallback: NdisSend begin!!\n"); NdisSend(&Status, pAdapt->BindingHandle, pMyPacket); if(Status == NDIS_STATUS_SUCCESS) DbgPrint("@IN PacketProcessTimerCallback: NDIS_STATUS_SUCCESS!!\n"); // @@@@@@@@@@@@@@ if (Status != NDIS_STATUS_PENDING) { NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pPacketMemory, PacketLen, 0); NdisFreePacket(pMyPacket); DbgPrint("@IN PacketProcessTimerCallback: NdisSend end!!\n"); } }while(FALSE); DbgPrint("@IN PacketProcessTimerCallback!!\n"); // @自定义函数段 |
|
5楼#
发布于:2004-10-08 21:19
当然可以了.连自定义结构的包都可以发的。
我想一定是你的NDIS Packet出的问题,你再参照论坛上相关的文章仔细对照一下你的代码。 good luck :) |
|