📄 tcphashmain.cpp
字号:
/************************************************************ * Copyright(C) 1998-2004,CongXing Tech. Co. Ltd. * FileName: CbTCPMain.cpp * Author: Jay * Version: V01.00.000 * Date: 2004.01.13 * Description: 获取IP包,组合TCP流,交给应用层处理 * (Hash表版) * 还没解决问题: * 一旦有人发起 对某个网站DoS攻击,则这个程序同样会受到严重影响 ************************************************************/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <arpa/inet.h>#include <error.h>#include <string.h>#include <signal.h>#include <Config.h>#include <TCPStream.h>#include <HashTable.h>#include <LongInt.h>#include <ShmApply.h>#include <Timeutil.h>#include "BaseConst.h"#include "Mem.h" #include "Log.h"#include "RtRadiusIP.h"#include <time.h>#include <new>const int RECEIVEDRATE = 99;const int C_MAX_PACKET_BUFFER = 10;//rbuffer的大小(个数)CRtRdsIP watchip;extern long G_TIME_NOW;//定义所有用到的变量unsigned char wbuffer[sizeof(int)+sizeof(ST_TCP_STREAM)+C_MAX_TCP_STREAM_LEN];char* ptmp;int C_ARR_MEM_STREAM_SIZE[]={ sizeof(CTCPStream), C_TCP_STREAM_INIT_SIZE, C_TCP_STREAM_INIT_SIZE*2, C_TCP_STREAM_INIT_SIZE*4, C_TCP_STREAM_INIT_SIZE*8, C_TCP_STREAM_INIT_SIZE*16, C_TCP_STREAM_INIT_SIZE*32, C_TCP_STREAM_INIT_SIZE*64, C_TCP_STREAM_INIT_SIZE*128, C_TCP_STREAM_INIT_SIZE*256, C_TCP_STREAM_INIT_SIZE*512, C_TCP_STREAM_INIT_SIZE*1024, C_TCP_STREAM_INIT_SIZE*2048, C_TCP_STREAM_INIT_SIZE*4096, 0};int C_ARR_MEM_STREAM_COUNT[]={ ///测试用以下数据 /* C_MAX_STREAM_COUNT , C_MAX_STREAM_COUNT , 500 , 400, 300, 220, 150, 100, 50, 26, 11, 4, //// */ /* //实际应用以下参数 // */ //use special ip watch: C_MAX_STREAM_COUNT , 4000, //C_MAX_STREAM_COUNT ,//2k 2000,//4k 1000,//8k 700,//16k 600,//32k 500,//64k 400,//128k 300,//256k 150,//512k 40,//1M 20,//2M 10,//4M 4,//8M //*/ 0};int C_ARR_MEM_HASH_ENTRY_SIZE[]={C_ENTRY_SIZE,0};int C_ARR_MEM_HASH_ENTRY_COUNT[]={C_MAX_COUNT,0};unsigned short sport,dport;CMem *g_p_memAdm;CMem mem_hash;ST_APPDATA *g_pwdata = (ST_APPDATA*)wbuffer;CShmApply *g_p_csa_in;CShmApply *g_p_csa_out_http;CShmApply *g_p_csa_out_email;#ifdef _OUT2FILEFILE* fpout=NULL;#endif/************************************************************ * function: 输出一条流 * Author: Jay * Version: V01.00.000 * Date: 2004.04.16 * Description: 把CTCPStream一个对象转换成 char*格式输出 * param: * _ps: 要输出的流 *(去掉) _pcsa: 接收输出流的共享内存管理器 * return: * <0: 失败 * >=0: 流的长度 * ************************************************************/int outputstream(CTCPStream *_ps){ unsigned int streamlen; //int i; ST_TCP_STREAM *stream2Save=(ST_TCP_STREAM*)(wbuffer+sizeof(int)); streamlen = _ps->getStream(sizeof(int)+wbuffer+sizeof(ST_TCP_STREAM),C_MAX_TCP_STREAM_LEN); memset(stream2Save,0x00,sizeof(stream2Save)); stream2Save->src_ip = _ps->get_src_ip(); stream2Save->src_port = _ps->get_src_port(); stream2Save->dst_ip = _ps->get_dst_ip(); stream2Save->dst_port = _ps->get_dst_port(); stream2Save->isInWatch = watchip.isInWatched(stream2Save->src_ip) || watchip.isInWatched(stream2Save->dst_ip) ?1:0; //debug struct in_addr inaddr; inaddr.s_addr = _ps->get_src_ip();#ifdef _DEBUG#ifdef _OUT2FILE if (stream2Save->isInWatch == 1) { fprintf(fpout,"stream finish,SIP:%s SPORT:%hu ",inet_ntoa(inaddr),ntohs(_ps->get_src_port()));#else // printf("stream finish,SIP:%s SPORT:%hu ",inet_ntoa(inaddr),ntohs(_ps->get_src_port()));#endif inaddr.s_addr = _ps->get_dst_ip();#ifdef _OUT2FILE fprintf(fpout,"DIP:%s DPORT:%hu length:%d,receive:%d%%\n",inet_ntoa(inaddr),ntohs(_ps->get_dst_port()) ,streamlen,_ps->getReceivedRate());#else // printf("DIP:%s DPORT:%hu length:%d,receive:%d%%\n",inet_ntoa(inaddr),ntohs(_ps->get_dst_port()) // ,streamlen,_ps->getReceivedRate());#endif for (i =0;i<streamlen;i++)#ifdef _OUT2FILE { if(_ps->get_src_port() == 20480|| _ps->get_dst_port() == 20480)//ntohs(20480) = 80 fprintf(fpout,"%c",wbuffer[sizeof(int) + i+sizeof(ST_TCP_STREAM)]); } fprintf(fpout,"\n///////////////////////////////////////////////////////////////////////////////\n"); fflush(fpout);#else { // printf("%c",wbuffer[sizeof(int) + i+sizeof(ST_TCP_STREAM)]); } // printf("\n////////////////////////////////////////////////////////////////////////////////\n");#endif }#endif //end debug if (stream2Save->isInWatch == 1) { struct in_addr ins,ind; ins.s_addr = stream2Save->src_ip; ind.s_addr = stream2Save->dst_ip; char tmp[30]; strcpy(tmp,inet_ntoa(ins));#ifdef _DEBUG if(stream2Save->src_port == 20480|| stream2Save->dst_port == 20480 || stream2Save->dst_port == 47873)//ntohs(20480) = 80 { writelog("tekong out http:sip:[%s],dip:[%s]",tmp,inet_ntoa(ind)); } else { writelog("tekong out email:sip:[%s],dip:[%s]",tmp,inet_ntoa(ind)); }#endif } stream2Save->length = streamlen; g_pwdata->size = stream2Save->length + sizeof(ST_TCP_STREAM) + sizeof(int); if(stream2Save->src_port == 20480|| stream2Save->dst_port == 20480 || stream2Save->dst_port ==47873)//ntohs(20480) = 80 { g_p_csa_out_http->write(wbuffer); } else { g_p_csa_out_email->write(wbuffer); } return streamlen;}/************************************************************ * function: 输出一条流到文件 * Author: Jay * Version: V01.00.000 * Date: 2004.04.16 * Description: 把CTCPStream一个对象转换成 char*格式输出 * param: * _ps: 要输出的流 *(去掉) _pcsa: 接收输出流的共享内存管理器 * return: * <0: 失败 * >=0: 流的长度 * ************************************************************/int outputstream2File(CTCPStream *_ps){ unsigned int streamlen; //int i; ST_TCP_STREAM *stream2Save=(ST_TCP_STREAM*)(wbuffer+sizeof(int)); streamlen = _ps->getStream(sizeof(int)+wbuffer+sizeof(ST_TCP_STREAM),C_MAX_TCP_STREAM_LEN); memset(stream2Save,0x00,sizeof(stream2Save)); stream2Save->src_ip = _ps->get_src_ip(); stream2Save->src_port = _ps->get_src_port(); stream2Save->dst_ip = _ps->get_dst_ip(); stream2Save->dst_port = _ps->get_dst_port(); stream2Save->isInWatch = watchip.isInWatched(stream2Save->src_ip) || watchip.isInWatched(stream2Save->dst_ip) ?1:0; //debug struct in_addr inaddr; inaddr.s_addr = _ps->get_src_ip(); char szfilename[256]; sprintf(szfilename,"/bugstream/%s:%d:",inet_ntoa(inaddr),ntohs(_ps->get_src_port())); inaddr.s_addr = _ps->get_dst_ip(); sprintf(szfilename+strlen(szfilename),"%s:%d",inet_ntoa(inaddr),ntohs(_ps->get_dst_port())); FILE *fp; if((fp==fopen(szfilename,"w"))==NULL) return 0; stream2Save->length = streamlen; g_pwdata->size = stream2Save->length + sizeof(ST_TCP_STREAM) + sizeof(int); fwrite(wbuffer,g_pwdata->size,1,fp); fclose(fp); return streamlen;}/************************************************************ * function: 判断一条流是否该删除 * Author: Jay * Version: V01.00.000 * Date: 2004.02.23 * Description: 供hash表遍历用,格式bool func(const void*) 如果流超长或者超时则删除流,并返回true 流指针从参数传入 * param: * return: * true:是 * false:不是 * ************************************************************/bool oughtDel(const void *_ps){ if((( CTCPStream*)_ps)->isStreamTimeOut() || (( CTCPStream*)_ps)->length()>C_MAX_TCP_STREAM_LEN ) { if(((CTCPStream*)_ps)->length() > 1 && ((CTCPStream*)_ps)->getReceivedRate() > RECEIVEDRATE) outputstream((CTCPStream*)_ps); else outputstream2File((CTCPStream*)_ps); ((CTCPStream*)_ps)->clear(); if(!g_p_memAdm->free((char*)_ps) ) writelog("%s %d:free space fail!",__FILE__,__LINE__); return true; } else return false;}/************************************************************ * Function: run * Author: Jay * Version: V01.00.000 * Date: 2004.01.13 * Description: 从前一层获取IP包,组合成完整 * TCP流,然后放进下一层的缓冲区 * (Hash表版) ************************************************************/void run( key_t _rkey,key_t _wkey_http,key_t _wkey_email,key_t _key_wip, int _rsize,int _wsize_http,int _wsize_email,int _size_wip){ printf ("radius key:%d,radius size:%d\n",_key_wip,_size_wip);#ifdef _OUT2FILE fpout = fopen("out.dat","w");#endif char rbuffer[C_MAX_PACKET_BUFFER][NETMON_IP_MTU]; int time_last_check_timeout=time(NULL); //unsigned int streamlen; //struct in_addr inaddr; CHashtable *hashtable ; //CHashtable g_hashtable(&mem_hash,C_MAX_COUNT,C_HASH_LOAD_FACTOR); // hashtable = &g_hashtable; int buff_counter,k; int iPacketCounter = 0;//增加一定数目的包后,扫描所有流,把超时的流删掉 int result; CTCPStream *ps; IP_PACKET *pip=NULL; TCP_PACKET *ptcp=NULL; CLongInt li; //int iptype; if (watchip.init (_key_wip,_size_wip) !=0) { writelog ("init watchip fail!"); return ; } //初始化内存管理相关变量 if(!mem_hash.init(C_ARR_MEM_HASH_ENTRY_COUNT,C_ARR_MEM_HASH_ENTRY_SIZE)) { writelog("init mem_hash fail!"); return; } printf("hashtable use:"); mem_hash.showTotalBytes(); hashtable = new CHashtable(&mem_hash,C_MAX_COUNT,C_HASH_LOAD_FACTOR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -