diaowubin
驱动牛犊
驱动牛犊
  • 注册日期2008-02-08
  • 最后登录2017-10-12
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望159点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分5分
  • 社区居民
阅读:1650回复:8

撑不住了,passthru的ptreceive的LookAheadBuffer中取得IP头数据是对的,但TCP头怎么不对??

楼主#
更多 发布于:2008-05-19 21:36
撑不住了,搞了两天了,passthru的ptreceive的LookAheadBuffer中取得IP头数据是对的,但TCP头怎么不对??

我的代码:
NDIS_STATUS
PtReceive(
          IN  NDIS_HANDLE         ProtocolBindingContext,
          IN  NDIS_HANDLE         MacReceiveContext,
          IN  PVOID               HeaderBuffer,
          IN  UINT                HeaderBufferSize,
          IN  PVOID               LookAheadBuffer,
          IN  UINT                LookAheadBufferSize,
          IN  UINT                PacketSize
          )
{
    PADAPT            pAdapt = (PADAPT)ProtocolBindingContext;
    PNDIS_PACKET      MyPacket, Packet;
    NDIS_STATUS       Status = NDIS_STATUS_SUCCESS;
    
       if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))
    {
        Status = NDIS_STATUS_FAILURE;
    }
    else do
    {
        //
        // Get at the packet, if any, indicated up by the miniport below.
        //
        Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);      
        ////////////////////////////我加入的代码//////////////////////////////
        if ( HeaderBufferSize >= sizeof(ETHeader) )
                  KdPrint(( "ETHeader type : %x\n", ((PETHeader)HeaderBuffer)->type ));
        FilterReceive( LookAheadBuffer, LookAheadBufferSize);
         /////////////////////////////////////////////////////////////////////////////////
        
        if (Packet != NULL)
        {
         。。。。。。。。。。。。。。。。。。。。。passthru原来的代码
         。。。。。。。。。。。。。。。。。。。。。
     。。。。。。。。。。。。。。。。。。。。。
}


VOID FilterReceive(I N PVOID   pData, IN UINT   pDataSize  )
{
    //剩下数据的长度
    ULONG ulLeavingLen = pDataSize;
    PIPHeader pIPHdr;
    PTCPHeader pTCPHdr;

    if ( ulLeavingLen < sizeof( IPHeader ) )
    {
        KdPrint(( "ulLeavingLen < sizeof( IPHeader )\n" ));
        return;
    }
    pIPHdr = ( PIPHeader  )( pData );
    DbgPrint( "The Src address is %d.%d.%d.%d\n",
                                           pIPHdr->ipSource << 24 >> 24,
        pIPHdr->ipSource << 16 >> 24,
                         pIPHdr->ipSource << 8 >> 24,
        pIPHdr->ipSource >> 24 );
    DbgPrint( "The Dest address is %d.%d.%d.%d\n",
        pIPHdr->ipDestination << 24 >> 24,
        pIPHdr->ipDestination << 16 >> 24,
        pIPHdr->ipDestination << 8 >> 24,
        pIPHdr->ipDestination >> 24 );

    ulLeavingLen -= sizeof( IPHeader );
    KdPrint(( "pIPHdr->ipProtocol = %d\n", pIPHdr->ipProtocol ));
    //不是TCP退出
    if ( pIPHdr->ipProtocol != 6 )
    {
        KdPrint(( "pIPHdr->ipProtocol != 6\n" ));
        return;
    }
    if ( ulLeavingLen < sizeof(TCPHeader) )
    {
        KdPrint(( "ulLeavingLen < sizeof(TCPHeader)\n" ));
        return;
    }
    pTCPHdr = ( PTCPHeader )( (char*)pIPHdr + sizeof(IPHeader) );
    KdPrint(( "TCPHeader sourcePort : %d\n", pTCPHdr->sourcePort ));
    KdPrint(( "TCPHeader destinationPort : %d\n", pTCPHdr->destinationPort ));
    //不是80端口退出
    if ( pTCPHdr->destinationPort != 80 )
        return;
    KdPrint(( "TCPHeader destinationPort : http80\n"));
}




//IP头和TCP头声明
typedef struct _IPHeader        // 20
{
    UCHAR     iphVerLen;      // 版本号和头长度(各占4位)
    UCHAR     ipTOS;          // 服务类型
    USHORT    ipLength;       // 封包总长度,即整个IP报的长度
    USHORT    ipID;              // 封包标识,惟一标识发送的每一个数据报
    USHORT    ipFlags;          // 标志
    UCHAR     ipTTL;          // 生存时间,就是TTL
    UCHAR     ipProtocol;     // 协议,可能是TCP、UDP、ICMP等
    USHORT    ipChecksum;     // 校验和
    ULONG     ipSource;       // 源IP地址
    ULONG     ipDestination;  // 目标IP地址
} IPHeader, *PIPHeader;


