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


#include "stdafx.h" 
#include "PIPMasq.h" 
 
////////////////////////// ArpMgr ///////////////////////////////// 
 
ArpMgr::ArpMgr(PseudIF* pseudIF) 
{ 
	m_pseudIF = pseudIF; 
 
	m_waitFlag = false; 
 
	m_arpLock_out = CreateEvent(0, FALSE, FALSE, 0); 
	m_arpLock_in = CreateEvent(0, FALSE, FALSE, 0); 
} 
 
 
ArpMgr::~ArpMgr() 
{ 
	printf(".....ArpMgr is destructed.\n");  
//	Sleep(1000); 
} 
 
bool 
ArpMgr::arpSendRecv(__u32 hostTypeIPAddr32, char* mac_ethAlen) 
{ 
	_ipAddr_u32_n = htonl(hostTypeIPAddr32); 
	_ipAddr_u32_h = hostTypeIPAddr32; 
	 
	if ((hostTypeIPAddr32 & m_pseudIF->m_subWanIPAddr_u32)  
		!= m_pseudIF->m_netWanAddr_u32 ) 
	{ 
		// return default gateway mac address 
		memcpy(mac_ethAlen, m_pseudIF->m_defaultGWMacAddr, ETH_ALEN); 
		return true; 
	} 
 
	struct arpPacket _ar; 
 
	// Destination: ff:ff:ff:ff:ff:ff (ff:ff:ff:ff:ff:ff) 
	_ar.ethhdr.h_dest[0]=0xff; 
	_ar.ethhdr.h_dest[1]=0xff; 
	_ar.ethhdr.h_dest[2]=0xff; 
	_ar.ethhdr.h_dest[3]=0xff; 
	_ar.ethhdr.h_dest[4]=0xff; 
	_ar.ethhdr.h_dest[5]=0xff;	 
 
	// Source: 
 	memcpy(_ar.ethhdr.h_source, m_pseudIF->m_pseudMacAddr, ETH_ALEN); 
 
	// Type 
	_ar.ethhdr.h_proto = htons(ETH_P_ARP); 
 
	//// Step.2 Make Arp Header + Data 
	// header 
	_ar.arphdr.ar_hrd = htons(ETH_P_802_3);		// Hardware type: Ethernet(0x0001) 
	_ar.arphdr.ar_pro = htons(ETH_P_IP);		// Protocol type: IP(0x0800) 
	_ar.arphdr.ar_hln = ETH_ALEN;				// Hardware size: 6(0x06) 
	_ar.arphdr.ar_pln = 4;						// Protocol size; 4 
	_ar.arphdr.ar_op  = htons(ARPOP_REQUEST);	// Opcode: request (0x0001) 
 
	// data 
	// Sender hardware address: 
	memcpy(_ar.arphdr.ar_sha, m_pseudIF->m_pseudMacAddr, ETH_ALEN); 
 
	// Sender protocol address: 
 
	__u32 _pseudIPAddr_u32_n = ntohl(m_pseudIF->m_pseudIPAddr_u32); 
	memcpy(_ar.arphdr.ar_sip, (void *)(&(_pseudIPAddr_u32_n)), 4); 
 
	// Target hardware addresse: 00:00:00:00:00:00 
	memset(_ar.arphdr.ar_tha, 0, sizeof(_ar.arphdr.ar_tha)); 
 
	// Target protocol address: 
	memcpy(_ar.arphdr.ar_tip, (void *)(&_ipAddr_u32_n), 4); 
 
	// Packet Release !! 
	m_pseudIF->releasePacket((void *)&_ar, sizeof(_ar)); 
	 
	// Wait ARP reply 
	m_waitFlag = true; 
 
	SetEvent(m_arpLock_in); 
	if (WaitForSingleObject(m_arpLock_out,INFINITE) != WAIT_OBJECT_0)// Wait 1 second. 
		return false; 
 
	memcpy(mac_ethAlen, m_getMacAddr, ETH_ALEN); 
 
	m_waitFlag = false; 
 
	return true; 
} 
 
bool 
ArpMgr::analizeArpPacket2(char *pChar, int dataLen) 
{ 
	if (m_waitFlag == false) 
		return false; 
	 
	struct arpPacket *p_arp = (struct arpPacket *)pChar; 
 
	if (memcmp(p_arp->arphdr.ar_sip, (void *)(&_ipAddr_u32_n), sizeof(unsigned char[4])) != 0) 
	{ 
		return false; 
	} 
 
	if (WaitForSingleObject(m_arpLock_in, 1000) != WAIT_OBJECT_0)  // Wait 1 second. 
		return false; 
		 
	memcpy(m_getMacAddr, p_arp->arphdr.ar_sha, ETH_ALEN); 
 
	SetEvent(m_arpLock_out); 
 
	return true; 
} 
 
 
 
bool 
ArpMgr::analizeArpPacket(char *pChar, int dataLen) 
{ 
	struct arpPacket *p_arp = (struct arpPacket *)pChar; 
 
	if (p_arp->arphdr.ar_op == htons(ARPOP_REPLY)) 
	{ 
		return analizeArpPacket2(pChar, dataLen); 
	} 
 
	if (p_arp->arphdr.ar_op != htons(ARPOP_REQUEST)) 
		return false; 
 
	__u32 _pseudIPAddr_n_u32 = htonl(m_pseudIF->m_pseudIPAddr_u32); 
 
	if (memcmp(p_arp->arphdr.ar_tip, &_pseudIPAddr_n_u32, sizeof(unsigned char[4])) != 0) 
		return true; 
 
	// Ethernet Address exchange 
	memcpy(p_arp->ethhdr.h_dest, p_arp->ethhdr.h_source, ETH_ALEN); 
	memcpy(p_arp->ethhdr.h_source, m_pseudIF->m_pseudMacAddr, ETH_ALEN); 
 
	// Making Arp Packet(Reply) 
	 
	// The following four lines should be same. 
	//p_arp->arphdr.ar_hrd = htons(ETH_P_802_3);	// Hardware type: Ethernet(0x0001) 
	//p_arp->arphdr.ar_pro = htons(ETH_P_IP);		// Protocol type: IP(0x0800) 
	//p_arp->arphdr.ar_hln = ETH_ALEN;				// Hardware size: 6(0x06) 
	//p_arp->arphdr.ar_pln = 4;						// Protocol size; 4 
	p_arp->arphdr.ar_op  = htons(ARPOP_REPLY);		// Opcode: request (0x0002) 
 
	/* Remote IP address		*/ 
	memcpy(p_arp->arphdr.ar_tip,  p_arp->arphdr.ar_sip, 4);	 
 
	/* Remote hardware address	*/ 
	memcpy(p_arp->arphdr.ar_tha, p_arp->ethhdr.h_dest, ETH_ALEN);	 
 
	/* Local IP address	*/ 
	memcpy(p_arp->arphdr.ar_sip, &_pseudIPAddr_n_u32, 4);	 
 
	/* Local hardware address	*/ 
	memcpy(p_arp->arphdr.ar_sha, m_pseudIF->m_pseudMacAddr, ETH_ALEN);	 
 
	// Packet Release !! 
	m_pseudIF->releasePacket(	(void *)pChar, dataLen); 
 
	return true; 
 
};