NDIS 修改数据包,拦截URL解决方法

NDIS 修改数据包,拦截URL
想实现:本机输入www.baidu.com 拦截后显示,This page is restricted by xiaoc!


下面这个函数就是在MPSend 和 MPSendOnePacket 调用后修改数据包的。
修改完后就会调用NdisSend发送,运行结果是输入www.baidu.com 后无法找到该页
不知道错在哪里?还有如何知道效验值check的正确性?

C/C++ code

void FilterHttpRequest(PUCHAR p)
{    
    __u32 u32temp;
    __u16 u16temp;
    struct psdhdr ph;    /* pseudo header declaration */
    

    //////////////////////////SENDING BLOCK PAGE TO CLIENT//////////////////////////

    // Use the first 40 bytes of m_pBlockBuffer for future TCP control packet transmission.
    char* pBlockBuffer;
    struct iphdr*    respIpHdr;
    struct tcphdr*    respTcpHdr;    
    char* pTcpData;
    unsigned int   dsize;
    //DbgBreakPoint();

    respIpHdr        = (struct iphdr*)(p + sizeof(struct ethhdr));
    respTcpHdr        = ((struct tcphdr*)((char*)respIpHdr + sizeof (struct iphdr)));
    pTcpData = (char*)respIpHdr + sizeof(struct iphdr) + sizeof(struct tcphdr);
    
    NdisAllocateMemoryWithTag(&pBlockBuffer, 512, TAG);
    NdisZeroMemory(pBlockBuffer, 512);
    sprintf(pBlockBuffer,
        "%s",
        "<html>"
        "<head>"
        "<title>HTTPFilter block page</title></head><body><TABLE height=\"100%\" width=\"100%\">"
        "<TR>"
        "<TD align=\"center\"><h1>This page is restricted by xiaoc!</h1>"
        "</TD>"
        "</TR>"
        "</TABLE>"
        "</body>"
        "</html>\n\n\n"
        );

    dsize = Xc_strlen(pBlockBuffer, '\0');

    NdisZeroMemory(pBlockBuffer, 512);


    sprintf(pBlockBuffer,
        "HTTP/1.1 200 OK\r\n"
        "Content-Type: Text/HTML\r\n"
        "Connection: close\r\n"
        "Content-Lenght: %d"        
        "\r\n\r\n"
        "%s",
        dsize,
        "<html>"
        "<head>"
        "<title>HTTPFilter block page</title></head><body><TABLE height=\"100%\" width=\"100%\">"
        "<TR>"
        "<TD align=\"center\"><h1>This page is restricted by xiaoc!</h1>"
        "</TD>"
        "</TR>"
        "</TABLE>"
        "</body>"
        "</html>\n\n\n"
        );

    dsize = Xc_strlen(pBlockBuffer, '\0');
    DbgPrint("[xiaoc httpfiter] block info : %s", pBlockBuffer);

    NdisZeroMemory(pTcpData, XC_ntohs(respIpHdr->tot_len) - sizeof(struct iphdr) - sizeof(struct tcphdr));
    NdisMoveMemory(pTcpData, pBlockBuffer, dsize);


    DbgPrint("[xiaoc httpfilter] FilterHttpRequest debug 1");


    respIpHdr->check = 0;

    u32temp = respIpHdr->daddr;
    respIpHdr->daddr = respIpHdr->saddr;
    respIpHdr->saddr = u32temp;
    respIpHdr->tot_len = XC_htons(sizeof (struct iphdr) + sizeof (struct tcphdr) + dsize);

    respIpHdr->id = XC_htons((__u16)2);    
    respIpHdr->frag_off = 0;
    respIpHdr->protocol = 0x06;

    respIpHdr->check = 
        CalcIPSum((__u16*) respIpHdr, sizeof(struct iphdr));



    u32temp = respTcpHdr->ack_seq;
    respTcpHdr->ack_seq = XC_htonl (XC_htonl (respTcpHdr->seq) + dsize);
    respTcpHdr->seq = u32temp;
    u16temp = respTcpHdr->source;
    respTcpHdr->source = respTcpHdr->dest;
    respTcpHdr->dest = u16temp;
    respTcpHdr->ack = 1;
    respTcpHdr->fin = 1;
    //SET_TCP_OFFSET(respTcpHdr, 0x5);
    //SET_TCP_X2(respTcpHdr, 0x0);
    respTcpHdr->urg = 0;


    ph.sourceip = respIpHdr->saddr;
    ph.destip    = respIpHdr->daddr;
    ph.mbz = 0;
    ph.ptcl = 0x06;
    ph.plen = XC_htons((__u16)(sizeof (struct tcphdr) + dsize));
    respTcpHdr->check = 0;

    respTcpHdr->check = 
        CalcTCPSum((__u16 *)&ph, 
        (__u16 *)respTcpHdr,
        sizeof(struct tcphdr) + dsize);

    if( pBlockBuffer )
    {
        NdisFreeMemory(pBlockBuffer, 512, 0);
    }

}