📄 smtpparser.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/delay.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 "smtpparser.h"
#include "createDir.h"
#include "function.h"
extern GVAR gVar;
void inline MailHashHandle( PDOUBLE_LIST_PACKET pItem );
char inline SmtpHashOp(PDOUBLE_LIST_PACKET pItem);
char inline SmtpHashHeadOp( PDOUBLE_LIST_HEAD pSmtpHashBucket ,PDOUBLE_LIST_PACKET pItem );
char inline SmtpHashItemOp( PSMTP_HASH_HEAD pSmtpHashHead ,PDOUBLE_LIST_PACKET pItem );
int inline FindDot( PSMTP_HASH_HEAD pSmtpHashHead, PDOUBLE_LIST_PACKET pItem );
//#define _SMTP_POP3_DEBUG
#ifdef _SMTP_POP3_DEBUG
char message[ 256 ];
#endif
int SmtpParser( void *arg )
{
PDOUBLE_LIST_PACKET pItem;
DOUBLE_LIST_HEAD listHead;
PTHREAD_CONTROL pControl = (PTHREAD_CONTROL)arg;
_InitializeList( &listHead );
daemonize( "smtp_pop3" );
allow_signal(SIGTERM);
while( !signal_pending (current) )
{
//Get SMTP TCP packet
if( gVar.pSmtpQueque->iNumber == 0 )
{
schedule();
continue;
}
_InitializeList( &listHead );
_RemoveTotalList( gVar.pSmtpQueque, &listHead );
pItem = (PDOUBLE_LIST_PACKET)_RemoveTailListNonLock(&listHead);
while( pItem )
{
//insert the item into smtp hash
if( !SmtpHashOp( pItem ) )
{
//put pItem to the Leisure pool
PutPacketPool( pItem );
}
pItem = (PDOUBLE_LIST_PACKET)_RemoveTailListNonLock(&listHead);
}
schedule();
}
complete_and_exit( &pControl->thread_exited, 1 );
return 0;
}
char inline SmtpHashOp(PDOUBLE_LIST_PACKET pItem)
{
struct iphdr* pIPHeader;
struct tcphdr* pTCPHeader;
UINT iHash;
pIPHeader = (struct iphdr *)pItem->packet.buf;
pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + pIPHeader->ihl * 4 );
if( IS_FROM_CLIENT( pItem->packet.type ) )
{
iHash = ( pIPHeader->saddr - pTCPHeader->source ) % _MAX_SMTP_HASH_BUCKET;
}
else
{
iHash = ( pIPHeader->daddr - pTCPHeader->dest ) % _MAX_SMTP_HASH_BUCKET;
}
if( gVar.pSmtpHash[ iHash ] == NULL )
{
printk("Not find the hash bucket: gVar.pSmtpHash[%d]\r\n", iHash);
return false;
}
if( !SmtpHashHeadOp( gVar.pSmtpHash[ iHash ], pItem ) )
return false;
return true;
}
char inline SmtpHashHeadOp( PDOUBLE_LIST_HEAD pSmtpHashBucket,
PDOUBLE_LIST_PACKET pItem )
{
struct iphdr* pIPHeader;
struct tcphdr* pTCPHeader;
PSMTP_HASH_HEAD pSmtpHashHead;
PSMTP_HASH_HEAD pOKHashHead = NULL;
char *pBegin, *pEnd;
pIPHeader = (struct iphdr *)pItem->packet.buf;
pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + pIPHeader->ihl * 4 );
down_interruptible( &pSmtpHashBucket->fastMutex );
pSmtpHashHead = (PSMTP_HASH_HEAD)pSmtpHashBucket->pHead;
if( IS_FROM_CLIENT( pItem->packet.type ) )
{
while( pSmtpHashHead )
{
if( pTCPHeader->source == pSmtpHashHead->sPort
&& pIPHeader->saddr == pSmtpHashHead->sIP )
{
break;
}
pSmtpHashHead = (PSMTP_HASH_HEAD)pSmtpHashHead->item.pNext;
}
if( pSmtpHashHead == NULL )
{
//the hash bucket begin here
pSmtpHashHead = (SMTP_HASH_HEAD *)ALLOCATE_HASHHEAD( GFP_ATOMIC, sizeof(SMTP_HASH_HEAD) );
if( pSmtpHashHead == NULL )
{
printk( "Allocate pSmtpHashHead fail\r\n" );
up( &pSmtpHashBucket->fastMutex );
return false;
}
InitializeSmtpHashHead( pSmtpHashHead );
pSmtpHashHead->ruleID = pItem->packet.ruleID;
pSmtpHashHead->sIP = pIPHeader->saddr;
pSmtpHashHead->sPort = pTCPHeader->source;
do_gettimeofday( &pSmtpHashHead->timeStamp );
pSmtpHashHead->timelast = pSmtpHashHead->timeStamp;
pSmtpHashHead->bFileHeader = true;
if( ++gVar.iSmtppop3Path >= gVar.Smtppop3PathNumber )
gVar.iSmtppop3Path = 0;
pSmtpHashHead->iFilePath = gVar.iSmtppop3Path;
if( IS_FROM_SMTP_CLIENT(pItem->packet.type) )
{
pSmtpHashHead->smtpPop3Type = pItem->packet.type;
}
else
{
pSmtpHashHead->smtpPop3Type = PACKET_TYPE_POP3_SERVER;
}
_InsertHeadListNonLock( pSmtpHashBucket, &pSmtpHashHead->item );
#ifdef _SMTP_POP3_DEBUG
sprintf( message, "new client src : %x; port : %x \r\n",
ntohl( pIPHeader->saddr ), ntohs( pTCPHeader->source ) );
WriteLogFile( message );
printk( "%s", message );
#endif
}
#ifdef _SMTP_POP3_DEBUG
sprintf( message, "client " );
WriteLogFile( message );
printk( "%s", message );
#endif
//匹配规则
if( pItem->packet.dataLen > 10 )
{
switch( *( (UINT *)(pItem->packet.buf + pItem->packet.dataOffset ) ) )
{
//MAIL FROM:
case 0x4d41494c:
case 0x4c49414d:
pBegin = strstr( pItem->packet.buf+pItem->packet.dataOffset, "<");
if( pBegin )
{
pBegin++;
pEnd = strstr( pBegin, ">");
if( pEnd )
{
*pEnd = '\0';
pItem->packet.ruleID = MatchRule( pBegin, strlen(pBegin), RULE_PROTOCOL_MAIL, pIPHeader->saddr,
( pSmtpHashHead->iUserLen != 0 ) );
*pEnd = '>';
}
}
break;
//RCPT TO:
case 0x52435054:
case 0x54504352:
pBegin = strstr( pItem->packet.buf+pItem->packet.dataOffset, "<");
if( pBegin )
{
pBegin++;
pEnd = strstr( pBegin, ">");
if( pEnd )
{
*pEnd = '\0';
pItem->packet.ruleID = MatchRule( pBegin, strlen(pBegin), RULE_PROTOCOL_MAIL, pIPHeader->saddr,
( pSmtpHashHead->iUserLen != 0 ) );
*pEnd = '>';
}
}
break;
default:
break;
}
}
}
else
{
while( pSmtpHashHead )
{
if( pTCPHeader->dest == pSmtpHashHead->sPort
&& pIPHeader->daddr == pSmtpHashHead->sIP )
break;
pSmtpHashHead = (PSMTP_HASH_HEAD)pSmtpHashHead->item.pNext;
}
if( pSmtpHashHead == NULL )
{
pSmtpHashHead = (SMTP_HASH_HEAD *)ALLOCATE_HASHHEAD( GFP_ATOMIC, sizeof(SMTP_HASH_HEAD) );
if( pSmtpHashHead == NULL )
{
printk("Allocate pSmtpHashHead fail\r\n");
up( &pSmtpHashBucket->fastMutex );
return false;
}
InitializeSmtpHashHead( pSmtpHashHead );
pSmtpHashHead->ruleID = pItem->packet.ruleID;
pSmtpHashHead->sIP = pIPHeader->daddr;
pSmtpHashHead->sPort = pTCPHeader->dest;
do_gettimeofday( &pSmtpHashHead->timeStamp );
pSmtpHashHead->timelast = pSmtpHashHead->timeStamp;
pSmtpHashHead->bFileHeader = true;
if( ++gVar.iSmtppop3Path >= gVar.Smtppop3PathNumber )
gVar.iSmtppop3Path = 0;
pSmtpHashHead->smtpPop3Type = PACKET_TYPE_POP3_SERVER;
_InsertHeadListNonLock( pSmtpHashBucket, &pSmtpHashHead->item );
#ifdef _SMTP_POP3_DEBUG
sprintf( message, "new server dest : %x; port : %x \r\n", ntohl( pIPHeader->daddr ),
ntohs( pTCPHeader->dest ) );
WriteLogFile( message );
printk( "%s", message );
#endif
}
#ifdef _SMTP_POP3_DEBUG
sprintf( message, "server " );
WriteLogFile( message );
printk( "%s", message );
#endif
}
if( pSmtpHashHead->iEml > 20 )
{
//主要是为了停止垃圾邮件
up( &pSmtpHashBucket->fastMutex );
return false;
}
if( pSmtpHashHead->ruleID == 0 && pItem->packet.ruleID != 0 )
pSmtpHashHead->ruleID = pItem->packet.ruleID;
do_gettimeofday( &pSmtpHashHead->timelast );
pSmtpHashHead->susTotalBytes += pItem->packet.len;
if( IS_FROM_POP3_CLIENT( pItem->packet.type ) )
{
#ifdef _SMTP_POP3_DEBUG
sprintf( message, "\r\n" );
WriteLogFile( message );
printk( "%s", message );
#endif
SetPop3UserAndPass( pSmtpHashHead, pItem );
up( &pSmtpHashBucket->fastMutex );
return false;
}
if( !SmtpHashItemOp( pSmtpHashHead, pItem ) )
{
#ifdef _SMTP_POP3_DEBUG
sprintf( message, "\r\n" );
WriteLogFile( message );
printk( "%s", message );
#endif
up( &pSmtpHashBucket->fastMutex );
return false;
}
#ifdef _SMTP_POP3_DEBUG
sprintf( message, "\r\n" );
WriteLogFile( message );
printk( "%s", message );
#endif
if( pSmtpHashHead->iPart > 0 && pSmtpHashHead->iPart++ > _MAX_SMTP_HASH_PART_NUMBER)
{
pSmtpHashHead->type |= SMTP_HASH_TYPE_PART;
}
if( pSmtpHashHead->bFileHeader )
{
if( pSmtpHashHead->iSeqCount > _MAX_HASH_PRE_WRITE_COUNT
&& pSmtpHashHead->iSeqLen > _MAX_HASH_PRE_WRITE_LEN )
{
pSmtpHashHead->type |= SMTP_HASH_TYPE_PREW;
pSmtpHashHead->bPrew = 1;
}
}
else
{
if( pSmtpHashHead->iSeqLen > _MAX_HASH_PRE_WRITE_LEN )
{
pSmtpHashHead->type |= SMTP_HASH_TYPE_PREW;
pSmtpHashHead->bPrew = 1;
}
}
#ifdef _SMTP_POP3_DEBUG
if( pSmtpHashHead->type & SMTP_HASH_TYPE_DOT )
{
sprintf( message, "find the dot\r\n" );
WriteLogFile( message );
printk( "%s", message );
}
#endif
if( pSmtpHashHead->type & SMTP_HASH_TYPE_DOT &&
pSmtpHashHead->type & SMTP_HASH_TYPE_SEQ &&
pSmtpHashHead->type & SMTP_HASH_TYPE_FIN )
{
pOKHashHead = pSmtpHashHead;
_RemoveItemNonLock( pSmtpHashBucket, &pSmtpHashHead->item);
}
else if( ( pSmtpHashHead->type == NON_REMOVE_HASHHEAD_WRITE )
|| ( pSmtpHashHead->type & SMTP_HASH_TYPE_PREW ) )
{
if( pSmtpHashHead->type & SMTP_HASH_TYPE_PREW )
pSmtpHashHead->nextSeqNumber = ( (PDOUBLE_LIST_PACKET)pSmtpHashHead->pSeq )->packet.nextSeqNumber;
pOKHashHead = _RemoveItemFromHashHead(pSmtpHashHead);
pOKHashHead->timelast.tv_sec = pSmtpHashHead->timelast.tv_sec;
pOKHashHead->timelast.tv_usec = pSmtpHashHead->timelast.tv_usec;
#ifdef _SMTP_POP3_DEBUG
sprintf( message, "move item %d\r\n", pOKHashHead->iNumber );
WriteLogFile( message );
printk( "%s", message );
#endif
if( pSmtpHashHead->pSeq == NULL && pSmtpHashHead->pHead != NULL )
{
pIPHeader = (struct iphdr *)(UCHAR *)( ( (PDOUBLE_LIST_PACKET)pSmtpHashHead->pHead )->packet.buf );
pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + pIPHeader->ihl * 4 );
if( pSmtpHashHead->nextSeqNumber == ntohl( pTCPHeader->seq ))
{
pSmtpHashHead->pSeq = pSmtpHashHead->pHead;
if( ((PDOUBLE_LIST_PACKET)pSmtpHashHead->pSeq)->bLong )
pSmtpHashHead->iSeqLen += _LONG_PACKET_LEN;
else
pSmtpHashHead->iSeqLen += _SHORT_PACKET_LEN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -