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


// Arp.cpp : Defines the entry point for the DLL application. 
// 
 
#include "stdafx.h" 
#include "PIPMasq.h" 
 
 
// Don't forget the following next two lines before using this function 
//		WSADATA			Data; 
//		int status = WSAStartup(MAKEWORD(1,1), &Data); 
 
bool _hostnameToDotIP(const char *IPAddr, char *dotIP); 
 
bool rev_inet_addr(__u32 netByteIPAddr32, char *dotIP); 
 
 
// This is the constructor of a class that has been exported. 
// see Arp.h for the class definition 
CArp::CArp( 
	const char* srcIPAddr, 
	const char* subnetIPAddr, 
	const char* defaultGWAddr, 
	unsigned long waitTime 
) 
{  
	WSADATA			Data; 
	int status = WSAStartup(MAKEWORD(1,1), &Data); 
 
	m_CArpFlag = false; 
 
	memset(m_message, 0, sizeof(m_message)); 
 
	_hostnameToDotIP(srcIPAddr, m_ipAddr); 
 
	strcpy(m_subAddr, subnetIPAddr); 
	 
	_hostnameToDotIP(defaultGWAddr, m_defgAddr); 
 
	m_subAddr_u32 = htonl(inet_addr(m_subAddr)); 
	m_netAddr_u32 = (htonl(inet_addr(m_ipAddr)) & m_subAddr_u32); 
 
	m_waitTime = waitTime; 
 
	memset(m_adapterName, 0 , sizeof(m_adapterName)); 
	memset(m_macAddr, 0, sizeof(m_macAddr)); 
 
	if (getAdapterInfo(m_ipAddr, m_adapterName, m_macAddr)) 
		m_lpAdapter = PacketOpenAdapter(m_adapterName); 
	else 
		return; 
 
	char m_addr_string[3]; 
	memset(m_localMacAddr, 0, sizeof(m_localMacAddr)); 
	for (int i = 0; i < 5; i++) 
	{ 
		sprintf(m_addr_string,"%02x",m_macAddr[i]); 
		strcat(m_localMacAddr, m_addr_string); 
		strcat(m_localMacAddr,":"); 
	} 
				 
	sprintf(m_addr_string,"%02x",m_macAddr[5]); 
	strcat(m_localMacAddr, m_addr_string); 
 
 
	// set the network adapter in DIRECTED mode 
	PacketSetHwFilter(m_lpAdapter,NDIS_PACKET_TYPE_DIRECTED); 
 
	if((m_lpPacket = PacketAllocatePacket())==NULL) 
	{ 
		(m_message,"\nError:failed to allocate the LPPACKET structure.");  
		return; 
	} 
 
	m_lpAdapter2 = PacketOpenAdapter(m_adapterName); 
	 
	// set the network adapter in DIRECTED mode 
	PacketSetHwFilter(m_lpAdapter2,NDIS_PACKET_TYPE_DIRECTED); 
 
	if((m_lpPacket2 = PacketAllocatePacket())==NULL) 
	{ 
		sprintf(m_message,"\nError:failed to allocate the LPPACKET structure.");  
		return; 
	} 
	 
	// set a 51.2K buffer in the driver 
	PacketSetBuff(m_lpAdapter2,51200); 
 
	// set a 1 second read timeout 
	PacketSetReadTimeout(m_lpAdapter2,waitTime); 
	 
	//allocate and initialize a packet structure that will be used to 
	//receive the packets. 
	if((m_lpPacket2 = PacketAllocatePacket())==NULL){ 
		sprintf(m_message, "\nError:failed to allocate the LPPACKET structure."); 
		return; 
	} 
 
	PacketInitPacket(m_lpPacket2,(char*)m_buffer2, sizeof(m_buffer2)); 
 
	m_CArpFlag = true; 
 
	if (inet_addr(m_ipAddr) == inet_addr(m_defgAddr)) 
	{ 
		memcpy(m_defgMacAddr, m_localMacAddr, sizeof(m_localMacAddr)); 
	} 
	else if (!arpSendRecv(m_defgAddr, m_defgMacAddr)) 
		m_CArpFlag = false; 
 
	return;  
} 
 
 
bool  
CArp::arpSendRecv(__u32 hostTypeIPAddr32, char* mac_ethAlen) 
{ 
	memset(mac_ethAlen, 0, ETH_ALEN); 
 
	char macAddr[18]; 
	memset(macAddr, 0, sizeof(macAddr)); 
 
	char ipAddr[16]; 
	memset(ipAddr, 0, sizeof(ipAddr)); 
	//memcpy(ipAddr, rev_inet_addr(htonl(hostTypeIPAddr32)), sizeof(ipAddr)); 
	rev_inet_addr(htonl(hostTypeIPAddr32), ipAddr); 
 
	bool truefalse = arpSendRecv(ipAddr,macAddr); 
 
	if (truefalse == false) 
		return false; 
 
	char *token; 
	int macAddrValue; 
 
	token = strtok( macAddr, ":" ); 
	sscanf( token, "%x", &macAddrValue); 
	mac_ethAlen[0] = (u_char) macAddrValue; 
 
	for (int i = 1; i < 6; i++) 
	{ 
		token = strtok( NULL, ":" ); 
		sscanf( token, "%x", &macAddrValue); 
		mac_ethAlen[i] = (u_char) macAddrValue; 
	} 
 
 
	return true; 
} 
 
 
bool 
CArp::arpSendRecv(const char* ipAddr, char* macAddr) 
{ 
	memset(m_message, 0, sizeof(m_message)); 
 
	memset(macAddr, 0, 18);	 
 
	char _dotIP[16]; 
 
	_hostnameToDotIP(ipAddr, _dotIP); 
	if (inet_addr(_dotIP) == inet_addr(m_ipAddr)) 
	{ 
		memcpy(macAddr, m_localMacAddr, sizeof(m_localMacAddr)); 
		return true; 
	} 
 
	if (m_CArpFlag == false) 
	{ 
		sprintf(m_message, "CArp is not instanciated by CArp::CArp()"); 
		return false; 
	} 
 
	__u32 _ipAddr_u32 = htonl(inet_addr(_dotIP)); 
 
	if ((_ipAddr_u32 & m_subAddr_u32) != m_netAddr_u32 ) 
	{ 
		memcpy(macAddr, m_defgMacAddr, sizeof(m_defgMacAddr)); 
		sprintf(m_message, "Returned Default Gateway MAC Address "); 
		return true; 
	} 
 
	struct arpPacket _ar, _arr; 
 
	//// Step.1 Make Ether Header 
 
	// 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_macAddr, sizeof(m_macAddr)); 
 
	// 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_macAddr, sizeof(_ar.arphdr.ar_sha));  
 
	// Sender protocol address: 
	char _ipAddr[16]; 
	memcpy(_ipAddr, m_ipAddr, sizeof(_ipAddr));	 
 
	char *token; 
	unsigned char ipAddrValue; 
 
	token = strtok( _ipAddr, "." ); 
	sscanf( token, "%d", &ipAddrValue); 
	_ar.arphdr.ar_sip[0] = ipAddrValue; 
 
	for (int i = 1; i < 4; i++) 
	{ 
		token = strtok( NULL, "." ); 
		sscanf( token, "%d", &ipAddrValue); 
		_ar.arphdr.ar_sip[i] =ipAddrValue; 
	} 
 
	// Target hardware addresse: 00:00:00:00:00:00 
	memset(_ar.arphdr.ar_tha, 0, sizeof(_ar.arphdr.ar_tha)); 
 
	// Target protocol address: 
 
	//memcpy(_ipAddr, _hostnameToDotIP(ipAddr), sizeof(_ipAddr)); 
	_hostnameToDotIP(ipAddr, _ipAddr); 
 
	token = strtok( _ipAddr, "." ); 
	sscanf( token, "%d", &ipAddrValue); 
	_ar.arphdr.ar_tip[0] = ipAddrValue; 
 
	for (i = 1; i < 4; i++) 
	{ 
		token = strtok( NULL, "." ); 
		sscanf( token, "%d", &ipAddrValue); 
		_ar.arphdr.ar_tip[i] =ipAddrValue; 
	}	 
 
 
	// Release Preparation 
	PacketInitPacket(m_lpPacket, (void *)&_ar, sizeof(_ar)); 
	//PacketSetNumWrites(m_lpAdapter,1); 
 
	// Release ! 
	BOOLEAN truefalse = PacketSendPacket(m_lpAdapter,m_lpPacket,TRUE); 
 
    /////////// Get ARP packet /////////////// 
	 
 
	DWORD _tickCount = GetTickCount(); 
  
	//main capture loop 
	while(1) 
	{ 
		DWORD _tickCount2 = GetTickCount(); 
 
		if ( (_tickCount2 -  _tickCount) < m_waitTime )   
		{ 
			// capture the packets 
			if(PacketReceivePacket(m_lpAdapter2,m_lpPacket2,TRUE)==FALSE) 
			{ 
				sprintf(m_message,"Error: PacketReceivePacket failed"); 
				return false; 
			} 
 
			if (packetDelimiter(&_arr, _ar.arphdr.ar_tip) == true) 
			{ 
				char m_addr_string[3]; 
				memset(macAddr, 0, sizeof(char[18])); 
 
				for (int i = 0; i < 5; i++) 
				{ 
					sprintf(m_addr_string,"%02x",_arr.arphdr.ar_sha[i]); 
					strcat(macAddr, m_addr_string); 
					strcat(macAddr,":"); 
				} 
				 
				sprintf(m_addr_string,"%02x",_arr.arphdr.ar_sha[5]); 
				strcat(macAddr, m_addr_string); 
 
				return true; 
			} 
		} 
		else 
		{ 
			sprintf(m_message,"Error: Timeout happened."); 
			break; 
		} 
	} 
 
	return false; 
} 
 
 
 
 
bool  
CArp::packetDelimiter( 
	struct arpPacket *p_arp, unsigned char* ar_tip) 
{ 
	ULONG	ulBytesReceived; 
	char	*pChar; 
	char	*buf; 
	u_int	off=0; 
	u_int	dataLen; 
	struct	bpf_hdr *hdr; 
 
