Skip to content

Commit 2c2b3de

Browse files
committed
Add (generic) JSON protocol dissector.
Signed-off-by: Toni Uhlig <[email protected]>
1 parent 11cc612 commit 2c2b3de

File tree

216 files changed

+773
-555
lines changed

Some content is hidden

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

216 files changed

+773
-555
lines changed

doc/protocols.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4257,3 +4257,10 @@ References: `Official site <https://www.espn.com/>`_
42574257
Akamai Technologies, Inc. is an American company specialized in content delivery network (CDN), cybersecurity, DDoS mitigation, and cloud services.
42584258

42594259
References: `Official site <https://www.akamai.com>`_
4260+
4261+
4262+
.. _Proto_468:
4263+
4264+
`NDPI_PROTOCOL_JSON`
4265+
====================
4266+
JSON (JavaScript Object Notation) is an open standard file format and data interchange format that uses human-readable text.

src/include/ndpi_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,7 @@ void init_mudfish_dissector(struct ndpi_detection_module_struct *ndpi_struct);
10861086
void init_tristation_dissector(struct ndpi_detection_module_struct *ndpi_struct);
10871087
void init_samsung_sdp_dissector(struct ndpi_detection_module_struct *ndpi_struct);
10881088
void init_matter_dissector(struct ndpi_detection_module_struct *ndpi_struct);
1089+
void init_json_dissector(struct ndpi_detection_module_struct *ndpi_struct);
10891090

10901091
#ifdef CUSTOM_NDPI_PROTOCOLS
10911092
#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
@@ -497,6 +497,7 @@ typedef enum {
497497
NDPI_PROTOCOL_AWS_DYNAMODB = 465,
498498
NDPI_PROTOCOL_ESPN = 466,
499499
NDPI_PROTOCOL_AKAMAI = 467,
500+
NDPI_PROTOCOL_JSON = 468,
500501

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

src/lib/ndpi_main.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2962,12 +2962,16 @@ static void init_protocol_defaults(struct ndpi_detection_module_struct *ndpi_str
29622962
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */ ,
29632963
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */,
29642964
0);
2965-
29662965
ndpi_set_proto_defaults(ndpi_str, 1 , 1 , NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_AKAMAI,
29672966
"Akamai", NDPI_PROTOCOL_CATEGORY_DATABASE, NDPI_PROTOCOL_QOE_CATEGORY_UNSPECIFIED,
29682967
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */ ,
29692968
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */,
29702969
0);
2970+
ndpi_set_proto_defaults(ndpi_str, 1 /* cleartext */, 1 /* app proto */, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_JSON,
2971+
"JSON", NDPI_PROTOCOL_CATEGORY_NETWORK, NDPI_PROTOCOL_QOE_CATEGORY_UNSPECIFIED,
2972+
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
2973+
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */,
2974+
0);
29712975

29722976
#ifdef CUSTOM_NDPI_PROTOCOLS
29732977
#include "../../../nDPI-custom/custom_ndpi_main.c"
@@ -7453,6 +7457,9 @@ static int dissectors_init(struct ndpi_detection_module_struct *ndpi_str) {
74537457
/* MATTER */
74547458
init_matter_dissector(ndpi_str);
74557459

7460+
/* JSON */
7461+
init_json_dissector(ndpi_str);
7462+
74567463
#ifdef CUSTOM_NDPI_PROTOCOLS
74577464
#include "../../../nDPI-custom/custom_ndpi_main_init.c"
74587465
#endif

src/lib/protocols/http.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
#include "ndpi_api.h"
3232
#include "ndpi_private.h"
3333

34+
extern void ndpi_search_json(struct ndpi_detection_module_struct *ndpi_struct,
35+
struct ndpi_flow_struct *flow);
36+
3437
static const char* binary_exec_file_mimes_e[] = { "exe", NULL };
3538
static const char* binary_exec_file_mimes_j[] = { "java-vm", NULL };
3639
static const char* binary_exec_file_mimes_v[] = { "vnd.ms-cab-compressed", "vnd.microsoft.portable-executable", NULL };
@@ -164,6 +167,10 @@ static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_
164167
return(0); /* We are good now */
165168
}
166169

170+
if (flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) {
171+
ndpi_search_json(ndpi_struct, flow);
172+
}
173+
167174
/* Possibly more processing */
168175
return(1);
169176
}

