Skip to content

Commit

Permalink
Add TiVoConnect dissector. Fixes ntop#1697. (ntop#1699)
Browse files Browse the repository at this point in the history
* added static assert if supported, to complain if the flow struct changes

Signed-off-by: lns <matzeton@googlemail.com>
  • Loading branch information
utoni committed Aug 8, 2022
1 parent 5233600 commit 2e25c36
Show file tree
Hide file tree
Showing 118 changed files with 1,945 additions and 1,699 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,10 @@ jobs:
make all
make -C example ndpiSimpleIntegration
make -C rrdtool
- name: Print nDPI long help
if: startsWith(matrix.arch, 'x86_64') && !startsWith(matrix.os, 'windows')
run: |
./example/ndpiReader -H
- name: Install nDPI
if: startsWith(matrix.arch, 'x86_64') && !startsWith(matrix.os, 'windows')
run: |
Expand Down
24 changes: 24 additions & 0 deletions example/ndpiReader.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,11 @@ static void help(u_int long_help) {
#endif

if(long_help) {
printf("\n\nSize of nDPI Flow structure: %u\n"
"Sizeof of nDPI Flow protocol union: %zu\n",
ndpi_detection_get_sizeof_ndpi_flow_struct(),
sizeof(((struct ndpi_flow_struct *)0)->protos));

NDPI_PROTOCOL_BITMASK all;

ndpi_info_mod = ndpi_init_detection_module(ndpi_no_prefs);
Expand Down Expand Up @@ -1484,6 +1489,25 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa
}
break;

case INFO_TIVOCONNECT:
if (flow->tivoconnect.identity_uuid[0] != '\0')
{
fprintf(out, "[UUID: %s]", flow->tivoconnect.identity_uuid);
}
if (flow->tivoconnect.machine[0] != '\0')
{
fprintf(out, "[Machine: %s]", flow->tivoconnect.machine);
}
if (flow->tivoconnect.platform[0] != '\0')
{
fprintf(out, "[Platform: %s]", flow->tivoconnect.platform);
}
if (flow->tivoconnect.services[0] != '\0')
{
fprintf(out, "[Services: %s]", flow->tivoconnect.services);
}
break;

case INFO_FTP_IMAP_POP_SMTP:
if (flow->ftp_imap_pop_smtp.username[0] != '\0')
{
Expand Down
12 changes: 12 additions & 0 deletions example/reader_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,18 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl
flow->bittorent_hash[j] = '\0';
}
}
/* TIVOCONNECT */
else if(is_ndpi_proto(flow, NDPI_PROTOCOL_TIVOCONNECT)) {
flow->info_type = INFO_TIVOCONNECT;
ndpi_snprintf(flow->tivoconnect.identity_uuid, sizeof(flow->tivoconnect.identity_uuid),
"%s", flow->ndpi_flow->protos.tivoconnect.identity_uuid);
ndpi_snprintf(flow->tivoconnect.machine, sizeof(flow->tivoconnect.machine),
"%s", flow->ndpi_flow->protos.tivoconnect.machine);
ndpi_snprintf(flow->tivoconnect.platform, sizeof(flow->tivoconnect.platform),
"%s", flow->ndpi_flow->protos.tivoconnect.platform);
ndpi_snprintf(flow->tivoconnect.services, sizeof(flow->tivoconnect.services),
"%s", flow->ndpi_flow->protos.tivoconnect.services);
}
/* SOFTETHER */
else if(is_ndpi_proto(flow, NDPI_PROTOCOL_SOFTETHER) && !is_ndpi_proto(flow, NDPI_PROTOCOL_HTTP)) {
flow->info_type = INFO_SOFTETHER;
Expand Down
7 changes: 7 additions & 0 deletions example/reader_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ enum info_type {
INFO_GENERIC,
INFO_KERBEROS,
INFO_SOFTETHER,
INFO_TIVOCONNECT,
INFO_FTP_IMAP_POP_SMTP,
INFO_TLS_QUIC_ALPN_VERSION,
INFO_TLS_QUIC_ALPN_ONLY,
Expand Down Expand Up @@ -234,6 +235,12 @@ typedef struct ndpi_flow_info {
char hostname[48];
char fqdn[48];
} softether;
struct {
char identity_uuid[36];
char machine[48];
char platform[32];
char services[48];
} tivoconnect;
};

ndpi_serializer ndpi_flow_serializer;
Expand Down
1 change: 1 addition & 0 deletions src/include/ndpi_protocol_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ typedef enum {
NDPI_PROTOCOL_THREEMA = 305,
NDPI_PROTOCOL_ALICLOUD = 306,
NDPI_PROTOCOL_AVAST = 307,
NDPI_PROTOCOL_TIVOCONNECT = 308,

#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_protocol_ids.h"
Expand Down
1 change: 1 addition & 0 deletions src/include/ndpi_protocols.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ void init_avast_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_in
void init_softether_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_activision_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_discord_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);
void init_tivoconnect_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask);