	ulBytesReceived = m_lpPacket2->ulBytesReceived; 
	buf = (char *)m_lpPacket2->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 
 
		if (analizeRawPacket(pChar, dataLen, p_arp, ar_tip) == true) 
			return true; 
	} 
 
	return false; 
} 
 
bool 
CArp::analizeRawPacket( 
	char *pChar, u_int dataLen, struct arpPacket *p_arp, unsigned char* ar_tip) 
{ 
	u_int	off=0; 
	char	*buf = pChar;  
 
 
	memcpy(p_arp, pChar, sizeof(struct arpPacket)); 
 
	if (p_arp->ethhdr.h_proto != htons(ETH_P_ARP)) 
	{ 
		return false; 
	} 
	 
	if( p_arp->arphdr.ar_op != htons(ARPOP_REPLY)) 
	{ 
		return false; 
	} 
 
	if (memcmp(p_arp->arphdr.ar_sip, ar_tip, sizeof(unsigned char[4])) != 0) 
	{ 
		return false; 
	} 
 
 
	return true; 
 
} 
 
		 
 
 
char*  
CArp::getLastMessage() 
{ 
	return m_message; 
} 
 
 
 
 
 
 
CArp::~CArp() 
{ 
	if (!m_CArpFlag) 
		return; 
 
	PacketFreePacket(m_lpPacket); 
	PacketCloseAdapter(m_lpAdapter); 
 
	PacketFreePacket(m_lpPacket2); 
	PacketCloseAdapter(m_lpAdapter2); 
 
 
	printf(".....CArp is finished completely.\n");  
//	Sleep(1000); 
} 
 
 
 
