yqw_haoze
驱动牛犊
驱动牛犊
  • 注册日期2004-08-22
  • 最后登录2011-04-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1760回复:5

请问:ndissend可否发udp广播包

楼主#
更多 发布于:2004-10-08 19:06
我在定时器中用ndissend发送本子网段的udp广播包
没次发送都蓝屏???

需要将网卡的模式变为广播模式??
dshadow79
驱动牛犊
驱动牛犊
  • 注册日期2002-09-29
  • 最后登录2006-04-10
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-10-09 19:53
注意发送广播包的时候,要将包的标志设成non loopback,否则ndis会将包派发到你的receive中,如果你在receive中再次进入发包过程,就会引起死循环,堆栈溢出了。

具体的资料,可以google一下loopback
yqw_haoze
驱动牛犊
驱动牛犊
  • 注册日期2004-08-22
  • 最后登录2011-04-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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
望各位大侠能施以援手,小弟不甚感谢,马上兑现给分!!!!
darkme
驱动牛犊
驱动牛犊
  • 注册日期2004-07-17
  • 最后登录2006-03-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-10-09 18:44
调用ndissend之后要记得在ptsendcomplete中释放资源
yqw_haoze
驱动牛犊
驱动牛犊
  • 注册日期2004-08-22
  • 最后登录2011-04-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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");
// @自定义函数段
nolasterror
驱动牛犊
驱动牛犊
  • 注册日期2004-09-22
  • 最后登录2006-06-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-10-08 21:19
当然可以了.连自定义结构的包都可以发的。
我想一定是你的NDIS Packet出的问题,你再参照论坛上相关的文章仔细对照一下你的代码。
good luck :)
游客

返回顶部