/* ndpi_main.c */
extern u_int32_t ndpi_ip_port_hash_funct(u_int32_t ip, u_int16_t port);
Expand Down
18 changes: 18 additions & 0 deletions src/include/ndpi_typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1447,6 +1447,13 @@ struct ndpi_flow_struct {
u_int8_t primitive; /* GET, SET... */
u_int8_t error_status;
} snmp;

struct {
char identity_uuid[36];
char machine[48];
char platform[32];
char services[48];
} tivoconnect;
} protos;

/*** ALL protocol specific 64 bit variables here ***/
Expand Down Expand Up @@ -1524,6 +1531,17 @@ struct ndpi_flow_struct {
u_int8_t priv_data[16];
};

#if !defined(NDPI_CFFI_PREPROCESSING) && defined(__linux__)
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(((struct ndpi_flow_struct *)0)->protos) <= 200,
"Size of the struct member protocols increased to more than 200 bytes, "
"please check if this change is necessary.");
_Static_assert(sizeof(struct ndpi_flow_struct) <= 904,
"Size of the flow struct increased to more than 904 bytes, "
"please check if this change is necessary.");
#endif
#endif

#define NDPI_PROTOCOL_DEFAULT_LEVEL 0

typedef struct {
Expand Down
7 changes: 7 additions & 0 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1962,6 +1962,10 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
"AVAST", NDPI_PROTOCOL_CATEGORY_NETWORK,
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_SAFE, NDPI_PROTOCOL_TIVOCONNECT,
"TiVoConnect", NDPI_PROTOCOL_CATEGORY_NETWORK,
ndpi_build_default_ports(ports_a, 2190, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 2190, 0, 0, 0, 0) /* UDP */);

#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_main.c"
Expand Down Expand Up @@ -4547,6 +4551,9 @@ static int ndpi_callback_init(struct ndpi_detection_module_struct *ndpi_str) {
/* Discord */
init_discord_dissector(ndpi_str, &a, detection_bitmask);

/* TiVoConnect */
init_tivoconnect_dissector(ndpi_str, &a, detection_bitmask);

#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_main_init.c"
#endif
Expand Down
147 changes: 147 additions & 0 deletions src/lib/protocols/tivoconnect.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* tivoconnect.c
*
* Copyright (C) 2022 - ntop.org
*
* 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_TIVOCONNECT

#include "ndpi_api.h"

static void ndpi_int_tivoconnect_add_connection(struct ndpi_detection_module_struct * const ndpi_struct,
struct ndpi_flow_struct * const flow)
{
NDPI_LOG_INFO(ndpi_struct, "found tivoconnect\n");
ndpi_set_detected_protocol(ndpi_struct, flow,
NDPI_PROTOCOL_TIVOCONNECT,
NDPI_PROTOCOL_UNKNOWN,
NDPI_CONFIDENCE_DPI);
}

static void dissect_tivoconnect_data(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow)
{
struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
char const * const payload = (char const *)packet->payload;
size_t const payload_len = packet->payload_packet_len;
char const *key = payload;
char const *newline;

for (newline = ndpi_strnstr(payload, "\n", payload_len);
newline != NULL;
key = ++newline,
newline = ndpi_strnstr(newline, "\n", payload_len - (newline - payload)))
{
size_t const line_len = newline - key;
char const *value = ndpi_strnstr(key, "=", line_len);

if (value == NULL)
{
ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Missing value type in TiViConnect beacon");
continue;
}
value++;

size_t const key_len = value - 1 - key;
size_t const value_len = newline - value;

if (key_len == NDPI_STATICSTRING_LEN("identity") &&
strncasecmp(key, "identity", key_len) == 0)
{
if (value_len >= NDPI_STATICSTRING_LEN("uuid:") &&
strncasecmp(value, "uuid:", NDPI_STATICSTRING_LEN("uuid:")) == 0)
{
size_t const len = ndpi_min(sizeof(flow->protos.tivoconnect.identity_uuid) - 1,
value_len - NDPI_STATICSTRING_LEN("uuid:"));
strncpy(flow->protos.tivoconnect.identity_uuid,
value + NDPI_STATICSTRING_LEN("uuid:"), len);
flow->protos.tivoconnect.identity_uuid[len] = '\0';
}
continue;
}
if (key_len == NDPI_STATICSTRING_LEN("machine") &&
strncasecmp(key, "machine", key_len) == 0)
{
size_t const len = ndpi_min(sizeof(flow->protos.tivoconnect.machine) - 1,
value_len);
strncpy(flow->protos.tivoconnect.machine, value, len);
flow->protos.tivoconnect.machine[len] = '\0';
continue;
}
if (key_len == NDPI_STATICSTRING_LEN("platform") &&
strncasecmp(key, "platform", key_len) == 0)
{
size_t const len = ndpi_min(sizeof(flow->protos.tivoconnect.platform) - 1,
value_len);
strncpy(flow->protos.tivoconnect.platform, value, len);
flow->protos.tivoconnect.platform[len] = '\0';
continue;
}
if (key_len == NDPI_STATICSTRING_LEN("services") &&
strncasecmp(key, "services", key_len) == 0)
{
size_t const len = ndpi_min(sizeof(flow->protos.tivoconnect.services) - 1,
value_len);
strncpy(flow->protos.tivoconnect.services, value, len);
flow->protos.tivoconnect.services[len] = '\0';
continue;
}
}

if ((size_t)(key - payload) != payload_len)
{
ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET,
"TiViConnect beacon malformed packet");
}
}

void ndpi_search_tivoconnect(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow)
{
struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;

NDPI_LOG_INFO(ndpi_struct, "search tivoconnect\n");

if (packet->payload_packet_len >= NDPI_STATICSTRING_LEN("tivoconnect=") &&
strncasecmp((char const *)packet->payload,
"tivoconnect=", NDPI_STATICSTRING_LEN("tivoconnect=")) == 0)
{
ndpi_int_tivoconnect_add_connection(ndpi_struct, flow);
} else {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
return;
}

dissect_tivoconnect_data(ndpi_struct, flow);
}

void init_tivoconnect_dissector(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
{
ndpi_set_bitmask_protocol_detection("TiVoConnect", ndpi_struct, detection_bitmask, *id,
NDPI_PROTOCOL_TIVOCONNECT,
ndpi_search_tivoconnect,
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
SAVE_DETECTION_BITMASK_AS_UNKNOWN,
ADD_TO_DETECTION_BITMASK
);

*id += 1;
}
Binary file added tests/pcap/TivoDVR.pcap
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/result/1kxun.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Confidence Unknown : 14 (flows)
Confidence Match by port : 5 (flows)
Confidence Match by IP : 1 (flows)
Confidence DPI : 177 (flows)
Num dissector calls: 4672 (23.72 diss/flow)
Num dissector calls: 4689 (23.80 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)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/443-chrome.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Guessed flow protos: 1

DPI Packets (TCP): 1 (1.00 pkts/flow)
Confidence Match by port : 1 (flows)
Num dissector calls: 122 (122.00 diss/flow)
Num dissector calls: 123 (123.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)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/443-opvn.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Guessed flow protos: 0

DPI Packets (TCP): 6 (6.00 pkts/flow)
Confidence DPI : 1 (flows)
Num dissector calls: 123 (123.00 diss/flow)
Num dissector calls: 124 (124.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)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/4in4tunnel.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Guessed flow protos: 1

DPI Packets (UDP): 5 (5.00 pkts/flow)
Confidence Unknown : 1 (flows)
Num dissector calls: 170 (170.00 diss/flow)
Num dissector calls: 171 (171.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)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/6in6tunnel.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Guessed flow protos: 1

DPI Packets (UDP): 2 (2.00 pkts/flow)
Confidence Unknown : 1 (flows)
Num dissector calls: 114 (114.00 diss/flow)
Num dissector calls: 115 (115.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)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/EAQ.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Guessed flow protos: 0
DPI Packets (TCP): 12 (6.00 pkts/flow)
DPI Packets (UDP): 116 (4.00 pkts/flow)
Confidence DPI : 31 (flows)
Num dissector calls: 4103 (132.35 diss/flow)
Num dissector calls: 4132 (133.29 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)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/KakaoTalk_chat.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ DPI Packets (other): 1 (1.00 pkts/flow)
Confidence Match by port : 4 (flows)
Confidence Match by IP : 1 (flows)
Confidence DPI : 33 (flows)
Num dissector calls: 617 (16.24 diss/flow)
Num dissector calls: 619 (16.29 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)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/KakaoTalk_talk.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ DPI Packets (UDP): 6 (1.20 pkts/flow)
Confidence Match by port : 4 (flows)
Confidence Match by IP : 5 (flows)
Confidence DPI : 11 (flows)
Num dissector calls: 853 (42.65 diss/flow)
Num dissector calls: 857 (42.85 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)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/Oscar.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Guessed flow protos: 1

DPI Packets (TCP): 33 (33.00 pkts/flow)
Confidence Match by port : 1 (flows)
Num dissector calls: 336 (336.00 diss/flow)
Num dissector calls: 337 (337.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)
Expand Down
Loading

0 comments on commit 2e25c36

Please sign in to comment.