예제 #1
0
Packet* IPReassembly::getCurrentPacket(const PacketKey& key)
{
	// create a hash out of the packet key
	uint32_t hash = key.getHashValue();

	// look for this hash value in the map
	std::map<uint32_t, IPFragmentData*>::iterator iter = m_FragmentMap.find(hash);

	// hash was found
	if (iter != m_FragmentMap.end())
	{
		IPFragmentData* fragData = iter->second;

		// some data already exists
		if (fragData != NULL && fragData->data != NULL)
		{
			// create a copy of the RawPacket object
			RawPacket* partialRawPacket = new RawPacket(*(fragData->data));

			// fix IP length field
			if (fragData->packetKey->getProtocolType() == IPv4)
			{
				Packet tempPacket(partialRawPacket, IPv4);
				tempPacket.getLayerOfType<IPv4Layer>()->getIPv4Header()->totalLength = htons(fragData->currentOffset + tempPacket.getLayerOfType<IPv4Layer>()->getHeaderLen());
			}
			else
			{
				Packet tempPacket(partialRawPacket, IPv6);
				tempPacket.getLayerOfType<IPv6Layer>()->getIPv6Header()->payloadLength = fragData->currentOffset;
			}

			// create a packet object wrapping the RawPacket we've just created
			Packet* partialDataPacket = new Packet(partialRawPacket, true);

			// prepare the packet and return it
			if (key.getProtocolType() == IPv4)
			{
				IPv4Layer* ipLayer = partialDataPacket->getLayerOfType<IPv4Layer>();
				ipLayer->getIPv4Header()->fragmentOffset = 0;
				ipLayer->computeCalculateFields();
			}
			else // key.getProtocolType() == IPv6
			{
				IPv6Layer* ipLayer = partialDataPacket->getLayerOfType<IPv6Layer>();
				ipLayer->removeAllExtensions();
				ipLayer->computeCalculateFields();
			}

			return partialDataPacket;
		}
	}

	return NULL;
}
예제 #2
0
void  VideoChannel::onReceive(const UInt8* pBuf, UInt32 iLen,unsigned int iSeq)
{
	if (m_bUserCancel) 
	{
		ErrTrace("VideoChannel::onReceive 已经取消操作....正在销毁...\n");
		return;
	}
		
	Packet tempPacket(-1);
	tempPacket.setContentPtr(const_cast<UInt8*>(pBuf), iLen);

	UInt16  sPacketType = ntohs(*(UInt16*)(&pBuf[2]));
	switch (sPacketType)
	{
	case VIDEO_PACKET_TYPE:
		processVideoPacket(&tempPacket);
		break;
	case VIDEO_PIECE_PACKET_TYPE:
		processVideoPiecePacket(&tempPacket);
		break;
	default:
		Assert(0);
		break;
	}

	tempPacket.setContentPtr(NULL, 0);
}
예제 #3
0
bool CBufferOutputVideoEngine::ParsePack(const UInt8* pBuf, UInt32 iLen,UInt32& iFrameSeq,UInt32& iPieceCount)
{
		//BufferTrace("CBufferOutputVideoEngine::ParsePack() begin %d\n",GetTickCount());
		Packet tempPacket(-1);
		tempPacket.setContentPtr(const_cast<UInt8*>(pBuf), iLen);

		bool bSucc = false;iPieceCount = 1;
		UInt16  sPacketType = ntohs(*(UInt16*)(&pBuf[2]));
		switch (sPacketType)
		{
		case VIDEO_PACKET_TYPE:
			ParseAllPack(&tempPacket,iFrameSeq,bSucc);
			break;
		case VIDEO_PIECE_PACKET_TYPE:
			ParsePiecePack(&tempPacket,iFrameSeq,iPieceCount,bSucc);
			break;
		default:
			Assert(0);
			break;
		}

		tempPacket.setContentPtr(NULL, 0);
		return bSucc;
}
예제 #4
0
Packet* IPReassembly::processPacket(Packet* fragment, ReassemblyStatus& status, ProtocolType parseUntil, OsiModelLayer parseUntilLayer)
{
	status = NON_IP_PACKET;

	// packet is not an IP packet
	if (!fragment->isPacketOfType(IPv4) && !fragment->isPacketOfType(IPv6))
	{
		LOG_DEBUG("Got a non-IP packet, returning packet to user");
		status = NON_IP_PACKET;
		return fragment;
	}

	// get IPv4 layer
	//IPv4Layer* ipLayer = fragment->getLayerOfType<IPv4Layer>();

	// create fragment wrapper
	IPv4FragmentWrapper ipv4Wrapper(fragment);
	IPv6FragmentWrapper ipv6Wrapper(fragment);
	IPFragmentWrapper* fragWrapper = NULL;
	if (fragment->isPacketOfType(IPv4))
		fragWrapper = &ipv4Wrapper;
	else // fragment->isPacketOfType(IPv6)
		fragWrapper = &ipv6Wrapper;

	// packet is not a fragment
	if (!(fragWrapper->isFragment()))
	{
		LOG_DEBUG("Got a non fragment packet with FragID=0x%X, returning packet to user", fragWrapper->getFragmentId());
		status = NON_FRAGMENT;
		return fragment;
	}

	// create a hash from source IP, destination IP and IP/fragment ID
	uint32_t hash = fragWrapper->hashPacket();

	IPFragmentData* fragData = NULL;

	// check whether this packet already exists in the map
	std::map<uint32_t, IPFragmentData*>::iterator iter = m_FragmentMap.find(hash);

	// this is the first fragment seen for this packet
	if (iter == m_FragmentMap.end())
	{
		LOG_DEBUG("Got new packet with FragID=0x%X, allocating place in map", fragWrapper->getFragmentId());

		// create the IPFragmentData object
		fragData = new IPFragmentData(fragWrapper->createPacketKey(), fragWrapper->getFragmentId());

		// add the new fragment to the map
		addNewFragment(hash, fragData);
	}
	else // packet was seen before
	{
		// get the IPFragmentData object
		fragData = iter->second;

		// mark this packet as used
		uint32_t* removedElement = m_PacketLRU->put(hash);
		if (removedElement != NULL)
			delete removedElement;
	}

	bool gotLastFragment = false;

	// if current fragment is the first fragment of this packet
	if (fragWrapper->isFirstFragment())
	{
		if (fragData->data == NULL) // first fragment
		{
			LOG_DEBUG("[FragID=0x%X] Got first fragment, allocating RawPacket", fragWrapper->getFragmentId());

			// create the reassembled packet and copy the fragment data to it
			fragData->data = new RawPacket(*(fragment->getRawPacket()));
			fragData->currentOffset = fragWrapper->getIPLayerPayloadSize();
			status = FIRST_FRAGMENT;

			// check if the next fragments already arrived out-of-order and waiting in the out-of-order list
			gotLastFragment = matchOutOfOrderFragments(fragData);
		}
		else // duplicated first fragment
		{
			LOG_DEBUG("[FragID=0x%X] Got duplicated first fragment", fragWrapper->getFragmentId());
			status = FRAGMENT;
			return NULL;
		}
	}

	else // not first fragment
	{
		LOG_DEBUG("[FragID=0x%X] Got fragment", fragWrapper->getFragmentId());

		uint16_t fragOffset = fragWrapper->getFragmentOffset();

		// check if the current fragment offset matches the expected fragment offset
		if (fragData->currentOffset == fragOffset)
		{
			// malformed fragment which is not the first fragment but its offset is 0
			if (fragData->data == NULL)
			{
				LOG_DEBUG("[FragID=0x%X] Fragment is malformed", fragWrapper->getFragmentId());
				status = MALFORMED_FRAGMENT;
				return NULL;
			}

			LOG_DEBUG("[FragID=0x%X] Found next matching fragment with offset %d, adding fragment data to reassembled packet", fragWrapper->getFragmentId(), (int)fragOffset);

			// copy fragment data to reassembled packet
			fragData->data->reallocateData(fragData->data->getRawDataLen() + fragWrapper->getIPLayerPayloadSize());
			fragData->data->appendData(fragWrapper->getIPLayerPayload(), fragWrapper->getIPLayerPayloadSize());

			// update expected offset
			fragData->currentOffset += fragWrapper->getIPLayerPayloadSize();

			// if this is the last fragment - mark it
			if (fragWrapper->isLastFragment())
				gotLastFragment = true;
			else
				// if not the last fragment - check if the next fragments are waiting in the out-of-order list
				gotLastFragment = matchOutOfOrderFragments(fragData);
		}
		// if current fragment offset is larger than expected - this means this fragment is out-of-order
		else if (fragOffset > fragData->currentOffset)
		{
			LOG_DEBUG("[FragID=0x%X] Got out-of-ordered fragment with offset %d (expected: %d). Adding it to out-of-order list", fragWrapper->getFragmentId(), (int)fragOffset, (int)fragData->currentOffset);

			// create a new IPFragment and copy the fragment data and params to it
			IPFragment* newFrag = new IPFragment();
			newFrag->fragmentOffset = fragWrapper->getFragmentOffset();
			newFrag->fragmentData = new uint8_t[fragWrapper->getIPLayerPayloadSize()];
			newFrag->fragmentDataLen = fragWrapper->getIPLayerPayloadSize();
			memcpy(newFrag->fragmentData, fragWrapper->getIPLayerPayload(), newFrag->fragmentDataLen);
			newFrag->lastFragment = fragWrapper->isLastFragment();

			// store the IPFragment in the out-of-order fragment list
			fragData->outOfOrderFragments.pushBack(newFrag);

			status = OUT_OF_ORDER_FRAGMENT;
			return NULL;
		}
		else
		{
			LOG_DEBUG("[FragID=0x%X] Got a fragment with an offset that was already seen: %d (current offset is: %d), probably duplicated fragment", fragWrapper->getFragmentId(), (int)fragOffset, (int)fragData->currentOffset);
		}

	}

	// if seen the last fragment
	if (gotLastFragment)
	{
		LOG_DEBUG("[FragID=0x%X] Reassembly process completed, allocating a packet and returning it", fragWrapper->getFragmentId());
		fragData->deleteData = false;

		// fix IP length field
		if (fragData->packetKey->getProtocolType() == IPv4)
		{
			Packet tempPacket(fragData->data, IPv4);
			tempPacket.getLayerOfType<IPv4Layer>()->getIPv4Header()->totalLength = htons(fragData->currentOffset + tempPacket.getLayerOfType<IPv4Layer>()->getHeaderLen());
		}
		else
		{
			Packet tempPacket(fragData->data, IPv6);
			tempPacket.getLayerOfType<IPv6Layer>()->getIPv6Header()->payloadLength = fragData->currentOffset;
		}

		// create a new Packet object with the reassembled data as its RawPacket
		Packet* reassembledPacket = new Packet(fragData->data, true, parseUntil, parseUntilLayer);

		if (fragData->packetKey->getProtocolType() == IPv4)
		{
			// set the fragment offset to 0
			IPv4Layer* ipLayer = reassembledPacket->getLayerOfType<IPv4Layer>();
			ipLayer->getIPv4Header()->fragmentOffset = 0;

			// re-calculate all IPv4 fields
			ipLayer->computeCalculateFields();
		}
		else
		{
			// remove fragment extension
			IPv6Layer* ipLayer = reassembledPacket->getLayerOfType<IPv6Layer>();
			ipLayer->removeAllExtensions();

			// re-calculate all IPv4 fields
			ipLayer->computeCalculateFields();
		}

		LOG_DEBUG("[FragID=0x%X] Deleting fragment data from map", fragWrapper->getFragmentId());

		// delete the IPFragmentData object and remove it from the map
		delete fragData;
		m_FragmentMap.erase(iter);
		m_PacketLRU->eraseElement(hash);
		status = REASSEMBLED;
		return reassembledPacket;
	}

	// if got to here it means this fragment is either the first fragment or a fragment in the middle. Set the appropriate status and return
	if (status != FIRST_FRAGMENT)
		status = FRAGMENT;

	return NULL;
}