diff options
Diffstat (limited to 'src/lib/protocols/source_engine.c')
-rw-r--r-- | src/lib/protocols/source_engine.c | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/src/lib/protocols/source_engine.c b/src/lib/protocols/source_engine.c index 8d92f537e..96d285a07 100644 --- a/src/lib/protocols/source_engine.c +++ b/src/lib/protocols/source_engine.c @@ -1,7 +1,7 @@ /* * source_engine.c * - * Source Engine Protocol + * Source Engine Protocol (Valveās A2S protocol) * * Copyright (C) 2023 - ntop.org * @@ -45,45 +45,59 @@ static void ndpi_search_source_engine(struct ndpi_detection_module_struct *ndpi_ struct ndpi_flow_struct *flow) { struct ndpi_packet_struct const * const packet = &ndpi_struct->packet; - char const source_engine_query[] = "Source Engine Query"; - size_t const source_engine_query_len = strlen(source_engine_query); NDPI_LOG_DBG(ndpi_struct, "search Source Engine\n"); - if (packet->payload_packet_len < source_engine_query_len + 1 /* '\0' */) - { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; - } + /* https://developer.valvesoftware.com/wiki/Server_queries */ - if (packet->payload[packet->payload_packet_len - 1] != '\0') + /* A2S request */ + if (current_pkt_from_client_to_server(ndpi_struct, flow) && + (packet->payload_packet_len > 8 && packet->payload_packet_len < 30) && + get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; + if (packet->payload[4] == 'T' || /* A2S_INFO */ + packet->payload[4] == 'U' || /* A2S_PLAYER */ + packet->payload[4] == 'V') /* A2S_RULES */ + { + ndpi_int_source_engine_add_connection(ndpi_struct, flow); + return; + } } - if (strncmp((char const *)&packet->payload[packet->payload_packet_len - source_engine_query_len - 1], - source_engine_query, source_engine_query_len) != 0) + /* A2S response */ + if (current_pkt_from_server_to_client(ndpi_struct, flow)) { - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); - return; + /* Challenge response */ + if (packet->payload_packet_len == 9 && + get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF && + packet->payload[4] == 'A') + { + ndpi_int_source_engine_add_connection(ndpi_struct, flow); + return; + } + + if (packet->payload_packet_len > 30 && /* A reasonable length for euristics */ + get_u_int32_t(packet->payload, 0) == 0xFFFFFFFF) + { + if (packet->payload[4] == 'I' || /* A2S_INFO */ + packet->payload[4] == 'D' || /* A2S_PLAYER */ + packet->payload[4] == 'E') /* A2S_RULES */ + { + ndpi_int_source_engine_add_connection(ndpi_struct, flow); + return; + } + } } - ndpi_int_source_engine_add_connection(ndpi_struct, flow); + NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); } /* ***************************************************** */ -void init_source_engine_dissector(struct ndpi_detection_module_struct *ndpi_struct, - u_int32_t *id) +void init_source_engine_dissector(struct ndpi_detection_module_struct *ndpi_struct) { - ndpi_set_bitmask_protocol_detection("Source_Engine", ndpi_struct, *id, - NDPI_PROTOCOL_SOURCE_ENGINE, - ndpi_search_source_engine, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK - ); - - *id += 1; + register_dissector("Source_Engine", ndpi_struct, + ndpi_search_source_engine, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + 1, NDPI_PROTOCOL_SOURCE_ENGINE); } |