static void IPX_ServerLoop() { UDPpacket inPacket; IPaddress tmpAddr; //char regString[] = "IPX Register\0"; Bit16u i; Bit32u host; Bits result; inPacket.channel = -1; inPacket.data = &inBuffer[0]; inPacket.maxlen = IPXBUFFERSIZE; result = SDLNet_UDP_Recv(ipxServerSocket, &inPacket); if (result != 0) { // Check to see if incoming packet is a registration packet // For this, I just spoofed the echo protocol packet designation 0x02 IPXHeader *tmpHeader; tmpHeader = (IPXHeader *)&inBuffer[0]; // Check to see if echo packet if(SDLNet_Read16(tmpHeader->dest.socket) == 0x2) { // Null destination node means its a server registration packet if(tmpHeader->dest.addr.byIP.host == 0x0) { UnpackIP(tmpHeader->src.addr.byIP, &tmpAddr); for(i=0;i<SOCKETTABLESIZE;i++) { if(!connBuffer[i].connected) { // Use prefered host IP rather than the reported source IP // It may be better to use the reported source ipconn[i] = inPacket.address; connBuffer[i].connected = true; host = ipconn[i].host; LOG_MSG("IPXSERVER: Connect from %d.%d.%d.%d", CONVIP(host)); ackClient(inPacket.address); return; } else { if((ipconn[i].host == tmpAddr.host) && (ipconn[i].port == tmpAddr.port)) { LOG_MSG("IPXSERVER: Reconnect from %d.%d.%d.%d", CONVIP(tmpAddr.host)); // Update anonymous port number if changed ipconn[i].port = inPacket.address.port; ackClient(inPacket.address); return; } } } } } // IPX packet is complete. Now interpret IPX header and send to respective IP address sendIPXPacket((Bit8u *)inPacket.data, inPacket.len); } }
/** * This function is called when the map-serv initialise is chrif interface. * Map-serv sent us his map indexes so we can transfert a player from a map-serv to another when necessary * We reply by sending back the char_serv_wisp_name fame list and * @param fd: wich fd to parse from * @param id: wich map_serv id * @return : 0 not enough data received, 1 success */ int chmapif_parse_getmapname(int fd, int id){ int j = 0, i = 0; if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) return 0; //Retain what map-index that map-serv contains memset(map_server[id].map, 0, sizeof(map_server[id].map)); for(i = 4; i < RFIFOW(fd,2); i += 4) { map_server[id].map[j] = RFIFOW(fd,i); j++; } ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n", id, j, CONVIP(map_server[id].ip), map_server[id].port); ShowStatus("Map-server %d loading complete.\n", id); // send name for wisp to player WFIFOHEAD(fd, 3 + NAME_LENGTH); WFIFOW(fd,0) = 0x2afb; WFIFOB(fd,2) = 0; //0 succes, 1:failure memcpy(WFIFOP(fd,3), charserv_config.wisp_server_name, NAME_LENGTH); WFIFOSET(fd,3+NAME_LENGTH); chmapif_send_fame_list(fd); //Send fame list. { int x; if (j == 0) { ShowWarning("Map-server %d has NO maps.\n", id); } else { unsigned char buf[16384]; // Transmitting maps information to the other map-servers WBUFW(buf,0) = 0x2b04; WBUFW(buf,2) = j * 4 + 10; WBUFL(buf,4) = htonl(map_server[id].ip); WBUFW(buf,8) = htons(map_server[id].port); memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4); chmapif_sendallwos(fd, buf, WBUFW(buf,2)); } // Transmitting the maps of the other map-servers to the new map-server for(x = 0; x < ARRAYLENGTH(map_server); x++) { if (map_server[x].fd > 0 && x != id) { WFIFOHEAD(fd,10 +4*ARRAYLENGTH(map_server[x].map)); WFIFOW(fd,0) = 0x2b04; WFIFOL(fd,4) = htonl(map_server[x].ip); WFIFOW(fd,8) = htons(map_server[x].port); j = 0; for(i = 0; i < ARRAYLENGTH(map_server[x].map); i++) if (map_server[x].map[i]) WFIFOW(fd,10+(j++)*4) = map_server[x].map[i]; if (j > 0) { WFIFOW(fd,2) = j * 4 + 10; WFIFOSET(fd,WFIFOW(fd,2)); } } } } RFIFOSKIP(fd,RFIFOW(fd,2)); return 1; }
/** * This function is called when the map-serv initialise is chrif interface. * Map-serv sent us his map indexes so we can transfert a player from a map-serv to another when necessary * We reply by sending back the char_serv_wisp_name fame list and * @param fd: wich fd to parse from * @param id: wich map_serv id * @return : 0 not enough data received, 1 success */ int chmapif_parse_getmapname(int fd, int id){ int i = 0, j = 0; unsigned char *mapbuf; if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) return 0; //Retain what map-index that map-serv contains memset(map_server[id].map, 0, sizeof(map_server[id].map)); for(i = 4; i < RFIFOW(fd,2); i += 4) { map_server[id].map[j] = RFIFOW(fd,i); j++; } mapbuf = RFIFOP(fd,4); RFIFOSKIP(fd,RFIFOW(fd,2)); ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n", id, j, CONVIP(map_server[id].ip), map_server[id].port); ShowStatus("Map-server %d loading complete.\n", id); chmapif_send_misc(fd); chmapif_send_fame_list(fd); //Send fame list. chmapif_send_maps(fd, id, j, mapbuf); return 1; }
/** * Received new charip from char-serv, update information. * @param fd: char-serv file descriptor * @param id: char-serv id * @return 0 not enough info transmitted, 1 success */ int logchrif_parse_updcharip(int fd, int id){ if( RFIFOREST(fd) < 6 ) return 0; ch_server[id].ip = ntohl(RFIFOL(fd,2)); ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(ch_server[id].ip)); RFIFOSKIP(fd,6); return 1; }
int make_connection(uint32 ip, uint16 port, bool silent) { struct sockaddr_in remote_address; int fd; int result; fd = sSocket(AF_INET, SOCK_STREAM, 0); if(fd == -1) { ShowError(read_message("Source.common.make_connection"), error_msg()); return -1; } if(fd == 0) { // reserved ShowError(read_message("Source.common.make_connection2")); sClose(fd); return -1; } if(fd >= FD_SETSIZE) { // socket number too big ShowError("make_connection: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE); sClose(fd); return -1; } setsocketopts(fd); remote_address.sin_family = AF_INET; remote_address.sin_addr.s_addr = htonl(ip); remote_address.sin_port = htons(port); if(!silent) ShowStatus(read_message("Source.common.make_connect"), CONVIP(ip), port); result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in)); if(result == SOCKET_ERROR) { if(!silent) ShowError(read_message("Source.common.make_sConnect"), fd, error_msg()); do_close(fd); return -1; } //Now the socket can be made non-blocking. [Skotlex] set_nonblocking(fd, 1); if(fd_max <= fd) fd_max = fd + 1; sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr); return fd; }
int make_connection(uint32 ip, uint16 port) { struct sockaddr_in remote_address; int fd; int result; fd = sSocket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { ShowError("make_connection: falha ao criar socket (codigo %d)!\n", sErrno); return -1; } if( fd == 0 ) {// reserved ShowError("make_connection: Socket #0 e reservado - Favor reportar isso!!!\n"); sClose(fd); return -1; } if( fd >= FD_SETSIZE ) {// socket number too big ShowError("Novo socket #%d e maior do que suportamos! aumente o valor de FD_SETSIZE (atualmente %d) para seu SO consertar isso!\n", fd, FD_SETSIZE); sClose(fd); return -1; } setsocketopts(fd); remote_address.sin_family = AF_INET; remote_address.sin_addr.s_addr = htonl(ip); remote_address.sin_port = htons(port); ShowStatus("Conectando a %d.%d.%d.%d:%i\n", CONVIP(ip), port); result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in)); if( result == SOCKET_ERROR ) { ShowError("make_connection: conexao falhou (socket #%d, codigo %d)!\n", fd, sErrno); do_close(fd); return -1; } //Now the socket can be made non-blocking. [Skotlex] set_nonblocking(fd, 1); if (fd_max <= fd) fd_max = fd + 1; sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr); return fd; }
// remove specified maps (used when some other map-server disconnects) int chrif_removemap(int fd) { int i, j; uint32 ip = RFIFOL(fd,4); uint16 port = RFIFOW(fd,8); for(i = 10, j = 0; i < RFIFOW(fd, 2); i += 4, j++) map_eraseipport(RFIFOW(fd, i), ip, port); other_mapserver_count--; if(battle_config.etc_log) ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j); return 0; }
int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt) { struct sockaddr_in remote_address; int fd; int result; fd = sSocket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { ShowError("make_connection: socket creation failed (%s)!\n", error_msg()); return -1; } if( fd == 0 ) {// reserved ShowError("make_connection: Socket #0 is reserved - Please report this!!!\n"); sClose(fd); return -1; } if( fd >= FD_SETSIZE ) {// socket number too big ShowError("make_connection: New socket #%d is greater than can we handle! Increase the value of FD_SETSIZE (currently %d) for your OS to fix this!\n", fd, FD_SETSIZE); sClose(fd); return -1; } setsocketopts(fd,opt); remote_address.sin_family = AF_INET; remote_address.sin_addr.s_addr = htonl(ip); remote_address.sin_port = htons(port); if( !( opt && opt->silent ) ) ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port); result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in)); if( result == SOCKET_ERROR ) { if( !( opt && opt->silent ) ) ShowError("make_connection: connect failed (socket #%d, %s)!\n", fd, error_msg()); sockt->close(fd); return -1; } //Now the socket can be made non-blocking. [Skotlex] set_nonblocking(fd, 1); if (sockt->fd_max <= fd) sockt->fd_max = fd + 1; sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr); return fd; }
int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt) { struct sockaddr_in remote_address = { 0 }; int fd; int result; fd = sSocket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { ShowError("make_connection: Criacao de socket falhou (%s)!\n", error_msg()); return -1; } if( fd == 0 ) {// reserved ShowError("make_connection: Socket #0 esta reservado - Por favor reporte isso!!!\n"); sClose(fd); return -1; } if( fd >= FD_SETSIZE ) {// socket number too big ShowError("make_connection: Novo socket #%d e maior do que o limite suportado! Aumentando o valor para FD_SETSIZE (atualmente %d) seu SO deve corrigir isso!\n", fd, FD_SETSIZE); sClose(fd); return -1; } setsocketopts(fd,opt); remote_address.sin_family = AF_INET; remote_address.sin_addr.s_addr = htonl(ip); remote_address.sin_port = htons(port); if( !( opt && opt->silent ) ) ShowStatus("Conectando-se a %d.%d.%d.%d:%i\n", CONVIP(ip), port); result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in)); if( result == SOCKET_ERROR ) { if( !( opt && opt->silent ) ) ShowError("make_connection: Falha na conexao (socket #%d, %s)!\n", fd, error_msg()); sockt->close(fd); return -1; } //Now the socket can be made non-blocking. [Skotlex] set_nonblocking(fd, 1); if (sockt->fd_max <= fd) sockt->fd_max = fd + 1; sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr); return fd; }
// receive maps from some other map-server (relayed via char-server) int chrif_recvmap(int fd) { int i, j; uint32 ip = ntohl(RFIFOL(fd,4)); uint16 port = ntohs(RFIFOW(fd,8)); for(i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) { map_setipport(RFIFOW(fd,i), ip, port); } if (battle_config.etc_log) ShowStatus("Received maps from %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j); other_mapserver_count++; return 0; }
void _FASTCALL harmony_log(int fd, const char *msg) { char ip[20]; TBL_PC *sd = (TBL_PC*)session[fd]->session_data; if (!sd) return; sprintf(ip, "%u.%u.%u.%u", CONVIP(session[fd]->client_addr)); if (log_method == LOG_SQL && !harmony_log_sql(sd, ip, msg)) { ShowError("Logging to harmony_log failed. Please check your Harmony setup.\n"); } else if (log_method == LOG_TRYSQL && log_stmt && harmony_log_sql(sd, ip, msg)) { ; } else if (log_method == LOG_TXT || log_method == LOG_TRYSQL) { harmony_log_txt(sd, ip, msg); } ShowMessage(""CL_MAGENTA"[Harmony]"CL_RESET": %s (Player: %s, IP: %s)\n", msg, sd->status.name, ip); }
size_t to_server_list_result(char* buf, const Packet* packet) { ServerListHeader* header = (ServerListHeader*)packet->param.Data; uint16 count = header->server_count; size_t res = 47 + 32 * count; memset(buf, 0, res); PUINT16(buf, 0) = 0x69; // opcode. PUINT16(buf, 2) = res; // length :-) uint32 id1 = header->id1; uint32 id2 = header->id2; uint32 account = header->account; uint8 sex = header->sex; uint32 ip = header->ip; PUINT32(buf, 4) = id1; PUINT32(buf, 8) = account; PUINT32(buf, 12) = id2; PUINT32(buf, 16) = 0; PUINT16(buf, 44) = 0; // unknown PUINT8(buf, 46) = sex_str2num(sex); int i = 0; for (; i < count; ++i) { ServerInfo* info = (ServerInfo*)(packet->param.Data + sizeof(ServerListHeader) + sizeof(ServerInfo) * i); uint32 subnet_char_ip = lan_subnetcheck(ip); PUINT32(buf, 47 + i * 32) = htonl((subnet_char_ip) ? subnet_char_ip : info->ip); printf("IP of Server : %d.%d.%d.%d.\n", CONVIP(info->ip)); printf("Port of Server : %d\n", info->port); PUINT16(buf, 47 + i * 32 + 4) = ntows(htons(info->port)); memcpy(PCHAR(buf, 47 + i * 32 + 6), info->name, 20); PUINT16(buf, 47 + i * 32 + 26) = info->users;// users PUINT16(buf, 47 + i * 32 + 28) = info->maintenance; // maintenance PUINT16(buf, 47 + i * 32 + 30) = info->new_; // new_ } return res; }
/** * Char-server request to connect to the login-server. * This is needed to exchange packets. * @param fd: file descriptor to parse from (client) * @param sd: client session * @param ip: ipv4 address (client) * @return 0 packet received too shirt, 1 success */ static int logclif_parse_reqcharconnec(int fd, struct login_session_data *sd, char* ip){ if (RFIFOREST(fd) < 86) return 0; else { int result; char server_name[20]; char message[256]; uint32 server_ip; uint16 server_port; uint16 type; uint16 new_; safestrncpy(sd->userid, RFIFOCP(fd,2), NAME_LENGTH); safestrncpy(sd->passwd, RFIFOCP(fd,26), NAME_LENGTH); if( login_config.use_md5_passwds ) MD5_String(sd->passwd, sd->passwd); sd->passwdenc = 0; server_ip = ntohl(RFIFOL(fd,54)); server_port = ntohs(RFIFOW(fd,58)); safestrncpy(server_name, RFIFOCP(fd,60), 20); type = RFIFOW(fd,82); new_ = RFIFOW(fd,84); RFIFOSKIP(fd,86); ShowInfo("Connection request of the char-server '%s' @ %u.%u.%u.%u:%u (account: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, sd->userid, ip); sprintf(message, "charserver - %s@%u.%u.%u.%u:%u", server_name, CONVIP(server_ip), server_port); login_log(session[fd]->client_addr, sd->userid, 100, message); result = login_mmo_auth(sd, true); if( runflag == LOGINSERVER_ST_RUNNING && result == -1 && sd->sex == 'S' && sd->account_id < ARRAYLENGTH(ch_server) && !session_isValid(ch_server[sd->account_id].fd) ) { ShowStatus("Connection of the char-server '%s' accepted.\n", server_name); safestrncpy(ch_server[sd->account_id].name, server_name, sizeof(ch_server[sd->account_id].name)); ch_server[sd->account_id].fd = fd; ch_server[sd->account_id].ip = server_ip; ch_server[sd->account_id].port = server_port; ch_server[sd->account_id].users = 0; ch_server[sd->account_id].type = type; ch_server[sd->account_id].new_ = new_; session[fd]->func_parse = logchrif_parse; session[fd]->flag.server = 1; realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); // send connection success WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x2711; WFIFOB(fd,2) = 0; WFIFOSET(fd,3); } else { ShowNotice("Connection of the char-server '%s' REFUSED.\n", server_name); WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x2711; WFIFOB(fd,2) = 3; WFIFOSET(fd,3); } } return 1; }
int make_connection(uint32 ip, uint16 port) { struct sockaddr_in remote_address; int fd; int result; fd = sSocket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { ShowError("make_connection: criação do socket falhou ("CL_RED"%s"CL_RESET")!\n", error_msg()); return -1; } if( fd == 0 ) {// reserved ShowError("make_connection: Socket #"CL_WHITE"0"CL_RESET" é reservado - Reporte isso!\n"); sClose(fd); return -1; } if( fd >= FD_SETSIZE ) {// socket number too big ShowError("make_connection: Novo socket #"CL_WHITE"%d"CL_RESET" é maior que o que suporta-se! Aumente o valor do FD_SETSIZE (atualemente "CL_WHITE"%d"CL_RESET") para seu SO consertar isso!\n", fd, FD_SETSIZE); sClose(fd); return -1; } setsocketopts(fd); remote_address.sin_family = AF_INET; remote_address.sin_addr.s_addr = htonl(ip); remote_address.sin_port = htons(port); ShowStatus("Conectando-se a "CL_WHITE"%d.%d.%d.%d"CL_RESET":"CL_WHITE"%i"CL_RESET"\n", CONVIP(ip), port); result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in)); if( result == SOCKET_ERROR ) { ShowError("make_connection: conexão falhou (soquete #"CL_WHITE"%d"CL_RESET", "CL_WHITE"%s"CL_RESET")!\n", fd, error_msg()); do_close(fd); return -1; } //Now the socket can be made non-blocking. [Skotlex] set_nonblocking(fd, 1); if (fd_max <= fd) fd_max = fd + 1; sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); session[fd]->client_addr = ntohl(remote_address.sin_addr.s_addr); return fd; }