Coverage Report

Created: 2023-06-29 06:52

/src/ndpi/src/lib/protocols/tinc.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * tinc.c
3
 *
4
 * Copyright (C) 2017 - William Guglielmo <william@deselmo.com>
5
 * Copyright (C) 2017-22 - ntop.org
6
 *
7
 * nDPI is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * nDPI is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with nDPI.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
#include "ndpi_protocol_ids.h"
22
23
2.20k
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_TINC
24
25
#include "ndpi_api.h"
26
#include "libcache.h"
27
28
PACK_ON struct tinc_cache_entry {
29
  u_int32_t src_address;
30
  u_int32_t dst_address;
31
  u_int16_t dst_port;
32
} PACK_OFF;
33
34
static void ndpi_check_tinc(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
35
2.20k
{
36
2.20k
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
37
2.20k
  const u_int8_t *packet_payload = packet->payload;
38
2.20k
  u_int32_t payload_len = packet->payload_packet_len;
39
  
40
2.20k
  if(packet->udp != NULL) {
41
372
    if(ndpi_struct->tinc_cache != NULL) {
42
0
      struct tinc_cache_entry tinc_cache_entry1 = {
43
0
        .src_address = packet->iph->saddr,
44
0
        .dst_address = packet->iph->daddr,
45
0
        .dst_port = packet->udp->dest
46
0
      };
47
48
0
      struct tinc_cache_entry tinc_cache_entry2 = {
49
0
        .src_address = packet->iph->daddr,
50
0
        .dst_address = packet->iph->saddr,
51
0
        .dst_port = packet->udp->source
52
0
      };
53
54
0
      if(cache_remove(ndpi_struct->tinc_cache, &tinc_cache_entry1, sizeof(tinc_cache_entry1)) == CACHE_NO_ERROR ||
55
0
   cache_remove(ndpi_struct->tinc_cache, &tinc_cache_entry2, sizeof(tinc_cache_entry2)) == CACHE_NO_ERROR) {
56
57
0
        cache_remove(ndpi_struct->tinc_cache, &tinc_cache_entry1, sizeof(tinc_cache_entry1));
58
0
        cache_remove(ndpi_struct->tinc_cache, &tinc_cache_entry2, sizeof(tinc_cache_entry2));
59
60
  /* cache_free(ndpi_struct->tinc_cache); */
61
62
0
        NDPI_LOG_INFO(ndpi_struct, "found tinc udp connection\n");
63
0
        ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TINC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_CACHE);
64
0
      }
65
0
    }
66
    
67
372
    NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
68
372
    return;
69
1.83k
  } else if(packet->tcp != NULL) {
70
71
1.83k
    switch(flow->tinc_state) {
72
1.83k
    case 0:
73
1.83k
    case 1:
74
1.83k
      if(payload_len > 6 && memcmp(packet_payload, "0 ", 2) == 0 && packet_payload[2] != ' ') {
75
26
  u_int32_t i = 3;
76
2.49k
  while(i < payload_len && packet_payload[i++] != ' ');
77
26
  if(i+3 == payload_len && memcmp((packet_payload+i), "17\n", 3) == 0) {
78
0
    flow->tinc_state++;
79
0
    return;
80
0
  }
81
26
      }
82
1.83k
      break;
83
84
1.83k
    case 2:
85
0
    case 3:
86
0
      if(payload_len > 11 && memcmp(packet_payload, "1 ", 2) == 0 && packet_payload[2] != ' ') {
87
0
  u_int16_t i = 3;
88
0
  u_int8_t numbers_left = 4;
89
0
  while(numbers_left) {
90
0
    while(i < payload_len && packet_payload[i] >= '0' && packet_payload[i] <= '9') {
91
0
      i++;
92
0
    }
93
94
0
    if(i < payload_len && packet_payload[i++] == ' ') {
95
0
      numbers_left--;
96
0
    }
97
0
    else break;
98
0
  }
99
          
100
0
  if(numbers_left) break;
101
          
102
0
  while(i < payload_len &&
103
0
        ((packet_payload[i] >= '0' && packet_payload[i] <= '9') ||
104
0
         (packet_payload[i] >= 'A' && packet_payload[i] <= 'Z'))) {
105
0
    i++;
106
0
  }
107
          
108
0
  if(i < payload_len && packet_payload[i] == '\n') {
109
0
    if(++flow->tinc_state > 3) {
110
0
      struct tinc_cache_entry tinc_cache_entry = {
111
0
        .src_address = flow->c_address.v4,
112
0
        .dst_address = flow->s_address.v4,
113
0
        .dst_port = flow->s_port,
114
0
      };
115
116
0
      if(ndpi_struct->tinc_cache == NULL)
117
0
        ndpi_struct->tinc_cache = cache_new(TINC_CACHE_MAX_SIZE);              
118
119
0
      cache_add(ndpi_struct->tinc_cache, &tinc_cache_entry, sizeof(tinc_cache_entry));
120
0
      NDPI_LOG_INFO(ndpi_struct, "found tinc tcp connection\n");
121
0
      ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TINC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
122
0
    }
123
0
    return;
124
0
  }
125
0
      }
126
0
      break;
127
      
128
0
    default: break;
129
1.83k
    }
130
1.83k
  }
131
132
1.83k
  NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
133
1.83k
}
134
135
2.20k
static void ndpi_search_tinc(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) {
136
2.20k
  NDPI_LOG_DBG(ndpi_struct, "tinc detection\n");
137
138
2.20k
  if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_TINC) {
139
2.20k
    ndpi_check_tinc(ndpi_struct, flow);
140
2.20k
  }
141
2.20k
}
142
143
void init_tinc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id)
144
8.54k
{
145
8.54k
  ndpi_set_bitmask_protocol_detection("TINC", ndpi_struct, *id,
146
8.54k
              NDPI_PROTOCOL_TINC,
147
8.54k
              ndpi_search_tinc,
148
8.54k
              NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, /* TODO: IPv6? */
149
8.54k
              SAVE_DETECTION_BITMASK_AS_UNKNOWN,
150
8.54k
              ADD_TO_DETECTION_BITMASK);
151
152
8.54k
  *id += 1;
153
8.54k
}
154