aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2023-07-21 03:39:40 +0200
committerGitHub <noreply@github.com>2023-07-21 03:39:40 +0200
commitfa0bd515b5c4861ba05cb14732da85c98d537386 (patch)
tree1932380d2691b5d5c6540b289b4421c11a1dddfc
parent3edfad01a1bb22b33bd5bafa0ceeb13e27f03e67 (diff)
Add detection of Roblox games (#2054)
-rw-r--r--doc/protocols.rst13
-rw-r--r--src/include/ndpi_protocol_ids.h1
-rw-r--r--src/include/ndpi_typedefs.h3
-rw-r--r--src/lib/inc_generated/ndpi_asn_roblox.c.inc31
-rw-r--r--src/lib/ndpi_content_match.c.inc3
-rw-r--r--src/lib/ndpi_main.c6
-rw-r--r--src/lib/protocols/raknet.c97
-rw-r--r--tests/cfgs/default/pcap/roblox.pcapngbin0 -> 36780 bytes
-rw-r--r--tests/cfgs/default/result/custom_rules_same-ip_multiple_ports.pcapng.out4
-rw-r--r--tests/cfgs/default/result/roblox.pcapng.out35
-rw-r--r--tests/cfgs/default/result/synscan.pcap.out4
-rwxr-xr-xutils/asn_update.sh5
12 files changed, 175 insertions, 27 deletions
diff --git a/doc/protocols.rst b/doc/protocols.rst
index 530a42666..468489acf 100644
--- a/doc/protocols.rst
+++ b/doc/protocols.rst
@@ -77,3 +77,16 @@ References: `Main site https://protonvpn.com/`
Apache Thrift is a generic data interchange framework that supports a bunch of different languages and platforms.
References: `Official site <https://thrift.apache.org>`_ `Github <https://github.com/apache/thrift>`_.
+
+
+.. _Proto 346:
+
+`NDPI_PROTOCOL_ROBLOX`
+=====================
+Roblox is an online game platform and game creation system.
+
+References: `Main site <https://www.roblox.com/>`_.
+
+Notes:
+
+- Since Roblox games use a custom version of the RakNet protocol, some Roblox flows might be classified as RakNet.
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h
index 7f9bb7c50..099127dff 100644
--- a/src/include/ndpi_protocol_ids.h
+++ b/src/include/ndpi_protocol_ids.h
@@ -374,6 +374,7 @@ typedef enum {
NDPI_PROTOCOL_BITCOIN = 343,
NDPI_PROTOCOL_PROTONVPN = 344,
NDPI_PROTOCOL_APACHE_THRIFT = 345,
+ NDPI_PROTOCOL_ROBLOX = 346,
#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 9c1f353c6..08ba99ef0 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -862,6 +862,9 @@ struct ndpi_flow_udp_struct {
u_int32_t epicgames_stage:1;
u_int32_t epicgames_word;
+ /* NDPI_PROTOCOL_RAKNET */
+ u_int32_t raknet_custom:1;
+
/* NDPI_PROTOCOL_SKYPE */
u_int8_t skype_crc[4];
diff --git a/src/lib/inc_generated/ndpi_asn_roblox.c.inc b/src/lib/inc_generated/ndpi_asn_roblox.c.inc
new file mode 100644
index 000000000..402b65690
--- /dev/null
+++ b/src/lib/inc_generated/ndpi_asn_roblox.c.inc
@@ -0,0 +1,31 @@
+/*
+ *
+ * This file is generated automatically and part of nDPI
+ *
+ * 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/>.
+ *
+ */
+
+/* ****************************************************** */
+
+
+static ndpi_network ndpi_protocol_roblox_protocol_list[] = {
+ { 0x678C1C00 /* 103.140.28.0/23 */, 23, NDPI_PROTOCOL_ROBLOX },
+ { 0x80740000 /* 128.116.0.0/17 */, 17, NDPI_PROTOCOL_ROBLOX },
+ { 0x8DC10300 /* 141.193.3.0/24 */, 24, NDPI_PROTOCOL_ROBLOX },
+ { 0xCDC93E00 /* 205.201.62.0/24 */, 24, NDPI_PROTOCOL_ROBLOX },
+ { 0xD1CE2800 /* 209.206.40.0/21 */, 21, NDPI_PROTOCOL_ROBLOX },
+ /* End */
+ { 0x0, 0, 0 }
+};
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index f3731bfbf..f6faf72ca 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -1396,6 +1396,9 @@ static ndpi_protocol_match host_match[] =
{ "proton.me", "ProtonVPN", NDPI_PROTOCOL_PROTONVPN, NDPI_PROTOCOL_CATEGORY_VPN, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DEFAULT_LEVEL },
{ "protonvpn.com", "ProtonVPN", NDPI_PROTOCOL_PROTONVPN, NDPI_PROTOCOL_CATEGORY_VPN, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_DEFAULT_LEVEL },
+ { "roblox.com", "Roblox", NDPI_PROTOCOL_ROBLOX, NDPI_PROTOCOL_CATEGORY_GAME, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
+ { "rbxcdn.com", "Roblox", NDPI_PROTOCOL_ROBLOX, NDPI_PROTOCOL_CATEGORY_GAME, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_DEFAULT_LEVEL },
+
/*
ADS/tracking/analytic
*/
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 65257593e..83c3b786e 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -110,6 +110,7 @@
#include "inc_generated/ndpi_asn_hulu.c.inc"
#include "inc_generated/ndpi_asn_epicgames.c.inc"
#include "inc_generated/ndpi_asn_nvidia.c.inc"
+#include "inc_generated/ndpi_asn_roblox.c.inc"
/* Third party libraries */
#include "third_party/include/ndpi_patricia.h"
@@ -2108,6 +2109,10 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
"Thrift", NDPI_PROTOCOL_CATEGORY_RPC,
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, 0 /* encrypted */, 1 /* app proto */, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_ROBLOX,
+ "Roblox", 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 */);
#ifdef CUSTOM_NDPI_PROTOCOLS
@@ -2874,6 +2879,7 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_hulu_protocol_list);
ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_epicgames_protocol_list);
ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_nvidia_protocol_list);
+ ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, ndpi_protocol_roblox_protocol_list);
}
if(prefs & ndpi_track_flow_payload)
diff --git a/src/lib/protocols/raknet.c b/src/lib/protocols/raknet.c
index d1deaec22..49db3cc55 100644
--- a/src/lib/protocols/raknet.c
+++ b/src/lib/protocols/raknet.c
@@ -46,6 +46,43 @@ static size_t raknet_dissect_ip(struct ndpi_packet_struct * const packet, size_t
return (packet->payload[offset] == 0x04 ? 4 : 16);
}
+static int is_custom_version(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &ndpi_struct->packet;
+ unsigned char magic[] = { 0x00, 0xFF, 0xFF, 0x00, 0xFE, 0xFE, 0xFE, 0xFE,
+ 0xFD, 0xFD, 0xFD, 0xFD, 0x12, 0x34, 0x56, 0x78 };
+
+ if (packet->payload_packet_len >= 1200) /* Full MTU packet */
+ {
+ /* Offset 32 has been found only in the traces; the other ones are present
+ also in the Raknet heuristic in Wireshark */
+ if (memcmp(magic, &packet->payload[1], sizeof(magic)) == 0 ||
+ memcmp(magic, &packet->payload[9], sizeof(magic)) == 0 ||
+ memcmp(magic, &packet->payload[17], sizeof(magic)) == 0 ||
+ memcmp(magic, &packet->payload[32], sizeof(magic)) == 0)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void exclude_proto(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ if (flow->l4.udp.raknet_custom == 1)
+ {
+ NDPI_LOG_INFO(ndpi_struct, "found RakNet (custom version)\n");
+ /* Classify as Raknet or as Roblox?
+ This pattern ha been observed with Roblox games but it might be used by
+ other protocols too. Keep the generic classification, for the time being */
+ ndpi_int_raknet_add_connection(ndpi_struct, flow);
+ } else {
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ }
+}
+
/* Reference: https://wiki.vg/Raknet_Protocol */
static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow)
@@ -55,9 +92,23 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
NDPI_LOG_DBG(ndpi_struct, "search RakNet\n");
- if (packet->udp == NULL || packet->payload_packet_len < 7)
+ /* There are two "versions" of Raknet:
+ * plaintext one: we need multiple packets for classification and for extracting metadata
+ * custom/encrypted one: an extension used by Roblox games (and others?).
+ Only the first pkt is required.
+ The main issue is that these two versions "overlap", i.e. some plaintext flows might be wrongly
+ identified as encrypted one (losing their metadata).
+ Solution: check for the custoom/encrypted version, cache the result and use it only if/when the
+ standard detection ends.
+ */
+ if (flow->packet_counter == 1)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ flow->l4.udp.raknet_custom = is_custom_version(ndpi_struct, flow);
+ }
+
+ if (packet->payload_packet_len < 7)
+ {
+ exclude_proto(ndpi_struct, flow);
return;
}
@@ -68,7 +119,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
case 0x00: /* Connected Ping */
if (packet->payload_packet_len != 8)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
required_packets = 6;
@@ -78,7 +129,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
case 0x02: /* Unconnected Ping */
if (packet->payload_packet_len != 32)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
required_packets = 6;
@@ -87,7 +138,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
case 0x03: /* Connected Pong */
if (packet->payload_packet_len != 16)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
required_packets = 6;
@@ -97,7 +148,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
if (packet->payload_packet_len < 18 ||
packet->payload[17] > 10 /* maximum supported protocol version */)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
required_packets = 6;
@@ -107,7 +158,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
if (packet->payload_packet_len != 28 ||
packet->payload[25] > 0x01 /* connection uses encryption: bool -> 0x00 or 0x01 */)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
@@ -115,7 +166,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t mtu_size = ntohs(get_u_int16_t(packet->payload, 26));
if (mtu_size > 1500 /* Max. supported MTU, see: http://www.jenkinssoftware.com/raknet/manual/programmingtips.html */)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
}
@@ -128,7 +179,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
!((ip_addr_offset == 16 && packet->payload_packet_len == 46) ||
(ip_addr_offset == 4 && packet->payload_packet_len == 34)))
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
@@ -136,7 +187,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t mtu_size = ntohs(get_u_int16_t(packet->payload, 20 + ip_addr_offset));
if (mtu_size > 1500 /* Max. supported MTU, see: http://www.jenkinssoftware.com/raknet/manual/programmingtips.html */)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
}
@@ -148,7 +199,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
!((ip_addr_offset == 16 && packet->payload_packet_len == 47) ||
(ip_addr_offset == 4 && packet->payload_packet_len == 35)))
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
@@ -156,7 +207,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t mtu_size = ntohs(get_u_int16_t(packet->payload, 28 + ip_addr_offset));
if (mtu_size > 1500 /* Max. supported MTU, see: http://www.jenkinssoftware.com/raknet/manual/programmingtips.html */)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
}
@@ -179,7 +230,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
ip_addr_offset += 16;
if (ip_addr_offset != packet->payload_packet_len)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
}
@@ -207,7 +258,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
u_int8_t msg_flags = get_u_int8_t(packet->payload, frame_offset);
if ((msg_flags & 0x0F) != 0)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
@@ -215,7 +266,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
msg_size /= 8;
if (msg_size == 0)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
break;
}
@@ -245,7 +296,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
{
ndpi_int_raknet_add_connection(ndpi_struct, flow);
} else {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
}
return;
}
@@ -254,7 +305,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
case 0x09: /* Connection Request */
if (packet->payload_packet_len != 16)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
required_packets = 6;
@@ -268,7 +319,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
if (packet->payload_packet_len != 25 ||
packet->payload[17] > 10)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
break;
@@ -276,7 +327,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
case 0x1c: /* Unconnected Pong */
if (packet->payload_packet_len < 35)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
@@ -285,7 +336,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
if (motd_len == 0 || motd_len + 35 != packet->payload_packet_len)
{
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
}
@@ -305,7 +356,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
{
record_offset += 4;
} else {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
} while (++record_index < record_count &&
@@ -315,7 +366,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
{
ndpi_int_raknet_add_connection(ndpi_struct, flow);
} else {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
}
return;
}
@@ -326,7 +377,7 @@ static void ndpi_search_raknet(struct ndpi_detection_module_struct *ndpi_struct,
break;
default: /* Invalid RakNet packet */
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ exclude_proto(ndpi_struct, flow);
return;
}
diff --git a/tests/cfgs/default/pcap/roblox.pcapng b/tests/cfgs/default/pcap/roblox.pcapng
new file mode 100644
index 000000000..0715584ee
--- /dev/null
+++ b/tests/cfgs/default/pcap/roblox.pcapng
Binary files differ
diff --git a/tests/cfgs/default/result/custom_rules_same-ip_multiple_ports.pcapng.out b/tests/cfgs/default/result/custom_rules_same-ip_multiple_ports.pcapng.out
index 0cc9da62a..bca393c7a 100644
--- a/tests/cfgs/default/result/custom_rules_same-ip_multiple_ports.pcapng.out
+++ b/tests/cfgs/default/result/custom_rules_same-ip_multiple_ports.pcapng.out
@@ -23,5 +23,5 @@ Patricia protocols: 2/2 (search/found)
CustomProtocolA 3 222 1
CustomProtocolB 2 148 1
- 1 TCP 192.168.1.245:56866 -> 3.3.3.3:443 [proto: 91.352/TLS.CustomProtocolA][IP: 352/CustomProtocolA][Encrypted][Confidence: Unknown][DPI packets: 1][cat: Web/5][3 pkts/222 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][3.05 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
- 2 TCP 192.168.1.245:59682 -> 3.3.3.3:444 [proto: 353/CustomProtocolB][IP: 353/CustomProtocolB][ClearText][Confidence: Unknown][DPI packets: 1][2 pkts/148 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][1.02 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 1 TCP 192.168.1.245:56866 -> 3.3.3.3:443 [proto: 91.353/TLS.CustomProtocolA][IP: 353/CustomProtocolA][Encrypted][Confidence: Unknown][DPI packets: 1][cat: Web/5][3 pkts/222 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][3.05 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 2 TCP 192.168.1.245:59682 -> 3.3.3.3:444 [proto: 354/CustomProtocolB][IP: 354/CustomProtocolB][ClearText][Confidence: Unknown][DPI packets: 1][2 pkts/148 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][1.02 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
diff --git a/tests/cfgs/default/result/roblox.pcapng.out b/tests/cfgs/default/result/roblox.pcapng.out
new file mode 100644
index 000000000..a32f16f76
--- /dev/null
+++ b/tests/cfgs/default/result/roblox.pcapng.out
@@ -0,0 +1,35 @@
+Guessed flow protos: 0
+
+DPI Packets (TCP): 5 (5.00 pkts/flow)
+DPI Packets (UDP): 3 (1.00 pkts/flow)
+Confidence DPI : 4 (flows)
+Num dissector calls: 268 (67.00 diss/flow)
+LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache bittorrent: 0/0/0 (insert/search/found)
+LRU cache zoom: 0/0/0 (insert/search/found)
+LRU cache stun: 0/0/0 (insert/search/found)
+LRU cache tls_cert: 0/0/0 (insert/search/found)
+LRU cache mining: 0/0/0 (insert/search/found)
+LRU cache msteams: 0/0/0 (insert/search/found)
+LRU cache stun_zoom: 0/0/0 (insert/search/found)
+Automa host: 1/1 (search/found)
+Automa domain: 1/0 (search/found)
+Automa tls cert: 0/0 (search/found)
+Automa risk mask: 0/0 (search/found)
+Automa common alpns: 1/1 (search/found)
+Patricia risk mask: 6/0 (search/found)
+Patricia risk: 0/0 (search/found)
+Patricia protocols: 4/4 (search/found)
+
+RakNet 44 21907 3
+Roblox 34 12002 1
+
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 192.168.12.156 1
+
+
+ 1 TCP 192.168.12.156:39034 <-> 128.116.122.4:443 [proto: 91.346/TLS.Roblox][IP: 346/Roblox][Encrypted][Confidence: DPI][DPI packets: 5][cat: Game/8][19 pkts/3517 bytes <-> 15 pkts/8485 bytes][Goodput ratio: 65/88][12.24 sec][Hostname/SNI: assetgame.roblox.com][(Advertised) ALPNs: http/1.1][TLS Supported Versions: TLSv1.3;TLSv1.2][bytes ratio: -0.414 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 808/1277 10785/10000 2671/3298][Pkt Len c2s/s2c min/avg/max/stddev: 54/54 185/566 1090/1514 279/584][TLSv1.3][JA3C: f436b9416f37d134cadd04886327d3e8][JA3S: f4febc55ea12b31ae17cfb7e614afda8][Firefox][Cipher: TLS_AES_128_GCM_SHA256][Plen Bins: 20,0,6,0,0,0,0,0,13,0,0,0,0,0,0,0,13,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,6,0,0,0,0,0,0,0,20,0,0]
+ 2 UDP 192.168.12.156:45693 <-> 128.116.44.33:53385 [proto: 286/RakNet][IP: 346/Roblox][ClearText][Confidence: DPI][DPI packets: 1][cat: Game/8][15 pkts/6993 bytes <-> 2 pkts/2748 bytes][Goodput ratio: 91/97][0.38 sec][bytes ratio: 0.436 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 25/0 127/0 36/0][Pkt Len c2s/s2c min/avg/max/stddev: 100/1374 466/1374 1398/1374 543/0][PLAIN TEXT (UniqueNumber)][Plen Bins: 0,30,18,5,0,5,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,18,11,0,0,0,0,0]
+ 3 UDP 192.168.12.156:46507 <-> 128.116.44.33:51438 [proto: 286/RakNet][IP: 346/Roblox][ClearText][Confidence: DPI][DPI packets: 1][cat: Game/8][13 pkts/6771 bytes <-> 1 pkts/1374 bytes][Goodput ratio: 92/97][0.42 sec][bytes ratio: 0.663 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 28/0 196/0 56/0][Pkt Len c2s/s2c min/avg/max/stddev: 100/1374 521/1374 1398/1374 563/0][PLAIN TEXT (UniqueNumber9)][Plen Bins: 0,28,14,7,0,7,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,14,14,0,0,0,0,0]
+ 4 UDP 192.168.12.156:42965 <-> 128.116.89.113:63862 [proto: 286/RakNet][IP: 346/Roblox][ClearText][Confidence: DPI][DPI packets: 1][cat: Game/8][6 pkts/3229 bytes <-> 7 pkts/792 bytes][Goodput ratio: 92/63][0.11 sec][bytes ratio: 0.606 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 20/11 34/29 13/14][Pkt Len c2s/s2c min/avg/max/stddev: 69/70 538/113 1398/180 609/46][PLAIN TEXT (UniqueNumber)][Plen Bins: 15,38,7,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0]
diff --git a/tests/cfgs/default/result/synscan.pcap.out b/tests/cfgs/default/result/synscan.pcap.out
index 674500600..02aab79fd 100644
--- a/tests/cfgs/default/result/synscan.pcap.out
+++ b/tests/cfgs/default/result/synscan.pcap.out
@@ -124,7 +124,7 @@ iSCSI 2 116 2
44 TCP 172.16.0.8:36050 -> 64.13.134.52:2605 [proto: 13/BGP][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
45 TCP 172.16.0.8:36050 -> 64.13.134.52:3000 [proto: 26/ntop][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
46 TCP 172.16.0.8:36050 -> 64.13.134.52:3128 [proto: 131/HTTP_Proxy][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Web/5][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
- 47 TCP 172.16.0.8:36050 -> 64.13.134.52:3260 [proto: 346/iSCSI][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 47 TCP 172.16.0.8:36050 -> 64.13.134.52:3260 [proto: 347/iSCSI][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
48 TCP 172.16.0.8:36050 -> 64.13.134.52:3306 [proto: 20/MySQL][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Database/11][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
49 TCP 172.16.0.8:36050 -> 64.13.134.52:3389 [proto: 88/RDP][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: RemoteAccess/12][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Desktop/File Sharing **** Unidirectional Traffic **][Risk Score: 20][Risk Info: No server to client traffic / Found RDP][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
50 TCP 172.16.0.8:36050 -> 64.13.134.52:4343 [proto: 170/Whois-DAS][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
@@ -188,7 +188,7 @@ iSCSI 2 116 2
108 TCP 172.16.0.8:36051 -> 64.13.134.52:2605 [proto: 13/BGP][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
109 TCP 172.16.0.8:36051 -> 64.13.134.52:3000 [proto: 26/ntop][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
110 TCP 172.16.0.8:36051 -> 64.13.134.52:3128 [proto: 131/HTTP_Proxy][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Web/5][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
- 111 TCP 172.16.0.8:36051 -> 64.13.134.52:3260 [proto: 346/iSCSI][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 111 TCP 172.16.0.8:36051 -> 64.13.134.52:3260 [proto: 347/iSCSI][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
112 TCP 172.16.0.8:36051 -> 64.13.134.52:3306 [proto: 20/MySQL][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Database/11][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
113 TCP 172.16.0.8:36051 -> 64.13.134.52:3389 [proto: 88/RDP][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: RemoteAccess/12][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Desktop/File Sharing **** Unidirectional Traffic **][Risk Score: 20][Risk Info: No server to client traffic / Found RDP][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
114 TCP 172.16.0.8:36051 -> 64.13.134.52:4343 [proto: 170/Whois-DAS][IP: 0/Unknown][ClearText][Confidence: Match by port][DPI packets: 1][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
diff --git a/utils/asn_update.sh b/utils/asn_update.sh
index 748358f3c..7385d80b7 100755
--- a/utils/asn_update.sh
+++ b/utils/asn_update.sh
@@ -202,6 +202,11 @@ DEST=../src/lib/inc_generated/ndpi_asn_nvidia.c.inc
create_list NDPI_PROTOCOL_NVIDIA $DEST "" "AS60977" "AS50889" "AS20347" "AS11414"
echo "(3) Nvidia IPs are available in $DEST"
+echo "(1) Downloading Roblox..."
+DEST=../src/lib/inc_generated/ndpi_asn_roblox.c.inc
+create_list NDPI_PROTOCOL_ROBLOX $DEST "" "AS22697"
+echo "(3) Roblox IPs are available in $DEST"
+
if [ ${TOTAL_ASN} -eq 0 -o ${TOTAL_ASN} -eq ${FAILED_ASN} ]; then
printf '%s: %s\n' "${0}" "All download(s) failed, ./get_routes_by_asn.sh broken?"
exit 1