Beispiel #1
0
void Client::Handle_SessionReady(const char* data, unsigned int size)
{
	if(status != cs_not_sent_session_ready)
	{
		server_log->Log(log_network_error, "Session ready recieved again after already being recieved.");
		return;
	}

	if(size < sizeof(unsigned int))
	{
		server_log->Log(log_network_error, "Session ready was too small.");
		return;
	}

	unsigned int mode = *((unsigned int*)data);
	if(mode == (unsigned int)lm_from_world)
	{
		server_log->Log(log_network, "Session ready indicated logged in from world(unsupported feature), disconnecting.");
		connection->Close();
		return;
	}

	status = cs_waiting_for_login;

	/**
	 * The packets are mostly the same but slightly different between the two versions.
	 */
	if(version == cv_sod)
	{
		EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 17);
		outapp->pBuffer[0] = 0x02;
		outapp->pBuffer[10] = 0x01;
		outapp->pBuffer[11] = 0x65;

		if(server.options.IsDumpOutPacketsOn())
		{
			DumpPacket(outapp);
		}

		connection->QueuePacket(outapp);
		delete outapp;
	}
	else
	{
		const char *msg = "ChatMessage";
		EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 16 + strlen(msg));
		outapp->pBuffer[0] = 0x02;
		outapp->pBuffer[10] = 0x01;
		outapp->pBuffer[11] = 0x65;
		strcpy((char*)(outapp->pBuffer + 15), msg);

		if(server.options.IsDumpOutPacketsOn())
		{
			DumpPacket(outapp);
		}

		connection->QueuePacket(outapp);
		delete outapp;
	}
}
bool EmuTCPConnection::SendPacket(EmuTCPNetPacket_Struct* tnps)
{
	if (RemoteID)
	{
		return false;
	}
	if (!Connected())
	{
		return false;
	}
	if (GetMode() != modePacket)
	{
		return false;
	}

	LockMutex lock(&MState);
	eTCPMode tmp = GetMode();
	if (tmp == modeTransition)
	{
		EmuTCPNetPacket_Struct* tnps2 = (EmuTCPNetPacket_Struct*) new uchar[tnps->size];
		memcpy(tnps2, tnps, tnps->size);
		InModeQueuePush(tnps2);
		return true;
	}
#if TCPN_LOG_PACKETS >= 1
	if (tnps && tnps->opcode != 0)
	{
		struct in_addr	in;
		in.s_addr = GetrIP();
		CoutTimestamp(true);
		std::cout << ": Logging outgoing TCP NetPacket. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << tnps->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << tnps->size << " " << inet_ntoa(in) << ":" << GetrPort();
		if (pOldFormat)
		{
			std::cout << " (OldFormat)";
		}
		std::cout << std::endl;
#if TCPN_LOG_PACKETS == 2
		if (tnps->size >= 32)
		{
			DumpPacket((uchar*) tnps, 32);
		}
		else
		{
			DumpPacket((uchar*) tnps, tnps->size);
		}
#endif
#if TCPN_LOG_PACKETS >= 3
		DumpPacket((uchar*) tnps, tnps->size);
#endif
	}
#endif
	ServerSendQueuePushEnd((const uchar*) tnps, tnps->size);
	return true;
}
Beispiel #3
0
DWORD __fastcall RecvHook_WOD(void* thisPTR, void* dummy, void* param1, void* param2, CDataStore* ds, void* param4)
{
    DumpPacket(SMSG, 0, *(DWORD*)ds->buffer, 4, ds->size, ds->buffer);
    CHECK(hookInfo.recvHookGood, "Recv hook is working.\n");
    typedef DWORD(__thiscall *proto)(void*, void*, void*, void*, void*);
    return reinterpret_cast<proto>(hookInfo.recvDetour)(thisPTR, param1, param2, ds, param4);
}
Beispiel #4
0
DWORD __fastcall SendHook(void* thisPTR, void* dummy, CDataStore* ds, DWORD connectionId)
{
    DumpPacket(CMSG, connectionId, *(DWORD*)ds->buffer, 4, ds->size, ds->buffer);
    CHECK(hookInfo.sendHookGood, "Send hook is working.\n");
    typedef DWORD(__thiscall *proto)(void*, void*, DWORD);
    return reinterpret_cast<proto>(hookInfo.sendDetour)(thisPTR, ds, connectionId);
}
Beispiel #5
0
DWORD __fastcall RecvHook(void* thisPTR, void* /* dummy */, void* param1, CDataStore* dataStore, void* param3)
{
    WORD opcodeSize = buildNumber <= WOW_MOP_16135 ? 2 : 4;
    // packet dump
    DumpPacket(SMSG, 0, opcodeSize, dataStore);

    // unhooks the recv function
    HookManager::UnHook(recvAddress, defaultMachineCodeRecv);

    // calls client's function so it can processes the packet
    DWORD returnValue = 0;
    if (buildNumber <= WOW_TBC_8606) // different prototype
        returnValue = RecvProto8606(recvAddress)(thisPTR, param1, dataStore);
    else
        returnValue = RecvProto(recvAddress)(thisPTR, param1, dataStore, param3);

    // hooks again to catch the next incoming packets also
    HookManager::ReHook(recvAddress, machineCodeHookRecv);

    if (!recvHookGood)
    {
        printf("Recv hook is working.\n");
        recvHookGood = true;
    }

    return returnValue;
}
Beispiel #6
0
void ServerManager::SendOldUserToWorldRequest(const char* server_id, unsigned int client_account_id)
{
	list<WorldServer*>::iterator iter = world_servers.begin();
	bool found = false;
	while(iter != world_servers.end())
	{
		if((*iter)->GetRemoteIP() == server_id)
		{
			ServerPacket *outapp = new ServerPacket(ServerOP_UsertoWorldReq, sizeof(UsertoWorldRequest_Struct));
			UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct*)outapp->pBuffer;
			utwr->worldid = (*iter)->GetServerListID();
			utwr->lsaccountid = client_account_id;
			(*iter)->GetConnection()->SendPacket(outapp);
			found = true;

			if(server.options.IsDumpInPacketsOn())
			{
				DumpPacket(outapp);
			}
			delete outapp;
		}
		++iter;
	}

	if(!found && server.options.IsTraceOn())
	{
		server_log->Log(log_client_error, "Client requested a user to world but supplied an invalid id of %s.", server_id);
	}
}
Beispiel #7
0
int handle_REQ_PERFORM_SUPPLEMENTARY_SERVICE( unsigned char * pkt, unsigned short len )
{
    perform_supplementary_service_req * prq = ( perform_supplementary_service_req * ) pkt;
    unsigned char * ssd = ( unsigned char * ) &prq[1];
    unsigned short ssd_len = ( len - ( unsigned short ) sizeof( perform_supplementary_service_req ) );

    printf( "Debugger request: REQ_PERFORM_SUPPLEMENTARY_SERVICE\n" );
    printf( "    ID: 0x%.08x", prq->id );

    ServiceNameAndId *lookup;
    for( lookup = services; lookup != NULL; lookup = lookup->next ) {
        if( prq->id == lookup->service_id ) {
            printf( " [%s]", lookup->service_name );
            break;
        }
    }
    last_service = lookup;

    printf( "\n" );

    if( ssd_len ) {
        int rc = 0;
        if( lookup && lookup->service_decode )
            rc = lookup->service_decode( 1, ssd, ssd_len );

        if( 0 != rc ) {
            printf( "    supplementary service data:\n" );
            DumpPacket( ssd, ssd_len, 1 );
        }
    }

    return 1;
}
Beispiel #8
0
bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
	if (GetAccountID() == 0)
	{
		clog(WORLD__CLIENT_ERR,"Account ID not set; unable to create character.");
		return false;
	}
	else if (app->size != sizeof(CharCreate_Struct))
	{
		clog(WORLD__CLIENT_ERR,"Wrong size on OP_CharacterCreate. Got: %d, Expected: %d",app->size,sizeof(CharCreate_Struct));
		DumpPacket(app);
		// the previous behavior was essentially returning true here
		// but that seems a bit odd to me.
		return true;
	}

	CharCreate_Struct *cc = (CharCreate_Struct*)app->pBuffer;
	if(OPCharCreate(char_name, cc) == false)
	{
		database.DeleteCharacter(char_name);
		EQApplicationPacket *outapp = new EQApplicationPacket(OP_ApproveName, 1);
		outapp->pBuffer[0] = 0;
		QueuePacket(outapp);
		safe_delete(outapp);
	}
	else
	{
		SendCharInfo();
	}

	return true;
}
int SDLNet_UDP_Send(UDPsocket sock, int channel, UDPpacket *packet)
{
	DumpPacket(packet);

	ssize_t sent = send(sock, packet->data, packet->len, 0);

	printf("SDLNet_UDP_Send Sock Descriptor=%d, Data=%p, Len=%d, Sent=%ld\n"
		, sock, packet->data, packet->len, sent);
	return sent;
}
Beispiel #10
0
int handle_REQ_READ_IO_REPLY( unsigned char * pkt, unsigned short len )
{
    printf( "Trap reply: REQ_READ_IO\n" );
    printf( "    Length: 0x%.04x\n", len );

    if( len ){
        printf( "    Data:\n" );
        DumpPacket( pkt, len, 1 );
    }
    return 1;
}
Beispiel #11
0
/*----------------------------------------------------------------------------*/
int
ProcessPacket(mtcp_manager_t mtcp, const int ifidx,
              uint32_t cur_ts, unsigned char *pkt_data, int len)
{
    struct ethhdr *ethh = (struct ethhdr *)pkt_data;
    u_short ip_proto = ntohs(ethh->h_proto);
    int ret;

#ifdef PKTDUMP
    DumpPacket(mtcp, (char *)pkt_data, len, "IN", ifidx);
#endif

#ifdef NETSTAT
    mtcp->nstat.rx_packets[ifidx]++;
    mtcp->nstat.rx_bytes[ifidx] += len + 24;
#endif /* NETSTAT */

#if 0
    /* ignore mac address which is not for current interface */
    int i;
    for (i = 0; i < 6; i ++) {
        if (ethh->h_dest[i] != CONFIG.eths[ifidx].haddr[i]) {
            return FALSE;
        }
    }
#endif

    if (ip_proto == ETH_P_IP) {
        /* process ipv4 packet */
        ret = ProcessIPv4Packet(mtcp, cur_ts, ifidx, pkt_data, len);

    } else if (ip_proto == ETH_P_ARP) {
        ProcessARPPacket(mtcp, cur_ts, ifidx, pkt_data, len);
        return TRUE;

    } else {
        //DumpPacket(mtcp, (char *)pkt_data, len, "??", ifidx);
        struct ps_packet packet;
        packet.ifindex = ifidx;
        packet.len = len;
        packet.buf = (char *)pkt_data;
        ps_slowpath_packet(mtcp->ctx->handle, &packet);
        return TRUE;
    }

#ifdef NETSTAT
    if (ret < 0) {
        mtcp->nstat.rx_errors[ifidx]++;
    }
#endif

    return ret;
}
Beispiel #12
0
void Client::SendServerListPacket()
{
	EQApplicationPacket *outapp = server.SM->CreateServerListPacket(this);
	
	if(server.options.IsDumpOutPacketsOn())
	{
		DumpPacket(outapp);
	}

	connection->QueuePacket(outapp);
	delete outapp;
}
Beispiel #13
0
bool EmuTCPConnection::SendPacket(ServerPacket* pack, uint32 iDestination) {
	if (!Connected())
		return false;
	eTCPMode tmp = GetMode();
	if (tmp != modePacket && tmp != modeTransition)
		return false;
	LockMutex lock(&MState);
	if (RemoteID)
		return RelayLink->SendPacket(pack, RemoteID);
	else if (pOldFormat) {
		#if TCPN_LOG_PACKETS >= 1
			if (pack && pack->opcode != 0) {
				struct in_addr	in;
				in.s_addr = GetrIP();
				CoutTimestamp(true);
				std::cout << ": Logging outgoing TCP OldPacket. OPCode: 0x" << hex << setw(4) << setfill('0') << pack->opcode << dec << ", size: " << setw(5) << setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
				#if TCPN_LOG_PACKETS == 2
					if (pack->size >= 32)
						DumpPacket(pack->pBuffer, 32);
					else
						DumpPacket(pack);
				#endif
				#if TCPN_LOG_PACKETS >= 3
					DumpPacket(pack);
				#endif
			}
		#endif
		SPackSendQueue* spsq = MakeOldPacket(pack);
		ServerSendQueuePushEnd(spsq->buffer, spsq->size);
		safe_delete_array(spsq);
	}
	else {
		EmuTCPNetPacket_Struct* tnps = MakePacket(pack, iDestination);
		if (tmp == modeTransition) {
			InModeQueuePush(tnps);
		}
		else {
			#if TCPN_LOG_PACKETS >= 1
				if (pack && pack->opcode != 0) {
					struct in_addr	in;
					in.s_addr = GetrIP();
					CoutTimestamp(true);
					std::cout << ": Logging outgoing TCP packet. OPCode: 0x" << hex << setw(4) << setfill('0') << pack->opcode << dec << ", size: " << setw(5) << setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
					#if TCPN_LOG_PACKETS == 2
						if (pack->size >= 32)
							DumpPacket(pack->pBuffer, 32);
						else
							DumpPacket(pack);
					#endif
					#if TCPN_LOG_PACKETS >= 3
						DumpPacket(pack);
					#endif
				}
			#endif
			ServerSendQueuePushEnd((uchar**) &tnps, tnps->size);
		}
	}
	return true;
}
Beispiel #14
0
void Mob::CreateHorseSpawnPacket(EQApplicationPacket* app, const char* ownername, uint16 ownerid, Mob* ForWho) {
    app->SetOpcode(OP_NewSpawn);
    app->pBuffer = new uchar[sizeof(NewSpawn_Struct)];
    app->size = sizeof(NewSpawn_Struct);
    memset(app->pBuffer, 0, sizeof(NewSpawn_Struct));
    NewSpawn_Struct* ns = (NewSpawn_Struct*)app->pBuffer;
    FillSpawnStruct(ns, ForWho);

#if (EQDEBUG >= 11)
    printf("Horse Spawn Packet - Owner: %s\n", ownername);
    DumpPacket(app);
#endif
}
Beispiel #15
0
int handle_REQ_WRITE_IO( unsigned char * pkt, unsigned short len )
{
    write_io_req * prq = ( write_io_req * ) pkt;
    unsigned short to_write = ( len - ( unsigned short ) sizeof( write_io_req ) );
    unsigned char * data = ( unsigned char * ) &prq[1];

    printf( "Debugger request: REQ_WRITE_IO\n" );
    printf( "    Address:    %.08x\n", prq->IO_offset );
    printf( "    Length:     %.04x\n", to_write );
    printf( "    Data:\n" );
    DumpPacket( data, to_write, 1 );

    return 1;
}
Beispiel #16
0
int handle_REQ_PERFORM_SUPPLEMENTARY_SERVICE_REPLY( unsigned char * pkt, unsigned short len)
{
    int rc = -1;
    if( last_service ) {
        if( last_service && last_service->service_decode )
            rc = last_service->service_decode( 0, pkt, len );
    }

    if( 0 != rc ) {
        printf( "    supplementary service response:\n" );
        DumpPacket( pkt, len, 1 );
    }

    return 1;
}
Beispiel #17
0
/*----------------------------------------------------------------------------*/
static int
psio_flush_pkts(struct mtcp_thread_context *ctx, int nif)
{
	struct ps_chunk_buf *c_buf;
	mtcp_manager_t mtcp;
	struct psio_private_context *ppc;
	int send_cnt, to_send_cnt = 0;
	int start_idx, i;

	ppc = (struct psio_private_context *)ctx->io_private_context;
	c_buf = &ppc->w_chunk_buf[nif];
	mtcp = ctx->mtcp_manager;

	/* if chunk (for writing) is not there... then return */
	if (!c_buf)
		return -1;
	
	to_send_cnt = c_buf->cnt;
	if (to_send_cnt > 0) {
		STAT_COUNT(mtcp->runstat.rounds_tx_try);
		start_idx = c_buf->next_to_send;
		send_cnt = ps_send_chunk_buf(&ppc->handle, c_buf);
		
		for (i = 0; i < send_cnt; i++) {
#ifdef NETSTAT
			mtcp->nstat.tx_bytes[nif] += c_buf->info[start_idx].len + 24;
#endif
#if PKTDUMP
			DumpPacket(mtcp, c_buf->buf + c_buf->info[start_idx].offset, 
				   c_buf->info[start_idx].len, "OUT", nif);
			
#endif
			start_idx = (start_idx + 1) % ENTRY_CNT;
		}
		if (send_cnt < 0) {
			TRACE_ERROR("ps_send_chunk_buf failed. "
				    "ret: %d, error: %s\n", send_cnt, strerror(errno));
#ifdef NETSTAT
		} else {
			mtcp->nstat.tx_packets[nif] += send_cnt;
#endif
		}
		
		return send_cnt;
	}
	
	return 0;
}
Beispiel #18
0
/*--------------------------------------------------------------------*/
int main()
{   int sd, bytes_read;
    char data[1024];

    sd  = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
    if ( sd < 0 )
		PANIC("Snooper socket");
    do
	{
    	bytes_read = recvfrom(sd, data, sizeof(data), 0, 0, 0);
        if ( bytes_read > 0 )
			DumpPacket(data, bytes_read);
    }
	while ( bytes_read > 0 );
    return 0;
}
Beispiel #19
0
int handle_REQ_MACHINE_DATA( unsigned char * pkt, unsigned short len )
{
    machine_data_req *  prq = ( machine_data_req * ) pkt;
    unsigned char *     msd = ( unsigned char * ) &prq[1];
    unsigned short      msd_len = ( len - ( unsigned short ) sizeof( machine_data_req ) );

    printf( "Debugger request: REQ_MACHINE_DATA\n" );
    printf( "    Type:       %u\n", prq->info_type );
    printf( "    Address:    %.04x:%.08x\n", prq->addr.segment, prq->addr.offset );

    if( msd_len ) {
        printf( "Machine specific data - to be decoded:\n" );
        DumpPacket( msd, msd_len, 1 );
    }
    return 1;
}
Beispiel #20
0
//sending functions
void PerlPacket::SendTo(Client *who) {
	if(!who || op == OP_Unknown || (len > 0 && packet == NULL))
		return;
	
	EQApplicationPacket *outapp = new EQApplicationPacket(op, len);
	if(len > 0)
		memcpy(outapp->pBuffer, packet, len);
	
#ifndef WIN32
#warning Rewrite this!
#endif
	//	printf("Created this packet with PerlPacket: OP: %s\n", ZoneOpcodeManager->EmuToName(op));
	DumpPacket(outapp);
	
	who->FastQueuePacket(&outapp);
}
Beispiel #21
0
int handle_REQ_MACHINE_DATA_REPLY( unsigned char * pkt, unsigned short len )
{
    machine_data_ret * pr = (machine_data_ret * ) pkt;
    unsigned char * msd = ( unsigned char * ) &pr[1];
    unsigned short  msd_len = ( len - ( unsigned short ) sizeof( machine_data_ret ) );

    printf( "Trap reply: REQ_MACHINE_DATA\n" );
    printf( "    Start:  %.08x\n", pr->cache_start );
    printf( "    End:    %.08x\n", pr->cache_end );

    if( msd_len ){
        printf( "Machine specific data - to be decoded:\n" );
        DumpPacket( msd, msd_len, 1 );
    }

    return 1;
}
Beispiel #22
0
VOID
DumpPacket2 (const char *prefix,
	     const ETH_HEADER *eth,
	     const unsigned char *data,
	     unsigned int len)
{
  struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE);
  if (ep)
    {
      if (len > DEFAULT_PACKET_LOOKAHEAD)
	len = DEFAULT_PACKET_LOOKAHEAD;
      ep->eth = *eth;
      NdisMoveMemory (ep->payload, data, len);
      DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len);
      MemFree (ep, sizeof (struct ethpayload));
    }
}
Beispiel #23
0
void WorldServer::SendClientAuth(unsigned int ip, string account, string key, unsigned int account_id, uint8 version)
{
	ServerPacket *outapp = new ServerPacket(ServerOP_LSClientAuth, sizeof(ServerLSClientAuth));
	ServerLSClientAuth* slsca = (ServerLSClientAuth*)outapp->pBuffer;

	slsca->lsaccount_id = account_id;
	strncpy(slsca->name, account.c_str(), account.size() > 30 ? 30 : account.size());
	strncpy(slsca->key, key.c_str(), 10);
	slsca->lsadmin = 0;
	slsca->worldadmin = 0;
	slsca->ip = ip;
	slsca->version = version;

	in_addr in;
	in.s_addr = ip;connection->GetrIP();
	string client_address(inet_ntoa(in));
	in.s_addr = connection->GetrIP();
	string world_address(inet_ntoa(in));

	if(client_address.compare(world_address) == 0)
	{
		slsca->local = 1;
	}
	else if (client_address.find(db.LoadServerSettings("options", "local_network").c_str()) != string::npos)
	{
		slsca->local = 1;
	}
	else
	{
		slsca->local = 0;
	}

	connection->SendPacket(outapp);

	if (server_log->DumpIn())
	{
		DumpPacket(outapp);
	}
	delete outapp;
}
Beispiel #24
0
DWORD __fastcall SendHook(void* thisPTR, void* /* dummy */, CDataStore* dataStore, void* param2)
{
    // dumps the packet
    DumpPacket(CMSG, 0, 4, dataStore);

    // unhooks the send function
    HookManager::UnHook(sendAddress, defaultMachineCodeSend);

    // now let's call client's function
    // so it can send the packet to the server (connection, CDataStore*, 2)
    DWORD returnValue = SendProto(sendAddress)(thisPTR, dataStore, param2);

    // hooks again to catch the next outgoing packets also
    HookManager::ReHook(sendAddress, machineCodeHookSend);

    if (!sendHookGood)
    {
        printf("Send hook is working.\n");
        sendHookGood = true;
    }

    return 0;
}
Beispiel #25
0
bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) {
	int32 base = 0;
	int32 size = 4;
	uchar* buffer;
	ServerPacket* pack = 0;
	while ((recvbuf_used - base) >= size) {
		buffer = &recvbuf[base];
		memcpy(&size, &buffer[2], 2);
		if (size >= MaxTCPReceiveBuffferSize) {
#if TCPN_DEBUG_Memory >= 1
			std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl;
#endif
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize");
			return false;
		}
		if ((recvbuf_used - base) >= size) {
			// ok, we got enough data to make this packet!
			pack = new ServerPacket;
			memcpy(&pack->opcode, &buffer[0], 2);
			pack->size = size - 4;
/*			if () { // TODO: Checksum or size check or something similar
				// Datastream corruption, get the hell outta here!
				delete pack;
				return false;
			}*/
			if (pack->size > 0) {
				pack->pBuffer = new uchar[pack->size];
				memcpy(pack->pBuffer, &buffer[4], pack->size);
			}
			if (pack->opcode == 0) {
				// keepalive, no need to process
				safe_delete(pack);
			}
			else {
				#if TCPN_LOG_PACKETS >= 1
					if (pack && pack->opcode != 0) {
						struct in_addr	in;
						in.s_addr = GetrIP();
						CoutTimestamp(true);
						std::cout << ": Logging incoming TCP OldPacket. OPCode: 0x" << hex << setw(4) << setfill('0') << pack->opcode << dec << ", size: " << setw(5) << setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
						#if TCPN_LOG_PACKETS == 2
							if (pack->size >= 32)
								DumpPacket(pack->pBuffer, 32);
							else
								DumpPacket(pack);
						#endif
						#if TCPN_LOG_PACKETS >= 3
							DumpPacket(pack);
						#endif
					}
				#endif
				OutQueuePush(pack);
			}
			base += size;
			size = 4;
		}
	}
	if (base != 0) {
		if (base >= recvbuf_used) {
			safe_delete_array(recvbuf);
		}
		else {
			uchar* tmpbuf = new uchar[recvbuf_size - base];
			memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base);
			safe_delete_array(recvbuf);
			recvbuf = tmpbuf;
			recvbuf_used -= base;
			recvbuf_size -= base;
		}
	}
	return true;
}
Beispiel #26
0
bool TCPConnection::SendData(bool &sent_something, char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	/************ Get first send packet on queue and send it! ************/
	uchar* data = 0;
	int32 size = 0;
	int status = 0;
	if (ServerSendQueuePop(&data, &size)) {
#ifdef _WINDOWS
		status = send(connection_socket, (const char *) data, size, 0);
#else
		status = send(connection_socket, data, size, MSG_NOSIGNAL);
		if(errno==EPIPE) status = SOCKET_ERROR;
#endif
		if (status >= 1) {
#if TCPN_LOG_RAW_DATA_OUT >= 1
			struct in_addr	in;
			in.s_addr = GetrIP();
			CoutTimestamp(true);
			std::cout << ": Wrote " << status << " bytes to network. " << inet_ntoa(in) << ":" << GetrPort();
			std::cout << std::endl;
	#if TCPN_LOG_RAW_DATA_OUT == 2
			int32 tmp = status;
			if (tmp > 32)
				tmp = 32;
			DumpPacket(data, status);
	#elif TCPN_LOG_RAW_DATA_OUT >= 3
			DumpPacket(data, status);
	#endif
#endif
			sent_something = true;
			if (status < (signed)size) {
#if TCPN_LOG_RAW_DATA_OUT >= 1
				struct in_addr	in;
				in.s_addr = GetrIP();
				CoutTimestamp(true);
				std::cout << ": Pushed " << (size - status) << " bytes back onto the send queue. " << inet_ntoa(in) << ":" << GetrPort();
				std::cout << std::endl;
#endif
				// If there's network congestion, the number of bytes sent can be less than
				// what we tried to give it... Push the extra back on the queue for later
				ServerSendQueuePushFront(&data[status], size - status);
			}
			else if (status > (signed)size) {
				return false;
			}
			// else if (status == size) {}
		}
		else {
			ServerSendQueuePushFront(data, size);
		}

		safe_delete_array(data);
		if (status == SOCKET_ERROR) {
#ifdef _WINDOWS
			if (WSAGetLastError() != WSAEWOULDBLOCK)
#else
			if (errno != EWOULDBLOCK)
#endif
			{
				if (errbuf) {
#ifdef _WINDOWS
					snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::SendData(): send(): Errorcode: %i", WSAGetLastError());
#else
					snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::SendData(): send(): Errorcode: %s", strerror(errno));
#endif
				}

				//if we get an error while disconnecting, just jump to disconnected
				MState.lock();
				if(pState == TCPS_Disconnecting)
					pState = TCPS_Disconnected;
				MState.unlock();

				return false;
			}
		}
	}
	return true;
}
Beispiel #27
0
bool TCPConnection::ProcessReceivedData(char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	if (!recvbuf)
		return true;
#if TCPN_DEBUG_Console >= 4
	if (recvbuf_used) {
		std::cout << "Starting Processing: recvbuf=" << recvbuf_used << std::endl;
		DumpPacket(recvbuf, recvbuf_used);
	}
#endif
	for (int i=0; i < recvbuf_used; i++) {
		if (GetEcho() && i >= recvbuf_echo) {
			Send(&recvbuf[i], 1);
			recvbuf_echo = i + 1;
		}
		switch(recvbuf[i]) {
		case 0: { // 0 is the code for clear buffer
				if (i==0) {
					recvbuf_used--;
					recvbuf_echo--;
					memmove(recvbuf, &recvbuf[1], recvbuf_used);
					i = -1;
				} else {
					if (i == recvbuf_used) {
						safe_delete_array(recvbuf);
						i = -1;
					}
					else {
						uchar* tmpdel = recvbuf;
						recvbuf = new uchar[recvbuf_size];
						memcpy(recvbuf, &tmpdel[i+1], recvbuf_used-i);
						recvbuf_used -= i + 1;
						recvbuf_echo -= i + 1;
						safe_delete_array(tmpdel);
						i = -1;
					}
				}
#if TCPN_DEBUG_Console >= 5
				std::cout << "Removed 0x00" << std::endl;
				if (recvbuf_used) {
					std::cout << "recvbuf left: " << recvbuf_used << std::endl;
					DumpPacket(recvbuf, recvbuf_used);
				}
				else
					std::cout << "recbuf left: None" << std::endl;
#endif
				m_previousLineEnd = false;
				break;
			}
			case 10:
			case 13: // newline marker
			{
				char *line = nullptr;
				if (i==0) { // empty line
					if(!m_previousLineEnd) {
						//char right before this was NOT a CR, report the empty line.
						line = new char[1];
						line[0] = '\0';
						m_previousLineEnd = true;
					} else {
						m_previousLineEnd = false;
					}
					recvbuf_used--;
					recvbuf_echo--;
					memcpy(recvbuf, &recvbuf[1], recvbuf_used);
					i = -1;
				} else {
					line = new char[i+1];
					memset(line, 0, i+1);
					memcpy(line, recvbuf, i);
#if TCPN_DEBUG_Console >= 3
					std::cout << "Line Out: " << std::endl;
					DumpPacket((uchar*) line, i);
#endif
					//line[i] = 0;
					uchar* tmpdel = recvbuf;
					recvbuf = new uchar[recvbuf_size];
					recvbuf_used -= i+1;
					recvbuf_echo -= i+1;
					memcpy(recvbuf, &tmpdel[i+1], recvbuf_used);
#if TCPN_DEBUG_Console >= 5
					std::cout << "i+1=" << i+1 << std::endl;
					if (recvbuf_used) {
						std::cout << "recvbuf left: " << recvbuf_used << std::endl;
						DumpPacket(recvbuf, recvbuf_used);
					}
					else
						std::cout << "recbuf left: None" << std::endl;
#endif
					safe_delete_array(tmpdel);
					i = -1;
					m_previousLineEnd = true;
				}


				if(line != nullptr) {
					bool finish_proc = false;
					finish_proc = LineOutQueuePush(line);
					if(finish_proc)
						return(true);	//break early as requested by LineOutQueuePush
				}

				break;
			}
			case 8: // backspace
			{
				if (i==0) { // nothin to backspace
					recvbuf_used--;
					recvbuf_echo--;
					memmove(recvbuf, &recvbuf[1], recvbuf_used);
					i = -1;
				} else {
					uchar* tmpdel = recvbuf;
					recvbuf = new uchar[recvbuf_size];
					memcpy(recvbuf, tmpdel, i-1);
					memcpy(&recvbuf[i-1], &tmpdel[i+1], recvbuf_used-i);
					recvbuf_used -= 2;
					recvbuf_echo -= 2;
					safe_delete_array(tmpdel);
					i -= 2;
				}
				break;
				m_previousLineEnd = false;
			}
			default:
				m_previousLineEnd = false;
		}
	}
	if (recvbuf_used < 0)
		safe_delete_array(recvbuf);
	return true;
}
Beispiel #28
0
bool TCPConnection::RecvData(char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	if (!Connected()) {
		return false;
	}

	int	status = 0;
	if (recvbuf == 0) {
		recvbuf = new uchar[5120];
		recvbuf_size = 5120;
		recvbuf_used = 0;
		recvbuf_echo = 0;
	}
	else if ((recvbuf_size - recvbuf_used) < 2048) {
		uchar* tmpbuf = new uchar[recvbuf_size + 5120];
		memcpy(tmpbuf, recvbuf, recvbuf_used);
		recvbuf_size += 5120;
		safe_delete_array(recvbuf);
		recvbuf = tmpbuf;
		if (recvbuf_size >= MaxTCPReceiveBuffferSize) {
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): recvbuf_size >= MaxTCPReceiveBuffferSize");
			return false;
		}
	}

	status = recv(connection_socket, (char *) &recvbuf[recvbuf_used], (recvbuf_size - recvbuf_used), 0);

	if (status >= 1) {
#if TCPN_LOG_RAW_DATA_IN >= 1
		struct in_addr	in;
		in.s_addr = GetrIP();
		CoutTimestamp(true);
		std::cout << ": Read " << status << " bytes from network. (recvbuf_used = " << recvbuf_used << ") " << inet_ntoa(in) << ":" << GetrPort();
		std::cout << std::endl;
	#if TCPN_LOG_RAW_DATA_IN == 2
		int32 tmp = status;
		if (tmp > 32)
			tmp = 32;
		DumpPacket(&recvbuf[recvbuf_used], status);
	#elif TCPN_LOG_RAW_DATA_IN >= 3
		DumpPacket(&recvbuf[recvbuf_used], status);
	#endif
#endif
		recvbuf_used += status;
		if (!ProcessReceivedData(errbuf))
			return false;
	}
	else if (status == SOCKET_ERROR) {
#ifdef _WINDOWS
		if (!(WSAGetLastError() == WSAEWOULDBLOCK)) {
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Error: %i", WSAGetLastError());
			return false;
		}
#else
		if (!(errno == EWOULDBLOCK)) {
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Error: %s", strerror(errno));
			return false;
		}
#endif
	} else if (status == 0) {
		snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Connection closed");
		return false;
	}

	return true;
}
Beispiel #29
0
bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	int32 base = 0;
	int32 size = 7;
	uchar* buffer;
	ServerPacket* pack = 0;
	while ((recvbuf_used - base) >= size) {
		EmuTCPNetPacket_Struct* tnps = (EmuTCPNetPacket_Struct*) &recvbuf[base];
		buffer = tnps->buffer;
		size = tnps->size;
		if (size >= MaxTCPReceiveBuffferSize) {
#if TCPN_DEBUG_Memory >= 1
			std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl;
			DumpPacket(&recvbuf[base], 16);
#endif
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize");
			return false;
		}
		if ((recvbuf_used - base) >= size) {
			// ok, we got enough data to make this packet!
			pack = new ServerPacket;
			pack->size = size - sizeof(EmuTCPNetPacket_Struct);
			// read headers
			pack->opcode = tnps->opcode;
			if (tnps->flags.compressed) {
				pack->compressed = true;
				pack->InflatedSize = *((int32*)buffer);
				pack->size -= 4;
				buffer += 4;
			}
			if (tnps->flags.destination) {
				pack->destination = *((int32*)buffer);
				pack->size -= 4;
				buffer += 4;
			}
			// end read headers
			if (pack->size > 0) {
				if (tnps->flags.compressed) {
					// Lets decompress the packet here
					pack->compressed = false;
					pack->pBuffer = new uchar[pack->InflatedSize];
					pack->size = InflatePacket(buffer, pack->size, pack->pBuffer, pack->InflatedSize);
				}
				else {
					pack->pBuffer = new uchar[pack->size];
					memcpy(pack->pBuffer, buffer, pack->size);
				}
			}
			if (pack->opcode == 0) {
				if (pack->size) {
					#if TCPN_DEBUG >= 2
						std::cout << "Received TCP Network layer packet" << std::endl;
					#endif
					ProcessNetworkLayerPacket(pack);
				}
				#if TCPN_DEBUG >= 5
					else {
						std::cout << "Received TCP keepalive packet. (opcode=0)" << std::endl;
					}
				#endif
				// keepalive, no need to process
				safe_delete(pack);
			}
			else {
				#if TCPN_LOG_PACKETS >= 1
					if (pack && pack->opcode != 0) {
						struct in_addr	in;
						in.s_addr = GetrIP();
						CoutTimestamp(true);
						std::cout << ": Logging incoming TCP packet. OPCode: 0x" << hex << setw(4) << setfill('0') << pack->opcode << dec << ", size: " << setw(5) << setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
						#if TCPN_LOG_PACKETS == 2
							if (pack->size >= 32)
								DumpPacket(pack->pBuffer, 32);
							else
								DumpPacket(pack);
						#endif
						#if TCPN_LOG_PACKETS >= 3
							DumpPacket(pack);
						#endif
					}
				#endif
				if (RelayServer && Server && pack->destination) {
					EmuTCPConnection* con = Server->FindConnection(pack->destination);
					if (!con) {
						#if TCPN_DEBUG >= 1
							std::cout << "Error relaying packet: con = 0" << std::endl;
						#endif
						safe_delete(pack);
					}
					else
						con->OutQueuePush(pack);
				}
				else
					OutQueuePush(pack);
			}
			base += size;
			size = 7;
		}
	}
	if (base != 0) {
		if (base >= recvbuf_used) {
			safe_delete_array(recvbuf);
		} else {
			uchar* tmpbuf = new uchar[recvbuf_size - base];
			memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base);
			safe_delete_array(recvbuf);
			recvbuf = tmpbuf;
			recvbuf_used -= base;
			recvbuf_size -= base;
		}
	}
	return true;
}
Beispiel #30
0
bool WorldServer::Process()
{
	ServerPacket *app = nullptr;
	while(app = connection->PopPacket())
	{
		server_log->WorldTrace("Application packet received from server: 0x%.4X, (size %u)", app->opcode, app->size);

		if (server_log->DumpIn())
		{
			DumpPacket(app);
		}

		switch(app->opcode)
		{
		case ServerOP_NewLSInfo:
			{
				if(app->size < sizeof(ServerNewLSInfo_Struct))
				{
					server_log->Log(log_network_error, "Received application packet from server that had opcode ServerOP_NewLSInfo, "
						"but was too small. Discarded to avoid buffer overrun.");
					break;
				}

				server_log->WorldTrace("New Login Info Received.");
				ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)app->pBuffer;
				Handle_NewLSInfo(info);
				break;
			}
		case ServerOP_LSStatus:
			{
				if(app->size < sizeof(ServerLSStatus_Struct))
				{
					server_log->Log(log_network_error, "Received application packet from server that had opcode ServerOP_LSStatus, "
						"but was too small. Discarded to avoid buffer overrun.");
					break;
				}

				server_log->WorldTrace("World Server Status Received.");

				ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)app->pBuffer;
				Handle_LSStatus(ls_status);
				break;
			}
		case ServerOP_LSZoneInfo:
		case ServerOP_LSZoneShutdown:
		case ServerOP_LSZoneStart:
		case ServerOP_LSZoneBoot:
		case ServerOP_LSZoneSleep:
		case ServerOP_LSPlayerLeftWorld:
		case ServerOP_LSPlayerJoinWorld:
		case ServerOP_LSPlayerZoneChange:
			{
				//Not logging these to cut down on spam until we implement them
				break;
			}

		case ServerOP_UsertoWorldResp:
			{
				if(app->size < sizeof(UsertoWorldResponse_Struct))
				{
					server_log->Log(log_network_error, "Received application packet from server that had opcode ServerOP_UsertoWorldResp, "
						"but was too small. Discarded to avoid buffer overrun.");
					break;
				}

				//I don't use world trace for this and here is why:
				//Because this is a part of the client login procedure it makes tracking client errors
				//While keeping world server spam with multiple servers connected almost impossible.
				server_log->Trace("User-To-World Response received.");

				UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)app->pBuffer;
				server_log->Log(log_client, "Trying to find client with user id of %u.", utwr->lsaccountid);
				Client *c = server.CM->GetClient(utwr->lsaccountid);
				if(c && c->GetClientVersion() == cv_old)
				{
					if(utwr->response > 0)
					{
						SendClientAuth(c->GetConnection()->GetRemoteIP(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), c->GetMacClientVersion());
					}

					switch(utwr->response)
					{
						case 1:
							break;
						case 0:
							c->FatalError("\nError 1020: Your chosen World Server is DOWN.\n\nPlease select another.");
							break;
						case -1:
							c->FatalError("You have been suspended from the worldserver.");
							break;
						case -2:
							c->FatalError("You have been banned from the worldserver.");
							break;
						case -3:
							c->FatalError("That server is full.");
							break;
						case -4:
							c->FatalError("Error 1018: You currently have an active character on that EverQuest Server, please allow a minute for synchronization and try again.");
							break;
						case -5:
							c->FatalError("Error IP Limit Exceeded: \n\nYou have exceeded the maximum number of allowed IP addresses for this account.");
							break;
					}
					server_log->Log(log_client, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str());
					EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestRequest, 17);
					strncpy((char*) &outapp->pBuffer[1], c->GetKey().c_str(), c->GetKey().size());

					c->SendPlayResponse(outapp);
				}
				else if(c)
				{
					server_log->Log(log_client, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str());
					EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct));
					PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer;
					per->Sequence = c->GetPlaySequence();
					per->ServerNumber = c->GetPlayServerID();
					server_log->Log(log_client, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
					server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size);

					if (utwr->response > 0)
					{
						per->Allowed = 1;
						SendClientAuth(c->GetConnection()->GetRemoteIP(), c->GetAccountName(), c->GetKey(), c->GetAccountID());
					}

					switch (utwr->response)
					{
					case 1:
						per->Message = 101;
						break;
					case 0:
						per->Message = 326;
						break;
					case -1:
						per->Message = 337;
						break;
					case -2:
						per->Message = 338;
						break;
					case -3:
						per->Message = 303;
						break;
					case -4:
						per->Message = 111;
						break;
					case -5:
						per->Message = 198;
						break;
					}

					server_log->Trace("Sending play response to client.");
					server_log->TracePacket((const char*)outapp->pBuffer, outapp->size);

					if (server_log->DumpOut())
					{
						DumpPacket(outapp);
					}
					c->SendPlayResponse(outapp);
					delete outapp;
				}
				else
				{
					server_log->Log(log_client_error, "Received User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid);
				}
				break;
			}
		case ServerOP_LSAccountUpdate:
			{
				if(app->size < sizeof(ServerLSAccountUpdate_Struct))
				{
					server_log->Log(log_network_error, "Received application packet from server that had opcode ServerLSAccountUpdate_Struct, "
						"but was too small. Discarded to avoid buffer overrun.");
					break;
				}
			
				server_log->Log(log_network_trace, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str());
				ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct*)app->pBuffer;
				if(trusted)
				{
					server_log->Log(log_network_trace, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount);
					string name;
					string password;
					string email;
					name.assign(lsau->useraccount);
					password.assign(lsau->userpassword);
					email.assign(lsau->useremail);
					db.CreateLSAccount(name, password, email, 0, "", "");
				}
				break;
			}
		default:
			{
				server_log->Log(log_network_error, "Received application packet from server that had an unknown operation code 0x%.4X.", app->opcode);
			}
		}
		delete app;
		app = nullptr;
	}
	return true;
}