BOOL CARPLayer::Send(unsigned char* ppayload, int length)
{
	CIPLayer::IPLayer_HEADER ipHeader;

	memcpy( arpHeader.arpData, ppayload, length );

	BOOL isCacheAvailable = FALSE;
	list<ARP_CACHE_RECORD>::iterator cacheIter = arpCacheTable.begin();
	for(cacheIter; cacheIter != arpCacheTable.end(); cacheIter++)
	{
		if(memcmp((*cacheIter).ipAddress, targetIPAddress, 4) == 0)
		{
			isCacheAvailable = TRUE;
			break;
		}
	}

	//if cache is vaild and complete record
	if((isCacheAvailable == TRUE) && ((*cacheIter).isComplete == TRUE))
	{
		setTargetHardwareAddress((*cacheIter).ethernetAddress);
		((CEthernetLayer*)GetUnderLayer())->SetEnetDstAddress((*cacheIter).ethernetAddress);
	}
	//it is not valid record
	else
	{
		memset(arpHeader.arpTargetHardwareAddress, 0, 6);
		((CEthernetLayer*)GetUnderLayer())->SetEnetDstAddress(BROADCAST_ADDR);
	}
	
	arpHeader.arpHardwareType = 0x0100;
	arpHeader.arpProtocolType = 0x0008;
	arpHeader.arpHardwareAddrSize = 0x6;
	arpHeader.arpProtocolAddrSize = 0x4;
	arpHeader.arpOperationType = ARP_REQUEST;
	memcpy(arpHeader.arpSenderHardwareAddress, ownMACAddress, 6);
	memcpy(arpHeader.arpSenderIPAddress, ownIPAddress, 4);
	memcpy(arpHeader.arpTargetIPAddress, targetIPAddress, 4);
	
	ARP_CACHE_RECORD newRecord;
	newRecord.arpInterface = this->adapter;
	memset(newRecord.ethernetAddress, 0, 6);
	memcpy(newRecord.ipAddress, targetIPAddress, 4);
	newRecord.isComplete = FALSE;

	arpCacheTable.push_back(newRecord);

	BOOL bSuccess = FALSE ;
	bSuccess = mp_UnderLayer->Send((unsigned char*)&arpHeader,length+ARP_HEADER_SIZE);

	return bSuccess;
}
Ejemplo n.º 2
0
BOOL CARPLayer::Send(unsigned char* ppayload, int length)
{
		memcpy( arpHeader.arpData, ppayload, length );
		
		BOOL bSuccess = FALSE ;
		BOOL isCacheSameIP = FALSE;	//캐시 이용가능한지.
		BOOL isCacheSameMAC = FALSE;
		BOOL isGratuitousPacket = FALSE;	//gratuitous 발생 했는지.
		list<ARP_CACHE_RECORD>::iterator cacheIter = arpCacheTable.begin();
		if(memcmp(targetIPAddress, ownIPAddress, 4) == 0)	// gratuitous인지 확인.
			isGratuitousPacket = TRUE;
		else
		{
			for(cacheIter; cacheIter != arpCacheTable.end(); cacheIter++)// gratuitous 아니라면, cache에 있는 만큼 for구문돌림.
			{
				if(memcmp((*cacheIter).ipAddress, targetIPAddress, 4) == 0) //보내려는 ip와 같은 ip가 있다면 
				{
					isCacheSameIP = TRUE;
					break;
				}
				if(memcmp((*cacheIter).ethernetAddress, targetMACAddress, 6) == 0)
				{
					isCacheSameMAC = TRUE;
					break;
				}
			}
		}

		//if cache is vaild and complete record
		if(((isCacheSameIP == TRUE) || (isCacheSameMAC == TRUE)) && ((*cacheIter).isComplete == TRUE))	// 캐시에 사용가능한 것이 존재한다면, 
		{	
			setTargetHardwareAddress((*cacheIter).ethernetAddress);	//캐시에 있다면 mac 주소를 알게 된 것이므로, 이 mac 주소로 재설정.
			((CEthernetLayer*)GetUnderLayer())->m_sHeader.enet_type = next_ethernet_type;
			((CEthernetLayer*)GetUnderLayer())->SetEnetDstAddress((*cacheIter).ethernetAddress);// ethernet layer의 mac 주소도 다시 설정.

		}
		else if(isCacheSameIP == TRUE)
		{
		}
		//it is not valid record
		else // 캐시도 없고, gratuitous도 아니고.
		{
			memset(arpHeader.arpTargetHardwareAddress, 0, 6);
			((CEthernetLayer*)GetUnderLayer())->SetEnetDstAddress(BROADCAST_ADDR);
			((CEthernetLayer*)GetUnderLayer())->m_sHeader.enet_type = next_ethernet_type;


			ARP_CACHE_RECORD newRecord;
			newRecord.arpInterface = this->adapter;
			memset(newRecord.ethernetAddress, 0, 6);
			memcpy(newRecord.ipAddress, targetIPAddress, 4);
			newRecord.isComplete = FALSE;
			newRecord.lifeTimeCounter = INCOMPLETE_DELETE_TIME;

			arpCacheTable.push_back(newRecord);
		}
		
		if(next_ethernet_type == ETHER_PROTO_TYPE_IP)
			bSuccess = mp_UnderLayer->Send((unsigned char*)ppayload, length);
		else
		{
			// ----정리---
			// 1. Gratuitous가 맞다면, 그냥 아무 작업 하지 않고, 패킷 만들어서 보냄.
			// 2. 캐시 이용가능하다면, 캐시에 있는 값으로 맥주소 설정해서 보냄.
			// 3. 이용가능한 캐시 없고, gratitous가 아니라면 broadcast로 목적지 설정해서 보냄.

			arpHeader.arpHardwareType = 0x0100;
			arpHeader.arpProtocolType = 0x0008;
			arpHeader.arpHardwareAddrSize = 0x6;
			arpHeader.arpProtocolAddrSize = 0x4;
			arpHeader.arpOperationType = ARP_REQUEST;
			memcpy(arpHeader.arpSenderHardwareAddress, ownMACAddress, 6);
			memcpy(arpHeader.arpSenderIPAddress, ownIPAddress, 4);
			memcpy(arpHeader.arpTargetIPAddress, targetIPAddress, 4);
	

			bSuccess = mp_UnderLayer->Send((unsigned char*)&arpHeader,length+ARP_HEADER_SIZE);
		}
		return bSuccess;
}