Coverage Report

Created: 2023-06-29 06:44

/src/ndpi/src/lib/protocols/line.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * line.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
0
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_LINE_CALL
25
26
#include "ndpi_api.h"
27
28
extern int is_valid_rtp_payload_type(uint8_t type);
29
30
static void ndpi_int_line_add_connection(struct ndpi_detection_module_struct * const ndpi_struct,
31
                                         struct ndpi_flow_struct * const flow)
32
0
{
33
0
  NDPI_LOG_INFO(ndpi_struct, "found LineCall\n");
34
0
  ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN,
35
0
                             NDPI_PROTOCOL_LINE_CALL, NDPI_CONFIDENCE_DPI);
36
0
}
37
38
static void ndpi_search_line(struct ndpi_detection_module_struct *ndpi_struct,
39
                             struct ndpi_flow_struct *flow)
40
0
{
41
0
  struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
42
43
0
  NDPI_LOG_DBG(ndpi_struct, "searching LineCall\n");
44
45
0
  if(packet->iph && (flow->guessed_protocol_id_by_ip == NDPI_PROTOCOL_LINE)) {
46
    /*
47
      The heuristic below (coming from reverse engineering packet traces)
48
      will apply only to IPv4 and Line IP addresses. This is to avoid puttin
49
      false positives in other nDPI-decoded protocols.
50
    */
51
52
0
    if ((packet->payload_packet_len == 110 &&
53
0
   ndpi_struct->packet.payload[0] == 0xB6 &&  ndpi_struct->packet.payload[1] == 0x18 && ndpi_struct->packet.payload[2] == 0x00 && ndpi_struct->packet.payload[3] == 0x6A) ||
54
0
  (packet->payload_packet_len >= 738 && (ndpi_struct->packet.payload[0] == 0xDA || ndpi_struct->packet.payload[0] == 0xDB) &&
55
0
   ndpi_struct->packet.payload[4] == 0x06 && ndpi_struct->packet.payload[5] == 0x02) ||
56
0
  (packet->payload_packet_len >= 150 && (ndpi_struct->packet.payload[0] == 0xD9 || ndpi_struct->packet.payload[0] == 0xD8) &&
57
0
   ((ndpi_struct->packet.payload[1] & 0xF0) == 0x90 || (ndpi_struct->packet.payload[1] & 0xF0) == 0xD0 || (ndpi_struct->packet.payload[1] & 0xF0) == 0xE0) && ndpi_struct->packet.payload[4] == 0x06 &&
58
0
   ndpi_struct->packet.payload[5] == 0x02)) {
59
0
      ndpi_int_line_add_connection(ndpi_struct, flow);
60
0
      return;
61
0
    }
62
63
0
    if ((packet->payload_packet_len == 46 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xb6130006) ||
64
0
  (packet->payload_packet_len == 8 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xb6070004) ||
65
0
  (packet->payload_packet_len == 16 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xb609000c) ||
66
0
  (packet->payload_packet_len >= 2 /* TODO */ && ndpi_struct->packet.payload[0] == 0xD0 &&
67
0
   (ndpi_struct->packet.payload[1] == 0xB3 || ndpi_struct->packet.payload[1] == 0xB4
68
0
    || ndpi_struct->packet.payload[1] == 0xDA || ndpi_struct->packet.payload[1] == 0xDB))) {
69
0
      ndpi_int_line_add_connection(ndpi_struct, flow);
70
0
      return;
71
0
    }
72
0
  }
73
74
  /* Some "random" UDP packets before the standard RTP stream:
75
     it seems that the 4th bytes of these packets is some kind of packet
76
     number. Look for 4 packets per direction with consecutive numbers. */
77
0
  if(packet->payload_packet_len > 10) {
78
0
    if(flow->l4.udp.line_pkts[packet->packet_direction] == 0) {
79
0
      flow->l4.udp.line_base_cnt[packet->packet_direction] = packet->payload[3];
80
0
      flow->l4.udp.line_pkts[packet->packet_direction] += 1;
81
0
      return;
82
0
    } else {
83
      /* It might be a RTP/RTCP packet. Ignore it and keep looking for the
84
         LINE packet numbers */
85
      /* Basic RTP detection */
86
0
      if((packet->payload[0] >> 6) == 2 && /* Version 2 */
87
0
         (packet->payload[1] == 201 || /* RTCP, Receiver Report */
88
0
          packet->payload[1] == 200 || /* RTCP, Sender Report */
89
0
          is_valid_rtp_payload_type(packet->payload[1] & 0x7F)) /* RTP */) {
90
0
        NDPI_LOG_DBG(ndpi_struct, "Probably RTP; keep looking for LINE");
91
0
        return;
92
0
      } else {
93
0
        if((u_int8_t)(flow->l4.udp.line_base_cnt[packet->packet_direction] +
94
0
                      flow->l4.udp.line_pkts[packet->packet_direction]) == packet->payload[3]) {
95
0
          flow->l4.udp.line_pkts[packet->packet_direction] += 1;
96
0
          if(flow->l4.udp.line_pkts[0] >= 4 && flow->l4.udp.line_pkts[1] >= 4) {
97
            /* To avoid false positives: usually "base pkt numbers" per-direction are different */
98
0
            if(flow->l4.udp.line_base_cnt[0] != flow->l4.udp.line_base_cnt[1])
99
0
              ndpi_int_line_add_connection(ndpi_struct, flow);
100
0
            else
101
0
              NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
102
0
    }
103
0
          return;
104
0
        }
105
0
      }
106
0
    }
107
0
  }
108
109
0
  NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
110
0
  return;
111
0
}
112
113
void init_line_dissector(struct ndpi_detection_module_struct *ndpi_struct,
114
                         u_int32_t *id)
115
0
{
116
0
  ndpi_set_bitmask_protocol_detection("LineCall", ndpi_struct, *id,
117
0
              NDPI_PROTOCOL_LINE_CALL,
118
0
              ndpi_search_line,
119
0
              NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
120
0
              SAVE_DETECTION_BITMASK_AS_UNKNOWN,
121
0
              ADD_TO_DETECTION_BITMASK);
122
123
0
  *id += 1;
124
0
}