www.pudn.com > PIPMasq.zip > cinward.cpp


#include "stdafx.h" 
#include "PIPMasq.h" 
 
bool getAdapterInfo( 
	const char* nicIPAddress,	// input 
	char* AdapterName,			// output 
	unsigned char*	macAddr		// output	 
); 
 
 
void DumpPacket(char *pPacket, int paketLen); 
 
////////////////////////// CInward ///////////////////////////////// 
 
CInward::CInward( 
	TableMgr*	tableMgr, 
	PortMgr*	portMgr,  
	ArpMgr*		arpMgr, 
	PingServer* pingSvr, 
	PseudIF*	pseudIF, 
	ThreadMgr*	threadMgr, 
	const char* lanIPAddr, 
	const char* wanIPAddr, 
	bool pingDown 
	) 
{ 
	memset(m_message, 0, sizeof(m_message)); 
	 
	m_tableMgr = tableMgr; 
	m_portMgr = portMgr; 
	m_arpMgr = arpMgr; 
	m_pingServer = pingSvr; 
	m_pseudIF = pseudIF; 
	m_pingDown = pingDown; 
	m_threadMgr = threadMgr; 
 
	strcpy(m_lanIPAddr, lanIPAddr); 
	strcpy(m_wanIPAddr, wanIPAddr); 
 
	m_lanIPAddr_u32 = htonl(inet_addr(m_lanIPAddr)); 
	m_wanIPAddr_u32 = htonl(inet_addr(m_wanIPAddr)); 
 
	memset(m_lanAdapterName, 0 , sizeof(m_lanAdapterName)); 
	memset(m_wanAdapterName, 0 , sizeof(m_wanAdapterName)); 
 
	if (getAdapterInfo(m_lanIPAddr, m_lanAdapterName, m_lanMacAddr)) 
		m_lanLpAdapter = PacketOpenAdapter(m_lanAdapterName); 
	else 
		return; 
 
	if (getAdapterInfo(m_wanIPAddr, m_wanAdapterName, m_wanMacAddr)) 
		m_wanLpAdapter = PacketOpenAdapter(m_wanAdapterName); 
	else 
		return; 
 
	// WAN Side only 
	PacketSetBuff(m_wanLpAdapter, RECV_BUF); 
 
#if 1 
	PacketSetReadTimeout(m_wanLpAdapter, 10000);	// 10 seconds 
	//PacketSetReadTimeout(m_wanLpAdapter, 0);	// Blocking mode 
#else 
	PacketSetReadTimeout(m_lanLpAdapter, 10000);	// 10 seconds 
	//PacketSetReadTimeout(m_lanLpAdapter, 0);	// Blocking mode 
#endif  
 
	PacketSetHwFilter(m_lanLpAdapter,NDIS_PACKET_TYPE_DIRECTED); 
 
	PacketSetHwFilter(m_wanLpAdapter,NDIS_PACKET_TYPE_PROMISCUOUS); 
 
	if((m_lanLpPacket = PacketAllocatePacket())==NULL) 
	{ 
		sprintf(m_message,"\nError:failed to allocate the LPPACKET structure.");  
		return; 
	} 
 
	if((m_wanLpPacket = PacketAllocatePacket())==NULL) 
	{ 
		sprintf(m_message,"\nError:failed to allocate the LPPACKET structure.");  
		return; 
	} 
 
	PacketInitPacket(m_wanLpPacket,(char*)m_wanBuffer, sizeof(m_wanBuffer)); 
	PacketInitPacket(m_lanLpPacket,(char*)m_lanBuffer, MAX_ETH_SIZE);	 
} 
 
CInward::~CInward() 
{ 
	PacketFreePacket(m_lanLpPacket); 
	PacketCloseAdapter(m_lanLpAdapter); 
 
	PacketFreePacket(m_wanLpPacket); 
	PacketCloseAdapter(m_wanLpAdapter); 
 
	printf(".....CInward is destructed.\n");  
//	Sleep(1000); 
} 
 
