Coverage Report

Created: 2025-08-03 06:23

/src/ndpi/src/lib/protocols/tivoconnect.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * tivoconnect.c
3
 *
4
 * Copyright (C) 2022-23 - 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
22
#include "ndpi_protocol_ids.h"
23
24
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_TIVOCONNECT
25
26
#include "ndpi_api.h"
27
#include "ndpi_private.h"
28
29
static void ndpi_int_tivoconnect_add_connection(struct ndpi_detection_module_struct * const ndpi_struct,
30
                                                struct ndpi_flow_struct * const flow)
31
0
{
32
0
  NDPI_LOG_INFO(ndpi_struct, "found tivoconnect\n");
33
0
  ndpi_set_detected_protocol(ndpi_struct, flow,
34
0
                             NDPI_PROTOCOL_TIVOCONNECT,
35
0
                             NDPI_PROTOCOL_UNKNOWN,
36
0
                             NDPI_CONFIDENCE_DPI);
37
0
}
38
39
static void dissect_tivoconnect_data(struct ndpi_detection_module_struct *ndpi_struct,
40
                                     struct ndpi_flow_struct *flow)
41
0
{
42
0
  struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
43
0
  char const * const payload = (char const *)packet->payload;
44
0
  size_t const payload_len = packet->payload_packet_len;
45
0
  char const *key = payload;
46
0
  char const *newline;
47
48
0
  for (newline = ndpi_strnstr(payload, "\n", payload_len);
49
0
       newline != NULL;
50
0
       key = ++newline,
51
0
       newline = ndpi_strnstr(newline, "\n", payload_len - (newline - payload)))
52
0
  {
53
0
    size_t const line_len = newline - key;
54
0
    char const *value = ndpi_strnstr(key, "=", line_len);
55
56
0
    if (value == NULL)
57
0
    {
58
0
      ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Missing value type in TiViConnect beacon");
59
0
      continue;
60
0
    }
61
0
    value++;
62
63
0
    size_t const key_len = value - 1 - key;
64
0
    size_t const value_len = newline - value;
65
66
0
    if (key_len == NDPI_STATICSTRING_LEN("identity") &&
67
0
        strncasecmp(key, "identity", key_len) == 0)
68
0
    {
69
0
      if (value_len >= NDPI_STATICSTRING_LEN("uuid:") &&
70
0
          strncasecmp(value, "uuid:", NDPI_STATICSTRING_LEN("uuid:")) == 0)
71
0
      {
72
0
        size_t const len = ndpi_min(sizeof(flow->protos.tivoconnect.identity_uuid) - 1,
73
0
                                    value_len - NDPI_STATICSTRING_LEN("uuid:"));
74
0
        strncpy(flow->protos.tivoconnect.identity_uuid,
75
0
                value + NDPI_STATICSTRING_LEN("uuid:"), len);
76
0
        flow->protos.tivoconnect.identity_uuid[len] = '\0';
77
0
      }
78
0
      continue;
79
0
    }
80
0
    if (key_len == NDPI_STATICSTRING_LEN("machine") &&
81
0
        strncasecmp(key, "machine", key_len) == 0)
82
0
    {
83
0
      size_t const len = ndpi_min(sizeof(flow->protos.tivoconnect.machine) - 1,
84
0
                                         value_len);
85
0
      strncpy(flow->protos.tivoconnect.machine, value, len);
86
0
      flow->protos.tivoconnect.machine[len] = '\0';
87
0
      continue;
88
0
    }
89
0
    if (key_len == NDPI_STATICSTRING_LEN("platform") &&
90
0
        strncasecmp(key, "platform", key_len) == 0)
91
0
    {
92
0
      size_t const len = ndpi_min(sizeof(flow->protos.tivoconnect.platform) - 1,
93
0
                                         value_len);
94
0
      strncpy(flow->protos.tivoconnect.platform, value, len);
95
0
      flow->protos.tivoconnect.platform[len] = '\0';
96
0
      continue;
97
0
    }
98
0
    if (key_len == NDPI_STATICSTRING_LEN("services") &&
99
0
        strncasecmp(key, "services", key_len) == 0)
100
0
    {
101
0
      size_t const len = ndpi_min(sizeof(flow->protos.tivoconnect.services) - 1,
102
0
                                         value_len);
103
0
      strncpy(flow->protos.tivoconnect.services, value, len);
104
0
      flow->protos.tivoconnect.services[len] = '\0';
105
0
      continue;
106
0
    }
107
0
  }
108
109
0
  if ((size_t)(key - payload) != payload_len)
110
0
  {
111
0
    ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET,
112
0
                  "TiViConnect beacon malformed packet");
113
0
  }
114
0
}
115
116
static void ndpi_search_tivoconnect(struct ndpi_detection_module_struct *ndpi_struct,
117
                                    struct ndpi_flow_struct *flow)
118
0
{
119
0
  struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
120
121
0
  NDPI_LOG_INFO(ndpi_struct, "search tivoconnect\n");
122
123
0
  if (packet->payload_packet_len >= NDPI_STATICSTRING_LEN("tivoconnect=") &&
124
0
      strncasecmp((char const *)packet->payload,
125
0
                  "tivoconnect=", NDPI_STATICSTRING_LEN("tivoconnect=")) == 0)
126
0
  {
127
0
    ndpi_int_tivoconnect_add_connection(ndpi_struct, flow);
128
0
  } else {
129
0
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
130
0
    return;
131
0
  }
132
133
0
  dissect_tivoconnect_data(ndpi_struct, flow);
134
0
}
135
136
void init_tivoconnect_dissector(struct ndpi_detection_module_struct *ndpi_struct)
137
0
{
138
0
  register_dissector("TiVoConnect", ndpi_struct,
139
0
                     ndpi_search_tivoconnect,
140
0
                     NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
141
0
                     1, NDPI_PROTOCOL_TIVOCONNECT);
142
0
}