📄 httpparse.cpp
字号:
// 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 + -