⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpparse.cpp

📁 监听分析流量中的http流量
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// HttpParse.cpp: implementation of the CHttpParse class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HttpParse.h"
#include "WriteLog.h"

#include <assert.h>
#include <iostream>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#endif

using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHttpParse::CHttpParse()
{
}

CHttpParse::~CHttpParse()
{
	DelHttpSessionList();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//入口分析函数
bool CHttpParse::Perform(char *pInput, int nBuffLen, UINT uPort, 
								   char *src_ip, char *src_mac,
								   char *src_port, char *des_ip, char *des_mac, char *des_port)
{
	if (!pInput || !src_ip || !des_ip || !src_port || !des_port)
	{
		printf("Perform() 中的一个字符指针没有指向一个有效的地址");
		return false;
	}

	//检查是否是HTTP协议
	if (!IsHttp(uPort, src_port, des_port))
	{
		return false;
	}

	try
	{

		//对当前的IP包进行会话解析, 进行会话处理
		if(!ParseSession(pInput, src_ip, src_mac, src_port, des_ip, des_mac, des_port))
		{
			printf("进行会话处理失败");
			return false;
		}
	}
	catch(...)
	{
		DWORD err = GetLastError();
		printf("ParseSession chatch....\r\n");
	}

	if(nBuffLen <= 0)
		return false;

	try
	{
		if(!SessionPro(pInput, nBuffLen, src_ip, des_ip, src_port, des_port, src_mac, des_mac))
			return false;
	}
	catch(...)
	{
		DWORD err = GetLastError();
		printf("SessionPro chatch....\r\n");
	}

	return true;
}

//用于判断是否是telnet通信, 这里的判断依据是监听类中的端口设置, 因为这个类最终是与监听类集成, 所以这里可以用这个进行判断
bool CHttpParse::IsHttp(UINT uPort, char *src_port, char *des_port)
{

	int nSrc_Port = atoi(src_port);
	int nDes_Port = atoi(des_port);

	if (nSrc_Port == 80 || nDes_Port == 80 || \
		nSrc_Port == 8080 || nDes_Port == 8080 || \
		nSrc_Port == 3128 || nDes_Port == 3128)
	{			
		return true;			
	}
	else
	{
		return false;
	}
	

	return true;
}

/************************************************************************/
/*                               会话模块(begin)                        */
/************************************************************************/
//会话模块入口函数
bool CHttpParse::ParseSession(char *pInput, char *src_ip,
										  char *src_mac, char *src_port, char *des_ip,
										  char *des_mac, char *des_port)
{
	if (!pInput || !src_ip || !des_ip || !src_port || !des_port)
	{
		printf("ParseSession() 中的一个字符指针没有指向一个有效的地址");
		return false;
	}

	//找会话链表中存不存在有当前会话
	int nIndex =  FindSession(src_ip, src_mac, src_port, des_ip, des_mac, des_port);

	//如果没有找到会话
	if (nIndex == -1)
	{
		//增加一个新Session
		AddSession(pInput, src_ip,
				  src_mac, src_port, des_ip,
				  des_mac, des_port);

		return true;
	}
	else if (nIndex >= 0)
	{
		m_CurSession = nIndex;
		return true;
	}
	else
	{
		//出错
		printf("会话解析出错");
		return false;
	}

	return true;
}

//新增一个会话到链表中
bool CHttpParse::AddSession(char *pInput, char *src_ip,
									  char *src_mac, char *src_port, char *des_ip,
									  char *des_mac, char *des_port)
{

	HTTP_SESSION *pSession = new HTTP_SESSION;
	pSession->Conut = 0;
	pSession->session_ID = pSession->Conut;	//计算ID
	memset(pSession->server_ip, 0, IPADDR_LEN);
	memset(pSession->client_ip, 0, IPADDR_LEN);
	memset(pSession->server_port, 0, PORT_MAXLEN);
	memset(pSession->server_port, 0, PORT_MAXLEN);
	memset(pSession->client_port, 0, PORT_MAXLEN);
	memset(pSession->server_mac, 0, MAC_LEN);
	memset(pSession->client_mac, 0, MAC_LEN);
	SetNowTime((char *)pSession->begin);
	memset(pSession->end, 0, MAC_LEN);
	

	bool bFlag = CheckClient(pInput, src_ip, src_mac, src_port, des_ip, des_mac, des_port, pSession);

	//如果是客户端
	if (!bFlag)
	{
		if (des_ip)			
			strcpy((char *)pSession->server_ip, des_ip);
		else
			strcpy((char *)pSession->server_ip, "未知");
		
		if (src_ip)
			strcpy((char *)pSession->client_ip, src_ip);
		else
			strcpy((char *)pSession->client_ip, "未知");
				
		if (des_port)
			strcpy((char *)pSession->server_port, des_port);
		else
			strcpy((char *)pSession->server_port, "未知");
		
		if (src_port)
			strcpy((char *)pSession->client_port, src_port);
		else
			strcpy((char *)pSession->client_port, "未知");
	}
	else
	{
		if (src_ip)
			strcpy((char *)pSession->server_ip, src_ip);
		else
			strcpy((char *)pSession->server_ip, "未知");

		if (des_ip)
			strcpy((char *)pSession->client_ip, des_ip);
		else
			strcpy((char *)pSession->client_ip, "未知");
				
		if (src_port)
			strcpy((char *)pSession->server_port, src_port);
		else
			strcpy((char *)pSession->server_port, "未知");

		if (des_port)
			strcpy((char *)pSession->client_port, des_port);
		else
			strcpy((char *)pSession->client_port, "未知");
	}
	
	pSession->Conut++;	//ID号自增
	m_Http_Session_List.push_back(pSession);
	m_CurSession = m_Http_Session_List.size() - 1;

	 return true;
}

//对会话方进行解析, 多层判断, 判断依据:(1) 端口, (2)是否有GET, 是否有POST, 返回值为真, 表明是Server端, 返回值为假, 表明是Client端
bool CHttpParse::CheckClient(char *pInput, char *src_ip, char *src_mac,
										char *src_port, char *des_ip, char *des_mac, char *des_port,
										HTTP_SESSION *Node)
{

	//规则一:是否是23端口
	int nSrc_Port = atoi(src_port);
	if (80 == nSrc_Port || 8080 == nSrc_Port || 3128 == nSrc_Port)
	{
		if (Node) 
		{
			Node->check_step = 1;
		}
		
		return true;
	}
	else
	{
		if (Node) 
		{
			Node->check_step = 1;

		//规则二:是否有"GET" or "POST"
		if (strstr(pInput, "GET") || strstr(pInput, "POST"))
		{
			
			Node->check_step = 2;	
		}
		}

		return false;
	}

	return true;
}

//查找会话节点, 如果找到了, 返回当前会话的下标, 否则返回-1
int CHttpParse::FindSession(char *src_ip, char *src_mac, char *src_port, char *des_ip, char *des_mac, char *des_port)
{
	for (int i = 0; i < m_Http_Session_List.size(); i++)
	{
		HTTP_SESSION *pSession = (HTTP_SESSION *)m_Http_Session_List.at(i);
		if (!strcmp((char *)pSession->server_port, src_port) && !strcmp((char *)pSession->server_ip, src_ip))
		{
			if (!strcmp((char *)pSession->client_port, des_port) && !strcmp((char *)pSession->client_ip, des_ip))
			{
				return i;
			}
		}
		else if (!strcmp((char *)pSession->server_port, des_port) && !strcmp((char *)pSession->server_ip, des_ip))
		{
			if (!strcmp((char *)pSession->client_port, src_port) && !strcmp((char *)pSession->client_ip, src_ip))
			{
				return i;
			}
		}
	}

	return -1;
}

//功能: 判断一个IP包是否是一个Client所发出, 如果是, 返回1, 如果是Server, 返回2, 否则返回-1
int CHttpParse::CheckServerOrClient(char *src_ip, char *src_mac, char *src_port, char *des_ip, char *des_mac, char *des_port)
{
	if (!src_ip || !des_ip || !src_port || !des_port)
	{
		printf("CheckServerOrClient() 中的字符指针没有指向一个有效的地址");
		return false;
	}

	HTTP_SESSION *pSessionList = m_Http_Session_List.at(m_CurSession);
	//这里可能有点bug
	if (!strcmp((char *)pSessionList->server_port, src_port) && !strcmp((char *)pSessionList->server_ip, src_ip))
	{
		if (!strcmp((char *)pSessionList->client_port, des_port) && !strcmp((char *)pSessionList->client_ip, des_ip))
		{
			//返回内容: 是一个服务端
			return IS_HTTP_SERVER;
		}
	}
	else if (!strcmp((char *)pSessionList->server_port, des_port) && !strcmp((char *)pSessionList->server_ip, des_ip))
	{
		if (!strcmp((char *)pSessionList->client_port, src_port) && !strcmp((char *)pSessionList->client_ip, src_ip))
		{
			//返回内容: 是一个客户端
			return IS_HTTP_CLIENT;
		}
	}

	//返回一个错误
	return IS_HTTP_ERROR;
}


//会话结束, 传入参数pInput是用于进行会话结束时间的获取
bool CHttpParse::CheckSessionEnd(char *pInput)
{
	if (!pInput)
	{
		printf("CheckSessionEnd() 函数中的pInput参数没有指向一个有效的地址");
		return false;
	}

	char array[256] = {0};
	strcpy(array, pInput);
	strlwr(array);		//将数据全部转换成小写, 便于判断

	char *pExit = strstr(array, "exit");
	if (pExit)
	{
		SetNowTime((char *)m_Http_Session_List.at(m_CurSession)->end);	
		return true;
	}

	return false;
}


/*-------------------------------------------------------------------------------------------------------------------*/
/*                                                    会话模块(end)											         */
/*-------------------------------------------------------------------------------------------------------------------*/

/*********************************************************************************************************************/
/*                                           组装命令字和回显(begin)                                                 */
/*********************************************************************************************************************/

//这里完成IP数据包的组装, 并进入链表, pCmdBuff协商后通信时的Client命令, pEchoBuff协商后通信时的Server回显
bool CHttpParse::SessionPro(char *pInput, int nBuffLen,
											 char *src_ip, char *des_ip, char *src_port, char *des_port, char *src_mac, char *des_mac)
{

	if (!pInput || !src_ip || !des_ip || !src_port || !des_port)
	{
		printf("SessionPro() 中的字符指针没有指向一个有效的地址");
		return false;
	}

	//判断是否是一个服务器或客户端
	int nRet = CheckServerOrClient(src_ip, src_mac, src_port, des_ip, des_mac, des_port);

	//命令包处理
	if(nRet == IS_HTTP_CLIENT)
	{
		try
		{
			//增加命令源数据包
			if(AddRawPackList_NetAddr(pInput, nBuffLen, src_ip, des_ip, src_port, des_port, src_mac, des_mac))
			{
				HTTP_APP_PACK *pAppPack = new HTTP_APP_PACK;
				memset(pAppPack->cmd, 0, CMD_MAXLEN);
				pAppPack->echo = NULL;
				pAppPack->pNetAddr = NULL;

				int nLenAddr = 0;

				//组装回显应用包
				if(ConfigNetAddr(&pAppPack->pNetAddr,(unsigned char *)des_ip, &nLenAddr, pAppPack->date))
				{
					pAppPack->nLenAddr = nLenAddr;
					int nSize = m_Http_Session_List.size();
					if(m_CurSession > nSize - 1)
						printf("*********m_CurSession is error************");

					HTTP_SESSION *pHttpSession = m_Http_Session_List.at(m_CurSession);
					pHttpSession->AppPackList.push_back(pAppPack);

					nSize = pHttpSession->AppPackList.size();
					if (nSize >= HTTP_MAX_SAVE)
					{

						//cout<<pInput<<endl<<endl;
						//ConfigSessionRecord(m_Http_Session_List, m_CurSession, MAX_BUFFER_LEN);
						//清除应用会话
						//ClearSessionAppPack(m_CurSession);
					}
				}
				
				return true;
			}
		}
		catch(...)
		{
			DWORD nErro = ::GetLastError();
			printf("AddRawPackList_NetAddr 1 catch", nErro);
		}
	}
	else
	{
		try
		{
			//增加回显源数据包
			if(AddRawPackList_Echo(pInput, nBuffLen, src_ip, des_ip, src_port, des_port, src_mac, des_mac))
			{
				HTTP_APP_PACK *pAppPack = new HTTP_APP_PACK;
				memset(pAppPack->cmd, 0, CMD_MAXLEN);
				pAppPack->echo = NULL;
				pAppPack->pNetAddr = NULL;

				//组装回显应用包
				if(!ConfigEcho((unsigned char*)pInput, &pAppPack->echo, pAppPack->date))
				{
					int nSize = m_Http_Session_List.size();
					if(m_CurSession>nSize-1)
						printf("*********m_CurSession is error************");

					if (pAppPack->echo)
					{
						//cout<<pAppPack->echo<<endl;
					}

					HTTP_SESSION *pHttpSession = m_Http_Session_List.at(m_CurSession);
					pHttpSession->AppPackList.push_back(pAppPack);

					nSize = pHttpSession->AppPackList.size();
					if (nSize >= HTTP_MAX_SAVE)
					{

						ConfigSessionRecord(m_Http_Session_List, m_CurSession, MAX_BUFFER_LEN);
						//清除应用会话
						ClearSessionAppPack(m_CurSession);
					}
				}
				else
				{
					HTTP_SESSION *pHttpSession = m_Http_Session_List.at(m_CurSession);
					int nSize = pHttpSession->AppPackList.size();
					if (nSize >= HTTP_MAX_SAVE)
					{

						ConfigSessionRecord(m_Http_Session_List, m_CurSession, MAX_BUFFER_LEN);
						//清除应用会话
						ClearSessionAppPack(m_CurSession);
					}
				}

				return true;
			}	
		}
		catch(...)
		{
			DWORD nErro = ::GetLastError();
			printf("AddRawPackList_Echo 2 catch",nErro);
		}
		
		return false;

	}

	return false;
}

//这个函数用于对网址的封装, 包括命令和回显, 封装原则, 一个server带一个client, 也就是一个浏览器请求加一个服务器回显
bool CHttpParse::ConfigNetAddr(unsigned char **pNetAddr, unsigned char *src_ip, int *nLenAddr, char *date)
{
	try
	{
		if (!pNetAddr)
		{
			printf("ConfigNetAddr()中的pCmd参数没有指向一个有效的地址");
			return false;
		}

		HTTP_SESSION *pSession = m_Http_Session_List.at(m_CurSession);
		int nSize = pSession->RawPackList.size();
		if(nSize <= 0)
			return false;

		//保存时间
		if (pSession->RawPackList.at(0)->date)
		{
			strcpy(date, pSession->RawPackList.at(0)->date);
		}
		else
		{
			printf("结构体中没有时间");
		}

		//将链表中的数据保存到数组中
		HTTP_RAW_PACK *pRawPack = pSession->RawPackList.at(nSize - 1);	
		unsigned char *pTemp = new unsigned char[MIN_BUFFER_LEN];
		if (pRawPack->nLenaddr > 0)
		{
			memset(pTemp, 0, MIN_BUFFER_LEN);
			memcpy(pTemp, pRawPack->netaddr, pRawPack->nLenaddr);
			*nLenAddr = pRawPack->nLenaddr;
		}	

		*pNetAddr = pTemp;
	}
	catch(...)
	{
		DWORD err = GetLastError();
		printf("for chatch....\r\n");
	}	

	return true;

}

bool CHttpParse::ConfigEcho(unsigned char *pInput, unsigned char **pEcho, char *date)
{
	try
	{
		if (!pEcho)
		{
			printf("ConfigNetAddr()中的pEcho参数没有指向一个有效的地址");
			return false;
		}

		HTTP_SESSION *pSession = m_Http_Session_List.at(m_CurSession);
		int nSize = pSession->RawPackList.size();
		if(nSize <= 0)
			return false;

		//保存时间
		if (pSession->RawPackList.at(0)->date)
		{
			strcpy(date, pSession->RawPackList.at(0)->date);
		}
		else
		{
			printf("结构体中没有时间");
		}

		try
		{
			int nAppPackSize = pSession->AppPackList.size(); 
			if(nAppPackSize<=0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -