Example #1
0
MEDIACODEC_API MediaPacket_t* ReadNextPacket(MediaFormatContext_t* ctx){
	MediaPacket_t* pkt = NULL;
	
	while(1){
		pkt = AllocPacket();
		if( pkt == NULL){
			return NULL;
		}
		if( av_read_frame((AVFormatContext*)ctx->fc, (AVPacket*)pkt->pkt) <0 ){
			FreePacket(pkt,0); //并没有释放内部的packet数据
			//printf("read_fream error!\n");
			return NULL;
		}
		
		int64_t pts;
		pts = pkt->pkt->pts;
		if( pts == 0){
			pts = pkt->pkt->dts;
		}
		pts *= (ctx->video.tb_num/(ctx->video.tb_den*1.0));
		//printf("elapsed time:%d, pts:%d,dts:%d\n",pts,pkt->pkt->pts,pkt->pkt->dts)	;

		if( ctx->video.videostream == pkt->pkt->stream_index){
			pkt->data = pkt->pkt->data;
			pkt->size = pkt->pkt->size; 
			pkt->stream = pkt->pkt->stream_index;
			pkt->duration = pts; //pkt->pkt->duration;
			
			return pkt;	
		}		
		FreePacket(pkt,1);
	}

	return NULL;
}
Example #2
0
// Release the Layer-3 interface
void L3FreeInterface(L3IF *f)
{
	UINT i;
	L3PACKET *p;
	PKT *pkt;
	// Validate arguments
	if (f == NULL)
	{
		return;
	}

	for (i = 0;i < LIST_NUM(f->ArpTable);i++)
	{
		L3ARPENTRY *a = LIST_DATA(f->ArpTable, i);
		Free(a);
	}
	ReleaseList(f->ArpTable);
	f->ArpTable = NULL;

	for (i = 0;i < LIST_NUM(f->ArpWaitTable);i++)
	{
		L3ARPWAIT *w = LIST_DATA(f->ArpWaitTable, i);
		Free(w);
	}
	ReleaseList(f->ArpWaitTable);
	f->ArpWaitTable = NULL;

	while (p = GetNext(f->IpPacketQueue))
	{
		Free(p->Packet->PacketData);
		FreePacket(p->Packet);
		Free(p);
	}
	ReleaseQueue(f->IpPacketQueue);
	f->IpPacketQueue = NULL;

	for (i = 0;i < LIST_NUM(f->IpWaitList);i++)
	{
		L3PACKET *p = LIST_DATA(f->IpWaitList, i);
		Free(p->Packet->PacketData);
		FreePacket(p->Packet);
		Free(p);
	}
	ReleaseList(f->IpWaitList);
	f->IpWaitList = NULL;

	while (pkt = GetNext(f->SendQueue))
	{
		Free(pkt->PacketData);
		FreePacket(pkt);
	}
	ReleaseQueue(f->SendQueue);
	f->SendQueue = NULL;
}
void LDBServerConnectToMasterServer::ProcessRecvedPacket()
{
	m_unPacketProcess = 0;
	for (unsigned int unIndex = 0; unIndex < m_unMaxPacketProcessOnce; ++unIndex)
	{
		LPacketSingle* pPacket = GetOneRecvedPacket();
		if (pPacket == NULL)
		{
			return ;
		}

		m_unPacketProcess++;

		if (pPacket->GetPacketType() == 1)
		{
			LPacketSingle* pPacket = GetOneSendPacketPool(120);
			pPacket->SetPacketID(Packet_SS_Start_Req);
			AddOneSendPacket(pPacket);
		}
		else
		{ 
			//	调用处理函数
			E_DBServer_Packet_From_Type eFromType = E_DBServer_Packet_From_Master;
			m_pDBServerMainLogic->GetPacketProcessManager()->DispatchMessageProcess(0, pPacket, eFromType);
		}
		FreePacket(pPacket);
	}
}
Example #4
0
void CutupProtocol::FreePackets( PCP_PACKET* ppPackets, DWORD dwPacketCount ) const
{
	for (DWORD i = 0; i < dwPacketCount; i++)
	{
		FreePacket(ppPackets[i]);
	}
}
Example #5
0
// Send an IP packet
void L3SendIp(L3IF *f, L3PACKET *p)
{
	L3ARPENTRY *a = NULL;
	bool broadcast = false;
	IPV4_HEADER *ip;
	bool for_me = false;
	// Validate arguments
	if (f == NULL || p == NULL)
	{
		return;
	}
	if (p->Packet->TypeL3 != L3_IPV4)
	{
		return;
	}

	ip = p->Packet->L3.IPv4Header;

	// Determining whether it's a broadcast
	if (p->NextHopIp == 0xffffffff ||
		((p->NextHopIp & f->SubnetMask) == (f->IpAddress & f->SubnetMask)) &&
		((p->NextHopIp & (~f->SubnetMask)) == (~f->SubnetMask)))
	{
		broadcast = true;
	}

	if (broadcast == false && ip->DstIP == f->IpAddress)
	{
		// me?
	}
	else if (broadcast == false)
	{
		// Examine whether the ARP entry contains this in the case of unicast
		a = L3SearchArpTable(f, p->NextHopIp);

		if (a == NULL)
		{
			// Since It is not in the ARP table,
			// insert it into the IP waiting list without sending immediately
			p->Expire = Tick64() + IP_WAIT_FOR_ARP_TIMEOUT;

			Insert(f->IpWaitList, p);

			// Issue an ARP query
			L3SendArp(f, p->NextHopIp);
			return;
		}
	}

	if (for_me == false)
	{
		// Send the IP packet
		L3SendIpNow(f, a, p);
	}

	// Release the packet
	Free(p->Packet->PacketData);
	FreePacket(p->Packet);
	Free(p);
}
Example #6
0
int SDLNet_UDP_Recv(UDPsocket socket, UDPpacket* result) {
  //fprintf(stderr, "SDLNet_UDP_Recv [socket=%p, maxlen=%u]\n", socket, result->maxlen);

  UDPsocket_Impl* impl = ToImpl(socket);
  for (int i = 1; i >= 0; --i) {  // check in reverse order
    if (impl->channels[i].packet_head) {
      UDPpacket* packet = impl->channels[i].packet_head; 

      //fprintf(stderr, "  ... found packet on channel=%u\n", i);

      if (packet->len > result->maxlen) {
        fprintf(stderr, "need to support partial recv!\n");
        return -1;
      }

      result->address = impl->channels[i].address;
      result->channel = i;
      memcpy(result->data, packet->data, packet->len);
      result->len = packet->len;

      SListPopFront(&impl->channels[i].packet_head,
                    &impl->channels[i].packet_tail);

      FreePacket(packet);
      return 1;
    }
  }

  return -1;
}
Example #7
0
void CutupProtocol::CreateEmptyPacket( ByteBuffer& data ) const
{
	PCP_PACKET pPacket = CreatePacket(0, 0, CPCMD_NO_DATA, NULL, 0);
	DWORD dwPacketSize = PACKET_SIZE(pPacket);
	data.Alloc(dwPacketSize);
	memcpy(data, pPacket, dwPacketSize);
	FreePacket(pPacket);
}
Example #8
0
void CutupProtocol::GetDataFromSendMsg( SEND_MSG& sendMsg, DWORD dwMaxSize, ByteBuffer& byteData, COMM_NAME* pExpectedComm /*= NULL*/ )
{
	if (dwMaxSize == 0) dwMaxSize = sendMsg.dwDefaultPacketMaxSize;
	if (NULL != pExpectedComm) *pExpectedComm = sendMsg.expectedCommName;

	_time64(&sendMsg.lastGetDataTime);

	if (sendMsg.bData)
	{
		DWORD dwReadSize = min(dwMaxSize, sendMsg.byteData.Size() - sendMsg.params.dataParams.dwNextSendPos);
		DWORD dwNextSendPos = sendMsg.params.dataParams.dwNextSendPos + dwReadSize;
		BOOL bSentAll = (dwNextSendPos >= sendMsg.byteData.Size());
		BYTE cmd = bSentAll ? CPCMD_DATA_END : CPCMD_DATA_MORE;

		PCP_PACKET pPacket = CreatePacket(sendMsg.serial, sendMsg.params.dataParams.dwNextIndex, 
			cmd, (LPBYTE)sendMsg.byteData + sendMsg.params.dataParams.dwNextSendPos, dwReadSize);
		pPacket->ToByteBuffer(byteData);
		FreePacket(pPacket);

		if (! bSentAll)
		{
			//还有未发完的数据
			sendMsg.params.dataParams.dwNextIndex++;
			sendMsg.params.dataParams.dwNextSendPos = dwNextSendPos;
		}
		else
		{
			//内容已经全部发出,记录时间,随后清除,保留一段时间以备重发的请求
			sendMsg.bAllSent = TRUE;
			_time64(&sendMsg.finishTime);
		}
	}
	else
	{
		//如果是packet类型的数据,byteData字段不能过长,这里就不再切分了
		PCP_PACKET pPacket = CreatePacket(sendMsg.serial, sendMsg.params.packetParams.index, sendMsg.params.packetParams.cmd,
			sendMsg.byteData, sendMsg.byteData.Size());
		pPacket->ToByteBuffer(byteData);
		FreePacket(pPacket);

		//下次清理掉
		sendMsg.bAllSent = TRUE;
		sendMsg.finishTime = 0;
	}
}
Example #9
0
void CutupProtocol::FreePackets( PacketList& packetList ) const
{
	PacketList::iterator iter = packetList.begin();
	for (; iter != packetList.end(); iter++)
	{
		FreePacket(*iter);
	}

	packetList.clear();
}
Example #10
0
// Process the Layer 2 packet
void L3RecvL2(L3IF *f, PKT *p)
{
	// Validate arguments
	if (f == NULL || p == NULL)
	{
		return;
	}

	// Ignore any packets except a unicast packet which is destinated other
	// or a packet which I sent
	if (Cmp(p->MacAddressSrc, f->MacAddress, 6) == 0 ||
		(p->BroadcastPacket == false && Cmp(p->MacAddressDest, f->MacAddress, 6) != 0))
	{
		// Release the packet
		Free(p->PacketData);
		FreePacket(p);
		return;
	}

	if (p->TypeL3 == L3_ARPV4)
	{
		// Received an ARP packet
		L3RecvArp(f, p);

		// Release the packet
		Free(p->PacketData);
		FreePacket(p);
	}
	else if (p->TypeL3 == L3_IPV4)
	{
		// Received an IP packet
		L3RecvIp(f, p, false);
	}
	else
	{
		// Release the packet
		Free(p->PacketData);
		FreePacket(p);
	}
}
Example #11
0
int Shutdown_Networking()
{
    FreePacket(recPack);

    ArrayMan_shutdown();

    int close_res = close(proxyfd);
    if (-1 == close_res) {
        printf("Closing socket file descriptor failed with error [%s].", strerror(errno));
        return BH_ERROR;
    }

    return BH_SUCCESS;
}
Example #12
0
void NetSocket::Flush()
{
	NetPacket *in;
	while ((in = (NetPacket *)m_IncomingPackets.RemoveTail())) {
		FreePacket(in);
	}

	if (m_Socket != INVALID_SOCKET)
	{
		sockaddr from;
		socklen_t fromlen = sizeof(from);
		while (recvfrom(m_Socket, (char *)m_Buffer, sizeof(m_Buffer), 0, &from, &fromlen) > 0)
			;
	}
}
void LConnectToMasterServer::ProcessPacket(unsigned int unMaxPacketProcessed)
{
	m_unPacketProcessed = 0;
	if (unMaxPacketProcessed == 0)
	{
		unMaxPacketProcessed = 100;
	}
	for (unsigned int unIndex = 0; unIndex < unMaxPacketProcessed; ++unIndex)
	{ 
		LPacketSingle* pPacket = GetOneRecvedPacket();
		if (pPacket == NULL)
		{
			break;
		} 
		m_unPacketProcessed++;
		if (pPacket->GetPacketType() == 1)
		{
			unsigned short usPacketLen = 128;
			//	连接上来了,发送本服务器的ID到MasterServer
			LPacketSingle* pSendPacket = m_ConnectorToMasterServer.GetOneSendPacketPool(usPacketLen);
			if (pSendPacket == NULL)
			{
				//	error
			}
			else
			{
				//	与MasterServer初始化发送序列
				//	发送服务器ID给MasterServer
				//	uint64_t u64ServerUniqueID = m_pGateServerMainLogic->GetServerUniqueID();
				//	压入数据包
				pSendPacket->SetPacketID(Packet_SS_Start_Req);

				//	pPacket->AddULongLong(u64ServerUniqueID);
				AddOneSendPacket(pSendPacket);
			}
		}
		else
		{ 
			//	分发数据处理包
			E_Packet_From_Type eFromType = E_Packet_From_MasterServer;
			m_pGateServerMainLogic->GetPacketProcessManager()->DispatchMessageProcess(0, pPacket, eFromType);
		}
		//	处理协议包
		//
		//	释放接受到的数据包到缓冲池
		FreePacket(pPacket);
	}
}
Example #14
0
PKT *ParsePacketEx3(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address)
{
	PKT *p;
	// 引数チェック
	if (buf == NULL || size == 0)
	{
		return NULL;
	}

	if (vlan_type_id == 0)
	{
		vlan_type_id = MAC_PROTO_TAGVLAN;
	}

	p = ZeroMallocFast(sizeof(PKT));

	p->VlanTypeID = vlan_type_id;

	// パース実行
	if (ParsePacketL2Ex(p, buf, size, no_l3) == false)
	{
		// パース失敗
		FreePacket(p);
		return NULL;
	}

	p->PacketData = buf;
	p->PacketSize = size;

	p->MacAddressSrc = p->MacHeader->SrcAddress;
	p->MacAddressDest = p->MacHeader->DestAddress;

	if (bridge_id_as_mac_address)
	{
		if (p->TypeL3 == L3_BPDU)
		{
			if (p->L3.BpduHeader != NULL)
			{
				p->MacAddressSrc = p->L3.BpduHeader->BridgeMacAddress;
			}
		}
	}

	// パース成功
	return p;
}
Example #15
0
void NetChannel::FlushIncoming(int stream)
{
	fragbuf_t *p, *n;

	NetPacket *in;
	while ((in = (NetPacket *)m_incomingPackets.RemoveTail())) {
		FreePacket(in);
	}

	p = m_incomingbufs[stream];
	while (p)
	{
		n = p->next;
		Mem_Free(p);
		p = n;
	}

	m_incomingbufs[stream] = nullptr;
}
Example #16
0
// Send the waiting IP packets whose destination MAC address has been resolved
void L3SendWaitingIp(L3IF *f, UCHAR *mac, UINT ip, L3ARPENTRY *a)
{
	UINT i;
	LIST *o = NULL;
	// Validate arguments
	if (f == NULL || mac == NULL || a == NULL)
	{
		return;
	}

	for (i = 0;i < LIST_NUM(f->IpWaitList);i++)
	{
		L3PACKET *p = LIST_DATA(f->IpWaitList, i);

		if (p->NextHopIp == ip)
		{
			if (o == NULL)
			{
				o = NewListFast(NULL);
			}
			Add(o, p);
		}
	}

	if (o != NULL)
	{
		for (i = 0;i < LIST_NUM(o);i++)
		{
			L3PACKET *p = LIST_DATA(o, i);

			// Transmission
			L3SendIpNow(f, a, p);

			Delete(f->IpWaitList, p);
			Free(p->Packet->PacketData);
			FreePacket(p->Packet);
			Free(p);
		}

		ReleaseList(o);
	}
}
Example #17
0
// Clear the IP waiting list
void L3DeleteOldIpWaitList(L3IF *f)
{
	UINT i;
	LIST *o = NULL;
	// Validate arguments
	if (f == NULL)
	{
		return;
	}

	for (i = 0;i < LIST_NUM(f->IpWaitList);i++)
	{
		L3PACKET *p = LIST_DATA(f->IpWaitList, i);

		if (p->Expire <= Tick64())
		{
			if (o == NULL)
			{
				o = NewListFast(NULL);
			}

			Insert(o, p);
		}
	}

	if (o != NULL)
	{
		for (i = 0;i < LIST_NUM(o);i++)
		{
			L3PACKET *p = LIST_DATA(o, i);

			Delete(f->IpWaitList, p);

			Free(p->Packet->PacketData);
			FreePacket(p->Packet);
			Free(p);
		}

		ReleaseList(o);
	}
}
Example #18
0
void FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
	CurrentFrame = &Frames[PacketNumber];

	AVPacket Packet;
	if (!ReadPacket(&Packet))
		throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN,
			"ReadPacket unexpectedly failed to read a packet");

	// ReadPacket may have changed the packet number
	CurrentFrame = &Frames[PacketNumber];
	CurrentSample = CurrentFrame->SampleStart;

	bool GotSamples = false;
	uint8_t *Data = Packet.data;
	while (Packet.size > 0) {
		DecodeFrame.reset();
		int GotFrame = 0;
		int Ret = avcodec_decode_audio4(CodecContext, DecodeFrame, &GotFrame, &Packet);

		// Should only ever happen if the user chose to ignore decoding errors
		// during indexing, so continue to just ignore decoding errors
		if (Ret < 0) break;

		if (Ret > 0) {
			Packet.size -= Ret;
			Packet.data += Ret;
			if (GotFrame && DecodeFrame->nb_samples > 0) {
				GotSamples = true;
				if (pos)
					CacheBlock(*pos);
			}
		}
	}
	Packet.data = Data;
	FreePacket(&Packet);

	// Zero sample packets aren't included in the index
	if (GotSamples)
		++PacketNumber;
}
Example #19
0
void NetChannel::Clear()
{
	NetPacket *packet;
	while ((packet = (NetPacket *)m_incomingPackets.RemoveHead())) {
		FreePacket(packet);
	}

	ClearFragments();

	for (int i = 0; i < MAX_STREAMS; i++)
	{
		m_reliable_fragid[i] = 0;
		m_reliable_fragment[i] = 0;
		m_fragbufcount[i] = 0;
		m_frag_startpos[i] = 0;
		m_frag_length[i] = 0;
	}

	if (m_tempBuffer)
	{
		Mem_Free(m_tempBuffer);
		m_tempBuffer = nullptr;
	}

	m_tempBufferSize = 0;
	m_reliableOutSize = 0;

	memset(m_reliableOutBuffer, 0, sizeof(m_reliableOutBuffer));
	memset(m_flow, 0, sizeof(m_flow));

	m_reliableStream.Clear();
	m_unreliableStream.Clear();

	m_last_send =
	m_last_received =
		m_cleartime = m_System->GetTime();

	m_loss = 0;
}
Example #20
0
// Process IP packets
void L3RecvIp(L3IF *f, PKT *p, bool self)
{
	IPV4_HEADER *ip;
	UINT header_size;
	UINT next_hop = 0;
	L3IF *dst;
	L3PACKET *packet;
	UINT new_ttl = 0;
	// Validate arguments
	if (f == NULL || p == NULL)
	{
		return;
	}

	ip = p->L3.IPv4Header;
	header_size = IPV4_GET_HEADER_LEN(p->L3.IPv4Header) * 4;

	// Calculate the checksum
	if (IpCheckChecksum(ip) == false)
	{
		// The checksum does not match
		goto FREE_PACKET;
	}

	// Register in the ARP table
	L3KnownArp(f, ip->SrcIP, p->MacAddressSrc);

	if (p->BroadcastPacket)
	{
		// Not to route in the case of broadcast packet
		goto FREE_PACKET;
	}

	// Calculate the TTL
	if (ip->TimeToLive >= 1)
	{
		new_ttl = ip->TimeToLive - 1;
	}
	else
	{
		new_ttl = 0;
	}

	if (new_ttl == 0)
	{
		if (ip->DstIP != f->IpAddress)
		{
			UINT src_packet_size = p->PacketSize - sizeof(MAC_HEADER);
			UINT icmp_packet_total_size = sizeof(MAC_HEADER) + sizeof(IPV4_HEADER) + sizeof(ICMP_HEADER) + 4 + header_size + 8;
			UCHAR *buf;
			IPV4_HEADER *ipv4;
			ICMP_HEADER *icmpv4;
			UCHAR *data;
			PKT *pkt;
			UINT data_size = MIN(p->PacketSize - header_size, header_size + 8);

			// Generate an ICMP message that means that the TTL has expired
			buf = ZeroMalloc(icmp_packet_total_size);
			ipv4 = (IPV4_HEADER *)(buf + sizeof(MAC_HEADER));
			icmpv4 = (ICMP_HEADER *)(buf + sizeof(MAC_HEADER) + sizeof(IPV4_HEADER));
			data = buf + sizeof(MAC_HEADER) + sizeof(IPV4_HEADER) + sizeof(ICMP_HEADER) + 4;

			IPV4_SET_VERSION(ipv4, 4);
			IPV4_SET_HEADER_LEN(ipv4, sizeof(IPV4_HEADER) / 4);
			ipv4->TotalLength = Endian16((USHORT)(icmp_packet_total_size - sizeof(MAC_HEADER)));
			ipv4->TimeToLive = 0xff;
			ipv4->Protocol = IP_PROTO_ICMPV4;
			ipv4->SrcIP = f->IpAddress;
			ipv4->DstIP = ip->SrcIP;
			ipv4->Checksum = IpChecksum(ipv4, sizeof(IPV4_HEADER));

			icmpv4->Type = 11;
			Copy(data, ip, data_size);
			icmpv4->Checksum = IpChecksum(icmpv4, sizeof(ICMP_HEADER) + data_size + 4);

			buf[12] = 0x08;
			buf[13] = 0x00;

			pkt = ParsePacket(buf, icmp_packet_total_size);
			if (pkt == NULL)
			{
				Free(buf);
			}
			else
			{
				L3RecvIp(f, pkt, true);
			}

			// Discard the packet body whose the TTL has expired
			goto FREE_PACKET;
		}
	}

	// Rewrite the TTL
	p->L3.IPv4Header->TimeToLive = (UCHAR)new_ttl;

	// Get the interface corresponding to the destination IP address
	dst = L3GetNextIf(f->Switch, ip->DstIP, &next_hop);

	if (dst == NULL && self == false)
	{
		UINT src_packet_size = p->PacketSize - sizeof(MAC_HEADER);
		UINT icmp_packet_total_size = sizeof(MAC_HEADER) + sizeof(IPV4_HEADER) + sizeof(ICMP_HEADER) + 4 + header_size + 8;
		UCHAR *buf;
		IPV4_HEADER *ipv4;
		ICMP_HEADER *icmpv4;
		UCHAR *data;
		PKT *pkt;
			UINT data_size = MIN(p->PacketSize - header_size, header_size + 8);

		// Respond with ICMP that indicates that no route can be found
		buf = ZeroMalloc(icmp_packet_total_size);
		ipv4 = (IPV4_HEADER *)(buf + sizeof(MAC_HEADER));
		icmpv4 = (ICMP_HEADER *)(buf + sizeof(MAC_HEADER) + sizeof(IPV4_HEADER));
		data = buf + sizeof(MAC_HEADER) + sizeof(IPV4_HEADER) + sizeof(ICMP_HEADER) + 4;

		IPV4_SET_VERSION(ipv4, 4);
		IPV4_SET_HEADER_LEN(ipv4, sizeof(IPV4_HEADER) / 4);
		ipv4->TotalLength = Endian16((USHORT)(icmp_packet_total_size - sizeof(MAC_HEADER)));
		ipv4->TimeToLive = 0xff;
		ipv4->Protocol = IP_PROTO_ICMPV4;
		ipv4->SrcIP = f->IpAddress;
		ipv4->DstIP = ip->SrcIP;
		ipv4->Checksum = IpChecksum(ipv4, sizeof(IPV4_HEADER));

		icmpv4->Type = 3;
		Copy(data, ip, data_size);
		icmpv4->Checksum = IpChecksum(icmpv4, sizeof(ICMP_HEADER) + data_size + 4);

		buf[12] = 0x08;
		buf[13] = 0x00;

		pkt = ParsePacket(buf, icmp_packet_total_size);
		if (pkt == NULL)
		{
			Free(buf);
		}
		else
		{
			L3RecvIp(f, pkt, true);
		}

		// Discard the packet body whose route can not be found
		goto FREE_PACKET;
	}

	if (dst != NULL && ip->DstIP == dst->IpAddress)
	{
		bool free_packet = true;
		// IP packet addressed to myself has arrived
		if (p->TypeL4 == L4_ICMPV4)
		{
			ICMP_HEADER *icmp = p->L4.ICMPHeader;
			if (icmp->Type == ICMP_TYPE_ECHO_REQUEST)
			{
				// Reply by rewriting the source and destination of the IP packet
				UINT src_ip, dst_ip;
				src_ip = p->L3.IPv4Header->DstIP;
				dst_ip = p->L3.IPv4Header->SrcIP;

				p->L3.IPv4Header->DstIP = dst_ip;
				p->L3.IPv4Header->SrcIP = src_ip;

				ip->TimeToLive = 0xff;

				// Recalculates the checksum
				ip->FlagsAndFlagmentOffset[0] = ip->FlagsAndFlagmentOffset[1] = 0;
				icmp->Checksum = 0;
				icmp->Type = ICMP_TYPE_ECHO_RESPONSE;
				icmp->Checksum = IpChecksum(icmp, p->PacketSize - sizeof(MAC_HEADER) - header_size);

				dst = L3GetNextIf(f->Switch, ip->DstIP, &next_hop);

				free_packet = false;
			}
		}

		if (free_packet)
		{
			goto FREE_PACKET;
		}
	}

	if (dst == NULL)
	{
		// The destination does not exist
		goto FREE_PACKET;
	}

	// Recalculate the IP checksum
	ip->Checksum = 0;
	ip->Checksum = IpChecksum(ip, header_size);

	// Treat as a Layer-3 packet
	packet = ZeroMalloc(sizeof(L3PACKET));
	packet->Expire = Tick64() + IP_WAIT_FOR_ARP_TIMEOUT;
	packet->NextHopIp = next_hop;
	packet->Packet = p;

	// Store to the destination session
	L3StoreIpPacketToIf(f, dst, packet);

	return;

FREE_PACKET:
	// Release the packet
	Free(p->PacketData);
	FreePacket(p);
	return;
}