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

📄 udpparser.c

📁 Linux下面截获以态网数据包!是在内核态下面运行的驱动程序
💻 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 "createDir.h"
#include "DomainIPHash.h"
#include "Rule.h"
#include "RuleIp.h"
#include "list.h"
#include "protocol.h"
#include "UdpParser.h"
#include "function.h"

extern GVAR gVar;

int UDPAppParser( void *arg)
{
//	struct ethhdr	*pEther;
	struct iphdr	*pIpHeader;
//	struct tcphdr	*pTcpHeader;
	struct udphdr	*pUdpHeader;   

	UINT		iRead;
	UCHAR		*pPacket;
/*	PDOUBLE_LIST_PACKET pItem;
	USHORT		dataLen,dataOffset;*/

	
//	KeSetPriorityThread(   KeGetCurrentThread(), LOW_REALTIME_PRIORITY );
//	KeSetPriorityThread(   KeGetCurrentThread(), 14 );
	
	while(!gVar.CtrlThreadCtx.bParserUnload)
	{
		if( gVar.UdpCycArrayHead.iWrite.counter - gVar.UdpCycArrayHead.iRead.counter 
			< _MAX_CYC_SAFE_NUMBER )
		{
			schedule();
			continue;
		}
		
// 		spin_lock( &gVar.UdpCycArrayHead.lock );

		iRead = atomic64_read( &gVar.UdpCycArrayHead.iRead );
		atomic64_inc( &gVar.UdpCycArrayHead.iRead );
// 		spin_unlock( &gVar.UdpCycArrayHead.lock );
		
		iRead = iRead % _MAX_UDP_CYC_ARRAY_DEPTH;
		if( gVar.UdpCycArrayHead.PacketArray[ iRead ]->len > _MAX_PACKET_LEN )
		{
			continue;
		}
		
		pPacket = gVar.UdpCycArrayHead.PacketArray[ iRead ]->buf;
		
		pIpHeader = (struct iphdr * )( pPacket + sizeof(struct ethhdr));
		pUdpHeader = (struct udphdr *)( (UCHAR *)pIpHeader + pIpHeader->ihl *4 );

		//printk("Web Mail----port: %d\r\n",pUDPHeader->uh_sport);
		if( ( gVar.UdpCycArrayHead.PacketArray[ iRead ]->len - sizeof(struct ethhdr)
			- pIpHeader->ihl * 4 ) < ntohs( pUdpHeader->len ) )
					continue;
		switch( gVar.UdpCycArrayHead.PacketArray[ iRead ]->AppType )
		{
#ifdef ADD_WEBMAIL_FUN
		case APP_TYPE_DNS:
			//printk( "Web Mail----sizeof(struct ether_header):%d\r\n", sizeof(struct ether_header));
			//printk( "len:%d udp len:%d\r\n",(gVar.pUDPCycArrayHead->pPacket[iRead].len-sizeof(struct ether_header)-(pIPHeader->ip_hl)*4),pUDPHeader->uh_ulen);
			ParserDns( ((char *)pUdpHeader) + sizeof(struct udphdr),
				ntohs(pUdpHeader->len) - sizeof(struct udphdr) );
			break;
#endif//ADD_WEBMAIL_FUN

#ifdef ADD_QQ_FUN
		case APP_TYPE_QQ:
			if( sizeof( QQ_PACKET ) > ntohs(pUdpHeader->len) )
				break;
			ParserQQ( (char *)pIpHeader, gVar.UdpCycArrayHead.Packet[iRead].ruleID );
			break;
#endif//ADD_QQ_FUN				
		default:
			break;
		}
	}
	
	return 0;	
}

void ParserDns( char *pDns, USHORT len )
{
	char *pDomain = NULL;
	char *p = NULL;
	USHORT i;
	USHORT ansNumber = 0;
	PDNS_HDR pDnsHdr;
	PDNS_Q_TYPE pQType;
	PDNS_ANSWER pDnsAns;
	PDOMAIN_HASH_BUCKET pDomainHash = NULL;
	struct in_address *pIP;
//	PWEB_MAIL_CONFIG pConfig = NULL;
	
	pDnsHdr = (PDNS_HDR)pDns;
	
	if( pDnsHdr->dh_flags != STD_Q_NO_ERROR || pDnsHdr->dh_as == 0 )
		return;
	
	ansNumber = ntohs(pDnsHdr->dh_as);
	pDomain = (char *)pDnsHdr->payload;
	
	//printk("domain:%s\r\n", pDomain );
	pDomainHash = FindDomain( pDomain, NULL );
	if( pDomainHash == NULL  )
	{
		//printk("not find domain:%s\r\n", pDomain );
		return;
	}

	if( pDomainHash->state == DOMAIN_STATE_INVALIDATE )
	{
		//域名已经无效
		printk("Invalidate domain:%s\r\n", pDomainHash->payload );
		return;
	}
		
	p = pDomain;
	while( *( (UCHAR *)p ) && (USHORT)(p-pDns) < len )
	{
		p += *( (UCHAR *)p ) + 1;
	} 
	p++;
	if( len < (USHORT)( p - pDns ) )
		return;

	pQType = (PDNS_Q_TYPE)p;
	if( pQType->da_type != TYPE_A || pQType->da_class != CLASS_IN )
		return;
	
	p += sizeof( DNS_Q_TYPE );
	if( len < (USHORT)(p+sizeof(DNS_ANSWER)-pDns) )
		return;
	pDnsAns = (PDNS_ANSWER)p;
	
	for( i=0; i<ansNumber; i++)
	{
		if( pDnsAns->da_type == TYPE_A 
			&& pDnsAns->da_class == CLASS_IN
			&& pDnsAns->da_len == IP_LEN )
		{
			pIP = (struct in_address *)(p+sizeof(DNS_ANSWER));
			if( IP_TYPE_POST & pDomainHash->type )
			{
				//将该服务器IP加入到规则IP HASH表
				AddRuleIP( *(UINT *)pIP, pDomainHash->ruleID, true, 0);
/*				printk( "Web Post----HOST:%s  :%d.%d.%d.%d\r\n", 
					pDomain, pIP->s_net, pIP->s_host, pIP->s_lh, pIP->s_impno );*/
			}

			if( IP_TYPE_POST != pDomainHash->type )
			{
				AddIPHash( *(UINT *)pIP, pDomainHash->type, pDomainHash->pConfig );
/*				printk( "Web Mail----HOST:%s  :%d.%d.%d.%d\r\n",
					pDomain, pIP->s_net, pIP->s_host, pIP->s_lh, pIP->s_impno );*/
			}
		}

		p += sizeof(DNS_ANSWER);
		p += ntohs(pDnsAns->da_len);
		
		if( len < (USHORT)(p-pDns) )
			return;		
		
		pDnsAns = (PDNS_ANSWER)p;	
	}
}

void ParserQQ( char *p, UINT ruleID)
{
//	static UINT		iNumber=0;
//	static UINT		iFile=0;	
	PQQ_PACKET 		pQQ = NULL;
	PSMTP_HASH_HEAD pQQHashHead = NULL;
	struct iphdr	*pIPHeader;    // See ip.h
	struct udphdr	*pUDPHeader;   
	UINT			qq = 0;
	
	pIPHeader = (struct iphdr *)p;
	pUDPHeader = (struct udphdr *)( (UCHAR *)pIPHeader + (pIPHeader->ihl)*4 );
	pQQ = (PQQ_PACKET )((char *)pUDPHeader+sizeof(struct udphdr));
	switch( pQQ->flag )
	{
	case 0x02:
		if( pQQ->com == QQ_COM_LOGIN )
		{
			pQQHashHead = ALLOCATE_HASHHEAD( GFP_ATOMIC, sizeof(SMTP_HASH_HEAD) );
			if( pQQHashHead == NULL )
				return;

			InitializeSmtpHashHead( pQQHashHead );	
			pQQHashHead->timelast 	= gVar.gSysCurTime;
			pQQHashHead->sIP 		= pIPHeader->saddr;
			pQQHashHead->dIP 		= pIPHeader->daddr;
			qq = ntohl(pQQ->qq);
			sprintf( pQQHashHead->user, "%u", qq );
			pQQHashHead->type = IM_HASH_TYPE_LOGIN;
			//if( ruleID == 0 )
				pQQHashHead->ruleID = MatchRule( &qq, 0, RULE_PROTOCOL_QQ, pIPHeader->saddr,false);
			//else
				//pQQHashHead->ruleID = ruleID;
//			WriteImLogOneFile( pQQHashHead, &iNumber, &iFile, APP_TYPE_QQ);

			FREE_HASHHEAD( pQQHashHead );
		}
		else if( pQQ->com == QQ_COM_LOGOUT )
		{
			pQQHashHead = ALLOCATE_HASHHEAD(  GFP_ATOMIC, sizeof(SMTP_HASH_HEAD));
			if( pQQHashHead == NULL )
				return;

			InitializeSmtpHashHead( pQQHashHead );	
			pQQHashHead->timelast = gVar.gSysCurTime;
			pQQHashHead->sIP = pIPHeader->saddr;
			pQQHashHead->dIP = pIPHeader->daddr;
			qq = ntohl(pQQ->qq);
			sprintf( pQQHashHead->user, "%u", qq );
			pQQHashHead->type = IM_HASH_TYPE_LOGOUT;
			//if( ruleID == 0 )
				pQQHashHead->ruleID = MatchRule( &qq, 0, RULE_PROTOCOL_QQ, pIPHeader->saddr,false );
			//else
				//pQQHashHead->ruleID = ruleID;			
//			WriteImLogOneFile( pQQHashHead, &iNumber, &iFile, APP_TYPE_QQ);

			FREE_HASHHEAD( pQQHashHead );			
		}
		break;
	default:
		break;
	}

}

⌨️ 快捷键说明

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