src/lib/protocols/json.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* json.c
3+
*
4+
* Copyright (C) 2011-25 - 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_JSON
24+
25+
#include "ndpi_api.h"
26+
#include "ndpi_private.h"
27+
28+
#define JSON_MAX_BYTES_TO_CHECK 16
29+
30+
static void ndpi_int_json_add_connection(struct ndpi_detection_module_struct * const ndpi_struct,
31+
struct ndpi_flow_struct * const flow)
32+
{
33+
NDPI_LOG_INFO(ndpi_struct, "found JSON\n");
34+
if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) {
35+
ndpi_set_detected_protocol_keeping_master(ndpi_struct, flow, NDPI_PROTOCOL_JSON, NDPI_CONFIDENCE_DPI);
36+
} else {
37+
ndpi_set_detected_protocol(ndpi_struct, flow,
38+
NDPI_PROTOCOL_JSON,
39+
NDPI_PROTOCOL_UNKNOWN,
40+
NDPI_CONFIDENCE_DPI);
41+
}
42+
}
43+
44+
void ndpi_search_json(struct ndpi_detection_module_struct *ndpi_struct,
45+
struct ndpi_flow_struct *flow)
46+
{
47+
struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
48+
size_t offset = 0;
49+
size_t bytes_checked = 0;
50+
51+
NDPI_LOG_DBG(ndpi_struct, "search JSON\n");
52+
53+
if (packet->payload_packet_len < 2) {
54+
NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
55+
return;
56+
}
57+
58+
do {
59+
if (offset >= packet->payload_packet_len) {
60+
break;
61+
}
62+
if (packet->payload[offset] == '{' ||
63+
packet->payload[offset] == '[')
64+
{
65+
break;
66+
}
67+
if (packet->payload[offset] != ' ' &&
68+
packet->payload[offset] != '\t' &&
69+
packet->payload[offset] != '\r' &&
70+
packet->payload[offset] != '\n' &&
71+
ndpi_isalnum(packet->payload[offset]) == 0 &&
72+
offset >= 8)
73+
{
74+
NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
75+
return;
76+
}
77+
} while (++offset < JSON_MAX_BYTES_TO_CHECK);
78+
79+
for (size_t i = offset; i < ndpi_min(JSON_MAX_BYTES_TO_CHECK, packet->payload_packet_len); ++i) {
80+
if (ndpi_isprint(packet->payload[i]) == 0 &&
81+
packet->payload[i] != '\t' &&
82+
packet->payload[i] != '\r' &&
83+
packet->payload[i] != '\n')
84+
{
85+
NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
86+
return;
87+
}
88+
}
89+
90+
if (offset == JSON_MAX_BYTES_TO_CHECK || offset >= packet->payload_packet_len) {
91+
NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
92+
return;
93+
}
94+
95+
offset = packet->payload_packet_len;
96+
97+
do {
98+
if (packet->payload[offset - 1] == '}' ||
99+
packet->payload[offset - 1] == ']')
100+
{
101+
break;
102+
}
103+
if (packet->payload[offset - 1] != ' ' &&
104+
packet->payload[offset - 1] != '\t' &&
105+
packet->payload[offset - 1] != '\r' &&
106+
packet->payload[offset - 1] != '\n' &&
107+
ndpi_isalnum(packet->payload[offset - 1]) == 0)
108+
{
109+
NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
110+
return;
111+
}
112+
} while (--offset > 0 && ++bytes_checked < JSON_MAX_BYTES_TO_CHECK);
113+
114+
ndpi_int_json_add_connection(ndpi_struct, flow);
115+
}
116+
117+
void init_json_dissector(struct ndpi_detection_module_struct *ndpi_struct)
118+
{
119+
register_dissector("JSON", ndpi_struct,
120+
ndpi_search_json,
121+
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
122+
1, NDPI_PROTOCOL_JSON);
123+
}

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: 572 (95.33 diss/flow)
6+
Num dissector calls: 575 (95.83 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: 521 (6.28 diss/flow)
9+
Num dissector calls: 523 (6.30 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/lru_ipv6_caches.pcapng.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ DPI Packets (TCP): 9 (3.00 pkts/flow)
22
DPI Packets (UDP): 35 (3.89 pkts/flow)
33
Confidence DPI (cache) : 4 (flows)
44
Confidence DPI : 8 (flows)
5-
Num dissector calls: 337 (28.08 diss/flow)
5+
Num dissector calls: 339 (28.25 diss/flow)
66
LRU cache ookla: 0/0/0 (insert/search/found)
77
LRU cache bittorrent: 25/4/2 (insert/search/found)
88
LRU cache stun: 6/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: 572 (95.33 diss/flow)
7+
Num dissector calls: 575 (95.83 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)

0 commit comments

Comments
 (0)