bool CArp::getAdapterInfo( 
	const char* nicIPAddress,	// input 
	char* AdapterName,			// output 
	unsigned char*	macAddr		// output	 
) 
{ 
	memset(m_message, 0, 1024); 
 
	WCHAR		TempBuffer[1024]; // string that contains a list of the network adapters 
	char        adapterList[Max_Num_Adapter][512]; 
	char        adapterList2[Max_Num_Adapter][512]; 
//	char		AdapterName[512];	// string that contains a list of the network adapters 
	char		AdapterName2[512]; 
//	unsigned char	macAddr[ETH_ALEN];	// MAC Address 
	__u32			ipAddr;				// IP Address 
	__u32			maskAddr;			// Mask (Subnet) Address 
 
	DWORD dwVersion=GetVersion(); 
	DWORD dwWindowsMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion))); 
 
	// Windows NT  
	if (!(!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4))) 
		return false; 
   
	ULONG		AdapterLength = 1024; 
 
	memset(TempBuffer,0, sizeof(TempBuffer)); 
	memset(adapterList,0, sizeof(adapterList)); 
	memset(adapterList2,0, sizeof(adapterList2)); 
	 
	PacketGetAdapterNames((char *)TempBuffer,&AdapterLength); 
 
	WCHAR		*temp,*temp1; 
 
	temp=TempBuffer; 
	temp1=TempBuffer; 
	 
	int i = 0; 
 
	while ((*temp!='\0')||(*(temp-1)!='\0')) 
	{ 
		if (*temp=='\0')  
		{ 
			memcpy(adapterList[i],temp1,(temp-temp1)*2); 
			temp1=temp+1; 
			i++; 
		} 
	 
		temp++; 
	} 
	  
	// Change adapterList the part of "/" to "//" for Windows NT 
	 
 
	int AdapterNum = i; 
	 
	for (i=0;i j ; k--) 
				{ 
					*(temp1 + k + 1) = *(temp1 + k);  
				} 
 
				*(temp + 1) =  0x005c;	// add "/" 
				temp++; 
				adapterList2Length++; 
			} 
			j++; 
			temp++; 
		} 
	} 
 
	__u32 nicAddr = htonl(inet_addr(nicIPAddress)); 
 
	for (i=0;ihFile == INVALID_HANDLE_VALUE)) 
			{ 
				DWORD dwErrorCode=GetLastError(); 
				sprintf(m_message,"Unable to open the driver, Error Code : %lx\n",dwErrorCode);  
	 
				return false; 
			} 
 
			// Check the Adapter Type (It should be Ethernet) 
			NetType netType; 
 
			PacketGetNetType(temp_lpAdapter, &netType); 
			if (netType.LinkType != NdisMedium802_3) 
				return false; 
			 
			// Get the MAC Address 
			PACKET_OID_DATA pod; 
 
			pod.Oid = OID_802_3_PERMANENT_ADDRESS; 
			pod.Length = ETH_ALEN /* sizeof(macAddr) */; 
 
			if (PacketRequest(temp_lpAdapter, 0, &pod) == NULL) 
			{ 
				sprintf(m_message,"\nError:failed to get MAC Address."); 
				return false; 
			} 
 
			memcpy(macAddr, pod.Data, pod.Length); 
 
			PacketCloseAdapter(temp_lpAdapter); 
 
			return true; 
		} 
	} 
	 
	sprintf(m_message,"\nError:failed to bind IP Address with NIC Adapter."); 
	return false; 
} 
 
 
bool  
CArp::isArpVaild() 
{ 
	return m_CArpFlag; 
}