aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_private.h1
-rw-r--r--src/include/ndpi_protocol_ids.h3
-rw-r--r--src/include/ndpi_typedefs.h7
-rw-r--r--src/lib/ndpi_content_match.c.inc2
-rw-r--r--src/lib/ndpi_main.c8
-rw-r--r--src/lib/protocols/csgo.c140
-rw-r--r--src/lib/protocols/http.c5
-rw-r--r--src/lib/protocols/steam.c312
-rw-r--r--src/lib/protocols/steam_datagram_relay.c71
9 files changed, 111 insertions, 438 deletions
diff --git a/src/include/ndpi_private.h b/src/include/ndpi_private.h
index ed246c01f..ad3bf31f7 100644
--- a/src/include/ndpi_private.h
+++ b/src/include/ndpi_private.h
@@ -721,6 +721,7 @@ void init_hl7_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int3
void init_ceph_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_roughtime_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
void init_kcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
+void init_valve_sdr_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id);
#endif
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h
index de3184913..ae350b093 100644
--- a/src/include/ndpi_protocol_ids.h
+++ b/src/include/ndpi_protocol_ids.h
@@ -263,7 +263,7 @@ typedef enum {
NDPI_PROTOCOL_PASTEBIN = 232,
NDPI_PROTOCOL_LINKEDIN = 233,
NDPI_PROTOCOL_SOUNDCLOUD = 234,
- NDPI_PROTOCOL_CSGO = 235, /* Counter-Strike Global Offensive, Dota = 2 */
+ NDPI_PROTOCOL_VALVE_SDR = 235, /* Used by all modern Valve games */
NDPI_PROTOCOL_LISP = 236,
NDPI_PROTOCOL_DIAMETER = 237,
NDPI_PROTOCOL_APPLE_PUSH = 238,
@@ -414,6 +414,7 @@ typedef enum {
NDPI_PROTOCOL_ROUGHTIME = 383,
NDPI_PROTOCOL_PIA = 384,
NDPI_PROTOCOL_KCP = 385,
+ NDPI_PROTOCOL_DOTA2 = 386,
#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_protocol_ids.h"
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 0e8f7a25c..78e2fc7cb 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -919,10 +919,6 @@ struct ndpi_flow_udp_struct {
u_int8_t *quic_reasm_buf_bitmap;
u_int32_t quic_reasm_buf_last_pos;
- /* NDPI_PROTOCOL_CSGO */
- u_int8_t csgo_strid[18],csgo_state,csgo_s2;
- u_int32_t csgo_id2;
-
/* NDPI_PROTOCOL_RDP */
u_int8_t rdp_to_srv[3], rdp_from_srv[3], rdp_to_srv_pkts, rdp_from_srv_pkts;
@@ -1441,9 +1437,6 @@ struct ndpi_flow_struct {
/* NDPI_PROTOCOL_RTMP */
u_int8_t rtmp_stage:2;
- /* NDPI_PROTOCOL_STEAM */
- u_int16_t steam_stage:3, steam_stage1:3, steam_stage2:2, steam_stage3:2;
-
/* NDPI_PROTOCOL_STARCRAFT */
u_int8_t starcraft_udp_stage : 3; // 0-7
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index 6326c226d..f9be668f9 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -961,6 +961,7 @@ static ndpi_protocol_match host_match[] =
{ "steamcommunity.com", "Steam", NDPI_PROTOCOL_STEAM, NDPI_PROTOCOL_CATEGORY_GAME, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
{ ".steamcontent.com", "Steam", NDPI_PROTOCOL_STEAM, NDPI_PROTOCOL_CATEGORY_GAME, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
{ ".steamstatic.com", "Steam", NDPI_PROTOCOL_STEAM, NDPI_PROTOCOL_CATEGORY_GAME, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
+ { ".steamserver.net", "Steam", NDPI_PROTOCOL_STEAM, NDPI_PROTOCOL_CATEGORY_GAME, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
{ "steamcommunity-a.akamaihd.net", "Steam", NDPI_PROTOCOL_STEAM, NDPI_PROTOCOL_CATEGORY_GAME, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
{ ".wechat.com", "WeChat", NDPI_PROTOCOL_WECHAT, NDPI_PROTOCOL_CATEGORY_CHAT, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
@@ -1596,6 +1597,7 @@ static ndpi_protocol_match host_match[] =
{ "digitalassets.tesla.com", "TeslaServices", NDPI_PROTOCOL_TESLA_SERVICES, NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DEFAULT_LEVEL },
{ "privateinternetaccess.com", "PrivateInternetAccess", NDPI_PROTOCOL_PIA, NDPI_PROTOCOL_CATEGORY_VPN, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DEFAULT_LEVEL },
+ { "dota2.com", "Dota2", NDPI_PROTOCOL_DOTA2, NDPI_PROTOCOL_CATEGORY_GAME, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_content_match_host_match.c.inc"
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 316b25ac2..61c01ee5c 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1774,8 +1774,8 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
"Nintendo", NDPI_PROTOCOL_CATEGORY_GAME,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
- ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, 0 /* nw proto */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_CSGO,
- "CSGO", NDPI_PROTOCOL_CATEGORY_GAME,
+ ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, 0 /* nw proto */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_VALVE_SDR,
+ "SteamDatagramRelay", NDPI_PROTOCOL_CATEGORY_GAME,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, 0 /* nw proto */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AJP,
@@ -5598,8 +5598,8 @@ static int ndpi_callback_init(struct ndpi_detection_module_struct *ndpi_str) {
/* AMQP */
init_amqp_dissector(ndpi_str, &a);
- /* CSGO */
- init_csgo_dissector(ndpi_str, &a);
+ /* Steam Datagram Relay */
+ init_valve_sdr_dissector(ndpi_str, &a);
/* LISP */
init_lisp_dissector(ndpi_str, &a);
diff --git a/src/lib/protocols/csgo.c b/src/lib/protocols/csgo.c
deleted file mode 100644
index d1a11950a..000000000
--- a/src/lib/protocols/csgo.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * csgo.c
- *
- * Copyright (C) 2016-2017 Vitaly Lavrov <vel21ripn@gmail.com>
- *
- * This file is part of nDPI, an open source deep packet inspection
- * library based on the OpenDPI and PACE technology by ipoque GmbH
- *
- * nDPI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * nDPI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-#include "ndpi_protocol_ids.h"
-
-#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_CSGO
-
-#include "ndpi_api.h"
-#include "ndpi_private.h"
-
-static void ndpi_search_csgo(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) {
- struct ndpi_packet_struct* packet = &ndpi_struct->packet;
-
- if(packet->udp != NULL) {
- if(packet->payload_packet_len < sizeof(uint32_t)) {
- NDPI_LOG_DBG2(ndpi_struct, "Short csgo packet\n");
- if(flow->packet_counter > 5)
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
- }
-
- uint32_t w = htonl(get_u_int32_t(packet->payload, 0));
- NDPI_LOG_DBG2(ndpi_struct, "CSGO: word %08x\n", w);
-
- if(!flow->l4.udp.csgo_state && packet->payload_packet_len == 23 && w == 0xfffffffful) {
- if(!memcmp(packet->payload + 5, "connect0x", 9)) {
- flow->l4.udp.csgo_state++;
- memcpy(flow->l4.udp.csgo_strid, packet->payload + 5, 18);
- NDPI_LOG_DBG2(ndpi_struct, "Found csgo connect0x\n");
- return;
- }
- }
-
- if(flow->l4.udp.csgo_state == 1 && packet->payload_packet_len >= 42 && w == 0xfffffffful) {
- if(!memcmp(packet->payload + 24, flow->l4.udp.csgo_strid, 18)) {
- flow->l4.udp.csgo_state++;
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CSGO, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
- NDPI_LOG_INFO( ndpi_struct, "found csgo connect0x reply\n");
- return;
- }
- }
-
- if(packet->payload_packet_len == 8 && ( w == 0x3a180000 || w == 0x39180000) ) {
- NDPI_LOG_INFO( ndpi_struct, "found csgo udp 8b\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CSGO, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
- return;
- }
-
- if(packet->payload_packet_len >= 36 && w == 0x01007364) {
- uint32_t w2 = htonl(get_u_int32_t(packet->payload, 4));
- if(w2 == 0x70696e67) {
- NDPI_LOG_INFO( ndpi_struct, "found csgo udp ping\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CSGO, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
- return;
- }
- }
-
- if(packet->payload_packet_len > 6 &&
- flow->l4.udp.csgo_s2 < 3 && (w & 0xffff0000ul) == 0x0d1d0000) {
- uint32_t w2 = get_u_int32_t(packet->payload, 2);
- if(packet->payload_packet_len == 13) {
- if(!flow->l4.udp.csgo_s2) {
- flow->l4.udp.csgo_id2 = w2;
- flow->l4.udp.csgo_s2 = 1;
- NDPI_LOG_DBG2( ndpi_struct, "Found csgo udp 0d1d step1\n");
- return;
- }
-
- if(flow->l4.udp.csgo_s2 == 1 && flow->l4.udp.csgo_id2 == w2) {
- NDPI_LOG_DBG2( ndpi_struct, "Found csgo udp 0d1d step1 DUP\n");
- return;
- }
- flow->l4.udp.csgo_s2 = 3;
- return;
- }
-
- if(packet->payload_packet_len == 15) {
- if(flow->l4.udp.csgo_s2 == 1 && flow->l4.udp.csgo_id2 == w2) {
- NDPI_LOG_INFO( ndpi_struct, "found csgo udp 0d1d\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CSGO, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
- return;
- }
- }
- flow->l4.udp.csgo_s2 = 3;
- }
-
- if(packet->payload_packet_len >= 140 && (w == 0x02124c6c || w == 0x02125c6c) &&
- !memcmp(&packet->payload[3], "lta\000mob\000tpc\000bhj\000bxd\000tae\000urg\000gkh\000", 32)) {
- NDPI_LOG_INFO( ndpi_struct, "found csgo dictionary udp\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CSGO, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
- return;
- }
-
- if(packet->payload_packet_len >= 33 && packet->iph && packet->iph->daddr == 0xffffffff &&
- !memcmp(&packet->payload[17], "LanSearch", 9)) {
- NDPI_LOG_INFO( ndpi_struct, "found csgo LanSearch udp\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CSGO, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
- return;
- }
-
- if(w == 0) {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
- }
- }
-
- if(flow->packet_counter > 5)
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
-}
-
-void init_csgo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id)
-{
- ndpi_set_bitmask_protocol_detection("CSGO", ndpi_struct, *id,
- NDPI_PROTOCOL_CSGO,
- ndpi_search_csgo,
- NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
- SAVE_DETECTION_BITMASK_AS_UNKNOWN,
- ADD_TO_DETECTION_BITMASK);
-
- *id += 1;
-}
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index 673345b93..8360330cf 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -546,6 +546,11 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp
flow->http.user_agent && strstr(flow->http.user_agent, "MSRPC")) {
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MS_RPCH, master_protocol, NDPI_CONFIDENCE_DPI);
}
+
+ if ((flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) &&
+ flow->http.user_agent && strstr(flow->http.user_agent, "Valve/Steam HTTP Client")) {
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STEAM, master_protocol, NDPI_CONFIDENCE_DPI);
+ }
}
/* ************************************************************* */
diff --git a/src/lib/protocols/steam.c b/src/lib/protocols/steam.c
index 4f5b88308..351279f59 100644
--- a/src/lib/protocols/steam.c
+++ b/src/lib/protocols/steam.c
@@ -1,11 +1,8 @@
/*
* steam.c
*
- * Copyright (C) 2011-22 - ntop.org
+ * Copyright (C) 2011-24 - ntop.org
* Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
- *
- * The signature is mostly based on the Libprotoident library
- * except the detection of HTTP Steam flows.
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -24,6 +21,7 @@
* along with nDPI. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
#include "ndpi_protocol_ids.h"
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_STEAM
@@ -31,296 +29,38 @@
#include "ndpi_api.h"
#include "ndpi_private.h"
-static void ndpi_int_steam_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STEAM, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
-}
-
-static void ndpi_check_steam_http(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &ndpi_struct->packet;
-
- NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet);
- if (packet->user_agent_line.ptr != NULL
- && packet->user_agent_line.len >= 23
- && memcmp(packet->user_agent_line.ptr, "Valve/Steam HTTP Client", 23) == 0) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- }
-}
-
-static void ndpi_check_steam_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &ndpi_struct->packet;
- u_int32_t payload_len = packet->payload_packet_len;
-
- if (flow->steam_stage == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage 0: \n");
-
- if ((payload_len == 1 && packet->payload[0] == 0x01) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x01\x00\x00\x00"))) {
- NDPI_LOG_DBG2(ndpi_struct, "Possible STEAM request detected, we will look further for the response..\n");
-
- /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
- flow->steam_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
- return;
- }
-
- if ((payload_len == 1 && packet->payload[0] == 0x00) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x00\x00\x00"))) {
- NDPI_LOG_DBG2(ndpi_struct, "Possible STEAM request detected, we will look further for the response..\n");
-
- /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
- flow->steam_stage = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4
+static void ndpi_search_steam(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
+
+ NDPI_LOG_DBG(ndpi_struct, "search Steam\n");
+
+ /* Steam In-Home Streaming Discovery */
+ if (packet->payload_packet_len >= 40)
+ {
+ if (le64toh(get_u_int64_t(packet->payload, 0)) == 0xA05F4C21FFFFFFFF)
+ {
+ NDPI_LOG_INFO(ndpi_struct, "found Steam In-Home Streaming Discovery\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STEAM,
+ NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
return;
}
- } else if ((flow->steam_stage == 1) || (flow->steam_stage == 2)) {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage %u: \n", flow->steam_stage);
-
- /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
- if ((flow->steam_stage - packet->packet_direction) == 1) {
- return;
- }
-
- /* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len == 1 && packet->payload[0] == 0x00) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x00\x00\x00"))) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- } else {
- NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to STEAM, resetting the stage to 0..\n");
- flow->steam_stage = 0;
- }
- } else if ((flow->steam_stage == 3) || (flow->steam_stage == 4)) {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage %u: \n", flow->steam_stage);
-
- /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
- if ((flow->steam_stage - packet->packet_direction) == 3) {
- return;
- }
-
- /* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len == 1 && packet->payload[0] == 0x01) || ((payload_len == 4 || payload_len == 5) && ndpi_match_strprefix(packet->payload, payload_len, "\x01\x00\x00\x00"))) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- } else {
- NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to STEAM, resetting the stage to 0..\n");
- flow->steam_stage = 0;
- }
}
-}
-static void ndpi_check_steam_udp1(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &ndpi_struct->packet;
- u_int32_t payload_len = packet->payload_packet_len;
-
- if (ndpi_match_strprefix(packet->payload, payload_len, "VS01")) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- return;
- }
-
- /* Check for Steam Datagram Relay (SDR) packets. */
- if (payload_len > 8) {
- u_int64_t n;
-
- /* Necessary as simple cast crashes on ARM */
- memcpy(&n, packet->payload, sizeof(u_int64_t));
-
- if(ndpi_ntohll(n) == 0x0101736470696e67 /* "\x01\x01sdping" */) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM (Steam Datagram Relay)\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- return;
- }
- }
-
- /* Check if we so far detected the protocol in the request or not. */
- if (flow->steam_stage1 == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage 0: \n");
-
- if (ndpi_match_strprefix(packet->payload, payload_len, "\x31\xff\x30\x2e")) {
- NDPI_LOG_DBG2(ndpi_struct, "Possible STEAM request detected, we will look further for the response..\n");
-
- /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
- flow->steam_stage1 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
- return;
- }
-
- if (ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) {
- NDPI_LOG_DBG2(ndpi_struct, "Possible STEAM request detected, we will look further for the response..\n");
-
- /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
- flow->steam_stage1 = packet->packet_direction + 3; // packet_direction 0: stage 3, packet_direction 1: stage 4
- return;
- }
+ /* TODO: implement Steam Remote Play detection */
- } else if ((flow->steam_stage1 == 1) || (flow->steam_stage1 == 2)) {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage %u: \n", flow->steam_stage1);
-
- /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
- if ((flow->steam_stage1 - packet->packet_direction) == 1) {
- return;
- }
-
- /* This is a packet in another direction. Check if we find the proper response. */
- if (ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- } else {
- NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to STEAM, resetting the stage to 0..\n");
- flow->steam_stage1 = 0;
- }
-
- } else if ((flow->steam_stage1 == 3) || (flow->steam_stage1 == 4)) {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage %u: \n", flow->steam_stage1);
-
- /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
- if ((flow->steam_stage1 - packet->packet_direction) == 3) {
- return;
- }
-
- /* This is a packet in another direction. Check if we find the proper response. */
- if (ndpi_match_strprefix(packet->payload, payload_len, "\x31\xff\x30\x2e")) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- } else {
- NDPI_LOG_DBG(ndpi_struct, "The reply did not seem to belong to STEAM, resetting the stage to 0..\n");
- flow->steam_stage1 = 0;
- }
-
- }
-}
-
-static void ndpi_check_steam_udp2(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &ndpi_struct->packet;
- u_int32_t payload_len = packet->payload_packet_len;
-
- /* Check if we so far detected the protocol in the request or not. */
- if (flow->steam_stage2 == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage 0: \n");
-
- if ((payload_len == 25) && ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) {
- NDPI_LOG_DBG2(ndpi_struct, "Possible STEAM request detected, we will look further for the response..\n");
-
- /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
- flow->steam_stage2 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
- }
-
- } else {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage %u: \n", flow->steam_stage2);
-
- /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
- if ((flow->steam_stage2 - packet->packet_direction) == 1) {
- return;
- }
-
- /* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len == 0) || ndpi_match_strprefix(packet->payload, payload_len, "\xff\xff\xff\xff")) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- } else {
- NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to STEAM, resetting the stage to 0..\n");
- flow->steam_stage2 = 0;
- }
-
- }
-}
-
-static void ndpi_check_steam_udp3(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &ndpi_struct->packet;
- u_int32_t payload_len = packet->payload_packet_len;
-
- /* Check if we so far detected the protocol in the request or not. */
- if (flow->steam_stage3 == 0) {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage 0: \n");
-
- if ((payload_len == 4) && (packet->payload[0] == 0x39) && (packet->payload[1] == 0x18) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x00)) {
- NDPI_LOG_DBG2(ndpi_struct, "Possible STEAM request detected, we will look further for the response..\n");
-
- /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
- flow->steam_stage3 = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2
- }
-
- } else {
- NDPI_LOG_DBG2(ndpi_struct, "STEAM stage %u: \n", flow->steam_stage3);
-
- /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
- if ((flow->steam_stage3 - packet->packet_direction) == 1) {
- return;
- }
-
- /* This is a packet in another direction. Check if we find the proper response. */
- if ((payload_len == 8) && (packet->payload[0] == 0x3a) && (packet->payload[1] == 0x18) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x00)) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
- } else {
- NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to STEAM, resetting the stage to 0..\n");
- flow->steam_stage3 = 0;
- }
-
- }
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}
-static void ndpi_check_steamdiscover(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &ndpi_struct->packet;
- const u_int32_t payload_len = packet->payload_packet_len;
- const u_int64_t signature = ndpi_ntohll(0xffffffff214c5fa0);
-
- if (payload_len < 8)
- return;
-
- if (get_u_int64_t(packet->payload, 0) != signature)
- return;
-
- NDPI_LOG_INFO(ndpi_struct, "found STEAM (steamdiscover)\n");
- ndpi_int_steam_add_connection(ndpi_struct, flow);
-}
-
-static void ndpi_search_steam(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- struct ndpi_packet_struct *packet = &ndpi_struct->packet;
-
- if(packet->udp != NULL) {
- if(flow->packet_counter > 5) {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
- }
-
- ndpi_check_steam_udp1(ndpi_struct, flow);
-
- if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM)
- return;
-
- ndpi_check_steam_udp2(ndpi_struct, flow);
-
- if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM)
- return;
-
- ndpi_check_steam_udp3(ndpi_struct, flow);
-
- ndpi_check_steamdiscover(ndpi_struct, flow);
- } else {
- /* Break after 10 packets. */
- if(flow->packet_counter > 10) {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
- }
-
- NDPI_LOG_DBG(ndpi_struct, "search STEAM\n");
- ndpi_check_steam_http(ndpi_struct, flow);
-
- if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM)
- return;
-
- ndpi_check_steam_tcp(ndpi_struct, flow);
-
- if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_STEAM)
- return;
- }
-}
-
-
-void init_steam_dissector(struct ndpi_detection_module_struct *ndpi_struct,
- u_int32_t *id) {
+void init_steam_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id)
+{
ndpi_set_bitmask_protocol_detection("Steam", ndpi_struct, *id,
- NDPI_PROTOCOL_STEAM,
- ndpi_search_steam,
- NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
- SAVE_DETECTION_BITMASK_AS_UNKNOWN,
- ADD_TO_DETECTION_BITMASK);
+ NDPI_PROTOCOL_STEAM,
+ ndpi_search_steam,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
*id += 1;
}
diff --git a/src/lib/protocols/steam_datagram_relay.c b/src/lib/protocols/steam_datagram_relay.c
new file mode 100644
index 000000000..27d5966c9
--- /dev/null
+++ b/src/lib/protocols/steam_datagram_relay.c
@@ -0,0 +1,71 @@
+/*
+ * steam_datagram_relay.c
+ *
+ * Copyright (C) 2024 - ntop.org
+ * Copyright (C) 2024 - V.G <jacendi@protonmail.com>
+ *
+ * This file is part of nDPI, an open source deep packet inspection
+ * library based on the OpenDPI and PACE technology by ipoque GmbH
+ *
+ * nDPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ndpi_protocol_ids.h"
+
+#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_VALVE_SDR
+
+#include "ndpi_api.h"
+#include "ndpi_private.h"
+
+static void ndpi_int_valve_sdr_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ NDPI_LOG_INFO(ndpi_struct, "found Steam Datagram Relay\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_VALVE_SDR,
+ NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
+}
+
+static void ndpi_search_valve_sdr(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
+
+ NDPI_LOG_DBG(ndpi_struct, "search Steam Datagram Relay\n");
+
+ /* Shortest ping packet I've ever seen. It's actually only 30 bytes long,
+ * but the rest is filled with zeros. */
+ if (packet->payload_packet_len >= 100) {
+ if (memcmp(&packet->payload[2], "sdping", NDPI_STATICSTRING_LEN("sdping")) == 0)
+ {
+ ndpi_int_valve_sdr_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+}
+
+void init_valve_sdr_dissector(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id)
+{
+ ndpi_set_bitmask_protocol_detection("SteamDatagramRelay", ndpi_struct, *id,
+ NDPI_PROTOCOL_VALVE_SDR,
+ ndpi_search_valve_sdr,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+
+ *id += 1;
+}