CInward::start() 
{ 
	while(1) 
	{ 
		if(PacketReceivePacket(m_wanLpAdapter,m_wanLpPacket,TRUE) == FALSE) 
		{ 
			sprintf(m_message,"Error: PacketReceivePacket failed"); 
			return false; 
		} 
		packetDelimiter(); 
 
		if (m_threadMgr->m_lifeFlag == true) 
			return false; 
 
	} 
} 
 
 
bool  
CInward::packetDelimiter() 
{ 
	ULONG	ulBytesReceived; 
	char	*pChar; 
	char	*buf; 
	u_int	off=0; 
	u_int	dataLen; 
	struct	bpf_hdr *hdr; 
	 
	ulBytesReceived = m_wanLpPacket->ulBytesReceived; 
	buf = (char *)m_wanLpPacket->Buffer;	 
	 
	off=0; 
 
	while(offbh_hdrlen; 
			 
		pChar = (char*)(buf+off);  // Top Address of thr Raw Packet 
 
		dataLen =hdr->bh_datalen; 
		off = Packet_WORDALIGN(off+dataLen); // For padding 
 
		analizeRawPacket(pChar, dataLen); 
	} 
 
	return true; 
} 
 
 
bool  
CInward::analizeRawPacket(char* pChar, int dataLen) 
{ 
	char* _pChar = pChar; 
 
	// Step.1  
	// If the packet is not IP packet, stop it 
	struct ethhdr *_ethhdr; 
	_ethhdr = (struct ethhdr *)_pChar; 
 
 
	if (_ethhdr->h_proto == htons(ETH_P_ARP)) 
	{ 
		m_arpMgr->analizeArpPacket(pChar, dataLen); 
		return true; 
	} 
	else if (_ethhdr->h_proto != htons(ETH_P_IP)) 
	{ 
		return false; 
	} 
	 
	_pChar += sizeof(struct ethhdr); 
	struct iphdr *_iphdr; 
	_iphdr = (struct iphdr *)_pChar; 
 
	// Destination IP Address is not Pseud IP Address 
	if (ntohl(_iphdr->daddr) !=  m_pseudIF->m_pseudIPAddr_u32) 
		return false; 
	 
	_pChar += sizeof(struct iphdr);	 
 
	TableEntry* pTable; 
 
	struct udphdr *_udphdr; 
	struct tcphdr *_tcphdr; 
	struct icmphdr *_icmphdr; 
 
	if (_iphdr->protocol == UDP) 
	{ 
		_udphdr = (struct udphdr *)_pChar; 
 
		if (m_tableMgr->refEntry2(UDP, _udphdr->dest, &pTable) == false) 
			return false; 
	} 
	else if (_iphdr->protocol == TCP) 
	{ 
		_tcphdr = (struct tcphdr *)_pChar; 
 
		if (m_tableMgr->refEntry2(TCP, _tcphdr->dest, &pTable) == false) 
			return false; 
	} 
	else if (_iphdr->protocol == ICMP) 
	{ 
		_icmphdr = (struct icmphdr *)_pChar; 
 
		if (_icmphdr->type == ICMP_ECHO) 
		{ 
			if (m_pingDown) 
			{ 
 
#if _NTS 
#else 
				printf("Catch a PING packet from somewhere host!!\n\n"); 
				DumpPacket(pChar, dataLen);	 
				printf("\n\n"); 
#endif 
 
				m_threadMgr->m_lifeFlag = true; 
 
 
				throw panic(); 
			} 
 
			m_pingServer->analizePingPacket(pChar, dataLen); 
			return true; 
		} 
		else // _icmphdr->type == ICMP_ECHOREPLY 
		{ 
			if (m_tableMgr->refEntry2(ICMP, _icmphdr->un.echo.id, &pTable) == false) 
				return false; 
		} 
	} 
	else 
		return false; 
 
 
	memcpy(_ethhdr->h_dest, pTable->srcMACAddr, ETH_ALEN); 
	memcpy(_ethhdr->h_source, m_lanMacAddr, ETH_ALEN); 
 
	_iphdr->daddr = pTable->srcIPAddr; 
 
	if (_iphdr->protocol == UDP) 
	{ 
		_udphdr->dest = pTable->srcPort; 
		// change expire time 
		pTable->expireTime = time(NULL) + EXPIRE_PERIOD; 
	} 
	else if (_iphdr->protocol == TCP) 
	{ 
		// For FTP active mode 
		if (_tcphdr->source == htons(FTP)) 
		{ 
			_tcphdr->ack_seq =  
				htonl(ntohl(_tcphdr->ack_seq) - pTable->diff_ack); 
		} 
 
		_tcphdr->dest = pTable->srcPort; 
		// change expire time 
		pTable->expireTime = time(NULL) + EXPIRE_PERIOD; 
	} 
	else if (_iphdr->protocol == ICMP) 
	{ 
		_icmphdr->un.echo.id = pTable->srcPort; 
		// change expire time 
		pTable->expireTime = time(NULL) + ICMP_EXPIRE_PERIOD; 
	} 
	else 
		return false; 
 
 
	///// Checksum calculation ///// 
 
	// IP checksum 
	_iphdr->check = 0; 
	_iphdr->check = in_cksum((unsigned short *)_iphdr, sizeof(struct iphdr)); 
 
 
	if (_iphdr->protocol == (UDP)) 
	{ 
		int udpDataLenInPacket =  
			ntohs(_iphdr->tot_len) - sizeof(struct iphdr) - sizeof(struct udphdr); 
 
		_udphdr->check = 0;  // Checksum should be set "0" first. 
		_udphdr->check =  
			udpchecksum(_udphdr, _iphdr, udpDataLenInPacket); 
	} 
	else if (_iphdr->protocol == (TCP)) 
	{ 
		int tcpDataLenInPacket =  
			ntohs(_iphdr->tot_len) - sizeof(struct iphdr) - sizeof(struct tcphdr); 
 
		_tcphdr->check = 0;	  // Checksum should be set "0" first. 
		_tcphdr->check =  
			tcpchecksum(_tcphdr, _iphdr, tcpDataLenInPacket); 
		 
	} 
	else if (_iphdr->protocol == ICMP) 
	{ 
		int icmpDataLenInPacket =  
			ntohs(_iphdr->tot_len) - sizeof(struct iphdr); 
		 
		_icmphdr->checksum = 0; // should be 0 
		_icmphdr->checksum =  
			in_cksum((unsigned short *)_icmphdr, icmpDataLenInPacket);	 
	} 
	else 
	{ 
		return false; 
	} 
	 
	// Release Preparation 
	PacketInitPacket(m_lanLpPacket, (void *)pChar, dataLen /*MAX_ETH_SIZE*/); 
	//PacketSetNumWrites(m_lpAdapter,1); 
 
	// Release ! 
	BOOLEAN truefalse = PacketSendPacket(m_lanLpAdapter,m_lanLpPacket,TRUE); 
 
	return true; 
}