2,640
社区成员
发帖
与我相关
我的任务
分享
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);
}
}
FILTER_STATUS DecodeTCP(PUCHAR pData)
{
struct tcphdr* pTCPHead;
struct iphdr* pIpHead;
char* pTCPData = NULL;
int datalen = 0;
int tcphdrlen = 0;
__u16 nSrcPort;
__u16 nDesPort;
struct psdhdr psd_header;
pIpHead = (struct iphdr*)(pData + sizeof(struct ethhdr));
pTCPHead = (struct tcphdr*)((char*)pIpHead + pIpHead->ihl*4);
nSrcPort = XC_ntohs(pTCPHead->source);
nDesPort = XC_ntohs(pTCPHead->dest);
tcphdrlen = XC_ntohs(pIpHead->tot_len) - sizeof(struct iphdr);
pTCPData = (char*)pIpHead + sizeof(struct iphdr) + sizeof(struct tcphdr);
DbgPrint("[xiaoc httpfilter] sport = %u, dport = %u, psh = %d, ack = %d",
nSrcPort, nDesPort, pTCPHead->psh, pTCPHead->ack);
if( pTCPHead->psh == 1 && pTCPHead->ack == 1 )
{
DbgPrint("[xiaoc httpfilter] DecodeTCP psh | ack");
if( nDesPort != 80 && nDesPort != 8080 )
{
return STATUS_PASS;
}
return DecodeHTTP(pTCPData, tcphdrlen, pData);
}
return STATUS_PASS;
}
FILTER_STATUS DecodeHTTP(__u8 * pkt, const __u32 len, PUCHAR p)
{
DbgPrint("[xiaoc httpfilter] DecodeHTTP");
if (CheckHttpState(pkt, len) == CLIENT_REQUEST)
{
int matched_idx = 0;
if (CheckPattern(pkt, len, &matched_idx))
{
DbgPrint("[xiaoc httpfilter] ban page");
/* packet caught, Filter it */
FilterHttpRequest(p);
DbgPrint("[xiaoc httpfilter exec FilterHttpRequest finished!" );
return STATUS_MODIFY;
}
}
return STATUS_PASS;
}