/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 | | |