Coverage Report

Created: 2026-02-21 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ndpi/src/lib/protocols/kcp.c
Line
Count
Source
1
/*
2
 * kcp.c
3
 *
4
 * Copyright (C) 2024 - 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_KCP
25
26
#include "ndpi_api.h"
27
#include "ndpi_private.h"
28
29
PACK_ON
30
struct kcp_header {
31
  uint32_t conversation_id;
32
  uint8_t command;
33
  uint8_t fragment_count;
34
  uint16_t window_size;
35
  uint32_t timestamp;
36
  uint32_t serial_number;
37
  uint32_t unacknowledged_serial_number;
38
  uint32_t length;
39
  uint8_t data[];
40
} PACK_OFF;
41
42
enum kcp_commands {
43
  IKCP_CMD_PUSH = 81,
44
  IKCP_CMD_ACK  = 82,
45
  IKCP_CMD_WASK = 83,
46
  IKCP_CMD_WINS = 84
47
};
48
49
static void ndpi_int_kcp_add_connection(struct ndpi_detection_module_struct * const ndpi_struct,
50
                                        struct ndpi_flow_struct * const flow)
51
0
{
52
0
  NDPI_LOG_INFO(ndpi_struct, "found kcp\n");
53
0
  ndpi_set_detected_protocol(ndpi_struct, flow,
54
0
                             NDPI_PROTOCOL_KCP,
55
0
                             NDPI_PROTOCOL_UNKNOWN,
56
0
                             NDPI_CONFIDENCE_DPI);
57
0
}
58
59
static void ndpi_search_kcp(struct ndpi_detection_module_struct *ndpi_struct,
60
                            struct ndpi_flow_struct *flow)
61
0
{
62
0
  struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
63
0
  struct kcp_header const * const kcp_header = (struct kcp_header *)packet->payload;
64
65
0
  NDPI_LOG_INFO(ndpi_struct, "search kcp\n");
66
67
0
  if (packet->payload_packet_len < sizeof(*kcp_header))
68
0
  {
69
0
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
70
0
    return;
71
0
  }
72
73
0
  switch (kcp_header->command)
74
0
  {
75
0
    case IKCP_CMD_PUSH:
76
0
    case IKCP_CMD_ACK:
77
0
    case IKCP_CMD_WASK:
78
0
    case IKCP_CMD_WINS:
79
0
      break;
80
0
    default:
81
0
      NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
82
0
      return;
83
0
  }
84
85
0
  uint32_t const kcp_pdu_length = le32toh(kcp_header->length);
86
0
  if (kcp_pdu_length + sizeof(*kcp_header) != packet->payload_packet_len)
87
0
  {
88
0
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
89
0
    return;
90
0
  }
91
92
0
  ndpi_int_kcp_add_connection(ndpi_struct, flow);
93
0
}
94
95
void init_kcp_dissector(struct ndpi_detection_module_struct *ndpi_struct)
96
1
{
97
1
  ndpi_register_dissector("KCP", ndpi_struct,
98
1
                     ndpi_search_kcp,
99
1
                     NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
100
1
                      1, NDPI_PROTOCOL_KCP);
101
1
}