📄 handle_bnet.c
字号:
return -1; } if (!packet) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL packet", conn_get_socket(c)); return -1; } if (packet_get_class(packet) != packet_class_bnet) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad packet (class %d)", conn_get_socket(c), (int) packet_get_class(packet)); return -1; } switch (conn_get_state(c)) { case conn_state_connected: switch (handle(bnet_htable_con, packet_get_type(packet), c, packet)) { case 1: eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown (unlogged in) bnet packet type 0x%04x, len %u", conn_get_socket(c), packet_get_type(packet), packet_get_size(packet)); break; case -1: eventlog(eventlog_level_error, __FUNCTION__, "[%d] (unlogged in) got error handling packet type 0x%04x, len %u", conn_get_socket(c), packet_get_type(packet), packet_get_size(packet)); break; }; break; case conn_state_loggedin: switch (handle(bnet_htable_log, packet_get_type(packet), c, packet)) { case 1: eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown (logged in) bnet packet type 0x%04x, len %u", conn_get_socket(c), packet_get_type(packet), packet_get_size(packet)); break; case -1: eventlog(eventlog_level_error, __FUNCTION__, "[%d] (logged in) got error handling packet type 0x%04x, len %u", conn_get_socket(c), packet_get_type(packet), packet_get_size(packet)); break; }; break; case conn_state_untrusted: eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown (untrusted) bnet packet type 0x%04x, len %u", conn_get_socket(c), packet_get_type(packet), packet_get_size(packet)); break; default: eventlog(eventlog_level_error, __FUNCTION__, "[%d] invalid login state %d", conn_get_socket(c), conn_get_state(c)); }; return 0;}static int handle(const t_htable_row * htable, int type, t_connection * c, t_packet const *const packet){ t_htable_row const *p; int res = 1; for (p = htable; p->type != -1; p++) if (p->type == type) { res = 0; if (p->handler != NULL) res = p->handler(c, packet); if (res != 2) break; /* return 2 means we want to continue parsing */ } return res;}/* checks if a clienttag is in the allowed_clients list * @ctag : clienttag integer to check * if it's allowed returns 0 * if it's not allowed returns -1 */static int _check_allowed_client(t_clienttag ctag){ char *list, *p, *q; /* by default allow all */ if (!prefs_get_allowed_clients()) return 0; /* this shortcut check should make server as fast as before if * the configuration is left in default mode */ if (!strcasecmp(prefs_get_allowed_clients(), "all")) return 0; list = xstrdup(prefs_get_allowed_clients()); p = list; do { q = strchr(p, ','); if (q) *q = '\0'; if (!strcasecmp(p, "all")) goto ok; if (strlen(p) != 4) continue; if (ctag == tag_case_str_to_uint(p)) goto ok; /* client allowed */ if (q) p = q + 1; } while (q); xfree((void *) list); return -1; /* client NOT allowed */ ok: xfree((void *) list); return 0;}/* handlers for bnet packets */static int _client_unknown_1b(t_connection * c, t_packet const *const packet){ if (packet_get_size(packet) < sizeof(t_client_unknown_1b)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad UNKNOWN_1B packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_unknown_1b), packet_get_size(packet)); return -1; } { unsigned int newip; unsigned short newport; eventlog(eventlog_level_debug, __FUNCTION__, "[%d] UNKNOWN_1B unknown1=0x%04hx", conn_get_socket(c), bn_short_get(packet->u.client_unknown_1b.unknown1)); eventlog(eventlog_level_debug, __FUNCTION__, "[%d] UNKNOWN_1B unknown2=0x%08x", conn_get_socket(c), bn_int_get(packet->u.client_unknown_1b.unknown2)); eventlog(eventlog_level_debug, __FUNCTION__, "[%d] UNKNOWN_1B unknown3=0x%08x", conn_get_socket(c), bn_int_get(packet->u.client_unknown_1b.unknown3)); newip = bn_int_nget(packet->u.client_unknown_1b.ip); newport = bn_short_nget(packet->u.client_unknown_1b.port); eventlog(eventlog_level_info, __FUNCTION__, "[%d] UNKNOWN_1B set new UDP address to %s", conn_get_socket(c), addr_num_to_addr_str(newip, newport)); conn_set_game_addr(c, newip); conn_set_game_port(c, newport); } return 0;}static int _client_compinfo1(t_connection * c, t_packet const *const packet){ t_packet *rpacket; if (packet_get_size(packet) < sizeof(t_client_compinfo1)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COMPINFO1 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_compinfo1), packet_get_size(packet)); return -1; } { char const *host; char const *user; if (!(host = packet_get_str_const(packet, sizeof(t_client_compinfo1), MAX_WINHOST_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COMPINFO1 packet (missing or too long host)", conn_get_socket(c)); return -1; } if (!(user = packet_get_str_const(packet, sizeof(t_client_compinfo1) + strlen(host) + 1, MAX_WINUSER_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COMPINFO1 packet (missing or too long user)", conn_get_socket(c)); return -1; } conn_set_host(c, host); conn_set_user(c, user); } if ((rpacket = packet_create(packet_class_bnet))) { packet_set_size(rpacket, sizeof(t_server_compreply)); packet_set_type(rpacket, SERVER_COMPREPLY); bn_int_set(&rpacket->u.server_compreply.reg_version, SERVER_COMPREPLY_REG_VERSION); bn_int_set(&rpacket->u.server_compreply.reg_auth, SERVER_COMPREPLY_REG_AUTH); bn_int_set(&rpacket->u.server_compreply.client_id, SERVER_COMPREPLY_CLIENT_ID); bn_int_set(&rpacket->u.server_compreply.client_token, SERVER_COMPREPLY_CLIENT_TOKEN); conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); } if ((rpacket = packet_create(packet_class_bnet))) { packet_set_size(rpacket, sizeof(t_server_sessionkey1)); packet_set_type(rpacket, SERVER_SESSIONKEY1); bn_int_set(&rpacket->u.server_sessionkey1.sessionkey, conn_get_sessionkey(c)); conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); } return 0;}static int _client_compinfo2(t_connection * c, t_packet const *const packet){ t_packet *rpacket; if (packet_get_size(packet) < sizeof(t_client_compinfo2)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COMPINFO2 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_compinfo2), packet_get_size(packet)); return -1; } { char const *host; char const *user; if (!(host = packet_get_str_const(packet, sizeof(t_client_compinfo2), MAX_WINHOST_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COMPINFO2 packet (missing or too long host)", conn_get_socket(c)); return -1; } if (!(user = packet_get_str_const(packet, sizeof(t_client_compinfo2) + strlen(host) + 1, MAX_WINUSER_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COMPINFO2 packet (missing or too long user)", conn_get_socket(c)); return -1; } conn_set_host(c, host); conn_set_user(c, user); } if ((rpacket = packet_create(packet_class_bnet))) { packet_set_size(rpacket, sizeof(t_server_compreply)); packet_set_type(rpacket, SERVER_COMPREPLY); bn_int_set(&rpacket->u.server_compreply.reg_version, SERVER_COMPREPLY_REG_VERSION); bn_int_set(&rpacket->u.server_compreply.reg_auth, SERVER_COMPREPLY_REG_AUTH); bn_int_set(&rpacket->u.server_compreply.client_id, SERVER_COMPREPLY_CLIENT_ID); bn_int_set(&rpacket->u.server_compreply.client_token, SERVER_COMPREPLY_CLIENT_TOKEN); conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); } if ((rpacket = packet_create(packet_class_bnet))) { packet_set_size(rpacket, sizeof(t_server_sessionkey2)); packet_set_type(rpacket, SERVER_SESSIONKEY2); bn_int_set(&rpacket->u.server_sessionkey2.sessionnum, conn_get_sessionnum(c)); bn_int_set(&rpacket->u.server_sessionkey2.sessionkey, conn_get_sessionkey(c)); conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); } return 0;}static int _client_countryinfo1(t_connection * c, t_packet const *const packet){ if (packet_get_size(packet) < sizeof(t_client_countryinfo1)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COUNTRYINFO1 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_countryinfo1), packet_get_size(packet)); return -1; } { char const *langstr; char const *countrycode; char const *country; unsigned int tzbias; if (!(langstr = packet_get_str_const(packet, sizeof(t_client_countryinfo1), MAX_LANG_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COUNTRYINFO1 packet (missing or too long langstr)", conn_get_socket(c)); return -1; } if (!(countrycode = packet_get_str_const(packet, sizeof(t_client_countryinfo1) + strlen(langstr) + 1, MAX_COUNTRYCODE_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COUNTRYINFO1 packet (missing or too long countrycode)", conn_get_socket(c)); return -1; } if (!(country = packet_get_str_const(packet, sizeof(t_client_countryinfo1) + strlen(langstr) + 1 + strlen(countrycode) + 1, MAX_COUNTRY_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COUNTRYINFO1 packet (missing or too long country)", conn_get_socket(c)); return -1; } if (!(packet_get_str_const(packet, sizeof(t_client_countryinfo1) + strlen(langstr) + 1 + strlen(countrycode) + 1 + strlen(country) + 1, MAX_COUNTRYNAME_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COUNTRYINFO1 packet (missing or too long countryname)", conn_get_socket(c)); return -1; } tzbias = bn_int_get(packet->u.client_countryinfo1.bias); eventlog(eventlog_level_debug, __FUNCTION__, "[%d] COUNTRYINFO1 packet from tzbias=0x%04x(%+d) langstr=%s countrycode=%s country=%s", tzbias, uint32_to_int(tzbias), conn_get_socket(c), langstr, countrycode, country); conn_set_country(c, country); conn_set_tzbias(c, uint32_to_int(tzbias)); } return 0;}static int _client_countryinfo109(t_connection * c, t_packet const *const packet){ t_packet *rpacket; if (packet_get_size(packet) < sizeof(t_client_countryinfo_109)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COUNTRYINFO_109 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_countryinfo_109), packet_get_size(packet)); return -1; } { char const *langstr; char const *countryname; unsigned int tzbias; char archtag_str[5]; char clienttag_str[5]; char gamelang_str[5]; if (!(langstr = packet_get_str_const(packet, sizeof(t_client_countryinfo_109), MAX_LANG_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COUNTRYINFO_109 packet (missing or too long langstr)", conn_get_socket(c)); return -1; } if (!(countryname = packet_get_str_const(packet, sizeof(t_client_countryinfo_109) + strlen(langstr) + 1, MAX_COUNTRYNAME_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad COUNTRYINFO_109 packet (missing or too long countryname)", conn_get_socket(c)); return -1; } /* check if it's an allowed client type */ if (_check_allowed_client(bn_int_get(packet->u.client_countryinfo_109.clienttag))) { conn_set_state(c, conn_state_destroy); return 0; } tzbias = bn_int_get(packet->u.client_countryinfo_109.bias); eventlog(eventlog_level_debug, __FUNCTION__, "[%d] COUNTRYINFO_109 packet tzbias=0x%04x(%+d) lcid=%u langid=%u arch=\"%s\" client=\"%s\" versionid=0x%08x gamelang=\"%s\"", conn_get_socket(c), tzbias, uint32_to_int(tzbias), bn_int_get(packet->u.client_countryinfo_109.lcid), bn_int_get(packet->u.client_countryinfo_109.langid), tag_uint_to_str(archtag_str, bn_int_get(packet->u.client_countryinfo_109.archtag)), tag_uint_to_str(clienttag_str, bn_int_get(packet->u.client_countryinfo_109.clienttag)), bn_int_get(packet->u.client_countryinfo_109.versionid), tag_uint_to_str(gamelang_str, bn_int_get(packet->u.client_countryinfo_109.gamelang))); eventlog(eventlog_level_debug, __FUNCTION__, "[%d] COUNTRYINFO_109 packet from \"%s\" \"%s\"", conn_get_socket(c), countryname, langstr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -