Skip to content

Commit 8e9fca8

Browse files
authored
Add Yggdrasil protocol dissector (#3207)
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
1 parent c1ced0b commit 8e9fca8

239 files changed

Lines changed: 762 additions & 575 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

doc/protocols.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4417,3 +4417,12 @@ References: `Official site: <https://lumo.proton.me/>`_
44174417
Proton Meet is an end-to-end encrypted video conferencing service by Proton AG.
44184418

44194419
References: `Official site: <https://proton.me/meet>`_
4420+
4421+
4422+
.. _Proto_487:
4423+
4424+
`NDPI_PROTOCOL_YGGDRASIL`
4425+
=========================
4426+
Yggdrasil is a new experimental compact routing scheme. It is designed to be a future-proof and decentralised alternative to the structured routing protocols commonly used today on the Internet, as well as an enabling technology for future large-scale mesh networks.
4427+
4428+
References: `Official site: <https://yggdrasil-network.github.io/>`_

src/include/ndpi_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,7 @@ void init_json_dissector(struct ndpi_detection_module_struct *ndpi_struct);
11141114
void init_msgpack_dissector(struct ndpi_detection_module_struct *ndpi_struct);
11151115
void init_sbe_dissector(struct ndpi_detection_module_struct *ndpi_struct);
11161116
void init_iris_dissector(struct ndpi_detection_module_struct *ndpi_struct);
1117+
void init_yggdrasil_dissector(struct ndpi_detection_module_struct *ndpi_struct);
11171118

11181119
#ifdef CUSTOM_NDPI_PROTOCOLS
11191120
#include "../../../nDPI-custom/custom_ndpi_private.h"

src/include/ndpi_protocol_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ typedef enum {
516516
NDPI_PROTOCOL_PROTON_WALLET = 484,
517517
NDPI_PROTOCOL_PROTON_LUMO = 485,
518518
NDPI_PROTOCOL_PROTON_MEET = 486,
519+
NDPI_PROTOCOL_YGGDRASIL = 487,
519520

520521
/* If you add a new protocol, please update the documentation at doc/protocols.rst, too! */
521522

src/lib/ndpi_content_match.c.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ static ndpi_network6 host_protocol_list_6[] = {
338338
{ "2403:300:a51::", 48, NDPI_PROTOCOL_APPLE_PUSH },
339339
{ "2a01:b740:a42::", 48, NDPI_PROTOCOL_APPLE_PUSH },
340340

341+
{ "ff02::114", 128, NDPI_PROTOCOL_YGGDRASIL },
342+
341343
/* End */
342344
{ NULL, 0, 0 }
343345
};

src/lib/ndpi_main.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,7 @@ static void init_protocol_defaults(struct ndpi_detection_module_struct *ndpi_str
12831283
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */,
12841284
0);
12851285
ndpi_set_proto_subprotocols(ndpi_str, NDPI_PROTOCOL_HTTP,
1286+
NDPI_PROTOCOL_YGGDRASIL,
12861287
NDPI_PROTOCOL_WEBSOCKET,
12871288
NDPI_PROTOCOL_CROSSFIRE, NDPI_PROTOCOL_SOAP,
12881289
NDPI_PROTOCOL_BITTORRENT,
@@ -3021,6 +3022,11 @@ static void init_protocol_defaults(struct ndpi_detection_module_struct *ndpi_str
30213022
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
30223023
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */,
30233024
0);
3025+
ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, 1 /* nw proto */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_YGGDRASIL,
3026+
"Yggdrasil", NDPI_PROTOCOL_CATEGORY_VPN, NDPI_PROTOCOL_QOE_CATEGORY_UNSPECIFIED,
3027+
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
3028+
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */,
3029+
0);
30243030

30253031
#ifdef CUSTOM_NDPI_PROTOCOLS
30263032
#include "../../../nDPI-custom/custom_ndpi_main.c"
@@ -7595,6 +7601,9 @@ static int dissectors_init(struct ndpi_detection_module_struct *ndpi_str) {
75957601
/* NetMotion Mobility */
75967602
init_netmotion_dissector(ndpi_str);
75977603

7604+
/* Yggdrasil */
7605+
init_yggdrasil_dissector(ndpi_str);
7606+
75987607
#ifdef CUSTOM_NDPI_PROTOCOLS
75997608
#include "../../../nDPI-custom/custom_ndpi_main_init.c"
76007609
#endif

src/lib/protocols/yggdrasil.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* yggdrasil.c
3+
*
4+
* Copyright (C) 2026 - ntop.org
5+
*
6+
* nDPI is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* nDPI is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with nDPI. If not, see <http://www.gnu.org/licenses/>.
18+
*
19+
*/
20+
21+
#include "ndpi_protocol_ids.h"
22+
23+
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_YGGDRASIL
24+
25+
#include "ndpi_api.h"
26+
#include "ndpi_private.h"
27+
28+
29+
static void ndpi_int_yggdrasil_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
30+
struct ndpi_flow_struct *flow)
31+
{
32+
NDPI_LOG_INFO(ndpi_struct, "found Yggdrasil\n");
33+
if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) {
34+
ndpi_set_detected_protocol_keeping_master(ndpi_struct, flow, NDPI_PROTOCOL_YGGDRASIL,
35+
NDPI_CONFIDENCE_DPI);
36+
} else {
37+
ndpi_set_detected_protocol(ndpi_struct, flow,
38+
NDPI_PROTOCOL_YGGDRASIL,
39+
NDPI_PROTOCOL_UNKNOWN,
40+
NDPI_CONFIDENCE_DPI);
41+
}
42+
}
43+
44+
static int ndpi_search_yggdrasil_http(struct ndpi_detection_module_struct *ndpi_struct,
45+
struct ndpi_flow_struct *flow)
46+
{
47+
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
48+
49+
NDPI_LOG_DBG(ndpi_struct, "search Yggdrasil\n");
50+
51+
if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_HTTP &&
52+
flow->detected_protocol_stack[1] != NDPI_PROTOCOL_HTTP)
53+
{
54+
return -1;
55+
}
56+
57+
if (packet->parsed_lines == 0)
58+
{
59+
ndpi_parse_packet_line_info(ndpi_struct, flow);
60+
}
61+
62+
if (packet->parsed_lines > 0)
63+
{
64+
size_t i;
65+
66+
for (i = 0; i < packet->parsed_lines && packet->line[i].len > 0; ++i)
67+
{
68+
if (LINE_STARTS(packet->line[i], "Sec-Websocket-Protocol") != 0 &&
69+
LINE_ENDS(packet->line[i], "ygg-ws") != 0)
70+
{
71+
return 0;
72+
}
73+
}
74+
}
75+
76+
NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
77+
return -1;
78+
}
79+
80+
static void ndpi_search_yggdrasil(struct ndpi_detection_module_struct *ndpi_struct,
81+
struct ndpi_flow_struct *flow)
82+
{
83+
if (ndpi_search_yggdrasil_http(ndpi_struct, flow) == 0) {
84+
ndpi_int_yggdrasil_add_connection(ndpi_struct, flow);
85+
return;
86+
} else {
87+
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
88+
89+
if (packet->payload_packet_len < 5) {
90+
NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
91+
return;
92+
}
93+
94+
if (get_u_int32_t(packet->payload, 0) == htonl(0x6D657461) // "meta"
95+
&& get_u_int8_t(packet->payload, 4) == 0x00)
96+
{
97+
ndpi_int_yggdrasil_add_connection(ndpi_struct, flow);
98+
return;
99+
}
100+
}
101+
102+
NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
103+
}
104+
105+
void init_yggdrasil_dissector(struct ndpi_detection_module_struct *ndpi_struct)
106+
{
107+
ndpi_register_dissector("Yggdrasil", ndpi_struct,
108+
ndpi_search_yggdrasil,
109+
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
110+
1, NDPI_PROTOCOL_YGGDRASIL);
111+
}

tests/cfgs/caches_cfg/result/ookla.pcap.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Guessed flow protos: 1
33
DPI Packets (TCP): 40 (6.67 pkts/flow)
44
Confidence Match by port : 1 (flows)
55
Confidence DPI : 5 (flows)
6-
Num dissector calls: 568 (94.67 diss/flow)
6+
Num dissector calls: 572 (95.33 diss/flow)
77
LRU cache ookla: 0/0/0 (insert/search/found)
88
LRU cache bittorrent: 0/3/0 (insert/search/found)
99
LRU cache stun: 0/0/0 (insert/search/found)

tests/cfgs/caches_cfg/result/teams.pcap.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ DPI Packets (other): 1 (1.00 pkts/flow)
66
Confidence Unknown : 1 (flows)
77
Confidence Match by port : 2 (flows)
88
Confidence DPI : 80 (flows)
9-
Num dissector calls: 528 (6.36 diss/flow)
9+
Num dissector calls: 529 (6.37 diss/flow)
1010
LRU cache ookla: 0/0/0 (insert/search/found)
1111
LRU cache bittorrent: 0/9/0 (insert/search/found)
1212
LRU cache stun: 30/0/0 (insert/search/found)

tests/cfgs/caches_global/result/ookla.pcap.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ DPI Packets (TCP): 40 (6.67 pkts/flow)
44
Confidence DPI (partial cache): 1 (flows)
55
Confidence DPI : 4 (flows)
66
Confidence DPI (aggressive) : 1 (flows)
7-
Num dissector calls: 568 (94.67 diss/flow)
7+
Num dissector calls: 572 (95.33 diss/flow)
88
LRU cache ookla: 4/2/2 (insert/search/found)
99
LRU cache bittorrent: 0/3/0 (insert/search/found)
1010
LRU cache stun: 0/0/0 (insert/search/found)

tests/cfgs/caches_global/result/teams.pcap.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Confidence Unknown : 1 (flows)
77
Confidence Match by port : 2 (flows)
88
Confidence DPI (partial) : 4 (flows)
99
Confidence DPI : 76 (flows)
10-
Num dissector calls: 528 (6.36 diss/flow)
10+
Num dissector calls: 529 (6.37 diss/flow)
1111
LRU cache ookla: 0/0/0 (insert/search/found)
1212
LRU cache bittorrent: 0/9/0 (insert/search/found)
1313
LRU cache stun: 30/0/0 (insert/search/found)

0 commit comments

Comments
 (0)