typedef struct _TCPHeader     //20 bytes
{
    USHORT            sourcePort;        // 16位源端口号
    USHORT            destinationPort;    // 16位目的端口号
    ULONG            sequenceNumber;        // 32位序列号
    ULONG            acknowledgeNumber;    // 32位确认号


    UCHAR            dataoffset;        // 高4位表示数据偏移
    UCHAR            flags;            // 6位标志位
                                                                
    USHORT            windows;        // 16位窗口大小
    USHORT            checksum;        // 16位校验和
    USHORT            urgentPointer;        // 16位紧急数据偏移量
} TCPHeader, *PTCPHeader;


请指教!谢谢!
eleqi
驱动小牛
驱动小牛
  • 注册日期2005-12-20
  • 最后登录2014-01-03
  • 粉丝4
  • 关注2
  • 积分172分
  • 威望1475点
  • 贡献值0点
  • 好评度115点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-05-19 22:48
不懂,学习中,帮顶一下
lgr98
驱动牛犊
驱动牛犊
  • 注册日期2008-04-29
  • 最后登录2008-09-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-05-20 06:52
取不到吗?没有试过你这种,你可以试试
    NdisQueryPacket(packet, NULL, NULL, &ndisBuffer, &totalLen);
    while (NULL != ndisBuffer)
    {
        NdisQueryBufferSafe(ndisBuffer, &address, &curLen, NormalPagePriority);
        NdisMoveMemory(pcontent, address, curLen);
        (PUCHAR)pcontent += curLen;
        NdisGetNextBuffer(ndisBuffer, &ndisBuffer);
    }
我这样是可以取到的
diaowubin
驱动牛犊
驱动牛犊
  • 注册日期2008-02-08
  • 最后登录2017-10-12
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望159点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分5分
  • 社区居民
地板#
发布于:2008-05-20 10:11
lgr98,我也用过你这种方法了,取到的数据和我这个方法是一样的,难道是我TCP头位置截错了?不可能的呀
lgr98
驱动牛犊
驱动牛犊
  • 注册日期2008-04-29
  • 最后登录2008-09-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-05-20 22:55
ip头取到了,ip头中的协议类型是tcp,  那ip头加上ip头的长度不就是tcp头吗?我这样取是可以取到的呀!!(ip头长度的单位是4字节的)
65551494
驱动牛犊
驱动牛犊
  • 注册日期2007-11-10
  • 最后登录2008-11-05
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望5点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-05-21 14:13
pTCPHdr = ( PTCPHeader )( (char*)pIPHdr + sizeof(IPHeader) );
如果IP头有可选头的话,这样定位就有问题了。。。
 UCHAR    iphVerLen;      // 版本号和头长度(各占4位)
(iphVerLen&0x0F)*4
diaowubin
驱动牛犊
驱动牛犊
  • 注册日期2008-02-08
  • 最后登录2017-10-12
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望159点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分5分
  • 社区居民
6楼#
发布于:2008-05-21 14:55
我已经改成这样了:
pTCPHdr = ( PTCPHeader )( (char*)pIPHdr + (pIPHdr->iphVerLen  &   0xf) * 4 );
但取到的源端口和目的端口都是很大的值,怎么回事?
还真是不知道错在哪?
驱动网的大小牛们都没看出来吗?
cyliu
论坛版主
论坛版主
  • 注册日期2003-06-13
  • 最后登录2014-04-11
  • 粉丝5
  • 关注0
  • 积分1238分
  • 威望2531点
  • 贡献值0点
  • 好评度577点
  • 原创分14分
  • 专家分10分
7楼#
发布于:2008-05-22 12:40
数据不再同一片上,需要遍历packet的里面的buffer(不是数据阿)数据片联表。你这样直接+数据,谁知道你读的数据是什么了。

似乎有什么NdisNextbuffer之类接口,好久了不写windows code了,忘记了。你可以从ndis的数据格式的api里面找到答案。
走走看看开源好 Solaris vs Linux
diaowubin
驱动牛犊
驱动牛犊
  • 注册日期2008-02-08
  • 最后登录2017-10-12
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望159点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分5分
  • 社区居民
8楼#
发布于:2008-05-22 22:09
NdisQueryPacket( Packet, NULL, NULL, &firstBuffer, &totalLength );
j = 0;
while(  firstBuffer  !=  NULL  )
{
         j ++;
         NdisQueryBufferSafe( firstBuffer, &virtualAddress, &totalLength, NormalPagePriority );
        //DBGPRINT( ( "PtReceive --- Buffer %d Length : %d\n", j, totalLength ) );
        if( ! virtualAddress )
                 return STATUS_INSUFFICIENT_RESOURCES;

        if ( j == 1 )
                  FilterReceive( (char*)virtualAddress + sizeof(ETHeader), totalLength-sizeof(ETHeader) );
          NdisGetNextBuffer( firstBuffer, &nextBuffer );
          firstBuffer = nextBuffer;
}

可是,版主,上边这个代码没问题吧,而且第一个Buffer是够 以太网头 + IP头 + TCP头 的长度,但是这段代码得到的TCP头和我上边的那段代码得到的是一样的,怎么说这个?

好像LookAheadBuffer是连续的吧?
游客

返回顶部