sweetzhf
驱动牛犊
驱动牛犊
  • 注册日期2005-01-08
  • 最后登录2005-01-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1283回复:3

求助:如何通过Passthru来发一个自己建立的包!!!!

楼主#
更多 发布于:2005-01-10 18:54
如题,本人想用NDIS来发一个自己的包,我想应该是在MINIPORT里把,但在里边程序都是转发由上层来的包,发出去的,但我想在MINIPORT里插入一个自己新建立的包,而不影响系统的正常发包,如何实现啊,最好能提供代码,本人万分感谢!  加分不是问题!!
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-01-11 10:17
如题,本人想用NDIS来发一个自己的包,我想应该是在MINIPORT里把,但在里边程序都是转发由上层来的包,发出去的,但我想在MINIPORT里插入一个自己新建立的包,而不影响系统的正常发包,如何实现啊,最好能提供代码,本人万分感谢!  加分不是问题!!

结合Packet驱动看看,你就明白了
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
sweetzhf
驱动牛犊
驱动牛犊
  • 注册日期2005-01-08
  • 最后登录2005-01-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-01-11 15:17
我试着用PASSTHRU写了下去,结果有错误啊,请老大指点!!

以下是我的原码,请指点错误的地方:

//规则标志位(1表示过滤,0表示放行,你可以通过改这个数值来配置规则)
    UINT ICMP = 0; //ICMP数据报规则
    UINT IGMP = 0; //IGMP数据报规则
    UINT TCP = 1; //TCP数据报规则
    UINT UDP = 0; //UDP数据报规则
//---------------------------------------------
    int Packetlength;
    PUCHAR pPacketContent;
    PUCHAR pBuf;
    UINT BufLength;
    MDL * pNext;
    UINT i;

//nat defined
PNDIS_BUFFER   firstBuffer;
PSD_HEADER pseudoHeader;
PIP_HEADER pIPHeader;
PUDP_HEADER pUDPHeader;
PTCP_HEADER pTCPHeader;
UINT protocolLen=0,ptLength=0,j;
UCHAR tempChar=0;
USHORT checkSum=0,ptChkSum=0,tempCheckSum=0;
BOOLEAN checkSumFirst=TRUE,ptChkSumFirst=TRUE;
PRSVD Rsvd;
USHORT ipOffset=0,protocolOffset=0;
PUCHAR pProtocolContent;
PNDIS_PACKET MyPackets;




DBGPRINT("==> Passthru Protocol PtReceivePacket\n");

if(!pAdapt->MiniportHandle) return 0;

if(pAdapt->isSecondary)
{
 DBGPRINT("PASSTHRU GETTING RECEIVES ON SECONDARY\n");
 ASSERT(0);
}

//把数据包内容从Packet拷贝到pPacketContent
    NdisQueryPacket( Packet,NULL,NULL,NULL,&Packetlength);
    Status= NdisAllocateMemory( &pPacketContent, 2000, 0,HighestAcceptableMax);
    if (Status!=NDIS_STATUS_SUCCESS ) return Status;
    NdisZeroMemory (pPacketContent, 2000);
    NdisQueryBufferSafe(Packet->Private.Head, &pBuf, &BufLength, 32 );
    NdisMoveMemory(pPacketContent, pBuf, BufLength);
i = BufLength;
pNext = Packet->Private.Head;
for(;;)
{
    if(pNext == Packet->Private.Tail)
    break;
    pNext = pNext->Next; //指针后移
    if(pNext == NULL)
    break;
    NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);
    NdisMoveMemory(pPacketContent+i,pBuf,BufLength);
    i+=BufLength;
}
//数据拷贝完毕
//-------------------------------------------------



//规则判断
if (ICMP == 1)
{
if(((char *)pPacketContent)[12] == 8 &&
((char *)pPacketContent)[13] == 0 &&
((char *)pPacketContent)[23] == 1)
{
DbgPrint("!!!!!!!!!!!!!!ICMP IS Droped!!!!!!!!!!!!!! ");
NdisFreeMemory(pPacketContent, 2000, 0);
return NDIS_STATUS_NOT_ACCEPTED;
}
}
if (IGMP == 1)
{
if(((char *)pPacketContent)[12] == 8 &&
((char *)pPacketContent)[13] == 0 &&
((char *)pPacketContent)[23] == 2)
{
DbgPrint("!!!!!!!!!!!!!!IGMP IS Droped!!!!!!!!!!!!!!! ");
NdisFreeMemory(pPacketContent, 2000, 0);
return NDIS_STATUS_NOT_ACCEPTED;
}
}
if (TCP == 1)
{
if(((char *)pPacketContent)[12] == 8 &&
((char *)pPacketContent)[13] == 0 &&
((char *)pPacketContent)[23] == 6)
{
DbgPrint("!!!!!!!!!!!!!!TCP IS Droped!!!!!!!!!!!!!!! ");

//对数据包进一步进行判断输出IP地址
//源地址:
DbgPrint("<====Souce_IP: %u",((char *)pPacketContent)[26]);
DbgPrint(". %u",((char *)pPacketContent)[27]);
DbgPrint(". %u",((char *)pPacketContent)[28]);
DbgPrint(". %u \n",((char *)pPacketContent)[29]);

//目的地址:
DbgPrint("====>Destination_IP: %u",((char *)pPacketContent)[30]);
DbgPrint(". %u",((char *)pPacketContent)[31]);
DbgPrint(". %u",((char *)pPacketContent)[32]);
DbgPrint(". %u \n",((char *)pPacketContent)[33]);

//源端口(分别将两个数字转换成二进制,然后拼接在一起转换成十进制就是端口号):
DbgPrint("<====Souce_Port: %u",((char *)pPacketContent)[34]);
DbgPrint("| %u",((char *)pPacketContent)[35]);

//目的端口(分别将两个数字转换成二进制,然后拼接在一起转换成十进制就是端口号):
DbgPrint("====>Destination: %u",((char *)pPacketContent)[36]);
DbgPrint("| %u",((char *)pPacketContent)[37]);

//控制字符(转换成二进制后取右边的6位):
DbgPrint("Control Character: %u",((char *)pPacketContent)[47]);

/*
//拦截SYN包
if (((char *)pPacketContent)[47] == 2)
{
DbgPrint("SYN Packet is Droped: %u",((char *)pPacketContent)[47]);
NdisFreeMemory(pPacketContent, 2000, 0);
return NDIS_STATUS_NOT_ACCEPTED;
}
*/

//******************************************************************************************************
//发送TCP数据包*********************************************************************
if(pPacketContent[12] == 8 &&  pPacketContent[13] == 0 )//is ip packet22222222222
{

//以下为对收到的包进行计算#############################################
//calc ip offset
pIPHeader=(PIP_HEADER)(pPacketContent+14) ;
       ipOffset=((pIPHeader->h_verlen &0x0F)-5)*4;
       //if last address is 128 and is UDP packet//tcp packet
       if(pIPHeader->proto == 6)  //TCP is 6 UDP is 17  33333333333333333333
        {
DBGPRINT("!!!!!!!!!!!!!!!Packet is Tcp!!!!!!!!!!!!!!\n");

pTCPHeader=(PTCP_HEADER)(pPacketContent+14+sizeof(IP_HEADER)+ipOffset) ;
protocolOffset=((pTCPHeader->len_res&0xF0)-5)*4;

     
//检查收到的包的地址是否正确,如果正确才进行下一步处理4444444444444444444444444
if(((UCHAR)(pIPHeader->srcip>>24)&0xFF) == 128&&
((UCHAR)(pIPHeader->destip>>24)&0xFF) == 218)  
{

DBGPRINT("!!!!!!!!!!!!!!!Packet is OK!!!!!!!!!!!!!!!\n");


//把数据包内容从Packet拷贝到pPacketContent
//分配内存为pProtocolContent!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  Status= NdisAllocateMemory( &pProtocolContent, 2000, 0,HighestAcceptableMax);
if (Status!=NDIS_STATUS_SUCCESS )
{  
//NdisFreeMemory(pPacketContent,2000, 0);  
goto goahead;
}
   

NdisZeroMemory (pProtocolContent, 2000);

//互换原来源地址和目标地址的MAC地址    
tempCheckSum=pTCPHeader->checksum;
for(j=0;j<6;j++)

{
tempChar=pPacketContent[j];
pPacketContent[j]=pPacketContent[j+6];
pPacketContent[j+6]=tempChar;
}

// transpose ip address of src and dest
for(j=0;j<4;j++)

{
tempChar=pPacketContent[26+j];
pPacketContent[26+j]=pPacketContent[30+j];
pPacketContent[30+j]=tempChar;
}

pTCPHeader->checksum=0;//reset check sum          
             pseudoHeader.srcip=pIPHeader->srcip;//(ULONG)(*(pPacketContent+26));//calcInetAddress(&pPacketContent,26);
             pseudoHeader.destip=pIPHeader->destip;////calcInetAddress(&pPacketContent,30);
             pseudoHeader.mbz=0;
             pseudoHeader.proto=pIPHeader->proto;//17;
             pseudoHeader.length=_rotl(_rotr(pIPHeader->total_len,8)-sizeof(pIPHeader)-ipOffset,8);// pTCPHeader->len;//pPacketContent[38]*256+pPacketContent[39];//(USHORT)(*(pPacketContent+38));//pPacketContent[38]+pPacketContent[39]*256;
       
 
NdisMoveMemory(pProtocolContent,&pseudoHeader,sizeof(pseudoHeader));
protocolLen=_rotr(pseudoHeader.length,8);//pPacketContent[38+ipOffset]*256+pPacketContent[39+ipOffset];
NdisMoveMemory(pProtocolContent+sizeof(pseudoHeader),pTCPHeader,protocolLen);
     
       
ptChkSum=checksum((USHORT*)pProtocolContent,protocolLen+sizeof(pseudoHeader));

if(tempCheckSum!=ptChkSum)

ptChkSum=tempCheckSum;      
     
//test check sum on good      
pTCPHeader->checksum=ptChkSum;        
pIPHeader->checksum=0;
checkSum=checksum((USHORT*)(pPacketContent+14),20);
pIPHeader->checksum=checkSum;


//回收内存pProtocolContent!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

NdisFreeMemory(pProtocolContent,2000, 0);
DBGPRINT(" locate packet for mypacket from send_handle\n");


//分配一个新的包NdisDprAllocatePacket!!!!!!!!!!!!!!!!!!!!!!!!!

NdisDprAllocatePacket(&Status,
 &MyPackets,  
 pAdapt->SendPacketPoolHandle);

if(Status == NDIS_STATUS_SUCCESS)

{


//分配内存空间Buffer!!!!!!!!!!!!!!!!!!!!!!!
NdisAllocateBuffer(&Status,&firstBuffer,send_handle,pPacketContent,i);


if(Status != NDIS_STATUS_SUCCESS)
goto goahead;
 
NdisChainBufferAtFront( MyPackets, firstBuffer);//  
Rsvd = (PRSVD)(MyPackets->ProtocolReserved);
Rsvd->OriginalPkt = Packet;

MyPackets->Private.Head->Next =NULL;//
MyPackets->Private.Tail =NULL;//
NdisSetPacketFlags(MyPackets, NDIS_FLAGS_DONT_LOOPBACK);//

DBGPRINT("  MPSend to call ndissend start!\n");
is_send=TRUE;


//系统NdisSend函数调用
NdisSend(&Status,pAdapt->BindingHandle,MyPackets);

DBGPRINT(" send finished\n");

//filter for firewall
if(Status!= NDIS_STATUS_PENDING)
{
DBGPRINT(" send fail release resource\n");

//释放包pPacketContent!!!!!!!!!!!!!!!!!!!
NdisFreePacket(MyPackets);
DBGPRINT(" free MyPackets finished\n");

//释放Memory!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NdisFreeMemory(pPacketContent,BufLength, 0);
DBGPRINT(" free Buffer finished\n");

//释放Buffer!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NdisFreeBuffer(firstBuffer);
DBGPRINT(" free Buffer finished\n");

is_send=FALSE;
}
       

     
//  DBGPRINT(" free pPacketContent Complete then break;\n");

//break;  

}  
       

}   //检查收到的包的地址是否正确,如果正确才进行下一步处理44444444444444444444444444444444444

}   //TCP is 6 UDP is 17  3333333333333333333333333333333333

       
//发送TCP包完成
       

} //is ip packet2222222222222222222222222222222



goahead:
NdisFreeMemory(pPacketContent,2000, 0);
//Status= NDIS_STATUS_NOT_ACCEPTED;

//*********************************************************************************************************
}
}
if (UDP == 1)
{
if(((char *)pPacketContent)[12] == 8 &&
((char *)pPacketContent)[13] == 0 &&
((char *)pPacketContent)[23] == 17)
{
DbgPrint("!!!!!!!!!!!!!!UDP IS Droped!!!!!!!!!!!!!!! ");
NdisFreeMemory(pPacketContent, 2000, 0);
return NDIS_STATUS_NOT_ACCEPTED;
}
}
//规则判断结束
//--------------------------------------------

ririri
驱动牛犊
驱动牛犊
  • 注册日期2004-06-02
  • 最后登录2005-07-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-01-26 14:46
我觉得这一段可能有问题
如果数据包只有一个缓冲区描述符和一个缓冲区,
Packet->Private.Head和Packet->Private.Tail指向相同
那么你的这个循环,将不会拷贝数据包的内容。
 
而且,数据包的Packet->Private.Head和Packet->Private.Tail相同
是比较常见的,尤其是数据包不太大的时候



//把数据包内容从Packet拷贝到pPacketContent
......

for(;
{
if(pNext == Packet->Private.Tail)
break;
pNext = pNext->Next; //指针后移
if(pNext == NULL)
break;
NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);
NdisMoveMemory(pPacketContent+i,pBuf,BufLength);
i+=BufLength;
}
......
游客

返回顶部