processpacket.cpp
来自「The C++ Client Edition contains a full s」· C++ 代码 · 共 742 行
CPP
742 行
#include "StdAfx.h"
#include ".\processPacket.h"
CProcessPacket::CProcessPacket(CFilterLog* in_pFilterLog):
m_szSourceDevice(NULL),
m_hSniffThread(NULL),
m_pUrlFilterObj(NULL),
m_pFilterLog(in_pFilterLog),
m_cbBlockBuffer(-1),
m_hThrdReadyEvent(NULL)
{
RetrieveAllAdaptersInfo();
WSADATA wsock;
WSAStartup(MAKEWORD(2,2), &wsock);
ZeroMemory(m_pBlockBuffer, 512);
CString strBufferHdr;
CString strBufferHTML;
strBufferHTML = "<html>";
strBufferHTML += "<head>";
strBufferHTML += "<title>HTTPFilter block page</title></head><body><TABLE height=\"100%\" width=\"100%\">";
strBufferHTML += "<TR>";
strBufferHTML += "<TD align=\"center\"><h1>This page is restricted by HTTPFilter!</h1>";
strBufferHTML += "</TD>";
strBufferHTML += "</TR>";
strBufferHTML += "</TABLE>";
strBufferHTML += "</body>";
strBufferHTML += "</html>\n\n\n";
char len[10];
_itoa (strBufferHTML.GetLength(), len, 10);
strBufferHdr += "HTTP/1.1 200 OK\r\n";
strBufferHdr += "Content-Type: Text/HTML\r\n";
strBufferHdr += "Connection: close\r\n";
strBufferHdr += "Content-Lenght: ";
strBufferHdr += len;
strBufferHdr += "\r\n\r\n";
strBufferHdr += strBufferHTML;
// First 40 bytes reserved for TCP and IP header placement
_mbscpy (m_pBlockBuffer + 40,(u_int8_t*) strBufferHdr.GetBuffer());
m_cbBlockBuffer = strBufferHdr.GetLength(); // size of HTTP payload only
}
CProcessPacket::~CProcessPacket(void)
{
WSACleanup();
}
int CProcessPacket::StartEngine(const char* in_szSourceDevice)
{
int optval;
m_szSourceDevice = strdup(in_szSourceDevice);
/* prepare URL list */
m_pUrlFilterObj = new CURIFilter();
if (m_pUrlFilterObj->Init(g_ProgVar) <= 0)
{
return 0;
}
if (m_szSourceDevice != NULL)
{
if((m_helperSocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))==SOCKET_ERROR)
{
return 0;
}
if(setsockopt(m_helperSocket, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
{
return 0;
}
if((m_sniffSocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP))==SOCKET_ERROR)
{
return 0;
}
PIP_ADAPTER_INFO pAdapterInfo = m_AdapterInfo;
u_long in = 0;
do {
if (strcmp (in_szSourceDevice, pAdapterInfo->AdapterName ) == 0)
{
break;
}
in++;
pAdapterInfo = pAdapterInfo->Next; // Progress through
}
while(pAdapterInfo);
struct sockaddr_in src;
memset(&src, 0, sizeof(src));
src.sin_addr.S_un.S_addr = inet_addr (pAdapterInfo->IpAddressList.IpAddress.String);
src.sin_family = AF_INET;
src.sin_port = 0;
if (bind(m_sniffSocket,(struct sockaddr *)&src,sizeof(src)) == SOCKET_ERROR)
{
return 0;
}
int j=1;
if (WSAIoctl(m_sniffSocket, SIO_RCVALL, &j, sizeof(j), 0, 0, &in,0, 0) == SOCKET_ERROR)
{
return 0;
}
m_hThrdReadyEvent = CreateEvent(
NULL, // no security attributes
TRUE, // manual-reset event
FALSE, // initial state is signaled
"HttpFilter_ThreadReadyEvent" // object name
);
DWORD dwThreadID = 0;
m_hSniffThread = CreateThread(NULL,
NULL,
CProcessPacket::ThreadHandler,
this,
NULL,
&dwThreadID);
// wait until the thready started completely
WaitForSingleObject(m_hThrdReadyEvent, INFINITE);
}
else
{
return 0;
}
// if successful
return 1;
}
int CProcessPacket::StopEngine()
{
closesocket(m_sniffSocket);
//closesocket(m_helperSocket);
if (m_hThrdReadyEvent)
CloseHandle(m_hThrdReadyEvent); // Close thread ready event
m_hThrdReadyEvent = NULL;
if (m_hSniffThread)
CloseHandle(m_hSniffThread);
m_hSniffThread = NULL;
if (m_pUrlFilterObj)
{
delete m_pUrlFilterObj;
m_pUrlFilterObj = NULL;
}
// if successful
return 1;
}
DWORD CProcessPacket::ThreadHandler(LPVOID in_pParam)
{
CProcessPacket* _this = (CProcessPacket*)in_pParam;
int res = 0;
char *pkt_data = (char *)malloc(65536); //Its Big!
char m_pLogString[256];
Packet p;
if (pkt_data == NULL)
{
return 0;
}
SetEvent(_this->m_hThrdReadyEvent);
// Capture packet
do
{
res = recvfrom(_this->m_sniffSocket,pkt_data,65536,0,0,0); //Eat as much as u can
if(res > 0)
{
ZeroMemory(&p, sizeof (Packet));
_this->DecodeIP((u_int8_t*)pkt_data, res, &p);
if (p.banned == 1)
{
_this->FilterHttpRequest(&p);
char ip_string_src[17];
char ip_string_dst[17];
memcpy (ip_string_src, inet_ntoa(p.iph->ip_src), 17);
memcpy (ip_string_dst, inet_ntoa(p.iph->ip_dst), 17);
sprintf (m_pLogString,
"Keyword \'%s\' is detected in a request from %s to %s. Session Droped!",
p.matched, ip_string_src, ip_string_dst);
_this->m_pFilterLog->AddLog(m_pLogString);
}
}
}
while (res > 0);
free(pkt_data);
return 1;
}
void CProcessPacket::DecodeIP(u_int8_t * pkt, const u_int32_t len, Packet * p){ u_int32_t ip_len; /* length from the start of the ip hdr to the * pkt end */ u_int32_t hlen; /* ip header length */ /* lay the IP struct over the raw data */ p->iph = (IPHdr *) pkt; /* do a little validation */ if(len < IP_HEADER_LEN) { p->iph = NULL; return; } if(IP_VER(p->iph) != 4) { p->iph = NULL; return; } /* set the IP datagram length */ ip_len = ntohs(p->iph->ip_len); /* set the IP header length */ hlen = IP_HLEN(p->iph) << 2; /* header length sanity check */ if(hlen < IP_HEADER_LEN) { p->iph = NULL; return; } if (ip_len > len) { ip_len = len; } if(ip_len < hlen) { p->iph = NULL; return; } /* test for IP options */ p->ip_options_len = hlen - IP_HEADER_LEN; if(p->ip_options_len > 0) { p->ip_options_data = pkt + IP_HEADER_LEN; } /* set the remaining packet length */ ip_len -= hlen; /* check for fragmented packets */ p->frag_offset = ntohs(p->iph->ip_off); /* * get the values of the reserved, more * fragments and don't fragment flags */ p->rf = (u_int8_t)((p->frag_offset & 0x8000) >> 15); p->df = (u_int8_t)((p->frag_offset & 0x4000) >> 14); p->mf = (u_int8_t)((p->frag_offset & 0x2000) >> 13); /* mask off the high bits in the fragment offset field */ p->frag_offset &= 0x1FFF; if(p->frag_offset || p->mf) { /* set the packet fragment flag */ p->frag_flag = 1; } /* if this packet isn't a fragment */ if(!(p->frag_flag)) { /* Decode only TCP headers */ if (p->iph->ip_proto == IPPROTO_TCP) {
DecodeTCP(pkt + hlen, ip_len, p);
} } else { /* set the payload pointer and payload size */ p->data = pkt + hlen; p->dsize = (u_short) ip_len; } return;}void CProcessPacket::DecodeTCP(u_int8_t * pkt, const u_int32_t len, Packet * p){
u_int32_t hlen; /* TCP header length */
if(len < 20) {
p->tcph = NULL;
return;
}
/* lay TCP on top of the data cause there is enough of it! */ p->tcph = (TCPHdr *) pkt; /* multiply the payload offset value by 4 */ hlen = TCP_OFFSET(p->tcph) << 2;
if(hlen < 20) {
p->tcph = NULL;
return;
}
if(hlen > len) {
p->tcph = NULL;
return;
}
/* if options are present, decode them */ p->tcp_options_len = hlen - 20;
if(p->tcp_options_len > 0) { p->tcp_options_data = pkt + 20; }
/* set the data pointer and size */ p->data = (u_int8_t *) (pkt + hlen);
if(hlen < len) { p->dsize = (u_short)(len - hlen); } else { p->dsize = 0; }
if (p->tcph->th_flags & TH_ACK
&& p->tcph->th_flags & TH_PSH)
{
if(p->tcph->th_dport != htons(80) &&
p->tcph->th_dport != htons(8080) )
return ;
DecodeHTTP(p->data, p->dsize, p);
}
return;
}
void CProcessPacket::DecodeHTTP(u_int8_t * pkt, const u_int32_t len, Packet * p)
{
if (CheckHttpState(pkt, len) == CLIENT_REQUEST)
{ int matched_idx = 0;
if (m_pUrlFilterObj->CheckPattern(pkt, len, &matched_idx))
{
/* packet caught, Filter it */
p->banned = 1;
_mbscpy(p->matched, m_pUrlFilterObj->GetPattern(matched_idx));
}
}
}
int CProcessPacket::CheckHttpState(u_int8_t* buffer,u_int32_t len)
{
if(!len)
return NOT_HTTP;
if( buffer[0] == 'G' &&
buffer[1] == 'E' &&
buffer[2] == 'T' &&
buffer[3] == ' ' &&
buffer[4] == '/'
)
return CLIENT_REQUEST;
if( buffer[0] == 'H' &&
buffer[1] == 'T' &&
buffer[2] == 'T' &&
buffer[3] == 'P')
return SERVER_RESPONSE;
//else anyway
return NOT_HTTP;
}
unsigned short CProcessPacket::CalcIPSum(unsigned short * w, int blen){ unsigned int cksum; /* IP must be >= 20 bytes */ cksum = w[0]; cksum += w[1]; cksum += w[2]; cksum += w[3]; cksum += w[4]; cksum += w[5]; cksum += w[6]; cksum += w[7]; cksum += w[8]; cksum += w[9]; blen -= 20; w += 10; while( blen ) /* IP-hdr must be an integral number of 4 byte words */ { cksum += w[0]; cksum += w[1]; w += 2; blen -= 4; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short) (~cksum);}unsigned short CProcessPacket::CalcTCPSum(unsigned short *h, unsigned short * d, int dlen){ unsigned int cksum; unsigned short answer=0; /* PseudoHeader must have 12 bytes */ cksum = h[0]; cksum += h[1]; cksum += h[2]; cksum += h[3]; cksum += h[4]; cksum += h[5]; /* TCP hdr must have 20 hdr bytes */ cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; cksum += d[4]; cksum += d[5]; cksum += d[6]; cksum += d[7]; cksum += d[8]; cksum += d[9]; dlen -= 20; /* bytes */ d += 10; /* short's */ while(dlen >=32) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; cksum += d[4]; cksum += d[5]; cksum += d[6]; cksum += d[7]; cksum += d[8]; cksum += d[9]; cksum += d[10]; cksum += d[11]; cksum += d[12]; cksum += d[13]; cksum += d[14]; cksum += d[15]; d += 16; dlen -= 32; } while(dlen >=8) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; d += 4; dlen -= 8; } while(dlen > 1) { cksum += *d++; dlen -= 2; } if( dlen == 1 ) { /* printf("new checksum odd byte-packet\n"); */ *(unsigned char*)(&answer) = (*(unsigned char*)d); /* cksum += (u_int16_t) (*(u_int8_t*)d); */ cksum += answer; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short)(~cksum);}
int CProcessPacket::FilterHttpRequest(Packet *p)
{
DWORD err = 0;
SOCKADDR_IN dest;
dest.sin_family = AF_INET;
struct pseudoheader /* pseudo header for TCP checksum calculations */
{
u_int32_t sip, dip; /* IP addr */
u_int8_t zero; /* checksum placeholder */
u_int8_t protocol; /* protocol number */
u_int16_t tcplen; /* TCP packet length */
};
struct pseudoheader ph; /* pseudo header declaration */
//////////////////////////SENDING BLOCK PAGE TO CLIENT//////////////////////////
// Use the first 40 bytes of m_pBlockBuffer for future TCP control packet transmission.
ZeroMemory(m_pBlockBuffer, 40); // only zero first 40 bytes
IPHdr* respIpHdr = ((IPHdr*)(m_pBlockBuffer ));
TCPHdr* respTcpHdr = ((TCPHdr*)(m_pBlockBuffer + sizeof (IPHdr)));
respIpHdr->ip_csum = 0;
respIpHdr->ip_dst = p->iph->ip_src;
respIpHdr->ip_src = p->iph->ip_dst;
respIpHdr->ip_len = htons(sizeof (IPHdr) + sizeof (TCPHdr) + m_cbBlockBuffer);
SET_IP_VER(respIpHdr, 0x4);
SET_IP_HLEN(respIpHdr, 0x5);
respIpHdr->ip_tos = p->iph->ip_tos;
respIpHdr->ip_ttl = p->iph->ip_ttl;
respIpHdr->ip_id = htons(2);
respIpHdr->ip_off = 0;
respIpHdr->ip_proto = 0x06;
respIpHdr->ip_csum =
CalcIPSum((u_short*) respIpHdr, IP_HLEN(respIpHdr) << 2);
respTcpHdr->th_ack = htonl (ntohl (p->tcph->th_seq) + p->dsize);
respTcpHdr->th_seq = p->tcph->th_ack;
respTcpHdr->th_sport = p->tcph->th_dport;
respTcpHdr->th_dport = p->tcph->th_sport;
respTcpHdr->th_flags = TH_ACK | TH_FIN;
SET_TCP_OFFSET(respTcpHdr, 0x5);
SET_TCP_X2(respTcpHdr, 0x0);
respTcpHdr->th_win = p->tcph->th_win;
respTcpHdr->th_urp = 0;
ph.sip = (u_int32_t)(p->iph->ip_dst.s_addr);
ph.dip = (u_int32_t)(p->iph->ip_src.s_addr);
ph.zero = 0;
ph.protocol = 0x06;
ph.tcplen = htons((u_short)(sizeof (TCPHdr) + m_cbBlockBuffer));
respTcpHdr->th_sum = 0;
respTcpHdr->th_sum =
CalcTCPSum((u_int16_t *)&ph,
(u_int16_t *)respTcpHdr,
sizeof(TCPHdr) + m_cbBlockBuffer);
dest.sin_port = p->tcph->th_sport;
dest.sin_addr = p->iph->ip_src;
if((sendto(m_helperSocket ,(const char*)( m_pBlockBuffer ), sizeof(IPHdr) + sizeof(TCPHdr) + m_cbBlockBuffer, 0,
(SOCKADDR *)&dest, sizeof(dest))) == SOCKET_ERROR)
{
m_pFilterLog->AddLog("sendto failed!");
return 0;
}
///////////////////////SENDING TCP RESET TO SERVER////////////////////////////
ZeroMemory(reset_buf, 40);
IPHdr* rstIpHdr = ((IPHdr*)(reset_buf ));
TCPHdr* rstTcpHdr = ((TCPHdr*)(reset_buf + sizeof (IPHdr) ));
rstIpHdr->ip_dst = p->iph->ip_dst;
rstIpHdr->ip_id = htons(2);
rstIpHdr->ip_len = htons(sizeof (IPHdr) + sizeof (TCPHdr));
rstIpHdr->ip_off = 0;
rstIpHdr->ip_proto = 0x06;
rstIpHdr->ip_src = p->iph->ip_src;
rstIpHdr->ip_tos = p->iph->ip_tos;
rstIpHdr->ip_ttl = p->iph->ip_ttl;
SET_IP_VER(rstIpHdr, 0x4);
SET_IP_HLEN(rstIpHdr, 0x5);
rstIpHdr->ip_csum =
CalcIPSum((u_short*) rstIpHdr, IP_HLEN(rstIpHdr) << 2);
rstTcpHdr->th_ack = p->tcph->th_ack;
rstTcpHdr->th_seq = p->tcph->th_seq;
rstTcpHdr->th_sport = p->tcph->th_sport;
rstTcpHdr->th_dport = p->tcph->th_dport;
rstTcpHdr->th_flags = TH_RST;
SET_TCP_OFFSET(rstTcpHdr, 0x5);
SET_TCP_X2(rstTcpHdr, 0x0);
rstTcpHdr->th_win = p->tcph->th_win;
rstTcpHdr->th_urp = 0;
ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);
ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);
ph.zero = 0;
ph.protocol = 0x06;
ph.tcplen = htons((u_short)sizeof (TCPHdr));
rstTcpHdr->th_sum =
CalcTCPSum((u_int16_t *)&ph,
(u_int16_t *)rstTcpHdr,
sizeof(TCPHdr));
dest.sin_port = p->tcph->th_dport;
dest.sin_addr = p->iph->ip_dst;
if((sendto(m_helperSocket ,(const char*)( reset_buf ), sizeof(IPHdr) + sizeof(TCPHdr), 0,
(SOCKADDR *)&dest, sizeof(dest))) == SOCKET_ERROR)
{
m_pFilterLog->AddLog("sendto failed!");
return 0;
}
return 1;
}
int CProcessPacket::RetrieveAllAdaptersInfo()
{
DWORD dwBufLen = sizeof(m_AdapterInfo);
if (GetAdaptersInfo( // Call GetAdapterInfo
m_AdapterInfo, // [out] buffer to receive data
&dwBufLen) != ERROR_SUCCESS)
{
return 0;
}
return 1;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?