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

📄 smtpparser.c

📁 Linux下面截获以态网数据包!是在内核态下面运行的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -